mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
Correctly prioritize exceptions in controller
This commit is contained in:
parent
95c0dc0556
commit
3e1c8df311
1 changed files with 49 additions and 73 deletions
|
@ -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).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue