Line 160... |
Line 160... |
clear : std_ulogic;
|
clear : std_ulogic;
|
end record;
|
end record;
|
signal ipb : ipb_t;
|
signal ipb : ipb_t;
|
|
|
-- instruction execution engine --
|
-- instruction execution engine --
|
type execute_engine_state_t is (IDLE, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, STORE, LOAD, LOADSTORE_0, LOADSTORE_1, CSR_ACCESS);
|
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, STORE, LOAD, LOADSTORE_0, LOADSTORE_1, 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;
|
i_reg : std_ulogic_vector(31 downto 0);
|
i_reg : std_ulogic_vector(31 downto 0);
|
Line 190... |
Line 190... |
exc_ack : std_ulogic; -- acknowledge all exceptions
|
exc_ack : std_ulogic; -- acknowledge all exceptions
|
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
|
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
|
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
|
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
|
cause : std_ulogic_vector(data_width_c-1 downto 0); -- trap ID (for "mcause")
|
cause : std_ulogic_vector(data_width_c-1 downto 0); -- trap ID (for "mcause")
|
cause_nxt : std_ulogic_vector(data_width_c-1 downto 0);
|
cause_nxt : std_ulogic_vector(data_width_c-1 downto 0);
|
instr : std_ulogic_vector(31 downto 0); -- faulting instruction
|
|
exc_src : std_ulogic_vector(exception_width_c-1 downto 0);
|
exc_src : std_ulogic_vector(exception_width_c-1 downto 0);
|
--
|
--
|
env_start : std_ulogic; -- start trap handler env
|
env_start : std_ulogic; -- start trap handler env
|
env_start_ack : std_ulogic; -- start of trap handler acknowledged
|
env_start_ack : std_ulogic; -- start of trap handler acknowledged
|
env_end : std_ulogic; -- end trap handler env
|
env_end : std_ulogic; -- end trap handler env
|
Line 230... |
Line 229... |
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
|
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
|
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
|
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
|
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W)
|
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W)
|
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-)
|
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-)
|
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
|
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
|
mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-)
|
|
cycle : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-), plus carry bit
|
cycle : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-), plus carry bit
|
instret : std_ulogic_vector(32 downto 0); -- instret (R/-), plus carry bit
|
instret : std_ulogic_vector(32 downto 0); -- instret (R/-), plus carry bit
|
cycleh : std_ulogic_vector(31 downto 0); -- cycleh, mtimeh (R/-)
|
cycleh : std_ulogic_vector(31 downto 0); -- cycleh, mtimeh (R/-)
|
instreth : std_ulogic_vector(31 downto 0); -- instreth (R/-)
|
instreth : std_ulogic_vector(31 downto 0); -- instreth (R/-)
|
misa_c_en : std_ulogic; -- misa: C extension enable bit (R/W)
|
misa_c_en : std_ulogic; -- misa: C extension enable bit (R/W)
|
Line 545... |
Line 543... |
execute_engine.last_pc <= boot_base_c(data_width_c-1 downto 1) & '0';
|
execute_engine.last_pc <= boot_base_c(data_width_c-1 downto 1) & '0';
|
else -- boot from IMEM
|
else -- boot from IMEM
|
execute_engine.pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
|
execute_engine.pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
|
execute_engine.last_pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
|
execute_engine.last_pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
|
end if;
|
end if;
|
execute_engine.state <= IDLE;
|
execute_engine.state <= SYS_WAIT;
|
execute_engine.state_prev <= IDLE;
|
execute_engine.state_prev <= SYS_WAIT;
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0';
|
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0';
|
if (execute_engine.state = EXECUTE) then
|
if (execute_engine.state = EXECUTE) then
|
execute_engine.last_pc <= execute_engine.pc(data_width_c-1 downto 1) & '0';
|
execute_engine.last_pc <= execute_engine.pc(data_width_c-1 downto 1) & '0';
|
end if;
|
end if;
|
Line 691... |
Line 689... |
end if;
|
end if;
|
|
|
-- state machine --
|
-- state machine --
|
case execute_engine.state is
|
case execute_engine.state is
|
|
|
when IDLE => -- Delay cycle (used to wait for side effects to kick in)
|
when SYS_WAIT => -- Delay cycle (used to wait for side effects to kick in)
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
execute_engine.state_nxt <= DISPATCH;
|
execute_engine.state_nxt <= DISPATCH;
|
|
|
when DISPATCH => -- Get new command from instruction prefetch buffer (IPB)
|
when DISPATCH => -- Get new command from instruction prefetch buffer (IPB)
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
Line 717... |
Line 715... |
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (trap_ctrl.env_start = '1') then
|
if (trap_ctrl.env_start = '1') then
|
trap_ctrl.env_start_ack <= '1';
|
trap_ctrl.env_start_ack <= '1';
|
execute_engine.pc_nxt <= csr.mtvec(data_width_c-1 downto 1) & '0';
|
execute_engine.pc_nxt <= csr.mtvec(data_width_c-1 downto 1) & '0';
|
fetch_engine.reset <= '1';
|
fetch_engine.reset <= '1';
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
end if;
|
end if;
|
|
|
when EXECUTE => -- Decode and execute instruction
|
when EXECUTE => -- Decode and execute instruction
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
|
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
|
Line 808... |
Line 806... |
--
|
--
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
|
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
|
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
|
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
|
when x"000" => -- ECALL
|
when x"000" => -- ECALL
|
trap_ctrl.env_call <= '1';
|
trap_ctrl.env_call <= '1';
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
when x"001" => -- EBREAK
|
when x"001" => -- EBREAK
|
trap_ctrl.break_point <= '1';
|
trap_ctrl.break_point <= '1';
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
when x"302" => -- MRET
|
when x"302" => -- MRET
|
trap_ctrl.env_end <= '1';
|
trap_ctrl.env_end <= '1';
|
execute_engine.pc_nxt <= csr.mepc(data_width_c-1 downto 1) & '0';
|
execute_engine.pc_nxt <= csr.mepc(data_width_c-1 downto 1) & '0';
|
fetch_engine.reset <= '1';
|
fetch_engine.reset <= '1';
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
when x"105" => -- WFI
|
when x"105" => -- WFI
|
execute_engine.state_nxt <= TRAP;
|
execute_engine.state_nxt <= TRAP;
|
when others => -- undefined
|
when others => -- undefined
|
NULL;
|
NULL;
|
end case;
|
end case;
|
Line 841... |
Line 839... |
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- default
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- default
|
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
|
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
|
|
-- register operations --
|
when funct3_csrrw_c => -- CSRRW
|
when funct3_csrrw_c => -- CSRRW
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2
|
ctrl_nxt(ctrl_rf_clear_rs2_c) <= '1'; -- rs2 = 0
|
ctrl_nxt(ctrl_rf_clear_rs2_c) <= '1'; -- rs2 = 0
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
|
Line 857... |
Line 856... |
when funct3_csrrc_c => -- CSRRC
|
when funct3_csrrc_c => -- CSRRC
|
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
|
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
|
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
|
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
|
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
|
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
|
|
-- immediate operations --
|
when funct3_csrrwi_c => -- CSRRWI
|
when funct3_csrrwi_c => -- CSRRWI
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
|
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
|
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- rs1 = 0
|
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- rs1 = 0
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
|
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
|
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
|
Line 896... |
Line 896... |
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (execute_engine.is_jump = '1') or (execute_engine.branch_taken = '1') then
|
if (execute_engine.is_jump = '1') or (execute_engine.branch_taken = '1') then
|
execute_engine.pc_nxt <= alu_add_i(data_width_c-1 downto 1) & '0';
|
execute_engine.pc_nxt <= alu_add_i(data_width_c-1 downto 1) & '0';
|
fetch_engine.reset <= '1';
|
fetch_engine.reset <= '1';
|
end if;
|
end if;
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
|
|
when LOAD => -- trigger memory read request
|
when LOAD => -- trigger memory read request
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
ctrl_nxt(ctrl_bus_rd_c) <= '1';--bus_fast_rd <= '1'; -- fast read request
|
ctrl_nxt(ctrl_bus_rd_c) <= '1';--bus_fast_rd <= '1'; -- fast read request
|
execute_engine.state_nxt <= LOADSTORE_0;
|
execute_engine.state_nxt <= LOADSTORE_0;
|
Line 918... |
Line 918... |
when LOADSTORE_1 => -- wait for bus transaction to finish
|
when LOADSTORE_1 => -- wait for bus transaction to finish
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
|
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
|
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
|
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
|
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction
|
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction
|
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD?
|
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD?
|
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
|
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
|
end if;
|
end if;
|
execute_engine.state_nxt <= DISPATCH;
|
execute_engine.state_nxt <= DISPATCH;
|
end if;
|
end if;
|
|
|
when others => -- undefined
|
when others => -- undefined
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
execute_engine.state_nxt <= IDLE;
|
execute_engine.state_nxt <= SYS_WAIT;
|
|
|
end case;
|
end case;
|
end process execute_engine_fsm_comb;
|
end process execute_engine_fsm_comb;
|
|
|
|
|
Line 1040... |
Line 1040... |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
|
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst
|
|
--
|
--
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycle
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycle
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- time
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- time
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instret
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instret
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycleh
|
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycleh
|
Line 1117... |
Line 1116... |
trap_ctrl.exc_buf <= (others => '0');
|
trap_ctrl.exc_buf <= (others => '0');
|
trap_ctrl.irq_buf <= (others => '0');
|
trap_ctrl.irq_buf <= (others => '0');
|
trap_ctrl.exc_ack <= '0';
|
trap_ctrl.exc_ack <= '0';
|
trap_ctrl.irq_ack <= (others => '0');
|
trap_ctrl.irq_ack <= (others => '0');
|
trap_ctrl.cause <= (others => '0');
|
trap_ctrl.cause <= (others => '0');
|
trap_ctrl.instr <= (others => '0');
|
|
trap_ctrl.exc_src <= (others => '0');
|
trap_ctrl.exc_src <= (others => '0');
|
trap_ctrl.env_start <= '0';
|
trap_ctrl.env_start <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
if (CPU_EXTENSION_RISCV_Zicsr = true) then
|
-- exception buffer: misaligned load/store/instruction address
|
-- exception buffer: misaligned load/store/instruction address
|
Line 1144... |
Line 1142... |
-- trap control --
|
-- trap control --
|
if (trap_ctrl.env_start = '0') then -- no started trap handler
|
if (trap_ctrl.env_start = '0') then -- no started trap handler
|
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and
|
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and
|
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- exception/IRQ detected!
|
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- exception/IRQ detected!
|
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program
|
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program
|
trap_ctrl.instr <= execute_engine.i_reg; -- FIXME mtinst transformation not fully implemented yet!
|
|
trap_ctrl.instr(1) <= not execute_engine.is_ci; -- bit is set for uncompressed instruction
|
|
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware
|
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware
|
trap_ctrl.exc_ack <= '1'; -- clear execption
|
trap_ctrl.exc_ack <= '1'; -- clear execption
|
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
|
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
|
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler
|
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler
|
end if;
|
end if;
|
Line 1171... |
Line 1167... |
-- exception acknowledge for bus unit --
|
-- exception acknowledge for bus unit --
|
bus_exc_ack_o <= trap_ctrl.env_start_ack or fetch_engine.bus_err_ack;
|
bus_exc_ack_o <= trap_ctrl.env_start_ack or fetch_engine.bus_err_ack;
|
|
|
-- exception/interrupt/status ID visible for program --
|
-- exception/interrupt/status ID visible for program --
|
csr.mcause <= trap_ctrl.cause;
|
csr.mcause <= trap_ctrl.cause;
|
csr.mtinst <= trap_ctrl.instr;
|
|
|
|
|
|
-- Trap Priority Detector -----------------------------------------------------------------
|
-- Trap Priority Detector -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
trap_priority: process(trap_ctrl)
|
trap_priority: process(trap_ctrl)
|
Line 1408... |
Line 1403... |
csr_rdata_o <= csr.mtval;
|
csr_rdata_o <= csr.mtval;
|
when x"344" => -- R/W: mip - machine interrupt pending
|
when x"344" => -- R/W: mip - machine interrupt pending
|
csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
|
csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
|
csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
|
csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
|
csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
|
csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
|
when x"34a" => -- R/-: mtinst - machine trap instruction (transformed)
|
|
csr_rdata_o <= csr.mtinst;
|
|
-- counter and timers --
|
-- counter and timers --
|
when x"c00" | x"c01" | x"b00" => -- R/-: cycle/time/mcycle: Cycle counter LOW / Timer LOW
|
when x"c00" | x"c01" | x"b00" => -- R/-: cycle/time/mcycle: Cycle counter LOW / Timer LOW
|
csr_rdata_o <= csr.cycle(31 downto 0);
|
csr_rdata_o <= csr.cycle(31 downto 0);
|
when x"c02" | x"b02" => -- R/-: instret/minstret: Instructions-retired counter LOW
|
when x"c02" | x"b02" => -- R/-: instret/minstret: Instructions-retired counter LOW
|
csr_rdata_o <= csr.instret(31 downto 0);
|
csr_rdata_o <= csr.instret(31 downto 0);
|