diff --git a/compressed_decoder.sv b/compressed_decoder.sv index a9cfc85f..39b908ee 100644 --- a/compressed_decoder.sv +++ b/compressed_decoder.sv @@ -58,7 +58,12 @@ module compressed_decoder // c.add -> add rd, rd, rs2 instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], `OPCODE_OP}; end - if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1; + if (instr_i[11:7] == 5'b0) begin + if (instr_i[6:2] == 5'b0) + instr_o = {32'h00_10_00_73}; // EBREAK + else + illegal_instr_o = 1'b1; + end end 3'b001: begin diff --git a/controller.sv b/controller.sv index b593b2f8..7568baf8 100644 --- a/controller.sv +++ b/controller.sv @@ -1032,7 +1032,7 @@ module controller // handle conditional branches if (jump_in_id == `BRANCH_COND) begin - // handle branch if decision is availble in next cycle + // handle branch if decision is available in next cycle if (~stall_id_o) ctrl_fsm_ns = BRANCH; end @@ -1083,13 +1083,17 @@ module controller end // take care of debug - // branches take two cycles, jumps just one - // everything else can be done immediately - if(trap_hit_i == 1'b1 && stall_ex_o == 1'b0 && jump_in_id == `BRANCH_NONE) + // branch conditional will be handled in next state + if(trap_hit_i && jump_in_id != `BRANCH_COND) begin + // halt pipeline immediately halt_if = 1'b1; halt_id = 1'b1; - ctrl_fsm_ns = DBG_FLUSH_EX; + + // make sure the current instruction has been executed + // before changing state to non-decode + if (~stall_ex_o) + ctrl_fsm_ns = DBG_FLUSH_EX; end end @@ -1130,6 +1134,7 @@ module controller end end + // make sure EX stage is flushed DBG_FLUSH_EX: begin halt_if = 1'b1; @@ -1139,6 +1144,7 @@ module controller ctrl_fsm_ns = DBG_FLUSH_WB; end + // make sure WB stage is flushed DBG_FLUSH_WB: begin halt_if = 1'b1; @@ -1148,15 +1154,19 @@ module controller ctrl_fsm_ns = DBG_SIGNAL; end + // now we can signal to the debugger that our pipeline is empty and it + // can examine our current state DBG_SIGNAL: begin dbg_trap_o = 1'b1; - halt_if = 1'b1; - halt_id = 1'b1; + halt_if = 1'b1; + halt_id = 1'b1; ctrl_fsm_ns = DBG_WAIT; end + // The Debugger is active in this state + // we wait until it is done and go back to DECODE DBG_WAIT: begin halt_if = 1'b1; @@ -1170,9 +1180,8 @@ module controller end if(dbg_stall_i == 1'b0) begin - halt_if = 1'b0; - halt_id = 1'b0; - + halt_if = 1'b0; + halt_id = 1'b0; ctrl_fsm_ns = DECODE; end end diff --git a/id_stage.sv b/id_stage.sv index 9b5362fa..c8af19cd 100644 --- a/id_stage.sv +++ b/id_stage.sv @@ -143,7 +143,6 @@ module id_stage input logic [31:0] regfile_alu_wdata_fw_i, // Performance Counters - output logic perf_compressed_o, // current instrution is compressed output logic perf_jump_o, // we are executing a jump instruction output logic perf_branch_o, // we are executing a branch instruction output logic perf_jr_stall_o, // jump-register-hazard @@ -509,7 +508,7 @@ module id_stage .we_b_i ( (dbg_reg_mux_i == 1'b0) ? regfile_alu_we_fw_i : dbg_reg_we_i ) ); - assign dbg_reg_rdata_o = regfile_data_ra_id; + assign dbg_reg_rdata_o = regfile_data_rc_id; //////////////////////////////////////////////////////////////////// // ____ ___ _ _ _____ ____ ___ _ _ _____ ____ // diff --git a/riscv_core.sv b/riscv_core.sv index 6d70da5d..bb1cf278 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -664,7 +664,7 @@ module riscv_core rs2_value = id_stage_i.operand_b_fw_id; // special case for WFI because we don't wait for unstalling there - if ((id_stage_i.stall_id_o == 1'b0 && id_stage_i.controller_i.ctrl_fsm_cs == id_stage_i.controller_i.DECODE) || id_stage_i.controller_i.pipe_flush) + if ((id_stage_i.stall_ex_o == 1'b0 && is_decoding) || id_stage_i.controller_i.pipe_flush) begin mnemonic = ""; imm = 0;