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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/rtl
    from Rev 62 to Rev 63
    Reverse comparison

Rev 62 → Rev 63

/templates/README.md File deleted
/core/neorv32_bootloader_image.vhd
154,13 → 154,13
00000140 => x"ffff1537",
00000141 => x"f5c50513",
00000142 => x"285000ef",
00000143 => x"fc002573",
00000144 => x"208000ef",
00000145 => x"ffff1537",
00000146 => x"f6450513",
00000147 => x"271000ef",
00000148 => x"fe802503",
00000149 => x"ffff1437",
00000143 => x"fe402503",
00000144 => x"ffff1437",
00000145 => x"204000ef",
00000146 => x"ffff1537",
00000147 => x"f6450513",
00000148 => x"26d000ef",
00000149 => x"fe802503",
00000150 => x"1f0000ef",
00000151 => x"ffff1537",
00000152 => x"f6c50513",
985,8 → 985,8
00000971 => x"0a3e3e20",
00000972 => x"444c420a",
00000973 => x"41203a56",
00000974 => x"20206775",
00000975 => x"30322038",
00000974 => x"31206775",
00000975 => x"30322039",
00000976 => x"480a3132",
00000977 => x"203a5657",
00000978 => x"00000020",
/core/neorv32_cpu.vhd
4,16 → 4,20
-- # NEORV32 CPU: #
-- # * neorv32_cpu.vhd - CPU top entity #
-- # * neorv32_cpu_alu.vhd - Arithmetic/logic unit #
-- # * neorv32_cpu_cp_bitmanip.vhd - Bit-manipulation co-processor #
-- # * neorv32_cpu_cp_fpu.vhd - Single-precision FPU co-processor #
-- # * neorv32_cpu_cp_muldiv.vhd - Integer multiplier/divider co-processor #
-- # * neorv32_cpu_cp_shifter.vhd - Base ISA shifter unit #
-- # * neorv32_cpu_bus.vhd - Instruction and data bus interface unit #
-- # * neorv32_cpu_cp_bitmanip.vhd - Bit-manipulation co-processor ('B') #
-- # * neorv32_cpu_cp_fpu.vhd - Single-precision FPU co-processor ('Zfinx') #
-- # * neorv32_cpu_cp_muldiv.vhd - Integer multiplier/divider co-processor ('M') #
-- # * neorv32_cpu_ctrl.vhd - CPU control and CSR system #
-- # * neorv32_cpu_control.vhd - CPU control and CSR system #
-- # * neorv32_cpu_decompressor.vhd - Compressed instructions decoder #
-- # * neorv32_cpu_regfile.vhd - Data register file #
-- # * neorv32_package.vhd - Main CPU & Processor package file #
-- # #
-- # Check out the processor's data sheet for more information: docs/NEORV32.pdf #
-- # Check out the CPU'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 #
-- # #
65,6 → 69,7
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
168,6 → 173,7
cond_sel_string_f(CPU_EXTENSION_RISCV_A, "A", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_C, "C", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_U, "U", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zbb, "_Zbb", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zicsr, "_Zicsr", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zifencei, "_Zifencei", "") &
cond_sel_string_f(CPU_EXTENSION_RISCV_Zfinx, "_Zfinx", "") &
201,7 → 207,7
assert not (cp_timeout_en_c = true) report "NEORV32 CPU CONFIG WARNING! Co-processor timeout counter enabled. This should be used for debugging/simulation only." severity warning;
 
-- PMP regions check --
assert not (PMP_NUM_REGIONS > 64) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions <PMP_NUM_REGIONS> out xf valid range (0..64)." severity error;
assert not (PMP_NUM_REGIONS > 64) report "NEORV32 CPU CONFIG ERROR! Number of PMP regions <PMP_NUM_REGIONS> out of valid range (0..64)." severity error;
-- PMP granularity --
assert not ((is_power_of_two_f(PMP_MIN_GRANULARITY) = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be a power of two." severity error;
assert not ((PMP_MIN_GRANULARITY < 8) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be >= 8 bytes." severity error;
215,12 → 221,18
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (HPM_NUM_CNTS > 0)) report "NEORV32 CPU CONFIG ERROR! Hardware performance monitors (HPM) require <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- Mul-extension --
assert not ((CPU_EXTENSION_RISCV_Zmmul = true) and (CPU_EXTENSION_RISCV_M = true)) report "NEORV32 CPU CONFIG ERROR! <M> and <ZMMUL> extensions cannot co-exist!" severity error;
assert not ((CPU_EXTENSION_RISCV_Zmmul = true) and (CPU_EXTENSION_RISCV_M = true)) report "NEORV32 CPU CONFIG ERROR! <M> and <Zmmul> extensions cannot co-exist!" severity error;
 
-- Debug mode --
assert not ((CPU_EXTENSION_RISCV_DEBUG = true) and (CPU_EXTENSION_RISCV_Zicsr = false)) report "NEORV32 CPU CONFIG ERROR! Debug mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error;
 
-- fast multiplication option --
assert not (FAST_MUL_EN = true) report "NEORV32 CPU CONFIG NOTE: <FAST_MUL_EN> set. Trying to use DSP blocks for base ISA multiplications." severity note;
 
-- fast shift option --
assert not (FAST_SHIFT_EN = true) report "NEORV32 CPU CONFIG NOTE: <FAST_SHIFT_EN> set. Implementing full-parallel logic / barrel shifters." severity note;
 
 
-- Control Unit ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_control_inst: neorv32_cpu_control
235,6 → 247,7
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
327,6 → 340,7
generic map (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
/core/neorv32_cpu_alu.vhd
45,6 → 45,7
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
278,12 → 279,37
end generate;
 
 
-- Co-Processor 2: reserved ---------------------------------------------------------------
-- Co-Processor 2: Bit-Manipulation Unit ('Zbb' Extension) --------------------------------
-- -------------------------------------------------------------------------------------------
cp_result(2) <= (others => '0');
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access
neorv32_cpu_cp_bitmanip_inst_true:
if (CPU_EXTENSION_RISCV_Zbb = true) generate
neorv32_cpu_cp_bitmanip_inst: neorv32_cpu_cp_bitmanip
generic map (
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
ctrl_i => ctrl_i, -- main control bus
start_i => cp_start(2), -- trigger operation
-- data input --
cmp_i => cmp_i, -- comparator status
rs1_i => rs1_i, -- rf source 1
rs2_i => rs2_i, -- rf source 2
-- result and status --
res_o => cp_result(2), -- operation result
valid_o => cp_valid(2) -- data output valid
);
end generate;
 
neorv32_cpu_cp_bitmanip_inst_false:
if (CPU_EXTENSION_RISCV_Zbb = false) generate
cp_result(2) <= (others => '0');
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access
end generate;
 
 
-- Co-Processor 3: Single-Precision Floating-Point Unit ('Zfinx' Extension) ---------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_cp_fpu_inst_true:
/core/neorv32_cpu_control.vhd
57,6 → 57,7
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
184,14 → 185,16
 
-- instruction decoding helper logic --
type decode_aux_t is record
alu_immediate : std_ulogic;
rs1_is_r0 : std_ulogic;
is_atomic_lr : std_ulogic;
is_atomic_sc : std_ulogic;
is_float_op : std_ulogic;
sys_env_cmd : std_ulogic_vector(11 downto 0);
is_m_mul : std_ulogic;
is_m_div : std_ulogic;
alu_immediate : std_ulogic;
rs1_is_r0 : std_ulogic;
is_atomic_lr : std_ulogic;
is_atomic_sc : std_ulogic;
is_float_op : std_ulogic;
sys_env_cmd : std_ulogic_vector(11 downto 0);
is_m_mul : std_ulogic;
is_m_div : std_ulogic;
is_bitmanip_imm : std_ulogic;
is_bitmanip_reg : std_ulogic;
end record;
signal decode_aux : decode_aux_t;
 
237,7 → 240,7
cause : std_ulogic_vector(6 downto 0); -- trap ID for mcause CSR
cause_nxt : std_ulogic_vector(6 downto 0);
db_irq_fire : std_ulogic; -- set if there is a valid IRQ source in the "enter debug mode" trap buffer
db_irq_en : std_ulogic; -- set if IRQs are allowed in debu mode
db_irq_en : std_ulogic; -- set if IRQs are allowed in debug mode
--
env_start : std_ulogic; -- start trap handler env
env_start_ack : std_ulogic; -- start of trap handler acknowledged
275,7 → 278,6
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr write data
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data
--
mstatus_fs : std_ulogic; -- mstatus.FS: FPU status (single-bit, only OFF and DIRTY states)
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/W)
mstatus_mpp : std_ulogic_vector(1 downto 0); -- mstatus.MPP: machine previous privilege mode
815,13 → 817,15
variable sys_env_cmd_mask_v : std_ulogic_vector(11 downto 0);
begin
-- defaults --
decode_aux.alu_immediate <= '0';
decode_aux.rs1_is_r0 <= '0';
decode_aux.is_atomic_lr <= '0';
decode_aux.is_atomic_sc <= '0';
decode_aux.is_float_op <= '0';
decode_aux.is_m_mul <= '0';
decode_aux.is_m_div <= '0';
decode_aux.alu_immediate <= '0';
decode_aux.rs1_is_r0 <= '0';
decode_aux.is_atomic_lr <= '0';
decode_aux.is_atomic_sc <= '0';
decode_aux.is_float_op <= '0';
decode_aux.is_m_mul <= '0';
decode_aux.is_m_div <= '0';
decode_aux.is_bitmanip_imm <= '0';
decode_aux.is_bitmanip_reg <= '0';
 
-- is immediate ALU operation? --
decode_aux.alu_immediate <= not execute_engine.i_reg(instr_opcode_msb_c-1);
835,6 → 839,37
decode_aux.is_atomic_sc <= execute_engine.i_reg(instr_funct5_lsb_c);
end if;
 
-- is BITMANIP instruction? --
-- pretty complex as we have to extract this from the ALU/ALUI instruction space --
-- immediate operation --
if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110000") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "001") and
(
(execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00000") or -- CLZ
(execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00001") or -- CTZ
(execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00010") or -- CPOP
(execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00100") or -- SEXT.B
(execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00101") -- SEXT.H
)
) or
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110000") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "101")) or -- RORI
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "101") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "00111")) or -- ORCB
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "101") and (execute_engine.i_reg(instr_funct12_lsb_c+4 downto instr_funct12_lsb_c) = "11000")) then -- REV8
decode_aux.is_bitmanip_imm <= '1';
end if;
-- register operation --
if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0110000") and (execute_engine.i_reg(instr_funct3_msb_c-1 downto instr_funct3_lsb_c) = "01")) or -- ROR / ROL
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000101") and (execute_engine.i_reg(instr_funct3_msb_c) = '1')) or -- MIN[U] / MAX[U]
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000100") and (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100")) or -- ZEXTH
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0100000") and
(
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "111") or -- ANDN
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") or -- ORN
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") -- XORN
)
) then
decode_aux.is_bitmanip_reg <= '1';
end if;
 
-- floating-point operations (Zfinx) --
if ((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+3) = "0000")) or -- FADD.S / FSUB.S
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c+2) = "00010")) or -- FMUL.S
952,7 → 987,7
end if;
 
 
when TRAP_ENTER => -- Start trap environment - get TVEC, stay here for sleep mode
when TRAP_ENTER => -- Start trap environment - get xTVEC, stay here for sleep mode
-- ------------------------------------------------------------
if (trap_ctrl.env_start = '1') then -- trap triggered?
trap_ctrl.env_start_ack <= '1';
959,12 → 994,12
execute_engine.state_nxt <= TRAP_EXECUTE;
end if;
 
when TRAP_EXIT => -- Return from trap environment - get EPC
when TRAP_EXIT => -- Return from trap environment - get xEPC
-- ------------------------------------------------------------
trap_ctrl.env_end <= '1';
execute_engine.state_nxt <= TRAP_EXECUTE;
 
when TRAP_EXECUTE => -- Start trap environment -> jump to *TVEC / return from trap environment -> jump to EPC
when TRAP_EXECUTE => -- Start trap environment -> jump to xTVEC / return from trap environment -> jump to xEPC
-- ------------------------------------------------------------
execute_engine.pc_mux_sel <= '0'; -- next_PC
fetch_engine.reset <= '1';
1013,6 → 1048,12
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
-- co-processor bit manipulation operation? --
elsif (CPU_EXTENSION_RISCV_Zbb = true) and
(((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- register operation
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) then -- immediate operation
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- use BITMANIP CP
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
else
-- ALU operation, function select --
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_shifter_c; -- use SHIFTER CP (only relevant for shift operations)
1030,7 → 1071,11
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or -- SLL shift operation?
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) or -- SR shift operation?
((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) or -- MUL
((CPU_EXTENSION_RISCV_Zbb = true) and (
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (decode_aux.is_bitmanip_reg = '1')) or -- BITMANIP CP register operation?
((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) -- BITMANIP CP immediate operation?
) then
execute_engine.state_nxt <= ALU_WAIT;
else -- single cycle ALU operation
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
1100,7 → 1145,7
 
when opcode_fop_c => -- floating-point operations
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zfinx = true) and (decode_aux.is_float_op = '1') and (csr.mstatus_fs = '1') then
if (CPU_EXTENSION_RISCV_Zfinx = true) and (decode_aux.is_float_op = '1') then
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- trigger FPU CP
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
execute_engine.state_nxt <= ALU_WAIT;
1123,7 → 1168,7
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- EBREAK
when funct12_wfi_c => execute_engine.sleep_nxt <= '1'; -- WFI
when funct12_mret_c => -- MRET
if (CPU_EXTENSION_RISCV_U = true) and (csr.priv_m_mode = '1') then -- only allowed in M-mode
if (csr.priv_m_mode = '1') then -- only allowed in M-mode
execute_engine.state_nxt <= TRAP_EXIT;
else
NULL;
1284,7 → 1329,7
 
-- floating-point CSRs --
when csr_fflags_c | csr_frm_c | csr_fcsr_c =>
if (CPU_EXTENSION_RISCV_Zfinx = true) and (csr.mstatus_fs = '1') then -- FPU implemented and enabled?
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented?
csr_acc_valid <= '1'; -- full access for everyone
else
NULL;
1296,8 → 1341,8
when csr_mip_c | csr_mtval_c => -- NOTE: MIP and MTVAL are read-only in the NEORV32!
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
 
-- physical memory protection (PMP) - address & configuration --
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c |
-- physical memory protection (PMP) --
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c | -- address
csr_pmpaddr8_c | csr_pmpaddr9_c | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c |
csr_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c |
csr_pmpaddr24_c | csr_pmpaddr25_c | csr_pmpaddr26_c | csr_pmpaddr27_c | csr_pmpaddr28_c | csr_pmpaddr29_c | csr_pmpaddr30_c | csr_pmpaddr31_c |
1305,7 → 1350,7
csr_pmpaddr40_c | csr_pmpaddr41_c | csr_pmpaddr42_c | csr_pmpaddr43_c | csr_pmpaddr44_c | csr_pmpaddr45_c | csr_pmpaddr46_c | csr_pmpaddr47_c |
csr_pmpaddr48_c | csr_pmpaddr49_c | csr_pmpaddr50_c | csr_pmpaddr51_c | csr_pmpaddr52_c | csr_pmpaddr53_c | csr_pmpaddr54_c | csr_pmpaddr55_c |
csr_pmpaddr56_c | csr_pmpaddr57_c | csr_pmpaddr58_c | csr_pmpaddr59_c | csr_pmpaddr60_c | csr_pmpaddr61_c | csr_pmpaddr62_c | csr_pmpaddr63_c |
csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c |
csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c | -- configuration
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c =>
if (PMP_NUM_REGIONS > 0) then
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
1357,14 → 1402,14
csr_acc_valid <= csr.priv_m_mode; -- M-mode only
 
 
-- machine information registers & custom (NEORV32-specific) read-only CSRs --
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c | csr_mzext_c =>
-- machine information registers, read-only --
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c =>
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only
 
-- debug mode CSRs --
when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c =>
if (CPU_EXTENSION_RISCV_DEBUG = true) then
csr_acc_valid <= debug_ctrl.running; -- access in only in debug-mode
csr_acc_valid <= debug_ctrl.running; -- access only in debug-mode
else
NULL;
end if;
1417,6 → 1462,10
if (CPU_EXTENSION_RISCV_M = false) then -- not implemented
illegal_instruction <= '1';
end if;
elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
illegal_instruction <= '1';
end if;
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and -- ADD/SUB or SRA/SRL check
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
1433,7 → 1482,11
 
when opcode_alui_c => -- check ALUI.funct7
-- ------------------------------------------------------------
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
illegal_instruction <= '1';
end if;
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000")) or -- shift logical left
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
1544,9 → 1597,9
(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ecall_c) or -- ECALL
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c)and (CPU_EXTENSION_RISCV_U = true) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode)
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = (funct12_dret_c)) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode)
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0
illegal_instruction <= '0';
else
illegal_instruction <= '1';
1567,7 → 1620,7
 
when opcode_fop_c => -- floating point operations - single/dual operands
-- ------------------------------------------------------------
if (CPU_EXTENSION_RISCV_Zfinx = true) and (csr.mstatus_fs = '1') and -- F extension implemented and enabled
if (CPU_EXTENSION_RISCV_Zfinx = true) and -- F extension implemented
(execute_engine.i_reg(instr_funct7_lsb_c+1 downto instr_funct7_lsb_c) = float_single_c) and -- single-precision operations only
(decode_aux.is_float_op = '1') then -- is correct/supported floating-point instruction
illegal_instruction <= '0';
1603,7 → 1656,6
begin
if (rstn_i = '0') then
trap_ctrl.exc_buf <= (others => '0');
trap_ctrl.exc_buf(exception_db_break_c) <= '0'; -- enter debug mode
trap_ctrl.irq_buf <= (others => def_rst_val_c);
trap_ctrl.irq_buf(interrupt_nm_irq_c) <= '0'; -- NMI
trap_ctrl.irq_buf(interrupt_db_halt_c) <= '0'; -- enter debug mode
1922,7 → 1974,6
csr.we <= '0';
--
csr.mstatus_mie <= '0';
csr.mstatus_fs <= '0';
csr.mstatus_mpie <= '0';
csr.mstatus_mpp <= (others => '0');
csr.mstatus_tw <= '0';
1990,9 → 2041,9
 
-- machine trap setup --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_class_setup_c) then -- trap setup CSR class
if (csr.addr(11 downto 3) = csr_class_setup_c) then -- trap setup CSR class
-- R/W: mstatus - machine status register --
if (csr.addr(3 downto 0) = csr_mstatus_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mstatus_c(2 downto 0)) then
csr.mstatus_mie <= csr.wdata(03);
csr.mstatus_mpie <= csr.wdata(07);
if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented
2000,12 → 2051,9
csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12);
csr.mstatus_tw <= csr.wdata(21);
end if;
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented
csr.mstatus_fs <= csr.wdata(14) or csr.wdata(13);
end if;
end if;
-- R/W: mie - machine interrupt enable register --
if (csr.addr(3 downto 0) = csr_mie_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mie_c(2 downto 0)) then
csr.mie_msie <= csr.wdata(03); -- machine SW IRQ enable
csr.mie_mtie <= csr.wdata(07); -- machine TIMER IRQ enable
csr.mie_meie <= csr.wdata(11); -- machine EXT IRQ enable
2014,12 → 2062,12
end loop; -- i
end if;
-- R/W: mtvec - machine trap-handler base address (for ALL exceptions) --
if (csr.addr(3 downto 0) = csr_mtvec_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mtvec_c(2 downto 0)) then
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
end if;
-- R/W: machine counter enable register --
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
if (csr.addr(3 downto 0) = csr_mcounteren_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mcounteren_c(2 downto 0)) then
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h]
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h]
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
2029,17 → 2077,17
 
-- machine trap handling --
-- --------------------------------------------------------------------
if (csr.addr(11 downto 4) = csr_class_trap_c) then -- machine trap handling CSR class
if (csr.addr(11 downto 3) = csr_class_trap_c) then -- machine trap handling CSR class
-- R/W: mscratch - machine scratch register --
if (csr.addr(3 downto 0) = csr_mscratch_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mscratch_c(2 downto 0)) then
csr.mscratch <= csr.wdata;
end if;
-- R/W: mepc - machine exception program counter --
if (csr.addr(3 downto 0) = csr_mepc_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mepc_c(2 downto 0)) then
csr.mepc <= csr.wdata(data_width_c-1 downto 1) & '0';
end if;
-- R/W: mcause - machine trap cause --
if (csr.addr(3 downto 0) = csr_mcause_c(3 downto 0)) then
if (csr.addr(2 downto 0) = csr_mcause_c(2 downto 0)) then
csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: interrupt, 0: exception
csr.mcause(4 downto 0) <= csr.wdata(4 downto 0); -- identifier
end if;
2087,7 → 2135,9
if (csr.addr(4 downto 0) = csr_mcountinhibit_c(4 downto 0)) then
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
if (HPM_NUM_CNTS > 0) then -- any HPMs available?
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
end if;
end if;
-- machine performance-monitors event selector --
if (HPM_NUM_CNTS > 0) then
2263,9 → 2313,8
 
-- floating-point extension disabled --
if (CPU_EXTENSION_RISCV_Zfinx = false) then
csr.mstatus_fs <= '0';
csr.fflags <= (others => '0');
csr.frm <= (others => '0');
csr.fflags <= (others => '0');
csr.frm <= (others => '0');
end if;
 
-- debug mode disabled --
2511,10 → 2560,7
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
csr.rdata(11) <= csr.mstatus_mpp(0); -- MPP: machine previous privilege mode low
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
csr.rdata(13) <= csr.mstatus_fs; -- FS(0): FPU status - OFF or DIRTY
csr.rdata(14) <= csr.mstatus_fs; -- FS(1): FPU status - OFF or DIRTY
csr.rdata(21) <= csr.mstatus_tw; -- TW: WFI timeout wait
csr.rdata(31) <= csr.mstatus_fs; -- SD: state dirty (only FPU yet)
when csr_misa_c => -- misa (r/-): ISA and extensions
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
2562,91 → 2608,91
csr.rdata(16+i) <= trap_ctrl.irq_buf(interrupt_firq_0_c+i);
end loop; -- i
 
-- physical memory protection - configuration --
-- physical memory protection - configuration (r/w) --
-- --------------------------------------------------------------------
when csr_pmpcfg0_c => if (PMP_NUM_REGIONS > 00) then csr.rdata <= csr.pmpcfg_rd(03) & csr.pmpcfg_rd(02) & csr.pmpcfg_rd(01) & csr.pmpcfg_rd(00); else NULL; end if; -- R/W: pmpcfg0
when csr_pmpcfg1_c => if (PMP_NUM_REGIONS > 03) then csr.rdata <= csr.pmpcfg_rd(07) & csr.pmpcfg_rd(06) & csr.pmpcfg_rd(05) & csr.pmpcfg_rd(04); else NULL; end if; -- R/W: pmpcfg1
when csr_pmpcfg2_c => if (PMP_NUM_REGIONS > 07) then csr.rdata <= csr.pmpcfg_rd(11) & csr.pmpcfg_rd(10) & csr.pmpcfg_rd(09) & csr.pmpcfg_rd(08); else NULL; end if; -- R/W: pmpcfg2
when csr_pmpcfg3_c => if (PMP_NUM_REGIONS > 11) then csr.rdata <= csr.pmpcfg_rd(15) & csr.pmpcfg_rd(14) & csr.pmpcfg_rd(13) & csr.pmpcfg_rd(12); else NULL; end if; -- R/W: pmpcfg3
when csr_pmpcfg4_c => if (PMP_NUM_REGIONS > 15) then csr.rdata <= csr.pmpcfg_rd(19) & csr.pmpcfg_rd(18) & csr.pmpcfg_rd(17) & csr.pmpcfg_rd(16); else NULL; end if; -- R/W: pmpcfg4
when csr_pmpcfg5_c => if (PMP_NUM_REGIONS > 19) then csr.rdata <= csr.pmpcfg_rd(23) & csr.pmpcfg_rd(22) & csr.pmpcfg_rd(21) & csr.pmpcfg_rd(20); else NULL; end if; -- R/W: pmpcfg5
when csr_pmpcfg6_c => if (PMP_NUM_REGIONS > 23) then csr.rdata <= csr.pmpcfg_rd(27) & csr.pmpcfg_rd(26) & csr.pmpcfg_rd(25) & csr.pmpcfg_rd(24); else NULL; end if; -- R/W: pmpcfg6
when csr_pmpcfg7_c => if (PMP_NUM_REGIONS > 27) then csr.rdata <= csr.pmpcfg_rd(31) & csr.pmpcfg_rd(30) & csr.pmpcfg_rd(29) & csr.pmpcfg_rd(28); else NULL; end if; -- R/W: pmpcfg7
when csr_pmpcfg8_c => if (PMP_NUM_REGIONS > 31) then csr.rdata <= csr.pmpcfg_rd(35) & csr.pmpcfg_rd(34) & csr.pmpcfg_rd(33) & csr.pmpcfg_rd(32); else NULL; end if; -- R/W: pmpcfg8
when csr_pmpcfg9_c => if (PMP_NUM_REGIONS > 35) then csr.rdata <= csr.pmpcfg_rd(39) & csr.pmpcfg_rd(38) & csr.pmpcfg_rd(37) & csr.pmpcfg_rd(36); else NULL; end if; -- R/W: pmpcfg9
when csr_pmpcfg10_c => if (PMP_NUM_REGIONS > 39) then csr.rdata <= csr.pmpcfg_rd(43) & csr.pmpcfg_rd(42) & csr.pmpcfg_rd(41) & csr.pmpcfg_rd(40); else NULL; end if; -- R/W: pmpcfg10
when csr_pmpcfg11_c => if (PMP_NUM_REGIONS > 43) then csr.rdata <= csr.pmpcfg_rd(47) & csr.pmpcfg_rd(46) & csr.pmpcfg_rd(45) & csr.pmpcfg_rd(44); else NULL; end if; -- R/W: pmpcfg11
when csr_pmpcfg12_c => if (PMP_NUM_REGIONS > 47) then csr.rdata <= csr.pmpcfg_rd(51) & csr.pmpcfg_rd(50) & csr.pmpcfg_rd(49) & csr.pmpcfg_rd(48); else NULL; end if; -- R/W: pmpcfg12
when csr_pmpcfg13_c => if (PMP_NUM_REGIONS > 51) then csr.rdata <= csr.pmpcfg_rd(55) & csr.pmpcfg_rd(54) & csr.pmpcfg_rd(53) & csr.pmpcfg_rd(52); else NULL; end if; -- R/W: pmpcfg13
when csr_pmpcfg14_c => if (PMP_NUM_REGIONS > 55) then csr.rdata <= csr.pmpcfg_rd(59) & csr.pmpcfg_rd(58) & csr.pmpcfg_rd(57) & csr.pmpcfg_rd(56); else NULL; end if; -- R/W: pmpcfg14
when csr_pmpcfg15_c => if (PMP_NUM_REGIONS > 59) then csr.rdata <= csr.pmpcfg_rd(63) & csr.pmpcfg_rd(62) & csr.pmpcfg_rd(61) & csr.pmpcfg_rd(60); else NULL; end if; -- R/W: pmpcfg15
when csr_pmpcfg0_c => if (PMP_NUM_REGIONS > 00) then csr.rdata <= csr.pmpcfg_rd(03) & csr.pmpcfg_rd(02) & csr.pmpcfg_rd(01) & csr.pmpcfg_rd(00); else NULL; end if;
when csr_pmpcfg1_c => if (PMP_NUM_REGIONS > 03) then csr.rdata <= csr.pmpcfg_rd(07) & csr.pmpcfg_rd(06) & csr.pmpcfg_rd(05) & csr.pmpcfg_rd(04); else NULL; end if;
when csr_pmpcfg2_c => if (PMP_NUM_REGIONS > 07) then csr.rdata <= csr.pmpcfg_rd(11) & csr.pmpcfg_rd(10) & csr.pmpcfg_rd(09) & csr.pmpcfg_rd(08); else NULL; end if;
when csr_pmpcfg3_c => if (PMP_NUM_REGIONS > 11) then csr.rdata <= csr.pmpcfg_rd(15) & csr.pmpcfg_rd(14) & csr.pmpcfg_rd(13) & csr.pmpcfg_rd(12); else NULL; end if;
when csr_pmpcfg4_c => if (PMP_NUM_REGIONS > 15) then csr.rdata <= csr.pmpcfg_rd(19) & csr.pmpcfg_rd(18) & csr.pmpcfg_rd(17) & csr.pmpcfg_rd(16); else NULL; end if;
when csr_pmpcfg5_c => if (PMP_NUM_REGIONS > 19) then csr.rdata <= csr.pmpcfg_rd(23) & csr.pmpcfg_rd(22) & csr.pmpcfg_rd(21) & csr.pmpcfg_rd(20); else NULL; end if;
when csr_pmpcfg6_c => if (PMP_NUM_REGIONS > 23) then csr.rdata <= csr.pmpcfg_rd(27) & csr.pmpcfg_rd(26) & csr.pmpcfg_rd(25) & csr.pmpcfg_rd(24); else NULL; end if;
when csr_pmpcfg7_c => if (PMP_NUM_REGIONS > 27) then csr.rdata <= csr.pmpcfg_rd(31) & csr.pmpcfg_rd(30) & csr.pmpcfg_rd(29) & csr.pmpcfg_rd(28); else NULL; end if;
when csr_pmpcfg8_c => if (PMP_NUM_REGIONS > 31) then csr.rdata <= csr.pmpcfg_rd(35) & csr.pmpcfg_rd(34) & csr.pmpcfg_rd(33) & csr.pmpcfg_rd(32); else NULL; end if;
when csr_pmpcfg9_c => if (PMP_NUM_REGIONS > 35) then csr.rdata <= csr.pmpcfg_rd(39) & csr.pmpcfg_rd(38) & csr.pmpcfg_rd(37) & csr.pmpcfg_rd(36); else NULL; end if;
when csr_pmpcfg10_c => if (PMP_NUM_REGIONS > 39) then csr.rdata <= csr.pmpcfg_rd(43) & csr.pmpcfg_rd(42) & csr.pmpcfg_rd(41) & csr.pmpcfg_rd(40); else NULL; end if;
when csr_pmpcfg11_c => if (PMP_NUM_REGIONS > 43) then csr.rdata <= csr.pmpcfg_rd(47) & csr.pmpcfg_rd(46) & csr.pmpcfg_rd(45) & csr.pmpcfg_rd(44); else NULL; end if;
when csr_pmpcfg12_c => if (PMP_NUM_REGIONS > 47) then csr.rdata <= csr.pmpcfg_rd(51) & csr.pmpcfg_rd(50) & csr.pmpcfg_rd(49) & csr.pmpcfg_rd(48); else NULL; end if;
when csr_pmpcfg13_c => if (PMP_NUM_REGIONS > 51) then csr.rdata <= csr.pmpcfg_rd(55) & csr.pmpcfg_rd(54) & csr.pmpcfg_rd(53) & csr.pmpcfg_rd(52); else NULL; end if;
when csr_pmpcfg14_c => if (PMP_NUM_REGIONS > 55) then csr.rdata <= csr.pmpcfg_rd(59) & csr.pmpcfg_rd(58) & csr.pmpcfg_rd(57) & csr.pmpcfg_rd(56); else NULL; end if;
when csr_pmpcfg15_c => if (PMP_NUM_REGIONS > 59) then csr.rdata <= csr.pmpcfg_rd(63) & csr.pmpcfg_rd(62) & csr.pmpcfg_rd(61) & csr.pmpcfg_rd(60); else NULL; end if;
 
-- physical memory protection - addresses --
-- physical memory protection - addresses (r/w) --
-- --------------------------------------------------------------------
when csr_pmpaddr0_c => if (PMP_NUM_REGIONS > 00) then csr.rdata <= csr.pmpaddr(00); else NULL; end if; -- R/W: pmpaddr0
when csr_pmpaddr1_c => if (PMP_NUM_REGIONS > 01) then csr.rdata <= csr.pmpaddr(01); else NULL; end if; -- R/W: pmpaddr1
when csr_pmpaddr2_c => if (PMP_NUM_REGIONS > 02) then csr.rdata <= csr.pmpaddr(02); else NULL; end if; -- R/W: pmpaddr2
when csr_pmpaddr3_c => if (PMP_NUM_REGIONS > 03) then csr.rdata <= csr.pmpaddr(03); else NULL; end if; -- R/W: pmpaddr3
when csr_pmpaddr4_c => if (PMP_NUM_REGIONS > 04) then csr.rdata <= csr.pmpaddr(04); else NULL; end if; -- R/W: pmpaddr4
when csr_pmpaddr5_c => if (PMP_NUM_REGIONS > 05) then csr.rdata <= csr.pmpaddr(05); else NULL; end if; -- R/W: pmpaddr5
when csr_pmpaddr6_c => if (PMP_NUM_REGIONS > 06) then csr.rdata <= csr.pmpaddr(06); else NULL; end if; -- R/W: pmpaddr6
when csr_pmpaddr7_c => if (PMP_NUM_REGIONS > 07) then csr.rdata <= csr.pmpaddr(07); else NULL; end if; -- R/W: pmpaddr7
when csr_pmpaddr8_c => if (PMP_NUM_REGIONS > 08) then csr.rdata <= csr.pmpaddr(08); else NULL; end if; -- R/W: pmpaddr8
when csr_pmpaddr9_c => if (PMP_NUM_REGIONS > 09) then csr.rdata <= csr.pmpaddr(09); else NULL; end if; -- R/W: pmpaddr9
when csr_pmpaddr10_c => if (PMP_NUM_REGIONS > 10) then csr.rdata <= csr.pmpaddr(10); else NULL; end if; -- R/W: pmpaddr10
when csr_pmpaddr11_c => if (PMP_NUM_REGIONS > 11) then csr.rdata <= csr.pmpaddr(11); else NULL; end if; -- R/W: pmpaddr11
when csr_pmpaddr12_c => if (PMP_NUM_REGIONS > 12) then csr.rdata <= csr.pmpaddr(12); else NULL; end if; -- R/W: pmpaddr12
when csr_pmpaddr13_c => if (PMP_NUM_REGIONS > 13) then csr.rdata <= csr.pmpaddr(13); else NULL; end if; -- R/W: pmpaddr13
when csr_pmpaddr14_c => if (PMP_NUM_REGIONS > 14) then csr.rdata <= csr.pmpaddr(14); else NULL; end if; -- R/W: pmpaddr14
when csr_pmpaddr15_c => if (PMP_NUM_REGIONS > 15) then csr.rdata <= csr.pmpaddr(15); else NULL; end if; -- R/W: pmpaddr15
when csr_pmpaddr16_c => if (PMP_NUM_REGIONS > 16) then csr.rdata <= csr.pmpaddr(16); else NULL; end if; -- R/W: pmpaddr16
when csr_pmpaddr17_c => if (PMP_NUM_REGIONS > 17) then csr.rdata <= csr.pmpaddr(17); else NULL; end if; -- R/W: pmpaddr17
when csr_pmpaddr18_c => if (PMP_NUM_REGIONS > 18) then csr.rdata <= csr.pmpaddr(18); else NULL; end if; -- R/W: pmpaddr18
when csr_pmpaddr19_c => if (PMP_NUM_REGIONS > 19) then csr.rdata <= csr.pmpaddr(19); else NULL; end if; -- R/W: pmpaddr19
when csr_pmpaddr20_c => if (PMP_NUM_REGIONS > 20) then csr.rdata <= csr.pmpaddr(20); else NULL; end if; -- R/W: pmpaddr20
when csr_pmpaddr21_c => if (PMP_NUM_REGIONS > 21) then csr.rdata <= csr.pmpaddr(21); else NULL; end if; -- R/W: pmpaddr21
when csr_pmpaddr22_c => if (PMP_NUM_REGIONS > 22) then csr.rdata <= csr.pmpaddr(22); else NULL; end if; -- R/W: pmpaddr22
when csr_pmpaddr23_c => if (PMP_NUM_REGIONS > 23) then csr.rdata <= csr.pmpaddr(23); else NULL; end if; -- R/W: pmpaddr23
when csr_pmpaddr24_c => if (PMP_NUM_REGIONS > 24) then csr.rdata <= csr.pmpaddr(24); else NULL; end if; -- R/W: pmpaddr24
when csr_pmpaddr25_c => if (PMP_NUM_REGIONS > 25) then csr.rdata <= csr.pmpaddr(25); else NULL; end if; -- R/W: pmpaddr25
when csr_pmpaddr26_c => if (PMP_NUM_REGIONS > 26) then csr.rdata <= csr.pmpaddr(26); else NULL; end if; -- R/W: pmpaddr26
when csr_pmpaddr27_c => if (PMP_NUM_REGIONS > 27) then csr.rdata <= csr.pmpaddr(27); else NULL; end if; -- R/W: pmpaddr27
when csr_pmpaddr28_c => if (PMP_NUM_REGIONS > 28) then csr.rdata <= csr.pmpaddr(28); else NULL; end if; -- R/W: pmpaddr28
when csr_pmpaddr29_c => if (PMP_NUM_REGIONS > 29) then csr.rdata <= csr.pmpaddr(29); else NULL; end if; -- R/W: pmpaddr29
when csr_pmpaddr30_c => if (PMP_NUM_REGIONS > 30) then csr.rdata <= csr.pmpaddr(30); else NULL; end if; -- R/W: pmpaddr30
when csr_pmpaddr31_c => if (PMP_NUM_REGIONS > 31) then csr.rdata <= csr.pmpaddr(31); else NULL; end if; -- R/W: pmpaddr31
when csr_pmpaddr32_c => if (PMP_NUM_REGIONS > 32) then csr.rdata <= csr.pmpaddr(32); else NULL; end if; -- R/W: pmpaddr32
when csr_pmpaddr33_c => if (PMP_NUM_REGIONS > 33) then csr.rdata <= csr.pmpaddr(33); else NULL; end if; -- R/W: pmpaddr33
when csr_pmpaddr34_c => if (PMP_NUM_REGIONS > 34) then csr.rdata <= csr.pmpaddr(34); else NULL; end if; -- R/W: pmpaddr34
when csr_pmpaddr35_c => if (PMP_NUM_REGIONS > 35) then csr.rdata <= csr.pmpaddr(35); else NULL; end if; -- R/W: pmpaddr35
when csr_pmpaddr36_c => if (PMP_NUM_REGIONS > 36) then csr.rdata <= csr.pmpaddr(36); else NULL; end if; -- R/W: pmpaddr36
when csr_pmpaddr37_c => if (PMP_NUM_REGIONS > 37) then csr.rdata <= csr.pmpaddr(37); else NULL; end if; -- R/W: pmpaddr37
when csr_pmpaddr38_c => if (PMP_NUM_REGIONS > 38) then csr.rdata <= csr.pmpaddr(38); else NULL; end if; -- R/W: pmpaddr38
when csr_pmpaddr39_c => if (PMP_NUM_REGIONS > 39) then csr.rdata <= csr.pmpaddr(39); else NULL; end if; -- R/W: pmpaddr39
when csr_pmpaddr40_c => if (PMP_NUM_REGIONS > 40) then csr.rdata <= csr.pmpaddr(40); else NULL; end if; -- R/W: pmpaddr40
when csr_pmpaddr41_c => if (PMP_NUM_REGIONS > 41) then csr.rdata <= csr.pmpaddr(41); else NULL; end if; -- R/W: pmpaddr41
when csr_pmpaddr42_c => if (PMP_NUM_REGIONS > 42) then csr.rdata <= csr.pmpaddr(42); else NULL; end if; -- R/W: pmpaddr42
when csr_pmpaddr43_c => if (PMP_NUM_REGIONS > 43) then csr.rdata <= csr.pmpaddr(43); else NULL; end if; -- R/W: pmpaddr43
when csr_pmpaddr44_c => if (PMP_NUM_REGIONS > 44) then csr.rdata <= csr.pmpaddr(44); else NULL; end if; -- R/W: pmpaddr44
when csr_pmpaddr45_c => if (PMP_NUM_REGIONS > 45) then csr.rdata <= csr.pmpaddr(45); else NULL; end if; -- R/W: pmpaddr45
when csr_pmpaddr46_c => if (PMP_NUM_REGIONS > 46) then csr.rdata <= csr.pmpaddr(46); else NULL; end if; -- R/W: pmpaddr46
when csr_pmpaddr47_c => if (PMP_NUM_REGIONS > 47) then csr.rdata <= csr.pmpaddr(47); else NULL; end if; -- R/W: pmpaddr47
when csr_pmpaddr48_c => if (PMP_NUM_REGIONS > 48) then csr.rdata <= csr.pmpaddr(48); else NULL; end if; -- R/W: pmpaddr48
when csr_pmpaddr49_c => if (PMP_NUM_REGIONS > 49) then csr.rdata <= csr.pmpaddr(49); else NULL; end if; -- R/W: pmpaddr49
when csr_pmpaddr50_c => if (PMP_NUM_REGIONS > 50) then csr.rdata <= csr.pmpaddr(50); else NULL; end if; -- R/W: pmpaddr50
when csr_pmpaddr51_c => if (PMP_NUM_REGIONS > 51) then csr.rdata <= csr.pmpaddr(51); else NULL; end if; -- R/W: pmpaddr51
when csr_pmpaddr52_c => if (PMP_NUM_REGIONS > 52) then csr.rdata <= csr.pmpaddr(52); else NULL; end if; -- R/W: pmpaddr52
when csr_pmpaddr53_c => if (PMP_NUM_REGIONS > 53) then csr.rdata <= csr.pmpaddr(53); else NULL; end if; -- R/W: pmpaddr53
when csr_pmpaddr54_c => if (PMP_NUM_REGIONS > 54) then csr.rdata <= csr.pmpaddr(54); else NULL; end if; -- R/W: pmpaddr54
when csr_pmpaddr55_c => if (PMP_NUM_REGIONS > 55) then csr.rdata <= csr.pmpaddr(55); else NULL; end if; -- R/W: pmpaddr55
when csr_pmpaddr56_c => if (PMP_NUM_REGIONS > 56) then csr.rdata <= csr.pmpaddr(56); else NULL; end if; -- R/W: pmpaddr56
when csr_pmpaddr57_c => if (PMP_NUM_REGIONS > 57) then csr.rdata <= csr.pmpaddr(57); else NULL; end if; -- R/W: pmpaddr57
when csr_pmpaddr58_c => if (PMP_NUM_REGIONS > 58) then csr.rdata <= csr.pmpaddr(58); else NULL; end if; -- R/W: pmpaddr58
when csr_pmpaddr59_c => if (PMP_NUM_REGIONS > 59) then csr.rdata <= csr.pmpaddr(59); else NULL; end if; -- R/W: pmpaddr59
when csr_pmpaddr60_c => if (PMP_NUM_REGIONS > 60) then csr.rdata <= csr.pmpaddr(60); else NULL; end if; -- R/W: pmpaddr60
when csr_pmpaddr61_c => if (PMP_NUM_REGIONS > 61) then csr.rdata <= csr.pmpaddr(61); else NULL; end if; -- R/W: pmpaddr61
when csr_pmpaddr62_c => if (PMP_NUM_REGIONS > 62) then csr.rdata <= csr.pmpaddr(62); else NULL; end if; -- R/W: pmpaddr62
when csr_pmpaddr63_c => if (PMP_NUM_REGIONS > 63) then csr.rdata <= csr.pmpaddr(63); else NULL; end if; -- R/W: pmpaddr63
when csr_pmpaddr0_c => if (PMP_NUM_REGIONS > 00) then csr.rdata <= csr.pmpaddr(00); else NULL; end if;
when csr_pmpaddr1_c => if (PMP_NUM_REGIONS > 01) then csr.rdata <= csr.pmpaddr(01); else NULL; end if;
when csr_pmpaddr2_c => if (PMP_NUM_REGIONS > 02) then csr.rdata <= csr.pmpaddr(02); else NULL; end if;
when csr_pmpaddr3_c => if (PMP_NUM_REGIONS > 03) then csr.rdata <= csr.pmpaddr(03); else NULL; end if;
when csr_pmpaddr4_c => if (PMP_NUM_REGIONS > 04) then csr.rdata <= csr.pmpaddr(04); else NULL; end if;
when csr_pmpaddr5_c => if (PMP_NUM_REGIONS > 05) then csr.rdata <= csr.pmpaddr(05); else NULL; end if;
when csr_pmpaddr6_c => if (PMP_NUM_REGIONS > 06) then csr.rdata <= csr.pmpaddr(06); else NULL; end if;
when csr_pmpaddr7_c => if (PMP_NUM_REGIONS > 07) then csr.rdata <= csr.pmpaddr(07); else NULL; end if;
when csr_pmpaddr8_c => if (PMP_NUM_REGIONS > 08) then csr.rdata <= csr.pmpaddr(08); else NULL; end if;
when csr_pmpaddr9_c => if (PMP_NUM_REGIONS > 09) then csr.rdata <= csr.pmpaddr(09); else NULL; end if;
when csr_pmpaddr10_c => if (PMP_NUM_REGIONS > 10) then csr.rdata <= csr.pmpaddr(10); else NULL; end if;
when csr_pmpaddr11_c => if (PMP_NUM_REGIONS > 11) then csr.rdata <= csr.pmpaddr(11); else NULL; end if;
when csr_pmpaddr12_c => if (PMP_NUM_REGIONS > 12) then csr.rdata <= csr.pmpaddr(12); else NULL; end if;
when csr_pmpaddr13_c => if (PMP_NUM_REGIONS > 13) then csr.rdata <= csr.pmpaddr(13); else NULL; end if;
when csr_pmpaddr14_c => if (PMP_NUM_REGIONS > 14) then csr.rdata <= csr.pmpaddr(14); else NULL; end if;
when csr_pmpaddr15_c => if (PMP_NUM_REGIONS > 15) then csr.rdata <= csr.pmpaddr(15); else NULL; end if;
when csr_pmpaddr16_c => if (PMP_NUM_REGIONS > 16) then csr.rdata <= csr.pmpaddr(16); else NULL; end if;
when csr_pmpaddr17_c => if (PMP_NUM_REGIONS > 17) then csr.rdata <= csr.pmpaddr(17); else NULL; end if;
when csr_pmpaddr18_c => if (PMP_NUM_REGIONS > 18) then csr.rdata <= csr.pmpaddr(18); else NULL; end if;
when csr_pmpaddr19_c => if (PMP_NUM_REGIONS > 19) then csr.rdata <= csr.pmpaddr(19); else NULL; end if;
when csr_pmpaddr20_c => if (PMP_NUM_REGIONS > 20) then csr.rdata <= csr.pmpaddr(20); else NULL; end if;
when csr_pmpaddr21_c => if (PMP_NUM_REGIONS > 21) then csr.rdata <= csr.pmpaddr(21); else NULL; end if;
when csr_pmpaddr22_c => if (PMP_NUM_REGIONS > 22) then csr.rdata <= csr.pmpaddr(22); else NULL; end if;
when csr_pmpaddr23_c => if (PMP_NUM_REGIONS > 23) then csr.rdata <= csr.pmpaddr(23); else NULL; end if;
when csr_pmpaddr24_c => if (PMP_NUM_REGIONS > 24) then csr.rdata <= csr.pmpaddr(24); else NULL; end if;
when csr_pmpaddr25_c => if (PMP_NUM_REGIONS > 25) then csr.rdata <= csr.pmpaddr(25); else NULL; end if;
when csr_pmpaddr26_c => if (PMP_NUM_REGIONS > 26) then csr.rdata <= csr.pmpaddr(26); else NULL; end if;
when csr_pmpaddr27_c => if (PMP_NUM_REGIONS > 27) then csr.rdata <= csr.pmpaddr(27); else NULL; end if;
when csr_pmpaddr28_c => if (PMP_NUM_REGIONS > 28) then csr.rdata <= csr.pmpaddr(28); else NULL; end if;
when csr_pmpaddr29_c => if (PMP_NUM_REGIONS > 29) then csr.rdata <= csr.pmpaddr(29); else NULL; end if;
when csr_pmpaddr30_c => if (PMP_NUM_REGIONS > 30) then csr.rdata <= csr.pmpaddr(30); else NULL; end if;
when csr_pmpaddr31_c => if (PMP_NUM_REGIONS > 31) then csr.rdata <= csr.pmpaddr(31); else NULL; end if;
when csr_pmpaddr32_c => if (PMP_NUM_REGIONS > 32) then csr.rdata <= csr.pmpaddr(32); else NULL; end if;
when csr_pmpaddr33_c => if (PMP_NUM_REGIONS > 33) then csr.rdata <= csr.pmpaddr(33); else NULL; end if;
when csr_pmpaddr34_c => if (PMP_NUM_REGIONS > 34) then csr.rdata <= csr.pmpaddr(34); else NULL; end if;
when csr_pmpaddr35_c => if (PMP_NUM_REGIONS > 35) then csr.rdata <= csr.pmpaddr(35); else NULL; end if;
when csr_pmpaddr36_c => if (PMP_NUM_REGIONS > 36) then csr.rdata <= csr.pmpaddr(36); else NULL; end if;
when csr_pmpaddr37_c => if (PMP_NUM_REGIONS > 37) then csr.rdata <= csr.pmpaddr(37); else NULL; end if;
when csr_pmpaddr38_c => if (PMP_NUM_REGIONS > 38) then csr.rdata <= csr.pmpaddr(38); else NULL; end if;
when csr_pmpaddr39_c => if (PMP_NUM_REGIONS > 39) then csr.rdata <= csr.pmpaddr(39); else NULL; end if;
when csr_pmpaddr40_c => if (PMP_NUM_REGIONS > 40) then csr.rdata <= csr.pmpaddr(40); else NULL; end if;
when csr_pmpaddr41_c => if (PMP_NUM_REGIONS > 41) then csr.rdata <= csr.pmpaddr(41); else NULL; end if;
when csr_pmpaddr42_c => if (PMP_NUM_REGIONS > 42) then csr.rdata <= csr.pmpaddr(42); else NULL; end if;
when csr_pmpaddr43_c => if (PMP_NUM_REGIONS > 43) then csr.rdata <= csr.pmpaddr(43); else NULL; end if;
when csr_pmpaddr44_c => if (PMP_NUM_REGIONS > 44) then csr.rdata <= csr.pmpaddr(44); else NULL; end if;
when csr_pmpaddr45_c => if (PMP_NUM_REGIONS > 45) then csr.rdata <= csr.pmpaddr(45); else NULL; end if;
when csr_pmpaddr46_c => if (PMP_NUM_REGIONS > 46) then csr.rdata <= csr.pmpaddr(46); else NULL; end if;
when csr_pmpaddr47_c => if (PMP_NUM_REGIONS > 47) then csr.rdata <= csr.pmpaddr(47); else NULL; end if;
when csr_pmpaddr48_c => if (PMP_NUM_REGIONS > 48) then csr.rdata <= csr.pmpaddr(48); else NULL; end if;
when csr_pmpaddr49_c => if (PMP_NUM_REGIONS > 49) then csr.rdata <= csr.pmpaddr(49); else NULL; end if;
when csr_pmpaddr50_c => if (PMP_NUM_REGIONS > 50) then csr.rdata <= csr.pmpaddr(50); else NULL; end if;
when csr_pmpaddr51_c => if (PMP_NUM_REGIONS > 51) then csr.rdata <= csr.pmpaddr(51); else NULL; end if;
when csr_pmpaddr52_c => if (PMP_NUM_REGIONS > 52) then csr.rdata <= csr.pmpaddr(52); else NULL; end if;
when csr_pmpaddr53_c => if (PMP_NUM_REGIONS > 53) then csr.rdata <= csr.pmpaddr(53); else NULL; end if;
when csr_pmpaddr54_c => if (PMP_NUM_REGIONS > 54) then csr.rdata <= csr.pmpaddr(54); else NULL; end if;
when csr_pmpaddr55_c => if (PMP_NUM_REGIONS > 55) then csr.rdata <= csr.pmpaddr(55); else NULL; end if;
when csr_pmpaddr56_c => if (PMP_NUM_REGIONS > 56) then csr.rdata <= csr.pmpaddr(56); else NULL; end if;
when csr_pmpaddr57_c => if (PMP_NUM_REGIONS > 57) then csr.rdata <= csr.pmpaddr(57); else NULL; end if;
when csr_pmpaddr58_c => if (PMP_NUM_REGIONS > 58) then csr.rdata <= csr.pmpaddr(58); else NULL; end if;
when csr_pmpaddr59_c => if (PMP_NUM_REGIONS > 59) then csr.rdata <= csr.pmpaddr(59); else NULL; end if;
when csr_pmpaddr60_c => if (PMP_NUM_REGIONS > 60) then csr.rdata <= csr.pmpaddr(60); else NULL; end if;
when csr_pmpaddr61_c => if (PMP_NUM_REGIONS > 61) then csr.rdata <= csr.pmpaddr(61); else NULL; end if;
when csr_pmpaddr62_c => if (PMP_NUM_REGIONS > 62) then csr.rdata <= csr.pmpaddr(62); else NULL; end if;
when csr_pmpaddr63_c => if (PMP_NUM_REGIONS > 63) then csr.rdata <= csr.pmpaddr(63); else NULL; end if;
 
-- machine counter setup --
-- --------------------------------------------------------------------
2653,39 → 2699,41
when csr_mcountinhibit_c => -- mcountinhibit (r/w): machine counter-inhibit register
csr.rdata(0) <= csr.mcountinhibit_cy; -- enable auto-increment of [m]cycle[h] counter
csr.rdata(2) <= csr.mcountinhibit_ir; -- enable auto-increment of [m]instret[h] counter
csr.rdata(csr.mcountinhibit_hpm'left+3 downto 3) <= csr.mcountinhibit_hpm; -- enable auto-increment of [m]hpmcounterx[h] counter
if (HPM_NUM_CNTS > 0) then -- any HPMs available?
csr.rdata(csr.mcountinhibit_hpm'left+3 downto 3) <= csr.mcountinhibit_hpm; -- enable auto-increment of [m]hpmcounterx[h] counter
end if;
 
-- machine performance-monitoring event selector --
-- machine performance-monitoring event selector (r/w) --
-- --------------------------------------------------------------------
when csr_mhpmevent3_c => if (HPM_NUM_CNTS > 00) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(00); else NULL; end if; -- R/W: mhpmevent3
when csr_mhpmevent4_c => if (HPM_NUM_CNTS > 01) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(01); else NULL; end if; -- R/W: mhpmevent4
when csr_mhpmevent5_c => if (HPM_NUM_CNTS > 02) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(02); else NULL; end if; -- R/W: mhpmevent5
when csr_mhpmevent6_c => if (HPM_NUM_CNTS > 03) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(03); else NULL; end if; -- R/W: mhpmevent6
when csr_mhpmevent7_c => if (HPM_NUM_CNTS > 04) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(04); else NULL; end if; -- R/W: mhpmevent7
when csr_mhpmevent8_c => if (HPM_NUM_CNTS > 05) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(05); else NULL; end if; -- R/W: mhpmevent8
when csr_mhpmevent9_c => if (HPM_NUM_CNTS > 06) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(06); else NULL; end if; -- R/W: mhpmevent9
when csr_mhpmevent10_c => if (HPM_NUM_CNTS > 07) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(07); else NULL; end if; -- R/W: mhpmevent10
when csr_mhpmevent11_c => if (HPM_NUM_CNTS > 08) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(08); else NULL; end if; -- R/W: mhpmevent11
when csr_mhpmevent12_c => if (HPM_NUM_CNTS > 09) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(09); else NULL; end if; -- R/W: mhpmevent12
when csr_mhpmevent13_c => if (HPM_NUM_CNTS > 10) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(10); else NULL; end if; -- R/W: mhpmevent13
when csr_mhpmevent14_c => if (HPM_NUM_CNTS > 11) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(11); else NULL; end if; -- R/W: mhpmevent14
when csr_mhpmevent15_c => if (HPM_NUM_CNTS > 12) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(12); else NULL; end if; -- R/W: mhpmevent15
when csr_mhpmevent16_c => if (HPM_NUM_CNTS > 13) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(13); else NULL; end if; -- R/W: mhpmevent16
when csr_mhpmevent17_c => if (HPM_NUM_CNTS > 14) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(14); else NULL; end if; -- R/W: mhpmevent17
when csr_mhpmevent18_c => if (HPM_NUM_CNTS > 15) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(15); else NULL; end if; -- R/W: mhpmevent18
when csr_mhpmevent19_c => if (HPM_NUM_CNTS > 16) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(16); else NULL; end if; -- R/W: mhpmevent19
when csr_mhpmevent20_c => if (HPM_NUM_CNTS > 17) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(17); else NULL; end if; -- R/W: mhpmevent20
when csr_mhpmevent21_c => if (HPM_NUM_CNTS > 18) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(18); else NULL; end if; -- R/W: mhpmevent21
when csr_mhpmevent22_c => if (HPM_NUM_CNTS > 19) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(19); else NULL; end if; -- R/W: mhpmevent22
when csr_mhpmevent23_c => if (HPM_NUM_CNTS > 20) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(20); else NULL; end if; -- R/W: mhpmevent23
when csr_mhpmevent24_c => if (HPM_NUM_CNTS > 21) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(21); else NULL; end if; -- R/W: mhpmevent24
when csr_mhpmevent25_c => if (HPM_NUM_CNTS > 22) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(22); else NULL; end if; -- R/W: mhpmevent25
when csr_mhpmevent26_c => if (HPM_NUM_CNTS > 23) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(23); else NULL; end if; -- R/W: mhpmevent26
when csr_mhpmevent27_c => if (HPM_NUM_CNTS > 24) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(24); else NULL; end if; -- R/W: mhpmevent27
when csr_mhpmevent28_c => if (HPM_NUM_CNTS > 25) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(25); else NULL; end if; -- R/W: mhpmevent28
when csr_mhpmevent29_c => if (HPM_NUM_CNTS > 26) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(26); else NULL; end if; -- R/W: mhpmevent29
when csr_mhpmevent30_c => if (HPM_NUM_CNTS > 27) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(27); else NULL; end if; -- R/W: mhpmevent30
when csr_mhpmevent31_c => if (HPM_NUM_CNTS > 28) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(28); else NULL; end if; -- R/W: mhpmevent31
when csr_mhpmevent3_c => if (HPM_NUM_CNTS > 00) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(00); else NULL; end if;
when csr_mhpmevent4_c => if (HPM_NUM_CNTS > 01) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(01); else NULL; end if;
when csr_mhpmevent5_c => if (HPM_NUM_CNTS > 02) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(02); else NULL; end if;
when csr_mhpmevent6_c => if (HPM_NUM_CNTS > 03) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(03); else NULL; end if;
when csr_mhpmevent7_c => if (HPM_NUM_CNTS > 04) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(04); else NULL; end if;
when csr_mhpmevent8_c => if (HPM_NUM_CNTS > 05) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(05); else NULL; end if;
when csr_mhpmevent9_c => if (HPM_NUM_CNTS > 06) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(06); else NULL; end if;
when csr_mhpmevent10_c => if (HPM_NUM_CNTS > 07) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(07); else NULL; end if;
when csr_mhpmevent11_c => if (HPM_NUM_CNTS > 08) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(08); else NULL; end if;
when csr_mhpmevent12_c => if (HPM_NUM_CNTS > 09) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(09); else NULL; end if;
when csr_mhpmevent13_c => if (HPM_NUM_CNTS > 10) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(10); else NULL; end if;
when csr_mhpmevent14_c => if (HPM_NUM_CNTS > 11) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(11); else NULL; end if;
when csr_mhpmevent15_c => if (HPM_NUM_CNTS > 12) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(12); else NULL; end if;
when csr_mhpmevent16_c => if (HPM_NUM_CNTS > 13) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(13); else NULL; end if;
when csr_mhpmevent17_c => if (HPM_NUM_CNTS > 14) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(14); else NULL; end if;
when csr_mhpmevent18_c => if (HPM_NUM_CNTS > 15) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(15); else NULL; end if;
when csr_mhpmevent19_c => if (HPM_NUM_CNTS > 16) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(16); else NULL; end if;
when csr_mhpmevent20_c => if (HPM_NUM_CNTS > 17) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(17); else NULL; end if;
when csr_mhpmevent21_c => if (HPM_NUM_CNTS > 18) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(18); else NULL; end if;
when csr_mhpmevent22_c => if (HPM_NUM_CNTS > 19) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(19); else NULL; end if;
when csr_mhpmevent23_c => if (HPM_NUM_CNTS > 20) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(20); else NULL; end if;
when csr_mhpmevent24_c => if (HPM_NUM_CNTS > 21) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(21); else NULL; end if;
when csr_mhpmevent25_c => if (HPM_NUM_CNTS > 22) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(22); else NULL; end if;
when csr_mhpmevent26_c => if (HPM_NUM_CNTS > 23) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(23); else NULL; end if;
when csr_mhpmevent27_c => if (HPM_NUM_CNTS > 24) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(24); else NULL; end if;
when csr_mhpmevent28_c => if (HPM_NUM_CNTS > 25) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(25); else NULL; end if;
when csr_mhpmevent29_c => if (HPM_NUM_CNTS > 26) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(26); else NULL; end if;
when csr_mhpmevent30_c => if (HPM_NUM_CNTS > 27) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(27); else NULL; end if;
when csr_mhpmevent31_c => if (HPM_NUM_CNTS > 28) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(28); else NULL; end if;
 
-- counters and timers --
-- --------------------------------------------------------------------
2699,101 → 2747,80
when csr_instreth_c | csr_minstreth_c => -- [m]instreth (r/w): Instructions-retired counter HIGH
if (cpu_cnt_hi_width_c > 0) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.minstreth(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
 
when csr_time_c => csr.rdata <= time_i(31 downto 0); -- time (r/-): System time LOW (from MTIME unit)
when csr_time_c => csr.rdata <= time_i(31 downto 0); -- time (r/-): System time LOW (from MTIME unit)
when csr_timeh_c => csr.rdata <= time_i(63 downto 32); -- timeh (r/-): System time HIGH (from MTIME unit)
 
-- hardware performance counters --
-- --------------------------------------------------------------------
when csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if; -- r/w: mhpmcounter3 - low
when csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if; -- r/w: mhpmcounter4 - low
when csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if; -- r/w: mhpmcounter5 - low
when csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if; -- r/w: mhpmcounter6 - low
when csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if; -- r/w: mhpmcounter7 - low
when csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if; -- r/w: mhpmcounter8 - low
when csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if; -- r/w: mhpmcounter9 - low
when csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if; -- r/w: mhpmcounter10 - low
when csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if; -- r/w: mhpmcounter11 - low
when csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if; -- r/w: mhpmcounter12 - low
when csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if; -- r/w: mhpmcounter13 - low
when csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if; -- r/w: mhpmcounter14 - low
when csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if; -- r/w: mhpmcounter15 - low
when csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if; -- r/w: mhpmcounter16 - low
when csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if; -- r/w: mhpmcounter17 - low
when csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if; -- r/w: mhpmcounter18 - low
when csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if; -- r/w: mhpmcounter19 - low
when csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if; -- r/w: mhpmcounter20 - low
when csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if; -- r/w: mhpmcounter21 - low
when csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if; -- r/w: mhpmcounter22 - low
when csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if; -- r/w: mhpmcounter23 - low
when csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if; -- r/w: mhpmcounter24 - low
when csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if; -- r/w: mhpmcounter25 - low
when csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if; -- r/w: mhpmcounter26 - low
when csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if; -- r/w: mhpmcounter27 - low
when csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if; -- r/w: mhpmcounter28 - low
when csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if; -- r/w: mhpmcounter29 - low
when csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if; -- r/w: mhpmcounter30 - low
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if; -- r/w: mhpmcounter31 - low
-- low word (r/w) --
when csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if;
when csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if;
when csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if;
when csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if;
when csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if;
when csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if;
when csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if;
when csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if;
when csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if;
when csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if;
when csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if;
when csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if;
when csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if;
when csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if;
when csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if;
when csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if;
when csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if;
when csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if;
when csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if;
when csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if;
when csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if;
when csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if;
when csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if;
when csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if;
when csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if;
when csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if;
when csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if;
when csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if;
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if;
-- high word (r/w) --
when csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if;
when csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if;
when csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if;
when csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if;
when csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if;
when csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if;
when csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if;
when csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if;
when csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if;
when csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if;
when csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if;
when csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if;
when csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if;
when csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if;
when csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if;
when csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if;
when csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if;
when csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if;
when csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if;
when csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if;
when csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if;
when csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if;
when csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if;
when csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if;
when csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if;
when csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if;
when csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if;
when csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if;
when csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if;
 
when csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if; -- r/w: mhpmcounter3h - high
when csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if; -- r/w: mhpmcounter4h - high
when csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if; -- r/w: mhpmcounter5h - high
when csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if; -- r/w: mhpmcounter6h - high
when csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if; -- r/w: mhpmcounter7h - high
when csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if; -- r/w: mhpmcounter8h - high
when csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if; -- r/w: mhpmcounter9h - high
when csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if; -- r/w: mhpmcounter10h - high
when csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if; -- r/w: mhpmcounter11h - high
when csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if; -- r/w: mhpmcounter12h - high
when csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if; -- r/w: mhpmcounter13h - high
when csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if; -- r/w: mhpmcounter14h - high
when csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if; -- r/w: mhpmcounter15h - high
when csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if; -- r/w: mhpmcounter16h - high
when csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if; -- r/w: mhpmcounter17h - high
when csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if; -- r/w: mhpmcounter18h - high
when csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if; -- r/w: mhpmcounter19h - high
when csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if; -- r/w: mhpmcounter20h - high
when csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if; -- r/w: mhpmcounter21h - high
when csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if; -- r/w: mhpmcounter22h - high
when csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if; -- r/w: mhpmcounter23h - high
when csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if; -- r/w: mhpmcounter24h - high
when csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if; -- r/w: mhpmcounter25h - high
when csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if; -- r/w: mhpmcounter26h - high
when csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if; -- r/w: mhpmcounter27h - high
when csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if; -- r/w: mhpmcounter28h - high
when csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if; -- r/w: mhpmcounter29h - high
when csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if; -- r/w: mhpmcounter30h - high
when csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if; -- r/w: mhpmcounter31h - high
 
-- machine information registers --
-- --------------------------------------------------------------------
-- when csr_mvendorid_c => csr.rdata <= (others => '0'); -- mvendorid (r/-): vendor ID, implemented but always zero
-- when csr_mvendorid_c => NULL; -- mvendorid (r/-): vendor ID, implemented but always zero
when csr_marchid_c => csr.rdata(4 downto 0) <= "10011"; -- marchid (r/-): arch ID - official RISC-V open-source arch ID
when csr_mimpid_c => csr.rdata <= hw_version_c; -- mimpid (r/-): implementation ID -- NEORV32 hardware version
when csr_mhartid_c => csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32)); -- mhartid (r/-): hardware thread ID
-- when csr_mconfigptr_c => csr.rdata <= (others => '0'); -- mconfigptr (r/-): machine configuration pointer register, implemented but not assigned yet
-- when csr_mconfigptr_c => NULL; -- mconfigptr (r/-): machine configuration pointer register, implemented but not assigned yet
 
-- custom machine read-only CSRs --
-- --------------------------------------------------------------------
when csr_mzext_c => -- mzext (r/-): available RISC-V Z* sub-extensions
csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr
csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
csr.rdata(2) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul
-- ... --
csr.rdata(5) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative")
if (CPU_CNT_WIDTH = 64) then
csr.rdata(6) <= '0'; -- Zxscnt (custom)
csr.rdata(7) <= '0'; -- Zxnocnt (custom)
elsif (CPU_CNT_WIDTH = 0) then
csr.rdata(6) <= '0'; -- Zxscnt (custom)
csr.rdata(7) <= '1'; -- Zxnocnt (custom)
else -- counters available but 0-bit < actual_size < 64-bit
csr.rdata(6) <= '1'; -- Zxscnt (custom)
csr.rdata(7) <= '0'; -- Zxnocnt (custom)
end if;
csr.rdata(8) <= bool_to_ulogic_f(boolean(PMP_NUM_REGIONS > 0)); -- PMP (physical memory protection)
csr.rdata(9) <= bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- HPM (hardware performance monitors)
csr.rdata(10) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- RISC-V debug mode
 
-- debug mode CSRs --
-- --------------------------------------------------------------------
when csr_dcsr_c => if (CPU_EXTENSION_RISCV_DEBUG = true) then csr.rdata <= csr.dcsr_rd; else NULL; end if; -- dcsr (r/w): debug mode control and status
/core/neorv32_cpu_cp_bitmanip.vhd
0,0 → 1,422
-- #################################################################################################
-- # << NEORV32 - CPU Co-Processor: Bit-Manipulation Co-Processor Unit (RISC-V "B" Extension) >> #
-- # ********************************************************************************************* #
-- # The bit manipulation unit is implemented as co-processor that has a processing latency of 1 #
-- # cycle for logic/arithmetic operations and 3+shamt (=shift amount) cycles for shift(-related) #
-- # operations. Use the FAST_SHIFT_EN option to reduce shift-related instruction's latency to a #
-- # fixed value of 3 cycles latency (using barrel shifters). #
-- # #
-- # Supported sub-extensions (Zb*): #
-- # - Zbb: Basic bit-manipulation instructions #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_cpu_cp_bitmanip is
generic (
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
start_i : in std_ulogic; -- trigger operation
-- data input --
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
);
end neorv32_cpu_cp_bitmanip;
 
architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
 
-- commands: logic with negate --
constant op_andn_c : natural := 0;
constant op_orn_c : natural := 1;
constant op_xnor_c : natural := 2;
-- commands: count leading/trailing zero bits --
constant op_clz_c : natural := 3;
constant op_ctz_c : natural := 4;
-- commands: count population --
constant op_cpop_c : natural := 5;
-- commands: integer minimum/maximum --
constant op_max_c : natural := 6; -- signed/unsigned
constant op_min_c : natural := 7; -- signed/unsigned
-- commands: sign- and zero-extension --
constant op_sextb_c : natural := 8;
constant op_sexth_c : natural := 9;
constant op_zexth_c : natural := 10;
-- commands: bitwise rotation --
constant op_rol_c : natural := 11;
constant op_ror_c : natural := 12; -- rori
-- commands: or-combine --
constant op_orcb_c : natural := 13;
-- commands: byte-reverse --
constant op_rev8_c : natural := 14;
--
constant op_width_c : natural := 15;
 
-- controller --
type ctrl_state_t is (S_IDLE, S_START_SHIFT, S_BUSY_SHIFT);
signal ctrl_state : ctrl_state_t;
signal cmd, cmd_buf : std_ulogic_vector(op_width_c-1 downto 0);
signal valid : std_ulogic;
 
-- operand buffers --
signal rs1_reg : std_ulogic_vector(data_width_c-1 downto 0);
signal rs2_reg : std_ulogic_vector(data_width_c-1 downto 0);
signal less_ff : std_ulogic;
 
-- shift amount (immediate or register) --
signal shamt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
 
-- serial shifter --
type shifter_t is record
start : std_ulogic;
run : std_ulogic;
bcnt : std_ulogic_vector(index_size_f(data_width_c) downto 0); -- bit counter
cnt : std_ulogic_vector(index_size_f(data_width_c) downto 0); -- iteration counter
cnt_max : std_ulogic_vector(index_size_f(data_width_c) downto 0);
sreg : std_ulogic_vector(data_width_c-1 downto 0);
end record;
signal shifter : shifter_t;
 
-- barrel shifter --
type bs_level_t is array (index_size_f(data_width_c) downto 0) of std_ulogic_vector(data_width_c-1 downto 0);
signal bs_level : bs_level_t;
 
-- operation results --
type res_t is array (0 to op_width_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
signal res_int, res_out : res_t;
 
begin
 
-- Instruction Decoding (One-Hot) ---------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- a minimal decoding logic is used here -> just to distinguish between B.Zbb instructions
-- a more specific decoding and instruction check is done by the CPU control unit
 
-- Zbb - Basic bit-manipulation instructions --
cmd(op_andn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
cmd(op_orn_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
cmd(op_xnor_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
--
cmd(op_max_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
cmd(op_min_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
cmd(op_zexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
--
cmd(op_orcb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") else '0';
--
cmd(op_clz_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "000") else '0';
cmd(op_ctz_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "001") else '0';
cmd(op_cpop_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "010") else '0';
cmd(op_sextb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") else '0';
cmd(op_sexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") else '0';
cmd(op_rol_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "001") and (ctrl_i(ctrl_ir_opcode7_5_c) = '1') else '0';
cmd(op_ror_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
cmd(op_rev8_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
 
 
-- Co-Processor Controller ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
coprocessor_ctrl: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
ctrl_state <= S_IDLE;
cmd_buf <= (others => def_rst_val_c);
rs1_reg <= (others => def_rst_val_c);
rs2_reg <= (others => def_rst_val_c);
less_ff <= def_rst_val_c;
shifter.start <= '0';
valid <= '0';
elsif rising_edge(clk_i) then
-- defaults --
shifter.start <= '0';
valid <= '0';
 
-- fsm --
case ctrl_state is
 
when S_IDLE => -- wait for operation trigger
-- ------------------------------------------------------------
if (start_i = '1') then
less_ff <= cmp_i(cmp_less_c);
cmd_buf <= cmd;
rs1_reg <= rs1_i;
rs2_reg <= rs2_i;
if ((cmd(op_clz_c) or cmd(op_ctz_c) or cmd(op_cpop_c) or cmd(op_ror_c) or cmd(op_rol_c)) = '1') then -- multi-cycle shift operation
if (FAST_SHIFT_EN = false) then -- default: iterative computation
shifter.start <= '1';
ctrl_state <= S_START_SHIFT;
else -- full-parallel computation
ctrl_state <= S_BUSY_SHIFT;
end if;
else
valid <= '1';
ctrl_state <= S_IDLE;
end if;
end if;
 
when S_START_SHIFT => -- one cycle delay to start shift operation
-- ------------------------------------------------------------
ctrl_state <= S_BUSY_SHIFT;
 
when S_BUSY_SHIFT => -- wait for multi-cycle shift operation to finish
-- ------------------------------------------------------------
if (shifter.run = '0') then
valid <= '1';
ctrl_state <= S_IDLE;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
ctrl_state <= S_IDLE;
 
end case;
end if;
end process coprocessor_ctrl;
 
 
-- Shift Amount ---------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- we could also use ALU's internal operand B - but we are having a local version here in order to allow
-- better logic combination inside the ALU (since that is the critical path of the CPU)
shamt <= ctrl_i(ctrl_ir_funct12_0_c+shamt'left downto ctrl_ir_funct12_0_c) when (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else rs2_reg(shamt'left downto 0);
 
 
-- Shifter Function Core (iterative: small but slow) --------------------------------------
-- -------------------------------------------------------------------------------------------
serial_shifter:
if (FAST_SHIFT_EN = false) generate
shifter_unit: process(rstn_i, clk_i)
variable new_bit_v : std_ulogic;
begin
if (rstn_i = '0') then
shifter.cnt <= (others => def_rst_val_c);
shifter.sreg <= (others => def_rst_val_c);
shifter.cnt_max <= (others => def_rst_val_c);
shifter.bcnt <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
if (shifter.start = '1') then -- trigger new shift
shifter.cnt <= (others => '0');
-- shift operand --
if (cmd_buf(op_clz_c) = '1') or (cmd_buf(op_rol_c) = '1') then -- count LEADING zeros / rotate LEFT
shifter.sreg <= bit_rev_f(rs1_reg); -- reverse - we can only do right shifts here
else -- ctz, cpop, ror
shifter.sreg <= rs1_reg;
end if;
-- max shift amount --
if (cmd_buf(op_cpop_c) = '1') then -- population count
shifter.cnt_max <= (others => '0');
shifter.cnt_max(shifter.cnt_max'left) <= '1';
else
shifter.cnt_max <= '0' & shamt;
end if;
shifter.bcnt <= (others => '0');
elsif (shifter.run = '1') then -- right shifts only
new_bit_v := ((cmd_buf(op_ror_c) or cmd_buf(op_rol_c)) and shifter.sreg(0)) or (cmd_buf(op_clz_c) or cmd_buf(op_ctz_c));
shifter.sreg <= new_bit_v & shifter.sreg(shifter.sreg'left downto 1); -- ro[r/l]/lsr(for counting)
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) + 1); -- iteration counter
if (shifter.sreg(0) = '1') then
shifter.bcnt <= std_ulogic_vector(unsigned(shifter.bcnt) + 1); -- bit counter
end if;
end if;
end if;
end process shifter_unit;
end generate;
 
-- run control --
serial_shifter_ctrl:
if (FAST_SHIFT_EN = false) generate
shifter_unit_ctrl: process(cmd_buf, shifter)
begin
-- keep shifting until ... --
if (cmd_buf(op_clz_c) = '1') or (cmd_buf(op_ctz_c) = '1') then -- count leading/trailing zeros
shifter.run <= not shifter.sreg(0);
else -- population count / rotate
if (shifter.cnt = shifter.cnt_max) then
shifter.run <= '0';
else
shifter.run <= '1';
end if;
end if;
end process shifter_unit_ctrl;
end generate;
 
 
-- Shifter Function Core (parallel: fast but large) ---------------------------------------
-- -------------------------------------------------------------------------------------------
barrel_shifter_async_sync:
if (FAST_SHIFT_EN = true) generate
shifter_unit_fast: process(rstn_i, clk_i)
variable new_bit_v : std_ulogic;
begin
if (rstn_i = '0') then
shifter.cnt <= (others => def_rst_val_c);
shifter.sreg <= (others => def_rst_val_c);
shifter.bcnt <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
-- population count --
shifter.bcnt <= std_ulogic_vector(to_unsigned(popcount_f(rs1_reg), shifter.bcnt'length));
-- count leading/trailing zeros --
if cmd_buf(op_clz_c) = '1' then -- leading
shifter.cnt <= std_ulogic_vector(to_unsigned(leading_zeros_f(rs1_reg), shifter.cnt'length));
else -- trailing
shifter.cnt <= std_ulogic_vector(to_unsigned(leading_zeros_f(bit_rev_f(rs1_reg)), shifter.cnt'length));
end if;
-- barrel shifter --
shifter.sreg <= bs_level(0); -- rol/ror[i]
end if;
end process shifter_unit_fast;
shifter.run <= '0'; -- we are done already!
end generate;
 
-- barrel shifter array --
barrel_shifter_async:
if (FAST_SHIFT_EN = true) generate
shifter_unit_async: process(rs1_reg, shamt, cmd_buf, bs_level)
begin
-- input level: convert left shifts to right shifts --
if (cmd_buf(op_rol_c) = '1') then -- is left shift?
bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_reg); -- reverse bit order of input operand
else
bs_level(index_size_f(data_width_c)) <= rs1_reg;
end if;
 
-- shifter array --
for i in index_size_f(data_width_c)-1 downto 0 loop
if (shamt(i) = '1') then
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= bs_level(i+1)((2**i)-1 downto 0);
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
else
bs_level(i) <= bs_level(i+1);
end if;
end loop;
end process shifter_unit_async;
end generate;
 
 
-- Operation Results ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- logic with negate --
res_int(op_andn_c) <= rs1_reg and (not rs2_reg); -- logical and-not
res_int(op_orn_c) <= rs1_reg or (not rs2_reg); -- logical or-not
res_int(op_xnor_c) <= rs1_reg xor (not rs2_reg); -- logical xor-not
 
-- count leading/trailing zeros --
res_int(op_clz_c)(data_width_c-1 downto shifter.cnt'left+1) <= (others => '0');
res_int(op_clz_c)(shifter.cnt'left downto 0) <= shifter.cnt;
res_int(op_ctz_c) <= (others => '0'); -- unused/redundant
 
-- count set bits --
res_int(op_cpop_c)(data_width_c-1 downto shifter.bcnt'left+1) <= (others => '0');
res_int(op_cpop_c)(shifter.bcnt'left downto 0) <= shifter.bcnt;
 
-- min/max select --
res_int(op_min_c) <= rs1_reg when ((less_ff xor cmd_buf(op_max_c)) = '1') else rs2_reg;
res_int(op_max_c) <= (others => '0'); -- unused/redundant
 
-- sign-extension --
res_int(op_sextb_c)(data_width_c-1 downto 8) <= (others => rs1_reg(7));
res_int(op_sextb_c)(7 downto 0) <= rs1_reg(7 downto 0); -- sign-extend byte
res_int(op_sexth_c)(data_width_c-1 downto 16) <= (others => rs1_reg(15));
res_int(op_sexth_c)(15 downto 0) <= rs1_reg(15 downto 0); -- sign-extend half-word
res_int(op_zexth_c)(data_width_c-1 downto 16) <= (others => '0');
res_int(op_zexth_c)(15 downto 0) <= rs1_reg(15 downto 0); -- zero-extend half-word
 
-- rotate right/left --
res_int(op_ror_c) <= shifter.sreg;
res_int(op_rol_c) <= bit_rev_f(shifter.sreg); -- reverse to compensate internal right-only shifts
 
-- or-combine.byte --
or_combine_gen:
for i in 0 to (data_width_c/8)-1 generate -- sub-byte loop
res_int(op_orcb_c)(i*8+7 downto i*8) <= (others => or_reduce_f(rs1_reg(i*8+7 downto i*8)));
end generate; -- i
 
-- reversal.8 (byte swap) --
res_int(op_rev8_c) <= bswap32_f(rs1_reg);
 
 
-- Output Selector ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
res_out(op_andn_c) <= res_int(op_andn_c) when (cmd_buf(op_andn_c) = '1') else (others => '0');
res_out(op_orn_c) <= res_int(op_orn_c) when (cmd_buf(op_orn_c) = '1') else (others => '0');
res_out(op_xnor_c) <= res_int(op_xnor_c) when (cmd_buf(op_xnor_c) = '1') else (others => '0');
res_out(op_clz_c) <= res_int(op_clz_c) when ((cmd_buf(op_clz_c) or cmd_buf(op_ctz_c)) = '1') else (others => '0');
res_out(op_ctz_c) <= (others => '0'); -- unused/redundant
res_out(op_cpop_c) <= res_int(op_cpop_c) when (cmd_buf(op_cpop_c) = '1') else (others => '0');
res_out(op_min_c) <= res_int(op_min_c) when ((cmd_buf(op_min_c) or cmd_buf(op_max_c)) = '1') else (others => '0');
res_out(op_max_c) <= (others => '0'); -- unused/redundant
res_out(op_sextb_c) <= res_int(op_sextb_c) when (cmd_buf(op_sextb_c) = '1') else (others => '0');
res_out(op_sexth_c) <= res_int(op_sexth_c) when (cmd_buf(op_sexth_c) = '1') else (others => '0');
res_out(op_zexth_c) <= res_int(op_zexth_c) when (cmd_buf(op_zexth_c) = '1') else (others => '0');
res_out(op_ror_c) <= res_int(op_ror_c) when (cmd_buf(op_ror_c) = '1') else (others => '0');
res_out(op_rol_c) <= res_int(op_rol_c) when (cmd_buf(op_rol_c) = '1') else (others => '0');
res_out(op_orcb_c) <= res_int(op_orcb_c) when (cmd_buf(op_orcb_c) = '1') else (others => '0');
res_out(op_rev8_c) <= res_int(op_rev8_c) when (cmd_buf(op_rev8_c) = '1') else (others => '0');
 
 
-- Output Gate ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
output_gate: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
res_o <= (others => def_rst_val_c);
elsif rising_edge(clk_i) then
res_o <= (others => '0');
if (valid = '1') then
res_o <= res_out(op_andn_c) or res_out(op_orn_c) or res_out(op_xnor_c) or
res_out(op_clz_c) or res_out(op_cpop_c) or -- res_out(op_ctz_c) is unused here
res_out(op_min_c) or -- res_out(op_max_c) is unused here
res_out(op_sextb_c) or res_out(op_sexth_c) or res_out(op_zexth_c) or
res_out(op_ror_c) or res_out(op_rol_c) or
res_out(op_orcb_c) or res_out(op_rev8_c);
end if;
end if;
end process output_gate;
 
-- valid output --
valid_o <= valid;
 
 
end neorv32_cpu_cp_bitmanip_rtl;
/core/neorv32_imem.vhd
1,10 → 1,8
-- #################################################################################################
-- # << NEORV32 - Processor-internal instruction memory (IMEM) >> #
-- # ********************************************************************************************* #
-- # This memory includes the in-place executable image of the application. See the #
-- # This memory optionally includes the in-place executable image of the application. See the #
-- # processor's documentary to get more information. #
-- # Note: IMEM is split up into four 8-bit memories - some EDA tools have problems to synthesize #
-- # a pre-initialized 32-bit memory with byte-enable signals. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
/core/neorv32_package.vhd
64,7 → 64,7
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050900"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060000"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
-- External Interface Types ---------------------------------------------------------------
102,6 → 102,8
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector;
function char_to_lower_f(ch : character) return character;
function str_equal_f(str0 : string; str1 : string) return boolean;
function popcount_f(input : std_ulogic_vector) return natural;
function leading_zeros_f(input : std_ulogic_vector) return natural;
impure function mem32_init_f(init : mem32_t; depth : natural) return mem32_t;
 
-- Internal (auto-generated) Configurations -----------------------------------------------
189,14 → 191,30
constant pwm_duty13_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffeb8";
constant pwm_duty14_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffebc";
 
-- Stream link interface (SLINK) --
-- Stream Link Interface (SLINK) --
constant slink_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffec0"; -- base address
constant slink_size_c : natural := 16*4; -- module's address space size in bytes
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00"; -- base address
--constant reserved_size_c : natural := 32*4; -- module's address space size in bytes
--constant reserved_size_c : natural := 16*4; -- module's address space size in bytes
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff40"; -- base address
--constant reserved_size_c : natural := 8*4; -- module's address space size in bytes
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff60"; -- base address
--constant reserved_size_c : natural := 4*4; -- module's address space size in bytes
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff70"; -- base address
--constant reserved_size_c : natural := 2*4; -- module's address space size in bytes
 
-- reserved --
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff78"; -- base address
--constant reserved_size_c : natural := 2*4; -- module's address space size in bytes
 
-- External Interrupt Controller (XIRQ) --
constant xirq_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; -- base address
constant xirq_size_c : natural := 4*4; -- module's address space size in bytes
241,7 → 259,7
constant wdt_size_c : natural := 1*4; -- module's address space size in bytes
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffbc";
 
-- reserved --
-- General Purpose Input/Output Controller (GPIO) --
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; -- base address
constant gpio_size_c : natural := 4*4; -- module's address space size in bytes
constant gpio_in_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0";
501,7 → 519,7
constant csr_frm_c : std_ulogic_vector(11 downto 0) := x"002";
constant csr_fcsr_c : std_ulogic_vector(11 downto 0) := x"003";
-- machine trap setup --
constant csr_class_setup_c : std_ulogic_vector(07 downto 0) := x"30"; -- trap setup
constant csr_class_setup_c : std_ulogic_vector(08 downto 0) := x"30" & '0'; -- trap setup
constant csr_mstatus_c : std_ulogic_vector(11 downto 0) := x"300";
constant csr_misa_c : std_ulogic_vector(11 downto 0) := x"301";
constant csr_mie_c : std_ulogic_vector(11 downto 0) := x"304";
542,7 → 560,7
constant csr_mhpmevent30_c : std_ulogic_vector(11 downto 0) := x"33e";
constant csr_mhpmevent31_c : std_ulogic_vector(11 downto 0) := x"33f";
-- machine trap handling --
constant csr_class_trap_c : std_ulogic_vector(07 downto 0) := x"34"; -- machine trap handling
constant csr_class_trap_c : std_ulogic_vector(08 downto 0) := x"34" & '0'; -- machine trap handling
constant csr_mscratch_c : std_ulogic_vector(11 downto 0) := x"340";
constant csr_mepc_c : std_ulogic_vector(11 downto 0) := x"341";
constant csr_mcause_c : std_ulogic_vector(11 downto 0) := x"342";
708,7 → 726,6
constant csr_cycle_c : std_ulogic_vector(11 downto 0) := x"c00";
constant csr_time_c : std_ulogic_vector(11 downto 0) := x"c01";
constant csr_instret_c : std_ulogic_vector(11 downto 0) := x"c02";
--
constant csr_cycleh_c : std_ulogic_vector(11 downto 0) := x"c80";
constant csr_timeh_c : std_ulogic_vector(11 downto 0) := x"c81";
constant csr_instreth_c : std_ulogic_vector(11 downto 0) := x"c82";
718,14 → 735,12
constant csr_mimpid_c : std_ulogic_vector(11 downto 0) := x"f13";
constant csr_mhartid_c : std_ulogic_vector(11 downto 0) := x"f14";
constant csr_mconfigptr_c : std_ulogic_vector(11 downto 0) := x"f15";
-- <<< custom (NEORV32-specific) read-only CSRs >>> --
constant csr_mzext_c : std_ulogic_vector(11 downto 0) := x"fc0";
 
-- Co-Processor IDs -----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant cp_sel_shifter_c : std_ulogic_vector(1 downto 0) := "00"; -- shift operation
constant cp_sel_muldiv_c : std_ulogic_vector(1 downto 0) := "01"; -- multiplication/division operations ('M' extension)
--constant cp_sel_bitmanip_c : std_ulogic_vector(1 downto 0) := "10"; -- bit manipulation ('B' extension)
constant cp_sel_shifter_c : std_ulogic_vector(1 downto 0) := "00"; -- shift operations (base ISA)
constant cp_sel_muldiv_c : std_ulogic_vector(1 downto 0) := "01"; -- multiplication/division operations ('M' extensions)
constant cp_sel_bitmanip_c : std_ulogic_vector(1 downto 0) := "10"; -- bit manipulation ('B' extensions)
constant cp_sel_fpu_c : std_ulogic_vector(1 downto 0) := "11"; -- floating-point unit ('Zfinx' extension)
 
-- ALU Function Codes ---------------------------------------------------------------------
872,7 → 887,6
generic (
-- General --
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
INT_BOOTLOADER_EN : boolean := false; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- On-Chip Debugger (OCD) --
883,6 → 897,7
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_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
1029,6 → 1044,7
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
1104,6 → 1120,7
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
1193,6 → 1210,7
generic (
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
-- Extension Options --
1264,6 → 1282,28
);
end component;
 
-- Component: CPU Co-Processor Bit-Manipulation Unit ('B' extension) ----------------------
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_cp_bitmanip is
generic (
FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
start_i : in std_ulogic; -- trigger operation
-- data input --
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
-- result and status --
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
valid_o : out std_ulogic -- data output valid
);
end component;
 
-- Component: CPU Co-Processor 32-bit FPU ('Zfinx' extension) -----------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_cp_fpu
1856,39 → 1896,53
component neorv32_sysinfo
generic (
-- General --
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
-- Processor peripherals --
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural -- number of external interrupt (XIRQ) channels to implement
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural -- number of external interrupt (XIRQ) channels to implement
);
port (
-- host access --
2265,6 → 2319,36
end if;
end function str_equal_f;
 
-- Function: Population count (number of set bits) ----------------------------------------
-- -------------------------------------------------------------------------------------------
function popcount_f(input : std_ulogic_vector) return natural is
variable cnt_v : natural range 0 to input'length;
begin
cnt_v := 0;
for i in input'length-1 downto 0 loop
if (input(i) = '1') then
cnt_v := cnt_v + 1;
end if;
end loop; -- i
return cnt_v;
end function popcount_f;
 
-- Function: Count leading zeros ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
function leading_zeros_f(input : std_ulogic_vector) return natural is
variable cnt_v : natural range 0 to input'length;
begin
cnt_v := 0;
for i in input'length-1 downto 0 loop
if (input(i) = '0') then
cnt_v := cnt_v + 1;
else
exit;
end if;
end loop; -- i
return cnt_v;
end function leading_zeros_f;
 
-- Function: Initialize mem32_t array from another mem32_t array --------------------------
-- -------------------------------------------------------------------------------------------
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed
/core/neorv32_sysinfo.vhd
45,39 → 45,53
entity neorv32_sysinfo is
generic (
-- General --
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb : boolean; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
-- Extension Options --
FAST_MUL_EN : boolean; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS : natural; -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural; -- number of implemented HPM counters (0..29)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN : boolean; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN : boolean; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
ICACHE_EN : boolean; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural; -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE : natural; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural; -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
MEM_EXT_EN : boolean; -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN : boolean; -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
ON_CHIP_DEBUGGER_EN : boolean; -- implement OCD?
-- Processor peripherals --
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural -- number of external interrupt (XIRQ) channels to implement
IO_GPIO_EN : boolean; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural; -- number of PWM channels to implement
IO_WDT_EN : boolean; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean; -- implement custom functions subsystem (CFS)?
IO_SLINK_EN : boolean; -- implement stream link interface?
IO_NEOLED_EN : boolean; -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH : natural -- number of external interrupt (XIRQ) channels to implement
);
port (
-- host access --
121,8 → 135,24
-- SYSINFO(0): Processor (primary) clock frequency --
sysinfo_mem(0) <= std_ulogic_vector(to_unsigned(CLOCK_FREQUENCY, 32));
 
-- SYSINFO(1): Custom user code/ID --
sysinfo_mem(1) <= USER_CODE;
-- SYSINFO(1): CPU configuration --
sysinfo_mem(1)(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr
sysinfo_mem(1)(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei
sysinfo_mem(1)(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul
sysinfo_mem(1)(03) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zbb); -- Zbb
--
sysinfo_mem(1)(04) <= '0'; -- reserved
--
sysinfo_mem(1)(05) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative")
sysinfo_mem(1)(07 downto 06) <= "00" when (CPU_CNT_WIDTH = 64) else "10" when (CPU_CNT_WIDTH = 0) else "01"; -- CPU counter size: Zxscnt | Zxnocnt
sysinfo_mem(1)(08) <= bool_to_ulogic_f(boolean(PMP_NUM_REGIONS > 0)); -- PMP (physical memory protection)
sysinfo_mem(1)(09) <= bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- HPM (hardware performance monitors)
sysinfo_mem(1)(10) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- RISC-V debug mode
--
sysinfo_mem(1)(29 downto 11) <= (others => '0'); -- reserved
-- misc --
sysinfo_mem(1)(30) <= bool_to_ulogic_f(FAST_MUL_EN); -- DSP-based multiplication (M extension only)
sysinfo_mem(1)(31) <= bool_to_ulogic_f(FAST_SHIFT_EN); -- parallel logic for shifts (like barrel shifters)
 
-- SYSINFO(2): Implemented processor devices/features --
-- Memory --
/core/neorv32_top.vhd
2,10 → 2,13
-- # << NEORV32 - Processor Top Entity >> #
-- # ********************************************************************************************* #
-- # This is the top entity of the NEORV32 PROCESSOR. Instantiate this unit in your own project #
-- # and define all the configuration generics according to your needs. Alternatively, you can use #
-- # one of the alternative top entities provided in the "rtl/templates" folder. #
-- # and define all the configuration generics according to your needs or use one of the #
-- # pre-defined template wrappers. #
-- # #
-- # Check out the processor's documentation for more information. #
-- # 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 #
-- # #
49,7 → 52,6
generic (
-- General --
CLOCK_FREQUENCY : natural; -- clock frequency of clk_i in Hz
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
INT_BOOTLOADER_EN : boolean := false; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
 
62,6 → 64,7
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_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
110,8 → 113,8
 
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 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
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_EN : boolean := false; -- implement general purpose input/output port unit (GPIO)?
233,7 → 236,7
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
 
-- reset generator --
signal rstn_gen : std_ulogic_vector(7 downto 0);
signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via (for FPGAs only)
signal ext_rstn : std_ulogic;
signal sys_rstn : std_ulogic;
signal wdt_rstn : std_ulogic;
461,6 → 464,7
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
534,10 → 538,10
msw_irq_ff <= msw_irq_i when rising_edge(clk_i);
mext_irq_ff <= mext_irq_i when rising_edge(clk_i);
-- rising-edge detector --
x_nm_irq <= nm_irq_i and (not nm_irq_ff);
x_mtime_irq <= mtime_irq_i and (not mtime_irq_ff);
x_msw_irq <= msw_irq_i and (not msw_irq_ff);
x_mext_irq <= mext_irq_i and (not mext_irq_ff);
x_nm_irq <= nm_irq_i and (not nm_irq_ff);
x_mtime_irq <= mtime_irq_i and (not mtime_irq_ff);
x_msw_irq <= msw_irq_i and (not msw_irq_ff);
x_mext_irq <= mext_irq_i and (not mext_irq_ff);
 
-- fast interrupts --
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout
1358,39 → 1362,53
neorv32_sysinfo_inst: neorv32_sysinfo
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
USER_CODE => USER_CODE, -- custom user code
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension?
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical memory protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
-- internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity (min 1), has to be a power 2
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 2), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity (min 1), has to be a power 2
-- External memory interface --
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
-- On-Chip Debugger --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement OCD?
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement OCD?
-- Processor peripherals --
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_SLINK_EN => io_slink_en_c, -- implement stream link interface?
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH => XIRQ_NUM_CH -- number of external interrupt (XIRQ) channels to implement
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_SLINK_EN => io_slink_en_c, -- implement stream link interface?
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)?
IO_XIRQ_NUM_CH => XIRQ_NUM_CH -- number of external interrupt (XIRQ) channels to implement
)
port map (
-- host access --
/processor_templates/README.md
0,0 → 1,3
# SoC Templates
 
:construction: Work in Progress :construction:
/processor_templates/neorv32_ProcessorTop_Minimal.vhd
0,0 → 1,246
-- #################################################################################################
-- # << NEORV32 - Minimal setup without a bootloader >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
 
entity neorv32_ProcessorTop_Minimal is
generic (
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic 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_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 8*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- Processor peripherals --
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)?
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := false -- implement watch dog timer (WDT)?
);
port (
clk_i : in std_logic;
rstn_i : in std_logic;
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0)
);
end entity;
 
architecture neorv32_ProcessorTop_Minimal_rtl of neorv32_ProcessorTop_Minimal is
 
begin
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => false, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit)
 
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => false, -- implement on-chip debugger?
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- External memory interface --
MEM_EXT_EN => false, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled)
 
-- Processor peripherals --
IO_GPIO_EN => false, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => false, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => false, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => false, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => false, -- implement true random number generator (TRNG)?
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
 
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i => '0', -- low-active TAP reset (optional)
jtag_tck_i => '0', -- serial clock
jtag_tdi_i => '0', -- serial data input
jtag_tdo_o => open, -- serial data output
jtag_tms_i => '0', -- mode select
 
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o => open, -- request tag
wb_adr_o => open, -- address
wb_dat_i => (others => '0'), -- read data
wb_dat_o => open, -- write data
wb_we_o => open, -- read/write
wb_sel_o => open, -- byte enable
wb_stb_o => open, -- strobe
wb_cyc_o => open, -- valid cycle
wb_lock_o => open, -- exclusive access request
wb_ack_i => '0', -- transfer acknowledge
wb_err_i => '0', -- transfer error
 
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => open, -- parallel output
gpio_i => (others => '0'), -- parallel input
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => open, -- UART0 send data
uart0_rxd_i => '0', -- UART0 receive data
uart0_rts_o => open, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i => '0', -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o => open, -- UART1 send data
uart1_rxd_i => '0', -- UART1 receive data
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional
 
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o => open, -- SPI serial clock
spi_sdo_o => open, -- controller data out, peripheral data in
spi_sdi_i => '0', -- controller data in, peripheral data out
spi_csn_o => open, -- SPI CS
 
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io => open, -- twi serial data line
twi_scl_io => open, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
cfs_out_o => open, -- custom CFS outputs conduit
 
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o => open, -- async serial data line
 
-- System time --
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true)
 
-- Interrupts --
nm_irq_i => '0', -- non-maskable interrupt
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i => '0', -- machine software interrupt
mext_irq_i => '0' -- machine external interrupt
);
 
end architecture;
/processor_templates/neorv32_ProcessorTop_MinimalBoot.vhd
0,0 → 1,267
-- #################################################################################################
-- # << NEORV32 - Minimal setup with the bootloader enabled >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
 
entity neorv32_ProcessorTop_MinimalBoot is
generic (
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := true; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := true; -- 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_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 64*1024; -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true -- implement watch dog timer (WDT)?
);
port (
clk_i : in std_logic;
rstn_i : in std_logic;
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_ulogic_vector(3 downto 0);
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart_txd_o : out std_ulogic; -- UART0 send data
uart_rxd_i : in std_ulogic := '0'; -- UART0 receive data
uart_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0)
);
end entity;
 
architecture neorv32_ProcessorTop_MinimalBoot_rtl of neorv32_ProcessorTop_MinimalBoot is
 
-- internal IO connection --
signal con_gpio_o : std_ulogic_vector(63 downto 0);
 
begin
 
-- IO Connection --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- GPIO --
gpio_o <= con_gpio_o(3 downto 0);
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN,-- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit)
 
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => false, -- implement on-chip debugger?
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- External memory interface --
MEM_EXT_EN => false, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled)
 
-- Processor peripherals --
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => false, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => false, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => false, -- implement true random number generator (TRNG)?
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
 
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i => '0', -- low-active TAP reset (optional)
jtag_tck_i => '0', -- serial clock
jtag_tdi_i => '0', -- serial data input
jtag_tdo_o => open, -- serial data output
jtag_tms_i => '0', -- mode select
 
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o => open, -- request tag
wb_adr_o => open, -- address
wb_dat_i => (others => '0'), -- read data
wb_dat_o => open, -- write data
wb_we_o => open, -- read/write
wb_sel_o => open, -- byte enable
wb_stb_o => open, -- strobe
wb_cyc_o => open, -- valid cycle
wb_lock_o => open, -- exclusive access request
wb_ack_i => '0', -- transfer acknowledge
wb_err_i => '0', -- transfer error
 
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => con_gpio_o, -- parallel output
gpio_i => (others => '0'), -- parallel input
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart_txd_o, -- UART0 send data
uart0_rxd_i => uart_rxd_i, -- UART0 receive data
uart0_rts_o => uart_rts_o, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i => uart_cts_i, -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o => open, -- UART1 send data
uart1_rxd_i => '0', -- UART1 receive data
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional
 
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o => open, -- SPI serial clock
spi_sdo_o => open, -- controller data out, peripheral data in
spi_sdi_i => '0', -- controller data in, peripheral data out
spi_csn_o => open, -- SPI CS
 
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io => open, -- twi serial data line
twi_scl_io => open, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
cfs_out_o => open, -- custom CFS outputs conduit
 
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o => open, -- async serial data line
 
-- System time --
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true)
 
-- Interrupts --
nm_irq_i => '0', -- non-maskable interrupt
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i => '0', -- machine software interrupt
mext_irq_i => '0' -- machine external interrupt
);
 
end architecture;
/processor_templates/neorv32_ProcessorTop_UP5KDemo.vhd
0,0 → 1,307
-- #################################################################################################
-- # << NEORV32 - Example setup for boards with UP5K devices >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
 
entity neorv32_ProcessorTop_UP5KDemo is
generic (
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
 
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger?
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := true; -- implement atomic extension?
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := true; -- 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_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 64*1024; -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true -- implement watch dog timer (WDT)?
);
port (
clk_i : in std_logic;
rstn_i : in std_logic;
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_i : in std_ulogic_vector(3 downto 0);
gpio_o : out std_ulogic_vector(3 downto 0);
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart_txd_o : out std_ulogic; -- UART0 send data
uart_rxd_i : in std_ulogic := '0'; -- UART0 receive data
uart_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- SPI to on-board flash --
flash_sck_o : out std_ulogic;
flash_sdo_o : out std_ulogic;
flash_sdi_i : in std_ulogic;
flash_csn_o : out std_ulogic; -- NEORV32.SPI_CS(0)
 
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o : out std_ulogic;
spi_sdo_o : out std_ulogic;
spi_sdi_i : in std_ulogic;
spi_csn_o : out std_ulogic; -- NEORV32.SPI_CS(1)
 
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io : inout std_logic;
twi_scl_io : inout std_logic;
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0)
);
end entity;
 
architecture neorv32_ProcessorTop_UP5KDemo_rtl of neorv32_ProcessorTop_UP5KDemo is
 
-- internal IO connection --
signal con_gpio_o : std_ulogic_vector(63 downto 0);
signal con_gpio_i : std_ulogic_vector(63 downto 0);
signal con_spi_sck : std_ulogic;
signal con_spi_sdi : std_ulogic;
signal con_spi_sdo : std_ulogic;
signal con_spi_csn : std_ulogic_vector(07 downto 0);
 
begin
 
-- IO Connection --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- SPI: on-board flash --
flash_sck_o <= con_spi_sck;
flash_sdo_o <= con_spi_sdo;
flash_csn_o <= con_spi_csn(0);
 
-- SPI: user port --
spi_sck_o <= con_spi_sck;
spi_sdo_o <= con_spi_sdo;
spi_csn_o <= con_spi_csn(1);
 
con_spi_sdi <= flash_sdi_i when (con_spi_csn(0) = '0') else spi_sdi_i;
 
-- GPIO --
gpio_o <= con_gpio_o(3 downto 0);
con_gpio_i(03 downto 0) <= gpio_i;
con_gpio_i(63 downto 4) <= (others => '0');
 
-- The core of the problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_inst: entity neorv32.neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => true, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit)
 
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger?
 
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
 
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
 
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
 
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64)
 
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
 
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
 
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
 
-- External memory interface --
MEM_EXT_EN => false, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled)
 
-- Processor peripherals --
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => false, -- implement true random number generator (TRNG)?
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
 
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i => '0', -- low-active TAP reset (optional)
jtag_tck_i => '0', -- serial clock
jtag_tdi_i => '0', -- serial data input
jtag_tdo_o => open, -- serial data output
jtag_tms_i => '0', -- mode select
 
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o => open, -- request tag
wb_adr_o => open, -- address
wb_dat_i => (others => '0'), -- read data
wb_dat_o => open, -- write data
wb_we_o => open, -- read/write
wb_sel_o => open, -- byte enable
wb_stb_o => open, -- strobe
wb_cyc_o => open, -- valid cycle
wb_lock_o => open, -- exclusive access request
wb_ack_i => '0', -- transfer acknowledge
wb_err_i => '0', -- transfer error
 
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
 
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => con_gpio_o, -- parallel output
gpio_i => con_gpio_i, -- parallel input
 
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart_txd_o, -- UART0 send data
uart0_rxd_i => uart_rxd_i, -- UART0 receive data
uart0_rts_o => uart_rts_o, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i => uart_cts_i, -- hw flow control: UART0.TX allowed to transmit, low-active, optional
 
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o => open, -- UART1 send data
uart1_rxd_i => '0', -- UART1 receive data
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional
 
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o => con_spi_sck, -- SPI serial clock
spi_sdo_o => con_spi_sdo, -- controller data out, peripheral data in
spi_sdi_i => con_spi_sdi, -- controller data in, peripheral data out
spi_csn_o => con_spi_csn, -- SPI CS
 
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io => twi_sda_io, -- twi serial data line
twi_scl_io => twi_scl_io, -- twi serial clock line
 
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o, -- pwm channels
 
-- Custom Functions Subsystem IO --
cfs_in_i => (others => '0'), -- custom CFS inputs conduit
cfs_out_o => open, -- custom CFS outputs conduit
 
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o => open, -- async serial data line
 
-- System time --
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true)
 
-- Interrupts --
nm_irq_i => '0', -- non-maskable interrupt
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i => '0', -- machine software interrupt
mext_irq_i => '0' -- machine external interrupt
);
 
end architecture;
/system_integration/neorv32_ProcessorTop_stdlogic.vhd
0,0 → 1,471
-- #################################################################################################
-- # << NEORV32 - Processor Top Entity with Resolved Port Signals (std_logic/std_logic_vector) >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_ProcessorTop_stdlogic is
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic 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 muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- External memory interface --
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
-- Stream link interface --
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8)
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8)
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)?
);
port (
-- Global control --
clk_i : in std_logic := '0'; -- global clock, rising edge
rstn_i : in std_logic := '0'; -- global reset, low-active, async
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i : in std_logic := '0'; -- low-active TAP reset (optional)
jtag_tck_i : in std_logic := '0'; -- serial clock
jtag_tdi_i : in std_logic := '0'; -- serial data input
jtag_tdo_o : out std_logic; -- serial data output
jtag_tms_i : in std_logic := '0'; -- mode select
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o : out std_logic_vector(02 downto 0); -- tag
wb_adr_o : out std_logic_vector(31 downto 0); -- address
wb_dat_i : in std_logic_vector(31 downto 0) := (others => '0'); -- read data
wb_dat_o : out std_logic_vector(31 downto 0); -- write data
wb_we_o : out std_logic; -- read/write
wb_sel_o : out std_logic_vector(03 downto 0); -- byte enable
wb_stb_o : out std_logic; -- strobe
wb_cyc_o : out std_logic; -- valid cycle
wb_lock_o : out std_logic; -- exclusive access request
wb_ack_i : in std_logic := '0'; -- transfer acknowledge
wb_err_i : in std_logic := '0'; -- transfer error
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o : out std_logic; -- indicates an executed FENCE operation
fencei_o : out std_logic; -- indicates an executed FENCEI operation
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o : out sdata_8x32r_t; -- output data
slink_tx_val_o : out std_logic_vector(7 downto 0); -- valid output
slink_tx_rdy_i : in std_logic_vector(7 downto 0) := (others => '0'); -- ready to send
-- RX stream interfaces (available if SLINK_NUM_RX > 0) --
slink_rx_dat_i : in sdata_8x32r_t := (others => (others => '0')); -- input data
slink_rx_val_i : in std_logic_vector(7 downto 0) := (others => '0'); -- valid input
slink_rx_rdy_o : out std_logic_vector(7 downto 0); -- ready to receive
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_logic_vector(63 downto 0); -- parallel output
gpio_i : in std_logic_vector(63 downto 0) := (others => '0'); -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o : out std_logic; -- UART0 send data
uart0_rxd_i : in std_logic := '0'; -- UART0 receive data
uart0_rts_o : out std_logic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i : in std_logic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o : out std_logic; -- UART1 send data
uart1_rxd_i : in std_logic := '0'; -- UART1 receive data
uart1_rts_o : out std_logic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i : in std_logic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o : out std_logic; -- SPI serial clock
spi_sdo_o : out std_logic; -- controller data out, peripheral data in
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o : out std_logic; -- async serial data line
-- System time --
mtime_i : in std_logic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o : out std_logic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true)
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels
-- CPU Interrupts --
nm_irq_i : in std_logic := '0'; -- non-maskable interrupt
mtime_irq_i : in std_logic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i : in std_logic := '0'; -- machine software interrupt
mext_irq_i : in std_logic := '0' -- machine external interrupt
);
end entity;
 
architecture neorv32_ProcessorTop_stdlogic_rtl of neorv32_ProcessorTop_stdlogic is
 
-- type conversion --
constant IO_CFS_CONFIG_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(IO_CFS_CONFIG);
constant XIRQ_TRIGGER_TYPE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_TYPE);
constant XIRQ_TRIGGER_POLARITY_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_POLARITY);
--
signal clk_i_int : std_ulogic;
signal rstn_i_int : std_ulogic;
--
signal jtag_trst_i_int :std_ulogic;
signal jtag_tck_i_int :std_ulogic;
signal jtag_tdi_i_int :std_ulogic;
signal jtag_tdo_o_int :std_ulogic;
signal jtag_tms_i_int :std_ulogic;
--
signal wb_tag_o_int : std_ulogic_vector(02 downto 0);
signal wb_adr_o_int : std_ulogic_vector(31 downto 0);
signal wb_dat_i_int : std_ulogic_vector(31 downto 0);
signal wb_dat_o_int : std_ulogic_vector(31 downto 0);
signal wb_we_o_int : std_ulogic;
signal wb_sel_o_int : std_ulogic_vector(03 downto 0);
signal wb_stb_o_int : std_ulogic;
signal wb_cyc_o_int : std_ulogic;
signal wb_lock_o_int : std_ulogic;
signal wb_ack_i_int : std_ulogic;
signal wb_err_i_int : std_ulogic;
--
signal fence_o_int : std_ulogic;
signal fencei_o_int : std_ulogic;
--
signal slink_tx_dat_o_int : sdata_8x32_t;
signal slink_tx_val_o_int : std_logic_vector(7 downto 0);
signal slink_tx_rdy_i_int : std_logic_vector(7 downto 0);
signal slink_rx_dat_i_int : sdata_8x32_t;
signal slink_rx_val_i_int : std_logic_vector(7 downto 0);
signal slink_rx_rdy_o_int : std_logic_vector(7 downto 0);
--
signal gpio_o_int : std_ulogic_vector(63 downto 0);
signal gpio_i_int : std_ulogic_vector(63 downto 0);
--
signal uart0_txd_o_int : std_ulogic;
signal uart0_rxd_i_int : std_ulogic;
signal uart0_rts_o_int : std_ulogic;
signal uart0_cts_i_int : std_ulogic;
--
signal uart1_txd_o_int : std_ulogic;
signal uart1_rxd_i_int : std_ulogic;
signal uart1_rts_o_int : std_ulogic;
signal uart1_cts_i_int : std_ulogic;
--
signal spi_sck_o_int : std_ulogic;
signal spi_sdo_o_int : std_ulogic;
signal spi_sdi_i_int : std_ulogic;
signal spi_csn_o_int : std_ulogic_vector(07 downto 0);
--
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0);
--
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0);
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0);
--
signal neoled_o_int : std_ulogic;
--
signal mtime_i_int : std_ulogic_vector(63 downto 0);
signal mtime_o_int : std_ulogic_vector(63 downto 0);
--
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
--
signal nm_irq_i_int : std_ulogic;
signal mtime_irq_i_int : std_ulogic;
signal msw_irq_i_int : std_ulogic;
signal mext_irq_i_int : std_ulogic;
 
begin
 
-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (hartid) (32-bit)
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (0..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- External memory interface --
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT, -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE => MEM_EXT_PIPE_MODE, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN => MEM_EXT_BIG_ENDIAN, -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX => MEM_EXT_ASYNC_RX, -- use register buffer for RX data when false
-- Stream link interface --
SLINK_NUM_TX => SLINK_NUM_TX, -- number of TX links (0..8)
SLINK_NUM_RX => SLINK_NUM_RX, -- number of TX links (0..8)
SLINK_TX_FIFO => SLINK_TX_FIFO, -- TX fifo depth, has to be a power of two
SLINK_RX_FIFO => SLINK_RX_FIFO, -- RX fifo depth, has to be a power of two
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE_INT, -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY_INT, -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits
IO_NEOLED_EN => IO_NEOLED_EN -- implement NeoPixel-compatible smart LED interface (NEOLED)?
)
port map (
-- Global control --
clk_i => clk_i_int, -- global clock, rising edge
rstn_i => rstn_i_int, -- global reset, low-active, async
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i => jtag_trst_i_int, -- low-active TAP reset (optional)
jtag_tck_i => jtag_tck_i_int, -- serial clock
jtag_tdi_i => jtag_tdi_i_int, -- serial data input
jtag_tdo_o => jtag_tdo_o_int, -- serial data output
jtag_tms_i => jtag_tms_i_int, -- mode select
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o => wb_tag_o_int, -- tag
wb_adr_o => wb_adr_o_int, -- address
wb_dat_i => wb_dat_i_int, -- read data
wb_dat_o => wb_dat_o_int, -- write data
wb_we_o => wb_we_o_int, -- read/write
wb_sel_o => wb_sel_o_int, -- byte enable
wb_stb_o => wb_stb_o_int, -- strobe
wb_cyc_o => wb_cyc_o_int, -- valid cycle
wb_lock_o => wb_lock_o_int, -- exclusive access request
wb_ack_i => wb_ack_i_int, -- transfer acknowledge
wb_err_i => wb_err_i_int, -- transfer error
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => fence_o_int, -- indicates an executed FENCE operation
fencei_o => fencei_o_int, -- indicates an executed FENCEI operation
-- TX stream interfaces (available if SLINK_NUM_TX > 0) --
slink_tx_dat_o => slink_tx_dat_o_int, -- output data
slink_tx_val_o => slink_tx_val_o_int, -- valid output
slink_tx_rdy_i => slink_tx_rdy_i_int, -- ready to send
-- RX stream interfaces (available if SLINK_NUM_RX > 0) --
slink_rx_dat_i => slink_rx_dat_i_int, -- input data
slink_rx_val_i => slink_rx_val_i_int, -- valid input
slink_rx_rdy_o => slink_rx_rdy_o_int, -- ready to receive
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => gpio_o_int, -- parallel output
gpio_i => gpio_i_int, -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart0_txd_o_int, -- UART0 send data
uart0_rxd_i => uart0_rxd_i_int, -- UART0 receive data
uart0_rts_o => uart0_rts_o_int, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i => uart0_cts_i_int, -- hw flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o => uart1_txd_o_int, -- UART1 send data
uart1_rxd_i => uart1_rxd_i_int, -- UART1 receive data
uart1_rts_o => uart1_rts_o_int, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i => uart1_cts_i_int, -- hw flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o => spi_sck_o_int, -- SPI serial clock
spi_sdo_o => spi_sdo_o_int, -- controller data out, peripheral data in
spi_sdi_i => spi_sdi_i_int, -- controller data in, peripheral data out
spi_csn_o => spi_csn_o_int, -- SPI CS
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io => twi_sda_io, -- twi serial data line
twi_scl_io => twi_scl_io, -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o_int, -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i => cfs_in_i_int, -- custom inputs
cfs_out_o => cfs_out_o_int, -- custom outputs
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o => neoled_o_int, -- async serial data line
-- System time --
mtime_i => mtime_i_int, -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o => mtime_o_int, -- current system time from int. MTIME (if IO_MTIME_EN = true)
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i => xirq_i_int, -- IRQ channels
-- CPU Interrupts --
nm_irq_i => nm_irq_i_int, -- non-maskable interrupt
mtime_irq_i => mtime_irq_i_int, -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i => msw_irq_i_int, -- machine software interrupt
mext_irq_i => mext_irq_i_int -- machine external interrupt
);
 
-- type conversion --
clk_i_int <= std_ulogic(clk_i);
rstn_i_int <= std_ulogic(rstn_i);
 
jtag_trst_i_int <= std_ulogic(jtag_trst_i);
jtag_tck_i_int <= std_ulogic(jtag_tck_i);
jtag_tdi_i_int <= std_ulogic(jtag_tdi_i);
jtag_tdo_o <= std_logic(jtag_tdo_o_int);
jtag_tms_i_int <= std_ulogic(jtag_tms_i);
 
wb_tag_o <= std_logic_vector(wb_tag_o_int);
wb_adr_o <= std_logic_vector(wb_adr_o_int);
wb_dat_i_int <= std_ulogic_vector(wb_dat_i);
wb_dat_o <= std_logic_vector(wb_dat_o_int);
wb_we_o <= std_logic(wb_we_o_int);
wb_sel_o <= std_logic_vector(wb_sel_o_int);
wb_stb_o <= std_logic(wb_stb_o_int);
wb_cyc_o <= std_logic(wb_cyc_o_int);
wb_lock_o <= std_logic(wb_lock_o_int);
wb_ack_i_int <= std_ulogic(wb_ack_i);
wb_err_i_int <= std_ulogic(wb_err_i);
 
fence_o <= std_logic(fence_o_int);
fencei_o <= std_logic(fencei_o_int);
 
slink_tx_val_o <= std_logic_vector(slink_tx_val_o_int);
slink_tx_rdy_i_int <= std_ulogic_vector(slink_tx_rdy_i);
slink_rx_val_i_int <= std_ulogic_vector(slink_rx_val_i);
slink_rx_rdy_o <= std_logic_vector(slink_rx_rdy_o_int);
 
slink_conv:
for i in 0 to 7 generate
slink_tx_dat_o(i) <= std_logic_vector(slink_tx_dat_o_int(i));
slink_rx_dat_i_int(i) <= std_ulogic_vector(slink_rx_dat_i(i));
end generate;
 
gpio_o <= std_logic_vector(gpio_o_int);
gpio_i_int <= std_ulogic_vector(gpio_i);
 
uart0_txd_o <= std_logic(uart0_txd_o_int);
uart0_rxd_i_int <= std_ulogic(uart0_rxd_i);
uart1_txd_o <= std_logic(uart1_txd_o_int);
uart1_rxd_i_int <= std_ulogic(uart1_rxd_i);
 
spi_sck_o <= std_logic(spi_sck_o_int);
spi_sdo_o <= std_logic(spi_sdo_o_int);
spi_sdi_i_int <= std_ulogic(spi_sdi_i);
spi_csn_o <= std_logic_vector(spi_csn_o_int);
 
pwm_o <= std_logic_vector(pwm_o_int);
 
cfs_in_i_int <= std_ulogic_vector(cfs_in_i);
cfs_out_o <= std_logic_vector(cfs_out_o_int);
 
neoled_o <= std_logic(neoled_o_int);
 
mtime_i_int <= std_ulogic_vector(mtime_i);
mtime_o <= std_logic_vector(mtime_o_int);
 
xirq_i_int <= std_ulogic_vector(xirq_i);
 
msw_irq_i_int <= std_ulogic(msw_irq_i);
mext_irq_i_int <= std_ulogic(mext_irq_i);
 
 
end architecture;
/system_integration/neorv32_SystemTop_axi4lite.vhd
0,0 → 1,512
-- #################################################################################################
-- # << NEORV32 - Processor Top Entity with AXI4-Lite Compatible Master Interface >> #
-- # ********************************************************************************************* #
-- # (c) "AXI", "AXI4" and "AXI4-Lite" are trademarks of Arm Holdings plc. #
-- # Note: External MTIME is not supported. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_SystemTop_axi4lite is
generic (
-- ------------------------------------------------------------
-- Configuration Generics --
-- ------------------------------------------------------------
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit)
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic 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 muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb : boolean := false; -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN : boolean := false; -- implement instruction cache
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := x"FFFFFFFF"; -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)?
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)?
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG : std_logic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)?
);
port (
-- ------------------------------------------------------------
-- AXI4-Lite-Compatible Master Interface --
-- ------------------------------------------------------------
-- Clock and Reset --
m_axi_aclk : in std_logic;
m_axi_aresetn : in std_logic;
-- Write Address Channel --
m_axi_awaddr : out std_logic_vector(31 downto 0);
m_axi_awprot : out std_logic_vector(2 downto 0);
m_axi_awvalid : out std_logic;
m_axi_awready : in std_logic;
-- Write Data Channel --
m_axi_wdata : out std_logic_vector(31 downto 0);
m_axi_wstrb : out std_logic_vector(3 downto 0);
m_axi_wvalid : out std_logic;
m_axi_wready : in std_logic;
-- Read Address Channel --
m_axi_araddr : out std_logic_vector(31 downto 0);
m_axi_arprot : out std_logic_vector(2 downto 0);
m_axi_arvalid : out std_logic;
m_axi_arready : in std_logic;
-- Read Data Channel --
m_axi_rdata : in std_logic_vector(31 downto 0);
m_axi_rresp : in std_logic_vector(1 downto 0);
m_axi_rvalid : in std_logic;
m_axi_rready : out std_logic;
-- Write Response Channel --
m_axi_bresp : in std_logic_vector(1 downto 0);
m_axi_bvalid : in std_logic;
m_axi_bready : out std_logic;
-- ------------------------------------------------------------
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
-- ------------------------------------------------------------
jtag_trst_i : in std_logic := '0'; -- low-active TAP reset (optional)
jtag_tck_i : in std_logic := '0'; -- serial clock
jtag_tdi_i : in std_logic := '0'; -- serial data input
jtag_tdo_o : out std_logic; -- serial data output
jtag_tms_i : in std_logic := '0'; -- mode select
-- ------------------------------------------------------------
-- Processor IO --
-- ------------------------------------------------------------
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o : out std_logic_vector(63 downto 0); -- parallel output
gpio_i : in std_logic_vector(63 downto 0) := (others => '0'); -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o : out std_logic; -- UART0 send data
uart0_rxd_i : in std_logic := '0'; -- UART0 receive data
uart0_rts_o : out std_logic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i : in std_logic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o : out std_logic; -- UART1 send data
uart1_rxd_i : in std_logic := '0'; -- UART1 receive data
uart1_rts_o : out std_logic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i : in std_logic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o : out std_logic; -- SPI serial clock
spi_sdo_o : out std_logic; -- controller data out, peripheral data in
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_NUM_CH > 0) --
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o : out std_logic; -- async serial data line
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels
-- CPU Interrupts --
nm_irq_i : in std_logic := '0'; -- non-maskable interrupt
msw_irq_i : in std_logic := '0'; -- machine software interrupt
mext_irq_i : in std_logic := '0' -- machine external interrupt
);
end entity;
 
architecture neorv32_SystemTop_axi4lite_rtl of neorv32_SystemTop_axi4lite is
 
-- type conversion --
constant IO_CFS_CONFIG_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(IO_CFS_CONFIG);
constant XIRQ_TRIGGER_TYPE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_TYPE);
constant XIRQ_TRIGGER_POLARITY_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_POLARITY);
--
signal clk_i_int : std_ulogic;
signal rstn_i_int : std_ulogic;
--
signal jtag_trst_i_int :std_ulogic;
signal jtag_tck_i_int :std_ulogic;
signal jtag_tdi_i_int :std_ulogic;
signal jtag_tdo_o_int :std_ulogic;
signal jtag_tms_i_int :std_ulogic;
--
signal gpio_o_int : std_ulogic_vector(63 downto 0);
signal gpio_i_int : std_ulogic_vector(63 downto 0);
--
signal uart0_txd_o_int : std_ulogic;
signal uart0_rxd_i_int : std_ulogic;
signal uart0_rts_o_int : std_ulogic;
signal uart0_cts_i_int : std_ulogic;
--
signal uart1_txd_o_int : std_ulogic;
signal uart1_rxd_i_int : std_ulogic;
signal uart1_rts_o_int : std_ulogic;
signal uart1_cts_i_int : std_ulogic;
--
signal spi_sck_o_int : std_ulogic;
signal spi_sdo_o_int : std_ulogic;
signal spi_sdi_i_int : std_ulogic;
signal spi_csn_o_int : std_ulogic_vector(07 downto 0);
--
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0);
--
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0);
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0);
--
signal neoled_o_int : std_ulogic;
--
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0);
--
signal nm_irq_i_int : std_ulogic;
signal msw_irq_i_int : std_ulogic;
signal mext_irq_i_int : std_ulogic;
 
-- internal wishbone bus --
type wb_bus_t is record
adr : std_ulogic_vector(31 downto 0); -- address
di : std_ulogic_vector(31 downto 0); -- processor input data
do : std_ulogic_vector(31 downto 0); -- processor output data
we : std_ulogic; -- write enable
sel : std_ulogic_vector(03 downto 0); -- byte enable
stb : std_ulogic; -- strobe
cyc : std_ulogic; -- valid cycle
ack : std_ulogic; -- transfer acknowledge
err : std_ulogic; -- transfer error
tag : std_ulogic_vector(02 downto 0); -- tag
lock : std_ulogic; -- exclusive access request
end record;
signal wb_core : wb_bus_t;
 
-- AXI bridge control --
type ctrl_t is record
radr_received : std_ulogic;
wadr_received : std_ulogic;
wdat_received : std_ulogic;
end record;
signal ctrl : ctrl_t;
 
signal ack_read, ack_write : std_ulogic; -- normal transfer termination
signal err_read, err_write : std_ulogic; -- error transfer termination
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 PROCESSOR CONFIG WARNING: AXI4-Lite provides NO support for atomic memory operations. LR/SC access via AXI will raise a bus exception." severity warning;
 
 
-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (hartid)
-- On-Chip Debugger (OCD) --
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension?
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zbb => CPU_EXTENSION_RISCV_Zbb, -- implement basic bit-manipulation sub-extension?
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!)
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
-- Physical Memory Protection (PMP) --
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
-- Hardware Performance Monitors (HPM) --
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (0..64)
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Internal Cache memory --
ICACHE_EN => ICACHE_EN, -- implement instruction cache
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2
-- External memory interface --
MEM_EXT_EN => true, -- implement external memory bus interface?
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled)
MEM_EXT_PIPE_MODE => false, -- protocol: false=classic/standard wishbone mode, true=pipelined wishbone mode
MEM_EXT_BIG_ENDIAN => false, -- byte order: true=big-endian, false=little-endian
MEM_EXT_ASYNC_RX => false, -- use register buffer for RX data when false
-- External Interrupts Controller (XIRQ) --
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32)
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE_INT, -- trigger type: 0=level, 1=edge
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY_INT, -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge
-- Processor peripherals --
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)?
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)?
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)?
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)?
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)?
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)?
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)?
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)?
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits
IO_NEOLED_EN => IO_NEOLED_EN -- implement NeoPixel-compatible smart LED interface (NEOLED)?
)
port map (
-- Global control --
clk_i => clk_i_int, -- global clock, rising edge
rstn_i => rstn_i_int, -- global reset, low-active, async
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) --
jtag_trst_i => jtag_trst_i_int, -- low-active TAP reset (optional)
jtag_tck_i => jtag_tck_i_int, -- serial clock
jtag_tdi_i => jtag_tdi_i_int, -- serial data input
jtag_tdo_o => jtag_tdo_o_int, -- serial data output
jtag_tms_i => jtag_tms_i_int, -- mode select
-- Wishbone bus interface (available if MEM_EXT_EN = true) --
wb_tag_o => wb_core.tag, -- tag
wb_adr_o => wb_core.adr, -- address
wb_dat_i => wb_core.di, -- read data
wb_dat_o => wb_core.do, -- write data
wb_we_o => wb_core.we, -- read/write
wb_sel_o => wb_core.sel, -- byte enable
wb_stb_o => wb_core.stb, -- strobe
wb_cyc_o => wb_core.cyc, -- valid cycle
wb_lock_o => wb_core.lock, -- exclusive access request
wb_ack_i => wb_core.ack, -- transfer acknowledge
wb_err_i => wb_core.err, -- transfer error
-- Advanced memory control signals (available if MEM_EXT_EN = true) --
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => gpio_o_int, -- parallel output
gpio_i => gpio_i_int, -- parallel input
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart0_txd_o_int, -- UART0 send data
uart0_rxd_i => uart0_rxd_i_int, -- UART0 receive data
uart0_rts_o => uart0_rts_o_int, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional
uart0_cts_i => uart0_cts_i_int, -- hw flow control: UART0.TX allowed to transmit, low-active, optional
-- secondary UART1 (available if IO_UART1_EN = true) --
uart1_txd_o => uart1_txd_o_int, -- UART1 send data
uart1_rxd_i => uart1_rxd_i_int, -- UART1 receive data
uart1_rts_o => uart1_rts_o_int, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional
uart1_cts_i => uart1_cts_i_int, -- hw flow control: UART1.TX allowed to transmit, low-active, optional
-- SPI (available if IO_SPI_EN = true) --
spi_sck_o => spi_sck_o_int, -- SPI serial clock
spi_sdo_o => spi_sdo_o_int, -- controller data out, peripheral data in
spi_sdi_i => spi_sdi_i_int, -- controller data in, peripheral data out
spi_csn_o => spi_csn_o_int, -- SPI CS
-- TWI (available if IO_TWI_EN = true) --
twi_sda_io => twi_sda_io, -- twi serial data line
twi_scl_io => twi_scl_io, -- twi serial clock line
-- PWM available if IO_PWM_NUM_CH > 0) --
pwm_o => pwm_o_int, -- pwm channels
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) --
cfs_in_i => cfs_in_i_int, -- custom inputs
cfs_out_o => cfs_out_o_int, -- custom outputs
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) --
neoled_o => neoled_o_int, -- async serial data line
-- System time --
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false)
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true)
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i => xirq_i_int, -- IRQ channels
-- CPU Interrupts --
nm_irq_i => nm_irq_i_int, -- non-maskable interrupt
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false
msw_irq_i => msw_irq_i_int, -- machine software interrupt
mext_irq_i => mext_irq_i_int -- machine external interrupt
);
 
-- type conversion --
gpio_o <= std_logic_vector(gpio_o_int);
gpio_i_int <= std_ulogic_vector(gpio_i);
 
jtag_trst_i_int <= std_ulogic(jtag_trst_i);
jtag_tck_i_int <= std_ulogic(jtag_tck_i);
jtag_tdi_i_int <= std_ulogic(jtag_tdi_i);
jtag_tdo_o <= std_logic(jtag_tdo_o_int);
jtag_tms_i_int <= std_ulogic(jtag_tms_i);
 
uart0_txd_o <= std_logic(uart0_txd_o_int);
uart0_rxd_i_int <= std_ulogic(uart0_rxd_i);
uart1_txd_o <= std_logic(uart0_txd_o_int);
uart1_rxd_i_int <= std_ulogic(uart0_rxd_i);
 
spi_sck_o <= std_logic(spi_sck_o_int);
spi_sdo_o <= std_logic(spi_sdo_o_int);
spi_sdi_i_int <= std_ulogic(spi_sdi_i);
spi_csn_o <= std_logic_vector(spi_csn_o_int);
 
pwm_o <= std_logic_vector(pwm_o_int);
 
cfs_in_i_int <= std_ulogic_vector(cfs_in_i);
cfs_out_o <= std_logic_vector(cfs_out_o_int);
 
neoled_o <= std_logic(neoled_o_int);
 
mext_irq_i_int <= std_ulogic(mext_irq_i);
 
 
-- Wishbone to AXI4-Lite Bridge -----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- access arbiter --
axi_access_arbiter: process(rstn_i_int, clk_i_int)
begin
if (rstn_i_int = '0') then
ctrl.radr_received <= '0';
ctrl.wadr_received <= '0';
ctrl.wdat_received <= '0';
elsif rising_edge(clk_i_int) then
if (wb_core.cyc = '0') then -- idle
ctrl.radr_received <= '0';
ctrl.wadr_received <= '0';
ctrl.wdat_received <= '0';
else -- busy
-- "read address received" flag --
if (wb_core.we = '0') then -- pending READ
if (m_axi_arready = '1') then -- read address received by interconnect?
ctrl.radr_received <= '1';
end if;
end if;
-- "write address received" flag --
if (wb_core.we = '1') then -- pending WRITE
if (m_axi_awready = '1') then -- write address received by interconnect?
ctrl.wadr_received <= '1';
end if;
end if;
-- "write data received" flag --
if (wb_core.we = '1') then -- pending WRITE
if (m_axi_wready = '1') then -- write data received by interconnect?
ctrl.wdat_received <= '1';
end if;
end if;
end if;
end if;
end process axi_access_arbiter;
 
 
-- AXI4-Lite Global Signals --
clk_i_int <= std_ulogic(m_axi_aclk);
rstn_i_int <= std_ulogic(m_axi_aresetn);
 
 
-- AXI4-Lite Read Address Channel --
m_axi_araddr <= std_logic_vector(wb_core.adr);
m_axi_arvalid <= std_logic((wb_core.cyc and (not wb_core.we)) and (not ctrl.radr_received));
--m_axi_arprot <= "000"; -- recommended by Xilinx
m_axi_arprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access
m_axi_arprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access
m_axi_arprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access
 
-- AXI4-Lite Read Data Channel --
m_axi_rready <= std_logic(wb_core.cyc and (not wb_core.we));
wb_core.di <= std_ulogic_vector(m_axi_rdata);
ack_read <= std_ulogic(m_axi_rvalid);
err_read <= '0' when (m_axi_rresp = "00") else '1'; -- read response = ok? check this signal only when m_axi_rvalid = '1'
 
 
-- AXI4-Lite Write Address Channel --
m_axi_awaddr <= std_logic_vector(wb_core.adr);
m_axi_awvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wadr_received));
--m_axi_awprot <= "000"; -- recommended by Xilinx
m_axi_awprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access
m_axi_awprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access
m_axi_awprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access
 
-- AXI4-Lite Write Data Channel --
m_axi_wdata <= std_logic_vector(wb_core.do);
m_axi_wvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wdat_received));
m_axi_wstrb <= std_logic_vector(wb_core.sel); -- byte-enable
 
-- AXI4-Lite Write Response Channel --
m_axi_bready <= std_logic(wb_core.cyc and wb_core.we);
ack_write <= std_ulogic(m_axi_bvalid);
err_write <= '0' when (m_axi_bresp = "00") else '1'; -- write response = ok? check this signal only when m_axi_bvalid = '1'
 
 
-- Wishbone transfer termination --
wb_core.ack <= ack_read or ack_write;
wb_core.err <= (ack_read and err_read) or (ack_write and err_write) or wb_core.lock;
 
 
end architecture;
/test_setups/README.md
0,0 → 1,53
# Test Setups
 
This folder contains very simple test setups that are intended for project beginners
to setup a minimal NEORV32 SoC. These setups are used in the :books:
[NEORV32 User Guide](https://stnolting.github.io/neorv32/ug/).
 
:information_source: Note that these setups provides a minimalistic configuration to keep
things at a simple level at first. Additional CPU ISA extensions, performance options and
optional peripheral modules can be enabled by specifying the according :book:
[configuration generics](https://stnolting.github.io/neorv32/#_processor_top_entity_generics).
 
 
### Setup's Top Entity
 
#### Clocking and Reset
 
All test setups require an external clock (via `clk_i` signal) and an external
low-active reset (via `rstn_i` signal).
 
#### Configuration Generics
 
Each setup provides three elementary generics that can/should be adapted to fit
your FPGA/board.
 
* The clock speed in Hz **has to be specified** via the `CLOCK_SPEED` generic to fit your clock source.
* The processor-internal instruction memory (IMEM) size _can be modified_ via the `MEM_INT_IMEM_SIZE` generic.
* The processor-internal data memory (DMEM) size _can be modified_ via the `MEM_INT_DMEM_SIZE` generic.
Note that this might require adaption of the NEORV32 linker script.
 
 
### [`neorv32_test_setup_approm.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_approm.vhd)
 
This setup configures a `rv32imc_Zicsr` CPU with 16kB IMEM (as pre-initialized ROM),
8kB DMEM and includes the GPIO module to drive 8 external signals (`gpio_o`)
and the MTIME module for generating timer interrupts.
The setup uses the [indidrect boot](https://stnolting.github.io/neorv32/#_indirect_boot)
configuration, so software applications are "installed" directly into the
processor-internal IMEM during synthesis.
 
:books: See User Guide section [_Installing an Executable Directly Into Memory_](https://stnolting.github.io/neorv32/ug/#_installing_an_executable_directly_into_memory).
 
 
### [`neorv32_test_setup_bootloader.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/test_setups/neorv32_test_setup_bootloader.vhd)
 
This setup configures a `rv32imc_Zicsr` CPU with 16kB IMEM (as RAM), 8kB DMEM
and includes the GPIO module to drive 8 external signals (`gpio_o`), the MTIME
module for generating timer interrupts and UART0 to interface with the bootloader
(via `uart0_txd_o` and `uart0_rxd_i`) via a serial terminal.
The setup uses the [direct boot](https://stnolting.github.io/neorv32/#_direct_boot)
configuration, so software applications can be uploaded and run at any timer via a serial terminal.
 
:books: See User Guide section
[_Uploading and Starting of a Binary Executable Image via UART_](https://stnolting.github.io/neorv32/ug/#_uploading_and_starting_of_a_binary_executable_image_via_uart).
/test_setups/neorv32_test_setup_approm.vhd
0,0 → 1,97
-- #################################################################################################
-- # << NEORV32 - Test Setup using the internal IMEM as ROM to run pre-installed executables >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_test_setup_approm is
generic (
-- adapt these for your setup --
CLOCK_FREQUENCY : natural := 100000000; -- clock frequency of clk_i in Hz
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes
);
port (
-- Global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- GPIO --
gpio_o : out std_ulogic_vector(7 downto 0) -- parallel output
);
end entity;
 
architecture neorv32_test_setup_approm_rtl of neorv32_test_setup_approm is
 
signal con_gpio_o : std_ulogic_vector(63 downto 0);
 
begin
 
-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => false, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => true, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => true, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Processor peripherals --
IO_GPIO_EN => true, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => true -- implement machine system timer (MTIME)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => con_gpio_o -- parallel output
);
 
-- GPIO output --
gpio_o <= con_gpio_o(7 downto 0);
 
 
end architecture;
/test_setups/neorv32_test_setup_bootloader.vhd
0,0 → 1,104
-- #################################################################################################
-- # << NEORV32 - Test Setup using the UART-Bootloader to upload and run executables >> #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 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. #
-- # ********************************************************************************************* #
-- # The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_test_setup_bootloader is
generic (
-- adapt these for your setup --
CLOCK_FREQUENCY : natural := 100000000; -- clock frequency of clk_i in Hz
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes
);
port (
-- Global control --
clk_i : in std_ulogic; -- global clock, rising edge
rstn_i : in std_ulogic; -- global reset, low-active, async
-- GPIO --
gpio_o : out std_ulogic_vector(7 downto 0); -- parallel output
-- UART0 --
uart0_txd_o : out std_ulogic; -- UART0 send data
uart0_rxd_i : in std_ulogic -- UART0 receive data
);
end entity;
 
architecture neorv32_test_setup_bootloader_rtl of neorv32_test_setup_bootloader is
 
signal con_gpio_o : std_ulogic_vector(63 downto 0);
 
begin
 
-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
INT_BOOTLOADER_EN => true, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => true, -- implement mul/div extension?
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system?
-- Internal Instruction memory --
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal Data memory --
MEM_INT_DMEM_EN => true, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- Processor peripherals --
IO_GPIO_EN => true, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_EN => true, -- implement machine system timer (MTIME)?
IO_UART0_EN => true -- implement primary universal asynchronous receiver/transmitter (UART0)?
)
port map (
-- Global control --
clk_i => clk_i, -- global clock, rising edge
rstn_i => rstn_i, -- global reset, low-active, async
-- GPIO (available if IO_GPIO_EN = true) --
gpio_o => con_gpio_o, -- parallel output
-- primary UART0 (available if IO_UART0_EN = true) --
uart0_txd_o => uart0_txd_o, -- UART0 send data
uart0_rxd_i => uart0_rxd_i -- UART0 receive data
);
 
-- GPIO output --
gpio_o <= con_gpio_o(7 downto 0);
 
 
end architecture;
/README.md
1,5 → 1,6
## VHDL Source Folders
 
 
### [`core`](https://github.com/stnolting/neorv32/tree/master/rtl/core)
 
This folder contains the core VHDL files for the NEORV32 CPU and the NEORV32 Processor.
6,6 → 7,24
When creating a new synthesis/simulation project make sure that all `*.vhd` files from this folder are added to a
*new design library* called `neorv32`.
 
### [`templates`](https://github.com/stnolting/neorv32/tree/master/rtl/templates)
 
Alternative top entities / wrappers for the NEORV32 Processor.
### [`processor_templates`](https://github.com/stnolting/neorv32/tree/master/rtl/processor_templates`)
 
Contains pre-configured "SoC" templates that instantiate the processor's top entity from `core`.
These templates can be instantiated directly within a FPGA-specific board wrapper.
 
 
### [`system_integration`](https://github.com/stnolting/neorv32/tree/master/rtl/system_integration`)
 
Top entities in this folder provide the same peripheral/IO signals and configuration generics as the default
processor top entity from `core`, but feature a different interface type.
For example: an **AXI4-Lite**-compatible bus interface instead of the default Wishbone bus interface
or a top entity with _resolved_ port signal types.
 
 
### [`test_setups`](https://github.com/stnolting/neorv32/tree/master/rtl/test_setups`)
 
Minimal test setups (FPGA- and board-independent) for the processor. See the
[README](https://github.com/stnolting/neorv32/tree/master/rtl/test_setups)
in that folder for more information. Note that these test setups are used in the
[NEORV32 USer Guide](https://stnolting.github.io/neorv32/ug).

powered by: WebSVN 2.1.0

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