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/system/neorv32_SystemTop_axi4lite.vhd
File deleted
/templates/README.md
File deleted
/templates/processor/neorv32_ProcessorTop_Test.vhd
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). |