Add support to debug unit to set the Program Counter

This commit is contained in:
Andreas Traber 2015-09-01 18:18:02 +02:00
parent 68a9171fb3
commit bb693c8e6b
4 changed files with 27 additions and 31 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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 ),