Skip to content

Commit

Permalink
Merge pull request #213 from provoostkris/main
Browse files Browse the repository at this point in the history
adding DE10 nano support
  • Loading branch information
stnolting authored Jan 6, 2025
2 parents 4cd25a6 + cadd907 commit cd2789b
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The setups using commercial toolchains provide pre-configured project files that
| Setup | Toolchain | Board | FPGA | Author(s) |
|:------|:----------|:------|:-----|:----------|
| :file_folder: [`de0-nano-test-setup`](https://github.com/stnolting/neorv32-setups/tree/main/quartus/de0-nano-test-setup) | Intel Quartus Prime | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`de10-nano-test-setup`](https://github.com/stnolting/neorv32-setups/tree/main/quartus/de10-nano-test-setup) | Intel Quartus Prime | [Terasic DE10-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=1046#contents) | Intel Cyclone V `5CSEBA6U23I7` | [provoostkris](https://github.com/provoostkris) |
| :file_folder: [`de0-nano-test-setup-qsys`](quartus/de0-nano-test-setup-qsys) | Intel Quartus Prime | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [torerams](https://github.com/torerams) |
| :file_folder: [`de0-nano-test-setup-avalonmm`](quartus/de0-nano-test-setup-avalonmm-wrapper) | Intel Quartus Prime | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [torerams](https://github.com/torerams) |
| :file_folder: [`terasic-cyclone-V-gx-starter-kit-test-setup`](https://github.com/stnolting/neorv32-setups/tree/main/quartus/terasic-cyclone-V-gx-starter-kit-test-setup) | Intel Quartus Prime | [Terasic Cyclone-V GX Starter Kit](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=830) | Intel Cyclone V `5CGXFC5C6F27C7N` | zs6mue |
Expand Down
6 changes: 6 additions & 0 deletions quartus/de10-nano-test-setup/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
db
incremental_db
output_files
*.qpf
*.qsf
*.qws
66 changes: 66 additions & 0 deletions quartus/de10-nano-test-setup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# NEORV32 Test Setup for the Terasic DE10-Nano FPGA Board

This setup provides a very simple script-based "demo setup" that allows to check out the
NEORV32 processor on the Terasic DE10-Nano board.
It uses the simplified [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd)
top entity, which is a wrapper for the actual processor
top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs).

* FPGA Board: :books: [Terasic DE10-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=167&No=1046)
* FPGA: Intel Cyclone-V `5CSEBA6U23I7`
* Toolchain: Intel Quartus Lite (tested with Quartus Prime Lite 22.1.2)


### NEORV32 Configuration

:information_source: See the top entity
[`\neorv32-setups\quartus\de10-nano-test-setup\neorv32_test_setup_bootloader.vhd`](/neorv32-setups/quartus/de10-nano-test-setup/neorv32_test_setup_bootloader.vhd)
for configuration and entity details and `create_project.tcl` for the according FPGA pin mapping.

* CPU: `rv32imc_Zicsr`
* Memory:
* 16kB instruction memory (internal IMEM)
* 8kB data memory (internal DMEM)
* bootloader ROM
* Peripherals:
* `GPIO`
* `CLINT`
* `UART0`
* Tested with version `1.10.8.8`
* Clock: 50MHz from on-board oscillator
* Reset: via on-board button "KEY0"
* GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0")
* UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header
* `uart0_txd_o:` output, connected to FPGA pin `Y15` - header pin `GPIO 0` (pin number "40")
* `uart0_rxd_i:` input, connected to FPGA pin `AA11` - header pin `GPIO 1` (pin number "1")


### FPGA Utilization

```
Logic utilization (in ALMs) 1,335 / 41,910 ( 3 % )
Total registers 1694
Total pins 12 / 314 ( 4 % )
Total virtual pins 0
Total block memory bits 231,424 / 5,662,720 ( 4 % )
Total DSP Blocks 0 / 112 ( 0 % )
```

## How To Run

The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project.
If not already available, this script will create a `work` folder in this directory.

1. start Quartus (in GUI mode)
2. in the menu line click "View/Utility Windows/Tcl console" to open the Tcl console
3. use the console to naviagte to **this** folder: `cd ..\neorv32-setups\quartus\de10-nano-test-setup`
4. execute `source create_project.tcl` - this will create and open the actual Quartus project in this folder
5. copy paste the neorv32_test_setup_bootloader.vhd in this folder and change the frequency to 50 MHz
6. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream
7. When the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA
8. Use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration:
19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline)
9. now you can communicate with the bootloader console and upload a new program.
Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example)
and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#------------------------------------------------------------------------------
#-- Quartus timing constraint file for uart_spw <> Terrasic DE10 nano Cyclone 5 design
#-- rev. 1.0 : 2021 Provoost Kris
#------------------------------------------------------------------------------

# clock definitions
create_clock -name clk_i -period 20 [get_ports clk_i]

# set false paths from user I/O
set_false_path -from [get_ports { rstn_i } ] -to [get_registers *]
set_false_path -to [get_ports { gpio_o[*] } ]

# general directives for PLL usage
derive_pll_clocks
derive_clock_uncertainty
93 changes: 93 additions & 0 deletions quartus/de10-nano-test-setup/create_project.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# make a local copy of original "./../../rtl/test_setups/neorv32_test_setup_bootloader.vhd " file
# and modify the default clock frequency: set to 50MHz
#set shell_script "cp -f ./../../../rtl/test_setups/neorv32_test_setup_bootloader.vhd . && sed -i 's/100000000/50000000/g' neorv32_test_setup_bootloader.vhd "
#exec sh -c $shell_script


# Load Quartus Prime Tcl Project package
package require ::quartus::project

set need_to_close_project 0
set make_assignments 1

# Check that the right project is open
if {[is_project_open]} {
if {[string compare $quartus(project) "de10-nano-test-setup"]} {
puts "Project de10-nano-test-setup is not open"
set make_assignments 0
}
} else {
# Only open if not already open
if {[project_exists de10-nano-test-setup]} {
project_open -revision de10-nano-test-setup de10-nano-test-setup
} else {
project_new -revision de10-nano-test-setup de10-nano-test-setup
}
set need_to_close_project 1
}

# Make assignments
if {$make_assignments} {

set_global_assignment -name FAMILY "Cyclone V"
set_global_assignment -name DEVICE 5CSEBA6U23I7
set_global_assignment -name TOP_LEVEL_ENTITY neorv32_test_setup_bootloader
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.10
set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:18:14 OCTOBER 31, 2021"
set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1

# core VHDL files
set core_src_dir [glob ./../../NEORV32/rtl/core/*.vhd]
foreach core_src_file $core_src_dir {
set_global_assignment -name VHDL_FILE $core_src_file -library neorv32
}
set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_dmem.default.vhd -library neorv32
set_global_assignment -name VHDL_FILE ./../../NEORV32/rtl/core/mem/neorv32_imem.default.vhd -library neorv32

# top entity: use local modified copy of the original test setup
set_global_assignment -name VHDL_FILE "neorv32_test_setup_bootloader.vhd"

set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top

set_location_assignment PIN_V11 -to clk_i
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk_i

set_location_assignment PIN_AH17 -to rstn_i
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to rstn_i

set_location_assignment PIN_W15 -to gpio_o[7]
set_location_assignment PIN_AA24 -to gpio_o[6]
set_location_assignment PIN_V16 -to gpio_o[5]
set_location_assignment PIN_V15 -to gpio_o[4]
set_location_assignment PIN_AF26 -to gpio_o[3]
set_location_assignment PIN_AE26 -to gpio_o[2]
set_location_assignment PIN_Y16 -to gpio_o[1]
set_location_assignment PIN_AA23 -to gpio_o[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio_o[0]

set_location_assignment PIN_AA11 -to uart0_rxd_i
set_location_assignment PIN_Y15 -to uart0_txd_o
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart0_rxd_i
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart0_txd_o


set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

# Commit assignments
export_assignments
}
81 changes: 81 additions & 0 deletions quartus/de10-nano-test-setup/neorv32_test_setup_bootloader.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
-- ================================================================================ --
-- NEORV32 - Test Setup Using The UART-Bootloader To Upload And Run Executables --
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
-- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. --
-- Licensed under the BSD-3-Clause license, see LICENSE for details. --
-- SPDX-License-Identifier: BSD-3-Clause --
-- ================================================================================ --

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library neorv32;
use neorv32.neorv32_package.all;

entity neorv32_test_setup_bootloader is
generic (
-- adapt these for your setup --
CLOCK_FREQUENCY : natural := 50_000_000; -- clock frequency of clk_i in Hz
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes
);
port (
-- Global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- GPIO --
gpio_o : out std_ulogic_vector(7 downto 0); -- parallel output
-- UART0 --
uart0_txd_o : out std_ulogic; -- UART0 send data
uart0_rxd_i : in std_ulogic -- UART0 receive data
);
end entity;

architecture neorv32_test_setup_bootloader_rtl of neorv32_test_setup_bootloader is

signal con_gpio_out : std_ulogic_vector(63 downto 0);

begin

-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- Clocking --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
-- Boot Configuration --
BOOT_MODE_SELECT => 0, -- boot via internal bootloader
-- RISC-V CPU Extensions --
RISCV_ISA_C => true, -- implement compressed extension?
RISCV_ISA_M => true, -- implement mul/div extension?
RISCV_ISA_Zicntr => true, -- implement base counters?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => true, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Processor peripherals --
IO_GPIO_NUM => 8, -- number of GPIO input/output pairs (0..64)
IO_CLINT_EN => true, -- implement core local interruptor (CLINT)?
IO_UART0_EN => true -- implement primary universal asynchronous receiver/transmitter (UART0)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
-- GPIO (available if IO_GPIO_NUM > 0) --
gpio_o => con_gpio_out, -- parallel output
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart0_txd_o, -- UART0 send data
uart0_rxd_i => uart0_rxd_i -- UART0 receive data
);

-- GPIO output --
gpio_o <= con_gpio_out(7 downto 0);


end architecture;

0 comments on commit cd2789b

Please sign in to comment.