OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [userguide/] [content.adoc] - Diff between revs 63 and 64

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 63 Rev 64
Line 143... Line 143...
if you instantiate one of the test setups.
if you instantiate one of the test setups.
 
 
[start=1]
[start=1]
. Create a new project with your FPGA EDA tool of choice.
. Create a new project with your FPGA EDA tool of choice.
. Add all VHDL files from the project's `rtl/core` folder to your project.
. Add all VHDL files from the project's `rtl/core` folder to your project.
 
 
 
.Internal Memories
 
[IMPORTANT]
 
For a _general_ first setup (technology-independent) use the _default_ memory architectures for the internal memories
 
(IMEM and DMEM). These are located in `rtl/core/mem`, so **make sure to add the files from `rtl/core/mem` to your project, too**. +
 
 +
 
If synthesis cannot efficiently map those default memory descriptions to the available memory resources, you can later replace the
 
default memory architectures by optimized platform-specific memory architectures. **Example:** The `setups/radiant/UPduino_v3`
 
example setup uses optimized memory primitives. Hence, it does not include the default memory architectures from
 
`rtl/core/mem` as these are replaced by device-specific implementations. However, it still has to include the entity
 
definitions from `rtl/core`.
 
 
 
[start=3]
. Make sure to add all the rtl files to a new library called `neorv32`. If your FPGA tools does not
. Make sure to add all the rtl files to a new library called `neorv32`. If your FPGA tools does not
provide a field to enter the library name, check out the "properties" menu of the added rtl files.
provide a field to enter the library name, check out the "properties" menu of the added rtl files.
 
 
 
.Compile order
 
[NOTE]
 
Some tools (like Lattice Radiant) might require a _manual compile order_ of the VHDL source files to identify the dependencies.
 
The package file `neorv32_package.vhd` should be analyzed first followed by the memory image files (`neorv32_application_imagevhd`
 
and `neorv32_bootloader_image.vhd`) and the entity-only files (`neorv32_*mem.entity.vhd`).
 
 
 
[start=4]
. The `rtl/core/neorv32_top.vhd` VHDL file is the top entity of the NEORV32 processor, which can be
. The `rtl/core/neorv32_top.vhd` VHDL file is the top entity of the NEORV32 processor, which can be
instantiated into the "real" project. However, in this tutorial we will use one of the pre-defined
instantiated into the "real" project. However, in this tutorial we will use one of the pre-defined
test setups from `rtl/test_setups` (see above).
test setups from `rtl/test_setups` (see above).
 
 
[IMPORTANT]
[IMPORTANT]
Line 740... Line 761...
 
 
 
 
 
 
// ####################################################################################################################
// ####################################################################################################################
:sectnums:
:sectnums:
 
== Adding Custom Hardware Modules
 
 
 
In resemblance to the RISC-V ISA, the NEORV32 processor was designed to ease customization and _extensibility_.
 
The processor provides several predefined options to add application-specific custom hardware modules and accelerators.
 
 
 
 
 
=== Standard (_External_) Interfaces
 
 
 
The processor already provides a set of standard interfaces that are intended to connect _chip-external_ devices.
 
However, these interfaces can also be used chip-internally. The most suitable interfaces are
 
https://stnolting.github.io/neorv32/#_general_purpose_input_and_output_port_gpio[GPIO],
 
https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0[UART],
 
https://stnolting.github.io/neorv32/#_serial_peripheral_interface_controller_spi[SPI] and
 
https://stnolting.github.io/neorv32/#_two_wire_serial_interface_controller_twi[TWI].
 
 
 
The SPI and (especially) the GPIO interfaces might be the most straightforward approaches since they
 
have a minimal  protocol overhead. Device-specific interrupt capabilities can be added using the
 
https://stnolting.github.io/neorv32/#_external_interrupt_controller_xirq[External Interrupt Controller (XIRQ)].
 
Beyond simplicity, these interface only provide a very limited bandwidth and require more sophisticated
 
software handling ("bit-banging" for the GPIO).
 
 
 
 
 
=== External Bus Interface
 
 
 
The https://stnolting.github.io/neorv32/#_processor_external_memory_interface_wishbone_axi4_lite[External Bus Interface]
 
provides the classic approach to connect to custom IP. By default, the bus interface implements the widely adopted
 
Wishbone interface standard. However, this project also includes wrappers to bridge to other protocol standards like ARM's
 
AXI4-Lite or Intel's Avalon. By using a full-featured bus protocol, complex SoC structures can be implemented (including
 
several modules and even multi-core architectures). Many FPGA EDA tools provide graphical editors to build and customize
 
whole SoC architectures and even include pre-defined IP libraries.
 
 
 
.Example AXI SoC using Xilinx Vivado
 
image::neorv32_axi_soc.png[]
 
 
 
The bus interface uses a memory-mapped approach. All data transfers are handled by simple load/store operations since the
 
external bus interface is mapped into the processor's https://stnolting.github.io/neorv32/#_address_space[address space].
 
This allows a very simple still high-bandwidth communications.
 
 
 
 
 
=== Stream Link Interface
 
 
 
The NEORV32 https://stnolting.github.io/neorv32/#_stream_link_interface_slink[Stream Link Interface] provides
 
point-to-point, unidirectional and parallel data channels that can be used to transfer streaming data. In
 
contrast to the external bus interface, the streaming data does not provide any kind of "direction" control,
 
so it can be seen as "constant address bursts". The stream link interface provides less protocol overhead
 
and less latency than the bus interface. Furthermore, FIFOs can be be configured to each direction (RX/TX) to
 
allow more CPU-independent operation.
 
 
 
 
 
=== Custom Functions Subsystem
 
 
 
The https://stnolting.github.io/neorv32/#_custom_functions_subsystem_cfs[NEORV32 Custom Functions Subsystem]
 
is as "empty" template for a processor-internal module. It provides 32 32-bit memory-mapped interface
 
registers that can be used to communicate with any arbitrary custom design logic. The intentions of this
 
subsystem is to provide a simple base, where the user can concentrate on implementing the actual design logic
 
rather than taking care of the communication between the CPU/software and the design logic. The interface
 
registers are already allocated within the processor's address space and are supported by the software framework
 
via low-level hardware access mechanisms. Additionally, the CFS provides a direct pre-defined interrupt channel to
 
the CPU, which is also supported by the _NEORV32 runtime environment_.
 
 
 
 
 
 
 
 
 
// ####################################################################################################################
 
:sectnums:
== Customizing the Internal Bootloader
== Customizing the Internal Bootloader
 
 
The NEORV32 bootloader provides several options to configure and customize it for a certain application setup.
The NEORV32 bootloader provides several options to configure and customize it for a certain application setup.
This configuration is done by passing _defines_ when compiling the bootloader. Of course you can also
This configuration is done by passing _defines_ when compiling the bootloader. Of course you can also
modify to bootloader source code to provide a setup that perfectly fits your needs.
modify to bootloader source code to provide a setup that perfectly fits your needs.
Line 779... Line 865...
| `SPI_BOOT_BASE_ADDR`    | `0x08000000` | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
| `SPI_BOOT_BASE_ADDR`    | `0x08000000` | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
|=======================
|=======================
 
 
Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
(using `+=`) to the makefile's `USER_FLAGS` variable. Make sure to use the `-D` prefix here.
(using `+=`) to the makefile `USER_FLAGS` variable. Make sure to use the `-D` prefix here.
 
 
For example, to configure a UART Baud rate of 57600 and redirecting the status LED to output pin 20
For example, to configure a UART Baud rate of 57600 and redirecting the status LED to output pin 20
use the following command (_in_ the bootloader's source folder `sw/bootloader`):
use the following command (_in_ the bootloader's source folder `sw/bootloader`):
 
 
.Example: customizing, re-compiling and re-installing the bootloader
.Example: customizing, re-compiling and re-installing the bootloader
Line 933... Line 1019...
// ####################################################################################################################
// ####################################################################################################################
:sectnums:
:sectnums:
== Packaging the Processor as IP block for Xilinx Vivado Block Designer
== Packaging the Processor as IP block for Xilinx Vivado Block Designer
 
 
[start=1]
[start=1]
. Import all the core files from `rtl/core` and assign them to a _new_ design library `neorv32`.
. Import all the core files from `rtl/core` (including default internal memory architectures from `rtl/core/mem`)
 
and assign them to a _new_ design library `neorv32`.
. Instantiate the `rtl/wrappers/neorv32_top_axi4lite.vhd` module.
. Instantiate the `rtl/wrappers/neorv32_top_axi4lite.vhd` module.
. Then either directly use that module in a new block-design ("Create Block Design", right-click -> "Add Module",
. Then either directly use that module in a new block-design ("Create Block Design", right-click -> "Add Module",
thats easier for a first try) or package it ("Tools", "Create and Package new IP") for the use in other projects.
thats easier for a first try) or package it ("Tools", "Create and Package new IP") for the use in other projects.
. Connect your AXI-peripheral directly to the core's AXI4-Interface if you only have one, or to an AXI-Interconnect
. Connect your AXI-peripheral directly to the core's AXI4-Interface if you only have one, or to an AXI-Interconnect
(from the IP-catalog) if you have multiple peripherals.
(from the IP-catalog) if you have multiple peripherals.
Line 959... Line 1046...
 
 
// ####################################################################################################################
// ####################################################################################################################
:sectnums:
:sectnums:
== Simulating the Processor
== Simulating the Processor
 
 
 
The NEORV32 project includes a core CPU, built-in peripherals in the Processor Subsystem, and additional peripherals in
 
the templates and examples.
 
Therefore, there is a wide range of possible testing and verification strategies.
 
 
 
On the one hand, a simple smoke testbench allows ensuring that functionality is correct from a software point of view.
 
That is used for running the RISC-V architecture tests, in order to guarantee compliance with the ISA specification(s).
 
 
 
On the other hand, http://vunit.github.io/[VUnit] and http://vunit.github.io/verification_components/user_guide.html[Verification Components] are used for verifying the functionality of the various peripherals from a hardware point of view.
 
 
:sectnums:
:sectnums:
=== Testbench
=== Testbench
 
 
The NEORV32 project features a simple, plain-VHDL (no third-party libraries) default testbench (`sim/neorv32_tb.simple.vhd`)
A plain-VHDL (no third-party libraries) testbench (`sim/simple/neorv32_tb.simple.vhd`) can be used for simulating and
that can be used to simulate and test the processor setup. This testbench features a 100MHz clock and enables all optional
testing the processor.
peripheral and CPU extensions except for the `E` extension and the TRNG IO module (that CANNOT be simulated due to its
This testbench features a 100MHz clock and enables all optional peripheral and CPU extensions except for the `E`
combinatorial (looped) architecture).
extension and the TRNG IO module (that CANNOT be simulated due to its combinatorial (looped) architecture).
 
 
The simulation setup is configured via the "User Configuration" section located right at the beginning of
The simulation setup is configured via the "User Configuration" section located right at the beginning of
the testbench's architecture. Each configuration constant provides comments to explain the functionality.
the testbench's architecture. Each configuration constant provides comments to explain the functionality.
 
 
Besides the actual NEORV32 Processor, the testbench also simulates "external" components that are connected
Besides the actual NEORV32 Processor, the testbench also simulates "external" components that are connected
Line 979... Line 1075...
* an external data memory
* an external data memory
* an external memory to simulate "external IO devices"
* an external memory to simulate "external IO devices"
* a memory-mapped registers to trigger the processor's interrupt signals
* a memory-mapped registers to trigger the processor's interrupt signals
 
 
The following table shows the base addresses of these four components and their default configuration and
The following table shows the base addresses of these four components and their default configuration and
properties (attributes: `r` = read, `w` = write, `e` = execute, `a` = atomic accesses possible, `8` = byte-accessible, `16` =
properties:
half-word-accessible, `32` = word-accessible).
 
 
[NOTE]
 
====
 
Attributes:
 
 
 
* `r` = read
 
* `w` = write
 
* `e` = execute
 
* `a` = atomic accesses possible
 
* `8` = byte-accessible
 
* `16` = half-word-accessible
 
* `32` = word-accessible
 
====
 
 
.Testbench: processor-external memories
.Testbench: processor-external memories
[cols="^4,>3,^5,<11"]
[cols="^4,>3,^5,<11"]
[options="header",grid="rows"]
[options="header",grid="rows"]
|=======================
|=======================
Line 993... Line 1101...
| `0x80000000` | `dmem_size_c` | `r/w/e,  a, 8/16/32` | external DMEM
| `0x80000000` | `dmem_size_c` | `r/w/e,  a, 8/16/32` | external DMEM
| `0xf0000000` |      64 bytes | `r/w/e, !a, 8/16/32` | external "IO" memory, atomic accesses will fail
| `0xf0000000` |      64 bytes | `r/w/e, !a, 8/16/32` | external "IO" memory, atomic accesses will fail
| `0xff000000` |       4 bytes | `-/w/-,  a,  -/-/32` | memory-mapped register to trigger "machine external", "machine software" and "SoC Fast Interrupt" interrupts
| `0xff000000` |       4 bytes | `-/w/-,  a,  -/-/32` | memory-mapped register to trigger "machine external", "machine software" and "SoC Fast Interrupt" interrupts
|=======================
|=======================
 
 
[NOTE]
[IMPORTANT]
The simulated NEORV32 does not use the bootloader and _directly boots_ the current application image (from
The simulated NEORV32 does not use the bootloader and _directly boots_ the current application image (from
the `rtl/core/neorv32_application_image.vhd` image file).
the `rtl/core/neorv32_application_image.vhd` image file).
 
 
.UART output during simulation
.UART output during simulation
[NOTE]
[IMPORTANT]
Data written to the NEORV32 UART0 / UART1 transmitter is send to a virtual UART receiver implemented
Data written to the NEORV32 UART0 / UART1 transmitter is send to a virtual UART receiver implemented
as part of the testbench. Received chars are send to the simulator console and are also stored to a log file
as part of the testbench. Received chars are send to the simulator console and are also stored to a log file
(`neorv32.testbench_uart0.out` for UART0, `neorv32.testbench_uart1.out` for UART1) inside the simulation's home folder.
(`neorv32.testbench_uart0.out` for UART0, `neorv32.testbench_uart1.out` for UART1) inside the simulation's home folder.
**Please note that printing via the native UART receiver takes a lot of time.** For faster simulation console output
**Please note that printing via the native UART receiver takes a lot of time.** For faster simulation console output
see section <<_faster_simulation_console_output>>.
see section <<_faster_simulation_console_output>>.
Line 1011... Line 1119...
:sectnums:
:sectnums:
=== Faster Simulation Console Output
=== Faster Simulation Console Output
 
 
When printing data via the UART the communication speed will always be based on the configured BAUD
When printing data via the UART the communication speed will always be based on the configured BAUD
rate. For a simulation this might take some time. To have faster output you can enable the **simulation mode**
rate. For a simulation this might take some time. To have faster output you can enable the **simulation mode**
or UART0/UART1 (see section https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0[Documentation: Primary Universal Asynchronous Receiver and Transmitter (UART0)]).
for UART0/UART1 (see section https://stnolting.github.io/neorv32/#_primary_universal_asynchronous_receiver_and_transmitter_uart0[Documentation: Primary Universal Asynchronous Receiver and Transmitter (UART0)]).
 
 
 
ASCII data sent to UART0|UART1 will be immediately printed to the simulator console and logged to files in the simulator
 
execution directory:
 
 
ASCII data send to UART0 will be immediately printed to the simulator console. Additionally, the
* `neorv32.uart?.sim_mode.text.out`: ASCII data.
ASCII data is logged in a file (`neorv32.uart0.sim_mode.text.out`) in the simulator home folder. All
* `neorv32.uart?.sim_mode.data.out`: all written 32-bit dumped as 8-char hexadecimal values.
written 32-bit data is also dumped as 8-char hexadecimal value into a file
 
(`neorv32.uart0.sim_mode.data.out`) also in the simulator home folder.
You can "automatically" enable the simulation mode of UART0/UART1 when compiling an application.
 
In this case, the "real" UART0/UART1 transmitter unit is permanently disabled.
ASCII data send to UART1 will be immediately printed to the simulator console. Additionally, the
To enable the simulation mode just compile and install your application and add _UART?_SIM_MODE_ to the compiler's
ASCII data is logged in a file (`neorv32.uart1.sim_mode.text.out`) in the simulator home folder. All
_USER_FLAGS_ variable (do not forget the `-D` suffix flag):
written 32-bit data is also dumped as 8-char hexadecimal value into a file
 
(`neorv32.uart1.sim_mode.data.out`) also in the simulator home folder.
 
 
 
You can "automatically" enable the simulation mode of UART0/UART1 when compiling an application. In this case the
 
"real" UART0/UART1 transmitter unit is permanently disabled. To enable the simulation mode just compile
 
and install your application and add _UART0_SIM_MODE_ for UART0 and/or _UART1_SIM_MODE_ for UART1 to
 
the compiler's _USER_FLAGS_ variable (do not forget the `-D` suffix flag):
 
 
 
[source, bash]
[source, bash]
----
----
sw/example/blink_led$ make USER_FLAGS+=-DUART0_SIM_MODE clean_all all
sw/example/blink_led$ make USER_FLAGS+=-DUART0_SIM_MODE clean_all all
----
----
Line 1042... Line 1146...
The UART simulation output (to file and to screen) outputs "complete lines" at once. A line is
The UART simulation output (to file and to screen) outputs "complete lines" at once. A line is
completed with a line feed (newline, ASCII `\n` = 10).
completed with a line feed (newline, ASCII `\n` = 10).
 
 
 
 
:sectnums:
:sectnums:
=== Simulation using GHDL
=== Simulation using a shell script (with GHDL)
 
 
To simulate the processor using _GHDL_ navigate to the `sim` folder and run the provided shell script.
To simulate the processor using _GHDL_ navigate to the `sim/simple/` folder and run the provided shell script.
Any arguments that are provided while executing this script are passed to GHDL.
Any arguments that are provided while executing this script are passed to GHDL.
For example the simulation time can be set to 20ms using `--stop-time=20ms` as argument.
For example the simulation time can be set to 20ms using `--stop-time=20ms` as argument.
 
 
[source, bash]
[source, bash]
----
----
neorv32/sim$ sh ghdl_sim.sh --stop-time=20ms
neorv32/sim/simple$ sh ghdl_sim.sh --stop-time=20ms
----
----
 
 
 
 
:sectnums:
:sectnums:
=== In-Console Application Simulation
=== Simulation using Application Makefiles (In-Console with GHDL)
 
 
To directly compile and run a program in the console (using the default testbench and GHDL
To directly compile and run a program in the console (using the default testbench and GHDL
as simulator) you can use the `sim` makefile target. Make sure to use the UART simulation mode
as simulator) you can use the `sim` makefile target. Make sure to use the UART simulation mode
(`USER_FLAGS+=-DUART0_SIM_MODE` and/or `USER_FLAGS+=-DUART1_SIM_MODE`) to get
(`USER_FLAGS+=-DUART0_SIM_MODE` and/or `USER_FLAGS+=-DUART1_SIM_MODE`) to get
faster / direct-to-console UART output.
faster / direct-to-console UART output.
Line 1071... Line 1175...
Blinking LED demo program
Blinking LED demo program
----
----
 
 
 
 
:sectnums:
:sectnums:
=== Hello World!
==== Hello World!
 
 
To do a quick test of the NEORV32 make sure to have [GHDL](https://github.com/ghdl/ghdl) and a
To do a quick test of the NEORV32 make sure to have https://github.com/ghdl/ghdl[GHDL] and a
[RISC-V gcc toolchain](https://github.com/stnolting/riscv-gcc-prebuilt) installed, navigate to the project's
[RISC-V gcc toolchain](https://github.com/stnolting/riscv-gcc-prebuilt) installed.
`sw/example/hello_world` folder and run `make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim`:
Navigate to the project's `sw/example/hello_world` folder and run `make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim`:
 
 
[TIP]
[TIP]
The simulator will output some _sanity check_ notes (and warnings or even errors if something is ill-configured)
The simulator will output some _sanity check_ notes (and warnings or even errors if something is ill-configured)
right at the beginning of the simulation to give a brief overview of the actual NEORV32 SoC and CPU configurations.
right at the beginning of the simulation to give a brief overview of the actual NEORV32 SoC and CPU configurations.
 
 
[source, bash]
[source, bash]
----
----
stnolting@Einstein:/mnt/n/Projects/neorv32/sw/example/hello_world$ make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim
stnolting@Einstein:/mnt/n/Projects/neorv32/sw/example/hello_world$ make USER_FLAGS+=-DUART0_SIM_MODE MARCH=-march=rv32imac clean_all sim
../../../sw/lib/source/neorv32_uart.c: In function 'neorv32_uart0_setup':
../../../sw/lib/source/neorv32_uart.c: In function 'neorv32_uart0_setup':
../../../sw/lib/source/neorv32_uart.c:301:4: warning: #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! [-Wcpp]
../../../sw/lib/source/neorv32_uart.c:301:4: warning: #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! [-Wcpp]
  301 |   #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only!
  301 |   #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! <1>
      |    ^~~~~~~
      |    ^~~~~~~
Memory utilization:
Memory utilization:
   text    data     bss     dec     hex filename
   text    data     bss     dec     hex filename
   4612       0     120    4732    127c main.elf
   4612       0     120    4732    127c main.elf <2>
Compiling ../../../sw/image_gen/image_gen
Compiling ../../../sw/image_gen/image_gen
Installing application image to ../../../rtl/core/neorv32_application_image.vhd
Installing application image to ../../../rtl/core/neorv32_application_image.vhd <3>
Simulating neorv32_application_image.vhd...
Simulating neorv32_application_image.vhd...
Tip: Compile application with USER_FLAGS+=-DUART[0/1]_SIM_MODE to auto-enable UART[0/1]'s simulation mode (redirect UART output to simulator console).
Tip: Compile application with USER_FLAGS+=-DUART[0/1]_SIM_MODE to auto-enable UART[0/1]'s simulation mode (redirect UART output to simulator console). <4>
Using simulation runtime args: --stop-time=10ms
Using simulation runtime args: --stop-time=10ms <5>
../rtl/core/neorv32_top.vhd:347:3:@0ms:(assertion note): NEORV32 PROCESSOR IO Configuration: GPIO MTIME UART0 UART1 SPI TWI PWM WDT CFS SLINK NEOLED XIRQ
../rtl/core/neorv32_top.vhd:347:3:@0ms:(assertion note): NEORV32 PROCESSOR IO Configuration: GPIO MTIME UART0 UART1 SPI TWI PWM WDT CFS SLINK NEOLED XIRQ <6>
../rtl/core/neorv32_top.vhd:370:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM).
../rtl/core/neorv32_top.vhd:370:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM).
../rtl/core/neorv32_top.vhd:394:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD).
../rtl/core/neorv32_top.vhd:394:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD).
../rtl/core/neorv32_cpu.vhd:169:3:@0ms:(assertion note): NEORV32 CPU ISA Configuration (MARCH): RV32IMACU_Zbb_Zicsr_Zifencei_Zfinx_Debug
../rtl/core/neorv32_cpu.vhd:169:3:@0ms:(assertion note): NEORV32 CPU ISA Configuration (MARCH): RV32IMACU_Zbb_Zicsr_Zifencei_Zfinx_Debug
../rtl/core/neorv32_cpu.vhd:189:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant  = TRUE to configure a DEFINED reset value for all CPU registers.
../rtl/core/neorv32_cpu.vhd:189:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant  = TRUE to configure a DEFINED reset value for all CPU registers.
../rtl/core/neorv32_imem.vhd:107:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (16384 bytes), pre-initialized with application (4612 bytes).
../rtl/core/neorv32_imem.vhd:107:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (16384 bytes), pre-initialized with application (4612 bytes).
Line 1108... Line 1212...
../rtl/core/neorv32_wishbone.vhd:136:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol.
../rtl/core/neorv32_wishbone.vhd:136:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol.
../rtl/core/neorv32_wishbone.vhd:140:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing auto-timeout (255 cycles).
../rtl/core/neorv32_wishbone.vhd:140:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing auto-timeout (255 cycles).
../rtl/core/neorv32_wishbone.vhd:144:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order.
../rtl/core/neorv32_wishbone.vhd:144:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order.
../rtl/core/neorv32_wishbone.vhd:148:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing registered RX path.
../rtl/core/neorv32_wishbone.vhd:148:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing registered RX path.
../rtl/core/neorv32_slink.vhd:161:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing 8 RX and 8 TX stream links.
../rtl/core/neorv32_slink.vhd:161:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing 8 RX and 8 TX stream links.
 
 
                                                                                       ##
                                                                                       ##
                                                                                       ##         ##   ##   ##
                                                                                       ##         ##   ##   ##
 ##     ##   #########   ########    ########   ##      ##   ########    ########      ##       ################
 ##     ##   #########   ########    ########   ##      ##   ########    ########      ##       ################
####    ##  ##          ##      ##  ##      ##  ##      ##  ##      ##  ##      ##     ##     ####            ####
####    ##  ##          ##      ##  ##      ##  ##      ##  ##      ##  ##      ##     ##     ####            ####
## ##   ##  ##          ##      ##  ##      ##  ##      ##          ##         ##      ##       ##   ######   ##
## ##   ##  ##          ##      ##  ##      ##  ##      ##          ##         ##      ##       ##   ######   ##
Line 1122... Line 1226...
##     ##    #########   ########   ##      ##      ##       ########   ##########     ##       ################
##     ##    #########   ########   ##      ##      ##       ########   ##########     ##       ################
                                                                                       ##         ##   ##   ##
                                                                                       ##         ##   ##   ##
                                                                                       ##
                                                                                       ##
Hello world! :)
Hello world! :)
----
----
 
<1> Notifier that "simulation mode" of UART0 is enabled (by the `USER_FLAGS+=-DUART0_SIM_MODE` makefile flag). All UART0 output is send to the simulator console.
 
<2> Final executable size (`text`) and _static_ data memory requirements (`data`, `bss`).
 
<3> The application code is _installed_ as pre-initialized IMEM. This is the default approach for simulation.
 
<4> A note regarding UART "simulation mode", but we have already enabled that.
 
<5> List of (default) arguments that were send to the simulator. Here: maximum simulation time (10ms).
 
<6> "Sanity checks" from the core's VHDL files. These reports give some brief information about the SoC/CPU configuration (-> generics). If there are problems with the current configuration, an ERROR will appear.
 
<7> Execution of the actual program starts.
 
 
 
 
:sectnums:
:sectnums:
=== Advanced Simulation using VUNIT
=== Advanced Simulation using VUnit
 
 
 
https://vunit.github.io/[VUnit] is an open source unit testing framework for VHDL/SystemVerilog.
 
It allows continuous and automated testing of HDL code by complementing traditional testing methodologies.
 
The motto of VUnit is _"testing early and often"_ through automation.
 
 
 
VUnit is composed by a http://vunit.github.io/py/ui.html[Python interface] and multiple optional
 
http://vunit.github.io/vhdl_libraries.html[VHDL libraries].
 
The Python interface allows declaring sources and simulation options, and it handles the compilation, execution and
 
gathering of the results regardless of the simulator used.
 
That allows having a single `run.py` script to be used with GHDL, ModelSim/QuestaSim, Riviera PRO, etc.
 
On the other hand, the VUnit's VHDL libraries provide utilities for assertions, logging, having virtual queues, handling CSV files, etc.
 
The http://vunit.github.io/verification_components/user_guide.html[Verification Component Library] uses those features
 
for abstracting away bit-toggling when verifying standard interfaces such as Wishbone, AXI, Avalon, UARTs, etc.
 
 
 
Testbench sources in `sim` (such as `sim/neorv32_tb.vhd` and `sim/uart_rx*.vhd`) use VUnit's VHDL libraries for testing
 
NEORV32 and peripherals.
 
The entrypoint for executing the tests is `sim/run.py`.
 
 
.WORK IN PROGRESS
[source, bash]
[WARNING]
----
This Section Is Under Construction! +
# ./sim/run.py -l
 +
neorv32.neorv32_tb.all
FIXME!
Listed 1 tests
 
 
The NEORV32 provides a more sophisticated simulation setup using https://vunit.github.io/[VUNIT].
# ./sim/run.py -v
The according VUNIT-based testbench is `sim/neorv32_tb.vhd`.
Compiling into neorv32:   rtl/core/neorv32_uart.vhd                                                                                            passed
 
Compiling into neorv32:   rtl/core/neorv32_twi.vhd                                                                                             passed
**WORK-IN-PROGRESS**
Compiling into neorv32:   rtl/core/neorv32_trng.vhd                                                                                            passed
 
...
 
----
 
 
 
See http://vunit.github.io/user_guide.html[VUnit: User Guide] and http://vunit.github.io/cli.html[VUnit: Command Line Interface] for further info about VUnit's features.
 
 
 
 
 
 
// ####################################################################################################################
// ####################################################################################################################
:sectnums:
:sectnums:
Line 1218... Line 1349...
[NOTE]
[NOTE]
This tutorial uses `gdb` to **directly upload an executable** to the processor. If you are using the default
This tutorial uses `gdb` to **directly upload an executable** to the processor. If you are using the default
processor setup _with_ internal instruction memory (IMEM) make sure it is implemented as RAM
processor setup _with_ internal instruction memory (IMEM) make sure it is implemented as RAM
(_INT_BOOTLOADER_EN_ generic = true).
(_INT_BOOTLOADER_EN_ generic = true).
 
 
 
[IMPORTANT]
 
The on-chip debugger is only implemented if the _ON_CHIP_DEBUGGER_EN_ generic is set _true_. Furthermore, it requires
 
the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_
 
and _CPU_EXTENSION_RISCV_Zifencei_ = true).
 
 
 
 
:sectnums:
:sectnums:
=== Hardware Requirements
=== Hardware Requirements
 
 
Make sure the on-chip debugger of your NEORV32 setups is implemented (_ON_CHIP_DEBUGGER_EN_ generic = true).
Make sure the on-chip debugger of your NEORV32 setups is implemented (_ON_CHIP_DEBUGGER_EN_ generic = true).
Line 1298... Line 1434...
Navigate to `sw/example/blink_led` and compile the application:
Navigate to `sw/example/blink_led` and compile the application:
 
 
.Compile the test application
.Compile the test application
[source, bash]
[source, bash]
--------------------------
--------------------------
.../neorv32/sw/example/blink_led$ make MARCH=-march=rv32i clean_all all
.../neorv32/sw/example/blink_led$ make MARCH=-march=rv32i USER_FLAGS+=-g clean_all all
--------------------------
--------------------------
 
 
 
.Adding debug symbols to the executable
 
[NOTE]
 
`USER_FLAGS+=-g` passes the `-g` flag to the compiler so it adds debug information/symbols
 
to the generated ELF file. This is optional but will provide more sophisticated information for debugging
 
(like source file line numbers).
 
 
This will generate an ELF file `main.elf` that contains all the symbols required for debugging.
This will generate an ELF file `main.elf` that contains all the symbols required for debugging.
Furthermore, an assembly listing file `main.asm` is generated that we will use to define breakpoints.
Furthermore, an assembly listing file `main.asm` is generated that we will use to define breakpoints.
 
 
Open another terminal in `sw/example/blink_led` and start `gdb`.
Open another terminal in `sw/example/blink_led` and start `gdb`.
The GNU debugger is part of the toolchain (see <<_software_toolchain_setup>>).
The GNU debugger is part of the toolchain (see <<_software_toolchain_setup>>).
Line 1329... Line 1471...
For help, type "help".
For help, type "help".
Type "apropos word" to search for commands related to "word".
Type "apropos word" to search for commands related to "word".
(gdb)
(gdb)
--------------------------
--------------------------
 
 
Now connect to OpenOCD using the default port 3333 on your local machine.
Now connect to OpenOCD using the default port 3333 on your machine.
Set the ELF file we want to debug to the recently generated `main.elf` from the `blink_led` example.
We will use the previously generated ELF file `main.elf` from the `blink_led` example.
Finally, upload the program to the processor.
Finally, upload the program to the processor and start debugging.
 
 
[NOTE]
[NOTE]
The executable that is uploaded to the processor is **not** the default NEORV32 executable (`neorv32_exe.bin`) that
The executable that is uploaded to the processor is **not** the default NEORV32 executable (`neorv32_exe.bin`) that
is used for uploading via the bootloader. Instead, all the required sections (like `.text`) are extracted from `mail.elf`
is used for uploading via the bootloader. Instead, all the required sections (like `.text`) are extracted from `mail.elf`
by GDB and uploaded via the debugger's indirect memory access.
by GDB and uploaded via the debugger's indirect memory access.
 
 
.Running GDB
.Running GDB
[source, bash]
[source, bash]
--------------------------
--------------------------
(gdb) target remote localhost:3333 <1>
(gdb) target extended-remote localhost:3333 <1>
Remote debugging using localhost:3333
Remote debugging using localhost:3333
warning: No executable has been specified and target does not support
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
determining executable automatically.  Try using the "file" command.
0xffff0c94 in ?? () <2>
0xffff0c94 in ?? () <2>
(gdb) file main.elf <3>
(gdb) file main.elf <3>
Line 1403... Line 1545...
--------------------------
--------------------------
(gdb) b * 0x690
(gdb) b * 0x690
Breakpoint 1 at 0x690
Breakpoint 1 at 0x690
--------------------------
--------------------------
 
 
 
.How do breakpoints work?
 
[TIP]
 
The NEORV32 on-chip debugger does not provide any hardware breakpoints (RISC-V "trigger modules") that compare an address like the PC
 
with a predefined value. Instead, gdb will modify the actual executable in IMEM: the actual instruction at the address
 
of the specified breakpoint is replaced by a `break` / `c.break` instruction. Whenever execution reaches this instruction, debug mode is
 
re-entered and the debugger restores the original instruction at this address to maintain original program behavior.
 
 
Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
By this we can "step" from increment to increment.
By this we can "step" from increment to increment.
 
 
.Iterating from breakpoint to breakpoint
.Iterating from breakpoint to breakpoint
[source, bash]
[source, bash]

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.