neorv32/rtl/core/neorv32_top.vhd

1649 lines
71 KiB
VHDL

-- #################################################################################################
-- # << The NEORV32 RISC-V Processor - Top Entity >> #
-- # ********************************************************************************************* #
-- # Check out the processor's online documentation for more information: #
-- # HQ: https://github.com/stnolting/neorv32 #
-- # Data Sheet: https://stnolting.github.io/neorv32 #
-- # User Guide: https://stnolting.github.io/neorv32/ug #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 #
-- # Copyright (c) 2024, 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: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- #################################################################################################
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library neorv32;
use neorv32.neorv32_package.all;
entity neorv32_top is
generic (
-- General --
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
CLOCK_GATING_EN : boolean := false; -- enable clock gating when in sleep mode
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- hardware thread ID
VENDOR_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- vendor's JEDEC ID
INT_BOOTLOADER_EN : boolean := false; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
DM_LEGACY_MODE : boolean := false; -- debug module spec version: false = v1.0, true = v0.13
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic memory operations extension?
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit-manipulation extension?
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/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 regs!)
CPU_EXTENSION_RISCV_Zicntr : boolean := true; -- implement base counters?
CPU_EXTENSION_RISCV_Zicond : boolean := false; -- implement integer conditional operations?
CPU_EXTENSION_RISCV_Zihpm : boolean := false; -- implement hardware performance monitors?
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zxcfu : boolean := false; -- implement custom (instr.) functions unit?
-- Tuning Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
REGFILE_HW_RST : boolean := false; -- implement full hardware reset for register file
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural range 0 to 16 := 0; -- number of regions (0..16)
PMP_MIN_GRANULARITY : natural := 4; -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
PMP_TOR_MODE_EN : boolean := true; -- implement TOR mode
PMP_NAP_MODE_EN : boolean := true; -- implement NAPOT/NA4 modes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural range 0 to 13 := 0; -- number of implemented HPM counters (0..13)
HPM_CNT_WIDTH : natural range 0 to 64 := 40; -- total size of HPM counters (0..64)
-- Atomic Memory Access - Reservation Set Granularity --
AMO_RVS_GRANULARITY : natural := 4; -- size in bytes, has to be a power of 2, min 4
-- Internal Instruction memory (IMEM) --
MEM_INT_IMEM_EN : boolean := false; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes (use a power of 2)
-- Internal Data memory (DMEM) --
MEM_INT_DMEM_EN : boolean := false; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes (use a power of 2)
-- Internal Instruction Cache (iCACHE) --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural range 1 to 256 := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural range 4 to 2**16 := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural range 1 to 2 := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- Internal Data Cache (dCACHE) --
DCACHE_EN : boolean := false; -- implement data cache
DCACHE_NUM_BLOCKS : natural range 1 to 256 := 4; -- d-cache: number of blocks (min 1), has to be a power of 2
DCACHE_BLOCK_SIZE : natural range 4 to 2**16 := 64; -- d-cache: block size in bytes (min 4), has to be a power of 2
-- External memory interface (WISHBONE) --
MEM_EXT_EN : boolean := false; -- implement external memory bus interface?
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE : boolean := false; -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN : boolean := false; -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX : boolean := false; -- use register buffer for RX data when false
MEM_EXT_ASYNC_TX : boolean := false; -- use register buffer for TX data when false
-- Execute in-place module (XIP) --
XIP_EN : boolean := false; -- implement execute in place module (XIP)?
XIP_CACHE_EN : boolean := false; -- implement XIP cache?
XIP_CACHE_NUM_BLOCKS : natural range 1 to 256 := 8; -- number of blocks (min 1), has to be a power of 2
XIP_CACHE_BLOCK_SIZE : natural range 1 to 2**16 := 256; -- block size in bytes (min 4), has to be a power of 2
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural range 0 to 32 := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := x"ffffffff"; -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := x"ffffffff"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_NUM : natural range 0 to 64 := 0; -- number of GPIO input/output pairs (0..64)
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART0_RX_FIFO : natural range 1 to 2**15 := 1; -- RX fifo depth, has to be a power of two, min 1
IO_UART0_TX_FIFO : natural range 1 to 2**15 := 1; -- TX fifo depth, has to be a power of two, min 1
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_UART1_RX_FIFO : natural range 1 to 2**15 := 1; -- RX fifo depth, has to be a power of two, min 1
IO_UART1_TX_FIFO : natural range 1 to 2**15 := 1; -- TX fifo depth, has to be a power of two, min 1
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)?
IO_SPI_FIFO : natural range 1 to 2**15 := 1; -- RTX fifo depth, has to be a power of two, min 1
IO_SDI_EN : boolean := false; -- implement serial data interface (SDI)?
IO_SDI_FIFO : natural range 1 to 2**15 := 1; -- RTX fifo depth, has to be zero or a power of two, min 1
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural range 0 to 12 := 0; -- number of PWM channels to implement (0..12); 0 = disabled
IO_WDT_EN : boolean := false; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_TRNG_FIFO : natural range 1 to 2**15 := 1; -- data fifo depth, has to be a power of two, min 1
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : natural := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : natural := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := false; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_NEOLED_TX_FIFO : natural range 1 to 2**15 := 1; -- NEOLED FIFO depth, has to be a power of two, min 1
IO_GPTMR_EN : boolean := false; -- implement general purpose timer (GPTMR)?
IO_ONEWIRE_EN : boolean := false; -- implement 1-wire interface (ONEWIRE)?
IO_DMA_EN : boolean := false; -- implement direct memory access controller (DMA)?
IO_SLINK_EN : boolean := false; -- implement stream link interface (SLINK)?
IO_SLINK_RX_FIFO : natural range 1 to 2**15 := 1; -- RX fifo depth, has to be a power of two, min 1
IO_SLINK_TX_FIFO : natural range 1 to 2**15 := 1; -- TX fifo depth, has to be a power of two, min 1
IO_CRC_EN : boolean := false -- implement cyclic redundancy check unit (CRC)?
);
port (
-- Global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i : in std_ulogic := 'H'; -- low-active TAP reset (optional)
jtag_tck_i : in std_ulogic := 'L'; -- serial clock
jtag_tdi_i : in std_ulogic := 'L'; -- serial data input
jtag_tdo_o : out std_ulogic; -- serial data output
jtag_tms_i : in std_ulogic := 'L'; -- mode select
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- read data
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data
wb_we_o : out std_ulogic; -- read/write
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_ulogic; -- strobe
wb_cyc_o : out std_ulogic; -- valid cycle
wb_ack_i : in std_ulogic := 'L'; -- transfer acknowledge
wb_err_i : in std_ulogic := 'L'; -- transfer error
-- Stream Link Interface (available if IO_SLINK_EN = true) --
slink_rx_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- RX input data
slink_rx_val_i : in std_ulogic := 'L'; -- RX valid input
slink_rx_lst_i : in std_ulogic := 'L'; -- last element of stream
slink_rx_rdy_o : out std_ulogic; -- RX ready to receive
slink_tx_dat_o : out std_ulogic_vector(31 downto 0); -- TX output data
slink_tx_val_o : out std_ulogic; -- TX valid output
slink_tx_lst_o : out std_ulogic; -- last element of stream
slink_tx_rdy_i : in std_ulogic := 'L'; -- TX ready to send
-- XIP (execute in place via SPI) signals (available if XIP_EN = true) --
xip_csn_o : out std_ulogic; -- chip-select, low-active
xip_clk_o : out std_ulogic; -- serial clock
xip_dat_i : in std_ulogic := 'L'; -- device data input
xip_dat_o : out std_ulogic; -- controller data output
-- GPIO (available if IO_GPIO_NUM > 0) --
gpio_o : out std_ulogic_vector(63 downto 0); -- parallel output
gpio_i : in std_ulogic_vector(63 downto 0) := (others => 'L'); -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o : out std_ulogic; -- UART0 send data
uart0_rxd_i : in std_ulogic := 'L'; -- UART0 receive data
uart0_rts_o : out std_ulogic; -- HW flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i : in std_ulogic := 'L'; -- HW flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o : out std_ulogic; -- UART1 send data
uart1_rxd_i : in std_ulogic := 'L'; -- UART1 receive data
uart1_rts_o : out std_ulogic; -- HW flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i : in std_ulogic := 'L'; -- HW flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_clk_o : out std_ulogic; -- SPI serial clock
spi_dat_o : out std_ulogic; -- controller data out, peripheral data in
spi_dat_i : in std_ulogic := 'L'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- chip-select
-- SDI (available if IO_SDI_EN = true) --
sdi_clk_i : in std_ulogic := 'L'; -- SDI serial clock
sdi_dat_o : out std_ulogic; -- controller data out, peripheral data in
sdi_dat_i : in std_ulogic := 'L'; -- controller data in, peripheral data out
sdi_csn_i : in std_ulogic := 'H'; -- chip-select
-- TWI (available if IO_TWI_EN = true) --
twi_sda_i : in std_ulogic := 'H'; -- serial data line sense input
twi_sda_o : out std_ulogic; -- serial data line output (pull low only)
twi_scl_i : in std_ulogic := 'H'; -- serial clock line sense input
twi_scl_o : out std_ulogic; -- serial clock line output (pull low only)
-- 1-Wire Interface (available if IO_ONEWIRE_EN = true) --
onewire_i : in std_ulogic := 'H'; -- 1-wire bus sense input
onewire_o : out std_ulogic; -- 1-wire bus output (pull low only)
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(11 downto 0); -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0) := (others => 'L'); -- custom CFS inputs conduit
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o : out std_ulogic; -- async serial data line
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o : out std_ulogic_vector(63 downto 0); -- current system time
-- GPTMR timer capture (available if IO_GPTMR_EN = true) --
gptmr_trig_i : in std_ulogic := 'L'; -- capture trigger
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- IRQ channels
-- CPU interrupts --
mtime_irq_i : in std_ulogic := 'L'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_ulogic := 'L'; -- machine software interrupt
mext_irq_i : in std_ulogic := 'L' -- machine external interrupt
);
end neorv32_top;
architecture neorv32_top_rtl of neorv32_top is
-- auto-configuration --
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_suv_f(INT_BOOTLOADER_EN, mem_boot_base_c, mem_imem_base_c);
constant imem_as_rom_c : boolean := not INT_BOOTLOADER_EN;
constant io_gpio_en_c : boolean := boolean(IO_GPIO_NUM > 0);
constant io_xirq_en_c : boolean := boolean(XIRQ_NUM_CH > 0);
constant io_pwm_en_c : boolean := boolean(IO_PWM_NUM_CH > 0);
-- make sure physical memory sizes are a power of two --
constant imem_size_valid_c : boolean := is_power_of_two_f(MEM_INT_IMEM_SIZE);
constant imem_size_pow2_c : natural := 2**index_size_f(MEM_INT_IMEM_SIZE);
constant imem_size_c : natural := cond_sel_natural_f(imem_size_valid_c, MEM_INT_IMEM_SIZE, imem_size_pow2_c);
--
constant dmem_size_valid_c : boolean := is_power_of_two_f(MEM_INT_DMEM_SIZE);
constant dmem_size_pow2_c : natural := 2**index_size_f(MEM_INT_DMEM_SIZE);
constant dmem_size_c : natural := cond_sel_natural_f(dmem_size_valid_c, MEM_INT_DMEM_SIZE, dmem_size_pow2_c);
-- reset generator --
signal rstn_wdt : std_ulogic;
signal rstn_sys_sreg, rstn_ext_sreg : std_ulogic_vector(3 downto 0);
signal rstn_sys, rstn_ext : std_ulogic;
signal rst_cause : std_ulogic_vector(1 downto 0);
-- clock generator --
signal clk_cpu : std_ulogic; -- CPU core clock, can be switched off
signal clk_div, clk_div_ff : std_ulogic_vector(11 downto 0);
signal clk_gen : std_ulogic_vector(07 downto 0);
signal clk_gen_en, clk_gen_en_ff : std_ulogic;
--
type cg_en_t is record
wdt, uart0, uart1, spi, twi, pwm, cfs, neoled, gptmr, xip, onewire : std_ulogic;
end record;
signal cg_en : cg_en_t;
-- CPU status --
signal cpu_debug, cpu_sleep : std_ulogic; -- cpu is in debug/sleep mode
-- debug module interface (DMI) --
signal dmi_req : dmi_req_t;
signal dmi_rsp : dmi_rsp_t;
-- debug core interface (DCI) --
signal dci_ndmrstn, dci_halt_req : std_ulogic;
-- bus: core complex --
signal cpu_i_req, cpu_d_req : bus_req_t; -- CPU core
signal cpu_i_rsp, cpu_d_rsp : bus_rsp_t; -- CPU core
signal icache_req, dcache_req : bus_req_t; -- CPU caches
signal icache_rsp, dcache_rsp : bus_rsp_t; -- CPU caches
signal core_req : bus_req_t; -- core complex (CPU + caches)
signal core_rsp : bus_rsp_t; -- core complex (CPU + caches)
-- bus: core complex + DMA --
signal main_req, main2_req, dma_req : bus_req_t; -- core complex (CPU + caches + DMA)
signal main_rsp, main2_rsp, dma_rsp : bus_rsp_t; -- core complex (CPU + caches + DMA)
-- bus: main sections --
signal imem_req, dmem_req, xip_req, boot_req, io_req, xbus_req : bus_req_t;
signal imem_rsp, dmem_rsp, xip_rsp, boot_rsp, io_rsp, xbus_rsp : bus_rsp_t;
-- bus: IO devices --
type io_devices_t is (
IODEV_OCD, IODEV_SYSINFO, IODEV_NEOLED, IODEV_GPIO, IODEV_WDT, IODEV_TRNG, IODEV_TWI,
IODEV_SPI, IODEV_SDI, IODEV_UART1, IODEV_UART0, IODEV_MTIME, IODEV_XIRQ, IODEV_ONEWIRE,
IODEV_GPTMR, IODEV_PWM, IODEV_XIP, IODEV_CRC, IODEV_DMA, IODEV_SLINK, IODEV_CFS
);
type iodev_req_t is array (io_devices_t) of bus_req_t;
type iodev_rsp_t is array (io_devices_t) of bus_rsp_t;
signal iodev_req : iodev_req_t;
signal iodev_rsp : iodev_rsp_t;
-- IRQs --
signal cpu_firq : std_ulogic_vector(15 downto 0);
type irq_t is record
wdt, uart0_rx, uart0_tx, uart1_rx, uart1_tx, spi, sdi, twi, cfs, neoled, xirq, gptmr, onewire, dma, trng, slink : std_ulogic;
end record;
signal firq : irq_t;
signal mtime_irq : std_ulogic;
-- misc --
signal mtime_time : std_ulogic_vector(63 downto 0);
begin
-- **************************************************************************************************************************
-- Sanity Checks
-- **************************************************************************************************************************
sanity_checks:
if (true) generate
-- say hello --
assert false report
"[NEORV32] The NEORV32 RISC-V Processor " &
"(version 0x" & to_hstring32_f(hw_version_c) & "), " &
"github.com/stnolting/neorv32" severity note;
-- show main SoC configuration --
assert false report
"[NEORV32] Processor Configuration: " &
cond_sel_string_f(MEM_INT_IMEM_EN, "IMEM ", "") &
cond_sel_string_f(MEM_INT_DMEM_EN, "DMEM ", "") &
cond_sel_string_f(INT_BOOTLOADER_EN, "BOOTROM ", "") &
cond_sel_string_f(ICACHE_EN, "I-CACHE ", "") &
cond_sel_string_f(DCACHE_EN, "D-CACHE ", "") &
cond_sel_string_f(MEM_EXT_EN, "WISHBONE ", "") &
cond_sel_string_f(io_gpio_en_c, "GPIO ", "") &
cond_sel_string_f(IO_MTIME_EN, "MTIME ", "") &
cond_sel_string_f(IO_UART0_EN, "UART0 ", "") &
cond_sel_string_f(IO_UART1_EN, "UART1 ", "") &
cond_sel_string_f(IO_SPI_EN, "SPI ", "") &
cond_sel_string_f(IO_SDI_EN, "SDI ", "") &
cond_sel_string_f(IO_TWI_EN, "TWI ", "") &
cond_sel_string_f(io_pwm_en_c, "PWM ", "") &
cond_sel_string_f(IO_WDT_EN, "WDT ", "") &
cond_sel_string_f(IO_TRNG_EN, "TRNG ", "") &
cond_sel_string_f(IO_CFS_EN, "CFS ", "") &
cond_sel_string_f(IO_NEOLED_EN, "NEOLED ", "") &
cond_sel_string_f(io_xirq_en_c, "XIRQ ", "") &
cond_sel_string_f(IO_GPTMR_EN, "GPTMR ", "") &
cond_sel_string_f(XIP_EN, "XIP ", "") &
cond_sel_string_f(IO_ONEWIRE_EN, "ONEWIRE ", "") &
cond_sel_string_f(IO_DMA_EN, "DMA ", "") &
cond_sel_string_f(IO_SLINK_EN, "SLINK ", "") &
cond_sel_string_f(IO_CRC_EN, "CRC ", "") &
cond_sel_string_f(true, "SYSINFO ", "") & -- always enabled
cond_sel_string_f(ON_CHIP_DEBUGGER_EN, "OCD ", "") &
""
severity note;
-- IMEM size --
assert not ((imem_size_valid_c = false) and (MEM_INT_IMEM_EN = true)) report
"[NEORV32] Auto-adjusting invalid IMEM size configuration." severity warning;
-- DMEM size --
assert not ((dmem_size_valid_c = false) and (MEM_INT_DMEM_EN = true)) report
"[NEORV32] Auto-adjusting invalid DMEM size configuration." severity warning;
end generate; -- /sanity_checks
-- **************************************************************************************************************************
-- Clock and Reset Generators
-- **************************************************************************************************************************
generators:
if (true) generate
-- Reset Generator ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
reset_generator: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
rstn_ext_sreg <= (others => '0');
rstn_ext <= '0';
rstn_sys_sreg <= (others => '0');
rstn_sys <= '0';
elsif falling_edge(clk_i) then -- inverted clock to release reset _before_ all FFs trigger (rising edge)
-- external reset --
rstn_ext_sreg <= rstn_ext_sreg(rstn_ext_sreg'left-1 downto 0) & '1'; -- active for at least <rstn_ext_sreg'size> clock cycles
rstn_ext <= and_reduce_f(rstn_ext_sreg);
-- internal reset --
if (rstn_wdt = '0') or (dci_ndmrstn = '0') then -- sync reset sources
rstn_sys_sreg <= (others => '0');
else
rstn_sys_sreg <= rstn_sys_sreg(rstn_sys_sreg'left-1 downto 0) & '1'; -- active for at least <rstn_sys_sreg'size> clock cycles
end if;
rstn_sys <= and_reduce_f(rstn_sys_sreg);
end if;
end process reset_generator;
-- Reset Cause ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
reset_cause: process(rstn_ext, clk_i)
begin
if (rstn_ext = '0') then
rst_cause <= "00"; -- reset from external pin
elsif falling_edge(clk_i) then
if (dci_ndmrstn = '0') then
rst_cause <= "01"; -- reset from on-chip debugger
elsif (rstn_wdt = '0') then
rst_cause <= "10"; -- reset from watchdog timer
end if;
end if;
end process reset_cause;
-- Clock Generator ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clock_generator: process(rstn_sys, clk_i)
begin
if (rstn_sys = '0') then
clk_gen_en_ff <= '0';
clk_div <= (others => '0');
clk_div_ff <= (others => '0');
elsif rising_edge(clk_i) then
clk_gen_en_ff <= clk_gen_en;
if (clk_gen_en_ff = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
else -- reset if disabled
clk_div <= (others => '0');
end if;
clk_div_ff <= clk_div;
end if;
end process clock_generator;
-- clock enables: rising edge detectors --
clk_gen(clk_div2_c) <= clk_div(0) and (not clk_div_ff(0)); -- clk/2
clk_gen(clk_div4_c) <= clk_div(1) and (not clk_div_ff(1)); -- clk/4
clk_gen(clk_div8_c) <= clk_div(2) and (not clk_div_ff(2)); -- clk/8
clk_gen(clk_div64_c) <= clk_div(5) and (not clk_div_ff(5)); -- clk/64
clk_gen(clk_div128_c) <= clk_div(6) and (not clk_div_ff(6)); -- clk/128
clk_gen(clk_div1024_c) <= clk_div(9) and (not clk_div_ff(9)); -- clk/1024
clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- clk/2048
clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- clk/4096
-- fresh clocks anyone? --
clk_gen_en <= cg_en.wdt or cg_en.uart0 or cg_en.uart1 or cg_en.spi or cg_en.twi or cg_en.pwm or
cg_en.cfs or cg_en.neoled or cg_en.gptmr or cg_en.xip or cg_en.onewire;
-- Clock Gating ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_clockgate_inst_true:
if CLOCK_GATING_EN generate
neorv32_clockgate_inst: entity neorv32.neorv32_clockgate
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
halt_i => cpu_sleep,
clk_o => clk_cpu
);
end generate;
neorv32_clockgate_inst_false:
if not CLOCK_GATING_EN generate
clk_cpu <= clk_i;
end generate;
end generate; -- /generators
-- **************************************************************************************************************************
-- Core Complex
-- **************************************************************************************************************************
core_complex:
if (true) generate
-- CPU Core -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_inst: entity neorv32.neorv32_cpu
generic map (
-- General --
HART_ID => HART_ID,
VENDOR_ID => VENDOR_ID,
CPU_BOOT_ADDR => cpu_boot_addr_c,
CPU_DEBUG_PARK_ADDR => dm_park_entry_c,
CPU_DEBUG_EXC_ADDR => dm_exc_entry_c,
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A,
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B,
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C,
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E,
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M,
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U,
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx,
CPU_EXTENSION_RISCV_Zicntr => CPU_EXTENSION_RISCV_Zicntr,
CPU_EXTENSION_RISCV_Zicond => CPU_EXTENSION_RISCV_Zicond,
CPU_EXTENSION_RISCV_Zihpm => CPU_EXTENSION_RISCV_Zihpm,
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul,
CPU_EXTENSION_RISCV_Zxcfu => CPU_EXTENSION_RISCV_Zxcfu,
CPU_EXTENSION_RISCV_Sdext => ON_CHIP_DEBUGGER_EN,
CPU_EXTENSION_RISCV_Sdtrig => ON_CHIP_DEBUGGER_EN,
-- Tuning Options --
FAST_MUL_EN => FAST_MUL_EN,
FAST_SHIFT_EN => FAST_SHIFT_EN,
REGFILE_HW_RST => REGFILE_HW_RST,
-- 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_cpu,
clk_aux_i => clk_i,
rstn_i => rstn_sys,
sleep_o => cpu_sleep,
debug_o => cpu_debug,
-- interrupts --
msi_i => msw_irq_i,
mei_i => mext_irq_i,
mti_i => mtime_irq,
firq_i => cpu_firq,
dbi_i => dci_halt_req,
-- 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
);
-- fast interrupt requests (FIRQs) --
cpu_firq(00) <= firq.wdt; -- highest priority
cpu_firq(01) <= firq.cfs;
cpu_firq(02) <= firq.uart0_rx;
cpu_firq(03) <= firq.uart0_tx;
cpu_firq(04) <= firq.uart1_rx;
cpu_firq(05) <= firq.uart1_tx;
cpu_firq(06) <= firq.spi;
cpu_firq(07) <= firq.twi;
cpu_firq(08) <= firq.xirq;
cpu_firq(09) <= firq.neoled;
cpu_firq(10) <= firq.dma;
cpu_firq(11) <= firq.sdi;
cpu_firq(12) <= firq.gptmr;
cpu_firq(13) <= firq.onewire;
cpu_firq(14) <= firq.slink;
cpu_firq(15) <= firq.trng; -- lowest priority
-- CPU Instruction Cache ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_icache_inst_true:
if ICACHE_EN generate
neorv32_icache_inst: entity neorv32.neorv32_icache
generic map (
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS,
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE,
ICACHE_NUM_SETS => ICACHE_ASSOCIATIVITY,
ICACHE_UC_PBEGIN => uncached_begin_c(31 downto 28)
)
port map (
clk_i => clk_cpu,
rstn_i => rstn_sys,
cpu_req_i => cpu_i_req,
cpu_rsp_o => cpu_i_rsp,
bus_req_o => icache_req,
bus_rsp_i => icache_rsp
);
end generate;
neorv32_icache_inst_false:
if not ICACHE_EN generate
icache_req <= cpu_i_req;
cpu_i_rsp <= icache_rsp;
end generate;
-- CPU Data Cache -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_dcache_inst_true:
if DCACHE_EN generate
neorv32_dcache_inst: entity neorv32.neorv32_dcache
generic map (
DCACHE_NUM_BLOCKS => DCACHE_NUM_BLOCKS,
DCACHE_BLOCK_SIZE => DCACHE_BLOCK_SIZE,
DCACHE_UC_PBEGIN => uncached_begin_c(31 downto 28)
)
port map (
clk_i => clk_cpu,
rstn_i => rstn_sys,
cpu_req_i => cpu_d_req,
cpu_rsp_o => cpu_d_rsp,
bus_req_o => dcache_req,
bus_rsp_i => dcache_rsp
);
end generate;
neorv32_dcache_inst_false:
if not DCACHE_EN generate
dcache_req <= cpu_d_req;
cpu_d_rsp <= dcache_rsp;
end generate;
-- Core Complex Bus Switch ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_core_bus_switch_inst: entity neorv32.neorv32_bus_switch
generic map (
PORT_A_READ_ONLY => false,
PORT_B_READ_ONLY => true -- i-fetch is read-only
)
port map (
clk_i => clk_cpu,
rstn_i => rstn_sys,
a_req_i => dcache_req, -- prioritized
a_rsp_o => dcache_rsp,
b_req_i => icache_req,
b_rsp_o => icache_rsp,
x_req_o => core_req,
x_rsp_i => core_rsp
);
end generate; -- /core_complex
-- **************************************************************************************************************************
-- Direct Memory Access Controller (DMA) Complex
-- **************************************************************************************************************************
neorv32_dma_complex_true:
if IO_DMA_EN generate
-- DMA Controller -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_dma_inst: entity neorv32.neorv32_dma
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_DMA),
bus_rsp_o => iodev_rsp(IODEV_DMA),
dma_req_o => dma_req,
dma_rsp_i => dma_rsp,
firq_i => cpu_firq,
irq_o => firq.dma
);
-- DMA Bus Switch -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_dma_bus_switch_inst: entity neorv32.neorv32_bus_switch
generic map (
PORT_A_READ_ONLY => false,
PORT_B_READ_ONLY => false
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
a_req_i => core_req, -- prioritized
a_rsp_o => core_rsp,
b_req_i => dma_req,
b_rsp_o => dma_rsp,
x_req_o => main_req,
x_rsp_i => main_rsp
);
end generate; -- /neorv32_dma_complex_true
neorv32_dma_complex_false:
if not IO_DMA_EN generate
iodev_rsp(IODEV_DMA) <= rsp_terminate_c;
main_req <= core_req;
core_rsp <= main_rsp;
firq.dma <= '0';
end generate;
-- **************************************************************************************************************************
-- Reservation Set Controller (for atomic LR/SC memory accesses)
-- **************************************************************************************************************************
neorv32_bus_reservation_set_true:
if CPU_EXTENSION_RISCV_A generate
neorv32_bus_reservation_set_inst: entity neorv32.neorv32_bus_reservation_set
generic map (
GRANULARITY => AMO_RVS_GRANULARITY
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
rvs_addr_o => open, -- yet unused
rvs_valid_o => open, -- yet unused
rvs_clear_i => '0', -- yet unused
core_req_i => main_req,
core_rsp_o => main_rsp,
sys_req_o => main2_req,
sys_rsp_i => main2_rsp
);
end generate;
neorv32_bus_reservation_set_false:
if not CPU_EXTENSION_RISCV_A generate
main2_req <= main_req;
main_rsp <= main2_rsp;
end generate;
-- **************************************************************************************************************************
-- Address Region Gateway
-- **************************************************************************************************************************
neorv32_bus_gateway_inst: entity neorv32.neorv32_bus_gateway
generic map (
TIMEOUT => bus_timeout_c,
-- IMEM port --
IMEM_ENABLE => MEM_INT_IMEM_EN,
IMEM_BASE => mem_imem_base_c,
IMEM_SIZE => imem_size_c,
-- DMEM port --
DMEM_ENABLE => MEM_INT_DMEM_EN,
DMEM_BASE => mem_dmem_base_c,
DMEM_SIZE => dmem_size_c,
-- XIP port --
XIP_ENABLE => XIP_EN,
XIP_BASE => mem_xip_base_c,
XIP_SIZE => mem_xip_size_c,
-- BOOT ROM port --
BOOT_ENABLE => INT_BOOTLOADER_EN,
BOOT_BASE => mem_boot_base_c,
BOOT_SIZE => mem_boot_size_c,
-- IO port --
IO_ENABLE => true, -- always enabled (mandatory core module)
IO_BASE => mem_io_base_c,
IO_SIZE => mem_io_size_c,
-- EXT port --
EXT_ENABLE => MEM_EXT_EN
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_sys,
-- host port --
main_req_i => main2_req,
main_rsp_o => main2_rsp,
-- section ports --
imem_req_o => imem_req,
imem_rsp_i => imem_rsp,
dmem_req_o => dmem_req,
dmem_rsp_i => dmem_rsp,
xip_req_o => xip_req,
xip_rsp_i => xip_rsp,
boot_req_o => boot_req,
boot_rsp_i => boot_rsp,
io_req_o => io_req,
io_rsp_i => io_rsp,
ext_req_o => xbus_req,
ext_rsp_i => xbus_rsp
);
-- **************************************************************************************************************************
-- Memory System
-- **************************************************************************************************************************
memory_system:
if (true) generate
-- Processor-Internal Instruction Memory (IMEM) -------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_int_imem_inst_true:
if MEM_INT_IMEM_EN generate
neorv32_int_imem_inst: entity neorv32.neorv32_imem
generic map (
IMEM_SIZE => imem_size_c,
IMEM_AS_IROM => imem_as_rom_c
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => imem_req,
bus_rsp_o => imem_rsp
);
end generate;
neorv32_int_imem_inst_false:
if not MEM_INT_IMEM_EN generate
imem_rsp <= rsp_terminate_c;
end generate;
-- Processor-Internal Data Memory (DMEM) --------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_int_dmem_inst_true:
if MEM_INT_DMEM_EN generate
neorv32_int_dmem_inst: entity neorv32.neorv32_dmem
generic map (
DMEM_SIZE => dmem_size_c
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => dmem_req,
bus_rsp_o => dmem_rsp
);
end generate;
neorv32_int_dmem_inst_false:
if not MEM_INT_DMEM_EN generate
dmem_rsp <= rsp_terminate_c;
end generate;
-- Processor-Internal Bootloader ROM (BOOTROM) --------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_boot_rom_inst_true:
if INT_BOOTLOADER_EN generate
neorv32_boot_rom_inst: entity neorv32.neorv32_boot_rom
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => boot_req,
bus_rsp_o => boot_rsp
);
end generate;
neorv32_boot_rom_inst_false:
if not INT_BOOTLOADER_EN generate
boot_rsp <= rsp_terminate_c;
end generate;
-- Execute In Place Module (XIP) ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_xip_inst_true:
if XIP_EN generate
neorv32_xip_inst: entity neorv32.neorv32_xip
generic map (
XIP_CACHE_EN => XIP_CACHE_EN,
XIP_CACHE_NUM_BLOCKS => XIP_CACHE_NUM_BLOCKS,
XIP_CACHE_BLOCK_SIZE => XIP_CACHE_BLOCK_SIZE
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_XIP),
bus_rsp_o => iodev_rsp(IODEV_XIP),
xip_req_i => xip_req,
xip_rsp_o => xip_rsp,
clkgen_en_o => cg_en.xip,
clkgen_i => clk_gen,
spi_csn_o => xip_csn_o,
spi_clk_o => xip_clk_o,
spi_dat_i => xip_dat_i,
spi_dat_o => xip_dat_o
);
end generate;
neorv32_xip_inst_false:
if not XIP_EN generate
iodev_rsp(IODEV_XIP) <= rsp_terminate_c;
xip_rsp <= rsp_terminate_c;
cg_en.xip <= '0';
xip_csn_o <= '1';
xip_clk_o <= '0';
xip_dat_o <= '0';
end generate;
-- External Wishbone Gateway (WISHBONE) ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_wishbone_inst_true:
if MEM_EXT_EN generate
neorv32_wishbone_inst: entity neorv32.neorv32_wishbone
generic map (
BUS_TIMEOUT => MEM_EXT_TIMEOUT,
PIPE_MODE => MEM_EXT_PIPE_MODE,
BIG_ENDIAN => MEM_EXT_BIG_ENDIAN,
ASYNC_RX => MEM_EXT_ASYNC_RX,
ASYNC_TX => MEM_EXT_ASYNC_TX
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => xbus_req,
bus_rsp_o => xbus_rsp,
--
wb_tag_o => wb_tag_o,
wb_adr_o => wb_adr_o,
wb_dat_i => wb_dat_i,
wb_dat_o => wb_dat_o,
wb_we_o => wb_we_o,
wb_sel_o => wb_sel_o,
wb_stb_o => wb_stb_o,
wb_cyc_o => wb_cyc_o,
wb_ack_i => wb_ack_i,
wb_err_i => wb_err_i
);
end generate;
neorv32_wishbone_inst_false:
if not MEM_EXT_EN generate
xbus_rsp <= rsp_terminate_c;
wb_adr_o <= (others => '0');
wb_dat_o <= (others => '0');
wb_we_o <= '0';
wb_sel_o <= (others => '0');
wb_stb_o <= '0';
wb_cyc_o <= '0';
wb_tag_o <= (others => '0');
end generate;
end generate; -- /memory_system
-- **************************************************************************************************************************
-- IO/Peripheral Modules
-- **************************************************************************************************************************
io_system:
if (true) generate
-- IO Switch ------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_bus_io_switch_inst: entity neorv32.neorv32_bus_io_switch
generic map (
DEV_SIZE => iodev_size_c, -- size of a single IO device
-- device port enable and base address --
DEV_00_EN => ON_CHIP_DEBUGGER_EN, DEV_00_BASE => base_io_dm_c,
DEV_01_EN => true, DEV_01_BASE => base_io_sysinfo_c, -- always enabled (mandatory core module)
DEV_02_EN => IO_NEOLED_EN, DEV_02_BASE => base_io_neoled_c,
DEV_03_EN => io_gpio_en_c, DEV_03_BASE => base_io_gpio_c,
DEV_04_EN => IO_WDT_EN, DEV_04_BASE => base_io_wdt_c,
DEV_05_EN => IO_TRNG_EN, DEV_05_BASE => base_io_trng_c,
DEV_06_EN => IO_TWI_EN, DEV_06_BASE => base_io_twi_c,
DEV_07_EN => IO_SPI_EN, DEV_07_BASE => base_io_spi_c,
DEV_08_EN => IO_SDI_EN, DEV_08_BASE => base_io_sdi_c,
DEV_09_EN => IO_UART1_EN, DEV_09_BASE => base_io_uart1_c,
DEV_10_EN => IO_UART0_EN, DEV_10_BASE => base_io_uart0_c,
DEV_11_EN => IO_MTIME_EN, DEV_11_BASE => base_io_mtime_c,
DEV_12_EN => io_xirq_en_c, DEV_12_BASE => base_io_xirq_c,
DEV_13_EN => IO_ONEWIRE_EN, DEV_13_BASE => base_io_onewire_c,
DEV_14_EN => IO_GPTMR_EN, DEV_14_BASE => base_io_gptmr_c,
DEV_15_EN => io_pwm_en_c, DEV_15_BASE => base_io_pwm_c,
DEV_16_EN => XIP_EN, DEV_16_BASE => base_io_xip_c,
DEV_17_EN => IO_CRC_EN, DEV_17_BASE => base_io_crc_c,
DEV_18_EN => IO_DMA_EN, DEV_18_BASE => base_io_dma_c,
DEV_19_EN => IO_SLINK_EN, DEV_19_BASE => base_io_slink_c,
DEV_20_EN => IO_CFS_EN, DEV_20_BASE => base_io_cfs_c
)
port map (
-- host port --
main_req_i => io_req,
main_rsp_o => io_rsp,
-- device ports --
dev_00_req_o => iodev_req(IODEV_OCD), dev_00_rsp_i => iodev_rsp(IODEV_OCD),
dev_01_req_o => iodev_req(IODEV_SYSINFO), dev_01_rsp_i => iodev_rsp(IODEV_SYSINFO),
dev_02_req_o => iodev_req(IODEV_NEOLED), dev_02_rsp_i => iodev_rsp(IODEV_NEOLED),
dev_03_req_o => iodev_req(IODEV_GPIO), dev_03_rsp_i => iodev_rsp(IODEV_GPIO),
dev_04_req_o => iodev_req(IODEV_WDT), dev_04_rsp_i => iodev_rsp(IODEV_WDT),
dev_05_req_o => iodev_req(IODEV_TRNG), dev_05_rsp_i => iodev_rsp(IODEV_TRNG),
dev_06_req_o => iodev_req(IODEV_TWI), dev_06_rsp_i => iodev_rsp(IODEV_TWI),
dev_07_req_o => iodev_req(IODEV_SPI), dev_07_rsp_i => iodev_rsp(IODEV_SPI),
dev_08_req_o => iodev_req(IODEV_SDI), dev_08_rsp_i => iodev_rsp(IODEV_SDI),
dev_09_req_o => iodev_req(IODEV_UART1), dev_09_rsp_i => iodev_rsp(IODEV_UART1),
dev_10_req_o => iodev_req(IODEV_UART0), dev_10_rsp_i => iodev_rsp(IODEV_UART0),
dev_11_req_o => iodev_req(IODEV_MTIME), dev_11_rsp_i => iodev_rsp(IODEV_MTIME),
dev_12_req_o => iodev_req(IODEV_XIRQ), dev_12_rsp_i => iodev_rsp(IODEV_XIRQ),
dev_13_req_o => iodev_req(IODEV_ONEWIRE), dev_13_rsp_i => iodev_rsp(IODEV_ONEWIRE),
dev_14_req_o => iodev_req(IODEV_GPTMR), dev_14_rsp_i => iodev_rsp(IODEV_GPTMR),
dev_15_req_o => iodev_req(IODEV_PWM), dev_15_rsp_i => iodev_rsp(IODEV_PWM),
dev_16_req_o => iodev_req(IODEV_XIP), dev_16_rsp_i => iodev_rsp(IODEV_XIP),
dev_17_req_o => iodev_req(IODEV_CRC), dev_17_rsp_i => iodev_rsp(IODEV_CRC),
dev_18_req_o => iodev_req(IODEV_DMA), dev_18_rsp_i => iodev_rsp(IODEV_DMA),
dev_19_req_o => iodev_req(IODEV_SLINK), dev_19_rsp_i => iodev_rsp(IODEV_SLINK),
dev_20_req_o => iodev_req(IODEV_CFS), dev_20_rsp_i => iodev_rsp(IODEV_CFS)
);
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cfs_inst_true:
if IO_CFS_EN generate
neorv32_cfs_inst: entity neorv32.neorv32_cfs
generic map (
CFS_CONFIG => IO_CFS_CONFIG,
CFS_IN_SIZE => IO_CFS_IN_SIZE,
CFS_OUT_SIZE => IO_CFS_OUT_SIZE
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_CFS),
bus_rsp_o => iodev_rsp(IODEV_CFS),
clkgen_en_o => cg_en.cfs,
clkgen_i => clk_gen,
irq_o => firq.cfs,
cfs_in_i => cfs_in_i,
cfs_out_o => cfs_out_o
);
end generate;
neorv32_cfs_inst_false:
if not IO_CFS_EN generate
iodev_rsp(IODEV_CFS) <= rsp_terminate_c;
cg_en.cfs <= '0';
firq.cfs <= '0';
cfs_out_o <= (others => '0');
end generate;
-- Serial Data Interface (SDI) ------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_sdi_inst_true:
if IO_SDI_EN generate
neorv32_sdi_inst: entity neorv32.neorv32_sdi
generic map (
RTX_FIFO => IO_SDI_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_SDI),
bus_rsp_o => iodev_rsp(IODEV_SDI),
sdi_csn_i => sdi_csn_i,
sdi_clk_i => sdi_clk_i,
sdi_dat_i => sdi_dat_i,
sdi_dat_o => sdi_dat_o,
irq_o => firq.sdi
);
end generate;
neorv32_sdi_inst_false:
if not IO_SDI_EN generate
iodev_rsp(IODEV_SDI) <= rsp_terminate_c;
sdi_dat_o <= '0';
firq.sdi <= '0';
end generate;
-- General Purpose Input/Output Port (GPIO) -----------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_gpio_inst_true:
if io_gpio_en_c generate
neorv32_gpio_inst: entity neorv32.neorv32_gpio
generic map (
GPIO_NUM => IO_GPIO_NUM
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_GPIO),
bus_rsp_o => iodev_rsp(IODEV_GPIO),
gpio_o => gpio_o,
gpio_i => gpio_i
);
end generate;
neorv32_gpio_inst_false:
if not io_gpio_en_c generate
iodev_rsp(IODEV_GPIO) <= rsp_terminate_c;
gpio_o <= (others => '0');
end generate;
-- Watch Dog Timer (WDT) ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_wdt_inst_true:
if IO_WDT_EN generate
neorv32_wdt_inst: entity neorv32.neorv32_wdt
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
rst_cause_i => rst_cause,
bus_req_i => iodev_req(IODEV_WDT),
bus_rsp_o => iodev_rsp(IODEV_WDT),
cpu_debug_i => cpu_debug,
cpu_sleep_i => cpu_sleep,
clkgen_en_o => cg_en.wdt,
clkgen_i => clk_gen,
irq_o => firq.wdt,
rstn_o => rstn_wdt
);
end generate;
neorv32_wdt_inst_false:
if not IO_WDT_EN generate
iodev_rsp(IODEV_WDT) <= rsp_terminate_c;
firq.wdt <= '0';
rstn_wdt <= '1';
cg_en.wdt <= '0';
end generate;
-- Machine System Timer (MTIME) -----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_mtime_inst_true:
if IO_MTIME_EN generate
neorv32_mtime_inst: entity neorv32.neorv32_mtime
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_MTIME),
bus_rsp_o => iodev_rsp(IODEV_MTIME),
time_o => mtime_time,
irq_o => mtime_irq
);
-- synchronize system time output LO --
mtime_sync: process(rstn_sys, clk_i)
begin
if (rstn_sys = '0') then
mtime_time_o(31 downto 0) <= (others => '0');
elsif rising_edge(clk_i) then
mtime_time_o(31 downto 0) <= mtime_time(31 downto 0);
end if;
end process mtime_sync;
-- system time output HI --
mtime_time_o(63 downto 32) <= mtime_time(63 downto 32);
end generate;
neorv32_mtime_inst_false:
if not IO_MTIME_EN generate
iodev_rsp(IODEV_MTIME) <= rsp_terminate_c;
mtime_irq <= mtime_irq_i;
mtime_time_o <= (others => '0');
end generate;
-- Primary Universal Asynchronous Receiver/Transmitter (UART0) ----------------------------
-- -------------------------------------------------------------------------------------------
neorv32_uart0_inst_true:
if IO_UART0_EN generate
neorv32_uart0_inst: entity neorv32.neorv32_uart
generic map (
SIM_LOG_FILE => "neorv32.uart0.sim_mode.text.out",
UART_RX_FIFO => IO_UART0_RX_FIFO,
UART_TX_FIFO => IO_UART0_TX_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_UART0),
bus_rsp_o => iodev_rsp(IODEV_UART0),
clkgen_en_o => cg_en.uart0,
clkgen_i => clk_gen,
uart_txd_o => uart0_txd_o,
uart_rxd_i => uart0_rxd_i,
uart_rts_o => uart0_rts_o,
uart_cts_i => uart0_cts_i,
irq_rx_o => firq.uart0_rx,
irq_tx_o => firq.uart0_tx
);
end generate;
neorv32_uart0_inst_false:
if not IO_UART0_EN generate
iodev_rsp(IODEV_UART0) <= rsp_terminate_c;
uart0_txd_o <= '0';
uart0_rts_o <= '1';
cg_en.uart0 <= '0';
firq.uart0_rx <= '0';
firq.uart0_tx <= '0';
end generate;
-- Secondary Universal Asynchronous Receiver/Transmitter (UART1) --------------------------
-- -------------------------------------------------------------------------------------------
neorv32_uart1_inst_true:
if IO_UART1_EN generate
neorv32_uart1_inst: entity neorv32.neorv32_uart
generic map (
SIM_LOG_FILE => "neorv32.uart1.sim_mode.text.out",
UART_RX_FIFO => IO_UART1_RX_FIFO,
UART_TX_FIFO => IO_UART1_TX_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_UART1),
bus_rsp_o => iodev_rsp(IODEV_UART1),
clkgen_en_o => cg_en.uart1,
clkgen_i => clk_gen,
uart_txd_o => uart1_txd_o,
uart_rxd_i => uart1_rxd_i,
uart_rts_o => uart1_rts_o,
uart_cts_i => uart1_cts_i,
irq_rx_o => firq.uart1_rx,
irq_tx_o => firq.uart1_tx
);
end generate;
neorv32_uart1_inst_false:
if not IO_UART1_EN generate
iodev_rsp(IODEV_UART1) <= rsp_terminate_c;
uart1_txd_o <= '0';
uart1_rts_o <= '1';
cg_en.uart1 <= '0';
firq.uart1_rx <= '0';
firq.uart1_tx <= '0';
end generate;
-- Serial Peripheral Interface (SPI) ------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_spi_inst_true:
if IO_SPI_EN generate
neorv32_spi_inst: entity neorv32.neorv32_spi
generic map (
IO_SPI_FIFO => IO_SPI_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_SPI),
bus_rsp_o => iodev_rsp(IODEV_SPI),
clkgen_en_o => cg_en.spi,
clkgen_i => clk_gen,
spi_clk_o => spi_clk_o,
spi_dat_o => spi_dat_o,
spi_dat_i => spi_dat_i,
spi_csn_o => spi_csn_o,
irq_o => firq.spi
);
end generate;
neorv32_spi_inst_false:
if not IO_SPI_EN generate
iodev_rsp(IODEV_SPI) <= rsp_terminate_c;
spi_clk_o <= '0';
spi_dat_o <= '0';
spi_csn_o <= (others => '1');
cg_en.spi <= '0';
firq.spi <= '0';
end generate;
-- Two-Wire Interface (TWI) ---------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_twi_inst_true:
if IO_TWI_EN generate
neorv32_twi_inst: entity neorv32.neorv32_twi
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_TWI),
bus_rsp_o => iodev_rsp(IODEV_TWI),
clkgen_en_o => cg_en.twi,
clkgen_i => clk_gen,
twi_sda_i => twi_sda_i,
twi_sda_o => twi_sda_o,
twi_scl_i => twi_scl_i,
twi_scl_o => twi_scl_o,
irq_o => firq.twi
);
end generate;
neorv32_twi_inst_false:
if not IO_TWI_EN generate
iodev_rsp(IODEV_TWI) <= rsp_terminate_c;
twi_sda_o <= '1';
twi_scl_o <= '1';
cg_en.twi <= '0';
firq.twi <= '0';
end generate;
-- Pulse-Width Modulation Controller (PWM) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_pwm_inst_true:
if io_pwm_en_c generate
neorv32_pwm_inst: entity neorv32.neorv32_pwm
generic map (
NUM_CHANNELS => IO_PWM_NUM_CH
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_PWM),
bus_rsp_o => iodev_rsp(IODEV_PWM),
clkgen_en_o => cg_en.pwm,
clkgen_i => clk_gen,
pwm_o => pwm_o
);
end generate;
neorv32_pwm_inst_false:
if not io_pwm_en_c generate
iodev_rsp(IODEV_PWM) <= rsp_terminate_c;
cg_en.pwm <= '0';
pwm_o <= (others => '0');
end generate;
-- True Random Number Generator (TRNG) ----------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_trng_inst_true:
if IO_TRNG_EN generate
neorv32_trng_inst: entity neorv32.neorv32_trng
generic map (
IO_TRNG_FIFO => IO_TRNG_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_TRNG),
bus_rsp_o => iodev_rsp(IODEV_TRNG),
irq_o => firq.trng
);
end generate;
neorv32_trng_inst_false:
if not IO_TRNG_EN generate
iodev_rsp(IODEV_TRNG) <= rsp_terminate_c;
firq.trng <= '0';
end generate;
-- Smart LED (WS2811/WS2812) Interface (NEOLED) -------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_neoled_inst_true:
if IO_NEOLED_EN generate
neorv32_neoled_inst: entity neorv32.neorv32_neoled
generic map (
FIFO_DEPTH => IO_NEOLED_TX_FIFO
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_NEOLED),
bus_rsp_o => iodev_rsp(IODEV_NEOLED),
clkgen_en_o => cg_en.neoled,
clkgen_i => clk_gen,
irq_o => firq.neoled,
neoled_o => neoled_o
);
end generate;
neorv32_neoled_inst_false:
if not IO_NEOLED_EN generate
iodev_rsp(IODEV_NEOLED) <= rsp_terminate_c;
cg_en.neoled <= '0';
firq.neoled <= '0';
neoled_o <= '0';
end generate;
-- External Interrupt Controller (XIRQ) ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_xirq_inst_true:
if io_xirq_en_c generate
neorv32_xirq_inst: entity neorv32.neorv32_xirq
generic map (
XIRQ_NUM_CH => XIRQ_NUM_CH,
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE,
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY
)
port map (
-- host access --
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_XIRQ),
bus_rsp_o => iodev_rsp(IODEV_XIRQ),
xirq_i => xirq_i,
cpu_irq_o => firq.xirq
);
end generate;
neorv32_xirq_inst_false:
if not io_xirq_en_c generate
iodev_rsp(IODEV_XIRQ) <= rsp_terminate_c;
firq.xirq <= '0';
end generate;
-- General Purpose Timer (GPTMR) ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_gptmr_inst_true:
if IO_GPTMR_EN generate
neorv32_gptmr_inst: entity neorv32.neorv32_gptmr
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_GPTMR),
bus_rsp_o => iodev_rsp(IODEV_GPTMR),
clkgen_en_o => cg_en.gptmr,
clkgen_i => clk_gen,
irq_o => firq.gptmr,
capture_i => gptmr_trig_i
);
end generate;
neorv32_gptmr_inst_false:
if not IO_GPTMR_EN generate
iodev_rsp(IODEV_GPTMR) <= rsp_terminate_c;
cg_en.gptmr <= '0';
firq.gptmr <= '0';
end generate;
-- 1-Wire Interface Controller (ONEWIRE) --------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_onewire_inst_true:
if IO_ONEWIRE_EN generate
neorv32_onewire_inst: entity neorv32.neorv32_onewire
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_ONEWIRE),
bus_rsp_o => iodev_rsp(IODEV_ONEWIRE),
clkgen_en_o => cg_en.onewire,
clkgen_i => clk_gen,
onewire_i => onewire_i,
onewire_o => onewire_o,
irq_o => firq.onewire
);
end generate;
neorv32_onewire_inst_false:
if not IO_ONEWIRE_EN generate
iodev_rsp(IODEV_ONEWIRE) <= rsp_terminate_c;
onewire_o <= '1';
cg_en.onewire <= '0';
firq.onewire <= '0';
end generate;
-- Stream Link Interface (SLINK) ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_slink_inst_true:
if IO_SLINK_EN generate
neorv32_slink_inst: entity neorv32.neorv32_slink
generic map (
SLINK_RX_FIFO => IO_SLINK_RX_FIFO,
SLINK_TX_FIFO => IO_SLINK_TX_FIFO
)
port map (
-- Host access --
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_SLINK),
bus_rsp_o => iodev_rsp(IODEV_SLINK),
irq_o => firq.slink,
-- RX stream interface --
slink_rx_data_i => slink_rx_dat_i,
slink_rx_valid_i => slink_rx_val_i,
slink_rx_last_i => slink_rx_lst_i,
slink_rx_ready_o => slink_rx_rdy_o,
-- TX stream interface --
slink_tx_data_o => slink_tx_dat_o,
slink_tx_valid_o => slink_tx_val_o,
slink_tx_last_o => slink_tx_lst_o,
slink_tx_ready_i => slink_tx_rdy_i
);
end generate;
neorv32_slink_inst_false:
if not IO_SLINK_EN generate
iodev_rsp(IODEV_SLINK) <= rsp_terminate_c;
firq.slink <= '0';
slink_rx_rdy_o <= '0';
slink_tx_dat_o <= (others => '0');
slink_tx_val_o <= '0';
slink_tx_lst_o <= '0';
end generate;
-- Cyclic Redundancy Check Unit (CRC) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_crc_inst_true:
if IO_CRC_EN generate
neorv32_crc_inst: entity neorv32.neorv32_crc
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_CRC),
bus_rsp_o => iodev_rsp(IODEV_CRC)
);
end generate;
neorv32_crc_inst_false:
if not IO_CRC_EN generate
iodev_rsp(IODEV_CRC) <= rsp_terminate_c;
end generate;
-- System Configuration Information Memory (SYSINFO) --------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_sysinfo_inst: entity neorv32.neorv32_sysinfo
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY,
CLOCK_GATING_EN => CLOCK_GATING_EN,
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN,
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN,
MEM_INT_IMEM_SIZE => imem_size_c,
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN,
MEM_INT_DMEM_SIZE => dmem_size_c,
-- Reservation Set Granularity --
AMO_RVS_GRANULARITY => AMO_RVS_GRANULARITY,
-- Instruction cache --
ICACHE_EN => ICACHE_EN,
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS,
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE,
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY,
-- Data cache --
DCACHE_EN => DCACHE_EN,
DCACHE_NUM_BLOCKS => DCACHE_NUM_BLOCKS,
DCACHE_BLOCK_SIZE => DCACHE_BLOCK_SIZE,
-- External memory interface --
MEM_EXT_EN => MEM_EXT_EN,
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN,
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN,
-- Processor peripherals --
IO_GPIO_EN => io_gpio_en_c,
IO_MTIME_EN => IO_MTIME_EN,
IO_UART0_EN => IO_UART0_EN,
IO_UART1_EN => IO_UART1_EN,
IO_SPI_EN => IO_SPI_EN,
IO_SDI_EN => IO_SDI_EN,
IO_TWI_EN => IO_TWI_EN,
IO_PWM_EN => io_pwm_en_c,
IO_WDT_EN => IO_WDT_EN,
IO_TRNG_EN => IO_TRNG_EN,
IO_CFS_EN => IO_CFS_EN,
IO_NEOLED_EN => IO_NEOLED_EN,
IO_XIRQ_EN => io_xirq_en_c,
IO_GPTMR_EN => IO_GPTMR_EN,
XIP_EN => XIP_EN,
IO_ONEWIRE_EN => IO_ONEWIRE_EN,
IO_DMA_EN => IO_DMA_EN,
IO_SLINK_EN => IO_SLINK_EN,
IO_CRC_EN => IO_CRC_EN
)
port map (
clk_i => clk_i,
rstn_i => rstn_sys,
bus_req_i => iodev_req(IODEV_SYSINFO),
bus_rsp_o => iodev_rsp(IODEV_SYSINFO)
);
end generate; -- /io_system
-- **************************************************************************************************************************
-- On-Chip Debugger Complex
-- **************************************************************************************************************************
neorv32_neorv32_ocd_inst_true:
if ON_CHIP_DEBUGGER_EN generate
-- On-Chip Debugger - Debug Transport Module (DTM) ----------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_debug_dtm_inst: entity neorv32.neorv32_debug_dtm
generic map (
IDCODE_VERSION => (others => '0'),
IDCODE_PARTID => (others => '0'),
IDCODE_MANID => (others => '0')
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_ext,
-- jtag connection --
jtag_trst_i => jtag_trst_i,
jtag_tck_i => jtag_tck_i,
jtag_tdi_i => jtag_tdi_i,
jtag_tdo_o => jtag_tdo_o,
jtag_tms_i => jtag_tms_i,
-- debug module interface (DMI) --
dmi_req_o => dmi_req,
dmi_rsp_i => dmi_rsp
);
-- On-Chip Debugger - Debug Module (DM) ---------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_debug_dm_inst: entity neorv32.neorv32_debug_dm
generic map (
CPU_BASE_ADDR => base_io_dm_c,
LEGACY_MODE => DM_LEGACY_MODE
)
port map (
-- global control --
clk_i => clk_i,
rstn_i => rstn_ext,
cpu_debug_i => cpu_debug,
-- debug module interface (DMI) --
dmi_req_i => dmi_req,
dmi_rsp_o => dmi_rsp,
-- CPU bus access --
bus_req_i => iodev_req(IODEV_OCD),
bus_rsp_o => iodev_rsp(IODEV_OCD),
-- CPU control --
cpu_ndmrstn_o => dci_ndmrstn,
cpu_halt_req_o => dci_halt_req
);
end generate;
neorv32_debug_ocd_inst_false:
if not ON_CHIP_DEBUGGER_EN generate
iodev_rsp(IODEV_OCD) <= rsp_terminate_c;
jtag_tdo_o <= jtag_tdi_i; -- JTAG feed-through
dci_ndmrstn <= '1';
dci_halt_req <= '0';
end generate;
end neorv32_top_rtl;