Alias DPC to the real program counter, small savings overall
This commit is contained in:
parent
aa438fc37c
commit
f771a1294d
|
@ -224,6 +224,10 @@ wire x_jump_not_except;
|
|||
wire x_mmode_execution;
|
||||
wire x_trap_wfi;
|
||||
|
||||
wire [W_ADDR-1:0] debug_dpc_wdata;
|
||||
wire debug_dpc_wen;
|
||||
wire [W_ADDR-1:0] debug_dpc_rdata;
|
||||
|
||||
hazard3_decode #(
|
||||
`include "hazard3_config_inst.vh"
|
||||
) decode_u (
|
||||
|
@ -243,6 +247,10 @@ hazard3_decode #(
|
|||
.m_mode (x_mmode_execution),
|
||||
.trap_wfi (x_trap_wfi),
|
||||
|
||||
.debug_dpc_wdata (debug_dpc_wdata),
|
||||
.debug_dpc_wen (debug_dpc_wen),
|
||||
.debug_dpc_rdata (debug_dpc_rdata),
|
||||
|
||||
.d_starved (d_starved),
|
||||
.x_stall (x_stall),
|
||||
.f_jump_now (f_jump_now),
|
||||
|
@ -964,6 +972,10 @@ hazard3_csr #(
|
|||
.dbg_data0_wdata (dbg_data0_wdata),
|
||||
.dbg_data0_wen (dbg_data0_wen),
|
||||
|
||||
.debug_dpc_wdata (debug_dpc_wdata),
|
||||
.debug_dpc_wen (debug_dpc_wen),
|
||||
.debug_dpc_rdata (debug_dpc_rdata),
|
||||
|
||||
// CSR access port
|
||||
// *en_soon are early access strobes which are not a function of bus stall.
|
||||
// Can generate access faults (hence traps), but do not actually perform access.
|
||||
|
|
|
@ -36,6 +36,10 @@ module hazard3_csr #(
|
|||
output wire [W_DATA-1:0] dbg_data0_wdata,
|
||||
output wire dbg_data0_wen,
|
||||
|
||||
output wire [W_ADDR-1:0] debug_dpc_wdata,
|
||||
output wire debug_dpc_wen,
|
||||
input wire [W_ADDR-1:0] debug_dpc_rdata,
|
||||
|
||||
// Read port is combinatorial.
|
||||
// Write port is synchronous, and write effects will be observed on the next clock cycle.
|
||||
// The *_soon strobes are versions which the core does not gate with its stall signal.
|
||||
|
@ -510,20 +514,14 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
end
|
||||
end
|
||||
|
||||
reg [XLEN-1:0] dpc;
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
dpc <= X0;
|
||||
end else if (DEBUG_SUPPORT) begin
|
||||
if (enter_debug_mode)
|
||||
dpc <= mepc_in;
|
||||
else if (debug_mode && wen && addr == DPC)
|
||||
// 1 or 2 LSBs are hardwired to 0, depending on IALIGN.
|
||||
dpc <= wdata_update & (~X0 << 2 - EXTENSION_C);
|
||||
end
|
||||
end
|
||||
// DPC is mapped to the real PC in the decode module. We set it to the
|
||||
// exception return address when entering Debug Mode, and whilst in Debug
|
||||
// Mode we can write to it as though it were a CSR. Note only IALIGN'd values
|
||||
// can be written to dpc.
|
||||
assign debug_dpc_wdata = (debug_mode ? wdata_update : mepc_in) & (~X0 << 2 - EXTENSION_C);
|
||||
assign debug_dpc_wen = debug_mode ? wen && addr == DPC : enter_debug_mode;
|
||||
|
||||
// Debug Module's data0 register is mapped into the core's CSR space:
|
||||
assign dbg_data0_wdata = wdata;
|
||||
assign dbg_data0_wen = debug_mode && wen && addr == DMDATA0;
|
||||
|
||||
|
@ -1059,7 +1057,7 @@ always @ (*) begin
|
|||
|
||||
DPC: if (DEBUG_SUPPORT) begin
|
||||
decode_match = match_drw;
|
||||
rdata = dpc;
|
||||
rdata = debug_dpc_rdata;
|
||||
end
|
||||
|
||||
DMDATA0: if (DEBUG_SUPPORT) begin
|
||||
|
@ -1290,8 +1288,8 @@ wire [3:0] mcause_irq_num = irq_active ? standard_irq_num : 4'd0;
|
|||
wire [3:0] vector_sel = !exception_req_any && irq_vector_enable ? mcause_irq_num : 4'd0;
|
||||
|
||||
assign trap_addr =
|
||||
except == EXCEPT_MRET ? mepc :
|
||||
pending_dbg_resume ? dpc : mtvec | {26'h0, vector_sel, 2'h0};
|
||||
except == EXCEPT_MRET ? mepc :
|
||||
pending_dbg_resume ? debug_dpc_rdata : mtvec | {26'h0, vector_sel, 2'h0};
|
||||
|
||||
// Check for exception-like or IRQ-like trap entry; any debug mode entry takes
|
||||
// priority over any regular trap.
|
||||
|
|
|
@ -25,6 +25,10 @@ module hazard3_decode #(
|
|||
input wire m_mode,
|
||||
input wire trap_wfi,
|
||||
|
||||
input wire [W_ADDR-1:0] debug_dpc_wdata,
|
||||
input wire debug_dpc_wen,
|
||||
output wire [W_ADDR-1:0] debug_dpc_rdata,
|
||||
|
||||
output wire d_starved,
|
||||
input wire x_stall,
|
||||
input wire f_jump_now,
|
||||
|
@ -131,6 +135,7 @@ end
|
|||
reg [W_ADDR-1:0] pc;
|
||||
wire [W_ADDR-1:0] pc_seq_next = pc + (d_instr_is_32bit ? 32'h4 : 32'h2);
|
||||
assign d_pc = pc;
|
||||
assign debug_dpc_rdata = pc;
|
||||
|
||||
// Frontend should mark the whole instruction, and nothing but the
|
||||
// instruction, as a predicted branch. This goes wrong when we execute the
|
||||
|
@ -146,7 +151,11 @@ always @ (posedge clk or negedge rst_n) begin
|
|||
if (!rst_n) begin
|
||||
pc <= RESET_VECTOR;
|
||||
end else begin
|
||||
if ((f_jump_now && !assert_cir_lock) || (cir_lock_prev && deassert_cir_lock)) begin
|
||||
if (debug_dpc_wen) begin
|
||||
pc <= debug_dpc_wdata;
|
||||
end else if (debug_mode) begin
|
||||
pc <= pc;
|
||||
end else if ((f_jump_now && !assert_cir_lock) || (cir_lock_prev && deassert_cir_lock)) begin
|
||||
pc <= f_jump_target;
|
||||
end else if (!d_stall && !cir_lock) begin
|
||||
// If this instruction is a predicted-taken branch (and has not
|
||||
|
|
Loading…
Reference in New Issue