Line 51... |
Line 51... |
HW_THREAD_ID : natural; -- hardware thread id (32-bit)
|
HW_THREAD_ID : natural; -- hardware thread id (32-bit)
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0); -- cpu boot address
|
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0); -- cpu boot address
|
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
CPU_DEBUG_ADDR : std_ulogic_vector(31 downto 0); -- cpu debug mode start address
|
-- RISC-V CPU Extensions --
|
-- RISC-V CPU Extensions --
|
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
CPU_EXTENSION_RISCV_A : boolean; -- implement atomic extension?
|
|
CPU_EXTENSION_RISCV_B : boolean; -- implement bit-manipulation extension?
|
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_C : boolean; -- implement compressed extension?
|
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_E : boolean; -- implement embedded RF extension?
|
CPU_EXTENSION_RISCV_M : boolean; -- implement muld/div extension?
|
CPU_EXTENSION_RISCV_M : boolean; -- implement mul/div extension?
|
CPU_EXTENSION_RISCV_U : boolean; -- implement user mode 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_Zfinx : boolean; -- implement 32-bit floating-point extension (using INT reg!)
|
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
CPU_EXTENSION_RISCV_Zicsr : boolean; -- implement CSR system?
|
|
CPU_EXTENSION_RISCV_Zicntr : boolean; -- implement base counters?
|
|
CPU_EXTENSION_RISCV_Zihpm : boolean; -- implement hardware performance monitors?
|
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zifencei : boolean; -- implement instruction stream sync.?
|
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_Zmmul : boolean; -- implement multiply-only M sub-extension?
|
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
|
CPU_EXTENSION_RISCV_DEBUG : boolean; -- implement CPU debug mode?
|
-- Extension Options --
|
-- Extension Options --
|
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
|
CPU_CNT_WIDTH : natural; -- total width of CPU cycle and instret counters (0..64)
|
Line 194... |
Line 196... |
is_bitmanip_reg : std_ulogic;
|
is_bitmanip_reg : std_ulogic;
|
end record;
|
end record;
|
signal decode_aux : decode_aux_t;
|
signal decode_aux : decode_aux_t;
|
|
|
-- instruction execution engine --
|
-- instruction execution engine --
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT, BRANCH,
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT,
|
FENCE_OP, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
|
BRANCH, LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS);
|
type execute_engine_t is record
|
type execute_engine_t is record
|
state : execute_engine_state_t;
|
state : execute_engine_state_t;
|
state_nxt : execute_engine_state_t;
|
state_nxt : execute_engine_state_t;
|
state_prev : execute_engine_state_t;
|
state_prev : execute_engine_state_t;
|
--
|
--
|
Line 207... |
Line 209... |
i_reg_nxt : std_ulogic_vector(31 downto 0);
|
i_reg_nxt : std_ulogic_vector(31 downto 0);
|
i_reg_last : std_ulogic_vector(31 downto 0); -- last executed instruction
|
i_reg_last : std_ulogic_vector(31 downto 0); -- last executed instruction
|
--
|
--
|
is_ci : std_ulogic; -- current instruction is de-compressed instruction
|
is_ci : std_ulogic; -- current instruction is de-compressed instruction
|
is_ci_nxt : std_ulogic;
|
is_ci_nxt : std_ulogic;
|
|
is_ici : std_ulogic; -- current instruction is illegal de-compressed instruction
|
|
is_ici_nxt : std_ulogic;
|
--
|
--
|
branch_taken : std_ulogic; -- branch condition fulfilled
|
branch_taken : std_ulogic; -- branch condition fulfilled
|
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
|
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
|
pc_mux_sel : std_ulogic; -- source select for PC update
|
pc_mux_sel : std_ulogic; -- source select for PC update
|
pc_we : std_ulogic; -- PC update enabled
|
pc_we : std_ulogic; -- PC update enabled
|
Line 357... |
Line 361... |
-- (hpm) counter events --
|
-- (hpm) counter events --
|
signal cnt_event, cnt_event_nxt : std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
|
signal cnt_event, cnt_event_nxt : std_ulogic_vector(hpmcnt_event_size_c-1 downto 0);
|
signal hpmcnt_trigger : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
|
signal hpmcnt_trigger : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0);
|
|
|
-- illegal instruction check --
|
-- illegal instruction check --
|
signal illegal_opcode_lsbs : std_ulogic; -- if opcode != rv32
|
signal illegal_opcode_lsbs : std_ulogic; -- opcode != rv32
|
signal illegal_instruction : std_ulogic;
|
signal illegal_instruction : std_ulogic;
|
signal illegal_register : std_ulogic; -- only for E-extension
|
signal illegal_register : std_ulogic; -- illegal register (>x15) - E-extension
|
signal illegal_compressed : std_ulogic; -- only fir C-extension
|
signal illegal_compressed : std_ulogic; -- illegal compressed instruction - C-extension
|
|
|
-- access (privilege) check --
|
-- access (privilege) check --
|
signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
|
signal csr_acc_valid : std_ulogic; -- valid CSR access (implemented and valid access rights)
|
|
|
begin
|
begin
|
Line 487... |
Line 491... |
issue_engine_fsm_sync: process(rstn_i, clk_i)
|
issue_engine_fsm_sync: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
issue_engine.state <= ISSUE_ACTIVE;
|
issue_engine.state <= ISSUE_ACTIVE;
|
issue_engine.align <= CPU_BOOT_ADDR(1); -- 32- or 16-bit boundary
|
issue_engine.align <= CPU_BOOT_ADDR(1); -- 32- or 16-bit boundary
|
issue_engine.buf <= (others => def_rst_val_c);
|
issue_engine.buf <= (others => '0');
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (ipb.clear = '1') then
|
if (ipb.clear = '1') then
|
if (CPU_EXTENSION_RISCV_C = true) then
|
if (CPU_EXTENSION_RISCV_C = true) then
|
if (execute_engine.pc(1) = '1') then -- branch to unaligned address?
|
if (execute_engine.pc(1) = '1') then -- branch to unaligned address?
|
issue_engine.state <= ISSUE_REALIGN;
|
issue_engine.state <= ISSUE_REALIGN;
|
Line 555... |
Line 559... |
if (execute_engine.state = DISPATCH) then -- ready to issue new command?
|
if (execute_engine.state = DISPATCH) then -- ready to issue new command?
|
cmd_issue.valid <= '1';
|
cmd_issue.valid <= '1';
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
|
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and "unaligned"
|
if (issue_engine.buf(1 downto 0) = "11") then -- uncompressed and "unaligned"
|
ipb.re <= '1';
|
ipb.re <= '1';
|
cmd_issue.data <= '0' & issue_engine.buf(17 downto 16) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
|
cmd_issue.data <= '0' & (ipb.rdata(33 downto 32) or issue_engine.buf(17 downto 16)) & '0' & (ipb.rdata(15 downto 0) & issue_engine.buf(15 downto 0));
|
else -- compressed
|
else -- compressed
|
-- do not read from ipb here!
|
-- do not read from ipb here!
|
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
|
issue_engine.align_nxt <= '0';
|
issue_engine.align_nxt <= '0';
|
end if;
|
end if;
|
Line 670... |
Line 674... |
execute_engine.branch_taken <= not cmp_i(cmp_equal_c);
|
execute_engine.branch_taken <= not cmp_i(cmp_equal_c);
|
when funct3_blt_c | funct3_bltu_c => -- branch if less (signed/unsigned)
|
when funct3_blt_c | funct3_bltu_c => -- branch if less (signed/unsigned)
|
execute_engine.branch_taken <= cmp_i(cmp_less_c);
|
execute_engine.branch_taken <= cmp_i(cmp_less_c);
|
when funct3_bge_c | funct3_bgeu_c => -- branch if greater or equal (signed/unsigned)
|
when funct3_bge_c | funct3_bgeu_c => -- branch if greater or equal (signed/unsigned)
|
execute_engine.branch_taken <= not cmp_i(cmp_less_c);
|
execute_engine.branch_taken <= not cmp_i(cmp_less_c);
|
when others => -- undefined
|
when others => -- invalid
|
execute_engine.branch_taken <= '0';
|
execute_engine.branch_taken <= '0';
|
end case;
|
end case;
|
end process branch_check;
|
end process branch_check;
|
|
|
|
|
Line 690... |
Line 694... |
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
|
execute_engine.branched <= '1'; -- reset is a branch from "somewhere"
|
-- no dedicated RESET required --
|
-- no dedicated RESET required --
|
execute_engine.state_prev <= SYS_WAIT; -- actual reset value is not relevant
|
execute_engine.state_prev <= SYS_WAIT; -- actual reset value is not relevant
|
execute_engine.i_reg <= (others => def_rst_val_c);
|
execute_engine.i_reg <= (others => def_rst_val_c);
|
execute_engine.is_ci <= def_rst_val_c;
|
execute_engine.is_ci <= def_rst_val_c;
|
|
execute_engine.is_ici <= def_rst_val_c;
|
execute_engine.last_pc <= (others => def_rst_val_c);
|
execute_engine.last_pc <= (others => def_rst_val_c);
|
execute_engine.i_reg_last <= (others => def_rst_val_c);
|
execute_engine.i_reg_last <= (others => def_rst_val_c);
|
execute_engine.next_pc <= (others => def_rst_val_c);
|
execute_engine.next_pc <= (others => def_rst_val_c);
|
ctrl <= (others => def_rst_val_c);
|
ctrl <= (others => def_rst_val_c);
|
--
|
--
|
Line 714... |
Line 719... |
execute_engine.branched <= execute_engine.branched_nxt;
|
execute_engine.branched <= execute_engine.branched_nxt;
|
--
|
--
|
execute_engine.state_prev <= execute_engine.state;
|
execute_engine.state_prev <= execute_engine.state;
|
execute_engine.i_reg <= execute_engine.i_reg_nxt;
|
execute_engine.i_reg <= execute_engine.i_reg_nxt;
|
execute_engine.is_ci <= execute_engine.is_ci_nxt;
|
execute_engine.is_ci <= execute_engine.is_ci_nxt;
|
|
execute_engine.is_ici <= execute_engine.is_ici_nxt;
|
|
|
-- PC & IR of "last executed" instruction --
|
-- PC & IR of "last executed" instruction for trap handling --
|
if (execute_engine.state = EXECUTE) then
|
if (execute_engine.state = EXECUTE) then
|
execute_engine.last_pc <= execute_engine.pc;
|
execute_engine.last_pc <= execute_engine.pc;
|
execute_engine.i_reg_last <= execute_engine.i_reg;
|
execute_engine.i_reg_last <= execute_engine.i_reg;
|
end if;
|
end if;
|
|
|
Line 854... |
Line 860... |
(
|
(
|
(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) = "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) = "110") or -- ORN
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") -- XORN
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") -- XORN
|
)
|
)
|
|
) or
|
|
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0010000") and
|
|
(
|
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "010") or -- SH1ADD
|
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "100") or -- SH2ADD
|
|
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "110") -- SH3ADD
|
|
)
|
) then
|
) then
|
decode_aux.is_bitmanip_reg <= '1';
|
decode_aux.is_bitmanip_reg <= '1';
|
end if;
|
end if;
|
|
|
-- floating-point operations (Zfinx) --
|
-- floating-point operations (Zfinx) --
|
Line 893... |
Line 906... |
begin
|
begin
|
-- arbiter defaults --
|
-- arbiter defaults --
|
execute_engine.state_nxt <= execute_engine.state;
|
execute_engine.state_nxt <= execute_engine.state;
|
execute_engine.i_reg_nxt <= execute_engine.i_reg;
|
execute_engine.i_reg_nxt <= execute_engine.i_reg;
|
execute_engine.is_ci_nxt <= execute_engine.is_ci;
|
execute_engine.is_ci_nxt <= execute_engine.is_ci;
|
|
execute_engine.is_ici_nxt <= '0';
|
execute_engine.sleep_nxt <= execute_engine.sleep;
|
execute_engine.sleep_nxt <= execute_engine.sleep;
|
execute_engine.branched_nxt <= execute_engine.branched;
|
execute_engine.branched_nxt <= execute_engine.branched;
|
--
|
--
|
execute_engine.pc_mux_sel <= '0';
|
execute_engine.pc_mux_sel <= '0';
|
execute_engine.pc_we <= '0';
|
execute_engine.pc_we <= '0';
|
Line 914... |
Line 928... |
-- exception trigger --
|
-- exception trigger --
|
trap_ctrl.instr_be <= '0';
|
trap_ctrl.instr_be <= '0';
|
trap_ctrl.instr_ma <= '0';
|
trap_ctrl.instr_ma <= '0';
|
trap_ctrl.env_call <= '0';
|
trap_ctrl.env_call <= '0';
|
trap_ctrl.break_point <= '0';
|
trap_ctrl.break_point <= '0';
|
illegal_compressed <= '0';
|
|
|
|
-- CSR access --
|
-- CSR access --
|
csr.we_nxt <= '0';
|
csr.we_nxt <= '0';
|
|
|
-- CONTROL DEFAULTS --
|
-- CONTROL DEFAULTS --
|
Line 962... |
Line 975... |
execute_engine.branched_nxt <= '0';
|
execute_engine.branched_nxt <= '0';
|
execute_engine.pc_we <= not execute_engine.branched; -- update PC with linear next_pc if there was no actual branch
|
execute_engine.pc_we <= not execute_engine.branched; -- update PC with linear next_pc if there was no actual branch
|
-- IR update - exceptions --
|
-- IR update - exceptions --
|
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
|
trap_ctrl.instr_ma <= cmd_issue.data(33); -- misaligned instruction fetch address
|
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
|
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch
|
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction
|
execute_engine.is_ici_nxt <= cmd_issue.data(35); -- invalid decompressed instruction
|
-- any reason to go to trap state? --
|
-- any reason to go to trap state? --
|
if (execute_engine.sleep = '1') or -- WFI instruction - this will enter sleep state
|
if (execute_engine.sleep = '1') or -- WFI instruction - this will enter sleep state
|
|
(trap_ctrl.exc_fire = '1') or -- exception during LAST instruction (illegal instruction)
|
(trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
|
(trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception)
|
((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then -- exception during instruction fetch of the CURRENT instruction
|
((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then -- exception during instruction fetch of the NEW instruction
|
execute_engine.state_nxt <= TRAP_ENTER;
|
execute_engine.state_nxt <= TRAP_ENTER;
|
else
|
else
|
execute_engine.state_nxt <= EXECUTE;
|
execute_engine.state_nxt <= EXECUTE;
|
end if;
|
end if;
|
end if;
|
end if;
|
Line 1036... |
Line 1050... |
if ((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
|
if ((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')) 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_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;
|
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
|
-- co-processor bit manipulation operation? --
|
-- co-processor bit manipulation operation? --
|
elsif (CPU_EXTENSION_RISCV_Zbb = true) and
|
elsif (CPU_EXTENSION_RISCV_B = 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_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
|
((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_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;
|
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c;
|
else
|
else
|
Line 1059... |
Line 1073... |
-- multi cycle ALU operation? --
|
-- multi cycle ALU operation? --
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or -- SLL shift operation?
|
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?
|
(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_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')) or -- MUL
|
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) or -- MUL
|
((CPU_EXTENSION_RISCV_Zbb = true) and (
|
((CPU_EXTENSION_RISCV_B = 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_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?
|
((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
|
) then
|
execute_engine.state_nxt <= ALU_WAIT;
|
execute_engine.state_nxt <= ALU_WAIT;
|
else -- single cycle ALU operation
|
else -- single cycle ALU operation
|
Line 1115... |
Line 1129... |
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB (branch target address offset)
|
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB (branch target address offset)
|
execute_engine.state_nxt <= BRANCH;
|
execute_engine.state_nxt <= BRANCH;
|
|
|
when opcode_fence_c => -- fence operations
|
when opcode_fence_c => -- fence operations
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
execute_engine.state_nxt <= FENCE_OP;
|
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fence_c(0)) then -- FENCE
|
|
ctrl_nxt(ctrl_bus_fence_c) <= '1';
|
|
execute_engine.state_nxt <= SYS_WAIT;
|
|
else -- FENCE.I
|
|
if (CPU_EXTENSION_RISCV_Zifencei = true) then
|
|
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
|
|
execute_engine.branched_nxt <= '1'; -- this is an actual branch
|
|
execute_engine.state_nxt <= TRAP_EXECUTE; -- use TRAP_EXECUTE to "modify" PC (PC <= PC)
|
|
else -- fence.i not implemented
|
|
execute_engine.state_nxt <= SYS_WAIT;
|
|
end if;
|
|
end if;
|
|
|
when opcode_syscsr_c => -- system/csr access
|
when opcode_syscsr_c => -- system/csr access
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment
|
Line 1216... |
Line 1241... |
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
|
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result
|
ctrl_nxt(ctrl_rf_wb_en_c) <= execute_engine.i_reg(instr_opcode_lsb_c+2); -- valid RF write-back? (is jump-and-link?)
|
ctrl_nxt(ctrl_rf_wb_en_c) <= execute_engine.i_reg(instr_opcode_lsb_c+2); -- valid RF write-back? (is jump-and-link?)
|
-- destination address --
|
-- destination address --
|
execute_engine.pc_mux_sel <= '1'; -- alu.add = branch/jump destination
|
execute_engine.pc_mux_sel <= '1'; -- alu.add = branch/jump destination
|
if (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') or (execute_engine.branch_taken = '1') then -- JAL/JALR or taken branch
|
if (execute_engine.i_reg(instr_opcode_lsb_c+2) = '1') or (execute_engine.branch_taken = '1') then -- JAL/JALR or taken branch
|
|
-- no need to check for illegal instructions here; the branch condition evaluation circuit will not set "branch_taken" if funct3 is invalid
|
execute_engine.pc_we <= '1'; -- update PC
|
execute_engine.pc_we <= '1'; -- update PC
|
execute_engine.branched_nxt <= '1'; -- this is an actual branch
|
execute_engine.branched_nxt <= '1'; -- this is an actual branch
|
fetch_engine.reset <= '1'; -- trigger new instruction fetch from modified PC
|
fetch_engine.reset <= '1'; -- trigger new instruction fetch from modified PC
|
execute_engine.state_nxt <= SYS_WAIT;
|
execute_engine.state_nxt <= SYS_WAIT;
|
else
|
else
|
execute_engine.state_nxt <= DISPATCH;
|
execute_engine.state_nxt <= DISPATCH;
|
end if;
|
end if;
|
|
|
|
|
when FENCE_OP => -- fence operations - execution
|
|
-- ------------------------------------------------------------
|
|
execute_engine.state_nxt <= SYS_WAIT;
|
|
-- FENCE.I --
|
|
if (CPU_EXTENSION_RISCV_Zifencei = true) then
|
|
execute_engine.pc_mux_sel <= '0'; -- linear next PC = start *new* instruction fetch with next instruction
|
|
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fencei_c(0)) then
|
|
execute_engine.pc_we <= '1'; -- update PC
|
|
execute_engine.branched_nxt <= '1'; -- this is an actual branch
|
|
fetch_engine.reset <= '1'; -- trigger new instruction fetch from modified PC
|
|
ctrl_nxt(ctrl_bus_fencei_c) <= '1';
|
|
end if;
|
|
end if;
|
|
-- FENCE --
|
|
if (execute_engine.i_reg(instr_funct3_lsb_c) = funct3_fence_c(0)) then
|
|
ctrl_nxt(ctrl_bus_fence_c) <= '1';
|
|
end if;
|
|
|
|
|
|
when LOADSTORE_0 => -- trigger memory request
|
when LOADSTORE_0 => -- trigger memory request
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_atomic_lr; -- atomic.LR: set lock
|
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_atomic_lr; -- atomic.LR: set lock
|
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate
|
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate
|
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
|
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
|
Line 1364... |
Line 1371... |
csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c | -- event configuration
|
csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c | -- event configuration
|
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c |
|
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c |
|
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
|
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c |
|
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
|
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c |
|
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c =>
|
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c =>
|
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- M-mode only
|
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zihpm); -- M-mode only
|
|
|
-- user-level counters/timers --
|
-- user-level counters/timers --
|
when csr_cycle_c | csr_cycleh_c | csr_instret_c | csr_instreth_c | csr_time_c | csr_timeh_c =>
|
when csr_cycle_c | csr_cycleh_c | csr_instret_c | csr_instreth_c | csr_time_c | csr_timeh_c =>
|
case csr.addr(1 downto 0) is
|
case csr.addr(1 downto 0) is
|
when "00" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- cyle[h]: M-mode, U-mode if authorized, read-only
|
when "00" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- cyle[h]: M-mode, U-mode if authorized, implemented at all, read-only
|
when "01" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- time[h]: M-mode, U-mode if authorized, read-only
|
when "01" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- time[h]: M-mode, U-mode if authorized, implemented at all, read-only
|
when "10" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- instret[h]: M-mode, U-mode if authorized, read-only
|
when "10" => csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicntr) and (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- instret[h]: M-mode, U-mode if authorized, implemented at all read-only
|
when others => csr_acc_valid <= '0';
|
when others => csr_acc_valid <= '0';
|
end case;
|
end case;
|
|
|
-- debug mode CSRs --
|
-- debug mode CSRs --
|
when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c =>
|
when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c =>
|
Line 1405... |
Line 1412... |
illegal_opcode_lsbs <= '0';
|
illegal_opcode_lsbs <= '0';
|
else
|
else
|
illegal_opcode_lsbs <= '1';
|
illegal_opcode_lsbs <= '1';
|
end if;
|
end if;
|
|
|
|
-- check for illegal compressed instruction --
|
|
if (CPU_EXTENSION_RISCV_C = true) then
|
|
illegal_compressed <= execute_engine.is_ici;
|
|
else
|
|
illegal_compressed <= '0';
|
|
end if;
|
|
|
-- check instructions --
|
-- check instructions --
|
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11"; -- save some bits here, LSBs are always 11 for rv32
|
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11"; -- save some bits here, LSBs are always 11 for rv32
|
case opcode_v is
|
case opcode_v is
|
|
|
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => -- check sufficient LUI, UIPC, JAL (only check actual OPCODE)
|
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => -- check sufficient LUI, UIPC, JAL (only check actual OPCODE)
|
Line 1428... |
Line 1442... |
elsif (decode_aux.is_m_div = '1') then -- DIV
|
elsif (decode_aux.is_m_div = '1') then -- DIV
|
if (CPU_EXTENSION_RISCV_M = false) then -- not implemented
|
if (CPU_EXTENSION_RISCV_M = false) then -- not implemented
|
illegal_instruction <= '1';
|
illegal_instruction <= '1';
|
end if;
|
end if;
|
elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
|
elsif (decode_aux.is_bitmanip_reg = '1') then -- bit manipulation
|
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
|
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
|
illegal_instruction <= '1';
|
illegal_instruction <= '1';
|
end if;
|
end if;
|
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
|
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_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
|
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
|
Line 1448... |
Line 1462... |
end if;
|
end if;
|
|
|
when opcode_alui_c => -- check ALUI.funct7
|
when opcode_alui_c => -- check ALUI.funct7
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
|
if (decode_aux.is_bitmanip_imm = '1') then -- bit manipulation
|
if (CPU_EXTENSION_RISCV_Zbb = false) then -- not implemented
|
if (CPU_EXTENSION_RISCV_B = false) then -- not implemented
|
illegal_instruction <= '1';
|
illegal_instruction <= '1';
|
end if;
|
end if;
|
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
|
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_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_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and
|
Line 1600... |
Line 1614... |
illegal_instruction <= '1';
|
illegal_instruction <= '1';
|
|
|
end case;
|
end case;
|
else
|
else
|
illegal_opcode_lsbs <= '0';
|
illegal_opcode_lsbs <= '0';
|
|
illegal_compressed <= '0';
|
illegal_instruction <= '0';
|
illegal_instruction <= '0';
|
illegal_register <= '0';
|
illegal_register <= '0';
|
end if;
|
end if;
|
end process illegal_instruction_check;
|
end process illegal_instruction_check;
|
|
|
-- any illegal condition? --
|
-- any illegal condition? --
|
-- ignore illegal register condition in debug mode
|
trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or illegal_register or illegal_compressed;
|
trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or (illegal_register and (not debug_ctrl.running)) or illegal_compressed;
|
|
|
|
|
|
-- ****************************************************************************************************************************
|
-- ****************************************************************************************************************************
|
-- Exception and Interrupt (= Trap) Control
|
-- Exception and Interrupt (= Trap) Control
|
-- ****************************************************************************************************************************
|
-- ****************************************************************************************************************************
|
Line 1993... |
Line 2007... |
end if;
|
end if;
|
-- R/W: mtvec - machine trap-handler base address (for ALL exceptions) --
|
-- R/W: mtvec - machine trap-handler base address (for ALL exceptions) --
|
if (csr.addr(2 downto 0) = csr_mtvec_c(2 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
|
csr.mtvec <= csr.wdata(data_width_c-1 downto 2) & "00"; -- mtvec.MODE=0
|
end if;
|
end if;
|
-- R/W: machine counter enable register --
|
-- R/W: mcounteren - machine counter enable register --
|
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
|
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented
|
if (csr.addr(2 downto 0) = csr_mcounteren_c(2 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_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_tm <= csr.wdata(1); -- enable user-level access to time[h]
|
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
|
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h]
|
Line 2067... |
Line 2081... |
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
|
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter
|
if (HPM_NUM_CNTS > 0) then -- any HPMs available?
|
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
|
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter
|
end if;
|
end if;
|
end if;
|
end if;
|
-- machine performance-monitors event selector --
|
-- R/W: mhpmevent - machine performance-monitors event selector --
|
if (HPM_NUM_CNTS > 0) then
|
if (HPM_NUM_CNTS > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
|
if (csr.addr(4 downto 0) = std_ulogic_vector(to_unsigned(i+3, 5))) then
|
csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
|
csr.mhpmevent(i) <= csr.wdata(csr.mhpmevent(i)'left downto 0);
|
end if;
|
end if;
|
csr.mhpmevent(i)(hpmcnt_event_never_c) <= '0'; -- would be used for "TIME"
|
csr.mhpmevent(i)(hpmcnt_event_never_c) <= '0'; -- would be used for "TIME"
|
Line 2120... |
Line 2134... |
end if;
|
end if;
|
|
|
-- mcause, mepc, mtval: write machine trap cause, PC and trap value register --
|
-- mcause, mepc, mtval: write machine trap cause, PC and trap value register --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
|
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
|
|
|
if (CPU_EXTENSION_RISCV_DEBUG = false) or ((trap_ctrl.cause(5) = '0') and -- update mtval/mepc/mcause only when NOT ENTRY debug mode exception
|
if (CPU_EXTENSION_RISCV_DEBUG = false) or ((trap_ctrl.cause(5) = '0') and -- update mtval/mepc/mcause only when NOT ENTRY debug mode exception
|
(debug_ctrl.running = '0')) then -- and NOT IN debug mode
|
(debug_ctrl.running = '0')) then -- and NOT IN debug mode
|
|
|
-- trap cause ID code --
|
-- trap cause ID code --
|
csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
|
csr.mcause(csr.mcause'left) <= trap_ctrl.cause(trap_ctrl.cause'left); -- 1: interrupt, 0: exception
|
Line 2175... |
Line 2190... |
end if;
|
end if;
|
|
|
-- mstatus: context switch --
|
-- mstatus: context switch --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
-- ENTER: trap handling starting?
|
-- ENTER: trap handling starting?
|
if (trap_ctrl.env_start_ack = '1') then
|
if (trap_ctrl.env_start_ack = '1') then -- trap handler starting?
|
|
|
if (CPU_EXTENSION_RISCV_DEBUG = false) or -- normal trapping (debug mode NOT implemented)
|
if (CPU_EXTENSION_RISCV_DEBUG = false) or -- normal trapping (debug mode NOT implemented)
|
((debug_ctrl.running = '0') and (trap_ctrl.cause(5) = '0')) then -- not IN debug mode and not ENTERING debug mode
|
((debug_ctrl.running = '0') and (trap_ctrl.cause(5) = '0')) then -- not IN debug mode and not ENTERING debug mode
|
csr.mstatus_mie <= '0'; -- disable interrupts
|
csr.mstatus_mie <= '0'; -- disable interrupts
|
csr.mstatus_mpie <= csr.mstatus_mie; -- buffer previous mie state
|
csr.mstatus_mpie <= csr.mstatus_mie; -- buffer previous mie state
|
if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
|
if (CPU_EXTENSION_RISCV_U = true) then -- implement user mode
|
Line 2308... |
Line 2324... |
csr.mhpmcounter_ovfl <= (others => (others => def_rst_val_c));
|
csr.mhpmcounter_ovfl <= (others => (others => def_rst_val_c));
|
csr.mhpmcounterh <= (others => (others => def_rst_val_c));
|
csr.mhpmcounterh <= (others => (others => def_rst_val_c));
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
|
|
-- [m]cycle --
|
-- [m]cycle --
|
if (cpu_cnt_lo_width_c > 0) then
|
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
|
csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left);
|
csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left);
|
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access
|
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
|
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0);
|
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0);
|
Line 2321... |
Line 2337... |
csr.mcycle <= (others => '-');
|
csr.mcycle <= (others => '-');
|
csr.mcycle_ovfl(0) <= '-';
|
csr.mcycle_ovfl(0) <= '-';
|
end if;
|
end if;
|
|
|
-- [m]cycleh --
|
-- [m]cycleh --
|
if (cpu_cnt_hi_width_c > 0) then
|
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
|
if (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access
|
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
|
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update
|
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mcycle_ovfl));
|
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mcycle_ovfl));
|
end if;
|
end if;
|
Line 2333... |
Line 2349... |
csr.mcycleh <= (others => '-');
|
csr.mcycleh <= (others => '-');
|
end if;
|
end if;
|
|
|
|
|
-- [m]instret --
|
-- [m]instret --
|
if (cpu_cnt_lo_width_c > 0) then
|
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
|
csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left);
|
csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left);
|
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access
|
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
|
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
|
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0);
|
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0);
|
Line 2346... |
Line 2362... |
csr.minstret <= (others => '-');
|
csr.minstret <= (others => '-');
|
csr.minstret_ovfl(0) <= '-';
|
csr.minstret_ovfl(0) <= '-';
|
end if;
|
end if;
|
|
|
-- [m]instreth --
|
-- [m]instreth --
|
if (cpu_cnt_hi_width_c > 0) then
|
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then
|
if (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access
|
if (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access
|
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
|
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update
|
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.minstret_ovfl));
|
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.minstret_ovfl));
|
end if;
|
end if;
|
Line 2361... |
Line 2377... |
|
|
-- [machine] hardware performance monitors (counters) --
|
-- [machine] hardware performance monitors (counters) --
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
|
|
-- [m]hpmcounter* --
|
-- [m]hpmcounter* --
|
if (hpm_cnt_lo_width_c > 0) then
|
if (hpm_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
|
csr.mhpmcounter_ovfl(i)(0) <= csr.mhpmcounter_nxt(i)(csr.mhpmcounter_nxt(i)'left);
|
csr.mhpmcounter_ovfl(i)(0) <= csr.mhpmcounter_nxt(i)(csr.mhpmcounter_nxt(i)'left);
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access
|
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.wdata(hpm_cnt_lo_width_c-1 downto 0);
|
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.wdata(hpm_cnt_lo_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
|
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter_nxt(i)(hpm_cnt_lo_width_c-1 downto 0);
|
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter_nxt(i)(hpm_cnt_lo_width_c-1 downto 0);
|
Line 2374... |
Line 2390... |
csr.mhpmcounter(i) <= (others => '-');
|
csr.mhpmcounter(i) <= (others => '-');
|
csr.mhpmcounter_ovfl(i)(0) <= '-';
|
csr.mhpmcounter_ovfl(i)(0) <= '-';
|
end if;
|
end if;
|
|
|
-- [m]hpmcounter*h --
|
-- [m]hpmcounter*h --
|
if (hpm_cnt_hi_width_c > 0) then
|
if (hpm_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
|
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access
|
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.wdata(hpm_cnt_hi_width_c-1 downto 0);
|
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.wdata(hpm_cnt_hi_width_c-1 downto 0);
|
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
|
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update
|
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mhpmcounter_ovfl(i)));
|
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mhpmcounter_ovfl(i)));
|
end if;
|
end if;
|
Line 2406... |
Line 2422... |
-- hpm counter read --
|
-- hpm counter read --
|
hpm_rd_dummy: process(csr)
|
hpm_rd_dummy: process(csr)
|
begin
|
begin
|
csr.mhpmcounter_rd <= (others => (others => '0'));
|
csr.mhpmcounter_rd <= (others => (others => '0'));
|
csr.mhpmcounterh_rd <= (others => (others => '0'));
|
csr.mhpmcounterh_rd <= (others => (others => '0'));
|
if (HPM_NUM_CNTS /= 0) then
|
if (HPM_NUM_CNTS /= 0) and (CPU_EXTENSION_RISCV_Zihpm = true) then
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
for i in 0 to HPM_NUM_CNTS-1 loop
|
if (hpm_cnt_lo_width_c > 0) then
|
if (hpm_cnt_lo_width_c > 0) then
|
csr.mhpmcounter_rd(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0);
|
csr.mhpmcounter_rd(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0);
|
end if;
|
end if;
|
if (hpm_cnt_hi_width_c > 0) then
|
if (hpm_cnt_hi_width_c > 0) then
|
Line 2494... |
Line 2510... |
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
|
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE
|
csr.rdata(11) <= csr.mstatus_mpp(0); -- MPP: machine previous privilege mode low
|
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(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
|
when csr_misa_c => -- misa (r/-): ISA and extensions
|
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(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension
|
|
csr.rdata(01) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_B); -- B CPU extension
|
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
|
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
|
csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
|
csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
|
csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
|
csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
|
csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
|
csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
|
csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- U CPU extension
|
csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); -- U CPU extension
|
Line 2636... |
Line 2653... |
csr.rdata(csr.mcountinhibit_hpm'left+3 downto 3) <= csr.mcountinhibit_hpm; -- enable auto-increment of [m]hpmcounterx[h] counter
|
csr.rdata(csr.mcountinhibit_hpm'left+3 downto 3) <= csr.mcountinhibit_hpm; -- enable auto-increment of [m]hpmcounterx[h] counter
|
end if;
|
end if;
|
|
|
-- machine performance-monitoring event selector (r/w) --
|
-- 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;
|
when csr_mhpmevent3_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent4_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent5_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent6_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent7_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent8_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent9_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent10_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent11_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent12_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent13_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent14_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent15_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent16_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent17_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent18_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent19_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent20_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent21_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent22_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent23_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent24_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent25_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent26_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent27_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent28_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent29_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmevent30_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) 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;
|
when csr_mhpmevent31_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata(hpmcnt_event_size_c-1 downto 0) <= csr.mhpmevent(28); else NULL; end if;
|
|
|
-- counters and timers --
|
-- counters and timers --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
when csr_cycle_c | csr_mcycle_c => -- [m]cycle (r/w): Cycle counter LOW
|
when csr_cycle_c | csr_mcycle_c => -- [m]cycle (r/w): Cycle counter LOW
|
if (cpu_cnt_lo_width_c > 0) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
|
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
|
when csr_cycleh_c | csr_mcycleh_c => -- [m]cycleh (r/w): Cycle counter HIGH
|
when csr_cycleh_c | csr_mcycleh_c => -- [m]cycleh (r/w): Cycle counter HIGH
|
if (cpu_cnt_hi_width_c > 0) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
|
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_hi_width_c-1 downto 0) <= csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0); else NULL; end if;
|
|
|
when csr_instret_c | csr_minstret_c => -- [m]instret (r/w): Instructions-retired counter LOW
|
when csr_instret_c | csr_minstret_c => -- [m]instret (r/w): Instructions-retired counter LOW
|
if (cpu_cnt_lo_width_c > 0) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
|
if (cpu_cnt_lo_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret(cpu_cnt_lo_width_c-1 downto 0); else NULL; end if;
|
when csr_instreth_c | csr_minstreth_c => -- [m]instreth (r/w): Instructions-retired counter HIGH
|
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;
|
if (cpu_cnt_hi_width_c > 0) and (CPU_EXTENSION_RISCV_Zicntr = true) 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 => -- 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)
|
if (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata <= time_i(31 downto 00); else NULL; end if;
|
|
when csr_timeh_c => -- timeh (r/-): System time HIGH (from MTIME unit)
|
|
if (CPU_EXTENSION_RISCV_Zicntr = true) then csr.rdata <= time_i(63 downto 32); else NULL; end if;
|
|
|
-- hardware performance counters --
|
-- hardware performance counters --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
-- low word (r/w) --
|
-- 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_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) 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;
|
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if;
|
-- high word (r/w) --
|
-- 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_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (CPU_EXTENSION_RISCV_Zihpm = true) 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_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (CPU_EXTENSION_RISCV_Zihpm = true) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if;
|
|
|
-- machine information registers --
|
-- machine information registers --
|
-- --------------------------------------------------------------------
|
-- --------------------------------------------------------------------
|
-- when csr_mvendorid_c => NULL; -- 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_marchid_c => csr.rdata(4 downto 0) <= "10011"; -- marchid (r/-): arch ID - official RISC-V open-source arch ID
|