1
0
SEm-Labos/Libs/RiscV/NEORV32/setups/radiant/UPduino_v3/README.md

104 lines
6.6 KiB
Markdown
Raw Permalink Normal View History

2024-02-23 13:01:05 +00:00
# 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: :books: [tinyVision.ai Inc. UPduino v3 FPGA Board (GitHub)](https://github.com/tinyvision-ai-inc/UPduino-v3.0/),
:credit_card: buy on [Tindie](https://www.tindie.com/products/tinyvision_ai/upduino-v30-low-cost-lattice-ice40-fpga-board/)
* 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`](https://github.com/stnolting/neorv32/blob/master/boards/UPduino_v3/neorv32_upduino_v3_top.vhd) (instantiates NEORV32 top entity)
### Processor Configuration
- [x] CPU: `rv32imacu_Zicsr_Zicntr` (reduced CPU `[m]instret` & `[m]cycle` counter width!)
- [x] Memory: 64 kB instruction memory (internal IMEM), 64 kB data memory (internal DMEM), 4 kB bootloader ROM
- [x] Peripherals: `GPIO`, `MTIME`, `UART0`, `SPI`, `TWI`, `PWM`, `WDT`, `TRNG`
- [x] Clock: 24 MHz from on-chip HF oscillator (via PLL)
- [x] Reset: via PLL "locked" signal; external "reset" via FPGA re-reconfiguration pin (`creset_n`)
- [x] Tested with processor version [`1.6.1.6`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)
- [x] On-board FPGA bitstream flash storage can also be used to store/load NEORV32 application software (via the bootloader)
:information_source: 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`](https://github.com/stnolting/neorv32/blob/master/boards/UPduino_v3/neorv32_imem.ice40up_spram.vhd);
VHDL source file for platform-specific DMEM: [`neorv32_dmem.ice40up_spram.vhd`](https://github.com/stnolting/neorv32/blob/master/boards/UPduino_v3/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
:information_source: See [`neorv32_upduino_v3.pdc`](https://github.com/stnolting/neorv32/blob/master/boards/UPduino_v3/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 | J2-5 |
| `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 |
:information_source: 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
1. start Lattice Radiant (in GUI mode)
2. click on "open project" and select `neorv32_upduino_v3.rdf` from this folder
3. click the :arrow_forward: button to synthesize, map, place and route the design and to generate a programming file
4. 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`
5. in the programmer double click on the field under "Operation" (_fast configuration_ should be the default) and select "External SPI Memory" as "Target Memory"
6. select "SPI Serial Flash" under "SPI Flash Options / Family"
7. select "WinBond" under "SPI Flash Options / Vendor"
8. select "W25Q32" under "SPI Flash Options / Device"
9. close the dialog by clicking "ok"
10. click on "Program Device"