diff --git a/controller.sv b/controller.sv index f20ab355..e00184ef 100644 --- a/controller.sv +++ b/controller.sv @@ -170,7 +170,6 @@ module controller logic jr_stall; logic trap_stall; - logic set_npc; `ifdef BRANCH_PREDICTION logic wrong_branch_taken; `endif @@ -1185,11 +1184,21 @@ module controller DBG_WAIT: begin - if(dbg_set_npc_i == 1'b1) - ctrl_fsm_ns = FIRST_FETCH; + halt_if = 1'b1; + halt_id = 1'b1; + + if(dbg_set_npc_i == 1'b1) begin + halt_id = 1'b0; + pc_mux_sel_o = `PC_DBG_NPC; + ctrl_fsm_ns = DBG_WAIT; + end + + if(dbg_stall_i == 1'b0) begin + halt_if = 1'b0; + halt_id = 1'b0; - if(dbg_stall_i == 1'b0) ctrl_fsm_ns = DECODE; + end end FLUSH_EX: @@ -1296,8 +1305,8 @@ module controller // we unstall the if_stage if the debug unit wants to set a new // pc, so that the new value gets written into current_pc_if and is // used by the instr_core_interface - stall_if_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | halt_if | dbg_stall_i | (~pc_valid_i) | (jump_in_id_o == `BRANCH_COND); - stall_id_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | halt_id | dbg_stall_i; + stall_if_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | halt_if | (~pc_valid_i) | (jump_in_id_o == `BRANCH_COND); + stall_id_o = instr_ack_stall | load_stall | jr_stall | lsu_stall | misalign_stall | halt_id; stall_ex_o = instr_ack_stall | lsu_stall | dbg_stall_i; stall_wb_o = lsu_stall | dbg_stall_i; end @@ -1374,22 +1383,6 @@ module controller end end - // hold NPC until IF stage has taken over this value - always_ff @(posedge clk , negedge rst_n) - begin : HOLD_NPC - if ( rst_n == 1'b0 ) - begin - set_npc <= 1'b0; - end - else - begin - if (dbg_set_npc_i == 1'b1) - set_npc <= 1'b1; - else if (stall_if_o == 1'b0) - set_npc <= 1'b0; - end - end - // Performance Counters assign perf_jump_o = (jump_in_id_o == `BRANCH_JAL || jump_in_id_o == `BRANCH_JALR); assign perf_branch_o = (jump_in_id_o == `BRANCH_COND); diff --git a/if_stage.sv b/if_stage.sv index 4fff8e6f..3abbeec0 100644 --- a/if_stage.sv +++ b/if_stage.sv @@ -73,8 +73,8 @@ module if_stage input logic branch_decision_i, // from debug unit - input logic [31:0] dbg_pc_from_npc, - input logic dbg_set_npc, + input logic [31:0] dbg_npc_i, + input logic dbg_set_npc_i, // pipeline stall input logic stall_if_i, @@ -161,6 +161,7 @@ module if_stage `PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler `PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception `PC_HWLOOP: fetch_addr_n = pc_from_hwloop_i; // PC is taken from hwloop start addr + `PC_DBG_NPC: fetch_addr_n = dbg_npc_i; // PC is taken from debug unit default: begin fetch_addr_n = {boot_addr_i[31:5], `EXC_OFF_RST}; @@ -176,10 +177,11 @@ module if_stage unaligned_jump = 1'b0; case (pc_mux_sel_i) - `PC_JUMP: unaligned_jump = jump_target_id_i[1]; - `PC_BRANCH: unaligned_jump = jump_target_ex_i[1]; - `PC_ERET: unaligned_jump = exception_pc_reg_i[1]; - `PC_HWLOOP: unaligned_jump = pc_from_hwloop_i[1]; + `PC_JUMP: unaligned_jump = jump_target_id_i[1]; + `PC_BRANCH: unaligned_jump = jump_target_ex_i[1]; + `PC_ERET: unaligned_jump = exception_pc_reg_i[1]; + `PC_HWLOOP: unaligned_jump = pc_from_hwloop_i[1]; + `PC_DBG_NPC: unaligned_jump = dbg_npc_i[1]; endcase end @@ -386,7 +388,7 @@ module if_stage offset_fsm_ns = WAIT_JUMPED_ALIGNED; end - end else if (jump_in_id_i == `BRANCH_JAL || jump_in_id_i == `BRANCH_JALR) begin + end else if (jump_in_id_i == `BRANCH_JAL || jump_in_id_i == `BRANCH_JALR || dbg_set_npc_i) begin fetch_req = 1'b1; if (unaligned_jump) offset_fsm_ns = WAIT_JUMPED_UNALIGNED; diff --git a/include/defines.sv b/include/defines.sv index 1e86ad0f..ec1fe205 100644 --- a/include/defines.sv +++ b/include/defines.sv @@ -359,6 +359,7 @@ endfunction // prettyPrintInstruction `define PC_EXCEPTION 3'b100 `define PC_ERET 3'b101 `define PC_HWLOOP 3'b110 +`define PC_DBG_NPC 3'b111 // Exception PC mux selector defines `define EXC_PC_NO_INCR 2'b00 diff --git a/riscv_core.sv b/riscv_core.sv index 0eb11a31..927f9159 100644 --- a/riscv_core.sv +++ b/riscv_core.sv @@ -274,8 +274,8 @@ module riscv_core .exc_pc_mux_i ( exc_pc_mux_id ), // selector for exception multiplexer // from debug unit - .dbg_pc_from_npc ( dbg_npc ), - .dbg_set_npc ( dbg_set_npc ), + .dbg_npc_i ( dbg_npc ), + .dbg_set_npc_i ( dbg_set_npc ), // Jump and branch target and decision .jump_in_id_i ( jump_in_id ),