:sectnums:
== Overview

The NEORV32 RISC-V Processor is an open-source RISC-V compatible processor system that is intended as
*ready-to-go* auxiliary processor within a larger SoC designs or as stand-alone custom / customizable
microcontroller.

The system is highly configurable and provides optional common peripherals like embedded memories,
timers, serial interfaces, general purpose IO ports and an external bus interface to connect custom IP like
memories, NoCs and other peripherals. On-line and in-system debugging is supported by an OpenOCD/gdb
compatible on-chip debugger accessible via JTAG.

Special focus is paid on **execution safety** to provide defined and predictable behavior at any time.
Therefore, the CPU ensures that all memory access are acknowledged and no invalid/malformed instructions
are executed. Whenever an unexpected situation occurs, the application code is informed via hardware exceptions.

The software framework of the processor comes with application makefiles, software libraries for all CPU
and processor features, a bootloader, a runtime environment and several example programs - including a port
of the CoreMark MCU benchmark and the official RISC-V architecture test suite. RISC-V GCC is used as
default toolchain (https://github.com/stnolting/riscv-gcc-prebuilt[prebuilt toolchains are also provided]).

Check out the processor's **https://stnolting.github.io/neorv32/ug[online User Guide]**
that provides hands-on tutorials to get you started.


**Structure**

[start=2]
. <<_neorv32_processor_soc>>
. <<_neorv32_central_processing_unit_cpu>>
. <<_software_framework>>
. <<_on_chip_debugger_ocd>>
. <<_legal>>


**Annotations Types**

[WARNING]
Warning

[IMPORTANT]
Important

[NOTE]
Note

[TIP]
Tip


<<<
// ####################################################################################################################

include::rationale.adoc[]



// ####################################################################################################################
:sectnums:
=== Project Key Features

**Project**

* all-in-one package: **CPU** + **SoC** + **Software Framework & Tooling**
* completely described in behavioral, platform-independent VHDL - no vendor- or technology-specific primitives, attributes, macros, libraries, etc. are used at all
* all-Verilog "version" available (auto-generated by GHDL)
* extensive configuration options for adapting the processor to the requirements of the application
* highly extensible hardware - on CPU, SoC and system level
* aims to be as small as possible while being as RISC-V-compliant as possible - with a reasonable area-vs-performance trade-off
* FPGA friendly (e.g. all internal memories can be mapped to block RAM - including the register file)
* optimized for high clock frequencies to ease timing closure and integration
* from zero to _"hello world!"_ - completely open source and documented
* easy to use even for FPGA/RISC-V starters – intended to _work out of the box_

**NEORV32 CPU (the core)**

* 32-bit RISC-V CPU
* fully compatible to the RISC-V ISA specs. - checked by the https://github.com/stnolting/neorv32-riscof[official RISCOF architecture tests]
* base ISA + privileged ISA + several optional standard and custom ISA extensions
* option to add user-defined RISC-V instructions as custom ISA extension
* rich set of customization options (ISA extensions, design goal: performance / area / energy, tuning options, ...)
* <<_full_virtualization>> capabilities to increase execution safety
* official RISC-V open source architecture ID

**NEORV32 Processor (the SoC)**

* highly-configurable full-scale microcontroller-like processor system
* based on the NEORV32 CPU
* optional standard serial interfaces (UART, TWI, SPI (host and device), 1-Wire)
* optional timers and counters (watchdog, system timer)
* optional general purpose IO and PWM; a native NeoPixel(c)-compatible smart LED interface
* optional embedded memories and caches for data, instructions and bootloader
* optional external memory interface for custom connectivity
* optional execute in-place (XIP) module to execute code directly form an external SPI flash
* optional DMA controller for CPU-independent data transfers
* optional CRC module to check data integrity
* on-chip debugger compatible with OpenOCD and GDB including hardware trigger module and optional authentication

**Software framework**

* GCC-based toolchain - https://github.com/stnolting/riscv-gcc-prebuilt[prebuilt toolchains available]; application compilation based on GNU makefiles
* internal bootloader with serial user interface (via UART)
* core libraries and HAL for high-level usage of the provided functions and peripherals
* processor-specific runtime environment and several example programs
* doxygen-based documentation of the software framework; a deployed version is available at https://stnolting.github.io/neorv32/sw/files.html
* FreeRTOS port + demos available

**Extensibility and Customization**

The NEORV32 processor is designed to ease customization and extensibility and provides several options for adding
application-specific custom hardware modules and accelerators. The three most common options for adding custom
on-chip modules are listed below.

* <<_processor_external_bus_interface_xbus>> to attach processor-external IP modules (memories and peripherals)
* <<_custom_functions_subsystem_cfs>> for tightly-coupled processor-internal co-processors
* <<_custom_functions_unit_cfu>> for custom RISC-V instructions

[TIP]
A more detailed comparison of the extension/customization options can be found in section
https://stnolting.github.io/neorv32/ug/#_adding_custom_hardware_modules[Adding Custom Hardware Modules]
of the user guide.


<<<
// ####################################################################################################################
:sectnums:
=== Project Folder Structure

The root directory of the repository is considered the NEORV32 base or home folder (i.e. `neorv32/`).

.Folder Structure
...................................
neorv32               - Project home folder
│
├docs                 - Project documentation
│├datasheet           - AsciiDoc sources for the NEORV32 data sheet
│├figures             - Figures and logos
│├references          - Data sheets and RISC-V specs
│├sources             - Sources for the images in 'figures/'
│└userguide           - AsciiDoc sources for the NEORV32 user guide
│
├rtl                  - VHDL sources
│├core                - Core sources of the CPU & SoC
│├processor_templates - Pre-configured SoC wrappers
│├system_integration  - System wrappers and bridges for advanced connectivity
│└test_setups         - Minimal test setup "SoCs" used in the User Guide
│
├sim                  - Simulation files
│
└-sw                  - Software framework
  ├bootloader         - Sources of the processor-internal bootloader
  ├common             - Linker script, crt0.S start-up code and central makefile
  ├example            - Example programs for the core and the SoC modules
  │├eclipse           - Pre-configured Eclipse IDE project
  │└...               - Several example programs
  ├lib                - Processor core library
  │├include           - NEORV32 core library header files (*.h)
  │└source            - NEORV32 core library source files (*.c)
  ├image_gen          - Helper program to generate executables & memory images
  ├ocd_firmware       - Firmware for the on-chip debugger's "park loop"
  ├openocd            - OpenOCD configuration files
  └svd                - Processor system view description file (CMSIS-SVD)
...................................



<<<
// ####################################################################################################################
:sectnums:
=== VHDL File Hierarchy

All required VHDL hardware source files are located in the project's `rtl/core` folder.

.VHDL Library
[IMPORTANT]
All core VHDL files from the list below have to be assigned to a **new library** named `neorv32`.

.Compilation Order
[NOTE]
See section <<_file_list_files>> for more information.

.RTL File List and Hierarchy (in alphabetical order)
...................................
neorv32_top.vhd                 - NEORV32 PROCESSOR/SOC TOP ENTITY
│
├neorv32_cpu.vhd                - NEORV32 CPU TOP ENTITY
│├neorv32_cpu_alu.vhd           - Arithmetic/logic unit
││├neorv32_cpu_cp_bitmanip.vhd  - Bit-manipulation co-processor (B ext.)
││├neorv32_cpu_cp_cfu.vhd       - Custom instructions co-processor (Zxcfu ext.)
││├neorv32_cpu_cp_cond.vhd      - Integer conditional co-processor (Zicond ext.)
││├neorv32_cpu_cp_crypto.vhd    - Scalar cryptographic co-processor (Zk*/Zbk* ext.)
││├neorv32_cpu_cp_fpu.vhd       - Floating-point co-processor (Zfinx ext.)
││├neorv32_cpu_cp_muldiv.vhd    - Mul/Div co-processor (M ext.)
││└neorv32_cpu_cp_shifter.vhd   - Bit-shift co-processor (base ISA)
│├neorv32_cpu_control.vhd       - CPU control, exception system and CSRs
││└neorv32_cpu_decompressor.vhd - Compressed instructions decoder (C ext.)
│├neorv32_cpu_lsu.vhd           - Load/store unit
│├neorv32_cpu_pmp.vhd           - Physical memory protection unit (Smpmp ext.)
│└neorv32_cpu_regfile.vhd       - Data register file
│
├neorv32_boot_rom.vhd           - Bootloader ROM
│└neorv32_bootloader_image.vhd  - Bootloader ROM memory image (package)
├neorv32_bus.vhd                - SoC bus infrastructure modules
├neorv32_cache.vhd              - Generic cache module
├neorv32_cfs.vhd                - Custom functions subsystem
├neorv32_clockgate.vhd          - Generic clock gating switch
├neorv32_crc.vhd                - Cyclic redundancy check unit
├neorv32_debug_dm.vhd           - on-chip debugger: debug module
├neorv32_debug_auth.vhd         - on-chip debugger: authentication module
├neorv32_debug_dtm.vhd          - on-chip debugger: debug transfer module
├neorv32_dma.vhd                - Direct memory access controller
├neorv32_dmem.vhd               - Generic processor-internal data memory
├neorv32_fifo.vhd               - Generic FIFO component
├neorv32_gpio.vhd               - General purpose input/output port unit
├neorv32_gptmr.vhd              - General purpose 32-bit timer
├neorv32_imem.vhd               - Generic processor-internal instruction memory
│└neorv32_application_image.vhd - IMEM application initialization image (package)
├neorv32_mtime.vhd              - Machine system timer
├neorv32_neoled.vhd             - NeoPixel (TM) compatible smart LED interface
├neorv32_onewire.vhd            - One-Wire serial interface controller
├neorv32_package.vhd            - Main VHDL package file
├neorv32_pwm.vhd                - Pulse-width modulation controller
├neorv32_sdi.vhd                - Serial data interface controller (SPI device)
├neorv32_slink.vhd              - Stream link interface
├neorv32_spi.vhd                - Serial peripheral interface controller (SPI host)
├neorv32_sys.vhd                - System infrastructure modules
├neorv32_sysinfo.vhd            - System configuration information memory
├neorv32_trng.vhd               - True random number generator
├neorv32_twi.vhd                - Two wire serial interface controller
├neorv32_uart.vhd               - Universal async. receiver/transmitter
├neorv32_wdt.vhd                - Watchdog timer
├neorv32_xbus.vhd               - External (Wishbone) bus interface gateways
├neorv32_xip.vhd                - Execute in place module
└neorv32_xirq.vhd               - External interrupt controller
...................................

.Replacing Modules for Customization or Optimization
[TIP]
Any module of the core can be replaced by the user for customization purpose. For example, the default IMEM and DMEM
modules as well as the CPU's register file can be replaced by technology-specific primitives to optimize energy, speed
and area utilization. The module, which are dedicated for customization, i.e. CFS and CFU can be replaced by
user-defined modules to implement application-specific functionality.


:sectnums:
==== File-List Files

Most of the RTL sources use **entity instantiation**. Hence, the RTL compile order might be relevant (depending on
the synthesis/simulation tool. Therefore, two file-list files are provided in the `rtl` folder that list all required
HDL files for the CPU core and for the entire processor and also represent their recommended compile order.
These file-list files can be consumed by EDA tools to simplify project setup.

* `file_list_cpu.f` - HDL files and compile order for the CPU core; top module: `neorv32_cpu`
* `file_list_soc.f` - HDL files and compile order for the entire processor/SoC; top module: `neorv32_top`

A simple bash script `generate_file_lists.sh` is provided for regenerating the file-lists (using GHDL's _elaborate_ command).
This script can also be invoked using the default application makefile (see <<_makefile_targets>>).

By default, the file-list files include a **placeholder** in the path of each included hardware source file.
These placeholders need to be replaced by the actual path before being used. Example:

* default: `NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_package.vhd`
* adjusted: `path/to/neorv32/rtl/core/neorv32_package.vhd`

.Example: Processing the File-List Files in a Makefile
[source,makefile]
----
NEORV32_HOME = path/to/neorv32 <1>
NEORV32_SOC_FILE = $(shell cat $(NEORV32_HOME)/rtl/file_list_soc.f) <2>
NEORV32_SOC_SRCS = $(subst NEORV32_RTL_PATH_PLACEHOLDER, $(NEORV32_HOME)/rtl, $(NEORV32_SOC_FILE))) <3>
----
<1> Path to the NEORV32 home folder (i.e. the root folder of the GitHub repository).
<2> Load the content of the `file_list_soc.f` file-list into a new variable `NEORV32_SOC_FILE`.
<3> Substitute the file-list file's path placeholder "`NEORV32_RTL_PATH_PLACEHOLDER`" by the actual path.

.Example: Processing the File-List Files in a TCL Script
[source,tcl]
----
set file_list_file [read [open "$neorv32_home/rtl/file_list_soc.f" r]]
set file_list [string map [list "NEORV32_RTL_PATH_PLACEHOLDER" "$neorv32_home/rtl"] $file_list_file]
puts "NEORV32 source files:"
puts $file_list
----

.File-List Usage Examples
[TIP]
The provided file-list files are used by the GHDL-based simple simulation setup (`sim/ghdl.setup.sh`) as
well as by the Vivado IP packager script (`rtl/system_integration/neorv32_vivado_ip.tcl`).


<<<
// ####################################################################################################################
:sectnums:
=== VHDL Coding Style

* The entire processor including the CPU core is written in platform-/technology-independent VHDL.
The code makes minimal use of VHDL 2008 features to provide compatibility even for older EDA tools.
* A single package / library file (`neorv32_package.vhd`) is used to provide global defines and helper
functions. The specific user-defined configuration is done entirely by the generics of the top entity.
* Internally, the generics are checked to ensure a correct configuration. Asserts and "sanity checks" are used
to inform the user about the actual processor configuration and potential illegal setting.
* The code uses _entity instation_ for all internal modules. However, if several "submodules" are specified
within the same file _component instantiation_ is used for those.
* When instantiating the processor top module (`neorv32_top.vhd`) in a custom design either entity instantiation or
component instantiation can be used as the NEORV32 package file / library already provides an according component declaration.

.Verilog Version
[TIP]
A GHDL-generated all-Verilog version of the processor is available at https://github.com/stnolting/neorv32-verilog.
The provided setup generates a synthesizable Verilog netlist for a custom processor configuration.


<<<
// ####################################################################################################################
:sectnums:
=== FPGA Implementation Results

This section shows **exemplary** FPGA implementation results for the NEORV32 CPU and NEORV32 Processor modules.

[IMPORTANT]
The results are generated by manual synthesis runs. Hence, they might not represent the latest version of the processor.

[discrete]
==== CPU

[cols="<2,<8"]
[grid="topbot"]
|=======================
| HW version:  | `1.7.8.5`
| Top entity:  | `rtl/core/neorv32_cpu.vhd`
| FPGA:        | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain:   | Quartus Prime Lite 21.1
| Constraints: | **no timing constraints**, "balanced optimization", f~max~ from "_Slow 1200mV 0C Model_"
|=======================

[cols="<6,>1,>1,>1,>1,>1"]
[options="header",grid="rows"]
|=======================
| CPU ISA Configuration                             | LEs  | FFs  | MEM bits | DSPs | _f~max~_
| `rv32i_Zicsr`                                     | 1223 |  607 |     1024 |    0 | 130 MHz
| `rv32i_Zicsr_Zicntr`                              | 1578 |  773 |     1024 |    0 | 130 MHz
| `rv32im_Zicsr_Zicntr`                             | 2087 |  983 |     1024 |    0 | 130 MHz
| `rv32imc_Zicsr_Zicntr`                            | 2338 |  992 |     1024 |    0 | 130 MHz
| `rv32imcb_Zicsr_Zicntr`                           | 3175 | 1247 |     1024 |    0 | 130 MHz
| `rv32imcbu_Zicsr_Zicntr`                          | 3186 | 1254 |     1024 |    0 | 130 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei`                 | 3187 | 1254 |     1024 |    0 | 130 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei_Zfinx`           | 4450 | 1906 |     1024 |    7 | 123 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 4825 | 2018 |     1024 |    7 | 123 MHz
|=======================

.Goal-Driven Optimization
[TIP]
The CPU provides further options to reduce the area footprint or to increase performance.
See section <<_processor_top_entity_generics>> for more information. Also, take a look at the User Guide section
https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configuration[Application-Specific Processor Configuration].


[discrete]
==== Processor - Modules

[cols="<2,<8"]
[grid="topbot"]
|=======================
| HW version:  | `1.8.6.7`
| Top entity:  | `rtl/core/neorv32_top.vhd`
| FPGA:        | Intel Cyclone IV E `EP4CE22F17C6`
| Toolchain:   | Quartus Prime Lite 21.1
| Constraints: | **no timing constraints**, "balanced optimization"
|=======================

.Hardware utilization by processor module
[cols="<2,<8,>1,>1,>2,>1"]
[options="header",grid="rows"]
|=======================
| Module            | Description                                                    | LEs | FFs | MEM bits | DSPs
| BOOT ROM          | Bootloader ROM (4kB)                                           |   2 |   2 |    32768 |    0
| Bus switch (core) | _SoC bus infrastructure_                                       |  28 |  15 |        0 |    0
| Bus switch (DMA)  | _SoC bus infrastructure_                                       | 159 |   9 |        0 |    0
| CFS               | Custom functions subsystem (depends on custom design logic)    |   - |   - |        - |    -
| CRC               | Cyclic redundancy check unit                                   | 130 | 117 |        0 |    0
| dCACHE            | Data cache (4 blocks, 64 bytes per block)                      | 300 | 167 |     2112 |    0
| DM                | On-chip debugger - debug module                                | 377 | 241 |        0 |    0
| DTM               | On-chip debugger - debug transfer module (JTAG)                | 262 | 220 |        0 |    0
| DMA               | Direct memory access controller                                | 365 | 291 |        0 |    0
| DMEM              | Processor-internal data memory (8kB)                           |   6 |   2 |    65536 |    0
| Gateway           | _SoC bus infrastructure_                                       | 215 |  91 |        0 |    0
| GPIO              | General purpose input/output ports                             | 102 |  98 |        0 |    0
| GPTMR             | General Purpose Timer                                          | 150 | 105 |        0 |    0
| IO Switch         | _SoC bus infrastructure_                                       | 217 |   0 |        0 |    0
| iCACHE            | Instruction cache (2x4 blocks, 64 bytes per block)             | 458 | 296 |     4096 |    0
| IMEM              | Processor-internal instruction memory (16kB)                   |   7 |   2 |   131072 |    0
| MTIME             | Machine system timer                                           | 307 | 166 |        0 |    0
| NEOLED            | Smart LED Interface (NeoPixel/WS28128) (FIFO_depth=1)          | 171 | 129 |        0 |    0
| ONEWIRE           | 1-wire interface                                               | 105 |  77 |        0 |    0
| PWM               | Pulse_width modulation controller (4 channels)                 |  91 |  81 |        0 |    0
| Reservation Set   | Reservation set controller for LR/SC instructions              |  52 |  33 |        0 |    0
| SDI               | Serial data interface                                          | 103 |  77 |      512 |    0
| SLINK             | Stream link interface (RX/TX FIFO depth=32)                    |  96 |  73 |     2048 |    0
| SPI               | Serial peripheral interface                                    | 137 |  97 |     1024 |    0
| SYSINFO           | System configuration information memory                        |  11 |  11 |        0 |    0
| TRNG              | True random number generator                                   | 140 | 108 |      512 |    0
| TWI               | Two-wire interface                                             |  93 |  64 |        0 |    0
| UART0, UART1      | Universal asynchronous receiver/transmitter 0/1 (FIFO_depth=1) | 222 | 142 |     1024 |    0
| WDT               | Watchdog timer                                                 | 107 |  89 |        0 |    0
| WISHBONE          | External memory interface                                      | 122 | 112 |        0 |    0
| XIP               | Execute in place module                                        | 369 | 276 |        0 |    0
| XIRQ              | External interrupt controller (4 channels)                     |  35 |  29 |        0 |    0
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== CPU Performance

The performance of the NEORV32 was tested and evaluated using the https://www.eembc.org/coremark/[Core Mark CPU benchmark].
The according sources can be found in the `sw/example/coremark` folder.
The resulting CoreMark score is defined as CoreMark iterations per second per MHz.

.Configuration
[cols="<2,<8"]
[grid="topbot"]
|=======================
| HW version:     | `1.5.7.10`
| Hardware:       | 32kB int. IMEM, 16kB int. DMEM, no caches, 100MHz clock
| CoreMark:       | 2000 iterations, MEM_METHOD is MEM_STACK
| Compiler:       | RISCV32-GCC 10.2.0 (compiled with `march=rv32i mabi=ilp32`)
| Compiler flags: | default but with `-O3`, see makefile
|=======================

.CoreMark results
[cols="<5,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| CPU                                                      | CoreMark Score | CoreMarks/MHz | Average CPI
| _small_ (`rv32i_Zicsr_Zifencei`)                         |          33.89 | **0.3389**    | **4.04**
| _medium_ (`rv32imc_Zicsr_Zifencei`)                      |          62.50 | **0.6250**    | **5.34**
| _performance_ (`rv32imc_Zicsr_Zifencei` + perf. options) |          95.23 | **0.9523**    | **3.54**
|=======================

The NEORV32 CPU is based on a multi-cycle architecture. Each instruction is executed in a sequence of
several consecutive micro operations. The average CPI (cycles per instruction) depends on the instruction
mix of a specific applications and also on the available CPU extensions. More information regarding the execution
time of each implemented instruction can be found in section <<_instruction_sets_and_extensions>>.
