diff --git a/rtl/ibex_controller.sv b/rtl/ibex_controller.sv index d2019155..67207fa4 100644 --- a/rtl/ibex_controller.sv +++ b/rtl/ibex_controller.sv @@ -411,57 +411,29 @@ module ibex_controller ( ctrl_fsm_ns = DECODE; end - // flush the pipeline, insert NOP FLUSH: begin + // flush the pipeline + halt_if_o = 1'b1; + halt_id = 1'b1; + ctrl_fsm_ns = DECODE; - halt_if_o = 1'b1; - halt_id = 1'b1; + // exceptions: set exception PC, save PC and exception cause + if (exc_req || store_err_q || load_err_q) begin + pc_set_o = 1'b1; + pc_mux_o = PC_EXC; + exc_pc_mux_o = debug_mode_q ? EXC_PC_DBG_EXC : EXC_PC_EXC; + csr_save_id_o = 1'b1; + csr_save_cause_o = 1'b1; - if (!wfi_insn_i) begin - ctrl_fsm_ns = DECODE; - end else begin - ctrl_fsm_ns = WAIT_SLEEP; - end + // set exception registers, priorities according to Table 3.7 of RISC-V Privileged Spec + if (illegal_insn_i) begin + exc_cause_o = EXC_CAUSE_ILLEGAL_INSN; + csr_mtval_o = instr_is_compressed_i ? {16'b0, instr_compressed_i} : instr_i; - unique case(1'b1) - ecall_insn_i: begin - //ecall - pc_mux_o = PC_EXC; - pc_set_o = 1'b1; - exc_pc_mux_o = EXC_PC_EXC; - exc_cause_o = EXC_CAUSE_ECALL_MMODE; - csr_save_id_o = 1'b1; - csr_save_cause_o = 1'b1; - end - illegal_insn_i: begin - //exceptions - pc_mux_o = PC_EXC; - pc_set_o = 1'b1; - if (debug_mode_q) begin - exc_pc_mux_o = EXC_PC_DBG_EXC; - end else begin - exc_pc_mux_o = EXC_PC_EXC; - end - exc_cause_o = EXC_CAUSE_ILLEGAL_INSN; - csr_save_id_o = 1'b1; - csr_save_cause_o = 1'b1; - csr_mtval_o = instr_is_compressed_i ? {16'b0, instr_compressed_i} : instr_i; - end - mret_insn_i: begin - //mret - pc_mux_o = PC_ERET; - pc_set_o = 1'b1; - csr_restore_mret_id_o = 1'b1; - end - dret_insn_i: begin - //dret - pc_mux_o = PC_DRET; - pc_set_o = 1'b1; - debug_mode_n = 1'b0; - csr_restore_dret_id_o = 1'b1; - end - ebrk_insn_i: begin - //ebreak + end else if (ecall_insn_i) begin + exc_cause_o = EXC_CAUSE_ECALL_MMODE; + + end else if (ebrk_insn_i) begin if (debug_mode_q) begin /* * ebreak in debug mode re-enters debug mode @@ -470,14 +442,20 @@ module ibex_controller ( * Mode, it halts the hart again but without updating dpc or * dcsr." [RISC-V Debug Specification v0.13.1, p. 41] */ - ctrl_fsm_ns = DBG_TAKEN_ID; + pc_set_o = 1'b0; + csr_save_id_o = 1'b0; + csr_save_cause_o = 1'b0; + ctrl_fsm_ns = DBG_TAKEN_ID; end else if (debug_ebreakm_i) begin /* * dcsr.ebreakm == 1: * "ebreak instructions in M-mode enter Debug Mode." * (Debug Spec, p. 44) */ - ctrl_fsm_ns = DBG_TAKEN_ID; + pc_set_o = 1'b0; + csr_save_id_o = 1'b0; + csr_save_cause_o = 1'b0; + ctrl_fsm_ns = DBG_TAKEN_ID; end else begin /* * "The EBREAK instruction is used by debuggers to cause control @@ -488,35 +466,33 @@ module ibex_controller ( * ECALL or EBREAK instruction itself, not the address of the * following instruction." (Privileged Spec, p. 40) */ - pc_mux_o = PC_EXC; - pc_set_o = 1'b1; - exc_pc_mux_o = EXC_PC_EXC; - exc_cause_o = EXC_CAUSE_BREAKPOINT; - csr_save_id_o = 1'b1; - csr_save_cause_o = 1'b1; + exc_cause_o = EXC_CAUSE_BREAKPOINT; end - end - load_err_q: begin - pc_mux_o = PC_EXC; - pc_set_o = 1'b1; - exc_pc_mux_o = EXC_PC_EXC; - exc_cause_o = EXC_CAUSE_LOAD_ACCESS_FAULT; - csr_save_id_o = 1'b1; - csr_save_cause_o = 1'b1; - csr_mtval_o = lsu_addr_last_i; - end - store_err_q: begin - pc_mux_o = PC_EXC; - pc_set_o = 1'b1; - exc_pc_mux_o = EXC_PC_EXC; + + end else if (store_err_q) begin exc_cause_o = EXC_CAUSE_STORE_ACCESS_FAULT; - csr_save_id_o = 1'b1; - csr_save_cause_o = 1'b1; + csr_mtval_o = lsu_addr_last_i; + + end else if (load_err_q) begin + exc_cause_o = EXC_CAUSE_LOAD_ACCESS_FAULT; csr_mtval_o = lsu_addr_last_i; end - default:; - endcase + end else begin + // special instructions + if (mret_insn_i) begin + pc_mux_o = PC_ERET; + pc_set_o = 1'b1; + csr_restore_mret_id_o = 1'b1; + end else if (dret_insn_i) begin + pc_mux_o = PC_DRET; + pc_set_o = 1'b1; + csr_restore_dret_id_o = 1'b1; + debug_mode_n = 1'b0; + end else if (wfi_insn_i) begin + ctrl_fsm_ns = WAIT_SLEEP; + end + end // exc_req // single stepping // set exception registers, but do not jump into handler (debug-spec p.44).