Minor rtl edits and cleanups (#1144)

This commit is contained in:
stnolting 2025-01-07 22:50:29 +01:00 committed by GitHub
commit 0deb073391
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 604 additions and 427 deletions

View file

@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 07.01.2025 | 1.10.8.9 | rtl edits and cleanups; add dedicated "core complex" wrapper (CPU + L1 caches + bus switch) | [#1144](https://github.com/stnolting/neorv32/pull/1144) |
| 04.01.2025 | 1.10.8.8 | :sparkles: add inter-core communication (ICC) for the SMP dual-core setup | [#1142](https://github.com/stnolting/neorv32/pull/1142) |
| 03.01.2025 | 1.10.8.7 | :warning: :sparkles: replace `Zalrsc` ISA extensions (reservation-set operations) by `Zaamo` ISA extension (atomic read-modify-write operations) | [#1141](https://github.com/stnolting/neorv32/pull/1141) |
| 01.01.2025 | 1.10.8.6 | :sparkles: :test_tube: add smp dual-core option | [#1135](https://github.com/stnolting/neorv32/pull/1135) |

View file

@ -130,36 +130,36 @@ The root directory of the repository is considered the NEORV32 base or home fold
.Folder Structure
...................................
neorv32 - Project home folder
neorv32 - Project home folder
├docs - Project documentation
datasheet - AsciiDoc sources for the NEORV32 data sheet
figures - Figures and logos
references - Data sheets and RISC-V specs
sources - Sources for the images in 'figures/'
userguide - AsciiDoc sources for the NEORV32 user guide
-docs - Project documentation
├-datasheet - AsciiDoc sources for the NEORV32 data sheet
├-figures - Figures and logos
├-references - Data sheets and RISC-V specs
├-sources - Sources for the images in 'figures/'
└-userguide - AsciiDoc sources for the NEORV32 user guide
├rtl - VHDL sources
core - Core sources of the CPU & SoC
processor_templates - Pre-configured SoC wrappers
system_integration - System wrappers and bridges for advanced connectivity
test_setups - Minimal test setup "SoCs" used in the User Guide
-rtl - VHDL sources
├-core - Core sources of the CPU & SoC
├-processor_templates - Pre-configured SoC wrappers
├-system_integration - System wrappers and bridges for advanced connectivity
└-test_setups - Minimal test setup "SoCs" used in the User Guide
├sim - Simulation files
-sim - Simulation files
└-sw - Software framework
├bootloader - Sources of the processor-internal bootloader
├common - Linker script, crt0.S start-up code and central makefile
├example - Example programs for the core and the SoC modules
eclipse - Pre-configured Eclipse IDE project
... - Several example programs
├lib - Processor core library
include - NEORV32 core library header files (*.h)
source - NEORV32 core library source files (*.c)
├image_gen - Helper program to generate executables & memory images
├ocd_firmware - Firmware for the on-chip debugger's "park loop"
├openocd - OpenOCD configuration files
└svd - Processor system view description file (CMSIS-SVD)
└-sw - Software framework
-bootloader - Sources of the processor-internal bootloader
-common - Linker script, crt0.S start-up code and central makefile
-example - Example programs for the core and the SoC modules
├-eclipse - Pre-configured Eclipse IDE project
└-... - Several example programs
-lib - Processor core library
├-include - NEORV32 core library header files (*.h)
└-source - NEORV32 core library source files (*.c)
-image_gen - Helper program to generate executables & memory images
-ocd_firmware - Firmware for the on-chip debugger's "park loop"
-openocd - OpenOCD configuration files
-svd - Processor system view description file (CMSIS-SVD)
...................................
@ -179,60 +179,61 @@ All core VHDL files from the list below have to be assigned to a **new library**
[NOTE]
See section <<_file_list_files>> for more information.
.RTL File List and Hierarchy (in alphabetical order)
.RTL File List (in alphabetical order)
...................................
neorv32_top.vhd - NEORV32 PROCESSOR/SOC TOP ENTITY
├neorv32_cpu.vhd - NEORV32 CPU TOP ENTITY
│├neorv32_cpu_alu.vhd - Arithmetic/logic unit
││├neorv32_cpu_cp_bitmanip.vhd - Bit-manipulation co-processor (B ext.)
││├neorv32_cpu_cp_cfu.vhd - Custom instructions co-processor (Zxcfu ext.)
││├neorv32_cpu_cp_cond.vhd - Integer conditional co-processor (Zicond ext.)
││├neorv32_cpu_cp_crypto.vhd - Scalar cryptographic co-processor (Zk*/Zbk* ext.)
││├neorv32_cpu_cp_fpu.vhd - Floating-point co-processor (Zfinx ext.)
││├neorv32_cpu_cp_muldiv.vhd - Mul/Div co-processor (M ext.)
││└neorv32_cpu_cp_shifter.vhd - Bit-shift co-processor (base ISA)
│├neorv32_cpu_control.vhd - CPU control, exception system and CSRs
││└neorv32_cpu_decompressor.vhd - Compressed instructions decoder (C ext.)
│├neorv32_cpu_icc.vhd - Inter-core communication unit
│├neorv32_cpu_lsu.vhd - Load/store unit
│├neorv32_cpu_pmp.vhd - Physical memory protection unit (Smpmp ext.)
│└neorv32_cpu_regfile.vhd - Data register file
├neorv32_boot_rom.vhd - Bootloader ROM
│└neorv32_bootloader_image.vhd - Bootloader ROM memory image (package)
├neorv32_bus.vhd - SoC bus infrastructure modules
├neorv32_cache.vhd - Generic cache module
├neorv32_cfs.vhd - Custom functions subsystem
├neorv32_clint.vhd - Core local interruptor
├neorv32_clockgate.vhd - Generic clock gating switch
├neorv32_crc.vhd - Cyclic redundancy check unit
├neorv32_debug_dm.vhd - on-chip debugger: debug module
├neorv32_debug_auth.vhd - on-chip debugger: authentication module
├neorv32_debug_dtm.vhd - on-chip debugger: debug transfer module
├neorv32_dma.vhd - Direct memory access controller
├neorv32_dmem.vhd - Generic processor-internal data memory
├neorv32_fifo.vhd - Generic FIFO component
├neorv32_gpio.vhd - General purpose input/output port unit
├neorv32_gptmr.vhd - General purpose 32-bit timer
├neorv32_imem.vhd - Generic processor-internal instruction memory
│└neorv32_application_image.vhd - IMEM application initialization image (package)
├neorv32_neoled.vhd - NeoPixel (TM) compatible smart LED interface
├neorv32_onewire.vhd - One-Wire serial interface controller
├neorv32_package.vhd - Main VHDL package file
├neorv32_pwm.vhd - Pulse-width modulation controller
├neorv32_sdi.vhd - Serial data interface controller (SPI device)
├neorv32_slink.vhd - Stream link interface
├neorv32_spi.vhd - Serial peripheral interface controller (SPI host)
├neorv32_sys.vhd - System infrastructure modules
├neorv32_sysinfo.vhd - System configuration information memory
├neorv32_trng.vhd - True random number generator
├neorv32_twi.vhd - Two wire serial interface controller
├neorv32_uart.vhd - Universal async. receiver/transmitter
├neorv32_wdt.vhd - Watchdog timer
├neorv32_xbus.vhd - External (Wishbone) bus interface gateways
├neorv32_xip.vhd - Execute in place module
└neorv32_xirq.vhd - External interrupt controller
rtl/core
├-neorv32_application_image.vhd - IMEM application initialization image (package)
├-neorv32_boot_rom.vhd - Bootloader ROM
├-neorv32_bootloader_image.vhd - Bootloader ROM memory image (package)
├-neorv32_bus.vhd - SoC bus infrastructure modules
├-neorv32_cache.vhd - Generic cache module
├-neorv32_clint.vhd - Core local interruptor
├-neorv32_clockgate.vhd - Generic clock gating switch
├-neorv32_cfs.vhd - Custom functions subsystem
├-neorv32_core_complex.vhd - NEORV32 CORE COMPLEX TOP ENTITY
├-neorv32_cpu.vhd - NEORV32 CPU TOP ENTITY
├-neorv32_cpu_alu.vhd - Arithmetic/logic unit
├-neorv32_cpu_control.vhd - CPU control, exception system and CSRs
├-neorv32_cpu_cp_bitmanip.vhd - Bit-manipulation co-processor (B ext.)
├-neorv32_cpu_cp_cfu.vhd - Custom instructions co-processor (Zxcfu ext.)
├-neorv32_cpu_cp_cond.vhd - Integer conditional co-processor (Zicond ext.)
├-neorv32_cpu_cp_crypto.vhd - Scalar cryptography co-processor (Zk*/Zbk* ext.)
├-neorv32_cpu_cp_fpu.vhd - Floating-point co-processor (Zfinx ext.)
├-neorv32_cpu_cp_muldiv.vhd - Mul/Div co-processor (M ext.)
├-neorv32_cpu_cp_shifter.vhd - Bit-shift co-processor (base ISA)
├-neorv32_cpu_decompressor.vhd - Compressed instructions decoder (C ext.)
├-neorv32_cpu_icc.vhd - Inter-core communication unit
├-neorv32_cpu_lsu.vhd - Load/store unit
├-neorv32_cpu_pmp.vhd - Physical memory protection unit (Smpmp ext.)
├-neorv32_cpu_regfile.vhd - Data register file
├-neorv32_crc.vhd - Cyclic redundancy check unit
├-neorv32_debug_auth.vhd - On-chip debugger: authentication module
├-neorv32_debug_dm.vhd - On-chip debugger: debug module
├-neorv32_debug_dtm.vhd - On-chip debugger: debug transfer module
├-neorv32_dma.vhd - Direct memory access controller
├-neorv32_dmem.vhd - Generic processor-internal data memory
├-neorv32_fifo.vhd - Generic FIFO component
├-neorv32_gpio.vhd - General purpose input/output port unit
├-neorv32_gptmr.vhd - General purpose 32-bit timer
├-neorv32_imem.vhd - Generic processor-internal instruction memory
├-neorv32_neoled.vhd - NeoPixel (TM) compatible smart LED interface
├-neorv32_onewire.vhd - One-Wire serial interface controller
├-neorv32_package.vhd - Main VHDL package file
├-neorv32_pwm.vhd - Pulse-width modulation controller
├-neorv32_sdi.vhd - Serial data interface controller (SPI device)
├-neorv32_slink.vhd - Stream link interface
├-neorv32_spi.vhd - Serial peripheral interface controller (SPI host)
├-neorv32_sys.vhd - System infrastructure modules
├-neorv32_sysinfo.vhd - System configuration information memory
├-neorv32_top.vhd - NEORV32 PROCESSOR/SOC TOP ENTITY
├-neorv32_trng.vhd - True random number generator
├-neorv32_twd.vhd - Two wire serial device controller
├-neorv32_twi.vhd - Two wire serial interface controller
├-neorv32_uart.vhd - Universal async. receiver/transmitter
├-neorv32_wdt.vhd - Watchdog timer
├-neorv32_xbus.vhd - External (Wishbone) bus interface gateways
├-neorv32_xip.vhd - Execute in place module
└-neorv32_xirq.vhd - External interrupt controller
...................................
.Replacing Modules for Customization or Optimization

View file

@ -1,7 +1,7 @@
-- The NEORV32 RISC-V Processor - github.com/stnolting/neorv32
-- Auto-generated memory initialization image (for internal IMEM)
-- Source: demo_blink_led/build/main.bin
-- Built: 04.01.2025 22:17:35
-- Built: 07.01.2025 21:36:11
library ieee;
use ieee.std_logic_1164.all;
@ -11,7 +11,7 @@ use neorv32.neorv32_package.all;
package neorv32_application_image is
constant application_init_size_c : natural := 1248; -- bytes
constant application_init_size_c : natural := 1228; -- bytes
constant application_init_image_c : mem32_t := (
x"f14020f3",
x"80002217",
@ -23,11 +23,11 @@ x"000022b7",
x"80028293",
x"30029073",
x"00000317",
x"1a430313",
x"19430313",
x"30531073",
x"30401073",
x"00000397",
x"4ac38393",
x"49838393",
x"80000417",
x"fc440413",
x"80000497",
@ -37,7 +37,7 @@ x"fb450513",
x"80000597",
x"fac58593",
x"00000617",
x"1ac60613",
x"19c60613",
x"00000693",
x"00000713",
x"00000793",
@ -57,31 +57,27 @@ x"00000e13",
x"00000e93",
x"00000f13",
x"00000f93",
x"06008263",
x"04008a63",
x"00000797",
x"01878793",
x"30579073",
x"30446073",
x"30046073",
x"0f80006f",
x"0e80006f",
x"fff40737",
x"00209793",
x"00f70733",
x"00072023",
x"34202773",
x"800007b7",
x"00378793",
x"02f71463",
x"bc201073",
x"bc0026f3",
x"ffab4737",
x"32170713",
x"00d71a63",
x"00d70463",
x"30200073",
x"bc171073",
x"bc002173",
x"bc002673",
x"0580006f",
x"30200073",
x"0540006f",
x"00838e63",
x"00945c63",
x"0003a783",
@ -94,9 +90,9 @@ x"00052023",
x"00450513",
x"ff5ff06f",
x"00000417",
x"3a040413",
x"39c40413",
x"00000497",
x"39848493",
x"39448493",
x"00945a63",
x"00042083",
x"000080e7",
@ -116,9 +112,9 @@ x"30551073",
x"f1402473",
x"02041463",
x"00000417",
x"34840413",
x"34440413",
x"00000497",
x"34048493",
x"33c48493",
x"00945a63",
x"00042083",
x"000080e7",
@ -148,12 +144,12 @@ x"00000513",
x"00000593",
x"00112623",
x"00812423",
x"138000ef",
x"140000ef",
x"00000513",
x"00150413",
x"00000593",
x"0ff57513",
x"124000ef",
x"12c000ef",
x"0fa00513",
x"038000ef",
x"00040513",
@ -170,49 +166,51 @@ x"c80025f3",
x"fef59ae3",
x"00008067",
x"fe010113",
x"01212823",
x"fffe0937",
x"00a12623",
x"00092503",
x"3e800593",
x"00112e23",
x"00812c23",
x"00912a23",
x"00a12623",
x"0e0000ef",
x"3e800593",
x"1a8000ef",
x"19c000ef",
x"00c12603",
x"00000693",
x"00000593",
x"0f8000ef",
x"0ec000ef",
x"00050413",
x"00058493",
x"fc0027f3",
x"0807f793",
x"04078463",
x"04078663",
x"320027f3",
x"0017f793",
x"02079e63",
x"f9dff0ef",
x"04079063",
x"f95ff0ef",
x"00850433",
x"00a43533",
x"009585b3",
x"00b504b3",
x"f89ff0ef",
x"f81ff0ef",
x"fe95eee3",
x"00b49463",
x"fe856ae3",
x"01c12083",
x"01812403",
x"01412483",
x"01012903",
x"02010113",
x"00008067",
x"fffe07b7",
x"0087a783",
x"00892783",
x"00f79713",
x"02075663",
x"f3dff0ef",
x"f35ff0ef",
x"00850433",
x"00a43533",
x"009585b3",
x"00b504b3",
x"f29ff0ef",
x"f21ff0ef",
x"fe95eee3",
x"fcb490e3",
x"fe856ae3",
@ -230,9 +228,6 @@ x"fffc07b7",
x"00a7a423",
x"00b7a623",
x"00008067",
x"fffe07b7",
x"0007a503",
x"00008067",
x"00050613",
x"00000513",
x"0015f693",

View file

@ -1,7 +1,7 @@
-- The NEORV32 RISC-V Processor - github.com/stnolting/neorv32
-- Auto-generated memory initialization image (for internal BOOTROM)
-- Source: bootloader/build/main.bin
-- Built: 04.01.2025 22:18:00
-- Built: 07.01.2025 21:35:42
library ieee;
use ieee.std_logic_1164.all;
@ -11,7 +11,7 @@ use neorv32.neorv32_package.all;
package neorv32_bootloader_image is
constant bootloader_init_size_c : natural := 4060; -- bytes
constant bootloader_init_size_c : natural := 4044; -- bytes
constant bootloader_init_image_c : mem32_t := (
x"f14020f3",
x"80200217",
@ -23,11 +23,11 @@ x"000022b7",
x"80028293",
x"30029073",
x"00000317",
x"11430313",
x"10430313",
x"30531073",
x"30401073",
x"00001397",
x"fa838393",
x"f9838393",
x"80200417",
x"fc440413",
x"80200497",
@ -37,35 +37,31 @@ x"fb450513",
x"80200597",
x"fb458593",
x"00000617",
x"11c60613",
x"10c60613",
x"00000693",
x"00000713",
x"00000793",
x"06008263",
x"04008a63",
x"00000797",
x"01878793",
x"30579073",
x"30446073",
x"30046073",
x"0a80006f",
x"0980006f",
x"fff40737",
x"00209793",
x"00f70733",
x"00072023",
x"34202773",
x"800007b7",
x"00378793",
x"02f71463",
x"bc201073",
x"bc0026f3",
x"ffab4737",
x"32170713",
x"00d71a63",
x"00d70463",
x"30200073",
x"bc171073",
x"bc002173",
x"bc002673",
x"0340006f",
x"30200073",
x"0300006f",
x"00838e63",
x"00945c63",
x"0003a783",
@ -116,7 +112,7 @@ x"ffe017b7",
x"00112823",
x"00812623",
x"00912423",
x"a5078793",
x"a4078793",
x"30579073",
x"fffe07b7",
x"0087a783",
@ -200,54 +196,54 @@ x"30479073",
x"00800793",
x"3007a073",
x"ffe01537",
x"dcc50513",
x"dbc50513",
x"6b4000ef",
x"f1302573",
x"648000ef",
x"ffe01537",
x"e0450513",
x"df450513",
x"6a0000ef",
x"fffe0437",
x"00042503",
x"630000ef",
x"ffe01537",
x"e0c50513",
x"dfc50513",
x"688000ef",
x"30102573",
x"61c000ef",
x"ffe01537",
x"e1450513",
x"e0450513",
x"674000ef",
x"fc002573",
x"608000ef",
x"ffe01537",
x"e1c50513",
x"e0c50513",
x"660000ef",
x"00842503",
x"00100493",
x"5f0000ef",
x"ffe01537",
x"e2450513",
x"e1450513",
x"648000ef",
x"00444503",
x"00a49533",
x"ffc57513",
x"5d4000ef",
x"ffe01537",
x"e2c50513",
x"e1c50513",
x"62c000ef",
x"00544783",
x"00f49533",
x"ffc57513",
x"5b8000ef",
x"ffe014b7",
x"dc848513",
x"db848513",
x"610000ef",
x"00842783",
x"00f79713",
x"06075063",
x"ffe01537",
x"e3450513",
x"e2450513",
x"5f8000ef",
x"2e0000ef",
x"00042703",
@ -267,13 +263,13 @@ x"00f69613",
x"0a065463",
x"ffe01537",
x"00472783",
x"e6050513",
x"e5050513",
x"5a8000ef",
x"ffe017b7",
x"e6c78513",
x"e5c78513",
x"59c000ef",
x"ffe01537",
x"eec50513",
x"edc50513",
x"590000ef",
x"fff507b7",
x"0007a703",
@ -283,14 +279,14 @@ x"0047a403",
x"0ff47413",
x"00040513",
x"4f4000ef",
x"dc848513",
x"db848513",
x"568000ef",
x"f9b40413",
x"0ff47413",
x"01300793",
x"2287e863",
x"ffe017b7",
x"f6878793",
x"f5878793",
x"00241413",
x"00f40433",
x"00042783",
@ -314,7 +310,7 @@ x"00b41463",
x"f2f564e3",
x"00100513",
x"6f8000ef",
x"dc848513",
x"db848513",
x"4ec000ef",
x"00000513",
x"031000ef",
@ -327,20 +323,20 @@ x"800007b7",
x"0047a403",
x"00041863",
x"ffe01537",
x"ef450513",
x"ee450513",
x"f1dff06f",
x"ffe01537",
x"f1050513",
x"f0050513",
x"4ac000ef",
x"00040513",
x"440000ef",
x"ffe01537",
x"f1850513",
x"f0850513",
x"498000ef",
x"00400537",
x"42c000ef",
x"ffe01537",
x"f3050513",
x"f2050513",
x"484000ef",
x"fff507b7",
x"0007a703",
@ -358,7 +354,7 @@ x"00050663",
x"00300513",
x"498000ef",
x"ffe01537",
x"f3c50513",
x"f2c50513",
x"43c000ef",
x"01045793",
x"00178793",
@ -396,7 +392,7 @@ x"00850513",
x"40e005b3",
x"2a8000ef",
x"ffe01537",
x"db050513",
x"da050513",
x"e09ff06f",
x"00f12223",
x"1ec000ef",
@ -422,14 +418,14 @@ x"800007b7",
x"0047a783",
x"e60790e3",
x"ffe01537",
x"f4c50513",
x"f3c50513",
x"da1ff06f",
x"fffe07b7",
x"0087a783",
x"2007f793",
x"00079863",
x"ffe01537",
x"f5c50513",
x"f4c50513",
x"d85ff06f",
x"00100513",
x"e35ff06f",
@ -618,7 +614,7 @@ x"01c00493",
x"00945733",
x"ffe017b7",
x"00f77713",
x"fb878793",
x"fa878793",
x"00e787b3",
x"0007c503",
x"ffc48493",
@ -654,13 +650,13 @@ x"ff810113",
x"00812023",
x"00050413",
x"ffe01537",
x"d5850513",
x"d4850513",
x"00112223",
x"f99ff0ef",
x"00241793",
x"ffe01537",
x"008787b3",
x"fc850513",
x"fb850513",
x"00f50533",
x"f81ff0ef",
x"00800793",
@ -741,7 +737,7 @@ x"0087a783",
x"00e79713",
x"04075263",
x"ffe01537",
x"d6050513",
x"d5050513",
x"e41ff0ef",
x"00048513",
x"dd5ff0ef",
@ -754,7 +750,7 @@ x"da5ff0ef",
x"34302573",
x"db5ff0ef",
x"ffe01537",
x"dc850513",
x"db850513",
x"e0dff0ef",
x"00440413",
x"34141073",
@ -769,7 +765,7 @@ x"00a12023",
x"00f4a023",
x"02051863",
x"ffe01537",
x"d6c50513",
x"d5c50513",
x"dd1ff0ef",
x"00012503",
x"004005b7",
@ -780,12 +776,12 @@ x"04f50863",
x"00000513",
x"0380006f",
x"ffe01537",
x"d8c50513",
x"d7c50513",
x"da5ff0ef",
x"00400537",
x"d39ff0ef",
x"ffe01537",
x"da850513",
x"d9850513",
x"d91ff0ef",
x"fffe07b7",
x"0087a783",
@ -817,7 +813,7 @@ x"00d787b3",
x"00200513",
x"fa0792e3",
x"ffe01537",
x"db050513",
x"da050513",
x"d11ff0ef",
x"800007b7",
x"0087a223",
@ -851,12 +847,12 @@ x"40a00533",
x"e0400437",
x"00a47433",
x"ffe01537",
x"db450513",
x"da450513",
x"c89ff0ef",
x"00040513",
x"c1dff0ef",
x"ffe01537",
x"dc450513",
x"db450513",
x"c75ff0ef",
x"975ff0ef",
x"00050863",
@ -906,7 +902,7 @@ x"0a3e3e20",
x"444c420a",
x"4a203a56",
x"20206e61",
x"30322034",
x"30322037",
x"480a3532",
x"203a5657",
x"00000020",
@ -999,26 +995,26 @@ x"00002e65",
x"61766e49",
x"2064696c",
x"00444d43",
x"ffe00654",
x"ffe0067c",
x"ffe0067c",
x"ffe00400",
x"ffe0067c",
x"ffe0067c",
x"ffe0067c",
x"ffe0064c",
x"ffe0067c",
x"ffe0067c",
x"ffe0067c",
x"ffe0067c",
x"ffe0067c",
x"ffe004c4",
x"ffe004d8",
x"ffe0067c",
x"ffe004cc",
x"ffe0067c",
x"ffe0067c",
x"ffe00644",
x"ffe0066c",
x"ffe0066c",
x"ffe003f0",
x"ffe0066c",
x"ffe0066c",
x"ffe0066c",
x"ffe0063c",
x"ffe0066c",
x"ffe0066c",
x"ffe0066c",
x"ffe0066c",
x"ffe0066c",
x"ffe004b4",
x"ffe004c8",
x"ffe0066c",
x"ffe004bc",
x"ffe0066c",
x"ffe0066c",
x"ffe0065c",
x"33323130",
x"37363534",
x"62613938",

View file

@ -0,0 +1,257 @@
-- ================================================================================ --
-- NEORV32 SoC - Core Complex Top --
-- -------------------------------------------------------------------------------- --
-- CPU core + optional L1 I-cache + optional L1 D-cache + bus switch --
-- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
-- Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. --
-- Licensed under the BSD-3-Clause license, see LICENSE for details. --
-- SPDX-License-Identifier: BSD-3-Clause --
-- ================================================================================ --
library ieee;
use ieee.std_logic_1164.all;
library neorv32;
use neorv32.neorv32_package.all;
entity neorv32_core_complex is
generic (
-- General --
HART_ID : natural range 0 to 3;
NUM_HARTS : natural range 1 to 4;
VENDOR_ID : std_ulogic_vector(31 downto 0);
BOOT_ADDR : std_ulogic_vector(31 downto 0);
DEBUG_PARK_ADDR : std_ulogic_vector(31 downto 0);
DEBUG_EXC_ADDR : std_ulogic_vector(31 downto 0);
-- RISC-V ISA Extensions --
RISCV_ISA_C : boolean;
RISCV_ISA_E : boolean;
RISCV_ISA_M : boolean;
RISCV_ISA_U : boolean;
RISCV_ISA_Zaamo : boolean;
RISCV_ISA_Zba : boolean;
RISCV_ISA_Zbb : boolean;
RISCV_ISA_Zbkb : boolean;
RISCV_ISA_Zbkc : boolean;
RISCV_ISA_Zbkx : boolean;
RISCV_ISA_Zbs : boolean;
RISCV_ISA_Zfinx : boolean;
RISCV_ISA_Zicntr : boolean;
RISCV_ISA_Zicond : boolean;
RISCV_ISA_Zihpm : boolean;
RISCV_ISA_Zknd : boolean;
RISCV_ISA_Zkne : boolean;
RISCV_ISA_Zknh : boolean;
RISCV_ISA_Zksed : boolean;
RISCV_ISA_Zksh : boolean;
RISCV_ISA_Zmmul : boolean;
RISCV_ISA_Zxcfu : boolean;
RISCV_ISA_Sdext : boolean;
RISCV_ISA_Sdtrig : boolean;
RISCV_ISA_Smpmp : boolean;
-- Tuning Options --
CPU_CLOCK_GATING_EN : boolean;
CPU_FAST_MUL_EN : boolean;
CPU_FAST_SHIFT_EN : boolean;
CPU_RF_HW_RST_EN : boolean;
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural range 0 to 16;
PMP_MIN_GRANULARITY : natural;
PMP_TOR_MODE_EN : boolean;
PMP_NAP_MODE_EN : boolean;
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural range 0 to 13;
HPM_CNT_WIDTH : natural range 0 to 64;
-- Instruction Cache (iCACHE) --
ICACHE_EN : boolean;
ICACHE_NUM_BLOCKS : natural range 1 to 256;
ICACHE_BLOCK_SIZE : natural range 4 to 2**16;
ICACHE_UC_BEGIN : std_ulogic_vector(31 downto 0);
-- Data Cache (dCACHE) --
DCACHE_EN : boolean;
DCACHE_NUM_BLOCKS : natural range 1 to 256;
DCACHE_BLOCK_SIZE : natural range 4 to 2**16;
DCACHE_UC_BEGIN : std_ulogic_vector(31 downto 0)
);
port (
-- global control --
clk_i : in std_ulogic;
rstn_i : in std_ulogic;
-- interrupts --
msi_i : in std_ulogic;
mei_i : in std_ulogic;
mti_i : in std_ulogic;
firq_i : in std_ulogic_vector(15 downto 0);
dbi_i : in std_ulogic;
-- inter-core communication links --
icc_tx_o : out icc_t; -- TX links
icc_rx_i : in icc_t; -- RX links
-- system bus interface --
bus_req_o : out bus_req_t;
bus_rsp_i : in bus_rsp_t
);
end neorv32_core_complex;
architecture neorv32_core_complex_rtl of neorv32_core_complex is
-- bus system --
signal cpu_i_req, cpu_d_req, icache_req, dcache_req : bus_req_t;
signal cpu_i_rsp, cpu_d_rsp, icache_rsp, dcache_rsp : bus_rsp_t;
begin
-- CPU Core -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_inst: entity neorv32.neorv32_cpu
generic map (
-- General --
HART_ID => HART_ID,
NUM_HARTS => NUM_HARTS,
VENDOR_ID => VENDOR_ID,
BOOT_ADDR => BOOT_ADDR,
DEBUG_PARK_ADDR => DEBUG_PARK_ADDR,
DEBUG_EXC_ADDR => DEBUG_EXC_ADDR,
-- RISC-V ISA Extensions --
RISCV_ISA_C => RISCV_ISA_C,
RISCV_ISA_E => RISCV_ISA_E,
RISCV_ISA_M => RISCV_ISA_M,
RISCV_ISA_U => RISCV_ISA_U,
RISCV_ISA_Zaamo => RISCV_ISA_Zaamo,
RISCV_ISA_Zba => RISCV_ISA_Zba,
RISCV_ISA_Zbb => RISCV_ISA_Zbb,
RISCV_ISA_Zbkb => RISCV_ISA_Zbkb,
RISCV_ISA_Zbkc => RISCV_ISA_Zbkc,
RISCV_ISA_Zbkx => RISCV_ISA_Zbkx,
RISCV_ISA_Zbs => RISCV_ISA_Zbs,
RISCV_ISA_Zfinx => RISCV_ISA_Zfinx,
RISCV_ISA_Zicntr => RISCV_ISA_Zicntr,
RISCV_ISA_Zicond => RISCV_ISA_Zicond,
RISCV_ISA_Zihpm => RISCV_ISA_Zihpm,
RISCV_ISA_Zknd => RISCV_ISA_Zknd,
RISCV_ISA_Zkne => RISCV_ISA_Zkne,
RISCV_ISA_Zknh => RISCV_ISA_Zknh,
RISCV_ISA_Zksed => RISCV_ISA_Zksed,
RISCV_ISA_Zksh => RISCV_ISA_Zksh,
RISCV_ISA_Zmmul => RISCV_ISA_Zmmul,
RISCV_ISA_Zxcfu => RISCV_ISA_Zxcfu,
RISCV_ISA_Sdext => RISCV_ISA_Sdext,
RISCV_ISA_Sdtrig => RISCV_ISA_Sdtrig,
RISCV_ISA_Smpmp => RISCV_ISA_Smpmp,
-- Tuning Options --
CPU_CLOCK_GATING_EN => CPU_CLOCK_GATING_EN,
CPU_FAST_MUL_EN => CPU_FAST_MUL_EN,
CPU_FAST_SHIFT_EN => CPU_FAST_SHIFT_EN,
CPU_RF_HW_RST_EN => CPU_RF_HW_RST_EN,
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS,
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY,
PMP_TOR_MODE_EN => PMP_TOR_MODE_EN,
PMP_NAP_MODE_EN => PMP_NAP_MODE_EN,
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS,
HPM_CNT_WIDTH => HPM_CNT_WIDTH
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_i,
-- interrupts --
msi_i => msi_i,
mei_i => mei_i,
mti_i => mti_i,
firq_i => firq_i,
dbi_i => dbi_i,
-- inter-core communication links --
icc_tx_o => icc_tx_o,
icc_rx_i => icc_rx_i,
-- instruction bus interface --
ibus_req_o => cpu_i_req,
ibus_rsp_i => cpu_i_rsp,
-- data bus interface --
dbus_req_o => cpu_d_req,
dbus_rsp_i => cpu_d_rsp
);
-- CPU L1 Instruction Cache (I-Cache) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_icache_enabled:
if ICACHE_EN generate
neorv32_icache_inst: entity neorv32.neorv32_cache
generic map (
NUM_BLOCKS => ICACHE_NUM_BLOCKS,
BLOCK_SIZE => ICACHE_BLOCK_SIZE,
UC_BEGIN => ICACHE_UC_BEGIN(31 downto 28),
UC_ENABLE => true,
READ_ONLY => true
)
port map (
clk_i => clk_i,
rstn_i => rstn_i,
host_req_i => cpu_i_req,
host_rsp_o => cpu_i_rsp,
bus_req_o => icache_req,
bus_rsp_i => icache_rsp
);
end generate;
neorv32_icache_disabled:
if not ICACHE_EN generate
icache_req <= cpu_i_req;
cpu_i_rsp <= icache_rsp;
end generate;
-- CPU L1 Data Cache (D-Cache) ------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_dcache_enabled:
if DCACHE_EN generate
neorv32_dcache_inst: entity neorv32.neorv32_cache
generic map (
NUM_BLOCKS => DCACHE_NUM_BLOCKS,
BLOCK_SIZE => DCACHE_BLOCK_SIZE,
UC_BEGIN => DCACHE_UC_BEGIN(31 downto 28),
UC_ENABLE => true,
READ_ONLY => false
)
port map (
clk_i => clk_i,
rstn_i => rstn_i,
host_req_i => cpu_d_req,
host_rsp_o => cpu_d_rsp,
bus_req_o => dcache_req,
bus_rsp_i => dcache_rsp
);
end generate;
neorv32_dcache_disabled:
if not DCACHE_EN generate
dcache_req <= cpu_d_req;
cpu_d_rsp <= dcache_rsp;
end generate;
-- Core Instruction/Data Bus Switch -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_core_bus_switch_inst: entity neorv32.neorv32_bus_switch
generic map (
ROUND_ROBIN_EN => false, -- use prioritizing arbitration
PORT_A_READ_ONLY => false,
PORT_B_READ_ONLY => true -- instruction fetch is read-only
)
port map (
clk_i => clk_i,
rstn_i => rstn_i,
a_lock_i => '0', -- no exclusive accesses
a_req_i => dcache_req, -- data accesses are prioritized
a_rsp_o => dcache_rsp,
b_req_i => icache_req,
b_rsp_o => icache_rsp,
x_req_o => bus_req_o,
x_rsp_i => bus_rsp_i
);
end neorv32_core_complex_rtl;

View file

@ -70,7 +70,7 @@ entity neorv32_cpu is
);
port (
-- global control --
clk_i : in std_ulogic; -- switchable global clock, rising edge
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- interrupts --
msi_i : in std_ulogic; -- risc-v machine software interrupt
@ -78,20 +78,15 @@ entity neorv32_cpu is
mti_i : in std_ulogic; -- risc-v machine timer interrupt
firq_i : in std_ulogic_vector(15 downto 0); -- custom fast interrupts
dbi_i : in std_ulogic; -- risc-v debug halt request interrupt
-- inter-core communication links --
icc_tx_o : out icc_t; -- TX links
icc_rx_i : in icc_t; -- RX links
-- instruction bus interface --
ibus_req_o : out bus_req_t; -- request bus
ibus_rsp_i : in bus_rsp_t; -- response bus
-- data bus interface --
dbus_req_o : out bus_req_t; -- request bus
dbus_rsp_i : in bus_rsp_t; -- response bus
-- ICC TX links --
icc_tx_rdy_o : out std_ulogic_vector(NUM_HARTS-1 downto 0); -- data available
icc_tx_ack_i : in std_ulogic_vector(NUM_HARTS-1 downto 0); -- read-enable
icc_tx_dat_o : out std_ulogic_vector((NUM_HARTS*XLEN)-1 downto 0); -- data word
-- ICC RX links --
icc_rx_rdy_i : in std_ulogic_vector(NUM_HARTS-1 downto 0); -- data available
icc_rx_ack_o : out std_ulogic_vector(NUM_HARTS-1 downto 0); -- read-enable
icc_rx_dat_i : in std_ulogic_vector((NUM_HARTS*XLEN)-1 downto 0) -- data word
dbus_rsp_i : in bus_rsp_t -- response bus
);
end neorv32_cpu;
@ -446,33 +441,29 @@ begin
if NUM_HARTS > 1 generate
neorv32_cpu_icc_inst: entity neorv32.neorv32_cpu_icc
generic map (
HART_ID => HART_ID, -- ID of this core
HART_ID => HART_ID, -- ID of this core
NUM_HARTS => NUM_HARTS -- number of cores, has to be a power of two
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
-- CSR interface --
csr_we_i => xcsr_we, -- global write enable
csr_re_i => xcsr_re, -- global read enable
csr_addr_i => xcsr_addr, -- address
csr_wdata_i => xcsr_wdata, -- write data
csr_rdata_o => xcsr_rdata_icc, -- read data
-- ICC TX links --
icc_tx_rdy_o => icc_tx_rdy_o, -- data available
icc_tx_ack_i => icc_tx_ack_i, -- read-enable
icc_tx_dat_o => icc_tx_dat_o, -- data word
-- ICC RX links --
icc_rx_rdy_i => icc_rx_rdy_i, -- data available
icc_rx_ack_o => icc_rx_ack_o, -- read-enable
icc_rx_dat_i => icc_rx_dat_i -- data word
csr_we_i => xcsr_we, -- global write enable
csr_re_i => xcsr_re, -- global read enable
csr_addr_i => xcsr_addr, -- address
csr_wdata_i => xcsr_wdata, -- write data
csr_rdata_o => xcsr_rdata_icc, -- read data
-- ICC links --
icc_tx_o => icc_tx_o, -- TX links
icc_rx_i => icc_rx_i -- RX links
);
end generate;
icc_disabled:
if NUM_HARTS = 1 generate
xcsr_rdata_icc <= (others => '0');
icc_tx_o <= icc_terminate_c;
end generate;

View file

@ -22,22 +22,17 @@ entity neorv32_cpu_icc is
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- CSR interface --
csr_we_i : in std_ulogic; -- global write enable
csr_re_i : in std_ulogic; -- global read enable
csr_addr_i : in std_ulogic_vector(11 downto 0); -- address
csr_wdata_i : in std_ulogic_vector(XLEN-1 downto 0); -- write data
csr_rdata_o : out std_ulogic_vector(XLEN-1 downto 0); -- read data
-- ICC TX links --
icc_tx_rdy_o : out std_ulogic_vector(NUM_HARTS-1 downto 0); -- data available
icc_tx_ack_i : in std_ulogic_vector(NUM_HARTS-1 downto 0); -- read-enable
icc_tx_dat_o : out std_ulogic_vector((NUM_HARTS*XLEN)-1 downto 0); -- data word
-- ICC RX links --
icc_rx_rdy_i : in std_ulogic_vector(NUM_HARTS-1 downto 0); -- data available
icc_rx_ack_o : out std_ulogic_vector(NUM_HARTS-1 downto 0); -- read-enable
icc_rx_dat_i : in std_ulogic_vector((NUM_HARTS*XLEN)-1 downto 0) -- data word
csr_we_i : in std_ulogic; -- global write enable
csr_re_i : in std_ulogic; -- global read enable
csr_addr_i : in std_ulogic_vector(11 downto 0); -- address
csr_wdata_i : in std_ulogic_vector(XLEN-1 downto 0); -- write data
csr_rdata_o : out std_ulogic_vector(XLEN-1 downto 0); -- read data
-- ICC links --
icc_tx_o : out icc_t; -- TX links
icc_rx_i : in icc_t -- RX links
);
end neorv32_cpu_icc;
@ -69,14 +64,14 @@ begin
end if;
end process csr_write;
csr_read: process(csr_addr_i, link_id, icc_rx_rdy_i, tx_fifo_free, rx_data)
csr_read: process(csr_addr_i, link_id, icc_rx_i, tx_fifo_free, rx_data)
begin
csr_rdata_o <= (others => '0'); -- default
if (csr_addr_i(11 downto 2) = csr_mxiccrxd_c(11 downto 2)) then -- ICC CSRs base address
if (csr_addr_i(1) = '0') then -- data register(s)
csr_rdata_o <= rx_data(to_integer(unsigned(link_id)));
else -- control and status register(s)
csr_rdata_o(XLEN-1) <= icc_rx_rdy_i(to_integer(unsigned(link_id)));
csr_rdata_o(XLEN-1) <= icc_rx_i.rdy(to_integer(unsigned(link_id)));
csr_rdata_o(XLEN-2) <= tx_fifo_free(to_integer(unsigned(link_id)));
csr_rdata_o(id_width_c-1 downto 0) <= link_id;
end if;
@ -111,29 +106,41 @@ begin
we_i => tx_fifo_we(i),
free_o => tx_fifo_free(i),
-- read port --
re_i => icc_tx_ack_i(i),
rdata_o => icc_tx_dat_o(i*XLEN+(XLEN-1) downto i*XLEN),
avail_o => icc_tx_rdy_o(i)
re_i => icc_rx_i.ack(i),
rdata_o => icc_tx_o.dat(i*XLEN+(XLEN-1) downto i*XLEN),
avail_o => icc_tx_o.rdy(i)
);
end generate;
-- no FIFO/link for *this* core --
queue_terminate:
if i = HART_ID generate
tx_fifo_free(i) <= '0';
icc_tx_dat_o(i*XLEN+(XLEN-1) downto i*XLEN) <= (others => '0');
icc_tx_rdy_o(i) <= '0';
tx_fifo_free(i) <= '0';
icc_tx_o.dat(i*XLEN+(XLEN-1) downto i*XLEN) <= (others => '0');
icc_tx_o.rdy(i) <= '0';
end generate;
-- reorganize incoming links as 2d-array --
rx_data(i) <= icc_rx_dat_i(i*XLEN+(XLEN-1) downto i*XLEN);
rx_data(i) <= icc_rx_i.dat(i*XLEN+(XLEN-1) downto i*XLEN);
-- link control --
link_sel(i) <= '1' when (unsigned(link_id) = to_unsigned(i, id_width_c)) else '0';
icc_rx_ack_o(i) <= '1' when (csr_re_i = '1') and (csr_addr_i = csr_mxiccrxd_c) and (link_sel(i) = '1') else '0';
icc_tx_o.ack(i) <= '1' when (csr_re_i = '1') and (csr_addr_i = csr_mxiccrxd_c) and (link_sel(i) = '1') else '0';
tx_fifo_we(i) <= '1' when (csr_we_i = '1') and (csr_addr_i = csr_mxicctxd_c) and (link_sel(i) = '1') else '0';
end generate;
-- terminate unused links --
link_terminate:
if NUM_HARTS < 4 generate
link_terminate_gen:
for i in NUM_HARTS to 3 generate
icc_tx_o.rdy(i) <= '0';
icc_tx_o.ack(i) <= '0';
icc_tx_o.dat(i*XLEN+(XLEN-1) downto i*XLEN) <= (others => '0');
end generate;
end generate;
end neorv32_cpu_icc_rtl;

View file

@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100808"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100809"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width
@ -224,16 +224,22 @@ package neorv32_package is
err => '0'
);
-- External Stream-Link Interface (SLINK / AXI4-Stream) -----------------------------------
-- Inter-Core Communication (ICC) Links ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
type slink_t is record
data : std_ulogic_vector(31 downto 0); -- data
addr : std_ulogic_vector(3 downto 0); -- source/destination ID
valid : std_ulogic; -- source valid
last : std_ulogic; -- last element of packet
ready : std_ulogic; -- sink ready
-- icc link (for up to 4 cores) --
type icc_t is record
rdy : std_ulogic_vector(4-1 downto 0); -- data available
ack : std_ulogic_vector(4-1 downto 0); -- read-enable
dat : std_ulogic_vector(4*XLEN-1 downto 0); -- data word
end record;
-- endpoint termination --
constant icc_terminate_c : icc_t := (
rdy => (others => '0'),
ack => (others => '0'),
dat => (others => '0')
);
-- **********************************************************************************************************
-- RISC-V ISA Definitions
-- **********************************************************************************************************

View file

@ -310,23 +310,19 @@ architecture neorv32_top_rtl of neorv32_top is
signal dci_ndmrstn : std_ulogic;
signal dci_haltreq : std_ulogic_vector(num_cores_c-1 downto 0);
-- CPU ICC links --
type icc_rdy_t is array (0 to num_cores_c-1) of std_ulogic_vector(num_cores_c-1 downto 0);
type icc_ack_t is array (0 to num_cores_c-1) of std_ulogic_vector(num_cores_c-1 downto 0);
type icc_dat_t is array (0 to num_cores_c-1) of std_ulogic_vector(num_cores_c*32-1 downto 0);
signal icc_tx_rdy, icc_rx_rdy : icc_rdy_t;
signal icc_tx_ack, icc_rx_ack : icc_ack_t;
signal icc_tx_dat, icc_rx_dat : icc_dat_t;
-- CPU ICC links (up to 4 instances) --
type multicore_icc_t is array (0 to 3) of icc_t;
signal icc_tx, icc_rx : multicore_icc_t;
-- bus: CPU core(s) + L1 caches --
type multicore_req_t is array (0 to num_cores_c-1) of bus_req_t;
type multicore_rsp_t is array (0 to num_cores_c-1) of bus_rsp_t;
signal cpu_i_req, cpu_d_req, icache_req, dcache_req, core_req : multicore_req_t;
signal cpu_i_rsp, cpu_d_rsp, icache_rsp, dcache_rsp, core_rsp : multicore_rsp_t;
-- bus: CPU core complex (up to 4 instances) --
type multicore_req_t is array (0 to 3) of bus_req_t;
type multicore_rsp_t is array (0 to 3) of bus_rsp_t;
signal core_req : multicore_req_t;
signal core_rsp : multicore_rsp_t;
-- bus: core complex and DMA --
signal complex_req, main_req, main2_req, dma_req : bus_req_t;
signal complex_rsp, main_rsp, main2_rsp, dma_rsp : bus_rsp_t;
-- bus: system bus (including DMA complex) --
signal sys1_req, sys2_req, dma_req, sys3_req : bus_req_t;
signal sys1_rsp, sys2_rsp, dma_rsp, sys3_rsp : bus_rsp_t;
-- bus: main sections --
signal imem_req, dmem_req, xipcache_req, xip_req, io_req, xcache_req, xbus_req : bus_req_t;
@ -372,7 +368,8 @@ begin
-- show SoC configuration --
assert false report
"[NEORV32] Processor Configuration: CPU " & -- cpu core is always enabled
cond_sel_string_f(DUAL_CORE_EN, "(dual-core-smp) ", "(single-core) ") &
cond_sel_string_f(boolean(num_cores_c = 1), "(single-core) ", "") &
cond_sel_string_f(boolean(num_cores_c = 2), "(smp-dual-core) ", "") &
cond_sel_string_f(MEM_INT_IMEM_EN, cond_sel_string_f(imem_as_rom_c, "IMEM-ROM ", "IMEM "), "") &
cond_sel_string_f(MEM_INT_DMEM_EN, "DMEM ", "") &
cond_sel_string_f(bootrom_en_c, "BOOTROM ", "") &
@ -501,9 +498,9 @@ begin
core_complex_gen:
for i in 0 to num_cores_c-1 generate
-- CPU Core -------------------------------------------------------------------------------
-- Core Complex ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_inst: entity neorv32.neorv32_cpu
neorv32_cpu_neorv32_core_complex: entity neorv32.neorv32_core_complex
generic map (
-- General --
HART_ID => i,
@ -550,141 +547,67 @@ begin
PMP_NAP_MODE_EN => PMP_NAP_MODE_EN,
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS,
HPM_CNT_WIDTH => HPM_CNT_WIDTH
HPM_CNT_WIDTH => HPM_CNT_WIDTH,
-- Instruction Cache (iCACHE) --
ICACHE_EN => ICACHE_EN,
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS,
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE,
ICACHE_UC_BEGIN => mem_uncached_begin_c,
-- Data Cache (dCACHE) --
DCACHE_EN => DCACHE_EN,
DCACHE_NUM_BLOCKS => DCACHE_NUM_BLOCKS,
DCACHE_BLOCK_SIZE => DCACHE_BLOCK_SIZE,
DCACHE_UC_BEGIN => mem_uncached_begin_c
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_sys,
clk_i => clk_i,
rstn_i => rstn_sys,
-- interrupts --
msi_i => msw_irq(i),
mei_i => mext_irq_i,
mti_i => mtime_irq(i),
firq_i => cpu_firq,
dbi_i => dci_haltreq(i),
-- instruction bus interface --
ibus_req_o => cpu_i_req(i),
ibus_rsp_i => cpu_i_rsp(i),
-- data bus interface --
dbus_req_o => cpu_d_req(i),
dbus_rsp_i => cpu_d_rsp(i),
-- ICC TX links --
icc_tx_rdy_o => icc_tx_rdy(i),
icc_tx_ack_i => icc_tx_ack(i),
icc_tx_dat_o => icc_tx_dat(i),
-- ICC RX links --
icc_rx_rdy_i => icc_rx_rdy(i),
icc_rx_ack_o => icc_rx_ack(i),
icc_rx_dat_i => icc_rx_dat(i)
msi_i => msw_irq(i),
mei_i => mext_irq_i,
mti_i => mtime_irq(i),
firq_i => cpu_firq,
dbi_i => dci_haltreq(i),
-- inter-core communication links --
icc_tx_o => icc_tx(i),
icc_rx_i => icc_rx(i),
-- system bus interface --
bus_req_o => core_req(i),
bus_rsp_i => core_rsp(i)
);
-- inter-core communication (ICC) links (connect every core with every other) --
icc_gen:
for j in 0 to num_cores_c-1 generate
icc_gen_terminate: -- do not connect a core's link to itself
if i = j generate
icc_rx_rdy(i)(j) <= '0';
icc_tx_ack(i)(j) <= '0';
icc_rx_dat(i)(j*32+31 downto j*32) <= (others => '0');
end generate;
ip_gen_connect:
if i /= j generate
icc_rx_rdy(i)(j) <= icc_tx_rdy(j)(i);
icc_tx_ack(i)(j) <= icc_rx_ack(j)(i);
icc_rx_dat(i)(j*32+31 downto j*32) <= icc_tx_dat(j)(i*32+31 downto i*32);
end generate;
end generate;
-- CPU L1 Instruction Cache (I-Cache) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_icache_enabled:
if ICACHE_EN generate
neorv32_icache_inst: entity neorv32.neorv32_cache
generic map (
NUM_BLOCKS => ICACHE_NUM_BLOCKS,
BLOCK_SIZE => ICACHE_BLOCK_SIZE,
UC_BEGIN => mem_uncached_begin_c(31 downto 28),
UC_ENABLE => true,
READ_ONLY => true
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
host_req_i => cpu_i_req(i),
host_rsp_o => cpu_i_rsp(i),
bus_req_o => icache_req(i),
bus_rsp_i => icache_rsp(i)
);
end generate;
neorv32_icache_disabled:
if not ICACHE_EN generate
icache_req(i) <= cpu_i_req(i);
cpu_i_rsp(i) <= icache_rsp(i);
end generate;
-- CPU L1 Data Cache (D-Cache) ------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_dcache_enabled:
if DCACHE_EN generate
neorv32_dcache_inst: entity neorv32.neorv32_cache
generic map (
NUM_BLOCKS => DCACHE_NUM_BLOCKS,
BLOCK_SIZE => DCACHE_BLOCK_SIZE,
UC_BEGIN => mem_uncached_begin_c(31 downto 28),
UC_ENABLE => true,
READ_ONLY => false
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
host_req_i => cpu_d_req(i),
host_rsp_o => cpu_d_rsp(i),
bus_req_o => dcache_req(i),
bus_rsp_i => dcache_rsp(i)
);
end generate;
neorv32_dcache_disabled:
if not DCACHE_EN generate
dcache_req(i) <= cpu_d_req(i);
cpu_d_rsp(i) <= dcache_rsp(i);
end generate;
-- Core Instruction/Data Bus Switch -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_core_bus_switch_inst: entity neorv32.neorv32_bus_switch
generic map (
ROUND_ROBIN_EN => false, -- use prioritizing arbitration
PORT_A_READ_ONLY => false,
PORT_B_READ_ONLY => true -- i-fetch is read-only
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
a_lock_i => '0', -- no exclusive accesses
a_req_i => dcache_req(i), -- prioritized
a_rsp_o => dcache_rsp(i),
b_req_i => icache_req(i),
b_rsp_o => icache_rsp(i),
x_req_o => core_req(i),
x_rsp_i => core_rsp(i)
);
-- inter-core communication (ICC) links --
icc_connect: process(icc_tx)
begin
icc_rx(i) <= icc_terminate_c;
for j in 0 to num_cores_c-1 loop -- connect this core with every other core
icc_rx(i).rdy(j) <= icc_tx(j).rdy(i);
icc_rx(i).ack(j) <= icc_tx(j).ack(i);
icc_rx(i).dat(j*32+31 downto j*32) <= icc_tx(j).dat(i*32+31 downto i*32);
end loop;
end process icc_connect;
end generate; -- /core_complex
-- terminate unused interfaces --
core_complex_terminate:
if num_cores_c < 4 generate
core_complex_terminate_gen:
for i in num_cores_c to 3 generate
core_req(i) <= req_terminate_c;
core_rsp(i) <= rsp_terminate_c;
icc_rx(i) <= icc_terminate_c;
icc_tx(i) <= icc_terminate_c;
end generate;
end generate;
-- Core Complex Bus Switch ----------------------------------------------------------------
-- Core Complex Bus Arbiter ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
core_complex_dual:
if num_cores_c > 1 generate
neorv32_complex_mux_inst: entity neorv32.neorv32_bus_switch
if num_cores_c = 2 generate
neorv32_complex_arbiter_inst: entity neorv32.neorv32_bus_switch
generic map (
ROUND_ROBIN_EN => true,
PORT_A_READ_ONLY => false,
@ -694,19 +617,19 @@ begin
clk_i => clk_i,
rstn_i => rstn_sys,
a_lock_i => '0',
a_req_i => core_req(core_req'left),
a_rsp_o => core_rsp(core_req'left),
b_req_i => core_req(core_req'right), -- [hack] core_req(1) does not exist if single core
b_rsp_o => core_rsp(core_req'right),
x_req_o => complex_req,
x_rsp_i => complex_rsp
a_req_i => core_req(0),
a_rsp_o => core_rsp(0),
b_req_i => core_req(1),
b_rsp_o => core_rsp(1),
x_req_o => sys1_req,
x_rsp_i => sys1_rsp
);
end generate;
core_complex_single:
if num_cores_c = 1 generate
complex_req <= core_req(0);
core_rsp(0) <= complex_rsp;
sys1_req <= core_req(0);
core_rsp(0) <= sys1_rsp;
end generate;
@ -744,12 +667,12 @@ begin
clk_i => clk_i,
rstn_i => rstn_sys,
a_lock_i => '0', -- no exclusive accesses
a_req_i => complex_req, -- prioritized
a_rsp_o => complex_rsp,
a_req_i => sys1_req, -- prioritized
a_rsp_o => sys1_rsp,
b_req_i => dma_req,
b_rsp_o => dma_rsp,
x_req_o => main_req,
x_rsp_i => main_rsp
x_req_o => sys2_req,
x_rsp_i => sys2_rsp
);
end generate; -- /neorv32_dma_complex_enabled
@ -757,8 +680,8 @@ begin
neorv32_dma_complex_disabled:
if not IO_DMA_EN generate
iodev_rsp(IODEV_DMA) <= rsp_terminate_c;
main_req <= complex_req;
complex_rsp <= main_rsp;
sys2_req <= sys1_req;
sys1_rsp <= sys2_rsp;
firq(FIRQ_DMA) <= '0';
end generate;
@ -773,17 +696,17 @@ begin
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
core_req_i => main_req,
core_rsp_o => main_rsp,
sys_req_o => main2_req,
sys_rsp_i => main2_rsp
core_req_i => sys2_req,
core_rsp_o => sys2_rsp,
sys_req_o => sys3_req,
sys_rsp_i => sys3_rsp
);
end generate;
neorv32_bus_amo_ctrl_disabled:
if not RISCV_ISA_Zaamo generate
main2_req <= main_req;
main_rsp <= main2_rsp;
sys3_req <= sys2_req;
sys2_rsp <= sys3_rsp;
end generate;
@ -823,8 +746,8 @@ begin
clk_i => clk_i,
rstn_i => rstn_sys,
-- host port --
req_i => main2_req,
rsp_o => main2_rsp,
req_i => sys3_req,
rsp_o => sys3_rsp,
-- section ports --
a_req_o => imem_req,
a_rsp_i => imem_rsp,
@ -1042,7 +965,7 @@ begin
generic map (
INREG_EN => true,
OUTREG_EN => true,
DEV_SIZE => iodev_size_c, -- size of a single IO device
DEV_SIZE => iodev_size_c,
DEV_00_EN => bootrom_en_c, DEV_00_BASE => base_io_bootrom_c,
DEV_01_EN => false, DEV_01_BASE => (others => '0'), -- reserved
DEV_02_EN => false, DEV_02_BASE => (others => '0'), -- reserved

View file

@ -19,6 +19,7 @@ NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu_icc.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cpu.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_bus.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_cache.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_core_complex.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_dma.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_application_image.vhd
NEORV32_RTL_PATH_PLACEHOLDER/core/neorv32_imem.vhd

View file

@ -91,6 +91,13 @@ architecture neorv32_tb_rtl of neorv32_tb is
signal msi, mei, mti : std_ulogic;
-- slink --
type slink_t is record
data : std_ulogic_vector(31 downto 0); -- data
addr : std_ulogic_vector(3 downto 0); -- source/destination ID
valid : std_ulogic; -- source valid
last : std_ulogic; -- last element of packet
ready : std_ulogic; -- sink ready
end record;
signal slink_tx, slink_rx : slink_t;
-- XBUS (Wishbone b4) bus --

View file

@ -92,23 +92,19 @@ __crt0_multicore_wakeup:
add x14, x14, x15
sw zero, 0(x14) // CLINT.MSWI[hart_id]
csrr x14, mcause
li x15, 0x80000003 // is machine software interrupt?
bne x14, x15, __crt0_multicore_exit // go back to sleep if not
// get launch configuration from core 0
// check launch configuration from core 0
csrw 0xbc2, zero // ICC.SR: link select = 0
csrr x13, 0xbc0 // ICC.RX: signature
li x14, 0xffab4321 // expected signature
bne x14, x13, __crt0_multicore_exit // abort if incorrect signature
beq x14, x13, __crt0_multicore_launch
mret // go back to sleep if incorrect signature
// get launch configuration from core 0
__crt0_multicore_launch:
csrw 0xbc1, x14 // ICC.TX: acknowledge start
csrr x2, 0xbc0 // ICC.RX: stack_top -> sp
csrr x12, 0xbc0 // ICC.RX: entry_point
j __crt0_main_entry // start main function
__crt0_multicore_exit:
mret // go back to sleep
csrr x2, 0xbc0 // ICC.RX: stack top -> sp
csrr x12, 0xbc0 // ICC.RX: entry point
j __crt0_main_entry // start at entry point
__crt0_multicore_primary:
#endif

View file

@ -49,7 +49,7 @@ int main(void) {
// check hardware/software configuration
if (NEORV32_SYSINFO->MISC[SYSINFO_MISC_HART] == 1) { // two cores available?
if (NEORV32_SYSINFO->MISC[SYSINFO_MISC_HART] != 2) { // two cores available?
neorv32_uart0_printf("[ERROR] dual-core option not enabled!\n");
return -1;
}
@ -135,8 +135,6 @@ int main(void) {
/**********************************************************************//**
* Main function for core 1 (secondary core).
*
* @return Irrelevant (but can be inspected by the debugger).
**************************************************************************/
void main_core1(void) {

View file

@ -599,7 +599,7 @@ int main() {
// number of traps we are expecting + expected instruction word of last illegal instruction
uint32_t invalid_instr;
if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C)) { // C extension enabled
tmp_a += 17;
tmp_a += 18;
invalid_instr = 0x08812681; // mtinst: pre-decompressed; clear bit 1 if compressed instruction
}
else { // C extension disabled

View file

@ -27,13 +27,10 @@
**************************************************************************/
int neorv32_smp_launch(int hart_id, void (*entry_point)(void), uint8_t* stack_memory, size_t stack_size_bytes) {
const uint32_t magic_number = 0xffab4321u;
int num_cores = (int)NEORV32_SYSINFO->MISC[SYSINFO_MISC_HART];
// sanity checks
if ((neorv32_cpu_csr_read(CSR_MHARTID) != 0) || // this can be executed on core 0 only
(hart_id == 0) || // we cannot launch core 0
(hart_id > (num_cores-1)) || // selected core not available
(hart_id > (neorv32_sysinfo_get_numcores()-1)) || // selected core not available
(neorv32_clint_available() == 0)) { // we need the CLINT
return -1;
}
@ -47,6 +44,7 @@ int neorv32_smp_launch(int hart_id, void (*entry_point)(void), uint8_t* stack_me
uint32_t stack_top = ((uint32_t)stack_memory + (uint32_t)(stack_size_bytes-1)) & 0xfffffff0u;
// send launch configuration
const uint32_t magic_number = 0xffab4321u;
neorv32_smp_icc_put(hart_id, magic_number); // identifies valid configuration
neorv32_smp_icc_put(hart_id, stack_top); // top of core's stack
neorv32_smp_icc_put(hart_id, (uint32_t)entry_point); // entry point