6.6 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	NEORV32 Example Setup for the tinyVision.ai Inc. "UPduino v3.0" FPGA Board
This example setup turns the UPduino v3.0 board, which features a Lattice iCE40 UltraPlus FPGA, into a medium-scale NEORV32 microcontroller. The processor setup provides 64kB of data and instruction memory, an RTOS-capable CPU (privileged architecture) and a set of standard peripherals like UART, TWI and SPI.
- FPGA Board: 📚 tinyVision.ai Inc. UPduino v3 FPGA Board (GitHub), 💳 buy on Tindie
- FPGA: Lattice iCE40 UltraPlus 5k iCE40UP5K-SG48I
- Toolchain: Lattice Radiant (tested with Radiant version 3.0.0), using Lattice Synthesis Engine (LSE)
- Top entity: neorv32_upduino_v3_top.vhd(instantiates NEORV32 top entity)
Processor Configuration
- CPU: rv32imacu_Zicsr_Zicntr(reduced CPU[m]instret&[m]cyclecounter width!)
- Memory: 64 kB instruction memory (internal IMEM), 64 kB data memory (internal DMEM), 4 kB bootloader ROM
- Peripherals: GPIO,MTIME,UART0,SPI,TWI,PWM,WDT,TRNG
- Clock: 24 MHz from on-chip HF oscillator (via PLL)
- Reset: via PLL "locked" signal; external "reset" via FPGA re-reconfiguration pin (creset_n)
- Tested with processor version 1.6.1.6
- On-board FPGA bitstream flash storage can also be used to store/load NEORV32 application software (via the bootloader)
ℹ️ This setup uses optimized platform-specific memory modules for the internal data and instruction memories (DMEM & IMEM). Each memory uses two
UltraPlus SPRAM primitives (total memory size per memory = 2 x 32kB = 64kB). VHDL source file for platform-specific IMEM:
neorv32_imem.ice40up_spram.vhd;
VHDL source file for platform-specific DMEM: neorv32_dmem.ice40up_spram.vhd.
These platform-specific memories are used instead of the default platform-agnostic modules from the core's rtl/core/mem folder.
Interface Signals
ℹ️ See neorv32_upduino_v3.pdc
for the FPGA pin mapping.
| Top Entity Signal | FPGA Pin | Package Pin | Board Header Pin | 
|---|---|---|---|
| flash_csn_o(spi_cs[0]) | IOB_35B | 16 | J3-1 | 
| flash_sck_o | IOB_34A | 15 | J3-2 | 
| flash_sdo_o | IOB_32A | 14 | J3-3 | 
| flash_sdi_i | IOB_33B | 17 | J3-4 | 
| gpio_i(0) | IOB_3B_G6 | 44 | J3-9 | 
| gpio_i(1) | IOB_8A | 4 | J3-10 | 
| gpio_i(2) | IOB_9B | 3 | J3-11 | 
| gpio_i(3) | IOB_4A | 48 | J3-12 | 
| gpio_o(0)(status LED) | IOB_5B | 45 | J3-13 | 
| gpio_o(1) | IOB_2A | 47 | J3-14 | 
| gpio_o(2) | IOB_0A | 46 | J3-15 | 
| gpio_o(3) | IOB_6A | 2 | J3-16 | 
| - | - | - | - | 
| reconfigure FPGA ("reset") | CRESET | 8 | J2-3 | 
| pwm_o(0) | gpio_i(0)(red) | RGB2 | 41 | 
| pwm_o(1)(green) | RGB0 | 39 | J2-6 | 
| pwm_o(2)(blue) | RGB1 | 40 | J2-7 | 
| twi_sda_io | IOT_42B | 31 | J2-9 | 
| twi_scl_io | IOT_45A_G1 | 37 | J2-10 | 
| spi_sdo_o | IOT_44B | 34 | J2-11 | 
| spi_sck_o | IOT_49A | 43 | J2-12 | 
| spi_csn_o(spi_cs[1]) | IOT_48B | 36 | J2-13 | 
| spi_sdi_i | IOT_51A | 42 | J2-14 | 
| uart_txd_o(UART0) | IOT_50B | 38 | J2-15 | 
| uart_rxd_i(UART0) | IOT_41A | 28 | J2-16 | 
ℹ️ The TWI signals (twi_sda_io and twi_scl_io) and the reset input (rstn_i) require an external pull-up resistor.
GPIO output 0 (gpio_o(0), also connected to the RGB drive) is used as output for a high-active status LED driven by the bootloader.
FPGA Utilization
Number of slice registers: 1754 out of 5280  (33%)
Number of I/O registers:     11 out of  117   (9%)
Number of LUT4s:           4882 out of 5280  (92%)
Number of DSPs:               0 out of    8   (0%)
Number of I2Cs:               0 out of    2   (0%)
Number of High Speed OSCs:    1 out of    1 (100%)
Number of Low Speed OSCs:     0 out of    1   (0%)
Number of RGB PWM:            0 out of    1   (0%)
Number of RGB Drivers:        1 out of    1 (100%)
Number of SCL FILTERs:        0 out of    2   (0%)
Number of SRAMs:              4 out of    4 (100%)
Number of WARMBOOTs:          0 out of    1   (0%)
Number of SPIs:               0 out of    2   (0%)
Number of EBRs:              15 out of   30  (50%)
Number of PLLs:               1 out of    1 (100%)
FPGA Setup
- start Lattice Radiant (in GUI mode)
- click on "open project" and select neorv32_upduino_v3.rdffrom this folder
- click the ▶️ button to synthesize, map, place and route the design and to generate a programming file
- when done open the programmer (for example via "Tools" -> "Programmer"); you will need a programmer configuration, which will be created in the next steps; alternatively,
you can use the pre-build configuration source/impl_1.xcf
- in the programmer double click on the field under "Operation" (fast configuration should be the default) and select "External SPI Memory" as "Target Memory"
- select "SPI Serial Flash" under "SPI Flash Options / Family"
- select "WinBond" under "SPI Flash Options / Vendor"
- select "W25Q32" under "SPI Flash Options / Device"
- close the dialog by clicking "ok"
- click on "Program Device"