NEORV32
Overview
The NEORV32 is an open-source RISC-V compatible processor system intended as a ready-to-go auxiliary processor within larger SoC designs or as a stand-alone customizable microcontroller.
For more information about the NEORV32, see the following websites:
The currently supported version is NEORV32 v1.11.2.
Supported Board Targets
The following NEORV32 board targets are supported by Zephyr:
neorv32/neorv32/minimalboot
neorv32/neorv32/up5kdemo
Each of these match one of the NEORV32 processor templates provided alongside the NEORV32 RTL. These board targets can be customized out-of-tree to match custom NEORV32 implementations using board extensions or devicetree overlays.
The neorv32
board supports the hardware features listed below.
- on-chip / on-board
- Feature integrated in the SoC / present on the board.
- 2 / 2
-
Number of instances that are enabled / disabled.
Click on the label to see the first instance of this feature in the board/SoC DTS files. -
vnd,foo
-
Compatible string for the Devicetree binding matching the feature.
Click on the link to view the binding documentation.
Type |
Location |
Description |
Compatible |
---|---|---|---|
CPU |
on-chip |
NEORV32 RISC-V CPU1 |
|
GPIO & Headers |
on-chip |
NEORV32 GPIO1 |
|
Interrupt controller |
on-chip |
RISC-V CPU interrupt controller1 |
|
on-chip |
SiFive RISC-V Core-Local Interruptor1 |
||
LED |
on-board |
Group of GPIO-controlled LEDs1 |
|
MTD |
on-chip |
Flash node1 |
|
RNG |
on-chip |
NEORV32 True Random Number Generator (TRNG)1 |
|
Serial controller |
on-chip |
||
SRAM |
on-chip |
Generic on-chip SRAM description2 |
|
System controller |
on-chip |
System Controller Registers R/W1 |
|
Timer |
on-chip |
RISC-V Machine Timer1 |
Supported Features
The following NEORV32 features are supported by Zephyr. These are pre-configured for the supported board targets, but can be customized to match custom NEORV32 implementations.
System Clock
The default board configuration reads the system clock frequency from the NEORV32 SYSINFO module,
which results in a small run-time overhead. If the clock frequency is known at build time, this
behavior can be overridden by setting the clock-frequency
property of the cpu0
devicetree
node.
CPU
The SoC configuration assumes the NEORV32 CPU implementation has the following RISC-V ISA extensions enabled:
Zicntr (Extension for Base Counters and Timers)
Zicsr (Control and Status Register (CSR) Instructions, always enabled)
Zifencei (Instruction-fetch fence, always enabled)
Other supported RISC-V ISA extensions must be enabled via Kconfig on the board level, and the
riscv,isa
devicetree property of the cpu0
node must be set accordingly.
Core Local Interruptor
The NEORV32 Core Local Interruptor (CLINT) and its machine timer (MTIMER) are supported but disabled
by default. For NEORV32 SoC implementations supporting these, support can be enabled by setting
the status
properties of the clint
and mtimer
devicetree node to okay
.
Internal Instruction Memory
The internal instruction memory (IMEM) for code execution is supported but disabled by default. For
NEORV32 SoC implementations supporting IMEM, support can be enabled by setting the size via the
reg
property of the imem
devicetree node and setting its status
property to okay
.
Internal Data Memory
The internal data memory (DMEM) is supported but disabled by default. For NEORV32 SoC
implementations supporting DMEM, support can be enabled by setting the size via the reg
property
of the dmem
devicetree node and setting its status
property to okay
.
Serial Port
The NEORV32 serial ports (UART0 and UART1) are supported but disabled by default. For NEORV32 SoC
implementations supporting either of the UARTs, support can be enabled by setting the status
properties of the uart0
and/or uart1
devicetree node to okay
.
Note
The board targets provide a console on UART0 with a baud rate of 19200 to match that of the
standard NEORV32 bootloader. The baudrate can be changed by modifying the current-speed
property of the uart0
devicetree node.
General Purpose Input/Output
The NEORV32 GPIO port is supported but disabled by default. For NEORV32 SoC implementations
supporting the GPIOs, support can be enabled by setting the status
property of the gpio
devicetree node to okay
. The number of supported GPIOs can be set via the ngpios
devicetree
property.
True Random-Number Generator
The True Random-Number Generator (TRNG) of the NEORV32 is supported, but disabled by default. For
NEORV32 SoC implementations supporting the TRNG, support can be enabled by setting the status
property of the trng
devicetree node to okay
.
Programming and Debugging
First, configure the FPGA with the NEORV32 bitstream as described in the NEORV32 user guide.
Next, build and flash applications as usual (see Building an Application and Run an Application for more details).
Configuring a Console
Use the following settings with your serial terminal of choice (minicom, putty, etc.):
Speed: 19200
Data: 8 bits
Parity: None
Stop bits: 1
Flashing via JTAG
Here is an example for building and flashing the Hello World application for the NEORV32 via JTAG. Flashing via JTAG requires a NEORV32 SoC implementation with the On-Chip Debugger (OCD) and bootloader enabled.
Note
If the bootloader is not enabled, the internal instruction memory (IMEM) is configured as ROM which cannot be modified via JTAG.
# From the root of the zephyr repository
west build -b neorv32/neorv32/<variant> samples/hello_world
west flash
The default board configuration uses an OpenOCD Debug Host Tools configuration similar to the example provided by the NEORV32 project. Other JTAGs can be used by providing further arguments when flashing. Here is an example for using the Flyswatter JTAG @ 2 kHz:
# From the root of the zephyr repository
west build -b neorv32/neorv32/<variant> samples/hello_world
west flash --config interface/ftdi/flyswatter.cfg --config neorv32.cfg --cmd-pre-init 'adapter speed 2000'
After flashing, you should see message similar to the following in the terminal:
*** Booting Zephyr OS build zephyr-vn.n.nn ***
Hello World! neorv32/neorv32/<variant>
Note, however, that the application was not persisted in flash memory by the above steps. It was merely written to internal block RAM in the FPGA. It will revert to the application stored in the block RAM within the FPGA bitstream the next time the FPGA is configured.
The steps to persist the application within the FPGA bitstream are covered by
the NEORV32 user guide. If the CONFIG_BUILD_OUTPUT_BIN
is enabled and
the NEORV32 image_gen
binary is available, the build system will
automatically generate a zephyr.vhd
file suitable for initialising the
internal instruction memory of the NEORV32.
In order for the build system to automatically detect the image_gen
binary
it needs to be in the PATH
environment variable. If not, the path
can be passed at build time:
# From the root of the zephyr repository
west build -b neorv32/neorv32/<variant> samples/hello_world -- -DCMAKE_PROGRAM_PATH=<path/to/neorv32/sw/image_gen/>
Uploading via UART
If the CONFIG_BUILD_OUTPUT_BIN
is enabled and the NEORV32
image_gen
binary is available, the build system will automatically generate
a zephyr_exe.bin
file suitable for uploading to the NEORV32 via the
built-in bootloader as described in the NEORV32 user guide.
Debugging via JTAG
Here is an example for the Hello World application.
# From the root of the zephyr repository
west build -b neorv32/neorv32/<variant> samples/hello_world
west debug
Step through the application in your debugger, and you should see a message similar to the following in the terminal:
*** Booting Zephyr OS build zephyr-vn.n.nn ***
Hello World! neorv32/neorv32/<variant>