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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 55 to Rev 56
    Reverse comparison

Rev 55 → Rev 56

/neorv32/trunk/boards/arty-a7-35-test-setup/README.md
0,0 → 1,47
# NEORV32 Test Setup for the Digilent Arty A7-35 FPGA Board
 
This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Digilent Arty A7-35 board.
It uses the simplified [`neorv32_test_setup.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) top entity, which is a wrapper for the actual processor
top entity that provides a minimalistic interface (clock, reset, UART and 4 LEDs).
 
* FPGA Board: :books: [Digilent Arty A7-35 FPGA Board](https://reference.digilentinc.com/reference/programmable-logic/arty-a7/reference-manual)
* FPGA: Xilinx Artix-7 `XC7A35TICSG324-1L`
* Toolchain: Xilinx Vivado (tested with Vivado 2019.2)
 
 
### NEORV32 Configuration
 
:information_source: See the top entity [`rtl/top_templates/neorv32_test_setup.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) for
configuration and entity details and [`arty_a7_35_test_setup.xdc`](https://github.com/stnolting/neorv32/blob/master/boards/arty-a7-35-test-setup/arty_a7_35_test_setup.xdc)
for the according FPGA pin mapping.
 
* CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors)
* Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM
* Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT`
* Tested with version [`1.5.3.3`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)
* Clock: 100MHz from on-board oscillator
* Reset: Via dedicated on-board "RESET" button
* GPIO output port `gpio_o`
* bits 0..3 are connected to the green on-board LEDs (LD4 - LD7); LD4 is the bootloader status LED
* bits 4..7 are (not actually used) connected to PMOD `JA` connector pins 1-4
* UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip
 
 
## How To Run
 
The `create_project.tcl` TCL script in this directory can be used to create a complete Vivado project.
If not already available, this script will create a `work` folder in this directory.
 
1. start Vivado (in GUI mode)
2. click on "TCL Console" at the bottom
3. use the console to naviagte to **this** folder: `cd .../neorv32/boards/arty-a7-35-test-setup`
4. execute `source create_project.tcl` - this will create the actual Vivado project in `work`
5. when the Vivado project has openend, click on "Run Implementation"
6. when the implementation is done create a bitstrem by clicking "Generate Bitstream" (maybe a prompt will ask for that)
7. open the "Hardware Manager" (maybe a prompt will ask for that)
8. click on "Open target/Auto Connect"
9. click on "Program device" and select `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`; click "Program"
10. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration:
19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline)
11. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example)
and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources.
/neorv32/trunk/boards/arty-a7-35-test-setup/arty_a7_35_test_setup.xdc
0,0 → 1,26
## This file is a general .xdc for the Arty A7-35 Rev. D
 
## For default neorv32_test_setup.vhd top entity
 
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_i }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { clk_i }];
 
## LEDs
set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[0] }]; #IO_L24N_T3_35 Sch=led[4]
set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[1] }]; #IO_25_35 Sch=led[5]
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[2] }]; #IO_L24P_T3_A01_D17_14 Sch=led[6]
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]
 
## Pmod Header JA (unused GPIO outputs)
set_property -dict { PACKAGE_PIN G13 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[4] }]; #IO_0_15 Sch=ja[1]
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[5] }]; #IO_L4P_T0_15 Sch=ja[2]
set_property -dict { PACKAGE_PIN A11 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[6] }]; #IO_L4N_T0_15 Sch=ja[3]
set_property -dict { PACKAGE_PIN D12 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[7] }]; #IO_L6P_T0_15 Sch=ja[4]
 
## USB-UART Interface
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { uart0_txd_o }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { uart0_rxd_i }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in
 
## Misc.
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports { rstn_i }]; #IO_L16P_T2_35 Sch=ck_rst
/neorv32/trunk/boards/arty-a7-35-test-setup/create_project.tcl
0,0 → 1,29
# create and clear output directory
set outputdir work
file mkdir $outputdir
 
set files [glob -nocomplain "$outputdir/*"]
if {[llength $files] != 0} {
puts "deleting contents of $outputdir"
file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
} else {
puts "$outputdir is empty"
}
 
 
# create project
create_project -part "xc7a35ticsg324-1L" "arty-a7-35-test-setup" $outputdir
 
 
# add source files: core sources
add_files [glob ./../../rtl/core/*.vhd]
set_property library neorv32 [get_files [glob ./../../rtl/core/*.vhd]]
 
# add source file: top entity
add_files [glob ./../../rtl/top_templates/neorv32_test_setup.vhd]
 
# add source files: simulation-only
add_files -fileset sim_1 ./../../sim/neorv32_tb.vhd
 
# add source files: constraints
add_files -fileset constrs_1 [glob ./*.xdc]
/neorv32/trunk/boards/de0-nano-test-setup/.gitignore
0,0 → 1,7
db
incremental_db
output_files
*.qpf
*.qsf
*.qws
*.vhd
/neorv32/trunk/boards/de0-nano-test-setup/README.md
0,0 → 1,50
# NEORV32 Test Setup for the Terasic DE0-Nano FPGA Board
 
This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Terasic DE0-Nano board.
It uses the simplified [`neorv32_test_setup.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) top entity, which is a wrapper for the actual processor
top entity that provides a minimalistic interface (clock, reset, UART and 8 LEDs).
 
* FPGA Board: :books: [Terasic DE0-Nano FPGA Board](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593)
* FPGA: Intel Cyclone-IV `EP4CE22F17C6N`
* Toolchain: Intel Quartus Prime (tested with Quartus Prime 20.1.0 - Lite Edition)
 
 
### NEORV32 Configuration
 
:information_source: See the top entity [`rtl/top_templates/neorv32_test_setup.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) for
configuration and entity details and `create_project.tcl` for the according FPGA pin mapping.
 
* CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors)
* Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM
* Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT`
* Tested with version [`1.5.3.8`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)
* Clock: 50MHz from on-board oscillator
* Reset: via on-board button "KEY0"
* GPIO output port `gpio_o` (8-bit) connected to the 8 green user LEDs ("LED7" - "LED0")
* UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the 40-pin **GPIO_0** header
* `uart0_txd_o:` output, connected to FPGA pin `C3` - header pin `GPIO_01` (pin number "4")
* `uart0_rxd_i:` input, connected to FPGA pin `A3` - header pin `GPIO_03` (pin number "6")
 
:warning: The default [`neorv32_test_setup.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) top entity
is configured for a 100MHz input clock. Since the on-board oscillator of the DE0-nano board generates a 50MHz clock, the test setup has to be modified.
This is automatically done by the `create_project.tcl` TCL script, which makes a local copy of the original test setup VHDL file
(in *this* folder) and uses `sed` to configure the `CLOCK_FREQUENCY` generic (in the local copy) for 50MHz. The local copy is then used as actual
top entity.
 
 
## How To Run
 
The `create_project.tcl` TCL script in this directory can be used to create a complete Quartus project.
If not already available, this script will create a `work` folder in this directory.
 
1. start Quartus (in GUI mode)
2. in the menu line click "View/Utility Windows/Tcl console" to open the Tcl console
3. use the console to naviagte to **this** folder: `cd .../neorv32/boards/de0-nano-test-setup`
4. execute `source create_project.tcl` - this will create and open the actual Quartus project in this folder
5. if a "select family" prompt appears select the "Cyclone IV E" family and click OK
6. double click on "Compile Design" in the "Tasks" window. This will synthesize, map and place & route your design and will also generate the actual FPGA bitstream
7. when the process is done open the programmer (for example via "Tools/Programmer") and click "Start" in the programmer window to upload the bitstream to your FPGA
8. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration:
19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline)
9. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example)
and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources.
/neorv32/trunk/boards/de0-nano-test-setup/create_project.tcl
0,0 → 1,92
# make a local copy of original "./../../rtl/top_templates/neorv32_test_setup.vhd" file
# and modify the default clock frequency: set to 50MHz
set shell_script "cp -f ./../../rtl/top_templates/neorv32_test_setup.vhd . && sed -i '/CLOCK_FREQUENCY/c\CLOCK_FREQUENCY => 50000000,' neorv32_test_setup.vhd"
exec sh -c $shell_script
 
# Copyright (C) 2020 Intel Corporation. All rights reserved.
# Your use of Intel Corporation's design tools, logic functions
# and other software and tools, and any partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Intel Program License
# Subscription Agreement, the Intel Quartus Prime License Agreement,
# the Intel FPGA IP License Agreement, or other applicable license
# agreement, including, without limitation, that your use is for
# the sole purpose of programming logic devices manufactured by
# Intel and sold by Intel or its authorized distributors. Please
# refer to the applicable agreement for further details, at
# https://fpgasoftware.intel.com/eula.
 
# Quartus Prime: Generate Tcl File for Project
# File: de0_nano_test.tcl
# Generated on: Sat Apr 10 16:57:48 2021
 
# Load Quartus Prime Tcl Project package
package require ::quartus::project
 
set need_to_close_project 0
set make_assignments 1
 
# Check that the right project is open
if {[is_project_open]} {
if {[string compare $quartus(project) "de0-nano-test-setup"]} {
puts "Project de0-nano-test-setup is not open"
set make_assignments 0
}
} else {
# Only open if not already open
if {[project_exists de0-nano-test-setup]} {
project_open -revision de0-nano-test-setup de0-nano-test-setup
} else {
project_new -revision de0-nano-test-setup de0-nano-test-setup
}
set need_to_close_project 1
}
 
# Make assignments
if {$make_assignments} {
set_global_assignment -name FAMILY "Cyclone IV E"
set_global_assignment -name DEVICE EP4CE22F17C6
set_global_assignment -name TOP_LEVEL_ENTITY neorv32_test_setup
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:40:53 APRIL 10, 2021"
set_global_assignment -name LAST_QUARTUS_VERSION "20.1.0 Lite Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
 
# core VHDL files
set core_src_dir [glob ./../../rtl/core/*.vhd]
foreach core_src_file $core_src_dir {
set_global_assignment -name VHDL_FILE $core_src_file -library neorv32
}
 
# top entity: use local modified copy of the original test setup
set_global_assignment -name VHDL_FILE "neorv32_test_setup.vhd"
 
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
 
set_location_assignment PIN_R8 -to clk_i
set_location_assignment PIN_L3 -to gpio_o[7]
set_location_assignment PIN_B1 -to gpio_o[6]
set_location_assignment PIN_F3 -to gpio_o[5]
set_location_assignment PIN_D1 -to gpio_o[4]
set_location_assignment PIN_A11 -to gpio_o[3]
set_location_assignment PIN_B13 -to gpio_o[2]
set_location_assignment PIN_A13 -to gpio_o[1]
set_location_assignment PIN_A15 -to gpio_o[0]
set_location_assignment PIN_J15 -to rstn_i
set_location_assignment PIN_C3 -to uart0_txd_o
set_location_assignment PIN_A3 -to uart0_rxd_i
 
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
 
# Commit assignments
export_assignments
}
/neorv32/trunk/boards/nexys-a7-test-setup/README.md
0,0 → 1,51
# NEORV32 Test Setup for the Digilent Nexys A7 and Nexys 4 DDR FPGA Boards
 
This setup provides a very simple script-based "demo setup" that allows to check out the NEORV32 processor on the Digilent Nexys A7 and Nexys 4 DDR boards.
It uses the simplified [`neorv32_test_setup.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) top entity, which is a wrapper for the actual processor
top entity that provides a minimalistic interface (clock, reset, UART and 4 LEDs).
 
* FPGA Boards:
* :books: [Digilent Nexys A7 FPGA Boards](https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/reference-manual)
* :books: [Digilent Nexys 4 DDR FPGA Board](https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/reference-manual)
* FPGAs:
* Xilinx Artix-7 `XC7A50TCSG324-1`
* Xilinx Artix-7 `XC7A100TCSG324-1`
* Toolchain: Xilinx Vivado (tested with Vivado 2020.2)
 
 
### NEORV32 Configuration
 
:information_source: See the top entity [`rtl/top_templates/neorv32_test_setup.vhd` ](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd) for
configuration and entity details and [`nexys_a7_test_setup.xdc`](https://github.com/AWenzel83/neorv32/blob/nexys_a7_example/boards/nexys-a7-test-setup/nexys_a7_test_setup.xdc)
for the according FPGA pin mapping.
 
* CPU: `rv32imcu_Zicsr` + 4 `HPM` (hardware performance monitors)
* Memory: 16kB instruction memory (internal IMEM), 8kB data memory (internal DMEM), bootloader ROM
* Peripherals: `GPIO`, `MTIME`, `UART0`, `WDT`
* Tested with version [`1.5.3.3`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md)
* Clock: 100MHz from on-board oscillator
* Reset: Via dedicated on-board "RESET" button
* GPIO output port `gpio_o` bits 0..7 are connected to the green on-board LEDs (LD0 - LD7); LD0 is the bootloader status LED
* UART0 signals `uart0_txd_o` and `uart0_rxd_i` are connected to the on-board USB-UART chip
 
 
## How To Run
 
The `create_project_nexys_a7_*.tcl` TCL scripts in this directory can be used to create a complete Vivado project.
If not already available, this script will create a `work` folder in this directory.
 
1. start Vivado (in GUI mode)
2. click on "TCL Console" at the bottom
3. use the console to naviagte to **this** folder: `cd .../neorv32/boards/nexys-a7-test-setup`
4. execute the tcl-script according to your board, this will create the actual Vivado project in `work`:
* `source create_project_nexys_a7_100.tcl`for a Nexys A7 100 or a Nexys 4 DDR board
* `source create_project_nexys_a7_50.tcl`for a Nexys A7 50 board
5. when the Vivado project has openend, click on "Run Implementation"
6. when the implementation is done create a bitstrem by clicking "Generate Bitstream" (maybe a prompt will ask for that)
7. open the "Hardware Manager" (maybe a prompt will ask for that)
8. click on "Open target/Auto Connect"
9. click on "Program device" and select `work/neorv32_test_setup.runs/impl_1/neorv32_test_setup.bit`; click "Program"
10. use a serial terminal (like :earth_asia: [Tera Term](https://ttssh2.osdn.jp/index.html.en)) to connect to the USB-UART interface using the following configuration:
19200 Baud, 8 data bits, 1 stop bit, no parity bits, no transmission / flow control protocol (raw bytes only), newline on `\r\n` (carriage return & newline)
11. now you can communicate with the bootloader console and upload a new program. Check out the [example programs](https://github.com/stnolting/neorv32/tree/master/sw/example)
and see section "Let's Get It Started" of the :page_facing_up: [NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) for further resources.
/neorv32/trunk/boards/nexys-a7-test-setup/create_project_nexys_a7_100.tcl
0,0 → 1,29
# create and clear output directory
set outputdir work
file mkdir $outputdir
 
set files [glob -nocomplain "$outputdir/*"]
if {[llength $files] != 0} {
puts "deleting contents of $outputdir"
file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
} else {
puts "$outputdir is empty"
}
 
 
# create project
create_project -part "xc7a100tcsg324-1" "nexys-a7-100-test-setup" $outputdir
 
 
# add source files: core sources
add_files [glob ./../../rtl/core/*.vhd]
set_property library neorv32 [get_files [glob ./../../rtl/core/*.vhd]]
 
# add source file: top entity
add_files [glob ./../../rtl/top_templates/neorv32_test_setup.vhd]
 
# add source files: simulation-only
add_files -fileset sim_1 ./../../sim/neorv32_tb.vhd
 
# add source files: constraints
add_files -fileset constrs_1 [glob ./*.xdc]
/neorv32/trunk/boards/nexys-a7-test-setup/create_project_nexys_a7_50.tcl
0,0 → 1,29
# create and clear output directory
set outputdir work
file mkdir $outputdir
 
set files [glob -nocomplain "$outputdir/*"]
if {[llength $files] != 0} {
puts "deleting contents of $outputdir"
file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
} else {
puts "$outputdir is empty"
}
 
 
# create project
create_project -part "xc7a50tcsg324-1" "nexys-a7-50-test-setup" $outputdir
 
 
# add source files: core sources
add_files [glob ./../../rtl/core/*.vhd]
set_property library neorv32 [get_files [glob ./../../rtl/core/*.vhd]]
 
# add source file: top entity
add_files [glob ./../../rtl/top_templates/neorv32_test_setup.vhd]
 
# add source files: simulation-only
add_files -fileset sim_1 ./../../sim/neorv32_tb.vhd
 
# add source files: constraints
add_files -fileset constrs_1 [glob ./*.xdc]
/neorv32/trunk/boards/nexys-a7-test-setup/nexys_a7_test_setup.xdc
0,0 → 1,23
## This file is a general .xdc for the Nexys A7 and Nexys 4 DDR
## For default neorv32_test_setup.vhd top entity
 
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { clk_i }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { clk_i }];
 
## LEDs
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { gpio_o[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
 
## USB-UART Interface
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { uart0_txd_o }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { uart0_rxd_i }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
 
## Misc.
set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { rstn_i }]; #IO_L3P_T0_DQS_AD1P_15 Sch=ck_rst
/neorv32/trunk/boards/README.md
0,0 → 1,26
# Exemplary FPGA Board Setups
 
**:construction: This page is still under construction :construction:**
 
This folder provides exemplary NEORV32 SoC setups for different FPGA platforms/boards. You can use one of the setups to directly get started
or as a starting point to build your own setup.
 
Project maintainers may make pull requests against this repository to add or link their setups.
 
 
| Setup | Board | FPGA | Author |
|:-----:|:------|:------|:------:|
| :file_folder: [`arty-a7-35-test-setup`](https://github.com/stnolting/neorv32/tree/master/boards/arty-a7-35-test-setup) | [Digilent Arty A7-35](https://reference.digilentinc.com/reference/programmable-logic/arty-a7/start) | Xilinx Artix-7 `XC7A35TICSG324-1L` | [stnolting](https://github.com/stnolting) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/boards/nexys-a7-test-setup) | [Digilent Nexys A7](https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/start) | Xilinx Artix-7 `XC7A50TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
| :file_folder: [`nexys-a7-test-setup`](https://github.com/stnolting/neorv32/tree/master/boards/nexys-a7-test-setup) | [Digilent Nexys 4 DDR](https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start) | Xilinx Artix-7 `XC7A100TCSG324-1` | [AWenzel83](https://github.com/AWenzel83) |
| :file_folder: [`de0-nano-test-setup`](https://github.com/stnolting/neorv32/tree/master/boards/de0-nano-test-setup) | [Terasic DE0-Nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=139&No=593) | Intel Cyclone IV `EP4CE22F17C6N` | [stnolting](https://github.com/stnolting) |
 
 
### Adding Your Project Setup
 
Please respect the following guidelines if you'd like to add (or link) your setup to the list.
 
* check out the project's [code of conduct](https://github.com/stnolting/neorv32/tree/master/CODE_OF_CONDUCT.md)
* add a link if the board you are using provides online documentation (and/or can be purchased somewhere)
* use the :file_folder: emoji (`:file_folder:`) if the setup is located *in this* folder; use the :earth_africa: emoji (`:earth_africa:`) if it is a link to your local project
* please add a `README` to give some brief information about the setup and a `.gitignore` to keep things clean; take a look at [`arty-a7-35-test-setup`](https://github.com/stnolting/neorv32/boards/arty-a7-35-test-setup) to get some ideas what a project setup might look like
/neorv32/trunk/docs/NEORV32.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neorv32/trunk/rtl/core/neorv32_application_image.vhd
6,7 → 6,7
 
package neorv32_application_image is
 
type application_init_image_t is array (0 to 1068) of std_ulogic_vector(31 downto 0);
type application_init_image_t is array (0 to 1071) of std_ulogic_vector(31 downto 0);
constant application_init_image : application_init_image_t := (
00000000 => x"00000093",
00000001 => x"00000113",
19,68 → 19,68
00000008 => x"00000493",
00000009 => x"00000713",
00000010 => x"00000793",
00000011 => x"00000597",
00000012 => x"10c58593",
00000013 => x"30559073",
00000014 => x"00000813",
00000015 => x"00000893",
00000016 => x"00000913",
00000017 => x"00000993",
00000018 => x"00000a13",
00000019 => x"00000a93",
00000020 => x"00000b13",
00000021 => x"00000b93",
00000022 => x"00000c13",
00000023 => x"00000c93",
00000024 => x"00000d13",
00000025 => x"00000d93",
00000026 => x"00000e13",
00000027 => x"00000e93",
00000028 => x"00000f13",
00000029 => x"00000f93",
00000030 => x"00002537",
00000031 => x"80050513",
00000032 => x"30051073",
00000033 => x"30401073",
00000034 => x"80002117",
00000035 => x"f7410113",
00000036 => x"ffc17113",
00000037 => x"00010413",
00000038 => x"80000197",
00000039 => x"76818193",
00000040 => x"f0000593",
00000041 => x"0005a023",
00000042 => x"00458593",
00000043 => x"feb01ce3",
00000044 => x"80000597",
00000045 => x"f5058593",
00000046 => x"87418613",
00000047 => x"00c5d863",
00000048 => x"00058023",
00000049 => x"00158593",
00000050 => x"ff5ff06f",
00000051 => x"00001597",
00000052 => x"fe458593",
00000053 => x"80000617",
00000054 => x"f2c60613",
00000055 => x"80000697",
00000056 => x"f2468693",
00000057 => x"00d65c63",
00000058 => x"00058703",
00000059 => x"00e60023",
00000060 => x"00158593",
00000061 => x"00160613",
00000062 => x"fedff06f",
00000063 => x"00000513",
00000064 => x"00000593",
00000065 => x"b0001073",
00000066 => x"b8001073",
00000067 => x"b0201073",
00000068 => x"b8201073",
00000069 => x"3063d073",
00000070 => x"32001073",
00000071 => x"80000637",
00000072 => x"34261073",
00000011 => x"00000517",
00000012 => x"10c50513",
00000013 => x"30551073",
00000014 => x"34151073",
00000015 => x"34301073",
00000016 => x"34201073",
00000017 => x"30001073",
00000018 => x"30401073",
00000019 => x"30601073",
00000020 => x"ffa00593",
00000021 => x"32059073",
00000022 => x"b0001073",
00000023 => x"b8001073",
00000024 => x"b0201073",
00000025 => x"b8201073",
00000026 => x"00000813",
00000027 => x"00000893",
00000028 => x"00000913",
00000029 => x"00000993",
00000030 => x"00000a13",
00000031 => x"00000a93",
00000032 => x"00000b13",
00000033 => x"00000b93",
00000034 => x"00000c13",
00000035 => x"00000c93",
00000036 => x"00000d13",
00000037 => x"00000d93",
00000038 => x"00000e13",
00000039 => x"00000e93",
00000040 => x"00000f13",
00000041 => x"00000f93",
00000042 => x"80002117",
00000043 => x"f5410113",
00000044 => x"ffc17113",
00000045 => x"00010413",
00000046 => x"80000197",
00000047 => x"74818193",
00000048 => x"f0000593",
00000049 => x"0005a023",
00000050 => x"00458593",
00000051 => x"feb01ce3",
00000052 => x"80000597",
00000053 => x"f3058593",
00000054 => x"87418613",
00000055 => x"00c5d863",
00000056 => x"00058023",
00000057 => x"00158593",
00000058 => x"ff5ff06f",
00000059 => x"00001597",
00000060 => x"fd058593",
00000061 => x"80000617",
00000062 => x"f0c60613",
00000063 => x"80000697",
00000064 => x"f0468693",
00000065 => x"00d65c63",
00000066 => x"00058703",
00000067 => x"00e60023",
00000068 => x"00158593",
00000069 => x"00160613",
00000070 => x"fedff06f",
00000071 => x"00000513",
00000072 => x"00000593",
00000073 => x"060000ef",
00000074 => x"30047073",
00000075 => x"00000013",
111,19 → 111,19
00000100 => x"00000593",
00000101 => x"b0050513",
00000102 => x"00112623",
00000103 => x"248000ef",
00000104 => x"201000ef",
00000103 => x"730000ef",
00000104 => x"16d000ef",
00000105 => x"02050063",
00000106 => x"151000ef",
00000106 => x"4a8000ef",
00000107 => x"00000513",
00000108 => x"1a5000ef",
00000108 => x"4fc000ef",
00000109 => x"00001537",
00000110 => x"d4450513",
00000111 => x"298000ef",
00000110 => x"d5050513",
00000111 => x"780000ef",
00000112 => x"020000ef",
00000113 => x"00001537",
00000114 => x"d2050513",
00000115 => x"288000ef",
00000114 => x"d2c50513",
00000115 => x"770000ef",
00000116 => x"00c12083",
00000117 => x"00000513",
00000118 => x"01010113",
133,949 → 133,952
00000122 => x"00812423",
00000123 => x"00112623",
00000124 => x"00000413",
00000125 => x"1bd000ef",
00000125 => x"129000ef",
00000126 => x"0ff47513",
00000127 => x"1b5000ef",
00000127 => x"121000ef",
00000128 => x"0c800513",
00000129 => x"43c000ef",
00000129 => x"14d000ef",
00000130 => x"00140413",
00000131 => x"fedff06f",
00000132 => x"fd010113",
00000133 => x"02812423",
00000134 => x"02912223",
00000135 => x"03212023",
00000136 => x"01312e23",
00000137 => x"01412c23",
00000138 => x"02112623",
00000139 => x"01512a23",
00000140 => x"00001a37",
00000141 => x"00050493",
00000142 => x"00058413",
00000143 => x"00058523",
00000144 => x"00000993",
00000145 => x"00410913",
00000146 => x"d60a0a13",
00000147 => x"00a00593",
00000148 => x"00048513",
00000149 => x"269000ef",
00000150 => x"00aa0533",
00000151 => x"00054783",
00000152 => x"01390ab3",
00000153 => x"00048513",
00000154 => x"00fa8023",
00000155 => x"00a00593",
00000156 => x"205000ef",
00000157 => x"00198993",
00000158 => x"00a00793",
00000159 => x"00050493",
00000160 => x"fcf996e3",
00000161 => x"00090693",
00000162 => x"00900713",
00000163 => x"03000613",
00000164 => x"0096c583",
00000165 => x"00070793",
00000166 => x"fff70713",
00000167 => x"01071713",
00000168 => x"01075713",
00000169 => x"00c59a63",
00000170 => x"000684a3",
00000171 => x"fff68693",
00000172 => x"fe0710e3",
00000173 => x"00000793",
00000174 => x"00f907b3",
00000175 => x"00000593",
00000176 => x"0007c703",
00000177 => x"00070c63",
00000178 => x"00158693",
00000179 => x"00b405b3",
00000180 => x"00e58023",
00000181 => x"01069593",
00000182 => x"0105d593",
00000183 => x"fff78713",
00000184 => x"02f91863",
00000185 => x"00b40433",
00000186 => x"00040023",
00000187 => x"02c12083",
00000188 => x"02812403",
00000189 => x"02412483",
00000190 => x"02012903",
00000191 => x"01c12983",
00000192 => x"01812a03",
00000193 => x"01412a83",
00000194 => x"03010113",
00000195 => x"00008067",
00000196 => x"00070793",
00000197 => x"fadff06f",
00000198 => x"00001637",
00000199 => x"00758693",
00000200 => x"00000713",
00000201 => x"d6c60613",
00000202 => x"02000813",
00000203 => x"00e557b3",
00000204 => x"00f7f793",
00000205 => x"00f607b3",
00000206 => x"0007c783",
00000207 => x"00470713",
00000208 => x"fff68693",
00000209 => x"00f680a3",
00000210 => x"ff0712e3",
00000211 => x"00058423",
00000212 => x"00008067",
00000213 => x"fa002023",
00000214 => x"fe002703",
00000215 => x"00151513",
00000216 => x"00000793",
00000217 => x"04a77463",
00000218 => x"000016b7",
00000219 => x"00000713",
00000220 => x"ffe68693",
00000221 => x"04f6e663",
00000222 => x"00367613",
00000223 => x"0035f593",
00000224 => x"fff78793",
00000225 => x"01461613",
00000226 => x"00c7e7b3",
00000227 => x"01659593",
00000228 => x"01871713",
00000229 => x"00b7e7b3",
00000230 => x"00e7e7b3",
00000231 => x"10000737",
00000232 => x"00e7e7b3",
00000233 => x"faf02023",
00000234 => x"00008067",
00000235 => x"00178793",
00000236 => x"01079793",
00000237 => x"40a70733",
00000238 => x"0107d793",
00000239 => x"fa9ff06f",
00000240 => x"ffe70513",
00000241 => x"0fd57513",
00000242 => x"00051a63",
00000243 => x"0037d793",
00000244 => x"00170713",
00000245 => x"0ff77713",
00000246 => x"f9dff06f",
00000247 => x"0017d793",
00000248 => x"ff1ff06f",
00000249 => x"f71ff06f",
00000250 => x"fa002783",
00000251 => x"fe07cee3",
00000252 => x"faa02223",
00000253 => x"00008067",
00000254 => x"ff1ff06f",
00000255 => x"ff010113",
00000256 => x"00812423",
00000257 => x"01212023",
00000258 => x"00112623",
00000259 => x"00912223",
00000260 => x"00050413",
00000261 => x"00a00913",
00000262 => x"00044483",
00000263 => x"00140413",
00000264 => x"00049e63",
00000265 => x"00c12083",
00000266 => x"00812403",
00000267 => x"00412483",
00000268 => x"00012903",
00000269 => x"01010113",
00000270 => x"00008067",
00000271 => x"01249663",
00000272 => x"00d00513",
00000273 => x"fa5ff0ef",
00000274 => x"00048513",
00000275 => x"f9dff0ef",
00000276 => x"fc9ff06f",
00000277 => x"fa9ff06f",
00000278 => x"fa010113",
00000279 => x"04f12a23",
00000280 => x"04410793",
00000281 => x"02812c23",
00000282 => x"03212823",
00000283 => x"03412423",
00000284 => x"03512223",
00000285 => x"03612023",
00000286 => x"01712e23",
00000287 => x"01812c23",
00000288 => x"01912a23",
00000289 => x"02112e23",
00000290 => x"02912a23",
00000291 => x"03312623",
00000292 => x"00050413",
00000293 => x"04b12223",
00000294 => x"04c12423",
00000295 => x"04d12623",
00000296 => x"04e12823",
00000297 => x"05012c23",
00000298 => x"05112e23",
00000299 => x"00f12023",
00000300 => x"02500a13",
00000301 => x"00a00a93",
00000302 => x"07300913",
00000303 => x"07500b13",
00000304 => x"07800b93",
00000305 => x"06300c13",
00000306 => x"06900c93",
00000307 => x"00044483",
00000308 => x"02048063",
00000309 => x"0f449a63",
00000310 => x"00144783",
00000311 => x"00240993",
00000312 => x"07278463",
00000313 => x"04f96063",
00000314 => x"07878e63",
00000315 => x"09978863",
00000316 => x"03c12083",
00000317 => x"03812403",
00000318 => x"03412483",
00000319 => x"03012903",
00000320 => x"02c12983",
00000321 => x"02812a03",
00000322 => x"02412a83",
00000323 => x"02012b03",
00000324 => x"01c12b83",
00000325 => x"01812c03",
00000326 => x"01412c83",
00000327 => x"06010113",
00000328 => x"00008067",
00000329 => x"09678663",
00000330 => x"fd7794e3",
00000331 => x"00012783",
00000332 => x"00410593",
00000333 => x"0007a503",
00000334 => x"00478713",
00000335 => x"00e12023",
00000336 => x"dd9ff0ef",
00000337 => x"0640006f",
00000338 => x"00012783",
00000339 => x"0007a503",
00000340 => x"00478713",
00000341 => x"00e12023",
00000342 => x"ea5ff0ef",
00000343 => x"00098413",
00000344 => x"f6dff06f",
00000345 => x"00012783",
00000346 => x"0007c503",
00000347 => x"00478713",
00000348 => x"00e12023",
00000349 => x"e75ff0ef",
00000350 => x"fe5ff06f",
00000351 => x"00012783",
00000352 => x"0007a403",
00000353 => x"00478713",
00000354 => x"00e12023",
00000355 => x"00045863",
00000356 => x"02d00513",
00000357 => x"40800433",
00000358 => x"e51ff0ef",
00000359 => x"00410593",
00000360 => x"00040513",
00000361 => x"c6dff0ef",
00000362 => x"00410513",
00000363 => x"fadff06f",
00000364 => x"00012783",
00000365 => x"00410593",
00000366 => x"00478713",
00000367 => x"0007a503",
00000368 => x"00e12023",
00000369 => x"fe1ff06f",
00000370 => x"01549663",
00000371 => x"00d00513",
00000372 => x"e19ff0ef",
00000373 => x"00140993",
00000374 => x"00048513",
00000375 => x"f99ff06f",
00000376 => x"fd010113",
00000377 => x"00112623",
00000378 => x"00b12a23",
00000379 => x"00c12c23",
00000380 => x"00d12e23",
00000381 => x"02e12023",
00000382 => x"02f12223",
00000383 => x"03012423",
00000384 => x"03112623",
00000385 => x"e55ff0ef",
00000386 => x"00c12083",
00000387 => x"03010113",
00000388 => x"00008067",
00000389 => x"ff010113",
00000390 => x"c80026f3",
00000391 => x"c0002773",
00000392 => x"c80027f3",
00000393 => x"fed79ae3",
00000394 => x"00e12023",
00000395 => x"00f12223",
00000396 => x"00012503",
00000397 => x"00412583",
00000398 => x"01010113",
00000399 => x"00008067",
00000400 => x"fe010113",
00000401 => x"00112e23",
00000402 => x"00812c23",
00000403 => x"00912a23",
00000404 => x"00a12623",
00000405 => x"fc1ff0ef",
00000406 => x"00050493",
00000407 => x"fe002503",
00000408 => x"00058413",
00000409 => x"3e800593",
00000410 => x"60c000ef",
00000411 => x"00c12603",
00000412 => x"00000693",
00000413 => x"00000593",
00000414 => x"564000ef",
00000415 => x"009504b3",
00000416 => x"00a4b533",
00000417 => x"00858433",
00000418 => x"00850433",
00000419 => x"f89ff0ef",
00000420 => x"fe85eee3",
00000421 => x"00b41463",
00000422 => x"fe956ae3",
00000423 => x"01c12083",
00000424 => x"01812403",
00000425 => x"01412483",
00000426 => x"02010113",
00000427 => x"00008067",
00000428 => x"fc010113",
00000429 => x"02112e23",
00000430 => x"02512c23",
00000431 => x"02612a23",
00000432 => x"02712823",
00000433 => x"02a12623",
00000434 => x"02b12423",
00000435 => x"02c12223",
00000436 => x"02d12023",
00000437 => x"00e12e23",
00000438 => x"00f12c23",
00000439 => x"01012a23",
00000440 => x"01112823",
00000441 => x"01c12623",
00000442 => x"01d12423",
00000443 => x"01e12223",
00000444 => x"01f12023",
00000445 => x"34102773",
00000446 => x"34071073",
00000447 => x"342027f3",
00000448 => x"0807ca63",
00000449 => x"00071683",
00000450 => x"00300593",
00000451 => x"0036f693",
00000452 => x"00270613",
00000453 => x"00b69463",
00000454 => x"00470613",
00000455 => x"34161073",
00000456 => x"00b00713",
00000457 => x"04f77c63",
00000458 => x"000017b7",
00000459 => x"93078793",
00000460 => x"000780e7",
00000461 => x"03c12083",
00000462 => x"03812283",
00000463 => x"03412303",
00000464 => x"03012383",
00000465 => x"02c12503",
00000466 => x"02812583",
00000467 => x"02412603",
00000468 => x"02012683",
00000469 => x"01c12703",
00000470 => x"01812783",
00000471 => x"01412803",
00000472 => x"01012883",
00000473 => x"00c12e03",
00000474 => x"00812e83",
00000475 => x"00412f03",
00000476 => x"00012f83",
00000477 => x"04010113",
00000478 => x"30200073",
00000479 => x"00001737",
00000480 => x"00279793",
00000481 => x"d8070713",
00000482 => x"00e787b3",
00000483 => x"0007a783",
00000484 => x"00078067",
00000485 => x"80000737",
00000486 => x"ffd74713",
00000487 => x"00e787b3",
00000488 => x"01c00713",
00000489 => x"f8f762e3",
00000490 => x"00001737",
00000491 => x"00279793",
00000492 => x"db070713",
00000493 => x"00e787b3",
00000494 => x"0007a783",
00000495 => x"00078067",
00000496 => x"800007b7",
00000497 => x"0007a783",
00000498 => x"f69ff06f",
00000499 => x"800007b7",
00000500 => x"0047a783",
00000501 => x"f5dff06f",
00000502 => x"800007b7",
00000503 => x"0087a783",
00000504 => x"f51ff06f",
00000505 => x"800007b7",
00000506 => x"00c7a783",
00000507 => x"f45ff06f",
00000508 => x"8101a783",
00000509 => x"f3dff06f",
00000510 => x"8141a783",
00000511 => x"f35ff06f",
00000512 => x"8181a783",
00000513 => x"f2dff06f",
00000514 => x"81c1a783",
00000515 => x"f25ff06f",
00000516 => x"8201a783",
00000517 => x"f1dff06f",
00000518 => x"8241a783",
00000519 => x"f15ff06f",
00000520 => x"8281a783",
00000521 => x"f0dff06f",
00000522 => x"82c1a783",
00000523 => x"f05ff06f",
00000524 => x"8301a783",
00000525 => x"efdff06f",
00000526 => x"8341a783",
00000527 => x"ef5ff06f",
00000528 => x"8381a783",
00000529 => x"eedff06f",
00000530 => x"83c1a783",
00000531 => x"ee5ff06f",
00000532 => x"8401a783",
00000533 => x"eddff06f",
00000534 => x"8441a783",
00000535 => x"ed5ff06f",
00000536 => x"8481a783",
00000537 => x"ecdff06f",
00000538 => x"84c1a783",
00000539 => x"ec5ff06f",
00000540 => x"8501a783",
00000541 => x"ebdff06f",
00000542 => x"8541a783",
00000543 => x"eb5ff06f",
00000544 => x"8581a783",
00000545 => x"eadff06f",
00000546 => x"85c1a783",
00000547 => x"ea5ff06f",
00000548 => x"8601a783",
00000549 => x"e9dff06f",
00000550 => x"8641a783",
00000551 => x"e95ff06f",
00000552 => x"8681a783",
00000553 => x"e8dff06f",
00000554 => x"86c1a783",
00000555 => x"e85ff06f",
00000556 => x"8701a783",
00000557 => x"e7dff06f",
00000558 => x"00000000",
00000559 => x"00000000",
00000560 => x"fe010113",
00000561 => x"01212823",
00000562 => x"00050913",
00000563 => x"00001537",
00000564 => x"00912a23",
00000565 => x"e2450513",
00000566 => x"000014b7",
00000567 => x"00812c23",
00000568 => x"01312623",
00000569 => x"00112e23",
00000570 => x"01c00413",
00000571 => x"b69ff0ef",
00000572 => x"0a048493",
00000573 => x"ffc00993",
00000574 => x"008957b3",
00000575 => x"00f7f793",
00000576 => x"00f487b3",
00000577 => x"0007c503",
00000578 => x"ffc40413",
00000579 => x"aedff0ef",
00000580 => x"ff3414e3",
00000581 => x"01c12083",
00000582 => x"01812403",
00000583 => x"01412483",
00000584 => x"01012903",
00000585 => x"00c12983",
00000586 => x"02010113",
00000587 => x"00008067",
00000588 => x"00001537",
00000589 => x"ff010113",
00000590 => x"e2850513",
00000591 => x"00112623",
00000592 => x"00812423",
00000593 => x"00912223",
00000594 => x"b0dff0ef",
00000595 => x"34202473",
00000596 => x"00900713",
00000597 => x"00f47793",
00000598 => x"05778493",
00000599 => x"00f76463",
00000600 => x"03078493",
00000601 => x"00b00793",
00000602 => x"0087ee63",
00000603 => x"00001737",
00000604 => x"00241793",
00000605 => x"fb470713",
00000606 => x"00e787b3",
00000607 => x"0007a783",
00000608 => x"00078067",
00000609 => x"800007b7",
00000610 => x"00b78713",
00000611 => x"12e40663",
00000612 => x"02876663",
00000613 => x"00378713",
00000614 => x"10e40463",
00000615 => x"00778793",
00000616 => x"10f40663",
00000617 => x"00001537",
00000618 => x"f8850513",
00000619 => x"aa9ff0ef",
00000620 => x"00040513",
00000621 => x"f0dff0ef",
00000622 => x"0380006f",
00000623 => x"ff07c793",
00000624 => x"00f407b3",
00000625 => x"00f00713",
00000626 => x"fcf76ee3",
00000627 => x"00001537",
00000628 => x"f7850513",
00000629 => x"a81ff0ef",
00000630 => x"00048513",
00000631 => x"a1dff0ef",
00000632 => x"0100006f",
00000633 => x"00001537",
00000634 => x"e3050513",
00000635 => x"a69ff0ef",
00000636 => x"00001537",
00000637 => x"fa050513",
00000638 => x"a5dff0ef",
00000639 => x"34002573",
00000640 => x"ec1ff0ef",
00000641 => x"00001537",
00000642 => x"fa850513",
00000643 => x"a49ff0ef",
00000644 => x"34302573",
00000645 => x"eadff0ef",
00000646 => x"00812403",
00000647 => x"00c12083",
00000648 => x"00412483",
00000649 => x"00001537",
00000650 => x"01050513",
00000651 => x"01010113",
00000652 => x"a25ff06f",
00000653 => x"00001537",
00000654 => x"e5050513",
00000655 => x"fb1ff06f",
00000656 => x"00001537",
00000657 => x"e6c50513",
00000658 => x"fa5ff06f",
00000659 => x"00001537",
00000660 => x"e8050513",
00000661 => x"f99ff06f",
00000662 => x"00001537",
00000663 => x"e8c50513",
00000664 => x"f8dff06f",
00000665 => x"00001537",
00000666 => x"ea450513",
00000667 => x"f81ff06f",
00000668 => x"00001537",
00000669 => x"eb850513",
00000670 => x"f75ff06f",
00000671 => x"00001537",
00000672 => x"ed450513",
00000673 => x"f69ff06f",
00000674 => x"00001537",
00000675 => x"ee850513",
00000676 => x"f5dff06f",
00000677 => x"00001537",
00000678 => x"f0850513",
00000679 => x"f51ff06f",
00000680 => x"00001537",
00000681 => x"f2850513",
00000682 => x"f45ff06f",
00000683 => x"00001537",
00000684 => x"f4450513",
00000685 => x"f39ff06f",
00000686 => x"00001537",
00000687 => x"f5c50513",
00000688 => x"f2dff06f",
00000689 => x"01f00793",
00000690 => x"02a7e463",
00000691 => x"800007b7",
00000692 => x"00078793",
00000693 => x"00251513",
00000694 => x"00a78533",
00000695 => x"000017b7",
00000696 => x"93078793",
00000697 => x"00f52023",
00000698 => x"00000513",
00000699 => x"00008067",
00000700 => x"00100513",
00000701 => x"00008067",
00000702 => x"ff010113",
00000703 => x"00112623",
00000704 => x"00812423",
00000705 => x"00912223",
00000706 => x"301027f3",
00000707 => x"00079863",
00000708 => x"00001537",
00000709 => x"fe450513",
00000710 => x"93dff0ef",
00000711 => x"6b000793",
00000712 => x"30579073",
00000713 => x"00000413",
00000714 => x"01d00493",
00000715 => x"00040513",
00000716 => x"00140413",
00000717 => x"0ff47413",
00000718 => x"f8dff0ef",
00000719 => x"fe9418e3",
00000720 => x"00c12083",
00000721 => x"00812403",
00000722 => x"00412483",
00000723 => x"01010113",
00000724 => x"00008067",
00000725 => x"ff010113",
00000726 => x"00112623",
00000727 => x"00812423",
00000728 => x"30102673",
00000729 => x"400005b7",
00000730 => x"10058593",
00000731 => x"00b677b3",
00000732 => x"00000413",
00000733 => x"00b78c63",
00000734 => x"00100413",
00000735 => x"00051863",
00000736 => x"00001537",
00000737 => x"01850513",
00000738 => x"a59ff0ef",
00000739 => x"00c12083",
00000740 => x"00040513",
00000741 => x"00812403",
00000742 => x"01010113",
00000743 => x"00008067",
00000744 => x"fe802503",
00000745 => x"01055513",
00000746 => x"00157513",
00000747 => x"00008067",
00000748 => x"f8a02223",
00000749 => x"00008067",
00000750 => x"00050613",
00000751 => x"00000513",
00000752 => x"0015f693",
00000753 => x"00068463",
00000754 => x"00c50533",
00000755 => x"0015d593",
00000756 => x"00161613",
00000757 => x"fe0596e3",
00000758 => x"00008067",
00000759 => x"00050313",
00000760 => x"ff010113",
00000761 => x"00060513",
00000762 => x"00068893",
00000763 => x"00112623",
00000764 => x"00030613",
00000765 => x"00050693",
00000766 => x"00000713",
00000767 => x"00000793",
00000768 => x"00000813",
00000769 => x"0016fe13",
00000770 => x"00171e93",
00000771 => x"000e0c63",
00000772 => x"01060e33",
00000773 => x"010e3833",
00000774 => x"00e787b3",
00000775 => x"00f807b3",
00000776 => x"000e0813",
00000777 => x"01f65713",
00000778 => x"0016d693",
00000779 => x"00eee733",
00000780 => x"00161613",
00000781 => x"fc0698e3",
00000782 => x"00058663",
00000783 => x"f7dff0ef",
00000784 => x"00a787b3",
00000785 => x"00088a63",
00000786 => x"00030513",
00000787 => x"00088593",
00000788 => x"f69ff0ef",
00000789 => x"00f507b3",
00000790 => x"00c12083",
00000791 => x"00080513",
00000792 => x"00078593",
00000793 => x"01010113",
00000794 => x"00008067",
00000795 => x"06054063",
00000796 => x"0605c663",
00000797 => x"00058613",
00000798 => x"00050593",
00000799 => x"fff00513",
00000800 => x"02060c63",
00000801 => x"00100693",
00000802 => x"00b67a63",
00000803 => x"00c05863",
00000804 => x"00161613",
00000805 => x"00169693",
00000806 => x"feb66ae3",
00000807 => x"00000513",
00000808 => x"00c5e663",
00000809 => x"40c585b3",
00000810 => x"00d56533",
00000811 => x"0016d693",
00000812 => x"00165613",
00000813 => x"fe0696e3",
00000814 => x"00008067",
00000815 => x"00008293",
00000816 => x"fb5ff0ef",
00000817 => x"00058513",
00000818 => x"00028067",
00000819 => x"40a00533",
00000820 => x"00b04863",
00000821 => x"40b005b3",
00000822 => x"f9dff06f",
00000823 => x"40b005b3",
00000824 => x"00008293",
00000825 => x"f91ff0ef",
00000826 => x"40a00533",
00000827 => x"00028067",
00000828 => x"00008293",
00000829 => x"0005ca63",
00000830 => x"00054c63",
00000831 => x"f79ff0ef",
00000832 => x"00058513",
00000833 => x"00028067",
00000834 => x"40b005b3",
00000835 => x"fe0558e3",
00000836 => x"40a00533",
00000837 => x"f61ff0ef",
00000838 => x"40b00533",
00000839 => x"00028067",
00000840 => x"6f727245",
00000841 => x"4e202172",
00000842 => x"5047206f",
00000843 => x"75204f49",
00000844 => x"2074696e",
00000845 => x"746e7973",
00000846 => x"69736568",
00000847 => x"2164657a",
00000848 => x"0000000a",
00000849 => x"6e696c42",
00000850 => x"676e696b",
00000851 => x"44454c20",
00000852 => x"6d656420",
00000853 => x"7270206f",
00000854 => x"6172676f",
00000855 => x"00000a6d",
00000856 => x"33323130",
00000857 => x"37363534",
00000858 => x"00003938",
00000859 => x"33323130",
00000860 => x"37363534",
00000861 => x"62613938",
00000862 => x"66656463",
00000863 => x"00000000",
00000864 => x"000007c0",
00000865 => x"000007cc",
00000866 => x"000007d8",
00000867 => x"000007e4",
00000868 => x"000007f0",
00000869 => x"000007f8",
00000870 => x"00000800",
00000871 => x"00000808",
00000872 => x"00000810",
00000873 => x"00000728",
00000874 => x"00000728",
00000875 => x"00000818",
00000876 => x"00000820",
00000877 => x"00000728",
00000878 => x"00000728",
00000879 => x"00000728",
00000880 => x"00000828",
00000881 => x"00000728",
00000882 => x"00000728",
00000883 => x"00000728",
00000884 => x"00000830",
00000885 => x"00000728",
00000886 => x"00000728",
00000887 => x"00000728",
00000888 => x"00000728",
00000889 => x"00000838",
00000890 => x"00000840",
00000891 => x"00000848",
00000892 => x"00000850",
00000893 => x"00000858",
00000894 => x"00000860",
00000895 => x"00000868",
00000896 => x"00000870",
00000897 => x"00000878",
00000898 => x"00000880",
00000899 => x"00000888",
00000900 => x"00000890",
00000901 => x"00000898",
00000902 => x"000008a0",
00000903 => x"000008a8",
00000904 => x"000008b0",
00000905 => x"00007830",
00000906 => x"4554523c",
00000907 => x"0000203e",
00000908 => x"74736e49",
00000909 => x"74637572",
00000910 => x"206e6f69",
00000911 => x"72646461",
00000912 => x"20737365",
00000913 => x"6173696d",
00000914 => x"6e67696c",
00000915 => x"00006465",
00000916 => x"74736e49",
00000917 => x"74637572",
00000918 => x"206e6f69",
00000919 => x"65636361",
00000920 => x"66207373",
00000921 => x"746c7561",
00000922 => x"00000000",
00000923 => x"656c6c49",
00000924 => x"206c6167",
00000925 => x"74736e69",
00000926 => x"74637572",
00000927 => x"006e6f69",
00000928 => x"61657242",
00000929 => x"696f706b",
00000930 => x"0000746e",
00000931 => x"64616f4c",
00000932 => x"64646120",
00000933 => x"73736572",
00000934 => x"73696d20",
00000935 => x"67696c61",
00000936 => x"0064656e",
00000937 => x"64616f4c",
00000938 => x"63636120",
00000939 => x"20737365",
00000940 => x"6c756166",
00000941 => x"00000074",
00000942 => x"726f7453",
00000943 => x"64612065",
00000944 => x"73657264",
00000945 => x"696d2073",
00000946 => x"696c6173",
00000947 => x"64656e67",
00000948 => x"00000000",
00000949 => x"726f7453",
00000950 => x"63612065",
00000951 => x"73736563",
00000952 => x"75616620",
00000953 => x"0000746c",
00000954 => x"69766e45",
00000955 => x"6d6e6f72",
00000956 => x"20746e65",
00000957 => x"6c6c6163",
00000958 => x"6f726620",
00000959 => x"2d55206d",
00000960 => x"65646f6d",
00000961 => x"00000000",
00000962 => x"69766e45",
00000963 => x"6d6e6f72",
00000964 => x"20746e65",
00000965 => x"6c6c6163",
00000966 => x"6f726620",
00000967 => x"2d4d206d",
00000968 => x"65646f6d",
00000969 => x"00000000",
00000970 => x"6863614d",
00000971 => x"20656e69",
00000972 => x"74666f73",
00000973 => x"65726177",
00000974 => x"746e6920",
00000975 => x"75727265",
00000976 => x"00007470",
00000977 => x"6863614d",
00000978 => x"20656e69",
00000979 => x"656d6974",
00000980 => x"6e692072",
00000981 => x"72726574",
00000982 => x"00747075",
00000983 => x"6863614d",
00000984 => x"20656e69",
00000985 => x"65747865",
00000986 => x"6c616e72",
00000987 => x"746e6920",
00000988 => x"75727265",
00000989 => x"00007470",
00000990 => x"74736146",
00000991 => x"746e6920",
00000992 => x"75727265",
00000993 => x"00207470",
00000994 => x"6e6b6e55",
00000995 => x"206e776f",
00000996 => x"70617274",
00000997 => x"75616320",
00000998 => x"203a6573",
00000132 => x"fc010113",
00000133 => x"02112e23",
00000134 => x"02512c23",
00000135 => x"02612a23",
00000136 => x"02712823",
00000137 => x"02a12623",
00000138 => x"02b12423",
00000139 => x"02c12223",
00000140 => x"02d12023",
00000141 => x"00e12e23",
00000142 => x"00f12c23",
00000143 => x"01012a23",
00000144 => x"01112823",
00000145 => x"01c12623",
00000146 => x"01d12423",
00000147 => x"01e12223",
00000148 => x"01f12023",
00000149 => x"34102773",
00000150 => x"34071073",
00000151 => x"342027f3",
00000152 => x"0807c863",
00000153 => x"00071683",
00000154 => x"00300593",
00000155 => x"0036f693",
00000156 => x"00270613",
00000157 => x"00b69463",
00000158 => x"00470613",
00000159 => x"34161073",
00000160 => x"00b00713",
00000161 => x"04f77a63",
00000162 => x"48c00793",
00000163 => x"000780e7",
00000164 => x"03c12083",
00000165 => x"03812283",
00000166 => x"03412303",
00000167 => x"03012383",
00000168 => x"02c12503",
00000169 => x"02812583",
00000170 => x"02412603",
00000171 => x"02012683",
00000172 => x"01c12703",
00000173 => x"01812783",
00000174 => x"01412803",
00000175 => x"01012883",
00000176 => x"00c12e03",
00000177 => x"00812e83",
00000178 => x"00412f03",
00000179 => x"00012f83",
00000180 => x"04010113",
00000181 => x"30200073",
00000182 => x"00001737",
00000183 => x"00279793",
00000184 => x"d6c70713",
00000185 => x"00e787b3",
00000186 => x"0007a783",
00000187 => x"00078067",
00000188 => x"80000737",
00000189 => x"ffd74713",
00000190 => x"00e787b3",
00000191 => x"01c00713",
00000192 => x"f8f764e3",
00000193 => x"00001737",
00000194 => x"00279793",
00000195 => x"d9c70713",
00000196 => x"00e787b3",
00000197 => x"0007a783",
00000198 => x"00078067",
00000199 => x"800007b7",
00000200 => x"0007a783",
00000201 => x"f69ff06f",
00000202 => x"800007b7",
00000203 => x"0047a783",
00000204 => x"f5dff06f",
00000205 => x"800007b7",
00000206 => x"0087a783",
00000207 => x"f51ff06f",
00000208 => x"800007b7",
00000209 => x"00c7a783",
00000210 => x"f45ff06f",
00000211 => x"8101a783",
00000212 => x"f3dff06f",
00000213 => x"8141a783",
00000214 => x"f35ff06f",
00000215 => x"8181a783",
00000216 => x"f2dff06f",
00000217 => x"81c1a783",
00000218 => x"f25ff06f",
00000219 => x"8201a783",
00000220 => x"f1dff06f",
00000221 => x"8241a783",
00000222 => x"f15ff06f",
00000223 => x"8281a783",
00000224 => x"f0dff06f",
00000225 => x"82c1a783",
00000226 => x"f05ff06f",
00000227 => x"8301a783",
00000228 => x"efdff06f",
00000229 => x"8341a783",
00000230 => x"ef5ff06f",
00000231 => x"8381a783",
00000232 => x"eedff06f",
00000233 => x"83c1a783",
00000234 => x"ee5ff06f",
00000235 => x"8401a783",
00000236 => x"eddff06f",
00000237 => x"8441a783",
00000238 => x"ed5ff06f",
00000239 => x"8481a783",
00000240 => x"ecdff06f",
00000241 => x"84c1a783",
00000242 => x"ec5ff06f",
00000243 => x"8501a783",
00000244 => x"ebdff06f",
00000245 => x"8541a783",
00000246 => x"eb5ff06f",
00000247 => x"8581a783",
00000248 => x"eadff06f",
00000249 => x"85c1a783",
00000250 => x"ea5ff06f",
00000251 => x"8601a783",
00000252 => x"e9dff06f",
00000253 => x"8641a783",
00000254 => x"e95ff06f",
00000255 => x"8681a783",
00000256 => x"e8dff06f",
00000257 => x"86c1a783",
00000258 => x"e85ff06f",
00000259 => x"8701a783",
00000260 => x"e7dff06f",
00000261 => x"00000000",
00000262 => x"00000000",
00000263 => x"fe010113",
00000264 => x"01212823",
00000265 => x"00050913",
00000266 => x"00001537",
00000267 => x"00912a23",
00000268 => x"e1050513",
00000269 => x"000014b7",
00000270 => x"00812c23",
00000271 => x"01312623",
00000272 => x"00112e23",
00000273 => x"01c00413",
00000274 => x"4f4000ef",
00000275 => x"08c48493",
00000276 => x"ffc00993",
00000277 => x"008957b3",
00000278 => x"00f7f793",
00000279 => x"00f487b3",
00000280 => x"0007c503",
00000281 => x"ffc40413",
00000282 => x"478000ef",
00000283 => x"ff3414e3",
00000284 => x"01c12083",
00000285 => x"01812403",
00000286 => x"01412483",
00000287 => x"01012903",
00000288 => x"00c12983",
00000289 => x"02010113",
00000290 => x"00008067",
00000291 => x"00001537",
00000292 => x"ff010113",
00000293 => x"e1450513",
00000294 => x"00112623",
00000295 => x"00812423",
00000296 => x"00912223",
00000297 => x"498000ef",
00000298 => x"34202473",
00000299 => x"00900713",
00000300 => x"00f47793",
00000301 => x"05778493",
00000302 => x"00f76463",
00000303 => x"03078493",
00000304 => x"00b00793",
00000305 => x"0087ee63",
00000306 => x"00001737",
00000307 => x"00241793",
00000308 => x"fa070713",
00000309 => x"00e787b3",
00000310 => x"0007a783",
00000311 => x"00078067",
00000312 => x"800007b7",
00000313 => x"00b78713",
00000314 => x"12e40663",
00000315 => x"02876663",
00000316 => x"00378713",
00000317 => x"10e40463",
00000318 => x"00778793",
00000319 => x"10f40663",
00000320 => x"00001537",
00000321 => x"f7450513",
00000322 => x"434000ef",
00000323 => x"00040513",
00000324 => x"f0dff0ef",
00000325 => x"0380006f",
00000326 => x"ff07c793",
00000327 => x"00f407b3",
00000328 => x"00f00713",
00000329 => x"fcf76ee3",
00000330 => x"00001537",
00000331 => x"f6450513",
00000332 => x"40c000ef",
00000333 => x"00048513",
00000334 => x"3a8000ef",
00000335 => x"0100006f",
00000336 => x"00001537",
00000337 => x"e1c50513",
00000338 => x"3f4000ef",
00000339 => x"00001537",
00000340 => x"f8c50513",
00000341 => x"3e8000ef",
00000342 => x"34002573",
00000343 => x"ec1ff0ef",
00000344 => x"00001537",
00000345 => x"f9450513",
00000346 => x"3d4000ef",
00000347 => x"34302573",
00000348 => x"eadff0ef",
00000349 => x"00812403",
00000350 => x"00c12083",
00000351 => x"00412483",
00000352 => x"00001537",
00000353 => x"ffc50513",
00000354 => x"01010113",
00000355 => x"3b00006f",
00000356 => x"00001537",
00000357 => x"e3c50513",
00000358 => x"fb1ff06f",
00000359 => x"00001537",
00000360 => x"e5850513",
00000361 => x"fa5ff06f",
00000362 => x"00001537",
00000363 => x"e6c50513",
00000364 => x"f99ff06f",
00000365 => x"00001537",
00000366 => x"e7850513",
00000367 => x"f8dff06f",
00000368 => x"00001537",
00000369 => x"e9050513",
00000370 => x"f81ff06f",
00000371 => x"00001537",
00000372 => x"ea450513",
00000373 => x"f75ff06f",
00000374 => x"00001537",
00000375 => x"ec050513",
00000376 => x"f69ff06f",
00000377 => x"00001537",
00000378 => x"ed450513",
00000379 => x"f5dff06f",
00000380 => x"00001537",
00000381 => x"ef450513",
00000382 => x"f51ff06f",
00000383 => x"00001537",
00000384 => x"f1450513",
00000385 => x"f45ff06f",
00000386 => x"00001537",
00000387 => x"f3050513",
00000388 => x"f39ff06f",
00000389 => x"00001537",
00000390 => x"f4850513",
00000391 => x"f2dff06f",
00000392 => x"01f00793",
00000393 => x"02a7e263",
00000394 => x"800007b7",
00000395 => x"00078793",
00000396 => x"00251513",
00000397 => x"00a78533",
00000398 => x"48c00793",
00000399 => x"00f52023",
00000400 => x"00000513",
00000401 => x"00008067",
00000402 => x"00100513",
00000403 => x"00008067",
00000404 => x"ff010113",
00000405 => x"00112623",
00000406 => x"00812423",
00000407 => x"00912223",
00000408 => x"301027f3",
00000409 => x"00079863",
00000410 => x"00001537",
00000411 => x"fd050513",
00000412 => x"2cc000ef",
00000413 => x"21000793",
00000414 => x"30579073",
00000415 => x"00000413",
00000416 => x"01d00493",
00000417 => x"00040513",
00000418 => x"00140413",
00000419 => x"0ff47413",
00000420 => x"f91ff0ef",
00000421 => x"fe9418e3",
00000422 => x"00c12083",
00000423 => x"00812403",
00000424 => x"00412483",
00000425 => x"01010113",
00000426 => x"00008067",
00000427 => x"ff010113",
00000428 => x"00112623",
00000429 => x"00812423",
00000430 => x"30102673",
00000431 => x"400005b7",
00000432 => x"10058593",
00000433 => x"00b677b3",
00000434 => x"00000413",
00000435 => x"00b78c63",
00000436 => x"00100413",
00000437 => x"00051863",
00000438 => x"00001537",
00000439 => x"00450513",
00000440 => x"3f8000ef",
00000441 => x"00c12083",
00000442 => x"00040513",
00000443 => x"00812403",
00000444 => x"01010113",
00000445 => x"00008067",
00000446 => x"fd010113",
00000447 => x"02812423",
00000448 => x"02912223",
00000449 => x"03212023",
00000450 => x"01312e23",
00000451 => x"01412c23",
00000452 => x"02112623",
00000453 => x"01512a23",
00000454 => x"00001a37",
00000455 => x"00050493",
00000456 => x"00058413",
00000457 => x"00058523",
00000458 => x"00000993",
00000459 => x"00410913",
00000460 => x"09ca0a13",
00000461 => x"00a00593",
00000462 => x"00048513",
00000463 => x"58c000ef",
00000464 => x"00aa0533",
00000465 => x"00054783",
00000466 => x"01390ab3",
00000467 => x"00048513",
00000468 => x"00fa8023",
00000469 => x"00a00593",
00000470 => x"528000ef",
00000471 => x"00198993",
00000472 => x"00a00793",
00000473 => x"00050493",
00000474 => x"fcf996e3",
00000475 => x"00090693",
00000476 => x"00900713",
00000477 => x"03000613",
00000478 => x"0096c583",
00000479 => x"00070793",
00000480 => x"fff70713",
00000481 => x"01071713",
00000482 => x"01075713",
00000483 => x"00c59a63",
00000484 => x"000684a3",
00000485 => x"fff68693",
00000486 => x"fe0710e3",
00000487 => x"00000793",
00000488 => x"00f907b3",
00000489 => x"00000593",
00000490 => x"0007c703",
00000491 => x"00070c63",
00000492 => x"00158693",
00000493 => x"00b405b3",
00000494 => x"00e58023",
00000495 => x"01069593",
00000496 => x"0105d593",
00000497 => x"fff78713",
00000498 => x"02f91863",
00000499 => x"00b40433",
00000500 => x"00040023",
00000501 => x"02c12083",
00000502 => x"02812403",
00000503 => x"02412483",
00000504 => x"02012903",
00000505 => x"01c12983",
00000506 => x"01812a03",
00000507 => x"01412a83",
00000508 => x"03010113",
00000509 => x"00008067",
00000510 => x"00070793",
00000511 => x"fadff06f",
00000512 => x"00001637",
00000513 => x"00758693",
00000514 => x"00000713",
00000515 => x"0a860613",
00000516 => x"02000813",
00000517 => x"00e557b3",
00000518 => x"00f7f793",
00000519 => x"00f607b3",
00000520 => x"0007c783",
00000521 => x"00470713",
00000522 => x"fff68693",
00000523 => x"00f680a3",
00000524 => x"ff0712e3",
00000525 => x"00058423",
00000526 => x"00008067",
00000527 => x"fa002023",
00000528 => x"fe002703",
00000529 => x"00151513",
00000530 => x"00000793",
00000531 => x"04a77463",
00000532 => x"000016b7",
00000533 => x"00000713",
00000534 => x"ffe68693",
00000535 => x"04f6e663",
00000536 => x"00367613",
00000537 => x"0035f593",
00000538 => x"fff78793",
00000539 => x"01461613",
00000540 => x"00c7e7b3",
00000541 => x"01659593",
00000542 => x"01871713",
00000543 => x"00b7e7b3",
00000544 => x"00e7e7b3",
00000545 => x"10000737",
00000546 => x"00e7e7b3",
00000547 => x"faf02023",
00000548 => x"00008067",
00000549 => x"00178793",
00000550 => x"01079793",
00000551 => x"40a70733",
00000552 => x"0107d793",
00000553 => x"fa9ff06f",
00000554 => x"ffe70513",
00000555 => x"0fd57513",
00000556 => x"00051a63",
00000557 => x"0037d793",
00000558 => x"00170713",
00000559 => x"0ff77713",
00000560 => x"f9dff06f",
00000561 => x"0017d793",
00000562 => x"ff1ff06f",
00000563 => x"f71ff06f",
00000564 => x"fa002783",
00000565 => x"fe07cee3",
00000566 => x"faa02223",
00000567 => x"00008067",
00000568 => x"ff1ff06f",
00000569 => x"ff010113",
00000570 => x"00812423",
00000571 => x"01212023",
00000572 => x"00112623",
00000573 => x"00912223",
00000574 => x"00050413",
00000575 => x"00a00913",
00000576 => x"00044483",
00000577 => x"00140413",
00000578 => x"00049e63",
00000579 => x"00c12083",
00000580 => x"00812403",
00000581 => x"00412483",
00000582 => x"00012903",
00000583 => x"01010113",
00000584 => x"00008067",
00000585 => x"01249663",
00000586 => x"00d00513",
00000587 => x"fa5ff0ef",
00000588 => x"00048513",
00000589 => x"f9dff0ef",
00000590 => x"fc9ff06f",
00000591 => x"fa9ff06f",
00000592 => x"fa010113",
00000593 => x"04f12a23",
00000594 => x"04410793",
00000595 => x"02812c23",
00000596 => x"03212823",
00000597 => x"03412423",
00000598 => x"03512223",
00000599 => x"03612023",
00000600 => x"01712e23",
00000601 => x"01812c23",
00000602 => x"01912a23",
00000603 => x"02112e23",
00000604 => x"02912a23",
00000605 => x"03312623",
00000606 => x"00050413",
00000607 => x"04b12223",
00000608 => x"04c12423",
00000609 => x"04d12623",
00000610 => x"04e12823",
00000611 => x"05012c23",
00000612 => x"05112e23",
00000613 => x"00f12023",
00000614 => x"02500a13",
00000615 => x"00a00a93",
00000616 => x"07300913",
00000617 => x"07500b13",
00000618 => x"07800b93",
00000619 => x"06300c13",
00000620 => x"06900c93",
00000621 => x"00044483",
00000622 => x"02049c63",
00000623 => x"03c12083",
00000624 => x"03812403",
00000625 => x"03412483",
00000626 => x"03012903",
00000627 => x"02c12983",
00000628 => x"02812a03",
00000629 => x"02412a83",
00000630 => x"02012b03",
00000631 => x"01c12b83",
00000632 => x"01812c03",
00000633 => x"01412c83",
00000634 => x"06010113",
00000635 => x"00008067",
00000636 => x"0d449863",
00000637 => x"00240993",
00000638 => x"00144403",
00000639 => x"05240263",
00000640 => x"00896e63",
00000641 => x"05840c63",
00000642 => x"07940663",
00000643 => x"02500513",
00000644 => x"ec1ff0ef",
00000645 => x"00040513",
00000646 => x"0540006f",
00000647 => x"09640663",
00000648 => x"ff7416e3",
00000649 => x"00012783",
00000650 => x"00410593",
00000651 => x"0007a503",
00000652 => x"00478713",
00000653 => x"00e12023",
00000654 => x"dc9ff0ef",
00000655 => x"0640006f",
00000656 => x"00012783",
00000657 => x"0007a503",
00000658 => x"00478713",
00000659 => x"00e12023",
00000660 => x"e95ff0ef",
00000661 => x"00098413",
00000662 => x"f5dff06f",
00000663 => x"00012783",
00000664 => x"0007c503",
00000665 => x"00478713",
00000666 => x"00e12023",
00000667 => x"e65ff0ef",
00000668 => x"fe5ff06f",
00000669 => x"00012783",
00000670 => x"0007a403",
00000671 => x"00478713",
00000672 => x"00e12023",
00000673 => x"00045863",
00000674 => x"02d00513",
00000675 => x"40800433",
00000676 => x"e41ff0ef",
00000677 => x"00410593",
00000678 => x"00040513",
00000679 => x"c5dff0ef",
00000680 => x"00410513",
00000681 => x"fadff06f",
00000682 => x"00012783",
00000683 => x"00410593",
00000684 => x"00478713",
00000685 => x"0007a503",
00000686 => x"00e12023",
00000687 => x"fe1ff06f",
00000688 => x"01549663",
00000689 => x"00d00513",
00000690 => x"e09ff0ef",
00000691 => x"00140993",
00000692 => x"00048513",
00000693 => x"f99ff06f",
00000694 => x"fd010113",
00000695 => x"00112623",
00000696 => x"00b12a23",
00000697 => x"00c12c23",
00000698 => x"00d12e23",
00000699 => x"02e12023",
00000700 => x"02f12223",
00000701 => x"03012423",
00000702 => x"03112623",
00000703 => x"e45ff0ef",
00000704 => x"00c12083",
00000705 => x"03010113",
00000706 => x"00008067",
00000707 => x"fe802503",
00000708 => x"01055513",
00000709 => x"00157513",
00000710 => x"00008067",
00000711 => x"f8a02223",
00000712 => x"00008067",
00000713 => x"ff010113",
00000714 => x"c80026f3",
00000715 => x"c0002773",
00000716 => x"c80027f3",
00000717 => x"fed79ae3",
00000718 => x"00e12023",
00000719 => x"00f12223",
00000720 => x"00012503",
00000721 => x"00412583",
00000722 => x"01010113",
00000723 => x"00008067",
00000724 => x"fe010113",
00000725 => x"00112e23",
00000726 => x"00812c23",
00000727 => x"00912a23",
00000728 => x"00a12623",
00000729 => x"3200f073",
00000730 => x"fbdff0ef",
00000731 => x"00050493",
00000732 => x"fe002503",
00000733 => x"00058413",
00000734 => x"3e800593",
00000735 => x"104000ef",
00000736 => x"00c12603",
00000737 => x"00000693",
00000738 => x"00000593",
00000739 => x"05c000ef",
00000740 => x"009504b3",
00000741 => x"00a4b533",
00000742 => x"00858433",
00000743 => x"00850433",
00000744 => x"f85ff0ef",
00000745 => x"fe85eee3",
00000746 => x"00b41463",
00000747 => x"fe956ae3",
00000748 => x"01c12083",
00000749 => x"01812403",
00000750 => x"01412483",
00000751 => x"02010113",
00000752 => x"00008067",
00000753 => x"00050613",
00000754 => x"00000513",
00000755 => x"0015f693",
00000756 => x"00068463",
00000757 => x"00c50533",
00000758 => x"0015d593",
00000759 => x"00161613",
00000760 => x"fe0596e3",
00000761 => x"00008067",
00000762 => x"00050313",
00000763 => x"ff010113",
00000764 => x"00060513",
00000765 => x"00068893",
00000766 => x"00112623",
00000767 => x"00030613",
00000768 => x"00050693",
00000769 => x"00000713",
00000770 => x"00000793",
00000771 => x"00000813",
00000772 => x"0016fe13",
00000773 => x"00171e93",
00000774 => x"000e0c63",
00000775 => x"01060e33",
00000776 => x"010e3833",
00000777 => x"00e787b3",
00000778 => x"00f807b3",
00000779 => x"000e0813",
00000780 => x"01f65713",
00000781 => x"0016d693",
00000782 => x"00eee733",
00000783 => x"00161613",
00000784 => x"fc0698e3",
00000785 => x"00058663",
00000786 => x"f7dff0ef",
00000787 => x"00a787b3",
00000788 => x"00088a63",
00000789 => x"00030513",
00000790 => x"00088593",
00000791 => x"f69ff0ef",
00000792 => x"00f507b3",
00000793 => x"00c12083",
00000794 => x"00080513",
00000795 => x"00078593",
00000796 => x"01010113",
00000797 => x"00008067",
00000798 => x"06054063",
00000799 => x"0605c663",
00000800 => x"00058613",
00000801 => x"00050593",
00000802 => x"fff00513",
00000803 => x"02060c63",
00000804 => x"00100693",
00000805 => x"00b67a63",
00000806 => x"00c05863",
00000807 => x"00161613",
00000808 => x"00169693",
00000809 => x"feb66ae3",
00000810 => x"00000513",
00000811 => x"00c5e663",
00000812 => x"40c585b3",
00000813 => x"00d56533",
00000814 => x"0016d693",
00000815 => x"00165613",
00000816 => x"fe0696e3",
00000817 => x"00008067",
00000818 => x"00008293",
00000819 => x"fb5ff0ef",
00000820 => x"00058513",
00000821 => x"00028067",
00000822 => x"40a00533",
00000823 => x"00b04863",
00000824 => x"40b005b3",
00000825 => x"f9dff06f",
00000826 => x"40b005b3",
00000827 => x"00008293",
00000828 => x"f91ff0ef",
00000829 => x"40a00533",
00000830 => x"00028067",
00000831 => x"00008293",
00000832 => x"0005ca63",
00000833 => x"00054c63",
00000834 => x"f79ff0ef",
00000835 => x"00058513",
00000836 => x"00028067",
00000837 => x"40b005b3",
00000838 => x"fe0558e3",
00000839 => x"40a00533",
00000840 => x"f61ff0ef",
00000841 => x"40b00533",
00000842 => x"00028067",
00000843 => x"6f727245",
00000844 => x"4e202172",
00000845 => x"5047206f",
00000846 => x"75204f49",
00000847 => x"2074696e",
00000848 => x"746e7973",
00000849 => x"69736568",
00000850 => x"2164657a",
00000851 => x"0000000a",
00000852 => x"6e696c42",
00000853 => x"676e696b",
00000854 => x"44454c20",
00000855 => x"6d656420",
00000856 => x"7270206f",
00000857 => x"6172676f",
00000858 => x"00000a6d",
00000859 => x"0000031c",
00000860 => x"00000328",
00000861 => x"00000334",
00000862 => x"00000340",
00000863 => x"0000034c",
00000864 => x"00000354",
00000865 => x"0000035c",
00000866 => x"00000364",
00000867 => x"0000036c",
00000868 => x"00000288",
00000869 => x"00000288",
00000870 => x"00000374",
00000871 => x"0000037c",
00000872 => x"00000288",
00000873 => x"00000288",
00000874 => x"00000288",
00000875 => x"00000384",
00000876 => x"00000288",
00000877 => x"00000288",
00000878 => x"00000288",
00000879 => x"0000038c",
00000880 => x"00000288",
00000881 => x"00000288",
00000882 => x"00000288",
00000883 => x"00000288",
00000884 => x"00000394",
00000885 => x"0000039c",
00000886 => x"000003a4",
00000887 => x"000003ac",
00000888 => x"000003b4",
00000889 => x"000003bc",
00000890 => x"000003c4",
00000891 => x"000003cc",
00000892 => x"000003d4",
00000893 => x"000003dc",
00000894 => x"000003e4",
00000895 => x"000003ec",
00000896 => x"000003f4",
00000897 => x"000003fc",
00000898 => x"00000404",
00000899 => x"0000040c",
00000900 => x"00007830",
00000901 => x"4554523c",
00000902 => x"0000203e",
00000903 => x"74736e49",
00000904 => x"74637572",
00000905 => x"206e6f69",
00000906 => x"72646461",
00000907 => x"20737365",
00000908 => x"6173696d",
00000909 => x"6e67696c",
00000910 => x"00006465",
00000911 => x"74736e49",
00000912 => x"74637572",
00000913 => x"206e6f69",
00000914 => x"65636361",
00000915 => x"66207373",
00000916 => x"746c7561",
00000917 => x"00000000",
00000918 => x"656c6c49",
00000919 => x"206c6167",
00000920 => x"74736e69",
00000921 => x"74637572",
00000922 => x"006e6f69",
00000923 => x"61657242",
00000924 => x"696f706b",
00000925 => x"0000746e",
00000926 => x"64616f4c",
00000927 => x"64646120",
00000928 => x"73736572",
00000929 => x"73696d20",
00000930 => x"67696c61",
00000931 => x"0064656e",
00000932 => x"64616f4c",
00000933 => x"63636120",
00000934 => x"20737365",
00000935 => x"6c756166",
00000936 => x"00000074",
00000937 => x"726f7453",
00000938 => x"64612065",
00000939 => x"73657264",
00000940 => x"696d2073",
00000941 => x"696c6173",
00000942 => x"64656e67",
00000943 => x"00000000",
00000944 => x"726f7453",
00000945 => x"63612065",
00000946 => x"73736563",
00000947 => x"75616620",
00000948 => x"0000746c",
00000949 => x"69766e45",
00000950 => x"6d6e6f72",
00000951 => x"20746e65",
00000952 => x"6c6c6163",
00000953 => x"6f726620",
00000954 => x"2d55206d",
00000955 => x"65646f6d",
00000956 => x"00000000",
00000957 => x"69766e45",
00000958 => x"6d6e6f72",
00000959 => x"20746e65",
00000960 => x"6c6c6163",
00000961 => x"6f726620",
00000962 => x"2d4d206d",
00000963 => x"65646f6d",
00000964 => x"00000000",
00000965 => x"6863614d",
00000966 => x"20656e69",
00000967 => x"74666f73",
00000968 => x"65726177",
00000969 => x"746e6920",
00000970 => x"75727265",
00000971 => x"00007470",
00000972 => x"6863614d",
00000973 => x"20656e69",
00000974 => x"656d6974",
00000975 => x"6e692072",
00000976 => x"72726574",
00000977 => x"00747075",
00000978 => x"6863614d",
00000979 => x"20656e69",
00000980 => x"65747865",
00000981 => x"6c616e72",
00000982 => x"746e6920",
00000983 => x"75727265",
00000984 => x"00007470",
00000985 => x"74736146",
00000986 => x"746e6920",
00000987 => x"75727265",
00000988 => x"00207470",
00000989 => x"6e6b6e55",
00000990 => x"206e776f",
00000991 => x"70617274",
00000992 => x"75616320",
00000993 => x"203a6573",
00000994 => x"00000000",
00000995 => x"50204020",
00000996 => x"00003d43",
00000997 => x"544d202c",
00000998 => x"3d4c4156",
00000999 => x"00000000",
00001000 => x"50204020",
00001001 => x"00003d43",
00001002 => x"544d202c",
00001003 => x"3d4c4156",
00001004 => x"00000000",
00001005 => x"000009e4",
00001006 => x"00000a34",
00001007 => x"00000a40",
00001008 => x"00000a4c",
00001009 => x"00000a58",
00001010 => x"00000a64",
00001011 => x"00000a70",
00001012 => x"00000a7c",
00001013 => x"00000a88",
00001014 => x"000009a4",
00001015 => x"000009a4",
00001016 => x"00000a94",
00001017 => x"4554523c",
00001018 => x"4157203e",
00001019 => x"4e494e52",
00001020 => x"43202147",
00001021 => x"43205550",
00001022 => x"73205253",
00001023 => x"65747379",
00001024 => x"6f6e206d",
00001025 => x"76612074",
00001026 => x"616c6961",
00001027 => x"21656c62",
00001028 => x"522f3c20",
00001029 => x"003e4554",
00001030 => x"5241570a",
00001031 => x"474e494e",
00001032 => x"57532021",
00001033 => x"4153495f",
00001034 => x"65662820",
00001035 => x"72757461",
00001036 => x"72207365",
00001037 => x"69757165",
00001038 => x"29646572",
00001039 => x"20737620",
00001040 => x"495f5748",
00001041 => x"28204153",
00001042 => x"74616566",
00001043 => x"73657275",
00001044 => x"61766120",
00001045 => x"62616c69",
00001046 => x"2029656c",
00001047 => x"6d73696d",
00001048 => x"68637461",
00001049 => x"57530a21",
00001050 => x"4153495f",
00001051 => x"30203d20",
00001052 => x"20782578",
00001053 => x"6d6f6328",
00001054 => x"656c6970",
00001055 => x"6c662072",
00001056 => x"29736761",
00001057 => x"5f57480a",
00001058 => x"20415349",
00001059 => x"7830203d",
00001060 => x"28207825",
00001061 => x"6173696d",
00001062 => x"72736320",
00001063 => x"000a0a29",
00001064 => x"33323130",
00001065 => x"37363534",
00001066 => x"42413938",
00001067 => x"46454443",
00001000 => x"00000540",
00001001 => x"00000590",
00001002 => x"0000059c",
00001003 => x"000005a8",
00001004 => x"000005b4",
00001005 => x"000005c0",
00001006 => x"000005cc",
00001007 => x"000005d8",
00001008 => x"000005e4",
00001009 => x"00000500",
00001010 => x"00000500",
00001011 => x"000005f0",
00001012 => x"4554523c",
00001013 => x"4157203e",
00001014 => x"4e494e52",
00001015 => x"43202147",
00001016 => x"43205550",
00001017 => x"73205253",
00001018 => x"65747379",
00001019 => x"6f6e206d",
00001020 => x"76612074",
00001021 => x"616c6961",
00001022 => x"21656c62",
00001023 => x"522f3c20",
00001024 => x"003e4554",
00001025 => x"5241570a",
00001026 => x"474e494e",
00001027 => x"57532021",
00001028 => x"4153495f",
00001029 => x"65662820",
00001030 => x"72757461",
00001031 => x"72207365",
00001032 => x"69757165",
00001033 => x"29646572",
00001034 => x"20737620",
00001035 => x"495f5748",
00001036 => x"28204153",
00001037 => x"74616566",
00001038 => x"73657275",
00001039 => x"61766120",
00001040 => x"62616c69",
00001041 => x"2029656c",
00001042 => x"6d73696d",
00001043 => x"68637461",
00001044 => x"57530a21",
00001045 => x"4153495f",
00001046 => x"30203d20",
00001047 => x"20782578",
00001048 => x"6d6f6328",
00001049 => x"656c6970",
00001050 => x"6c662072",
00001051 => x"29736761",
00001052 => x"5f57480a",
00001053 => x"20415349",
00001054 => x"7830203d",
00001055 => x"28207825",
00001056 => x"6173696d",
00001057 => x"72736320",
00001058 => x"000a0a29",
00001059 => x"33323130",
00001060 => x"37363534",
00001061 => x"42413938",
00001062 => x"46454443",
00001063 => x"33323130",
00001064 => x"37363534",
00001065 => x"00003938",
00001066 => x"33323130",
00001067 => x"37363534",
00001068 => x"62613938",
00001069 => x"66656463",
00001070 => x"00000000",
others => x"00000000"
);
 
/neorv32/trunk/rtl/core/neorv32_bootloader_image.vhd
6,7 → 6,7
 
package neorv32_bootloader_image is
 
type bootloader_init_image_t is array (0 to 1009) of std_ulogic_vector(31 downto 0);
type bootloader_init_image_t is array (0 to 1014) of std_ulogic_vector(31 downto 0);
constant bootloader_init_image : bootloader_init_image_t := (
00000000 => x"00000093",
00000001 => x"00000113",
19,52 → 19,52
00000008 => x"00000493",
00000009 => x"00000713",
00000010 => x"00000793",
00000011 => x"00000597",
00000012 => x"0cc58593",
00000013 => x"30559073",
00000014 => x"00002537",
00000015 => x"80050513",
00000016 => x"30051073",
00000017 => x"30401073",
00000018 => x"80012117",
00000019 => x"fb410113",
00000020 => x"ffc17113",
00000021 => x"00010413",
00000022 => x"80010197",
00000023 => x"7a818193",
00000024 => x"f0000593",
00000025 => x"0005a023",
00000026 => x"00458593",
00000027 => x"feb01ce3",
00000028 => x"80010597",
00000029 => x"f9058593",
00000030 => x"80818613",
00000031 => x"00c5d863",
00000032 => x"00058023",
00000033 => x"00158593",
00000034 => x"ff5ff06f",
00000035 => x"00001597",
00000036 => x"f3858593",
00000037 => x"80010617",
00000038 => x"f6c60613",
00000039 => x"80010697",
00000040 => x"f6468693",
00000041 => x"00d65c63",
00000042 => x"00058703",
00000043 => x"00e60023",
00000044 => x"00158593",
00000045 => x"00160613",
00000046 => x"fedff06f",
00000047 => x"00000513",
00000048 => x"00000593",
00000049 => x"b0001073",
00000050 => x"b8001073",
00000051 => x"b0201073",
00000052 => x"b8201073",
00000053 => x"3063d073",
00000054 => x"32001073",
00000055 => x"80000637",
00000056 => x"34261073",
00000011 => x"80012117",
00000012 => x"fd010113",
00000013 => x"ffc17113",
00000014 => x"00010413",
00000015 => x"80010197",
00000016 => x"7c418193",
00000017 => x"00000517",
00000018 => x"0b450513",
00000019 => x"30551073",
00000020 => x"34151073",
00000021 => x"34301073",
00000022 => x"34201073",
00000023 => x"30001073",
00000024 => x"30401073",
00000025 => x"30601073",
00000026 => x"ffa00593",
00000027 => x"32059073",
00000028 => x"b0001073",
00000029 => x"b8001073",
00000030 => x"b0201073",
00000031 => x"b8201073",
00000032 => x"f0000593",
00000033 => x"0005a023",
00000034 => x"00458593",
00000035 => x"feb01ce3",
00000036 => x"80010597",
00000037 => x"f7058593",
00000038 => x"80818613",
00000039 => x"00c5d863",
00000040 => x"00058023",
00000041 => x"00158593",
00000042 => x"ff5ff06f",
00000043 => x"00001597",
00000044 => x"f2c58593",
00000045 => x"80010617",
00000046 => x"f4c60613",
00000047 => x"80010697",
00000048 => x"f4468693",
00000049 => x"00d65c63",
00000050 => x"00058703",
00000051 => x"00e60023",
00000052 => x"00158593",
00000053 => x"00160613",
00000054 => x"fedff06f",
00000055 => x"00000513",
00000056 => x"00000593",
00000057 => x"060000ef",
00000058 => x"30047073",
00000059 => x"00000013",
134,32 → 134,32
00000123 => x"00000013",
00000124 => x"00000013",
00000125 => x"ffff1537",
00000126 => x"edc50513",
00000126 => x"eec50513",
00000127 => x"309000ef",
00000128 => x"f1302573",
00000129 => x"260000ef",
00000130 => x"ffff1537",
00000131 => x"f1450513",
00000131 => x"f2450513",
00000132 => x"2f5000ef",
00000133 => x"fe002503",
00000134 => x"24c000ef",
00000135 => x"ffff1537",
00000136 => x"f1c50513",
00000136 => x"f2c50513",
00000137 => x"2e1000ef",
00000138 => x"fe402503",
00000139 => x"238000ef",
00000140 => x"ffff1537",
00000141 => x"f2450513",
00000141 => x"f3450513",
00000142 => x"2cd000ef",
00000143 => x"30102573",
00000144 => x"224000ef",
00000145 => x"ffff1537",
00000146 => x"f2c50513",
00000146 => x"f3c50513",
00000147 => x"2b9000ef",
00000148 => x"fc002573",
00000149 => x"210000ef",
00000150 => x"ffff1537",
00000151 => x"f3450513",
00000151 => x"f4450513",
00000152 => x"2a5000ef",
00000153 => x"fe802503",
00000154 => x"ffff14b7",
166,25 → 166,25
00000155 => x"00341413",
00000156 => x"1f4000ef",
00000157 => x"ffff1537",
00000158 => x"f3c50513",
00000158 => x"f4c50513",
00000159 => x"289000ef",
00000160 => x"ff802503",
00000161 => x"1e0000ef",
00000162 => x"f4448513",
00000162 => x"f5448513",
00000163 => x"279000ef",
00000164 => x"ff002503",
00000165 => x"1d0000ef",
00000166 => x"ffff1537",
00000167 => x"f5050513",
00000167 => x"f6050513",
00000168 => x"265000ef",
00000169 => x"ffc02503",
00000170 => x"1bc000ef",
00000171 => x"f4448513",
00000171 => x"f5448513",
00000172 => x"255000ef",
00000173 => x"ff402503",
00000174 => x"1ac000ef",
00000175 => x"ffff1537",
00000176 => x"f5850513",
00000176 => x"f6850513",
00000177 => x"241000ef",
00000178 => x"0b9000ef",
00000179 => x"00a404b3",
193,7 → 193,7
00000182 => x"1d1000ef",
00000183 => x"02050263",
00000184 => x"ffff1537",
00000185 => x"f8050513",
00000185 => x"f9450513",
00000186 => x"21d000ef",
00000187 => x"0d9000ef",
00000188 => x"02300793",
215,12 → 215,12
00000204 => x"07500b93",
00000205 => x"ffff14b7",
00000206 => x"ffff1c37",
00000207 => x"f8c90513",
00000207 => x"fa090513",
00000208 => x"1c5000ef",
00000209 => x"155000ef",
00000210 => x"00050413",
00000211 => x"129000ef",
00000212 => x"e9498513",
00000212 => x"ea498513",
00000213 => x"1b1000ef",
00000214 => x"fb4400e3",
00000215 => x"01541863",
246,9 → 246,9
00000235 => x"02c000ef",
00000236 => x"f8dff06f",
00000237 => x"03f00793",
00000238 => x"f94c0513",
00000238 => x"fa8c0513",
00000239 => x"00f40463",
00000240 => x"fa848513",
00000240 => x"fbc48513",
00000241 => x"141000ef",
00000242 => x"f75ff06f",
00000243 => x"ffff1537",
294,7 → 294,7
00000283 => x"00050913",
00000284 => x"ffff1537",
00000285 => x"00912a23",
00000286 => x"e6050513",
00000286 => x"e5450513",
00000287 => x"ffff14b7",
00000288 => x"00812c23",
00000289 => x"01312623",
301,7 → 301,7
00000290 => x"00112e23",
00000291 => x"01c00413",
00000292 => x"075000ef",
00000293 => x"fb448493",
00000293 => x"fc848493",
00000294 => x"ffc00993",
00000295 => x"008957b3",
00000296 => x"00f7f793",
373,12 → 373,12
00000362 => x"00100513",
00000363 => x"02079863",
00000364 => x"ffff1537",
00000365 => x"e5450513",
00000365 => x"e5850513",
00000366 => x"74c000ef",
00000367 => x"00040513",
00000368 => x"ea5ff0ef",
00000369 => x"ffff1537",
00000370 => x"e5c50513",
00000370 => x"e6c50513",
00000371 => x"738000ef",
00000372 => x"34102573",
00000373 => x"e91ff0ef",
519,7 → 519,7
00000508 => x"04079663",
00000509 => x"02041863",
00000510 => x"ffff1537",
00000511 => x"e6450513",
00000511 => x"e7450513",
00000512 => x"504000ef",
00000513 => x"008005b7",
00000514 => x"00040513",
530,7 → 530,7
00000519 => x"00000513",
00000520 => x"01c0006f",
00000521 => x"ffff1537",
00000522 => x"e8450513",
00000522 => x"e9450513",
00000523 => x"4d8000ef",
00000524 => x"db1ff0ef",
00000525 => x"fc0518e3",
556,7 → 556,7
00000545 => x"00200513",
00000546 => x"fa049ae3",
00000547 => x"ffff1537",
00000548 => x"e9050513",
00000548 => x"ea050513",
00000549 => x"470000ef",
00000550 => x"02c12083",
00000551 => x"02812403",
584,7 → 584,7
00000573 => x"00112623",
00000574 => x"ea1ff0ef",
00000575 => x"ffff1537",
00000576 => x"e9450513",
00000576 => x"ea450513",
00000577 => x"400000ef",
00000578 => x"ad1ff0ef",
00000579 => x"0000006f",
672,17 → 672,17
00000661 => x"02010113",
00000662 => x"2ac0006f",
00000663 => x"ffff1537",
00000664 => x"e9850513",
00000664 => x"ea850513",
00000665 => x"2a0000ef",
00000666 => x"00040513",
00000667 => x"9f9ff0ef",
00000668 => x"ffff1537",
00000669 => x"ea450513",
00000669 => x"eb450513",
00000670 => x"28c000ef",
00000671 => x"00800537",
00000672 => x"9e5ff0ef",
00000673 => x"ffff1537",
00000674 => x"ec050513",
00000674 => x"ed050513",
00000675 => x"278000ef",
00000676 => x"208000ef",
00000677 => x"00050493",
694,7 → 694,7
00000683 => x"00300513",
00000684 => x"975ff0ef",
00000685 => x"ffff1537",
00000686 => x"ecc50513",
00000686 => x"edc50513",
00000687 => x"01045493",
00000688 => x"244000ef",
00000689 => x"00148493",
724,7 → 724,7
00000713 => x"412005b3",
00000714 => x"e41ff0ef",
00000715 => x"ffff1537",
00000716 => x"e9050513",
00000716 => x"ea050513",
00000717 => x"f05ff06f",
00000718 => x"00090513",
00000719 => x"e85ff0ef",
925,98 → 925,103
00000914 => x"52450a07",
00000915 => x"5f524f52",
00000916 => x"00000000",
00000917 => x"58450a0a",
00000918 => x"00282043",
00000919 => x"20402029",
00000920 => x"00007830",
00000921 => x"69617741",
00000922 => x"676e6974",
00000923 => x"6f656e20",
00000924 => x"32337672",
00000925 => x"6578655f",
00000926 => x"6e69622e",
00000927 => x"202e2e2e",
00000928 => x"00000000",
00000929 => x"64616f4c",
00000930 => x"2e676e69",
00000931 => x"00202e2e",
00000932 => x"00004b4f",
00000933 => x"0000000a",
00000934 => x"74697257",
00000935 => x"78302065",
00000936 => x"00000000",
00000937 => x"74796220",
00000938 => x"74207365",
00000939 => x"5053206f",
00000940 => x"6c662049",
00000941 => x"20687361",
00000942 => x"78302040",
00000943 => x"00000000",
00000944 => x"7928203f",
00000945 => x"20296e2f",
00000946 => x"00000000",
00000947 => x"616c460a",
00000948 => x"6e696873",
00000949 => x"2e2e2e67",
00000950 => x"00000020",
00000951 => x"0a0a0a0a",
00000952 => x"4e203c3c",
00000953 => x"56524f45",
00000954 => x"42203233",
00000955 => x"6c746f6f",
00000956 => x"6564616f",
00000957 => x"3e3e2072",
00000958 => x"4c420a0a",
00000959 => x"203a5644",
00000960 => x"2072614d",
00000961 => x"32203332",
00000962 => x"0a313230",
00000963 => x"3a565748",
00000964 => x"00002020",
00000965 => x"4b4c430a",
00000966 => x"0020203a",
00000967 => x"4553550a",
00000968 => x"00203a52",
00000969 => x"53494d0a",
00000970 => x"00203a41",
00000971 => x"58455a0a",
00000972 => x"00203a54",
00000973 => x"4f52500a",
00000974 => x"00203a43",
00000975 => x"454d490a",
00000976 => x"00203a4d",
00000977 => x"74796220",
00000978 => x"40207365",
00000979 => x"00000020",
00000980 => x"454d440a",
00000981 => x"00203a4d",
00000982 => x"75410a0a",
00000983 => x"6f626f74",
00000984 => x"6920746f",
00000985 => x"7338206e",
00000986 => x"7250202e",
00000987 => x"20737365",
00000988 => x"2079656b",
00000989 => x"61206f74",
00000990 => x"74726f62",
00000991 => x"00000a2e",
00000992 => x"726f6241",
00000993 => x"2e646574",
00000994 => x"00000a0a",
00000995 => x"444d430a",
00000996 => x"00203e3a",
00000997 => x"53207962",
00000998 => x"68706574",
00000999 => x"4e206e61",
00001000 => x"69746c6f",
00001001 => x"0000676e",
00001002 => x"61766e49",
00001003 => x"2064696c",
00001004 => x"00444d43",
00001005 => x"33323130",
00001006 => x"37363534",
00001007 => x"42413938",
00001008 => x"46454443",
00000917 => x"00007830",
00000918 => x"58450a0a",
00000919 => x"54504543",
00000920 => x"204e4f49",
00000921 => x"7561636d",
00000922 => x"003d6573",
00000923 => x"70204020",
00000924 => x"00003d63",
00000925 => x"69617741",
00000926 => x"676e6974",
00000927 => x"6f656e20",
00000928 => x"32337672",
00000929 => x"6578655f",
00000930 => x"6e69622e",
00000931 => x"202e2e2e",
00000932 => x"00000000",
00000933 => x"64616f4c",
00000934 => x"2e676e69",
00000935 => x"00202e2e",
00000936 => x"00004b4f",
00000937 => x"0000000a",
00000938 => x"74697257",
00000939 => x"78302065",
00000940 => x"00000000",
00000941 => x"74796220",
00000942 => x"74207365",
00000943 => x"5053206f",
00000944 => x"6c662049",
00000945 => x"20687361",
00000946 => x"78302040",
00000947 => x"00000000",
00000948 => x"7928203f",
00000949 => x"20296e2f",
00000950 => x"00000000",
00000951 => x"616c460a",
00000952 => x"6e696873",
00000953 => x"2e2e2e67",
00000954 => x"00000020",
00000955 => x"0a0a0a0a",
00000956 => x"4e203c3c",
00000957 => x"56524f45",
00000958 => x"42203233",
00000959 => x"6c746f6f",
00000960 => x"6564616f",
00000961 => x"3e3e2072",
00000962 => x"4c420a0a",
00000963 => x"203a5644",
00000964 => x"20727041",
00000965 => x"32203331",
00000966 => x"0a313230",
00000967 => x"3a565748",
00000968 => x"00002020",
00000969 => x"4b4c430a",
00000970 => x"0020203a",
00000971 => x"4553550a",
00000972 => x"00203a52",
00000973 => x"53494d0a",
00000974 => x"00203a41",
00000975 => x"58455a0a",
00000976 => x"00203a54",
00000977 => x"4f52500a",
00000978 => x"00203a43",
00000979 => x"454d490a",
00000980 => x"00203a4d",
00000981 => x"74796220",
00000982 => x"40207365",
00000983 => x"00000020",
00000984 => x"454d440a",
00000985 => x"00203a4d",
00000986 => x"75410a0a",
00000987 => x"6f626f74",
00000988 => x"6920746f",
00000989 => x"3828206e",
00000990 => x"202e7329",
00000991 => x"73657250",
00000992 => x"656b2073",
00000993 => x"6f742079",
00000994 => x"6f626120",
00000995 => x"0a2e7472",
00000996 => x"00000000",
00000997 => x"726f6241",
00000998 => x"2e646574",
00000999 => x"00000a0a",
00001000 => x"444d430a",
00001001 => x"00203e3a",
00001002 => x"53207962",
00001003 => x"68706574",
00001004 => x"4e206e61",
00001005 => x"69746c6f",
00001006 => x"0000676e",
00001007 => x"61766e49",
00001008 => x"2064696c",
00001009 => x"00444d43",
00001010 => x"33323130",
00001011 => x"37363534",
00001012 => x"62613938",
00001013 => x"66656463",
others => x"00000000"
);
 
/neorv32/trunk/rtl/core/neorv32_cpu.vhd
11,7 → 11,7
-- # * neorv32_cpu_ctrl.vhd - CPU control and CSR system #
-- # * neorv32_cpu_decompressor.vhd - Compressed instructions decoder #
-- # * neorv32_cpu_regfile.vhd - Data register file #
-- # * neorv32_package.vhd - Main CPU/processor package file #
-- # * neorv32_package.vhd - Main CPU & Processor package file #
-- # #
-- # Check out the processor's data sheet for more information: docs/NEORV32.pdf #
-- # ********************************************************************************************* #
72,11 → 72,14
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0 -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (1..64)
);
port (
-- global control --
167,12 → 170,20
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- hardware reset notifier --
assert not ((dedicated_reset_c = false) and (def_rst_val_c = '-')) report "NEORV32 CPU CONFIG NOTE: Using NO dedicated hardware reset for uncritical registers (default, might reduce area footprint). Set the package constant <dedicated_reset_c> to TRUE if you need a defined reset value." severity note;
assert not ((dedicated_reset_c = true) and (def_rst_val_c = '0')) report "NEORV32 CPU CONFIG NOTE: Using defined hardware reset for uncritical registers (non-default, reset-to-zero, might increase area footprint)." severity note;
assert not ((def_rst_val_c /= '-') and (def_rst_val_c /= '0')) report "NEORV32 CPU CONFIG ERROR! Invalid configuration of package <def_rst_val_c> constant (has to be '-' or '0')." severity error;
 
-- CSR system --
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/privileged features available when CPU_EXTENSION_RISCV_Zicsr = false." severity warning;
assert not (CPU_EXTENSION_RISCV_Zicsr = false) report "NEORV32 CPU CONFIG WARNING! No exception/interrupt/trap/privileged features available when <CPU_EXTENSION_RISCV_Zicsr> = false." severity warning;
 
-- CPU counters (cycle and instret) --
assert not ((CPU_CNT_WIDTH < 0) or (CPU_CNT_WIDTH > 64)) report "NEORV32 CPU CONFIG ERROR! Invalid <CPU_CNT_WIDTH> configuration. Has to be 0..64." severity error;
assert not (CPU_CNT_WIDTH < 64) report "NEORV32 CPU CONFIG WARNING! Implementing CPU <cycle> and <instret> CSRs with reduced size (" & integer'image(CPU_CNT_WIDTH) & "-bit instead of 64-bit). This is not RISC-V compliant and might have unintended SW side effects." severity warning;
 
-- U-extension requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
-- PMP requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires CPU_EXTENSION_RISCV_Zicsr extension." severity error;
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- Bus timeout --
assert not (BUS_TIMEOUT < 2) report "NEORV32 CPU CONFIG ERROR! Invalid bus access timeout value <BUS_TIMEOUT>. Has to be >= 2." severity error;
183,7 → 194,7
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 CPU CONFIG WARNING! Atomic operations extension (A) only supports <lr.w> and <sc.w> instructions." severity warning;
 
-- FIXME: Bit manipulation warning --
assert not (CPU_EXTENSION_RISCV_B = true) report "NEORV32 CPU CONFIG WARNING! Bit manipulation extension (B) is still HIGHLY EXPERIMENTAL (and spec. is not ratified yet)." severity warning;
assert not (CPU_EXTENSION_RISCV_B = true) report "NEORV32 CPU CONFIG WARNING! Bit manipulation extension (B) is still EXPERIMENTAL (and spec. is not ratified yet)." severity warning;
 
-- Co-processor timeout counter (for debugging only) --
assert not (cp_timeout_en_c = true) report "NEORV32 CPU CONFIG WARNING! Co-processor timeout counter enabled. This should be used for debugging/simulation only." severity warning;
191,17 → 202,20
-- PMP regions check --
assert not (PMP_NUM_REGIONS > 64) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions <PMP_NUM_REGIONS> out xf valid range (0..64)." severity error;
-- PMP granulartiy --
assert not ((is_power_of_two_f(PMP_MIN_GRANULARITY) = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be a power of two." severity error;
assert not ((PMP_MIN_GRANULARITY < 8) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! PMP granulartiy has to be >= 8 bytes." severity error;
assert not ((is_power_of_two_f(PMP_MIN_GRANULARITY) = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be a power of two." severity error;
assert not ((PMP_MIN_GRANULARITY < 8) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be >= 8 bytes." severity error;
-- PMP notifier --
assert not (PMP_NUM_REGIONS > 0) report "NEORV32 CPU CONFIG NOTE: Implementing physical memory protection (PMP) with " & integer'image(PMP_NUM_REGIONS) & " regions and a minimal granularity of " & integer'image(PMP_MIN_GRANULARITY) & " bytes." severity note;
-- PMP requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- HPM counters check --
assert not (HPM_NUM_CNTS > 29) report "NEORV32 CPU CONFIG ERROR! Number of HPM counters <HPM_NUM_CNTS> out of valid range (0..29)." severity error;
assert not ((HPM_CNT_WIDTH < 1) or (HPM_CNT_WIDTH > 64)) report "NEORV32 CPU CONFIG ERROR! HPM counter width <HPM_CNT_WIDTH> has to be 1..64 bit." severity error;
-- HPM counters notifier --
assert not (HPM_NUM_CNTS > 0) report "NEORV32 CPU CONFIG NOTE: Implementing " & integer'image(HPM_NUM_CNTS) & " HPM counters." severity note;
assert not (HPM_NUM_CNTS > 0) report "NEORV32 CPU CONFIG NOTE: Implementing " & integer'image(HPM_NUM_CNTS) & " HPM counters (each " & integer'image(HPM_CNT_WIDTH) & "-bit wide)." severity note;
-- HPM CNT requires Zicsr extension --
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (HPM_NUM_CNTS > 0)) report "NEORV32 CPU CONFIG ERROR! Performance monitors (HMP) require CPU_EXTENSION_RISCV_Zicsr extension." severity error;
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (HPM_NUM_CNTS > 0)) report "NEORV32 CPU CONFIG ERROR! Hardware performance monitors (HPM) require <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
 
-- Control Unit ---------------------------------------------------------------------------
220,11 → 234,14
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters
)
port map (
-- global control --
299,7 → 316,8
neorv32_cpu_alu_inst: neorv32_cpu_alu
generic map (
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
TINY_SHIFT_EN => TINY_SHIFT_EN -- use tiny (single-bit) shifter for shift operations
)
port map (
-- global control --
357,9 → 375,13
-- -------------------------------------------------------------------------------------------
-- "pseudo" co-processor for atomic operations
-- required to get the result of a store-conditional operation into the data path
atomic_op_cp: process(clk_i)
atomic_op_cp: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
atomic_sc_val <= def_rst_val_c;
atomic_sc_res <= def_rst_val_c;
atomic_sc_res_ff <= def_rst_val_c;
elsif rising_edge(clk_i) then
atomic_sc_val <= cp_start(1);
atomic_sc_res <= bus_excl_ok;
if (atomic_sc_val = '1') then
407,7 → 429,7
-- Co-Processor 3: CSR (Read) Access ('Zicsr' Extension) ----------------------------------
-- -------------------------------------------------------------------------------------------
-- "pseudo" co-processor for CSR *read* access operations
-- required to get the CSR read data into the data path
-- required to get CSR read data into the data path
cp_result(3) <= csr_rdata when (CPU_EXTENSION_RISCV_Zicsr = true) else (others => '0');
cp_valid(3) <= cp_start(3); -- always assigned even if Zicsr extension is disabled to make sure CPU does not get stalled if there is an accidental access
 
425,6 → 447,7
start_i => cp_start(4), -- trigger operation
-- data input --
frm_i => fpu_rm, -- rounding mode
cmp_i => comparator, -- comparator status
rs1_i => rs1, -- rf source 1
rs2_i => rs2, -- rf source 2
-- result and status --
442,7 → 465,7
end generate;
 
 
-- Co-Processor 5..7: Not Implemented Yet -------------------------------------------------
-- Co-Processor 5,6,7: Not Implemented Yet ------------------------------------------------
-- -------------------------------------------------------------------------------------------
cp_result(5) <= (others => '0');
cp_valid(5) <= '0';
/neorv32/trunk/rtl/core/neorv32_cpu_alu.vhd
43,8 → 43,9
 
entity neorv32_cpu_alu is
generic (
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false -- use tiny (single-bit) shifter for shift operations
);
port (
-- global control --
176,7 → 177,8
shifter.cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount
elsif (shifter.run = '1') then -- running shift
-- coarse shift: multiples of 4 --
if (or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
if (TINY_SHIFT_EN = false) and -- use coarse shifts first if TINY SHIFT option is NOT enabled
(or_all_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4);
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000";
186,7 → 188,7
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) &
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4);
end if;
-- fine shift: single shifts, 0..3 times --
-- fine shift: single shifts, 0..3 times; use ONLY single-bit shifts if TINY_SHIFT_EN is enabled (even smaller than the default approach) --
else
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1);
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical
/neorv32/trunk/rtl/core/neorv32_cpu_bus.vhd
179,9 → 179,11
 
-- Data Interface: Access Address ---------------------------------------------------------
-- -------------------------------------------------------------------------------------------
mem_adr_reg: process(clk_i)
mem_adr_reg: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
mar <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mo_we_c) = '1') then
mar <= addr_i;
end if;
213,9 → 215,11
 
-- Data Interface: Write Data -------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
mem_do_reg: process(clk_i)
mem_do_reg: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
mdo <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mo_we_c) = '1') then
mdo <= wdata_i; -- memory data output register (MDO)
end if;
254,9 → 258,11
 
-- Data Interface: Read Data --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
mem_out_buf: process(clk_i)
mem_out_buf: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
mdi <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_bus_mi_we_c) = '1') then
mdi <= d_bus_rdata; -- memory data input register (MDI)
end if;
442,9 → 448,11
-- Physical Memory Protection (PMP) -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- compute address masks (ITERATIVE!!!) --
pmp_masks: process(clk_i)
pmp_masks: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then -- address mask computation (not the actual address check!) has a latency of max +32 cycles
if (rstn_i = '0') then
pmp.addr_mask <= (others => (others => def_rst_val_c));
elsif rising_edge(clk_i) then -- address mask computation (not the actual address check!) has a latency of max +32 cycles
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions
pmp.addr_mask(r) <= (others => '0');
for i in pmp_g_c to data_width_c-1 loop
/neorv32/trunk/rtl/core/neorv32_cpu_control.vhd
60,11 → 60,14
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0 -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (1..64)
);
port (
-- global control --
113,6 → 116,14
 
architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
 
-- CPU core counter ([m]cycle, [m]instret) width - high/low parts --
constant cpu_cnt_lo_width_c : natural := natural(cond_sel_int_f(boolean(CPU_CNT_WIDTH < 32), CPU_CNT_WIDTH, 32));
constant cpu_cnt_hi_width_c : natural := natural(cond_sel_int_f(boolean(CPU_CNT_WIDTH > 32), CPU_CNT_WIDTH-32, 0));
 
-- HPM counter width - high/low parts --
constant hpm_cnt_lo_width_c : natural := natural(cond_sel_int_f(boolean(HPM_CNT_WIDTH < 32), HPM_CNT_WIDTH, 32));
constant hpm_cnt_hi_width_c : natural := natural(cond_sel_int_f(boolean(HPM_CNT_WIDTH > 32), HPM_CNT_WIDTH-32, 0));
 
-- instruction fetch enginge --
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_REQUEST, IFETCH_ISSUE);
type fetch_engine_t is record
254,10 → 265,10
type pmp_ctrl_rd_t is array (0 to 63) of std_ulogic_vector(7 downto 0);
type pmp_addr_rd_t is array (0 to 63) of std_ulogic_vector(data_width_c-1 downto 0);
type mhpmevent_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
type mhpmcnt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(32 downto 0);
type mhpmcnth_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(31 downto 0);
type mhpmcnt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(32 downto 0); -- 32-bit, plus 1-bit overflow
type mhpmcnth_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(31 downto 0); -- 32-bit
type mhpmevent_rd_t is array (0 to 29) of std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
type mhpmcnt_rd_t is array (0 to 29) of std_ulogic_vector(32 downto 0);
type mhpmcnt_rd_t is array (0 to 29) of std_ulogic_vector(31 downto 0);
type mhpmcnth_rd_t is array (0 to 29) of std_ulogic_vector(31 downto 0);
type csr_t is record
addr : std_ulogic_vector(11 downto 0); -- csr address
302,9 → 313,9
mhpmevent_rd : mhpmevent_rd_t; -- mhpmevent*: actual read data
--
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
--
mcycle : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit
minstret : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit
--
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W)
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W)
--
344,7 → 355,7
begin
 
-- ****************************************************************************************************************************
-- Instruction Fetch (always fetches aligned 32-bit chunks of data)
-- Instruction Fetch (always fetch 32-bit-aligned 32-bit chunks of data)
-- ****************************************************************************************************************************
 
-- Fetch Engine FSM Sync ------------------------------------------------------------------
354,7 → 365,7
if (rstn_i = '0') then
fetch_engine.state <= IFETCH_RESET;
fetch_engine.state_prev <= IFETCH_RESET;
fetch_engine.pc <= (others => '0');
fetch_engine.pc <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (fetch_engine.reset = '1') then
fetch_engine.state <= IFETCH_RESET;
425,9 → 436,12
 
-- Instruction Prefetch Buffer (FIFO) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
instr_prefetch_buffer: process(clk_i)
instr_prefetch_buffer_ctrl: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
ipb.w_pnt <= (others => def_rst_val_c);
ipb.r_pnt <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- write port --
if (ipb.clear = '1') then
ipb.w_pnt <= (others => '0');
434,9 → 448,6
elsif (ipb.we = '1') then
ipb.w_pnt <= std_ulogic_vector(unsigned(ipb.w_pnt) + 1);
end if;
if (ipb.we = '1') then -- write data
ipb.data(to_integer(unsigned(ipb.w_pnt(ipb.w_pnt'left-1 downto 0)))) <= ipb.wdata;
end if;
-- read port --
if (ipb.clear = '1') then
ipb.r_pnt <= (others => '0');
444,8 → 455,17
ipb.r_pnt <= std_ulogic_vector(unsigned(ipb.r_pnt) + 1);
end if;
end if;
end process instr_prefetch_buffer;
end process instr_prefetch_buffer_ctrl;
 
instr_prefetch_buffer_data: process(clk_i)
begin
if rising_edge(clk_i) then
if (ipb.we = '1') then -- write access
ipb.data(to_integer(unsigned(ipb.w_pnt(ipb.w_pnt'left-1 downto 0)))) <= ipb.wdata;
end if;
end if;
end process instr_prefetch_buffer_data;
 
-- async read --
ipb.rdata <= ipb.data(to_integer(unsigned(ipb.r_pnt(ipb.r_pnt'left-1 downto 0))));
 
468,7 → 488,7
if (rstn_i = '0') then
issue_engine.state <= ISSUE_ACTIVE;
issue_engine.align <= CPU_BOOT_ADDR(1); -- 32- or 16-bit boundary
issue_engine.buf <= (others => '0');
issue_engine.buf <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ipb.clear = '1') then
if (CPU_EXTENSION_RISCV_C = true) then
592,11 → 612,13
 
-- Immediate Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imm_gen: process(execute_engine.i_reg, clk_i)
imm_gen: process(execute_engine.i_reg, rstn_i, clk_i)
variable opcode_v : std_ulogic_vector(6 downto 0);
begin
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
if rising_edge(clk_i) then
if (rstn_i = '0') then
imm_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (execute_engine.state = BRANCH) then -- next_PC as immediate for jump-and-link operations (=return address) via ALU.MOV_B
imm_o <= execute_engine.next_pc;
else -- "normal" immediate from instruction word
657,14 → 679,26
 
-- Execute Engine FSM Sync ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- for registers that DO require a specific reset state --
execute_engine_fsm_sync_rst: process(rstn_i, clk_i)
execute_engine_fsm_sync: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
-- registers that DO require a specific reset state --
execute_engine.pc <= CPU_BOOT_ADDR(data_width_c-1 downto 1) & '0';
execute_engine.state <= SYS_WAIT;
execute_engine.sleep <= '0';
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
-- no dedicated RESEt required --
execute_engine.state_prev <= SYS_WAIT;
execute_engine.i_reg <= (others => def_rst_val_c);
execute_engine.is_ci <= def_rst_val_c;
execute_engine.is_cp_op <= def_rst_val_c;
execute_engine.last_pc <= (others => def_rst_val_c);
execute_engine.i_reg_last <= (others => def_rst_val_c);
execute_engine.next_pc <= (others => def_rst_val_c);
ctrl <= (others => def_rst_val_c);
--
ctrl(ctrl_bus_rd_c) <= '0';
ctrl(ctrl_bus_wr_c) <= '0';
elsif rising_edge(clk_i) then
-- PC update --
if (execute_engine.pc_we = '1') then
678,14 → 712,7
execute_engine.state <= execute_engine.state_nxt;
execute_engine.sleep <= execute_engine.sleep_nxt;
execute_engine.branched <= execute_engine.branched_nxt;
end if;
end process execute_engine_fsm_sync_rst;
 
 
-- for registers that do NOT require a specific reset state --
execute_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
--
execute_engine.state_prev <= execute_engine.state;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
707,6 → 734,7
end if;
end process execute_engine_fsm_sync;
 
 
-- PC increment for next linear instruction (+2 for compressed instr., +4 otherwise) --
execute_engine.next_pc_inc <= x"00000004" when ((execute_engine.is_ci = '0') or (CPU_EXTENSION_RISCV_C = false)) else x"00000002";
 
1139,7 → 1167,6
when ALU_WAIT => -- wait for multi-cycle ALU operation (shifter or CP) to finish
-- ------------------------------------------------------------
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (permanent write-back)
-- cp access or alu.shift? --
if (execute_engine.is_cp_op = '1') then
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
1148,7 → 1175,8
end if;
-- wait for result --
if (alu_wait_i = '0') then
execute_engine.state_nxt <= DISPATCH;
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
execute_engine.state_nxt <= DISPATCH;
end if;
 
 
1266,7 → 1294,7
csr_access_check: process(execute_engine.i_reg, csr)
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs
-- variable csr_racc_v : std_ulogic; -- to check access to write-only CSRs
variable csr_mcounteren_hpm_v : std_ulogic_vector(28 downto 0); -- max 29 HPM counters
variable csr_mcounteren_hpm_v : std_ulogic_vector(31 downto 0); -- max 29 HPM counters, plus 3 LSB-aligned dummy bits
begin
-- is this CSR instruction really going to write/read to/from a CSR? --
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
1280,8 → 1308,8
 
-- low privilege level access to hpm counters? --
csr_mcounteren_hpm_v := (others => '0');
if (CPU_EXTENSION_RISCV_U = true) then
csr_mcounteren_hpm_v(HPM_NUM_CNTS-1 downto 0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0);
if (CPU_EXTENSION_RISCV_U = true) and (HPM_NUM_CNTS /= 0) then
csr_mcounteren_hpm_v(3+(HPM_NUM_CNTS-1) downto 3+0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0);
else -- 'mcounteren' CSR is hardwired to zero if user mode is not implemented
csr_mcounteren_hpm_v := (others => '0');
end if;
1288,25 → 1316,25
 
-- check CSR access --
case csr.addr is
-- standard read/write CSRs --
when csr_fflags_c | csr_frm_c | csr_fcsr_c => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if Zfinx extension is enabled
--
when csr_mstatus_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mstatush_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_misa_c => csr_acc_valid <= csr.priv_m_mode;-- and (not csr_wacc_v); -- M-mode only, MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
when csr_mie_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mtvec_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mscratch_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mepc_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mcause_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mcounteren_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mtval_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_mip_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
 
-- user floating-point CSRs --
when csr_fflags_c | csr_frm_c | csr_fcsr_c =>
csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if Zfinx extension is implemented
 
-- machine trap setup --
when csr_mstatus_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mcounteren_c | csr_mstatush_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only, NOTE: MISA is read-only in the NEORV32 but we do not cause an exception here for compatibility
 
-- machine trap handling --
when csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mtval_c | csr_mip_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
-- physical memory protection - configuration --
when csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c |
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
 
-- physical memory protection - address --
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c |
csr_pmpaddr8_c | csr_pmpaddr9_c | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
csr_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c |
1316,9 → 1344,58
csr_pmpaddr48_c | csr_pmpaddr49_c | csr_pmpaddr50_c | csr_pmpaddr51_c | csr_pmpaddr52_c | csr_pmpaddr53_c | csr_pmpaddr54_c | csr_pmpaddr55_c |
csr_pmpaddr56_c | csr_pmpaddr57_c | csr_pmpaddr58_c | csr_pmpaddr59_c | csr_pmpaddr60_c | csr_pmpaddr61_c | csr_pmpaddr62_c | csr_pmpaddr63_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_mcountinhibit_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
 
-- machine counters/timers --
when csr_mcycle_c =>
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode only, access if implemented
when csr_mcycleh_c =>
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode only, access if implemented
when csr_minstret_c =>
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode only, access if implemented
when csr_minstreth_c =>
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode only, access if implemented
 
when csr_mhpmcounter3_c | csr_mhpmcounter4_c | csr_mhpmcounter5_c | csr_mhpmcounter6_c | csr_mhpmcounter7_c | csr_mhpmcounter8_c | -- LOW
csr_mhpmcounter9_c | csr_mhpmcounter10_c | csr_mhpmcounter11_c | csr_mhpmcounter12_c | csr_mhpmcounter13_c | csr_mhpmcounter14_c |
csr_mhpmcounter15_c | csr_mhpmcounter16_c | csr_mhpmcounter17_c | csr_mhpmcounter18_c | csr_mhpmcounter19_c | csr_mhpmcounter20_c |
csr_mhpmcounter21_c | csr_mhpmcounter22_c | csr_mhpmcounter23_c | csr_mhpmcounter24_c | csr_mhpmcounter25_c | csr_mhpmcounter26_c |
csr_mhpmcounter27_c | csr_mhpmcounter28_c | csr_mhpmcounter29_c | csr_mhpmcounter30_c | csr_mhpmcounter31_c |
csr_mhpmcounter3h_c | csr_mhpmcounter4h_c | csr_mhpmcounter5h_c | csr_mhpmcounter6h_c | csr_mhpmcounter7h_c | csr_mhpmcounter8h_c | -- HIGH
csr_mhpmcounter9h_c | csr_mhpmcounter10h_c | csr_mhpmcounter11h_c | csr_mhpmcounter12h_c | csr_mhpmcounter13h_c | csr_mhpmcounter14h_c |
csr_mhpmcounter15h_c | csr_mhpmcounter16h_c | csr_mhpmcounter17h_c | csr_mhpmcounter18h_c | csr_mhpmcounter19h_c | csr_mhpmcounter20h_c |
csr_mhpmcounter21h_c | csr_mhpmcounter22h_c | csr_mhpmcounter23h_c | csr_mhpmcounter24h_c | csr_mhpmcounter25h_c | csr_mhpmcounter26h_c |
csr_mhpmcounter27h_c | csr_mhpmcounter28h_c | csr_mhpmcounter29h_c | csr_mhpmcounter30h_c | csr_mhpmcounter31h_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
-- user counters/timers --
when csr_cycle_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy) and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
when csr_cycleh_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy) and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
when csr_instret_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir) and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
when csr_instreth_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir) and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented
 
when csr_time_c | csr_timeh_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
 
when csr_hpmcounter3_c | csr_hpmcounter4_c | csr_hpmcounter5_c | csr_hpmcounter6_c | csr_hpmcounter7_c | csr_hpmcounter8_c | -- LOW
csr_hpmcounter9_c | csr_hpmcounter10_c | csr_hpmcounter11_c | csr_hpmcounter12_c | csr_hpmcounter13_c | csr_hpmcounter14_c |
csr_hpmcounter15_c | csr_hpmcounter16_c | csr_hpmcounter17_c | csr_hpmcounter18_c | csr_hpmcounter19_c | csr_hpmcounter20_c |
csr_hpmcounter21_c | csr_hpmcounter22_c | csr_hpmcounter23_c | csr_hpmcounter24_c | csr_hpmcounter25_c | csr_hpmcounter26_c |
csr_hpmcounter27_c | csr_hpmcounter28_c | csr_hpmcounter29_c | csr_hpmcounter30_c | csr_hpmcounter31_c |
csr_hpmcounter3h_c | csr_hpmcounter4h_c | csr_hpmcounter5h_c | csr_hpmcounter6h_c | csr_hpmcounter7h_c | csr_hpmcounter8h_c | -- HIGH
csr_hpmcounter9h_c | csr_hpmcounter10h_c | csr_hpmcounter11h_c | csr_hpmcounter12h_c | csr_hpmcounter13h_c | csr_hpmcounter14h_c |
csr_hpmcounter15h_c | csr_hpmcounter16h_c | csr_hpmcounter17h_c | csr_hpmcounter18h_c | csr_hpmcounter19h_c | csr_hpmcounter20h_c |
csr_hpmcounter21h_c | csr_hpmcounter22h_c | csr_hpmcounter23h_c | csr_hpmcounter24h_c | csr_hpmcounter25h_c | csr_hpmcounter26h_c |
csr_hpmcounter27h_c | csr_hpmcounter28h_c | csr_hpmcounter29h_c | csr_hpmcounter30h_c | csr_hpmcounter31h_c =>
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(to_integer(unsigned(csr.addr(4 downto 0))))); -- M-mode, U-mode if authorized, read-only
 
-- machine counter setup --
when csr_mcountinhibit_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
when csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c |
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c |
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
1325,104 → 1402,16
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_mcycle_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_minstret_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_mhpmcounter3_c | csr_mhpmcounter4_c | csr_mhpmcounter5_c | csr_mhpmcounter6_c | csr_mhpmcounter7_c | csr_mhpmcounter8_c |
csr_mhpmcounter9_c | csr_mhpmcounter10_c | csr_mhpmcounter11_c | csr_mhpmcounter12_c | csr_mhpmcounter13_c | csr_mhpmcounter14_c |
csr_mhpmcounter15_c | csr_mhpmcounter16_c | csr_mhpmcounter17_c | csr_mhpmcounter18_c | csr_mhpmcounter19_c | csr_mhpmcounter20_c |
csr_mhpmcounter21_c | csr_mhpmcounter22_c | csr_mhpmcounter23_c | csr_mhpmcounter24_c | csr_mhpmcounter25_c | csr_mhpmcounter26_c |
csr_mhpmcounter27_c | csr_mhpmcounter28_c | csr_mhpmcounter29_c | csr_mhpmcounter30_c | csr_mhpmcounter31_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_mcycleh_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
when csr_minstreth_c => csr_acc_valid <= csr.priv_m_mode; -- M-mode only
--
when csr_mhpmcounter3h_c | csr_mhpmcounter4h_c | csr_mhpmcounter5h_c | csr_mhpmcounter6h_c | csr_mhpmcounter7h_c | csr_mhpmcounter8h_c |
csr_mhpmcounter9h_c | csr_mhpmcounter10h_c | csr_mhpmcounter11h_c | csr_mhpmcounter12h_c | csr_mhpmcounter13h_c | csr_mhpmcounter14h_c |
csr_mhpmcounter15h_c | csr_mhpmcounter16h_c | csr_mhpmcounter17h_c | csr_mhpmcounter18h_c | csr_mhpmcounter19h_c | csr_mhpmcounter20h_c |
csr_mhpmcounter21h_c | csr_mhpmcounter22h_c | csr_mhpmcounter23h_c | csr_mhpmcounter24h_c | csr_mhpmcounter25h_c | csr_mhpmcounter26h_c |
csr_mhpmcounter27h_c | csr_mhpmcounter28h_c | csr_mhpmcounter29h_c | csr_mhpmcounter30h_c | csr_mhpmcounter31h_c =>
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
-- standard read-only CSRs --
when csr_cycle_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
when csr_time_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
when csr_instret_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
--
when csr_hpmcounter3_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(00)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter4_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(01)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter5_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(02)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter6_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(03)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter7_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(04)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter8_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(05)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter9_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(06)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter10_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(07)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter11_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(08)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter12_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(09)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter13_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(10)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter14_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(11)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter15_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(12)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter16_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(13)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter17_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(14)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter18_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(15)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter19_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(16)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter20_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(17)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter21_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(18)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter22_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(19)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter23_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(20)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter24_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(21)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter25_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(22)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter26_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(23)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter27_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(24)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter28_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(25)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter29_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(26)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter30_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(27)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter31_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(28)); -- M-mode, U-mode if authorized, read-only
--
when csr_cycleh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only
when csr_timeh_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only
when csr_instreth_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only
--
when csr_hpmcounter3h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(00)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter4h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(01)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter5h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(02)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter6h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(03)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter7h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(04)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter8h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(05)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter9h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(06)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter10h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(07)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter11h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(08)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter12h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(09)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter13h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(10)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter14h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(11)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter15h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(12)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter16h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(13)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter17h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(14)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter18h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(15)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter19h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(16)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter20h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(17)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter21h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(18)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter22h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(19)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter23h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(20)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter24h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(21)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter25h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(22)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter26h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(23)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter27h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(24)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter28h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(25)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter29h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(26)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter30h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(27)); -- M-mode, U-mode if authorized, read-only
when csr_hpmcounter31h_c => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(28)); -- M-mode, U-mode if authorized, read-only
--
when csr_mvendorid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
when csr_marchid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
when csr_mimpid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
when csr_mhartid_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
-- custom read-only CSRs --
when csr_mzext_c => csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
--
when others => csr_acc_valid <= '0'; -- invalid access
-- machine information registers --
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c =>
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
-- custom (NEORV32-specific) read-only CSRs --
when csr_mzext_c =>
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
-- undefined / not implemented --
when others =>
csr_acc_valid <= '0'; -- invalid access
end case;
end process csr_access_check;
 
1658,12 → 1647,12
begin
if (rstn_i = '0') then
trap_ctrl.exc_buf <= (others => '0');
trap_ctrl.irq_buf <= (others => '0');
trap_ctrl.irq_buf <= (others => def_rst_val_c);
trap_ctrl.exc_ack <= '0';
trap_ctrl.irq_ack <= (others => '0');
trap_ctrl.env_start <= '0';
trap_ctrl.cause <= trap_reset_c;
trap_ctrl.firq_sync <= (others => '0');
trap_ctrl.cause <= (others => def_rst_val_c);
trap_ctrl.firq_sync <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_Zicsr = true) then
-- exception buffer: misaligned load/store/instruction address
1910,49 → 1899,51
-- -------------------------------------------------------------------------------------------
csr_write_access: process(rstn_i, clk_i)
begin
-- NOTE: Register that reset to "def_rst_val_c" do NOT actually have a real reset by default (def_rst_val_c = '-') and have to be
-- explicitly initialized by software!
-- see: https://forums.xilinx.com/t5/General-Technical-Discussion/quot-Don-t-care-quot-reset-value/td-p/412845
if (rstn_i = '0') then
csr.we <= '0';
--
csr.mstatus_mie <= '0';
csr.mstatus_mpie <= '0';
csr.mstatus_mpp <= priv_mode_m_c; -- start in MACHINE mode
csr.mstatus_mpp <= (others => '0');
csr.privilege <= priv_mode_m_c; -- start in MACHINE mode
csr.mie_msie <= '0';
csr.mie_meie <= '0';
csr.mie_mtie <= '0';
csr.mie_firqe <= (others => '0');
csr.mtvec <= (others => '0');
csr.mscratch <= x"19880704"; -- :)
csr.mepc <= (others => '0');
csr.mcause <= trap_reset_c; -- mcause = TRAP_CODE_RESET (hardware reset, "non-maskable interrupt")
csr.mtval <= (others => '0');
csr.mip_clear <= (others => '0');
csr.mie_msie <= def_rst_val_c;
csr.mie_meie <= def_rst_val_c;
csr.mie_mtie <= def_rst_val_c;
csr.mie_firqe <= (others => def_rst_val_c);
csr.mtvec <= (others => def_rst_val_c);
csr.mscratch <= x"19880704";
csr.mepc <= (others => def_rst_val_c);
csr.mcause <= (others => def_rst_val_c);
csr.mtval <= (others => def_rst_val_c);
csr.mip_clear <= (others => def_rst_val_c);
--
csr.pmpcfg <= (others => (others => '0'));
csr.pmpaddr <= (others => (others => '1'));
csr.pmpaddr <= (others => (others => def_rst_val_c));
--
csr.mhpmevent <= (others => (others => '0'));
csr.mhpmevent <= (others => (others => def_rst_val_c));
--
csr.mcounteren_cy <= '0';
csr.mcounteren_tm <= '0';
csr.mcounteren_ir <= '0';
csr.mcounteren_hpm <= (others => '0');
csr.mcounteren_cy <= def_rst_val_c;
csr.mcounteren_tm <= def_rst_val_c;
csr.mcounteren_ir <= def_rst_val_c;
csr.mcounteren_hpm <= (others => def_rst_val_c);
--
csr.mcountinhibit_cy <= '0';
csr.mcountinhibit_ir <= '0';
csr.mcountinhibit_hpm <= (others => '0');
csr.mcountinhibit_cy <= def_rst_val_c;
csr.mcountinhibit_ir <= def_rst_val_c;
csr.mcountinhibit_hpm <= (others => def_rst_val_c);
--
csr.fflags <= (others => '0');
csr.frm <= (others => '0');
csr.fflags <= (others => def_rst_val_c);
csr.frm <= (others => def_rst_val_c);
 
elsif rising_edge(clk_i) then
-- write access? --
csr.we <= csr.we_nxt;
-- defaults --
csr.mip_clear <= (others => '0');
 
if (CPU_EXTENSION_RISCV_Zicsr = true) then
 
-- defaults --
csr.mip_clear <= (others => '0');
 
-- --------------------------------------------------------------------------------
-- CSR access by application software
-- --------------------------------------------------------------------------------
1960,25 → 1951,24
 
-- user floating-point CSRs --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_class_float_c) then -- floating point CSR class
-- R/W: fflags - floating-point (FPU) exception flags --
if (csr.addr(3 downto 0) = csr_fflags_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
csr.fflags <= csr.wdata(4 downto 0);
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- floating point CSR class
if (csr.addr(11 downto 4) = csr_class_float_c) and (csr.addr(3 downto 2) = csr_fcsr_c(3 downto 2)) then
case csr.addr(1 downto 0) is
when "01" => -- R/W: fflags - floating-point (FPU) exception flags
csr.fflags <= csr.wdata(4 downto 0);
when "10" => -- R/W: frm - floating-point (FPU) rounding mode
csr.frm <= csr.wdata(2 downto 0);
when "11" => -- R/W: fcsr - floating-point (FPU) control/status (frm + fflags)
csr.frm <= csr.wdata(7 downto 5);
csr.fflags <= csr.wdata(4 downto 0);
when others => NULL;
end case;
end if;
-- R/W: frm - floating-point (FPU) rounding mode --
if (csr.addr(3 downto 0) = csr_frm_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
csr.frm <= csr.wdata(2 downto 0);
end if;
-- R/W: fflags - floating-point (FPU) control/status (frm + fflags) --
if (csr.addr(3 downto 0) = csr_fcsr_c(3 downto 0)) and (CPU_EXTENSION_RISCV_Zfinx = true) then
csr.frm <= csr.wdata(7 downto 5);
csr.fflags <= csr.wdata(4 downto 0);
end if;
end if;
 
-- machine trap setup --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_setup_c) then -- ftrap setup CSR class
if (csr.addr(11 downto 4) = csr_class_setup_c) then -- ftrap setup CSR class
-- R/W: mstatus - machine status register --
if (csr.addr(3 downto 0) = csr_mstatus_c(3 downto 0)) then
csr.mstatus_mie <= csr.wdata(03);
2004,8 → 1994,8
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
end if;
-- R/W: machine counter enable register --
if (csr.addr(3 downto 0) = csr_mcounteren_c(3 downto 0)) then
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
if (csr.addr(3 downto 0) = csr_mcounteren_c(3 downto 0)) then
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h]
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h]
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
2047,8 → 2037,8
 
-- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
if (PMP_NUM_REGIONS > 0) then
if (PMP_NUM_REGIONS > 0) then
if (csr.addr(11 downto 4) = csr_class_pmpcfg_c) then -- pmp configuration CSR class
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(3 downto 0) = std_ulogic_vector(to_unsigned(i, 4))) then
if (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpcfg access
2068,9 → 2058,9
 
-- physical memory protection: R/W: pmpaddr* - PMP address registers --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_pmpaddr0_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr16_c(11 downto 4)) or
(csr.addr(11 downto 4) = csr_pmpaddr32_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr48_c(11 downto 4)) then
if (PMP_NUM_REGIONS > 0) then
if (PMP_NUM_REGIONS > 0) then
if (csr.addr(11 downto 4) = csr_pmpaddr0_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr16_c(11 downto 4)) or
(csr.addr(11 downto 4) = csr_pmpaddr32_c(11 downto 4)) or (csr.addr(11 downto 4) = csr_pmpaddr48_c(11 downto 4)) then
for i in 0 to PMP_NUM_REGIONS-1 loop
if (csr.addr(6 downto 0) = std_ulogic_vector(unsigned(csr_pmpaddr0_c(6 downto 0)) + i)) and (csr.pmpcfg(i)(7) = '0') then -- unlocked pmpaddr access
csr.pmpaddr(i) <= csr.wdata;
2082,22 → 2072,20
 
-- machine counter setup --
-- --------------------------------------------------------------------
-- R/W: mcountinhibit - machine counter-inhibit register --
if (csr.addr = csr_mcountinhibit_c) then
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
end if;
 
-- machine performance-monitoring event selector --
-- --------------------------------------------------------------------
if (unsigned(csr.addr) >= unsigned(csr_mhpmevent3_c)) and (unsigned(csr.addr) <= unsigned(csr_mhpmevent31_c)) then
if (csr.addr(11 downto 5) = csr_cnt_setup_c) then -- counter configuration CSR class
-- R/W: mcountinhibit - machine counter-inhibit register --
if (csr.addr(4 downto 0) = csr_mcountinhibit_c(4 downto 0)) then
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
end if;
-- machine performance-monitoring event selector --
if (HPM_NUM_CNTS > 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
csr.mhpmevent(i)(1) <= '0'; -- would be used for "TIME"
end if;
csr.mhpmevent(i)(hpmcnt_event_never_c) <= '0'; -- would be used for "TIME"
end loop; -- i (CSRs)
end if;
end if;
2123,7 → 2111,7
-- trap PC --
if (trap_ctrl.cause(trap_ctrl.cause'left) = '1') then -- for INTERRUPTS
csr.mepc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
else -- for EXCEPTIONS
else -- for sync. EXCEPTIONS
csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
end if;
-- trap value --
2194,6 → 2182,14
csr.mcountinhibit_hpm <= (others => '0');
end if;
 
-- cpu counters disabled --
if (CPU_CNT_WIDTH = 0) then
csr.mcounteren_cy <= '0';
csr.mcounteren_ir <= '0';
csr.mcountinhibit_cy <= '0';
csr.mcountinhibit_ir <= '0';
end if;
 
-- floating-point extension disabled --
if (CPU_EXTENSION_RISCV_Zfinx = false) then
csr.fflags <= (others => '0');
2203,7 → 2199,7
end if;
end process csr_write_access;
 
-- decode privilege mode --
-- decode current privilege mode --
csr.priv_m_mode <= '1' when (csr.privilege = priv_mode_m_c) else '0';
csr.priv_u_mode <= '1' when (csr.privilege = priv_mode_u_c) else '0';
 
2212,11 → 2208,13
begin
pmp_addr_o <= (others => (others => '0'));
pmp_ctrl_o <= (others => (others => '0'));
for i in 0 to PMP_NUM_REGIONS-1 loop
pmp_addr_o(i) <= csr.pmpaddr(i) & "11";
pmp_addr_o(i)(index_size_f(PMP_MIN_GRANULARITY)-4 downto 0) <= (others => '1');
pmp_ctrl_o(i) <= csr.pmpcfg(i);
end loop; -- i
if (PMP_NUM_REGIONS /= 0) then
for i in 0 to PMP_NUM_REGIONS-1 loop
pmp_addr_o(i) <= csr.pmpaddr(i) & "11";
pmp_addr_o(i)(index_size_f(PMP_MIN_GRANULARITY)-4 downto 0) <= (others => '1');
pmp_ctrl_o(i) <= csr.pmpcfg(i);
end loop; -- i
end if;
end process pmp_output;
 
-- PMP read dummy --
2224,13 → 2222,15
begin
csr.pmpcfg_rd <= (others => (others => '0'));
csr.pmpaddr_rd <= (others => (others => '0'));
for i in 0 to PMP_NUM_REGIONS-1 loop
csr.pmpcfg_rd(i) <= csr.pmpcfg(i);
csr.pmpaddr_rd(i) <= csr.pmpaddr(i);
if (csr.pmpcfg(i)(4 downto 3) = "00") then -- mode = off
csr.pmpaddr_rd(i)(index_size_f(PMP_MIN_GRANULARITY)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end loop; -- i
if (PMP_NUM_REGIONS /= 0) then
for i in 0 to PMP_NUM_REGIONS-1 loop
csr.pmpcfg_rd(i) <= csr.pmpcfg(i);
csr.pmpaddr_rd(i) <= csr.pmpaddr(i);
if (csr.pmpcfg(i)(4 downto 3) = "00") then -- mode = off
csr.pmpaddr_rd(i)(index_size_f(PMP_MIN_GRANULARITY)-3 downto 0) <= (others => '0'); -- required for granularity check by SW
end if;
end loop; -- i
end if;
end process pmp_rd_dummy;
 
-- FPU rounding mode --
2239,59 → 2239,94
 
-- Control and Status Registers - Counters ------------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_counters: process(clk_i)
csr_counters: process(rstn_i, clk_i)
begin
-- Counter CSRs (each counter is split into two 32-bit counters)
if rising_edge(clk_i) then
-- Counter CSRs (each counter is split into two 32-bit counters - coupled via an MSB overflow detector)
if (rstn_i = '0') then
csr.mcycle <= (others => def_rst_val_c);
mcycle_msb <= def_rst_val_c;
csr.mcycleh <= (others => def_rst_val_c);
csr.minstret <= (others => def_rst_val_c);
minstret_msb <= def_rst_val_c;
csr.minstreth <= (others => def_rst_val_c);
csr.mhpmcounter <= (others => (others => def_rst_val_c));
mhpmcounter_msb <= (others => def_rst_val_c);
csr.mhpmcounterh <= (others => (others => def_rst_val_c));
elsif rising_edge(clk_i) then
 
-- [m]cycle --
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
csr.mcycle <= '0' & csr.wdata;
csr.mcycle(csr.mcycle'left downto cpu_cnt_lo_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (cpu_cnt_lo_width_c = 0) then
csr.mcycle <= (others => '0');
mcycle_msb <= '0';
elsif (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
csr.mcycle(cpu_cnt_lo_width_c downto 0) <= '0' & csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
mcycle_msb <= '0';
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
csr.mcycle <= std_ulogic_vector(unsigned(csr.mcycle) + 1);
mcycle_msb <= csr.mcycle(csr.mcycle'left);
csr.mcycle(cpu_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned(csr.mcycle(cpu_cnt_lo_width_c downto 0)) + 1);
mcycle_msb <= csr.mcycle(cpu_cnt_lo_width_c);
end if;
 
-- [m]cycleh --
if (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access
csr.mcycleh <= csr.wdata;
elsif ((mcycle_msb xor csr.mcycle(csr.mcycle'left)) = '1') then -- automatic update (continued)
csr.mcycleh <= std_ulogic_vector(unsigned(csr.mcycleh) + 1);
csr.mcycleh(csr.mcycleh'left downto cpu_cnt_hi_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (cpu_cnt_hi_width_c = 0) then
csr.mcycleh <= (others => '0');
elsif (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
elsif ((mcycle_msb xor csr.mcycle(cpu_cnt_lo_width_c)) = '1') then -- automatic update (continued)
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + 1);
end if;
 
-- [m]instret --
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
csr.minstret <= '0' & csr.wdata;
csr.minstret(csr.minstret'left downto cpu_cnt_lo_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (cpu_cnt_lo_width_c = 0) then
csr.minstret <= (others => '0');
minstret_msb <= '0';
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
csr.minstret <= std_ulogic_vector(unsigned(csr.minstret) + 1);
elsif (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
csr.minstret(cpu_cnt_lo_width_c downto 0) <= '0' & csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
minstret_msb <= '0';
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
csr.minstret(cpu_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned(csr.minstret(cpu_cnt_lo_width_c downto 0)) + 1);
minstret_msb <= csr.minstret(csr.minstret'left);
end if;
 
-- [m]instreth --
if (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access
csr.minstreth <= csr.wdata;
elsif ((minstret_msb xor csr.minstret(csr.minstret'left)) = '1') then -- automatic update (continued)
csr.minstreth <= std_ulogic_vector(unsigned(csr.minstreth) + 1);
csr.minstreth(csr.minstreth'left downto cpu_cnt_hi_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (cpu_cnt_hi_width_c = 0) then
csr.minstreth <= (others => '0');
elsif (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
elsif ((minstret_msb xor csr.minstret(cpu_cnt_lo_width_c)) = '1') then -- automatic update (continued)
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + 1);
end if;
 
-- [machine] hardware performance monitors (counters) --
for i in 0 to HPM_NUM_CNTS-1 loop
-- [m]hpmcounter* --
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
csr.mhpmcounter(i) <= '0' & csr.wdata;
csr.mhpmcounter(i)(csr.mhpmcounter(i)'left downto hpm_cnt_lo_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (hpm_cnt_lo_width_c = 0) then
csr.mhpmcounter(i) <= (others => '0');
mhpmcounter_msb(i) <= '0';
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
csr.mhpmcounter(i) <= std_ulogic_vector(unsigned(csr.mhpmcounter(i)) + 1);
mhpmcounter_msb(i) <= csr.mhpmcounter(i)(csr.mhpmcounter(i)'left);
else
-- [m]hpmcounter* --
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
csr.mhpmcounter(i)(hpm_cnt_lo_width_c downto 0) <= '0' & csr.wdata(hpm_cnt_lo_width_c-1 downto 0);
mhpmcounter_msb(i) <= '0';
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
csr.mhpmcounter(i)(hpm_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounter(i)(hpm_cnt_lo_width_c downto 0)) + 1);
mhpmcounter_msb(i) <= csr.mhpmcounter(i)(csr.mhpmcounter(i)'left);
end if;
end if;
 
-- [m]hpmcounter*h --
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
csr.mhpmcounterh(i) <= csr.wdata;
elsif ((mhpmcounter_msb(i) xor csr.mhpmcounter(i)(csr.mhpmcounter(i)'left)) = '1') then -- automatic update (continued)
csr.mhpmcounterh(i) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)) + 1);
csr.mhpmcounterh(i)(csr.mhpmcounterh(i)'left downto hpm_cnt_hi_width_c+1) <= (others => '0'); -- set unsued bits to zero
if (hpm_cnt_hi_width_c = 0) then
csr.mhpmcounterh(i) <= (others => '0');
else
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.wdata(hpm_cnt_hi_width_c-1 downto 0);
elsif ((mhpmcounter_msb(i) xor csr.mhpmcounter(i)(hpm_cnt_lo_width_c)) = '1') then -- automatic update (continued)
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + 1);
end if;
end if;
end loop; -- i
 
2304,34 → 2339,45
csr.mhpmevent_rd <= (others => (others => '0'));
csr.mhpmcounter_rd <= (others => (others => '0'));
csr.mhpmcounterh_rd <= (others => (others => '0'));
for i in 0 to HPM_NUM_CNTS-1 loop
csr.mhpmevent_rd(i) <= csr.mhpmevent(i);
csr.mhpmcounter_rd(i) <= csr.mhpmcounter(i);
csr.mhpmcounterh_rd(i) <= csr.mhpmcounterh(i);
end loop; -- i
if (HPM_NUM_CNTS /= 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
csr.mhpmevent_rd(i) <= csr.mhpmevent(i);
if (hpm_cnt_lo_width_c > 0) then
csr.mhpmcounter_rd(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0);
end if;
if (hpm_cnt_hi_width_c > 0) then
csr.mhpmcounterh_rd(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0);
end if;
end loop; -- i
end if;
end process hpm_rd_dummy;
 
 
-- (HPM) Counter Event Control ------------------------------------------------------------
-- Hardware Performance Monitor - Counter Event Control -----------------------------------
-- -------------------------------------------------------------------------------------------
hpmcnt_ctrl: process(clk_i)
hpmcnt_ctrl: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
cnt_event <= (others => def_rst_val_c);
hpmcnt_trigger <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- buffer event sources --
cnt_event <= cnt_event_nxt;
-- enable selected triggers by ANDing actual events and according CSR configuration bits --
-- OR everything to see if counter should increment --
hpmcnt_trigger <= (others => '0'); -- default
for i in 0 to HPM_NUM_CNTS-1 loop
hpmcnt_trigger(i) <= or_all_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0));
end loop; -- i
if (HPM_NUM_CNTS /= 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
hpmcnt_trigger(i) <= or_all_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0));
end loop; -- i
end if;
end if;
end process hpmcnt_ctrl;
 
-- counter event trigger - RISC-V specific --
cnt_event_nxt(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
cnt_event_nxt(hpmcnt_event_never_c) <= '0'; -- undefined (never)
cnt_event_nxt(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- retired instruction
-- counter event trigger - RISC-V-specific --
cnt_event_nxt(hpmcnt_event_cy_c) <= not execute_engine.sleep; -- active cycle
cnt_event_nxt(hpmcnt_event_never_c) <= '0'; -- undefined (never)
cnt_event_nxt(hpmcnt_event_ir_c) <= '1' when (execute_engine.state = EXECUTE) else '0'; -- retired instruction
 
-- counter event trigger - custom / NEORV32-specific --
cnt_event_nxt(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction
2353,9 → 2399,12
 
-- Control and Status Registers - Read Access ---------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_read_access: process(clk_i)
csr_read_access: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
csr.re <= def_rst_val_c;
csr.rdata <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
csr.re <= csr.re_nxt; -- read access?
csr.rdata <= (others => '0'); -- default output
if (CPU_EXTENSION_RISCV_Zicsr = true) and (csr.re = '1') then
2373,7 → 2422,7
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
csr.rdata(2 downto 0) <= csr.frm;
end if;
when csr_fcsr_c => -- R/W: fflags - floating-point (FPU) control/status (frm + fflags)
when csr_fcsr_c => -- R/W: fcsr - floating-point (FPU) control/status (frm + fflags)
csr.rdata <= (others => '0');
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
csr.rdata(7 downto 5) <= csr.frm;
2394,7 → 2443,6
csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- B CPU extension
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
csr.rdata(05) <= '0'; -- F CPU extension
csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- U CPU extension
2411,13 → 2459,12
when csr_mtvec_c => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
csr.rdata <= csr.mtvec(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
when csr_mcounteren_c => -- R/W: machine counter enable register
csr.rdata <= (others => '0');
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
csr.rdata(0) <= csr.mcounteren_cy; -- enable user-level access to cycle[h]
csr.rdata(1) <= csr.mcounteren_tm; -- enable user-level access to time[h]
csr.rdata(2) <= csr.mcounteren_ir; -- enable user-level access to instret[h]
csr.rdata(csr.mcounteren_hpm'left+3 downto 3) <= csr.mcounteren_hpm; -- enable user-level access to hpmcounterx[h]
else
csr.rdata <= (others => '0');
end if;
 
-- machine trap handling --
2562,17 → 2609,17
 
-- counters and timers --
when csr_cycle_c | csr_mcycle_c => -- (R)/(W): [m]cycle: Cycle counter LOW
csr.rdata <= csr.mcycle(31 downto 0);
csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle(cpu_cnt_lo_width_c-1 downto 0);
when csr_time_c => -- (R)/-: time: System time LOW (from MTIME unit)
csr.rdata <= time_i(31 downto 0);
when csr_instret_c | csr_minstret_c => -- (R)/(W): [m]instret: Instructions-retired counter LOW
csr.rdata <= csr.minstret(31 downto 0);
csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret(cpu_cnt_lo_width_c-1 downto 0);
when csr_cycleh_c | csr_mcycleh_c => -- (R)/(W): [m]cycleh: Cycle counter HIGH
csr.rdata <= csr.mcycleh(31 downto 0);
csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0);
when csr_timeh_c => -- (R)/-: timeh: System time HIGH (from MTIME unit)
csr.rdata <= time_i(63 downto 32);
when csr_instreth_c | csr_minstreth_c => -- (R)/(W): [m]instreth: Instructions-retired counter HIGH
csr.rdata <= csr.minstreth(31 downto 0);
csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.minstreth(cpu_cnt_hi_width_c-1 downto 0);
 
-- hardware performance counters --
when csr_hpmcounter3_c | csr_mhpmcounter3_c => csr.rdata <= csr.mhpmcounter_rd(00)(31 downto 0); -- (R)/(W): [m]hpmcounter3 - low
2653,6 → 2700,16
csr.rdata(3) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- Zbs (B)
csr.rdata(4) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- Zba (B)
csr.rdata(5) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative")
if (CPU_CNT_WIDTH = 64) then
csr.rdata(6) <= '0'; -- Zxscnt (custom)
csr.rdata(7) <= '0'; -- Zxnocnt (custom)
elsif (CPU_CNT_WIDTH = 0) then
csr.rdata(6) <= '0'; -- Zxscnt (custom)
csr.rdata(7) <= '1'; -- Zxnocnt (custom)
else -- counters available but 0-bit < actual_size < 64-bit
csr.rdata(6) <= '1'; -- Zxscnt (custom)
csr.rdata(7) <= '0'; -- Zxnocnt (custom)
end if;
 
-- undefined/unavailable --
when others =>
/neorv32/trunk/rtl/core/neorv32_cpu_cp_bitmanip.vhd
181,10 → 181,10
begin
if (rstn_i = '0') then
ctrl_state <= S_IDLE;
cmd_buf <= (others => '0');
rs1_reg <= (others => '0');
rs2_reg <= (others => '0');
less_ff <= '0';
cmd_buf <= (others => def_rst_val_c);
rs1_reg <= (others => def_rst_val_c);
rs2_reg <= (others => def_rst_val_c);
less_ff <= def_rst_val_c;
shifter.start <= '0';
valid <= '0';
elsif rising_edge(clk_i) then
247,10 → 247,15
 
-- Shifter Function Core ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
shifter_unit: process(clk_i)
shifter_unit: process(rstn_i, clk_i)
variable new_bit_v : std_ulogic;
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
shifter.cnt <= (others => def_rst_val_c);
shifter.sreg <= (others => def_rst_val_c);
shifter.cnt_max <= (others => def_rst_val_c);
shifter.bcnt <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (shifter.start = '1') then -- trigger new shift
shifter.cnt <= (others => '0');
-- shift operand --
397,9 → 402,11
 
-- Output Gate ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
output_gate: process(clk_i)
output_gate: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
res_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
res_o <= (others => '0');
if (valid = '1') then
res_o <= res_out(op_clz_c) or res_out(op_cpop_c) or -- res_out(op_ctz_c) is unused here
/neorv32/trunk/rtl/core/neorv32_cpu_cp_fpu.vhd
64,6 → 64,7
start_i : in std_ulogic; -- trigger operation
-- data input --
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
-- result and status --
168,9 → 169,9
signal fpu_operands : fpu_operands_t;
 
-- floating-point comparator --
signal cmp_ff : std_ulogic_vector(01 downto 0);
signal comp_equal_ff : std_ulogic;
signal comp_less_ff : std_ulogic;
signal comp_less : std_ulogic;
 
-- functional units interface --
type fu_interface_t is record
319,7 → 320,7
-- check special cases --
op_is_zero_v := op_e_all_zero_v and op_m_all_zero_v; -- zero
op_is_inf_v := op_e_all_one_v and op_m_all_zero_v; -- infinity
op_is_denorm_v := '0'; -- FIXME / TODO op_e_all_zero_v and (not op_m_all_zero_v); -- subnormal
op_is_denorm_v := '0'; -- FIXME / TODO -- op_e_all_zero_v and (not op_m_all_zero_v); -- subnormal
op_is_nan_v := op_e_all_one_v and (not op_m_all_zero_v); -- NaN
 
-- actual attributes --
344,12 → 345,13
if (rstn_i = '0') then
ctrl_engine.state <= S_IDLE;
ctrl_engine.start <= '0';
fpu_operands.frm <= (others => '0');
fpu_operands.rs1 <= (others => '0');
fpu_operands.rs1_class <= (others => '0');
fpu_operands.rs2 <= (others => '0');
fpu_operands.rs2_class <= (others => '0');
funct_ff <= (others => '0');
fpu_operands.frm <= (others => def_rst_val_c);
fpu_operands.rs1 <= (others => def_rst_val_c);
fpu_operands.rs1_class <= (others => def_rst_val_c);
fpu_operands.rs2 <= (others => def_rst_val_c);
fpu_operands.rs2_class <= (others => def_rst_val_c);
funct_ff <= (others => def_rst_val_c);
cmp_ff <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- arbiter defaults --
ctrl_engine.valid <= '0';
361,6 → 363,7
when S_IDLE => -- waiting for operation trigger
-- ------------------------------------------------------------
funct_ff <= cmd.funct; -- actual operation to execute
cmp_ff <= cmp_i; -- main ALU comparator
-- rounding mode --
-- TODO / FIXME "round to nearest, ties to max magnitude" (0b100) is not supported yet
if (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "111") then
425,16 → 428,21
 
-- Floating-Point Comparator --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
float_comparator: process(clk_i)
float_comparator: process(rstn_i, clk_i)
variable cond_v : std_ulogic_vector(1 downto 0);
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
comp_equal_ff <= def_rst_val_c;
comp_less_ff <= def_rst_val_c;
fu_compare.done <= def_rst_val_c;
fu_min_max.done <= def_rst_val_c;
elsif rising_edge(clk_i) then
-- equal --
if ((fpu_operands.rs1_class(fp_class_pos_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_pos_inf_c) = '1')) or -- +inf == +inf
((fpu_operands.rs1_class(fp_class_neg_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_neg_inf_c) = '1')) or -- -inf == -inf
(((fpu_operands.rs1_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs1_class(fp_class_neg_zero_c) = '1')) and
((fpu_operands.rs2_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs2_class(fp_class_neg_zero_c) = '1'))) or -- +/-zero == +/-zero
(fpu_operands.rs1 = fpu_operands.rs2) then -- identical in every way
(cmp_ff(cmp_equal_c) = '1') then -- identical in every way (comparator result from main ALU)
comp_equal_ff <= '1';
else
comp_equal_ff <= '0';
451,8 → 459,8
case cond_v is
when "10" => comp_less_ff <= '1'; -- rs1 negative, rs2 positive
when "01" => comp_less_ff <= '0'; -- rs1 positive, rs2 negative
when "00" => comp_less_ff <= comp_less; -- both positive
when "11" => comp_less_ff <= not comp_less; -- both negative
when "00" => comp_less_ff <= cmp_ff(cmp_less_c); -- both positive (comparator result from main ALU)
when "11" => comp_less_ff <= not cmp_ff(cmp_less_c); -- both negative (comparator result from main ALU)
when others => comp_less_ff <= '0'; -- undefined
end case;
end if;
463,10 → 471,7
end if;
end process float_comparator;
 
-- less than - only compare the "magnitude" part - sign bit has to be handled separately --
comp_less <= '1' when (unsigned(fpu_operands.rs1(30 downto 0)) < unsigned(fpu_operands.rs2(30 downto 0))) else '0';
 
 
-- Comparison (FEQ/FLT/FLE) ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
float_comparison: process(fpu_operands, ctrl_i, comp_equal_ff, comp_less_ff)
575,11 → 580,14
 
-- Convert: [unsigned] Integer to Float (FCVT.W.S) ----------------------------------------
-- -------------------------------------------------------------------------------------------
convert_i2f: process(clk_i)
convert_i2f: process(rstn_i, clk_i)
begin
-- this process only computes the absolute input value
-- the actual conversion is done by the normalizer
if rising_edge(clk_i) then
if (rstn_i = '0') then
fu_conv_i2f.result <= (others => def_rst_val_c);
fu_conv_i2f.sign <= def_rst_val_c;
elsif rising_edge(clk_i) then
if (ctrl_i(ctrl_ir_funct12_0_c) = '0') and (rs1_i(31) = '1') then -- convert signed integer
fu_conv_i2f.result <= std_ulogic_vector(0 - unsigned(rs1_i));
fu_conv_i2f.sign <= rs1_i(31); -- original sign
594,13 → 602,24
 
-- Multiplier Core (FMUL) -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
multiplier_core: process(clk_i)
begin
if rising_edge(clk_i) then
multiplier_core: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
multiplier.opa <= (others => '-'); -- these might be DSP regs!
multiplier.opb <= (others => '-'); -- these might be DSP regs!
multiplier.buf_ff <= (others => '-'); -- these might be DSP regs!
multiplier.product <= (others => '-'); -- these might be DSP regs!
multiplier.sign <= def_rst_val_c;
multiplier.exp_res <= (others => def_rst_val_c);
multiplier.flags(fp_exc_of_c) <= def_rst_val_c;
multiplier.flags(fp_exc_uf_c) <= def_rst_val_c;
multiplier.flags(fp_exc_nv_c) <= def_rst_val_c;
multiplier.latency <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- multiplier core --
if (multiplier.start = '1') then -- FIXME / TODO remove buffer?
multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one
multiplier.opb <= unsigned('1' & fpu_operands.rs2(22 downto 0));
multiplier.opb <= unsigned('1' & fpu_operands.rs2(22 downto 0)); -- append hidden one
end if;
multiplier.buf_ff <= multiplier.opa * multiplier.opb;
multiplier.product <= std_ulogic_vector(multiplier.buf_ff(47 downto 0)); -- let the register balancing do the magic here
645,7 → 664,7
 
 
-- result class --
multiplier_class_core: process(clk_i)
multiplier_class_core: process(rstn_i, clk_i)
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
652,7 → 671,14
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
multiplier.res_class(fp_class_pos_norm_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_norm_c) <= def_rst_val_c;
multiplier.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
multiplier.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
multiplier.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
745,9 → 771,21
 
-- Adder/Subtractor Core (FADD, FSUB) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
adder_subtractor_core: process(clk_i)
begin
if rising_edge(clk_i) then
adder_subtractor_core: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
addsub.latency <= (others => def_rst_val_c);
addsub.exp_comp <= (others => def_rst_val_c);
addsub.man_sreg <= (others => def_rst_val_c);
addsub.exp_cnt <= (others => def_rst_val_c);
addsub.man_g_ext <= def_rst_val_c;
addsub.man_r_ext <= def_rst_val_c;
addsub.man_s_ext <= def_rst_val_c;
addsub.man_comp <= def_rst_val_c;
addsub.add_stage <= (others => def_rst_val_c);
addsub.res_sign <= def_rst_val_c;
addsub.flags(fp_exc_nv_c) <= def_rst_val_c;
elsif rising_edge(clk_i) then
-- arbitration / latency --
if (ctrl_engine.state = S_IDLE) then -- hacky "reset"
addsub.latency <= (others => '0');
865,7 → 903,7
 
 
-- result class --
adder_subtractor_class_core: process(clk_i)
adder_subtractor_class_core: process(rstn_i, clk_i)
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
872,7 → 910,13
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
addsub.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
addsub.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
addsub.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
addsub.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
addsub.res_class(fp_class_qnan_c) <= def_rst_val_c;
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
1079,9 → 1123,12
 
-- Result Output to CPU Pipeline ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
output_gate: process(clk_i)
output_gate: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
res_o <= (others => def_rst_val_c);
fflags_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (ctrl_engine.valid = '1') then
case funct_ff is
when op_class_c =>
1233,24 → 1280,24
begin
if (rstn_i = '0') then
ctrl.state <= S_IDLE;
ctrl.norm_r <= '0';
ctrl.cnt <= (others => '0');
ctrl.cnt_pre <= (others => '0');
ctrl.cnt_of <= '0';
ctrl.cnt_uf <= '0';
ctrl.rounded <= '0';
ctrl.res_exp <= (others => '0');
ctrl.res_man <= (others => '0');
ctrl.res_sgn <= '0';
ctrl.class <= (others => '0');
ctrl.flags <= (others => '0');
ctrl.norm_r <= def_rst_val_c;
ctrl.cnt <= (others => def_rst_val_c);
ctrl.cnt_pre <= (others => def_rst_val_c);
ctrl.cnt_of <= def_rst_val_c;
ctrl.cnt_uf <= def_rst_val_c;
ctrl.rounded <= def_rst_val_c;
ctrl.res_exp <= (others => def_rst_val_c);
ctrl.res_man <= (others => def_rst_val_c);
ctrl.res_sgn <= def_rst_val_c;
ctrl.class <= (others => def_rst_val_c);
ctrl.flags <= (others => def_rst_val_c);
--
sreg.upper <= (others => '0');
sreg.lower <= (others => '0');
sreg.dir <= '0';
sreg.ext_g <= '0';
sreg.ext_r <= '0';
sreg.ext_s <= '0';
sreg.upper <= (others => def_rst_val_c);
sreg.lower <= (others => def_rst_val_c);
sreg.dir <= def_rst_val_c;
sreg.ext_g <= def_rst_val_c;
sreg.ext_r <= def_rst_val_c;
sreg.ext_s <= def_rst_val_c;
--
done_o <= '0';
elsif rising_edge(clk_i) then
1609,18 → 1656,18
begin
if (rstn_i = '0') then
ctrl.state <= S_IDLE;
ctrl.cnt <= (others => '0');
ctrl.sign <= '0';
ctrl.class <= (others => '0');
ctrl.rounded <= '0';
ctrl.over <= '0';
ctrl.under <= '0';
ctrl.unsign <= '0';
ctrl.result <= (others => '0');
ctrl.result_tmp <= (others => '0');
sreg.int <= (others => '0');
sreg.mant <= (others => '0');
sreg.ext_s <= '0';
ctrl.cnt <= (others => def_rst_val_c);
ctrl.sign <= def_rst_val_c;
ctrl.class <= (others => def_rst_val_c);
ctrl.rounded <= def_rst_val_c;
ctrl.over <= def_rst_val_c;
ctrl.under <= def_rst_val_c;
ctrl.unsign <= def_rst_val_c;
ctrl.result <= (others => def_rst_val_c);
ctrl.result_tmp <= (others => def_rst_val_c);
sreg.int <= (others => def_rst_val_c);
sreg.mant <= (others => def_rst_val_c);
sreg.ext_s <= def_rst_val_c;
done_o <= '0';
elsif rising_edge(clk_i) then
-- defaults --
/neorv32/trunk/rtl/core/neorv32_cpu_cp_muldiv.vhd
1,10 → 1,13
-- #################################################################################################
-- # << NEORV32 - CPU Co-Processor: Integer Multiplier/Divider Unit (RISC-V "M" Extension)>> #
-- # ********************************************************************************************* #
-- # Multiplier and Divider unit. Implements the RISC-V RV32-M CPU extension. #
-- # Multiplier core (signed/unsigned) uses serial algorithm. -> 32+4 cycles latency #
-- # Divider core (unsigned) uses serial algorithm. -> 32+6 cycles latency #
-- # Multiplications can be mapped to DSP block when FAST_MUL_EN = true. #
-- # Multiplier and Divider unit. Implements the RISC-V M CPU extension. #
-- # #
-- # Multiplier core (signed/unsigned) uses classical serial algorithm. Unit atency: 31+3 cycles #
-- # Divider core (unsigned) uses classical serial algorithm. Unit latency: 32+4 cycles #
-- # #
-- # Multiplications can be mapped to DSP blocks (faster!) when FAST_MUL_EN = true. #
-- # Unit latency: 3 cycles #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
65,9 → 68,6
 
architecture neorv32_cpu_cp_muldiv_rtl of neorv32_cpu_cp_muldiv is
 
-- advanced configuration --
constant dsp_add_reg_stage_c : boolean := false; -- add another register stage to DSP-based multiplication for timing-closure
 
-- operations --
constant cp_op_mul_c : std_ulogic_vector(2 downto 0) := "000"; -- mul
constant cp_op_mulh_c : std_ulogic_vector(2 downto 0) := "001"; -- mulh
79,16 → 79,18
constant cp_op_remu_c : std_ulogic_vector(2 downto 0) := "111"; -- remu
 
-- controller --
type state_t is (IDLE, DECODE, INIT_OPX, INIT_OPY, PROCESSING, FINALIZE, COMPLETED, FAST_MUL);
type state_t is (IDLE, DIV_PREPROCESS, PROCESSING, FINALIZE, COMPLETED);
signal state : state_t;
signal cnt : std_ulogic_vector(4 downto 0);
signal cp_op : std_ulogic_vector(2 downto 0); -- operation to execute
signal cp_op_ff : std_ulogic_vector(2 downto 0); -- operation that was executed
signal start : std_ulogic;
signal start_div : std_ulogic;
signal start_mul : std_ulogic;
signal operation : std_ulogic;
signal rs1, opx, opy : std_ulogic_vector(data_width_c-1 downto 0); -- input operands
signal opx_is_signed : std_ulogic;
signal opy_is_signed : std_ulogic;
signal div_opx : std_ulogic_vector(data_width_c-1 downto 0);
signal div_opy : std_ulogic_vector(data_width_c-1 downto 0);
signal rs1_is_signed : std_ulogic;
signal rs2_is_signed : std_ulogic;
signal opy_is_zero : std_ulogic;
signal div_res_corr : std_ulogic;
signal valid : std_ulogic;
102,6 → 104,8
signal div_res : std_ulogic_vector(data_width_c-1 downto 0);
 
-- multiplier core --
signal mul_product_p : std_ulogic_vector(63 downto 0);
signal mul_product_s : std_ulogic_vector(63 downto 0);
signal mul_product : std_ulogic_vector(63 downto 0);
signal mul_do_add : std_ulogic_vector(data_width_c downto 0);
signal mul_sign_cycle : std_ulogic;
109,7 → 113,6
signal mul_op_x : signed(32 downto 0); -- for using DSPs
signal mul_op_y : signed(32 downto 0); -- for using DSPs
signal mul_buf_ff : signed(65 downto 0); -- for using DSPs
signal mul_buf2_ff : signed(65 downto 0); -- for using DSPs
 
begin
 
119,72 → 122,64
begin
if (rstn_i = '0') then
state <= IDLE;
opx <= (others => '0');
opy <= (others => '0');
rs1 <= (others => '0');
cnt <= (others => '0');
start <= '0';
div_opx <= (others => def_rst_val_c);
div_opy <= (others => def_rst_val_c);
cnt <= (others => def_rst_val_c);
cp_op_ff <= (others => def_rst_val_c);
start_div <= '0';
valid <= '0';
div_res_corr <= '0';
opy_is_zero <= '0';
cp_op_ff <= (others => '0');
div_res_corr <= def_rst_val_c;
opy_is_zero <= def_rst_val_c;
elsif rising_edge(clk_i) then
-- defaults --
start <= '0';
valid <= '0';
cp_op_ff <= cp_op;
start_div <= '0';
valid <= '0';
 
-- FSM --
case state is
when IDLE =>
cp_op_ff <= cp_op;
if (start_i = '1') then
opx <= rs1_i;
rs1 <= rs1_i;
opy <= rs2_i;
state <= DECODE;
if (operation = '1') then -- division
cnt <= "11111";
state <= DIV_PREPROCESS;
else
cnt <= "11110";
if (FAST_MUL_EN = true) then
state <= FINALIZE;
else
state <= PROCESSING;
end if;
end if;
end if;
 
when DECODE =>
--
when DIV_PREPROCESS =>
-- check rlevatn input signs --
if (cp_op = cp_op_div_c) then -- result sign compensation for div?
div_res_corr <= opx(opx'left) xor opy(opy'left);
div_res_corr <= rs1_i(rs1_i'left) xor rs2_i(rs2_i'left);
elsif (cp_op = cp_op_rem_c) then -- result sign compensation for rem?
div_res_corr <= opx(opx'left);
div_res_corr <= rs1_i(rs1_i'left);
else
div_res_corr <= '0';
end if;
--
if (or_all_f(opy) = '0') then -- *divide* by 0?
opy_is_zero <= '1';
-- divide by zero? --
opy_is_zero <= not or_all_f(rs2_i); -- set if rs2 = 0
-- abs(rs1) --
if ((rs1_i(rs1_i'left) and rs1_is_signed) = '1') then -- signed division?
div_opx <= std_ulogic_vector(0 - unsigned(rs1_i)); -- make positive
else
opy_is_zero <= '0';
div_opx <= rs1_i;
end if;
-- abs(rs2) --
if ((rs2_i(rs2_i'left) and rs2_is_signed) = '1') then -- signed division?
div_opy <= std_ulogic_vector(0 - unsigned(rs2_i)); -- make positive
else
div_opy <= rs2_i;
end if;
--
cnt <= "11111";
if (operation = '1') then -- division
state <= INIT_OPX;
else -- multiplication
start <= '1';
if (FAST_MUL_EN = true) then
state <= FAST_MUL;
else
state <= PROCESSING;
end if;
end if;
start_div <= '1';
state <= PROCESSING;
 
when INIT_OPX =>
if ((opx(opx'left) and opx_is_signed) = '1') then -- signed division?
opx <= div_sign_comp; -- make positive
end if;
state <= INIT_OPY;
 
when INIT_OPY =>
start <= '1';
if ((opy(opy'left) and opy_is_signed) = '1') then -- signed division?
opy <= div_sign_comp; -- make positive
end if;
state <= PROCESSING;
 
when PROCESSING =>
cnt <= std_ulogic_vector(unsigned(cnt) - 1);
if (cnt = "00000") then
191,9 → 186,6
state <= FINALIZE;
end if;
 
when FAST_MUL =>
state <= FINALIZE;
 
when FINALIZE =>
state <= COMPLETED;
 
207,56 → 199,63
-- co-processor command --
cp_op <= ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c);
 
-- operation --
operation <= '1' when (cp_op = cp_op_div_c) or (cp_op = cp_op_divu_c) or (cp_op = cp_op_rem_c) or (cp_op = cp_op_remu_c) else '0';
-- operation: 0=mul, 1=div --
operation <= '1' when (cp_op(2) = '1') else '0';
 
-- opx (rs1) signed? --
opx_is_signed <= '1' when (cp_op = cp_op_mulh_c) or (cp_op = cp_op_mulhsu_c) or (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) else '0';
rs1_is_signed <= '1' when (cp_op = cp_op_mulh_c) or (cp_op = cp_op_mulhsu_c) or (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) else '0';
 
-- opy (rs2) signed? --
opy_is_signed <= '1' when (cp_op = cp_op_mulh_c) or (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) else '0';
rs2_is_signed <= '1' when (cp_op = cp_op_mulh_c) or (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) else '0';
 
-- start MUL operation (do it fast!) --
start_mul <= '1' when (state = IDLE) and (start_i = '1') and (operation = '0') else '0';
 
 
-- Multiplier Core (signed/unsigned) ------------------------------------------------------
-- -------------------------------------------------------------------------------------------
multiplier_core: process(clk_i)
multiplier_core_serial: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
-- ---------------------------------------------------------
if (rstn_i = '0') then
mul_product_s <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (FAST_MUL_EN = false) then -- use small iterative computation
if (start = '1') then -- start new multiplication
mul_product(63 downto 32) <= (others => '0');
mul_product(31 downto 00) <= opy;
elsif ((state = PROCESSING) or (state = FINALIZE)) and (operation = '0') then
mul_product(63 downto 31) <= mul_do_add(32 downto 0);
mul_product(30 downto 00) <= mul_product(31 downto 1);
if (start_mul = '1') then -- start new multiplication
mul_product_s(63 downto 32) <= (others => '0');
mul_product_s(31 downto 00) <= rs2_i;
elsif (state = PROCESSING) or (state = FINALIZE) then -- processing step or sign-finalization step
mul_product_s(63 downto 31) <= mul_do_add(32 downto 0);
mul_product_s(30 downto 00) <= mul_product_s(31 downto 1);
end if;
-- ---------------------------------------------------------
else -- use direct approach using (several!) DSP blocks
if (start = '1') then
mul_op_x <= signed((opx(opx'left) and opx_is_signed) & opx);
mul_op_y <= signed((opy(opy'left) and opy_is_signed) & opy);
end if;
end if;
end process multiplier_core_serial;
 
multiplier_core_dsp: process(clk_i)
begin
if rising_edge(clk_i) then
if (FAST_MUL_EN = true) then -- use direct approach using DSP blocks
if (start_mul = '1') then
mul_op_x <= signed((rs1_i(rs1_i'left) and rs1_is_signed) & rs1_i);
mul_op_y <= signed((rs2_i(rs2_i'left) and rs2_is_signed) & rs2_i);
end if;
mul_buf_ff <= mul_op_x * mul_op_y;
if (dsp_add_reg_stage_c = true) then -- add another reg stage?
mul_buf2_ff <= mul_buf_ff;
mul_product <= std_ulogic_vector(mul_buf2_ff(63 downto 0)); -- let the register balancing do the magic here
else
mul_product <= std_ulogic_vector(mul_buf_ff(63 downto 0)); -- let the register balancing do the magic here
end if;
mul_buf_ff <= mul_op_x * mul_op_y;
mul_product_p <= std_ulogic_vector(mul_buf_ff(63 downto 0)); -- let the register balancing do the magic here
end if;
end if;
end process multiplier_core;
end process multiplier_core_dsp;
 
-- MUL: do another addition --
mul_update: process(mul_product, mul_sign_cycle, mul_p_sext, opx_is_signed, opx)
mul_product <= mul_product_p when (FAST_MUL_EN = true) else mul_product_s;
 
-- do another addition --
mul_update: process(mul_product, mul_sign_cycle, mul_p_sext, rs1_is_signed, rs1_i)
begin
-- current bit of opy to take care of --
-- current bit of rs2_i to take care of --
if (mul_product(0) = '1') then -- multiply with 1
if (mul_sign_cycle = '1') then -- for signed operations only: take care of negative weighted MSB -> multiply with -1
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((opx(opx'left) and opx_is_signed) & opx));
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((rs1_i(rs1_i'left) and rs1_is_signed) & rs1_i));
else -- multiply with +1
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((opx(opx'left) and opx_is_signed) & opx));
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((rs1_i(rs1_i'left) and rs1_is_signed) & rs1_i));
end if;
else -- multiply with 0
mul_do_add <= mul_p_sext & mul_product(63 downto 32);
264,19 → 263,22
end process mul_update;
 
-- sign control --
mul_sign_cycle <= opy_is_signed when (state = FINALIZE) else '0';
mul_p_sext <= mul_product(mul_product'left) and opx_is_signed;
mul_sign_cycle <= rs2_is_signed when (state = FINALIZE) else '0';
mul_p_sext <= mul_product(mul_product'left) and rs1_is_signed;
 
 
-- Divider Core (unsigned) ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
divider_core: process(clk_i)
divider_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (start = '1') then -- start new division
quotient <= opx;
if (rstn_i = '0') then
quotient <= (others => def_rst_val_c);
remainder <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (start_div = '1') then -- start new division
quotient <= div_opx;
remainder <= (others => '0');
elsif ((state = PROCESSING) or (state = FINALIZE)) and (operation = '1') then -- running?
elsif (state = PROCESSING) or (state = FINALIZE) then -- running?
quotient <= quotient(30 downto 0) & (not div_sub(32));
if (div_sub(32) = '0') then -- still overflowing
remainder <= div_sub(31 downto 0);
287,24 → 289,22
end if;
end process divider_core;
 
-- DIV: try another subtraction --
div_sub <= std_ulogic_vector(unsigned('0' & remainder(30 downto 0) & quotient(31)) - unsigned('0' & opy));
-- try another subtraction --
div_sub <= std_ulogic_vector(unsigned('0' & remainder(30 downto 0) & quotient(31)) - unsigned('0' & div_opy));
 
-- Div sign compensation --
div_sign_comp_in <= opx when (state = INIT_OPX) else
opy when (state = INIT_OPY) else
quotient when ((cp_op = cp_op_div_c) or (cp_op = cp_op_divu_c)) else remainder;
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in));
-- result sign compensation --
div_sign_comp_in <= quotient when (cp_op = cp_op_div_c) else remainder;
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in));
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in;
 
-- result sign correction --
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in;
 
 
-- Data Output ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
operation_result: process(clk_i)
operation_result: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
res_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
res_o <= (others => '0');
if (valid = '1') then
case cp_op_ff is
320,7 → 320,7
if (opy_is_zero = '0') then
res_o <= div_res;
else
res_o <= rs1;
res_o <= rs1_i;
end if;
when others => -- cp_op_remu_c
res_o <= remainder;
/neorv32/trunk/rtl/core/neorv32_icache.vhd
556,10 → 556,9
else
tag_mem_s1(to_integer(unsigned(cache_index))) <= ctrl_acc_addr.tag;
end if;
else -- read access
tag(0) <= tag_mem_s0(to_integer(unsigned(cache_index)));
tag(1) <= tag_mem_s1(to_integer(unsigned(cache_index)));
end if;
tag(0) <= tag_mem_s0(to_integer(unsigned(cache_index)));
tag(1) <= tag_mem_s1(to_integer(unsigned(cache_index)));
end if;
end process tag_memory;
 
584,15 → 583,15
begin
if rising_edge(clk_i) then
if (cache_we = '1') then -- write access from control (full-word)
if (set_select = '0') then
if (set_select = '0') or (ICACHE_NUM_SETS = 1) then
cache_data_memory_s0(to_integer(unsigned(cache_addr))) <= ctrl_wdata_i;
else
cache_data_memory_s1(to_integer(unsigned(cache_addr))) <= ctrl_wdata_i;
end if;
else -- read access from host (full-word)
cache_rdata(0) <= cache_data_memory_s0(to_integer(unsigned(cache_addr)));
cache_rdata(1) <= cache_data_memory_s1(to_integer(unsigned(cache_addr)));
end if;
-- read access from host (full-word) --
cache_rdata(0) <= cache_data_memory_s0(to_integer(unsigned(cache_addr)));
cache_rdata(1) <= cache_data_memory_s1(to_integer(unsigned(cache_addr)));
end if;
end process cache_mem_access;
 
/neorv32/trunk/rtl/core/neorv32_mtime.vhd
1,17 → 1,12
-- #################################################################################################
-- # << NEORV32 - Machine System Timer (MTIME) >> #
-- # ********************************************************************************************* #
-- # Compatible to RISC-V spec's mtime & mtimecmp. #
-- # Write mtime.LO first when updating the system time. System time should be written only at #
-- # system start. RISC-V spec. exception: The MTIME interrupt is ACKed by the processor itself. #
-- # However, the achine time cannot issue a new interrupt until the mtimecmp.HI register is #
-- # written again. #
-- # Note: The 64-bit time and compare system is broken and de-coupled into two 32-bit systems. #
-- # Note: The register of this unit can only be written in WORD MODE. #
-- # Compatible to RISC-V spec's 64-bit MACHINE system timer including "mtime[h]" & "mtimecmp[h]". #
-- # Note: The 64-bit counter and compare system is broken and de-coupled into two 32-bit systems. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
125,7 → 120,7
-- mtime high --
if (wren = '1') and (addr = mtime_time_hi_addr_c) then
mtime_hi <= data_i;
elsif ((mtime_lo_msb_ff xor mtime_lo(mtime_lo'left)) = '1') then -- mtime_lo carry?
elsif ((mtime_lo_msb_ff xor mtime_lo(mtime_lo'left)) = '1') then -- auto increment: mtime_lo carry?
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + 1);
end if;
end if;
147,7 → 142,7
data_o <= mtime_hi;
when mtime_cmp_lo_addr_c => -- mtimecmp LOW
data_o <= mtimecmp_lo;
when others => -- mtime_cmp_hi_addr_c - mtimecmp HIGH
when others => -- mtime_cmp_hi_addr_c -- mtimecmp HIGH
data_o <= mtimecmp_hi;
end case;
end if;
/neorv32/trunk/rtl/core/neorv32_package.vhd
50,8 → 50,9
constant xbus_big_endian_c : boolean := true; -- external memory access byte order: true=big endian (default); false=little endian
 
-- CPU core --
constant ipb_entries_c : natural := 2; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2
constant cp_timeout_en_c : boolean := false; -- auto-terminate pending co-processor operations after 256 cycles (for debugging only), default = false
constant ipb_entries_c : natural := 2; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2
constant cp_timeout_en_c : boolean := false; -- auto-terminate pending co-processor operations after 256 cycles (for debugging only), default = false
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value)
 
-- "critical" number of implemented PMP regions --
-- if more PMP regions (> pmp_num_regions_critical_c) are defined, another register stage is automatically inserted into the memory interfaces
58,19 → 59,13
-- increasing instruction fetch & data access latency by +1 cycle but also reducing critical path length
constant pmp_num_regions_critical_c : natural := 8; -- default=8
 
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050302"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
constant rf_r0_is_reg_c : boolean := true; -- reg_file.r0 is a *physical register* that has to be initialized to zero by the CPU HW
 
-- Helper Functions -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
function index_size_f(input : natural) return natural;
function cond_sel_natural_f(cond : boolean; val_t : natural; val_f : natural) return natural;
function cond_sel_int_f(cond : boolean; val_t : integer; val_f : integer) return integer;
function cond_sel_stdulogicvector_f(cond : boolean; val_t : std_ulogic_vector; val_f : std_ulogic_vector) return std_ulogic_vector;
function cond_sel_stdulogic_f(cond : boolean; val_t : std_ulogic; val_f : std_ulogic) return std_ulogic;
function cond_sel_string_f(cond : boolean; val_t : string; val_f : string) return string;
function bool_to_ulogic_f(cond : boolean) return std_ulogic;
function or_all_f(a : std_ulogic_vector) return std_ulogic;
83,6 → 78,14
function is_power_of_two_f(input : natural) return boolean;
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector;
 
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050400"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
constant rf_r0_is_reg_c : boolean := true; -- x0 is a *physical register* that has to be initialized to zero by the CPU
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-');
 
-- Internal Types -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
type pmp_ctrl_if_t is array (0 to 63) of std_ulogic_vector(07 downto 0);
97,121 → 100,121
--> internal data/instruction memory sizes are configured via top's generics
 
-- Internal Bootloader ROM --
constant boot_rom_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFF0000"; -- bootloader base address, fixed!
constant boot_rom_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffff0000"; -- bootloader base address, fixed!
constant boot_rom_size_c : natural := 4*1024; -- module's address space in bytes
constant boot_rom_max_size_c : natural := 32*1024; -- max module's address space in bytes, fixed!
 
-- IO: Peripheral Devices ("IO") Area --
-- Control register(s) (including the device-enable) should be located at the base address of each device
constant io_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF00";
constant io_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00";
constant io_size_c : natural := 64*4; -- module's address space in bytes, fixed!
 
-- Custom Functions Subsystem (CFS) --
constant cfs_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF00"; -- base address
constant cfs_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00"; -- base address
constant cfs_size_c : natural := 32*4; -- module's address space in bytes
constant cfs_reg0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF00";
constant cfs_reg1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF04";
constant cfs_reg2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF08";
constant cfs_reg3_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF0C";
constant cfs_reg4_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF10";
constant cfs_reg5_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF14";
constant cfs_reg6_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF18";
constant cfs_reg7_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF1C";
constant cfs_reg8_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF20";
constant cfs_reg9_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF24";
constant cfs_reg10_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF28";
constant cfs_reg11_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF2C";
constant cfs_reg12_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF30";
constant cfs_reg13_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF34";
constant cfs_reg14_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF38";
constant cfs_reg15_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF3C";
constant cfs_reg16_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF40";
constant cfs_reg17_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF44";
constant cfs_reg18_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF48";
constant cfs_reg19_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF4C";
constant cfs_reg20_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF50";
constant cfs_reg21_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF54";
constant cfs_reg22_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF58";
constant cfs_reg23_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF5C";
constant cfs_reg24_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF60";
constant cfs_reg25_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF64";
constant cfs_reg26_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF68";
constant cfs_reg27_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF6C";
constant cfs_reg28_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF70";
constant cfs_reg29_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF74";
constant cfs_reg30_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF78";
constant cfs_reg31_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF7C";
constant cfs_reg0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00";
constant cfs_reg1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff04";
constant cfs_reg2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff08";
constant cfs_reg3_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff0c";
constant cfs_reg4_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff10";
constant cfs_reg5_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff14";
constant cfs_reg6_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff18";
constant cfs_reg7_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff1c";
constant cfs_reg8_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff20";
constant cfs_reg9_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff24";
constant cfs_reg10_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff28";
constant cfs_reg11_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff2c";
constant cfs_reg12_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff30";
constant cfs_reg13_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff34";
constant cfs_reg14_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff38";
constant cfs_reg15_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff3c";
constant cfs_reg16_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff40";
constant cfs_reg17_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff44";
constant cfs_reg18_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff48";
constant cfs_reg19_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff4c";
constant cfs_reg20_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff50";
constant cfs_reg21_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff54";
constant cfs_reg22_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff58";
constant cfs_reg23_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff5c";
constant cfs_reg24_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff60";
constant cfs_reg25_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff64";
constant cfs_reg26_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff68";
constant cfs_reg27_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff6c";
constant cfs_reg28_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff70";
constant cfs_reg29_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff74";
constant cfs_reg30_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff78";
constant cfs_reg31_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff7c";
 
-- General Purpose Input/Output Unit (GPIO) --
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF80"; -- base address
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; -- base address
constant gpio_size_c : natural := 2*4; -- module's address space in bytes
constant gpio_in_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF80";
constant gpio_out_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF84";
constant gpio_in_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80";
constant gpio_out_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff84";
 
-- True Random Number Generator (TRNG) --
constant trng_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88"; -- base address
constant trng_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88"; -- base address
constant trng_size_c : natural := 1*4; -- module's address space in bytes
constant trng_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF88";
constant trng_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88";
 
-- Watch Dog Timer (WDT) --
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF8C"; -- base address
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c"; -- base address
constant wdt_size_c : natural := 1*4; -- module's address space in bytes
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF8C";
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c";
 
-- Machine System Timer (MTIME) --
constant mtime_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF90"; -- base address
constant mtime_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff90"; -- base address
constant mtime_size_c : natural := 4*4; -- module's address space in bytes
constant mtime_time_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF90";
constant mtime_time_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF94";
constant mtime_cmp_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF98";
constant mtime_cmp_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFF9C";
constant mtime_time_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff90";
constant mtime_time_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff94";
constant mtime_cmp_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff98";
constant mtime_cmp_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff9c";
 
-- Universal Asynchronous Receiver/Transmitter 0 (UART0), primary UART --
constant uart0_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA0"; -- base address
constant uart0_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa0"; -- base address
constant uart0_size_c : natural := 2*4; -- module's address space in bytes
constant uart0_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA0";
constant uart0_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA4";
constant uart0_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa0";
constant uart0_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa4";
 
-- Serial Peripheral Interface (SPI) --
constant spi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA8"; -- base address
constant spi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa8"; -- base address
constant spi_size_c : natural := 2*4; -- module's address space in bytes
constant spi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFA8";
constant spi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFAC";
constant spi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa8";
constant spi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffac";
 
-- Two Wire Interface (TWI) --
constant twi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB0"; -- base address
constant twi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb0"; -- base address
constant twi_size_c : natural := 2*4; -- module's address space in bytes
constant twi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB0";
constant twi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB4";
constant twi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb0";
constant twi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb4";
 
-- Pulse-Width Modulation Controller (PWM) --
constant pwm_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB8"; -- base address
constant pwm_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb8"; -- base address
constant pwm_size_c : natural := 2*4; -- module's address space in bytes
constant pwm_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFB8";
constant pwm_duty_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFBC";
constant pwm_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb8";
constant pwm_duty_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffbc";
 
-- Numerically-Controlled Oscillator (NCO) --
constant nco_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC0"; -- base address
constant nco_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; -- base address
constant nco_size_c : natural := 4*4; -- module's address space in bytes
constant nco_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC0";
constant nco_ch0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC4";
constant nco_ch1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFC8";
constant nco_ch2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFCC";
constant nco_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0";
constant nco_ch0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc4";
constant nco_ch1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc8";
constant nco_ch2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffcc";
 
-- Universal Asynchronous Receiver/Transmitter 1 (UART1), secondary UART --
constant uart1_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD0"; -- base address
constant uart1_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd0"; -- base address
constant uart1_size_c : natural := 2*4; -- module's address space in bytes
constant uart1_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD0";
constant uart1_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD4";
constant uart1_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd0";
constant uart1_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd4";
 
-- Smart LED (WS2811/WS2812) Interface (NEOLED) --
constant neoled_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD8"; -- base address
constant neoled_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd8"; -- base address
constant neoled_size_c : natural := 2*4; -- module's address space in bytes
constant neoled_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFD8";
constant neoled_data_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFDC";
constant neoled_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd8";
constant neoled_data_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffdc";
 
-- System Information Memory (SYSINFO) --
constant sysinfo_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"FFFFFFE0"; -- base address
constant sysinfo_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffe0"; -- base address
constant sysinfo_size_c : natural := 8*4; -- module's address space in bytes
 
-- Main Control Bus -----------------------------------------------------------------------
263,7 → 266,7
constant ctrl_bus_excl_c : natural := 41; -- exclusive bus access
-- co-processors --
constant ctrl_cp_id_lsb_c : natural := 42; -- cp select ID lsb
constant ctrl_cp_id_hsb_c : natural := 43; -- cp select ID hsb
constant ctrl_cp_id_hsb_c : natural := 43; -- cp select ID
constant ctrl_cp_id_msb_c : natural := 44; -- cp select ID msb
-- current privilege level --
constant ctrl_priv_lvl_lsb_c : natural := 45; -- privilege level lsb
438,23 → 441,23
 
-- RISC-V CSR Addresses -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- read/write CSRs --
-- <<< standard read/write CSRs >>> --
-- user floating-point CSRs --
constant csr_class_float_c : std_ulogic_vector(07 downto 0) := x"00"; -- floating point
constant csr_fflags_c : std_ulogic_vector(11 downto 0) := x"001";
constant csr_frm_c : std_ulogic_vector(11 downto 0) := x"002";
constant csr_fcsr_c : std_ulogic_vector(11 downto 0) := x"003";
--
constant csr_setup_c : std_ulogic_vector(07 downto 0) := x"30"; -- trap setup
-- machine trap setup --
constant csr_class_setup_c : std_ulogic_vector(07 downto 0) := x"30"; -- trap setup
constant csr_mstatus_c : std_ulogic_vector(11 downto 0) := x"300";
constant csr_misa_c : std_ulogic_vector(11 downto 0) := x"301";
constant csr_mie_c : std_ulogic_vector(11 downto 0) := x"304";
constant csr_mtvec_c : std_ulogic_vector(11 downto 0) := x"305";
constant csr_mcounteren_c : std_ulogic_vector(11 downto 0) := x"306";
--
constant csr_mstatush_c : std_ulogic_vector(11 downto 0) := x"310";
--
-- machine counter setup --
constant csr_cnt_setup_c : std_ulogic_vector(06 downto 0) := x"3" & "001"; -- counter setup
constant csr_mcountinhibit_c : std_ulogic_vector(11 downto 0) := x"320";
--
constant csr_mhpmevent3_c : std_ulogic_vector(11 downto 0) := x"323";
constant csr_mhpmevent4_c : std_ulogic_vector(11 downto 0) := x"324";
constant csr_mhpmevent5_c : std_ulogic_vector(11 downto 0) := x"325";
484,7 → 487,7
constant csr_mhpmevent29_c : std_ulogic_vector(11 downto 0) := x"33d";
constant csr_mhpmevent30_c : std_ulogic_vector(11 downto 0) := x"33e";
constant csr_mhpmevent31_c : std_ulogic_vector(11 downto 0) := x"33f";
--
-- machine trap handling --
constant csr_class_trap_c : std_ulogic_vector(07 downto 0) := x"34"; -- machine trap handling
constant csr_mscratch_c : std_ulogic_vector(11 downto 0) := x"340";
constant csr_mepc_c : std_ulogic_vector(11 downto 0) := x"341";
491,7 → 494,7
constant csr_mcause_c : std_ulogic_vector(11 downto 0) := x"342";
constant csr_mtval_c : std_ulogic_vector(11 downto 0) := x"343";
constant csr_mip_c : std_ulogic_vector(11 downto 0) := x"344";
--
-- physical memory protection - configuration --
constant csr_class_pmpcfg_c : std_ulogic_vector(07 downto 0) := x"3a"; -- pmp configuration
constant csr_pmpcfg0_c : std_ulogic_vector(11 downto 0) := x"3a0";
constant csr_pmpcfg1_c : std_ulogic_vector(11 downto 0) := x"3a1";
509,7 → 512,7
constant csr_pmpcfg13_c : std_ulogic_vector(11 downto 0) := x"3ad";
constant csr_pmpcfg14_c : std_ulogic_vector(11 downto 0) := x"3ae";
constant csr_pmpcfg15_c : std_ulogic_vector(11 downto 0) := x"3af";
--
-- physical memory protection - address --
constant csr_pmpaddr0_c : std_ulogic_vector(11 downto 0) := x"3b0";
constant csr_pmpaddr1_c : std_ulogic_vector(11 downto 0) := x"3b1";
constant csr_pmpaddr2_c : std_ulogic_vector(11 downto 0) := x"3b2";
574,7 → 577,7
constant csr_pmpaddr61_c : std_ulogic_vector(11 downto 0) := x"3ed";
constant csr_pmpaddr62_c : std_ulogic_vector(11 downto 0) := x"3ee";
constant csr_pmpaddr63_c : std_ulogic_vector(11 downto 0) := x"3ef";
--
-- machine counters/timers --
constant csr_mcycle_c : std_ulogic_vector(11 downto 0) := x"b00";
constant csr_minstret_c : std_ulogic_vector(11 downto 0) := x"b02";
--
641,7 → 644,8
constant csr_mhpmcounter30h_c : std_ulogic_vector(11 downto 0) := x"b9e";
constant csr_mhpmcounter31h_c : std_ulogic_vector(11 downto 0) := x"b9f";
 
-- read-only CSRs --
-- <<< standard read-only CSRs >>> --
-- user counters/timers --
constant csr_cycle_c : std_ulogic_vector(11 downto 0) := x"c00";
constant csr_time_c : std_ulogic_vector(11 downto 0) := x"c01";
constant csr_instret_c : std_ulogic_vector(11 downto 0) := x"c02";
709,13 → 713,12
constant csr_hpmcounter29h_c : std_ulogic_vector(11 downto 0) := x"c9d";
constant csr_hpmcounter30h_c : std_ulogic_vector(11 downto 0) := x"c9e";
constant csr_hpmcounter31h_c : std_ulogic_vector(11 downto 0) := x"c9f";
--
-- machine information registers --
constant csr_mvendorid_c : std_ulogic_vector(11 downto 0) := x"f11";
constant csr_marchid_c : std_ulogic_vector(11 downto 0) := x"f12";
constant csr_mimpid_c : std_ulogic_vector(11 downto 0) := x"f13";
constant csr_mhartid_c : std_ulogic_vector(11 downto 0) := x"f14";
 
-- custom read-only CSRs --
-- <<< custom (NEORV32-specific) read-only CSRs >>> --
constant csr_mzext_c : std_ulogic_vector(11 downto 0) := x"fc0";
 
-- Co-Processor IDs -----------------------------------------------------------------------
763,7 → 766,6
constant trap_mti_c : std_ulogic_vector(5 downto 0) := "1" & "00111"; -- 1.7: machine timer interrupt
constant trap_mei_c : std_ulogic_vector(5 downto 0) := "1" & "01011"; -- 1.11: machine external interrupt
-- NEORV32-specific (custom) interrupts (async. exceptions) --
constant trap_reset_c : std_ulogic_vector(5 downto 0) := "1" & "00000"; -- 1.0: hardware reset
constant trap_firq0_c : std_ulogic_vector(5 downto 0) := "1" & "10000"; -- 1.16: fast interrupt 0
constant trap_firq1_c : std_ulogic_vector(5 downto 0) := "1" & "10001"; -- 1.17: fast interrupt 1
constant trap_firq2_c : std_ulogic_vector(5 downto 0) := "1" & "10010"; -- 1.18: fast interrupt 2
827,7 → 829,7
-- HPM Event System -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hpmcnt_event_cy_c : natural := 0; -- Active cycle
constant hpmcnt_event_never_c : natural := 1;
constant hpmcnt_event_never_c : natural := 1; -- Unused / never (actually, this would be used for TIME)
constant hpmcnt_event_ir_c : natural := 2; -- Retired instruction
constant hpmcnt_event_cir_c : natural := 3; -- Retired compressed instruction
constant hpmcnt_event_wait_if_c : natural := 4; -- Instruction fetch memory wait cycle
871,17 → 873,20
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
907,7 → 912,7
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)?
993,11 → 998,14
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0 -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (1..64)
);
port (
-- global control --
1059,11 → 1067,14
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0 -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40 -- total size of HPM counters (1..64)
);
port (
-- global control --
1134,8 → 1145,9
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_alu
generic (
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension?
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false -- use tiny (single-bit) shifter for shift operations
);
port (
-- global control --
1210,6 → 1222,7
start_i : in std_ulogic; -- trigger operation
-- data input --
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
-- result and status --
1804,6 → 1817,17
end if;
end function cond_sel_natural_f;
 
-- Function: Conditional select integer ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
function cond_sel_int_f(cond : boolean; val_t : integer; val_f : integer) return integer is
begin
if (cond = true) then
return val_t;
else
return val_f;
end if;
end function cond_sel_int_f;
 
-- Function: Conditional select std_ulogic_vector -----------------------------------------
-- -------------------------------------------------------------------------------------------
function cond_sel_stdulogicvector_f(cond : boolean; val_t : std_ulogic_vector; val_f : std_ulogic_vector) return std_ulogic_vector is
1815,6 → 1839,17
end if;
end function cond_sel_stdulogicvector_f;
 
-- Function: Conditional select std_ulogic ------------------------------------------------
-- -------------------------------------------------------------------------------------------
function cond_sel_stdulogic_f(cond : boolean; val_t : std_ulogic; val_f : std_ulogic) return std_ulogic is
begin
if (cond = true) then
return val_t;
else
return val_f;
end if;
end function cond_sel_stdulogic_f;
 
-- Function: Conditional select string ----------------------------------------------------
-- -------------------------------------------------------------------------------------------
function cond_sel_string_f(cond : boolean; val_t : string; val_f : string) return string is
1842,9 → 1877,9
function or_all_f(a : std_ulogic_vector) return std_ulogic is
variable tmp_v : std_ulogic;
begin
tmp_v := a(a'low);
tmp_v := '0';
if (a'low < a'high) then -- not null range?
for i in a'low+1 to a'high loop
for i in a'low to a'high loop
tmp_v := tmp_v or a(i);
end loop; -- i
end if;
1856,9 → 1891,9
function and_all_f(a : std_ulogic_vector) return std_ulogic is
variable tmp_v : std_ulogic;
begin
tmp_v := a(a'low);
tmp_v := '1';
if (a'low < a'high) then -- not null range?
for i in a'low+1 to a'high loop
for i in a'low to a'high loop
tmp_v := tmp_v and a(i);
end loop; -- i
end if;
1870,9 → 1905,9
function xor_all_f(a : std_ulogic_vector) return std_ulogic is
variable tmp_v : std_ulogic;
begin
tmp_v := a(a'low);
tmp_v := '0';
if (a'low < a'high) then -- not null range?
for i in a'low+1 to a'high loop
for i in a'low to a'high loop
tmp_v := tmp_v xor a(i);
end loop; -- i
end if;
1884,9 → 1919,9
function xnor_all_f(a : std_ulogic_vector) return std_ulogic is
variable tmp_v : std_ulogic;
begin
tmp_v := a(a'low);
tmp_v := '1';
if (a'low < a'high) then -- not null range?
for i in a'low+1 to a'high loop
for i in a'low to a'high loop
tmp_v := tmp_v xnor a(i);
end loop; -- i
end if;
/neorv32/trunk/rtl/core/neorv32_top.vhd
67,6 → 67,8
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
74,6 → 76,7
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (1..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
104,7 → 107,7
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)?
422,11 → 425,13
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters (1..64)
)
port map (
-- global control --
/neorv32/trunk/rtl/core/neorv32_uart.vhd
403,6 → 403,9
 
-- SIMULATION Output ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- pragma translate_off
-- synthesis translate_off
-- RTL_SYNTHESIS OFF
sim_output: process(clk_i) -- for SIMULATION ONLY!
file file_uart_text_out : text open write_mode is sim_uart_text_file_c;
file file_uart_data_out : text open write_mode is sim_uart_data_file_c;
451,6 → 454,8
end if;
end if;
end process sim_output;
-- RTL_SYNTHESIS ON
-- synthesis translate_on
-- pragma translate_on
 
 
end neorv32_uart_rtl;
/neorv32/trunk/rtl/core/neorv32_wishbone.vhd
193,8 → 193,8
ctrl.rd_req <= '0';
ctrl.wr_req <= '0';
-- buffer all outgoing signals --
ctrl.we <= wren_i;
ctrl.adr <= addr_i;
ctrl.we <= wren_i or ctrl.wr_req;
ctrl.adr <= addr_i;
if (xbus_big_endian_c = true) then -- endianness conversion
ctrl.wdat <= data_i;
ctrl.sel <= ben_i;
206,7 → 206,7
ctrl.excl <= excl_i;
ctrl.priv <= priv_i;
-- valid new or buffered read/write request --
if ((xbus_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req)) = '1') then
if ((xbus_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req) and (not cancel_i)) = '1') then
ctrl.state <= BUSY;
end if;
 
237,6 → 237,8
 
when RESYNC => -- make sure transfer is done!
-- ------------------------------------------------------------
ctrl.wr_req <= ctrl.wr_req or wren_i; -- buffer new request
ctrl.rd_req <= ctrl.rd_req or rden_i; -- buffer new request
if (wb_ack_i = '0') then
ctrl.state <= IDLE;
end if;
/neorv32/trunk/rtl/top_templates/neorv32_test_setup.vhd
86,11 → 86,14
-- Extension Options --
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations
TINY_SHIFT_EN => false, -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH => 64, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => 2, -- number of regions (0..64)
PMP_NUM_REGIONS => 0, -- number of regions (0..64)
PMP_MIN_GRANULARITY => 64*1024, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => 2, -- number of implemented HPM counters (0..29)
HPM_NUM_CNTS => 4, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => 40, -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => 16*1024, -- size of processor-internal instruction memory in bytes
/neorv32/trunk/rtl/top_templates/neorv32_top_axi4lite.vhd
65,11 → 65,14
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
266,11 → 269,14
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
TINY_SHIFT_EN => TINY_SHIFT_EN, -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
/neorv32/trunk/rtl/top_templates/neorv32_top_stdlogic.vhd
59,11 → 59,14
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
236,11 → 239,14
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
TINY_SHIFT_EN => TINY_SHIFT_EN, -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
/neorv32/trunk/sim/ghdl/ghdl_sim.sh
24,15 → 24,15
echo ""
 
# List files
echo "Simulation source files:"
ls -l $srcdir_core
ls -l $srcdir_sim
ls -l $srcdir_top_templates
#echo "Simulation source files:"
#ls -l $srcdir_core
#ls -l $srcdir_sim
#ls -l $srcdir_top_templates
#echo ""
 
# Just a hint
echo "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)."
echo ""
echo "Tip: Compile application with USER_FLAGS+=-DUART_SIM_MODE to auto-enable UART's SIM MODE."
echo ""
 
# Analyse sources; libs and images at first!
ghdl -a --work=neorv32 $srcdir_core/neorv32_package.vhd
/neorv32/trunk/sim/neorv32_tb.vhd
70,7 → 70,7
constant ext_mem_b_base_addr_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- wishbone memory base address (external DMEM base)
constant ext_mem_b_size_c : natural := dmem_size_c; -- wishbone memory size in bytes
constant ext_mem_b_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory C (can be used as external IO) --
-- simulated external Wishbone memory C (can be used to simulate external IO access) --
constant ext_mem_c_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address (default begin of EXTERNAL IO area)
constant ext_mem_c_size_c : natural := 64; -- wishbone memory size in bytes
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
206,11 → 206,14
-- Extension Options --
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations
TINY_SHIFT_EN => false, -- use tiny (single-bit) shifter for shift operations
CPU_CNT_WIDTH => 64, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => 4, -- number of regions (0..64)
PMP_MIN_GRANULARITY => 64*1024, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => 12, -- number of inmplemnted HPM counters (0..29)
HPM_CNT_WIDTH => 40, -- total size of HPM counters (1..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => int_imem_c , -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => imem_size_c, -- size of processor-internal instruction memory in bytes
/neorv32/trunk/sw/bootloader/bootloader.c
68,11 → 68,11
/** Enable auto-boot sequence if != 0 */
#define AUTOBOOT_EN (1)
/** Time until the auto-boot sequence starts (in seconds) */
#define AUTOBOOT_TIMEOUT 8
#define AUTOBOOT_TIMEOUT (8)
/** Set to 0 to disable bootloader status LED */
#define STATUS_LED_EN (1)
/** SPI_DIRECT_BOOT_EN: Define/uncomment to enable SPI direct boot (disables the entire user console!) */
//#define SPI_DIRECT_BOOT_EN
/** Set to 1 to enable SPI direct boot (disables the entire user console!) */
#define SPI_DIRECT_BOOT_EN (0)
/** Bootloader status LED at GPIO output port */
#define STATUS_LED (0)
/** SPI flash boot image base address (warning! address might wrap-around!) */
84,7 → 84,7
/** SPI flash sector size in bytes (default = 64kb) */
#define SPI_FLASH_SECTOR_SIZE (64*1024)
/** ASCII char to start fast executable upload process (for use with automatic upload scripts) */
#define FAST_UPLOAD_CMD '#'
#define FAST_UPLOAD_CMD ('#')
/**@}*/
 
 
191,8 → 191,9
**************************************************************************/
int main(void) {
 
#ifdef __riscv_compressed
#warning In order to allow the bootloader to run on any CPU configuration it should be compiled using the base ISA (rv32i/e) only.
// check ISA
#if defined __riscv_atomic || defined __riscv_a || __riscv_b || __riscv_compressed || defined __riscv_c || defined __riscv_mul || defined __riscv_m
#warning In order to allow the bootloader to run on *ANY* CPU configuration it should be compiled using the base ISA (rv32i/e) only.
#endif
 
exe_available = 0; // global variable for executable size; 0 means there is no exe available
214,10 → 215,10
neorv32_spi_setup(CLK_PRSC_128, 0, 0);
}
 
if (STATUS_LED_EN == 1) {
#if (STATUS_LED_EN != 0)
// activate status LED, clear all others
neorv32_gpio_port_set(1 << STATUS_LED);
}
#endif
 
// init UART (no parity bit, no hardware flow control)
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
238,7 → 239,7
// Bootloader will directly boot and execute image from SPI memory.
// No user UART console is available in this mode!
// ------------------------------------------------
#ifdef SPI_DIRECT_BOOT_EN
#if (SPI_DIRECT_BOOT_EN != 0)
#warning Compiling bootloader in 'SPI direct boot mode'. Bootloader will directly boot from SPI memory. No user UART console will be available.
 
neorv32_uart_print("\nNEORV32 bootloader\nAccessing SPI flash at ");
418,10 → 419,10
 
// make sure this was caused by MTIME IRQ
if (cause == TRAP_CODE_MTI) { // raw exception code for MTI
if (STATUS_LED_EN == 1) {
#if (STATUS_LED_EN != 0)
// toggle status LED
neorv32_gpio_pin_toggle(STATUS_LED);
}
#endif
// set time for next IRQ
neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + (SYSINFO_CLK/4));
}
433,9 → 434,9
}
// unknown error
else {
neorv32_uart_print("\n\nEXC (");
neorv32_uart_print("\n\nEXCEPTION mcause=");
print_hex_word(cause);
neorv32_uart_print(") @ 0x");
neorv32_uart_print(" @ pc=");
print_hex_word(neorv32_cpu_csr_read(CSR_MEPC));
system_error(ERROR_SYSTEM);
}
633,7 → 634,7
**************************************************************************/
void print_hex_word(uint32_t num) {
 
static const char hex_symbols[16] = "0123456789ABCDEF";
static const char hex_symbols[16] = "0123456789abcdef";
 
neorv32_uart_print("0x");
 
/neorv32/trunk/sw/common/crt0.S
69,14 → 69,58
 
 
// *********************************************************
// Initialize dummy trap handler base address
// Setup pointers using linker script symbols
// *********************************************************
__crt0_neorv32_trap_init:
la x11, __crt0_dummy_trap_handler
csrw mtvec, x11 // set address of first-level exception handler
__crt0_pointer_init:
.option push
.option norelax
la sp, __crt0_stack_begin
andi sp, sp, 0xfffffffc // make sure this is aligned
addi fp, sp, 0 // frame pointer = stack pointer
la gp, __global_pointer$ // global pointer
.option pop
 
 
// *********************************************************
// Setup CPU core CSRs (some of them DO NOT have a dedicated reset and need to be explicitly initialized)
// *********************************************************
__crt0_cpu_csr_init:
 
// set address of first-level exception handler
la x10, __crt0_dummy_trap_handler
csrw mtvec, x10
csrw mepc, x10
csrw mtval, zero
csrw mcause, zero
 
// no global IRQ enable (is also done by hardware)
csrw mstatus, zero
 
// absolutely no interrupts, thanks
csrw mie, zero
 
// no access from less-privileged modes to counter CSRs
csrw mcounteren, zero
 
// stop all counters except for [m]cycle[h] and [m]instret[h]
li x11, ~5
csrw mcountinhibit, x11
 
// clear cycle counters
csrw mcycle, zero
csrw mcycleh, zero
 
// clear instruction counters
csrw minstret, zero
csrw minstreth, zero
 
#if defined(__riscv_flen) && (__riscv_flen != 0)
// clear floating-point CSR (rounding mode & exception flags)
csrw fcsr, zero
#endif
 
 
// *********************************************************
// Clear integer register file (upper half, if no E extension)
// *********************************************************
#ifndef __riscv_32e
103,28 → 147,6
 
 
// *********************************************************
// No interrupts, thanks
// *********************************************************
__crt0_status_init:
li x10, 0x00001800 // clear mstatus and set mpp(1:0)
csrrw zero, mstatus, x10
csrrw zero, mie, zero // clear mie
 
 
// *********************************************************
// Setup pointers using linker script symbols
// *********************************************************
__crt0_pointer_init:
.option push
.option norelax
la sp, __crt0_stack_begin
andi sp, sp, 0xfffffffc // make sure this is aligned
addi fp, sp, 0 // frame pointer = stack pointer
la gp, __global_pointer$ // global pointer
.option pop
 
 
// *********************************************************
// Reset/deactivate IO/peripheral devices
// Devices, that are not implemented, will cause a store access fault
// which is captured but actually ignored due to the dummy handler.
182,20 → 204,6
addi x10, zero, 0 // argc = 0
addi x11, zero, 0 // argv = 0
 
// clear cycle and instruction counters
csrw mcycle, zero
csrw mcycleh, zero
csrw minstret, zero
csrw minstreth, zero
// enable read-access from user-mode for cycle[h], time[h] and instret[h]
csrwi 0x306, 7 // mcounteren
// enable auto-increment of all counters
csrw 0x320, x0 // mcountinhibit
 
// restore mcause reset value (so that 'main' knows we are coming from reset)
li x12, 0x80000000
csrw mcause, x12
 
// call actual app's main function
jal ra, main
 
/neorv32/trunk/sw/example/cpu_test/main.c
48,13 → 48,17
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
#define BAUD_RATE (19200)
//** Reachable unaligned address */
#define ADDR_UNALIGNED 0x00000002
#define ADDR_UNALIGNED (0x00000002)
//** Unreachable word-aligned address */
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//* external memory base address */
#define EXT_MEM_BASE 0xF0000000
#define ADDR_UNREACHABLE (IO_BASE_ADDRESS-4)
//** external memory base address */
#define EXT_MEM_BASE (0xF0000000)
//** exclusive access to this address will always succeed */
#define ATOMIC_SUCCESS_ADDR (EXT_MEM_BASE + 0)
//** exclusive access to this address will always fail */
#define ATOMIC_FAILURE_ADDR (EXT_MEM_BASE + 4)
/**@}*/
 
 
71,30 → 75,11
int cnt_ok = 0;
/// Global counter for total number of tests
int cnt_test = 0;
/// Global timestamp for traps (stores mcycle.low on trap enter)
uint32_t trap_timestamp32 = 0;
/// Global numbe rof available HPMs
uint32_t num_hpm_cnts_global = 0;
 
 
/**********************************************************************//**
* Unreachable memory-mapped register that should be always available
**************************************************************************/
#define MMR_UNREACHABLE (*(IO_REG32 (ADDR_UNREACHABLE)))
 
 
/**********************************************************************//**
* "Simulated external IO" - exclusive access will always succeed
**************************************************************************/
# define ATOMIC_SUCCESS (*(IO_REG32 (EXT_MEM_BASE + 0)))
 
/**********************************************************************//**
* "Simulated external IO" - exclusive access will always fail
**************************************************************************/
# define ATOMIC_FAILURE (*(IO_REG32 (EXT_MEM_BASE + 4)))
 
 
/**********************************************************************//**
* High-level CPU/processor test program.
*
* @note Applications has to be compiler with <USER_FLAGS+=-DRUN_CPUTEST>
103,7 → 88,6
**************************************************************************/
int main() {
 
volatile uint64_t temp64;
register uint32_t tmp_a, tmp_b;
volatile uint32_t dummy_dst __attribute__((unused));
uint8_t id;
110,7 → 94,7
uint32_t is_simulation = 0;
 
 
// init UART at default baud rate, no parity bits, ho hw flow control
// init UART at default baud rate, no parity bits, no hw flow control
neorv32_uart_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
 
// Disable cpu_test compilation by default
131,26 → 115,25
is_simulation = 0;
}
 
neorv32_uart_printf("\n<< CPU/PROCESSOR TEST >>\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
// ----------------------------------------------
// setup RTE
neorv32_rte_setup(); // this will install a full-detailed debug handler for ALL traps
// ----------------------------------------------
 
// check if we came from hardware reset
neorv32_uart_printf("\nComing from HW reset? ");
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_RESET) {
neorv32_uart_printf("yes\n");
}
else {
neorv32_uart_printf("unknown\n");
}
 
// check available hardware extensions and compare with compiler flags
neorv32_rte_check_isa(0); // silent = 0 -> show message if isa mismatch
 
 
// intro
neorv32_uart_printf("\n<< CPU/PROCESSOR TEST >>\n");
neorv32_uart_printf("build: "__DATE__" "__TIME__"\n");
 
 
// reset performance counter
neorv32_cpu_set_minstret(0);
neorv32_cpu_set_mcycle(0);
 
neorv32_cpu_csr_write(CSR_MCYCLEH, 0);
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
neorv32_cpu_csr_write(CSR_MINSTRETH, 0);
neorv32_cpu_csr_write(CSR_MINSTRET, 0);
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable performance counter auto increment (ALL counters)
neorv32_cpu_csr_write(CSR_MCOUNTEREN, 7); // allow access from user-mode code to standard counters only
 
174,10 → 157,8
 
// configure RTE
// -----------------------------------------------
neorv32_uart_printf("\n\nInitializing NEORV32 RTE... ");
neorv32_uart_printf("\n\nConfiguring NEORV32 RTE... ");
 
neorv32_rte_setup(); // this will install a full-detailed debug handler for all traps
 
int install_err = 0;
// initialize ALL provided trap handler (overriding the default debug handlers)
for (id=0; id<NEORV32_RTE_NUM_TRAPS; id++) {
210,15 → 191,15
 
cnt_test++;
 
// get current cycle counter
temp64 = neorv32_cpu_get_cycle();
// make sure counter is enabled
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
 
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
// get current cycle counter LOW
tmp_a = neorv32_cpu_csr_read(CSR_MCYCLE);
tmp_a = neorv32_cpu_csr_read(CSR_MCYCLE) - tmp_a;
 
// make sure cycle counter has incremented and there was no exception during access
if ((neorv32_cpu_get_cycle() > temp64) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
if ((tmp_a > 0) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
234,17 → 215,22
 
cnt_test++;
 
// get current instruction counter
temp64 = neorv32_cpu_get_instret();
// make sure counter is enabled
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
 
// wait some time to have a nice increment
asm volatile ("nop");
asm volatile ("nop");
// get instruction counter LOW
tmp_a = neorv32_cpu_csr_read(CSR_INSTRET);
tmp_a = neorv32_cpu_csr_read(CSR_INSTRET) - tmp_a;
 
// make sure instruction counter has incremented and there was no exception during access
if ((neorv32_cpu_get_instret() > temp64) &&
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
if ((tmp_a > 0) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
if (tmp_a > 1) {
neorv32_uart_printf("INSTRET_diff > 1 (%u)!", tmp_a);
test_fail();
}
else {
test_ok();
}
}
else {
test_fail();
274,7 → 260,7
tmp_b = neorv32_cpu_csr_read(CSR_CYCLE);
 
// make sure instruction counter has NOT incremented and there was no exception during access
if ((tmp_a == tmp_b) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
if ((tmp_a == tmp_b) && (tmp_a != 0) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
366,29 → 352,27
}
 
 
// ----------------------------------------------------------
// Bus timeout latency estimation
// ----------------------------------------------------------
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Estimating bus time-out latency: ", cnt_test);
cnt_test++;
//// ----------------------------------------------------------
//// Bus timeout latency estimation
//// out of order :P
//// ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//neorv32_uart_printf("[%i] Estimating bus time-out latency: ", cnt_test);
//cnt_test++;
//
//// start timing
//neorv32_cpu_csr_write(CSR_MCYCLE, 0);
//
//// make sure there was a timeout
//if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
// neorv32_uart_printf("~%u cycles ", trap_timestamp32-175); // remove trap handler overhead - empiric value ;)
// test_ok();
//}
//else {
// test_fail();
//}
 
// start timing
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
 
// this store access will timeout
MMR_UNREACHABLE = 0; // trap handler will store mcycle.low to "trap_timestamp32"
 
// make sure there was a timeout
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
neorv32_uart_printf("~%u cycles ", trap_timestamp32-175); // remove trap handler overhead - empiric value ;)
test_ok();
}
else {
test_fail();
}
 
 
// ----------------------------------------------------------
// External memory interface test
// ----------------------------------------------------------
751,7 → 735,7
cnt_test++;
 
// load from unreachable aligned address
dummy_dst = MMR_UNREACHABLE;
dummy_dst = neorv32_cpu_load_unsigned_word(ADDR_UNREACHABLE);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_ACCESS) {
test_ok();
787,7 → 771,7
cnt_test++;
 
// store to unreachable aligned address
MMR_UNREACHABLE = 0;
neorv32_cpu_store_unsigned_word(ADDR_UNREACHABLE, 0);
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
test_ok();
1589,11 → 1573,11
 
cnt_test++;
 
ATOMIC_SUCCESS = 0x11223344;
neorv32_cpu_store_unsigned_word(ATOMIC_SUCCESS_ADDR, 0x11223344);
 
// atomic compare-and-swap
if ((neorv32_cpu_atomic_cas((uint32_t)(&ATOMIC_SUCCESS), 0x11223344, 0xAABBCCDD) == 0) && // status: success
(ATOMIC_SUCCESS == 0xAABBCCDD) && // data written correctly
if ((neorv32_cpu_atomic_cas((uint32_t)ATOMIC_SUCCESS_ADDR, 0x11223344, 0xAABBCCDD) == 0) && // status: success
(neorv32_cpu_load_unsigned_word(ATOMIC_SUCCESS_ADDR) == 0xAABBCCDD) && // data written correctly
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception triggered
test_ok();
}
1627,10 → 1611,10
 
cnt_test++;
 
ATOMIC_FAILURE = 0x55667788;
neorv32_cpu_store_unsigned_word(ATOMIC_FAILURE_ADDR, 0x55667788);
 
// atomic compare-and-swap
if ((neorv32_cpu_atomic_cas((uint32_t)(&ATOMIC_FAILURE), 0x55667788, 0xEEFFDDBB) != 0) && // staus: failed
if ((neorv32_cpu_atomic_cas((uint32_t)ATOMIC_FAILURE_ADDR, 0x55667788, 0xEEFFDDBB) != 0) && // staus: failed
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception triggered
test_ok();
}
1675,7 → 1659,7
// ----------------------------------------------------------
// Final test reports
// ----------------------------------------------------------
neorv32_uart_printf("\n\nTest results:\nOK: %i/%i\nFAILED: %i/%i\n\n", cnt_ok, cnt_test, cnt_fail, cnt_test);
neorv32_uart_printf("\n\nTest results:\nOK: %i/%i\nFAILED: %i/%i\n\n", cnt_ok, cnt_test, cnt_fail, cnt_test);
 
// final result
if (cnt_fail == 0) {
1705,9 → 1689,6
**************************************************************************/
void global_trap_handler(void) {
 
// store time stamp
trap_timestamp32 = neorv32_cpu_csr_read(CSR_MCYCLE);
 
// hack: always come back in MACHINE MODE
register uint32_t mask = (1<<CSR_MSTATUS_MPP_H) | (1<<CSR_MSTATUS_MPP_L);
asm volatile ("csrrs zero, mstatus, %[input_j]" : : [input_j] "r" (mask));
/neorv32/trunk/sw/example/floating_point_test/README.md
1,5 → 1,7
# NEORV32 `Zfinx` Floating-Point Extension
 
The NEORV32 floating-point unit (FPU) implements the `Zfinx` RISC-V extension. The extensions can be enabled via the `CPU_EXTENSION_RISCV_Zfinx` top configuration generic.
 
The RISC-V `Zfinx` single-precision floating-point extensions uses the integer register file `x` instead of the dedicated floating-point `f` register file (which is
defined by the RISC-V `F` single-precision floating-point extension). Hence, the standard data transfer instructions from the `F` extension are **not** available in `Zfinx`:
 
6,7 → 8,6
* floating-point load/store operations (`FLW`, `FSW`) and their compressed versions
* integer register file `x` <-> floating point register file `f` move operations (`FMV.W.X`, `FMV.X.W`)
 
 
:information_source: More information regarding the RISC-V `Zfinx` single-precision floating-point extension can be found in the officail GitHub repo:
[`github.com/riscv/riscv-zfinx`](https://github.com/riscv/riscv-zfinx).
 
14,6 → 15,12
Make sure you **do not** use the `f` ISA attribute when compiling applications that use floating-point arithmetic (`-march=rv32i*f*` is **NOT ALLOWED!**).
 
 
### :warning: FPU Limitations
 
* The FPU **does not support subnormal numbers** yet. Subnormal FPU inputs and subnormal FPU results are always *flushed to zero*. The *classify* instruction `FCLASS` will never set the "subnormal" mask bits.
* Rounding mode `ob100` "round to nearest, ties to max magnitude" is not supported yet (this and all invalid rounding mode configurations behave as "round towards zero" (truncation)).
 
 
## Intrinsic Library
 
The NEORV32 `Zfinx` floating-point extension can still be used using the provided **intrinsic library**. This library uses "custom" inline assmbly instructions
36,3 → 43,10
 
The provided test program `main.c` verifies all currently implemented `Zfinx` instructions by checking the functionality against the pure software-based emulation model
(GCC soft-float library).
 
 
## Resources
 
* Great page with online calculators for floating-point artihmetic: [http://www.ecs.umass.edu/ece/koren/arith/simulator/](http://www.ecs.umass.edu/ece/koren/arith/simulator/)
* A handy tool for visualizing floating-point numbers in their binary representation: [https://www.h-schmidt.net/FloatConverter/IEEE754.html](https://www.h-schmidt.net/FloatConverter/IEEE754.html)
* This helped me to understand what results the different FPU operation generate when having "special" inputs like NaN: [https://techdocs.altium.com/display/FPGA/IEEE+754+Standard+-+Overview](https://techdocs.altium.com/display/FPGA/IEEE+754+Standard+-+Overview)
/neorv32/trunk/sw/example/floating_point_test/main.c
82,6 → 82,8
#define RUN_CLASSIFY_TESTS (1)
//** Run unsupported instructions tests when != 0 */
#define RUN_UNAVAIL_TESTS (1)
//** Run average instruction execution time test when != 0 */
#define RUN_TIMING_TESTS (0)
/**@}*/
 
 
143,7 → 145,8
#if (SILENT_MODE != 0)
neorv32_uart_printf("SILENT_MODE enabled (only showing actual errors)\n");
#endif
neorv32_uart_printf("Test cases per instruction: %u\n\n", (uint32_t)NUM_TEST_CASES);
neorv32_uart_printf("Test cases per instruction: %u\n", (uint32_t)NUM_TEST_CASES);
neorv32_uart_printf("NOTE: The NEORV32 FPU does not support subnormal numbers yet. Subnormal numbers are flushed to zero.\n\n");
 
 
// clear exception status word
413,7 → 416,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fdivs(opa.float_value, opb.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
426,7 → 429,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fsqrts(opa.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
439,7 → 442,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fmadds(opa.float_value, opb.float_value, -opa.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
452,7 → 455,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fmsubs(opa.float_value, opb.float_value, -opa.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
465,7 → 468,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
478,7 → 481,7
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
riscv_intrinsic_fnmadds(opa.float_value, opb.float_value, -opa.float_value);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("%c[1m[FAILED]%c[0m\n", 27, 27);
err_cnt_total++;
}
488,7 → 491,325
#endif
 
 
// final report
// ----------------------------------------------------------------------------
// Instruction execution timing test
// ----------------------------------------------------------------------------
 
#if (RUN_TIMING_TESTS != 0)
 
uint32_t time_start, time_sw, time_hw;
const uint32_t num_runs = 4096;
 
neorv32_uart_printf("\nAverage execution time tests (%u runs)\n", num_runs);
 
 
// signed integer to float
neorv32_uart_printf("FCVT.S.W: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fcvt_sw((int32_t)opa.binary_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fcvt_sw((int32_t)opa.binary_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// float to signed integer
neorv32_uart_printf("FCVT.W.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.binary_value = (uint32_t)riscv_intrinsic_fcvt_ws(opa.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.binary_value = (uint32_t)riscv_emulate_fcvt_ws(opa.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// addition
neorv32_uart_printf("FADD.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fadds(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fadds(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// subtraction
neorv32_uart_printf("FSUB.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fsubs(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fsubs(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// multiplication
neorv32_uart_printf("FMUL.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fmuls(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fmuls(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// Max
neorv32_uart_printf("FMAX.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fmaxs(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fmaxs(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// Comparison
neorv32_uart_printf("FLE.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fles(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fles(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
 
 
// Sign-injection
neorv32_uart_printf("FSGNJX.S: ");
time_sw = 0;
time_hw = 0;
err_cnt = 0;
for (i=0; i<num_runs; i++) {
opa.binary_value = get_test_vector();
opb.binary_value = get_test_vector();
 
// hardware execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_hw.float_value = riscv_intrinsic_fsgnjxs(opa.float_value, opb.float_value);
}
time_hw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
time_hw -= 4; // remove the 2 dummy instructions
 
// software (emulation) execution time
time_start = neorv32_cpu_csr_read(CSR_CYCLE);
{
res_sw.float_value = riscv_emulate_fsgnjxs(opa.float_value, opb.float_value);
}
time_sw += neorv32_cpu_csr_read(CSR_CYCLE) - time_start;
 
if (res_sw.binary_value != res_hw.binary_value) {
err_cnt++;
}
}
 
if (err_cnt == 0) {
neorv32_uart_printf("cycles[SW] = %u vs. cycles[HW] = %u\n", time_sw/num_runs, time_hw/num_runs);
}
else {
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
err_cnt_total++;
}
#endif
 
 
// ----------------------------------------------------------------------------
// Final report
// ----------------------------------------------------------------------------
 
if (err_cnt_total != 0) {
neorv32_uart_printf("\n%c[1m[ZFINX EXTENSION VERIFICATION FAILED!]%c[0m\n", 27, 27);
neorv32_uart_printf("%u errors in %u test cases\n", err_cnt_total, test_cnt*(uint32_t)NUM_TEST_CASES);
529,10 → 850,6
tmp.binary_value = xorshift32();
}
 
// subnormal numbers are not supported yet!
// flush them to zero
//tmp.float_value = subnormal_flush(tmp.float_value);
 
return tmp.binary_value;
}
 
/neorv32/trunk/sw/example/floating_point_test/neorv32_zfinx_extension_intrinsics.h
90,7 → 90,7
*
* @warning Subnormal numbers are not supported yet! Flush them to zero.
*
* @param[in] tmp Source operand 1.
* @param[in] tmp Source operand.
* @return Result.
**************************************************************************/
float subnormal_flush(float tmp) {
167,13 → 167,11
/**********************************************************************//**
* Single-precision floating-point addition
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fadds(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fadds(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
189,6 → 187,9
// fadd.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0000000, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
197,13 → 198,11
/**********************************************************************//**
* Single-precision floating-point subtraction
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fsubs(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fsubs(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
219,6 → 218,9
// fsub.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0000100, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
227,13 → 229,11
/**********************************************************************//**
* Single-precision floating-point multiplication
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fmuls(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fmuls(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
249,6 → 249,9
// fmul.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0001000, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
257,13 → 260,11
/**********************************************************************//**
* Single-precision floating-point minimum
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fmins(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fmins(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
279,6 → 280,9
// fmin.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010100, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
287,13 → 291,11
/**********************************************************************//**
* Single-precision floating-point maximum
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fmaxs(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fmaxs(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
309,6 → 311,9
// fmax.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010100, a1, a0, 0b001, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
317,12 → 322,10
/**********************************************************************//**
* Single-precision floating-point convert float to unsigned integer
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
uint32_t __attribute__ ((noinline)) riscv_intrinsic_fcvt_wus(float rs1) {
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_fcvt_wus(float rs1) {
 
float_conv_t opa;
opa.float_value = rs1;
336,6 → 339,9
// fcvt.wu.s a0, a0
CUSTOM_INSTR_R2_TYPE(0b1100000, x1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return result;
}
 
343,12 → 349,10
/**********************************************************************//**
* Single-precision floating-point convert float to signed integer
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
int32_t __attribute__ ((noinline)) riscv_intrinsic_fcvt_ws(float rs1) {
inline int32_t __attribute__ ((always_inline)) riscv_intrinsic_fcvt_ws(float rs1) {
 
float_conv_t opa;
opa.float_value = rs1;
362,6 → 366,9
// fcvt.w.s a0, a0
CUSTOM_INSTR_R2_TYPE(0b1100000, x0, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return (int32_t)result;
}
 
369,12 → 376,10
/**********************************************************************//**
* Single-precision floating-point convert unsigned integer to float
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fcvt_swu(uint32_t rs1) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fcvt_swu(uint32_t rs1) {
 
float_conv_t res;
 
387,6 → 392,9
// fcvt.s.wu a0, a0
CUSTOM_INSTR_R2_TYPE(0b1101000, x1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
395,12 → 403,10
/**********************************************************************//**
* Single-precision floating-point convert signed integer to float
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fcvt_sw(int32_t rs1) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fcvt_sw(int32_t rs1) {
 
float_conv_t res;
 
413,6 → 419,9
// fcvt.s.w a0, a0
CUSTOM_INSTR_R2_TYPE(0b1101000, x0, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
421,13 → 430,11
/**********************************************************************//**
* Single-precision floating-point equal comparison
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
uint32_t __attribute__ ((noinline)) riscv_intrinsic_feqs(float rs1, float rs2) {
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_feqs(float rs1, float rs2) {
 
float_conv_t opa, opb;
opa.float_value = rs1;
443,6 → 450,9
// feq.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b1010000, a1, a0, 0b010, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return result;
}
 
450,13 → 460,11
/**********************************************************************//**
* Single-precision floating-point less-than comparison
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
uint32_t __attribute__ ((noinline)) riscv_intrinsic_flts(float rs1, float rs2) {
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_flts(float rs1, float rs2) {
 
float_conv_t opa, opb;
opa.float_value = rs1;
472,6 → 480,9
// flt.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b1010000, a1, a0, 0b001, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return result;
}
 
479,13 → 490,11
/**********************************************************************//**
* Single-precision floating-point less-than-or-equal comparison
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
uint32_t __attribute__ ((noinline)) riscv_intrinsic_fles(float rs1, float rs2) {
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_fles(float rs1, float rs2) {
 
float_conv_t opa, opb;
opa.float_value = rs1;
501,6 → 510,9
// fle.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b1010000, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return result;
}
 
508,13 → 520,11
/**********************************************************************//**
* Single-precision floating-point sign-injection
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fsgnjs(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fsgnjs(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
530,6 → 540,9
// fsgnj.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
538,13 → 551,11
/**********************************************************************//**
* Single-precision floating-point sign-injection NOT
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fsgnjns(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fsgnjns(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
560,6 → 571,9
// fsgnjn.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b001, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
568,13 → 582,11
/**********************************************************************//**
* Single-precision floating-point sign-injection XOR
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fsgnjxs(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fsgnjxs(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
590,6 → 602,9
// fsgnjx.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0010000, a1, a0, 0b010, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
598,12 → 613,10
/**********************************************************************//**
* Single-precision floating-point number classification
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
uint32_t __attribute__ ((noinline)) riscv_intrinsic_fclasss(float rs1) {
inline uint32_t __attribute__ ((always_inline)) riscv_intrinsic_fclasss(float rs1) {
 
float_conv_t opa;
opa.float_value = rs1;
617,6 → 630,9
// fclass.s a0, a0
CUSTOM_INSTR_R2_TYPE(0b1110000, x0, a0, 0b001, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
return result;
}
 
628,8 → 644,6
/**********************************************************************//**
* Single-precision floating-point division
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0).
636,7 → 650,7
* @param[in] rs2 Source operand 2 (a1).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fdivs(float rs1, float rs2) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fdivs(float rs1, float rs2) {
 
float_conv_t opa, opb, res;
opa.float_value = rs1;
652,6 → 666,9
// fdiv.s a0, a0, x1
CUSTOM_INSTR_R2_TYPE(0b0001100, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
660,14 → 677,12
/**********************************************************************//**
* Single-precision floating-point square root
*
* @note "noinline" attributed to make sure arguments/return values are in a0 and a1.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0).
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fsqrts(float rs1) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fsqrts(float rs1) {
 
float_conv_t opa, res;
opa.float_value = rs1;
681,6 → 696,9
// fsqrt.s a0, a0, a1
CUSTOM_INSTR_R2_TYPE(0b0101100, a1, a0, 0b000, a0, 0b1010011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
689,8 → 707,6
/**********************************************************************//**
* Single-precision floating-point fused multiply-add
*
* @note "noinline" attributed to make sure arguments/return values are in a0, a1 and a2.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0)
698,7 → 714,7
* @param[in] rs3 Source operand 3 (a2)
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fmadds(float rs1, float rs2, float rs3) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fmadds(float rs1, float rs2, float rs3) {
 
float_conv_t opa, opb, opc, res;
opa.float_value = rs1;
717,6 → 733,9
// fmadd.s a0, a0, a1, a2
CUSTOM_INSTR_R3_TYPE(a2, a1, a0, 0b000, a0, 0b1000011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
725,8 → 744,6
/**********************************************************************//**
* Single-precision floating-point fused multiply-sub
*
* @note "noinline" attributed to make sure arguments/return values are in a0, a1 and a2.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0)
734,7 → 751,7
* @param[in] rs3 Source operand 3 (a2)
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fmsubs(float rs1, float rs2, float rs3) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fmsubs(float rs1, float rs2, float rs3) {
 
float_conv_t opa, opb, opc, res;
opa.float_value = rs1;
753,6 → 770,9
// fmsub.s a0, a0, a1, a2
CUSTOM_INSTR_R3_TYPE(a2, a1, a0, 0b000, a0, 0b1000111);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
761,8 → 781,6
/**********************************************************************//**
* Single-precision floating-point fused negated multiply-sub
*
* @note "noinline" attributed to make sure arguments/return values are in a0, a1 and a2.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0)
770,7 → 788,7
* @param[in] rs3 Source operand 3 (a2)
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fnmsubs(float rs1, float rs2, float rs3) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fnmsubs(float rs1, float rs2, float rs3) {
 
float_conv_t opa, opb, opc, res;
opa.float_value = rs1;
789,6 → 807,9
// fnmsub.s a0, a0, a1, a2
CUSTOM_INSTR_R3_TYPE(a2, a1, a0, 0b000, a0, 0b1001011);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
797,8 → 818,6
/**********************************************************************//**
* Single-precision floating-point fused negated multiply-add
*
* @note "noinline" attributed to make sure arguments/return values are in a0, a1 and a2.
*
* @warning This instruction is not supported and should raise an illegal instruction exception when executed.
*
* @param[in] rs1 Source operand 1 (a0)
806,7 → 825,7
* @param[in] rs3 Source operand 3 (a2)
* @return Result.
**************************************************************************/
float __attribute__ ((noinline)) riscv_intrinsic_fnmadds(float rs1, float rs2, float rs3) {
inline float __attribute__ ((always_inline)) riscv_intrinsic_fnmadds(float rs1, float rs2, float rs3) {
 
float_conv_t opa, opb, opc, res;
opa.float_value = rs1;
825,6 → 844,9
// fnmadd.s a0, a0, a1, a2
CUSTOM_INSTR_R3_TYPE(a2, a1, a0, 0b000, a0, 0b1001111);
 
// dummy instruction to prevent GCC "constprop" optimization
asm volatile ("add %[res], %[input], x0" : [res] "=r" (result) : [input] "r" (result) );
 
res.binary_value = result;
return res.float_value;
}
841,7 → 863,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fadds(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fadds(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
858,7 → 880,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fsubs(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fsubs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
875,7 → 897,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fmuls(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fmuls(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
892,7 → 914,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fmins(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fmins(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
933,7 → 955,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fmaxs(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fmaxs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
974,7 → 996,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
uint32_t riscv_emulate_fcvt_wus(float rs1) {
uint32_t __attribute__ ((noinline)) riscv_emulate_fcvt_wus(float rs1) {
 
float opa = subnormal_flush(rs1);
 
988,7 → 1010,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
int32_t riscv_emulate_fcvt_ws(float rs1) {
int32_t __attribute__ ((noinline)) riscv_emulate_fcvt_ws(float rs1) {
 
float opa = subnormal_flush(rs1);
 
1002,7 → 1024,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
float riscv_emulate_fcvt_swu(uint32_t rs1) {
float __attribute__ ((noinline)) riscv_emulate_fcvt_swu(uint32_t rs1) {
 
return (float)rs1;
}
1014,7 → 1036,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
float riscv_emulate_fcvt_sw(int32_t rs1) {
float __attribute__ ((noinline)) riscv_emulate_fcvt_sw(int32_t rs1) {
 
return (float)rs1;
}
1027,7 → 1049,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
uint32_t riscv_emulate_feqs(float rs1, float rs2) {
uint32_t __attribute__ ((noinline)) riscv_emulate_feqs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1055,7 → 1077,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
uint32_t riscv_emulate_flts(float rs1, float rs2) {
uint32_t __attribute__ ((noinline)) riscv_emulate_flts(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1080,7 → 1102,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
uint32_t riscv_emulate_fles(float rs1, float rs2) {
uint32_t __attribute__ ((noinline)) riscv_emulate_fles(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1105,7 → 1127,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fsgnjs(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fsgnjs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1142,7 → 1164,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fsgnjns(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fsgnjns(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1179,7 → 1201,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fsgnjxs(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fsgnjxs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1215,7 → 1237,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
uint32_t riscv_emulate_fclasss(float rs1) {
uint32_t __attribute__ ((noinline)) riscv_emulate_fclasss(float rs1) {
 
float opa = subnormal_flush(rs1);
 
1287,7 → 1309,7
* @param[in] rs2 Source operand 2.
* @return Result.
**************************************************************************/
float riscv_emulate_fdivs(float rs1, float rs2) {
float __attribute__ ((noinline)) riscv_emulate_fdivs(float rs1, float rs2) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1303,7 → 1325,7
* @param[in] rs1 Source operand 1.
* @return Result.
**************************************************************************/
float riscv_emulate_fsqrts(float rs1) {
float __attribute__ ((noinline)) riscv_emulate_fsqrts(float rs1) {
 
float opa = subnormal_flush(rs1);
 
1324,7 → 1346,7
* @param[in] rs3 Source operand 3
* @return Result.
**************************************************************************/
float riscv_emulate_fmadds(float rs1, float rs2, float rs3) {
float __attribute__ ((noinline)) riscv_emulate_fmadds(float rs1, float rs2, float rs3) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1343,7 → 1365,7
* @param[in] rs3 Source operand 3
* @return Result.
**************************************************************************/
float riscv_emulate_fmsubs(float rs1, float rs2, float rs3) {
float __attribute__ ((noinline)) riscv_emulate_fmsubs(float rs1, float rs2, float rs3) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1362,7 → 1384,7
* @param[in] rs3 Source operand 3
* @return Result.
**************************************************************************/
float riscv_emulate_fnmsubs(float rs1, float rs2, float rs3) {
float __attribute__ ((noinline)) riscv_emulate_fnmsubs(float rs1, float rs2, float rs3) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
1381,7 → 1403,7
* @param[in] rs3 Source operand 3
* @return Result.
**************************************************************************/
float riscv_emulate_fnmadds(float rs1, float rs2, float rs3) {
float __attribute__ ((noinline)) riscv_emulate_fnmadds(float rs1, float rs2, float rs3) {
 
float opa = subnormal_flush(rs1);
float opb = subnormal_flush(rs2);
/neorv32/trunk/sw/example/hex_viewer/main.c
158,10 → 158,8
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
register uint32_t mem_data = 0;
uint32_t mem_data = neorv32_cpu_load_unsigned_word(mem_address);
 
asm volatile ("lw %[rdata], 0(%[raddr])" : [rdata] "=r" (mem_data) : [raddr] "r" (mem_address));
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart_printf("0x%x", mem_data);
181,12 → 179,12
// enter address
neorv32_uart_printf("Enter address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// enter data
neorv32_uart_printf("\nEnter data (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// perform write access
neorv32_uart_printf("\n[0x%x] = ", mem_address);
193,8 → 191,7
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
asm volatile ("sw %[wdata], 0(%[waddr])" : : [wdata] "r" (mem_data), [waddr] "r" (mem_address));
asm volatile ("nop");
neorv32_cpu_store_unsigned_word(mem_address, mem_data);
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
254,7 → 251,7
// enter base address
neorv32_uart_printf("Enter base address (8 hex chars): 0x");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
neorv32_uart_printf("\nPress key to start dumping. Press any key to abort.\n");
 
261,7 → 258,7
neorv32_uart_getc(); // wait for key
 
// perform read accesses
register uint32_t mem_data = 0;
uint32_t mem_data = 0;
while(neorv32_uart_char_received() == 0) {
 
neorv32_uart_printf("[0x%x] = ", mem_address);
268,8 → 265,7
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
asm volatile ("lw %[rdata], 0(%[raddr])" : [rdata] "=r" (mem_data) : [raddr] "r" (mem_address));
asm volatile ("nop");
mem_data = neorv32_cpu_load_unsigned_word(mem_address);
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
/neorv32/trunk/sw/lib/include/neorv32.h
351,9 → 351,39
* CPU <b>mcounteren</b> CSR (r/w): Machine counter enable (RISC-V spec.)
**************************************************************************/
enum NEORV32_CSR_MCOUNTEREN_enum {
CSR_MCOUNTEREN_CY = 0, /**< CPU mcounteren CSR (0): CY - Allow access to cycle[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_TM = 1, /**< CPU mcounteren CSR (1): TM - Allow access to time[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_IR = 2 /**< CPU mcounteren CSR (2): IR - Allow access to instret[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_CY = 0, /**< CPU mcounteren CSR (0): CY - Allow access to cycle[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_TM = 1, /**< CPU mcounteren CSR (1): TM - Allow access to time[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_IR = 2, /**< CPU mcounteren CSR (2): IR - Allow access to instret[h] CSRs from U-mode when set (r/w) */
 
CSR_MCOUNTEREN_HPM3 = 3, /**< CPU mcounteren CSR (3): HPM3 - Allow access to hpmcnt3[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM4 = 4, /**< CPU mcounteren CSR (4): HPM4 - Allow access to hpmcnt4[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM5 = 5, /**< CPU mcounteren CSR (5): HPM5 - Allow access to hpmcnt5[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM6 = 6, /**< CPU mcounteren CSR (6): HPM6 - Allow access to hpmcnt6[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM7 = 7, /**< CPU mcounteren CSR (7): HPM7 - Allow access to hpmcnt7[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM8 = 8, /**< CPU mcounteren CSR (8): HPM8 - Allow access to hpmcnt8[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM9 = 9, /**< CPU mcounteren CSR (9): HPM9 - Allow access to hpmcnt9[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM10 = 10, /**< CPU mcounteren CSR (10): HPM10 - Allow access to hpmcnt10[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM11 = 11, /**< CPU mcounteren CSR (11): HPM11 - Allow access to hpmcnt11[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM12 = 12, /**< CPU mcounteren CSR (12): HPM12 - Allow access to hpmcnt12[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM13 = 13, /**< CPU mcounteren CSR (13): HPM13 - Allow access to hpmcnt13[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM14 = 14, /**< CPU mcounteren CSR (14): HPM14 - Allow access to hpmcnt14[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM15 = 15, /**< CPU mcounteren CSR (15): HPM15 - Allow access to hpmcnt15[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM16 = 16, /**< CPU mcounteren CSR (16): HPM16 - Allow access to hpmcnt16[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM17 = 17, /**< CPU mcounteren CSR (17): HPM17 - Allow access to hpmcnt17[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM18 = 18, /**< CPU mcounteren CSR (18): HPM18 - Allow access to hpmcnt18[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM19 = 19, /**< CPU mcounteren CSR (19): HPM19 - Allow access to hpmcnt19[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM20 = 20, /**< CPU mcounteren CSR (20): HPM20 - Allow access to hpmcnt20[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM21 = 21, /**< CPU mcounteren CSR (21): HPM21 - Allow access to hpmcnt21[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM22 = 22, /**< CPU mcounteren CSR (22): HPM22 - Allow access to hpmcnt22[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM23 = 23, /**< CPU mcounteren CSR (23): HPM23 - Allow access to hpmcnt23[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM24 = 24, /**< CPU mcounteren CSR (24): HPM24 - Allow access to hpmcnt24[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM25 = 25, /**< CPU mcounteren CSR (25): HPM25 - Allow access to hpmcnt25[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM26 = 26, /**< CPU mcounteren CSR (26): HPM26 - Allow access to hpmcnt26[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM27 = 27, /**< CPU mcounteren CSR (27): HPM27 - Allow access to hpmcnt27[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM28 = 28, /**< CPU mcounteren CSR (28): HPM28 - Allow access to hpmcnt28[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM29 = 29, /**< CPU mcounteren CSR (29): HPM29 - Allow access to hpmcnt29[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM30 = 30, /**< CPU mcounteren CSR (30): HPM30 - Allow access to hpmcnt30[h] CSRs from U-mode when set (r/w) */
CSR_MCOUNTEREN_HPM31 = 31 /**< CPU mcounteren CSR (31): HPM31 - Allow access to hpmcnt31[h] CSRs from U-mode when set (r/w) */
};
 
 
361,8 → 391,38
* CPU <b>mcountinhibit</b> CSR (r/w): Machine counter-inhibit (RISC-V spec.)
**************************************************************************/
enum NEORV32_CSR_MCOUNTINHIBIT_enum {
CSR_MCOUNTINHIBIT_CY = 0, /**< CPU mcountinhibit CSR (0): CY - Enable auto-increment of [m]cycle[h] CSR when set (r/w) */
CSR_MCOUNTINHIBIT_IR = 2 /**< CPU mcountinhibit CSR (2): IR - Enable auto-increment of [m]instret[h] CSR when set (r/w) */
CSR_MCOUNTINHIBIT_CY = 0, /**< CPU mcountinhibit CSR (0): CY - Enable auto-increment of [m]cycle[h] CSR when set (r/w) */
CSR_MCOUNTINHIBIT_IR = 2, /**< CPU mcountinhibit CSR (2): IR - Enable auto-increment of [m]instret[h] CSR when set (r/w) */
 
CSR_MCOUNTINHIBIT_HPM3 = 3, /**< CPU mcountinhibit CSR (3): HPM3 - Enable auto-increment of hpmcnt3[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM4 = 4, /**< CPU mcountinhibit CSR (4): HPM4 - Enable auto-increment of hpmcnt4[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM5 = 5, /**< CPU mcountinhibit CSR (5): HPM5 - Enable auto-increment of hpmcnt5[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM6 = 6, /**< CPU mcountinhibit CSR (6): HPM6 - Enable auto-increment of hpmcnt6[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM7 = 7, /**< CPU mcountinhibit CSR (7): HPM7 - Enable auto-increment of hpmcnt7[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM8 = 8, /**< CPU mcountinhibit CSR (8): HPM8 - Enable auto-increment of hpmcnt8[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM9 = 9, /**< CPU mcountinhibit CSR (9): HPM9 - Enable auto-increment of hpmcnt9[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM10 = 10, /**< CPU mcountinhibit CSR (10): HPM10 - Enable auto-increment of hpmcnt10[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM11 = 11, /**< CPU mcountinhibit CSR (11): HPM11 - Enable auto-increment of hpmcnt11[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM12 = 12, /**< CPU mcountinhibit CSR (12): HPM12 - Enable auto-increment of hpmcnt12[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM13 = 13, /**< CPU mcountinhibit CSR (13): HPM13 - Enable auto-increment of hpmcnt13[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM14 = 14, /**< CPU mcountinhibit CSR (14): HPM14 - Enable auto-increment of hpmcnt14[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM15 = 15, /**< CPU mcountinhibit CSR (15): HPM15 - Enable auto-increment of hpmcnt15[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM16 = 16, /**< CPU mcountinhibit CSR (16): HPM16 - Enable auto-increment of hpmcnt16[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM17 = 17, /**< CPU mcountinhibit CSR (17): HPM17 - Enable auto-increment of hpmcnt17[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM18 = 18, /**< CPU mcountinhibit CSR (18): HPM18 - Enable auto-increment of hpmcnt18[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM19 = 19, /**< CPU mcountinhibit CSR (19): HPM19 - Enable auto-increment of hpmcnt19[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM20 = 20, /**< CPU mcountinhibit CSR (20): HPM20 - Enable auto-increment of hpmcnt20[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM21 = 21, /**< CPU mcountinhibit CSR (21): HPM21 - Enable auto-increment of hpmcnt21[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM22 = 22, /**< CPU mcountinhibit CSR (22): HPM22 - Enable auto-increment of hpmcnt22[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM23 = 23, /**< CPU mcountinhibit CSR (23): HPM23 - Enable auto-increment of hpmcnt23[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM24 = 24, /**< CPU mcountinhibit CSR (24): HPM24 - Enable auto-increment of hpmcnt24[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM25 = 25, /**< CPU mcountinhibit CSR (25): HPM25 - Enable auto-increment of hpmcnt25[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM26 = 26, /**< CPU mcountinhibit CSR (26): HPM26 - Enable auto-increment of hpmcnt26[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM27 = 27, /**< CPU mcountinhibit CSR (27): HPM27 - Enable auto-increment of hpmcnt27[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM28 = 28, /**< CPU mcountinhibit CSR (28): HPM28 - Enable auto-increment of hpmcnt28[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM29 = 29, /**< CPU mcountinhibit CSR (29): HPM29 - Enable auto-increment of hpmcnt29[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM30 = 30, /**< CPU mcountinhibit CSR (30): HPM30 - Enable auto-increment of hpmcnt30[h] when set (r/w) */
CSR_MCOUNTINHIBIT_HPM31 = 31 /**< CPU mcountinhibit CSR (31): HPM31 - Enable auto-increment of hpmcnt31[h] when set (r/w) */
};
 
 
449,7 → 509,9
CSR_MZEXT_ZBB = 2, /**< CPU mzext CSR (2): Zbb extension (B sub-extension) available when set (r/-) */
CSR_MZEXT_ZBS = 3, /**< CPU mzext CSR (3): Zbs extension (B sub-extension) available when set (r/-) */
CSR_MZEXT_ZBA = 4, /**< CPU mzext CSR (4): Zba extension (B sub-extension) available when set (r/-) */
CSR_MZEXT_ZFINX = 5 /**< CPU mzext CSR (5): Zfinx extension (F sub-/alternative-extension) available when set (r/-) */
CSR_MZEXT_ZFINX = 5, /**< CPU mzext CSR (5): Zfinx extension (F sub-/alternative-extension) available when set (r/-) */
CSR_MZEXT_ZXSCNT = 6, /**< CPU mzext CSR (6): Custom extension - Small CPU counters: "cycle" & "instret" CSRs have less than 64-bit when set (r/-) */
CSR_MZEXT_ZXNOCNT = 7 /**< CPU mzext CSR (7): Custom extension - NO CPU counters: "cycle" & "instret" CSRs are NOT available at all when set (r/-) */
};
 
 
491,7 → 553,6
TRAP_CODE_S_ACCESS = 0x00000007, /**< 0.7: Store (bus) access fault */
TRAP_CODE_UENV_CALL = 0x00000008, /**< 0.8: Environment call from user mode (ECALL instruction) */
TRAP_CODE_MENV_CALL = 0x0000000b, /**< 0.11: Environment call from machine mode (ECALL instruction) */
TRAP_CODE_RESET = 0x80000000, /**< 1.0: Hardware reset */
TRAP_CODE_MSI = 0x80000003, /**< 1.3: Machine software interrupt */
TRAP_CODE_MTI = 0x80000007, /**< 1.7: Machine timer interrupt */
TRAP_CODE_MEI = 0x8000000b, /**< 1.11: Machine external interrupt */
/neorv32/trunk/sw/lib/include/neorv32_cpu.h
50,7 → 50,7
uint64_t neorv32_cpu_get_instret(void);
void neorv32_cpu_set_minstret(uint64_t value);
uint64_t neorv32_cpu_get_systime(void);
void neorv32_cpu_delay_ms(uint32_t time_ms);
void neorv32_cpu_delay_ms(int16_t time_ms);
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void);
int neorv32_cpu_atomic_cas(uint32_t addr, uint32_t expected, uint32_t desired);
uint32_t neorv32_cpu_pmp_get_num_regions(void);
57,10 → 57,115
uint32_t neorv32_cpu_pmp_get_granularity(void);
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint32_t size, uint8_t config);
uint32_t neorv32_cpu_hpm_get_counters(void);
uint32_t neorv32_cpu_hpm_get_size(void);
int neorv32_check_zextension(uint32_t);
 
 
/**********************************************************************//**
* Store unsigned word to address space.
*
* @note An unaligned access address will raise an alignment exception.
*
* @param[in] addr Address (32-bit).
* @param[in] wdata Data word (32-bit) to store.
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_word(uint32_t addr, uint32_t wdata) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data = wdata;
 
asm volatile ("sw %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
}
 
 
/**********************************************************************//**
* Store unsigned half-word to address space.
*
* @note An unaligned access address will raise an alignment exception.
*
* @param[in] addr Address (32-bit).
* @param[in] wdata Data half-word (16-bit) to store.
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_half(uint32_t addr, uint16_t wdata) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data = (uint32_t)wdata;
 
asm volatile ("sh %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
}
 
 
/**********************************************************************//**
* Store unsigned byte to address space.
*
* @param[in] addr Address (32-bit).
* @param[in] wdata Data byte (8-bit) to store.
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_store_unsigned_byte(uint32_t addr, uint8_t wdata) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data = (uint32_t)wdata;
 
asm volatile ("sb %[da], 0(%[ad])" : : [da] "r" (reg_data), [ad] "r" (reg_addr));
}
 
 
/**********************************************************************//**
* Load unsigned word from address space.
*
* @note An unaligned access address will raise an alignment exception.
*
* @param[in] addr Address (32-bit).
* @return Read data word (32-bit).
**************************************************************************/
inline uint32_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_word(uint32_t addr) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data;
 
asm volatile ("lw %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
 
return (uint32_t)reg_data;
}
 
 
/**********************************************************************//**
* Load unsigned half-word from address space.
*
* @note An unaligned access address will raise an alignment exception.
*
* @param[in] addr Address (32-bit).
* @return Read data half-word (16-bit).
**************************************************************************/
inline uint16_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_half(uint32_t addr) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data;
 
asm volatile ("lhu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
 
return (uint16_t)reg_data;
}
 
 
/**********************************************************************//**
* Load unsigned byte from address space.
*
* @param[in] addr Address (32-bit).
* @return Read data byte (8-bit).
**************************************************************************/
inline uint8_t __attribute__ ((always_inline)) neorv32_cpu_load_unsigned_byte(uint32_t addr) {
 
register uint32_t reg_addr = addr;
register uint32_t reg_data;
 
asm volatile ("lbu %[da], 0(%[ad])" : [da] "=r" (reg_data) : [ad] "r" (reg_addr));
 
return (uint8_t)reg_data;
}
 
 
/**********************************************************************//**
* Read data from CPU configuration and status register (CSR).
*
* @param[in] csr_id ID of CSR to read. See #NEORV32_CSR_enum.
96,8 → 201,8
* @note This function executes the WFI insstruction.
* The WFI (wait for interrupt) instruction will make the CPU stall until
* an interupt request is detected. Interrupts have to be globally enabled
* and at least one external source must be enabled (e.g., the CLIC or the machine
* timer) to allow the CPU to wake up again. If 'Zicsr' CPU extension is disabled,
* and at least one external source must be enabled (like the MTI machine
* timer interrupt) to allow the CPU to wake up again. If 'Zicsr' CPU extension is disabled,
* this will permanently stall the CPU.
**************************************************************************/
inline void __attribute__ ((always_inline)) neorv32_cpu_sleep(void) {
/neorv32/trunk/sw/lib/source/neorv32_cpu.c
271,27 → 271,36
 
 
/**********************************************************************//**
* Simple delay function using busy wait.
* Simple delay function using busy wait (simple loop).
*
* @warning This function requires the cycle CSR(s). Hence, the Zicsr extension is mandatory.
* @warning This function is not really precise (especially if there is no M extension available)! Use a timer-based approach (using cycle or time CSRs) for precise timings.
*
* @param[in] time_ms Time in ms to wait.
* @param[in] time_ms Time in ms to wait (max 32767ms).
**************************************************************************/
void neorv32_cpu_delay_ms(uint32_t time_ms) {
void neorv32_cpu_delay_ms(int16_t time_ms) {
 
uint64_t time_resume = neorv32_cpu_get_cycle();
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop
 
// check input
if (time_ms < 0) {
time_ms = -time_ms;
}
 
uint32_t clock = SYSINFO_CLK; // clock ticks per second
clock = clock / 1000; // clock ticks per ms
 
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
time_resume += wait_cycles;
uint32_t ticks = (uint32_t)(wait_cycles / loop_cycles_c);
 
while(1) {
if (neorv32_cpu_get_cycle() >= time_resume) {
break;
}
}
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned
" __neorv32_cpu_delay_ms_start: \n"
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken)
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken)
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles
" nop \n" // 2 cycles
" j __neorv32_cpu_delay_ms_start \n" // 6 cycles
" __neorv32_cpu_delay_ms_end: "
: [cnt_w] "=r" (ticks) : [cnt_r] "r" (ticks));
}
 
 
304,10 → 313,10
 
// make sure to use NO registers in here! -> naked
 
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can now use ra as general purpose register in here
"li ra, %[input_imm] \n\t" // bit mask to clear the two MPP bits
"csrrc zero, mstatus, ra \n\t" // clear MPP bits -> MPP=u-mode
"mret \n\t" // return and switch to user mode
asm volatile ("csrw mepc, ra \n" // move return address to mepc so we can return using "mret". also, we can now use ra as general purpose register in here
"li ra, %[input_imm] \n" // bit mask to clear the two MPP bits
"csrrc zero, mstatus, ra \n" // clear MPP bits -> MPP=u-mode
"mret \n" // return and switch to user mode
: : [input_imm] "i" ((1<<CSR_MSTATUS_MPP_H) | (1<<CSR_MSTATUS_MPP_L)));
}
 
621,6 → 630,11
**************************************************************************/
uint32_t neorv32_cpu_hpm_get_counters(void) {
 
// inhibit all HPM counters
uint32_t tmp = neorv32_cpu_csr_read(CSR_MCOUNTINHIBIT);
tmp |= 0xfffffff8;
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, tmp);
 
// try setting all mhpmcounter* CSRs to 1
neorv32_cpu_csr_write(CSR_MHPMCOUNTER3, 1);
neorv32_cpu_csr_write(CSR_MHPMCOUNTER4, 1);
650,7 → 664,7
neorv32_cpu_csr_write(CSR_MHPMCOUNTER28, 1);
neorv32_cpu_csr_write(CSR_MHPMCOUNTER29, 1);
 
// sum up all written ones (only available PMPCFG* CSRs/entries will return =! 0)
// sum up all written ones (only available HPM counter CSRs will return =! 0)
uint32_t num_hpm_cnts = 0;
 
num_hpm_cnts += neorv32_cpu_csr_read(CSR_MHPMCOUNTER3);
686,6 → 700,42
 
 
/**********************************************************************//**
* Hardware performance monitors (HPM): Get total counter width
*
* @warning This function overrides mhpmcounter3[h] CSRs.
*
* @return Size of HPM counter bits (1-64).
**************************************************************************/
uint32_t neorv32_cpu_hpm_get_size(void) {
 
// inhibt auto-update
asm volatile ("csrwi %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTEREN_HPM3));
 
neorv32_cpu_csr_write(CSR_MHPMCOUNTER3, 0xffffffff);
neorv32_cpu_csr_write(CSR_MHPMCOUNTER3H, 0xffffffff);
 
uint32_t tmp, size, i;
 
if (neorv32_cpu_csr_read(CSR_MHPMCOUNTER3H) == 0) {
size = 0;
tmp = neorv32_cpu_csr_read(CSR_MHPMCOUNTER3);
}
else {
size = 32;
tmp = neorv32_cpu_csr_read(CSR_MHPMCOUNTER3H);
}
 
for (i=0; i<32; i++) {
if (tmp & (1<<i)) {
size++;
}
}
 
return size;
}
 
 
/**********************************************************************//**
* Check if certain Z* extension is available
*
* @param[in] flag Index of the Z-extension to check from #NEORV32_CSR_MZEXT_enum
/neorv32/trunk/sw/lib/source/neorv32_rte.c
282,7 → 282,6
 
// ID
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
 
neorv32_uart_printf("Vendor ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MVENDORID));
 
tmp = neorv32_cpu_csr_read(CSR_MARCHID);
353,6 → 352,12
if (tmp & (1<<CSR_MZEXT_ZFINX)) {
neorv32_uart_printf("Zfinx ");
}
if (tmp & (1<<CSR_MZEXT_ZXNOCNT)) {
neorv32_uart_printf("Zxnocnt(!) ");
}
if (tmp & (1<<CSR_MZEXT_ZXSCNT)) {
neorv32_uart_printf("Zxscnt(!) ");
}
 
// check physical memory protection
neorv32_uart_printf("\nPMP: ");
365,7 → 370,7
}
 
// check hardware performance monitors
neorv32_uart_printf("HPM Counters: %u\n", neorv32_cpu_hpm_get_counters());
neorv32_uart_printf("HPM Counters: %ux, %u-bit wide\n", neorv32_cpu_hpm_get_counters(), neorv32_cpu_hpm_get_size());
 
 
// Memory configuration
372,17 → 377,27
neorv32_uart_printf("\n=== << Memory Configuration >> ===\n");
 
neorv32_uart_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
 
// IMEM
neorv32_uart_printf("Internal IMEM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM));
neorv32_uart_printf("IMEM size: %u bytes\n", SYSINFO_IMEM_SIZE);
neorv32_uart_printf("Internal IMEM as ROM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)) {
neorv32_uart_printf("yes, %u bytes", SYSINFO_IMEM_SIZE);
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) {
neorv32_uart_printf(", read-only (ROM)");
}
}
else {
neorv32_uart_printf("no");
}
neorv32_uart_printf("\n");
 
// DMEM
neorv32_uart_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart_printf("Internal DMEM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
neorv32_uart_printf("DMEM size: %u bytes\n", SYSINFO_DMEM_SIZE);
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM)) { neorv32_uart_printf("yes, %u bytes\n", SYSINFO_DMEM_SIZE); }
else { neorv32_uart_printf("no\n"); }
 
// i-cache
neorv32_uart_printf("Internal i-cache: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE));
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)) {
/neorv32/trunk/CHANGELOG.md
6,7 → 6,7
A list of all releases can be found [here](https://github.com/stnolting/neorv32/releases). The most recent version of the *NEORV32 data sheet*
can be found [here](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
:information_source: To see a list of all commits between release run `git log RELEASE_A..RELEASE_B` (example: `v1.4.7.0..v1.4.8.0`).
:information_source: To see a list of all commits between releases run `git log RELEASE_A..RELEASE_B` (example: `v1.4.7.0..v1.4.8.0`).
 
:information_source: The processor can determine it's version from the `mimpid` CSR (at CSR address 0xf13). A 8x4-bit BCD representation is used.
Leading zeros are optional. Example: `CSR(mimpid) = 0x01040312 => 01.04.03.12 = Version 01.04.03.12 = v1.4.3.12`. The version number is globally
24,6 → 24,18
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 17.04.2021 | [**:rocket:1.5.4.0**](https://github.com/stnolting/neorv32/releases/tag/v1.5.4.0) | **New release** |
| 16.04.2021 | 1.5.3.13 | :warning: added new top configuration generic `TINY_SHIFT_EN` (type = `boolean`, default = `false`) to configure a tiny single-bit (iterative) shifter for CPU ALU shift operations (for highly area-constrained setups) |
| 16.04.2021 | 1.5.3.12 | :sparkles: reworked reset system of the complete CPU: by default most registers (= "uncritical registers") **do not** provide an initialization via hardware reset; a **defined reset value** can be enabled by setting a constant from the main VHDL package (`rtl/core/neorv32_package.vhd`): `constant dedicated_reset_c : boolean := false;` (set `true` to enable CPU-wide dedicated register reset); see new section "2.11. CPU Hardware Reset" of NEORV32.pdf for more information |
| 14.04.2021 | 1.5.3.11 | minor rtl edits to allow synthesis using [`ghdl-yosys-plugin`](https://github.com/ghdl/ghdl-yosys-plugin) (:construction: work in progress :construction:)
| 13.04.2021 | 1.5.3.10 | :bug: fixed bug when configuring `HPM_CNT_WIDTH` less than 32; :warning: added new generic `CPU_CNT_WIDTH` to configure total size of CPU's `cycle` and `instret` CSRs (default = 64-bit); added `Zxnocnt` (no counters) and `Zxscnt` (small counters) flags to `mzexr` CSR to check if `CPU_CNT_WIDTH` is zero or less than 64, respectively; :bug: fixed bug in `crt0.S` start-up code: stack pointer has to be initialized before an exception can occur; updated `cpu_test` example program |
| 11.04.2021 | 1.5.3.9 | :warning: reworked CPU reset system (in addition to modifications in v1.5.3.7): default reset: most register are "initialized" with '-' (don't care) since no real reset is required; however, a "real" reset can be configured using the packages 'def_rst_val_c' constant that defines the reset value for all "uncritical regsiter" (see new NEORV32.pdf section 2.11 "CPU Hardware Reset") |
| 09.04.2021 | 1.5.3.8 | optimized CPU control: register write back during multi-cycle ALU operation only when result is really available (reducing switching activity; avoids possible source operand corruption); optimized `M` extension's co-processor: multiplications and divisions are 2 cycles faster |
| 08.04.2021 | 1.5.3.7 | :bug: fixed bug in HPM event configuration via `mhpmevent*` CSRs - there was a CSR address decoding overlap between the HPM event CSRs and the machine trap setup CSRs (introduced in version 1.5.3.6); :warning: reworked CPU core CSRs: most CSRs are not reset by hardware and need explicit initialization (done by crt0.S start-up code) |
| 02.04.2021 | 1.5.3.6 | :bug: fixed bug in external memory interface (`neorv32_wishbone.vhd`) that caused bus exceptions when using external memories with very high access latencies (race condition in bus timeouts); VHDL code clean-up |
| 30.03.2021 | 1.5.3.5 | added new top's generic `HPM_CNT_WIDTH` (type `natural`, default=40) to configure the total bit width of the hardware performance monitors (HPM) counter (min 1, max 64); mofified `crt0.S`: stops all counters (incl. HPMs), no user-level access to ANY counter; `neorv32.h`: added missing `mcounteren` and `mcountinhibit` CSR bit definitions |
| 28.03.2021 | 1.5.3.4 | default "test setup" `rtl/top_templetes/neorv32_test_setup.vhd`: disabled PMP, implementing 4 HPM counters; :sparkles: added [`boards`](https://github.com/stnolting/neorv32/tree/master/boards) folder for exemplary FPGA setups |
| 27.03.2021 | 1.5.3.3 | minor optimization in CPU control engine; FPU comparator now uses comparatos results from main ALU (reduces FPU hardware footprint) |
| 26.03.2021 | 1.5.3.2 | :sparkles: **added single-precision floating-point unit (FPU)** `rtl/core/neorv32_cpu_cp_fpu.vhd` implementing the `Zfinx` CPU extension; added/updated `Zfinx` **intrinsic library** and verification framework: [`sw/example/floating_point_test`](https://github.com/stnolting/neorv32/tree/master/sw/example/floating_point_test); added co-processor timeout counter to CPU to auto-terminate co-processor operations (for debugging only; defaullt=deactivated) |
| 25.03.2021 | 1.5.3.1 | :bug: fixed bug in invalid floating-point instruction detection (caused CPU to stall if executing an invalid floating-point operation); intrinsic core library (mainly used for not-yet-supported CPU extensions like `B` and `Zfinx`): clean-up, added R3 instruction type |
| 24.03.2021 | [**:rocket:1.5.3.0**](https://github.com/stnolting/neorv32/releases/tag/v1.5.3.0) | **New release** |
/neorv32/trunk/README.md
24,7 → 24,7
![neorv32 Overview](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_processor.png)
 
The NEORV32 Processor is a customizable microcontroller-like system on chip (SoC) that is based
on the RISC-V NEORV32 CPU. The processor is intended as auxiliary processor within a larger SoC
on the RISC-V NEORV32 CPU. The processor is intended as auxiliary processor in larger SoC
designs or as *ready-to-go* stand-alone custom microcontroller.
 
:books: For detailed information take a look at the [NEORV32 data sheet (pdf)](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
33,6 → 33,8
:label: The project’s change log is available as [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md) in the root directory of this repository.
To see the changes between *stable* releases visit the project's [release page](https://github.com/stnolting/neorv32/releases).
 
:rocket: The [`boards`](https://github.com/stnolting/neorv32/tree/master/boards) folder provides exemplary setups targeting various FPGA boards to get you started.
 
:spiral_notepad: Check out the [project boards](https://github.com/stnolting/neorv32/projects) for a list of current **ideas**,
**TODOs**, features being **planned** and **work-in-progress**.
 
57,7 → 59,7
* [`X`](#X---NEORV32-specific-CPU-extensions) - NEORV32-specific extensions (always enabled)
* [`Zfinx`](#Zfinx---Single-precision-floating-point-extension) - Single-precision floating-point extensions (optional)
* [`Zicsr`](#Zicsr---Privileged-architecture---CSR-access-extension) - control and status register access instructions (+ exception/irq system) (optional)
* [`Zifencei`](#Zifencei---Privileged-architecture---Instruction-stream-synchronization-extension) - instruction stream synchronization (optional)
* [`Zifencei`](#Zifencei---Instruction-stream-synchronization-extension) - instruction stream synchronization (optional)
* [`PMP`](#PMP---Privileged-architecture---Physical-memory-protection) - physical memory protection (optional)
* [`HPM`](#HPM---Privileged-architecture---Hardware-performance-monitors) - hardware performance monitors (optional)
* Full-scale RISC-V microcontroller system / **SoC** [**NEORV32 Processor**](#NEORV32-Processor-Features) with optional submodules
140,7 → 142,9
* smart LED interface (**NEOLED**) - WS2812 / NeoPixel(c) compatible
* system configuration information memory to check hardware configuration by software (**SYSINFO**)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### NEORV32 CPU Features
 
The NEORV32 CPU implements the
163,12 → 167,16
* Privilege levels: `machine` mode, `user` mode (if enabled via `U` extension)
* Official [RISC-V open-source architecture ID](https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `A` - Atomic memory access extension
 
* Supported instructions: `LR.W` (load-reservate) `SC.W` (store-conditional)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `B` - Bit manipulation instructions extension
 
* :construction: **work-in-progress** :construction:
180,7 → 188,9
* `Zbs` single-bit instructions: `SBSET[I]` `SBCLR[I]` `SBINV[I]` `SBEXT[I]`
* `Zba` shifted-add instructions: `SH1ADD` `SH2ADD` `SH3ADD`
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `C` - Compressed instructions extension
 
* ALU instructions: `C.ADDI4SPN` `C.ADD[I]` `C.ADDI16SP` `C.LI` `C.LUI` `C.SLLI` `C.SRLI` `C.SRAI` `C.ANDI` `C.SUB` `C.XOR` `C.OR` `C.AND` `C.MV` `C.NOP`
189,11 → 199,16
* System instructions: `C.EBREAK` (requires `Zicsr` extension)
* Pseudo-instructions are not listed
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `E` - Embedded CPU version extension
 
* Reduced register file (only the 16 lowest registers are implemented)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `I` - Base integer instruction set
 
* ALU instructions: `LUI` `AUIPC` `ADD[I]` `SLT[I][U]` `XOR[I]` `OR[I]` `AND[I]` `SLL[I]` `SRL[I]` `SRA[I]` `SUB`
202,7 → 217,9
* System instructions: `ECALL` `EBREAK` `FENCE`
* Pseudo-instructions are not listed
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `M` - Integer multiplication and division hardware extension
 
* Multiplication instructions: `MUL` `MULH` `MULHSU` `MULHU`
210,13 → 227,17
* By default, the multiplier and divider cores use an iterative bit-serial processing scheme
* Multiplications can be mapped to DSPs via the `FAST_MUL_EN` generic to increase performance
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `U` - Privileged architecture - User mode extension
 
* Requires `Zicsr` extension
* Privilege levels: `M` (machine mode) + less-privileged `U` (user mode)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `X` - NEORV32-specific CPU extensions
 
* The NEORV32-specific extensions are always enabled and are indicated via the `X` bit set in the `misa` CSR.
224,7 → 245,9
* `mzext` CSR to check for implemented `Z*` CPU extensions (like `Zifencei`)
* All undefined/umimplemented/malformed/illegal instructions do raise an illegal instruction exception
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `Zfinx` - Single-precision floating-point extension
 
* :warning: this extension has not been officially ratified yet!
235,6 → 258,8
* Comparison instructions: `FMIN.S` `FMAX.S` `FEQ.S` `FLT.S` `FLE.S`
* Conversion instructions: `FCVT.W.S` `FCVT.WU.S` `FCVT.S.W` `FCVT.S.WU`
* Additional CSRs: `fcsr` `frm` `fflags`
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
#### `Zicsr` - Privileged architecture - CSR access extension
262,12 → 287,16
* RISC-V machine external interrupt `mei` (via external signal)
* 16 fast interrupt requests, 6+1 available for custom usage
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
#### `Zifencei` - Privileged architecture - Instruction stream synchronization extension
 
#### `Zifencei` - Instruction stream synchronization extension
 
* System instructions: `FENCE.I` (among others, used to clear and reload instruction cache)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `PMP` - Privileged architecture - Physical memory protection
 
* Requires `Zicsr` extension
274,7 → 303,9
* Configurable number of regions (0..63)
* Additional machine CSRs: `pmpcfg*`(0..15) `pmpaddr*`(0..63)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
#### `HPM` - Privileged architecture - Hardware performance monitors
 
* Requires `Zicsr` extension
281,17 → 312,20
* Configurable number of counters (0..29)
* Additional machine CSRs: `mhpmevent*`(3..31) `[m]hpmcounter*[h]`(3..31)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### :warning: Non-RISC-V-Compatible Issues and Limitations
 
* CPU and Processor are BIG-ENDIAN, but this should be no problem as the external memory bus interface provides big- and little-endian configurations
* `misa` CSR is read-only - no dynamic enabling/disabling of synthesized CPU extensions during runtime; for compatibility: write accesses (in m-mode) are ignored and do not cause an exception
* The physical memory protection (**PMP**) only supports `NAPOT` mode yet and a minimal granularity of 8 bytes
* The `A` extension only implements `lr.w` and `sc.w` instructions yet. However, these instructions are sufficient to emulate all further AMO operations
* The `mcause` trap code `0x80000000` (originally reserved in the RISC-V specs) is used to indicate a hardware reset (as "non-maskable interrupt")
* The `A` extension only implements `lr.w` and `sc.w` instructions yet. However, these instructions are sufficient to emulate all remaining AMO operations
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
 
## FPGA Implementation Results
 
### NEORV32 CPU
313,12 → 347,14
| `rv32imac` + `Zicsr` | 2685 | 1156 | 1024 | 0 | 124 MHz |
| `rv32imac` + `Zicsr` + `u` | 2698 | 1162 | 1024 | 0 | 124 MHz |
| `rv32imac` + `Zicsr` + `u` + `Zifencei` | 2715 | 1162 | 1024 | 0 | 122 MHz |
| `rv32imac` + `Zicsr` + `u` + `Zifencei` + `Zfinx` | 4004 | 1812 | 1024 | 0 | 121 MHz |
| `rv32imac` + `Zicsr` + `u` + `Zifencei` + `Zfinx` | 4004 | 1812 | 1024 | 7 | 121 MHz |
 
Setups with enabled "embedded CPU extension" `E` show the same LUT and FF utilization and identical f_max as the according `I` configuration.
However, the size of the register file is cut in half.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### NEORV32 Processor-Internal Peripherals and Memories
 
Results generated for hardware version [`1.5.3.2`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
344,14 → 380,16
| WDT | Watchdog timer | 60 | 45 | 0 | 0 |
| WISHBONE | External memory interface | 129 | 104 | 0 | 0 |
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### NEORV32 Processor - Exemplary FPGA Setups
 
Exemplary processor implementation results for different FPGA platforms. The processor setup uses *the default peripheral configuration* (like no _CFS_ and no _TRNG_),
no external memory interface and only internal instruction and data memories. IMEM uses 16kB and DMEM uses 8kB memory space. The setup's top entity connects most of the
processor's [top entity](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd) signals
to FPGA pins - except for the Wishbone bus and the interrupt signals. The "default" strategy of each toolchain is used.
:information_source: Check out the [`boards`](https://github.com/stnolting/neorv32/tree/master/boards) folder for exemplary setups targeting various FPGA boards.
 
The following tables show exemplary processor implementation results for different FPGA platforms. The processor setups use *the default peripheral configuration* (like no *CFS* and no *TRNG*),
no external memory interface and only internal instruction and data memories. IMEM uses 16kB and DMEM uses 8kB memory space.
 
Results generated for hardware version [`1.4.9.0`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| Vendor | FPGA | Board | Toolchain | CPU Configuration | LUT / LE | FF / REG | DSP (9-bit) | Memory Bits | BRAM / EBR | SPRAM | Frequency |
361,6 → 399,7
| Xilinx | Artix-7 `XC7A35TICSG324-1L` | Arty A7-35T | Vivado 2019.2 | `rv32imc` + `u` + `Zicsr` + `Zifencei` + `PMP` | 2465 (12%) | 1912 (5%) | 0 (0%) | - | 8 (16%) | - | *c* 100 MHz |
 
**_Notes_**
* The "default" implementation strategy of the according toolchain is used.
* The Lattice iCE40 UltraPlus setup uses the FPGA's SPRAM memory primitives for the internal IMEM and DMEM (each 64kb).
The FPGA-specific memory components can be found in [`rtl/fpga_specific`](https://github.com/stnolting/neorv32/blob/master/rtl/fpga_specific/lattice_ice40up).
* The clock frequencies marked with a "c" are constrained clocks. The remaining ones are _f_max_ results from the place and route timing reports.
369,8 → 408,10
* The setups with `PMP` implement 2 regions with a minimal granularity of 64kB.
* No HPM counters are implemented.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
 
## Performance
 
### CoreMark Benchmark
381,21 → 422,20
 
~~~
**Configuration**
Hardware: 32kB IMEM, 16kB DMEM, no caches, 100MHz clock
Hardware: 32kB IMEM, 8kB DMEM, no caches, 100MHz clock
CoreMark: 2000 iterations, MEM_METHOD is MEM_STACK
Compiler: RISCV32-GCC 10.1.0 (rv32i toolchain)
Compiler flags: default, see makefile
Optimization: -O3
Peripherals: UART for printing the results
~~~
 
Results generated for hardware version [`1.4.9.8`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU (including `Zicsr`) | Executable Size | Optimization | CoreMark Score | CoreMarks/MHz |
| CPU (including `Zicsr` extension) | Executable Size | Optimization | CoreMark Score | CoreMarks/MHz |
|:--------------------------------------------|:---------------:|:------------:|:--------------:|:-------------:|
| `rv32i` | 28 756 bytes | `-O3` | 36.36 | **0.3636** |
| `rv32im` | 27 516 bytes | `-O3` | 68.97 | **0.6897** |
| `rv32imc` | 22 008 bytes | `-O3` | 68.97 | **0.6897** |
| `rv32imc` + `FAST_MUL_EN` | 22 008 bytes | `-O3` | 86.96 | **0.8696** |
| `rv32imc` + `FAST_MUL_EN` + `FAST_SHIFT_EN` | 22 008 bytes | `-O3` | 90.91 | **0.9091** |
 
The `FAST_MUL_EN` configuration uses DSPs for the multiplier of the `M` extension (enabled via the `FAST_MUL_EN` generic). The `FAST_SHIFT_EN` configuration
403,7 → 443,9
 
When the `C` extension is enabled, branches to an unaligned uncompressed instruction require additional instruction fetch cycles.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### Instruction Cycles
 
The NEORV32 CPU is based on a two-stages pipelined architecutre. Each stage uses a multi-cycle processing scheme. Hence,
419,12 → 461,10
 
Results generated for hardware version [`1.4.9.8`](https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md).
 
| CPU (including `Zicsr`) | Required Clock Cycles | Executed Instructions | Average CPI |
| CPU (including `Zicsr` extension) | Required Clock Cycles | Executed Instructions | Average CPI |
|:--------------------------------------------|----------------------:|----------------------:|:-----------:|
| `rv32i` | 5 595 750 503 | 1 466 028 607 | **3.82** |
| `rv32im` | 2 966 086 503 | 598 651 143 | **4.95** |
| `rv32imc` | 2 981 786 734 | 611 814 918 | **4.87** |
| `rv32imc` + `FAST_MUL_EN` | 2 399 234 734 | 611 814 918 | **3.92** |
| `rv32imc` + `FAST_MUL_EN` + `FAST_SHIFT_EN` | 2 265 135 174 | 611 814 948 | **3.70** |
 
The `FAST_MUL_EN` configuration uses DSPs for the multiplier of the `M` extension (enabled via the `FAST_MUL_EN` generic). The `FAST_SHIFT_EN` configuration
432,8 → 472,10
 
When the `C` extension is enabled branches to an unaligned uncompressed instruction require additional instruction fetch cycles.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
 
## Top Entities
 
The top entity of the **NEORV32 Processor** (SoC) is [`rtl/core/neorv32_top.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd),
454,7 → 496,9
**Alternative top entities**, like the simplified ["hello world" test setup](#Create-a-new-Hardware-Project) or CPU/Processor
wrappers with resolved port signal types (i.e. *std_logic*), can be found in [`rtl/top_templates`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
### AXI4 Connectivity
 
Via the [`rtl/top_templates/neorv32_top_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_top_axi4lite.vhd)
474,8 → 518,10
the attached block RAMs are used for storing instructions and data: the first RAM is used as instruction memory
and is mapped to address `0x00000000 - 0x00003fff` (16kB), the second RAM is used as data memory and is mapped to address `0x80000000 - 0x80001fff` (8kB).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
 
## Getting Started
 
This overview is just a short excerpt from the *Let's Get It Started* section of the NEORV32 documentary:
520,6 → 566,9
 
### 3. Create a new FPGA Project
 
:information_source: If want to use a script-based exemplary project setup check out the [`boards`](https://github.com/stnolting/neorv32/tree/master/boards) folder,
which provides exemplary setups targeting various FPGA boards.
 
Create a new project with your FPGA design tool of choice. Add all the `*.vhd` files from the [`rtl/core`](https://github.com/stnolting/neorv32/blob/master/rtl)
folder to this project. Make sure to add these files to a **new design library** called `neorv32`.
 
609,6 → 658,7
 
Going further: Take a look at the _Let's Get It Started!_ chapter of the [:page_facing_up: NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
## Contribute/Feedback/Questions
628,7 → 678,9
6. Push to the branch: `git push origin awesome_new_feature_branch`
7. Create a new [pull request](https://github.com/stnolting/neorv32/pulls)
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
## Legal
 
This project is released under the BSD 3-Clause license. No copyright infringement intended.
690,8 → 742,10
 
"NeoPixel" is a trademark of Adafruit Industries.
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
 
 
## Acknowledgements
 
[![RISC-V](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/riscv_logo.png)](https://riscv.org/)
704,6 → 758,8
 
This project is not affiliated with or endorsed by the Open Source Initiative (https://www.oshwa.org / https://opensource.org).
 
[[back to top](#The-NEORV32-RISC-V-Processor)]
 
--------
 
Made with :coffee: in Hannover, Germany :eu:

powered by: WebSVN 2.1.0

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