From 1953773ca58246ba71da3485d28176ad2d058e71 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Mon, 10 Oct 2022 22:14:05 +0100 Subject: [PATCH] Don't gate exception into D-mode CSR write, as a valid CSR instruction writing to a valid CSR in D-mode is guaranteed not to raise any exception (particularly the external data0 CSR is of interest) --- hdl/hazard3_core.v | 1 + hdl/hazard3_csr.v | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hdl/hazard3_core.v b/hdl/hazard3_core.v index 8601244..e2fa6f7 100644 --- a/hdl/hazard3_core.v +++ b/hdl/hazard3_core.v @@ -981,6 +981,7 @@ hazard3_csr #( // Can generate access faults (hence traps), but do not actually perform access. .addr (fd_cir[31:20]), // Always I-type immediate .wdata (x_csr_wdata), + .wen_raw (d_csr_wen), .wen_soon (d_csr_wen && !m_trap_enter_soon), .wen (d_csr_wen && !m_trap_enter_soon && !x_stall), .wtype (d_csr_wtype), diff --git a/hdl/hazard3_csr.v b/hdl/hazard3_csr.v index 1a2f9c3..1e6be4f 100644 --- a/hdl/hazard3_csr.v +++ b/hdl/hazard3_csr.v @@ -49,6 +49,7 @@ module hazard3_csr #( input wire [XLEN-1:0] wdata, input wire wen, input wire wen_soon, // wen will be asserted once some stall condition clears + input wire wen_raw, // raw, ungated instruction decode signal, for D-mode regs input wire [1:0] wtype, output reg [XLEN-1:0] rdata, input wire ren, @@ -217,7 +218,7 @@ always @ (posedge clk or negedge rst_n) begin // Note only the MSB of MPP is implemented. It reads back as 11 or 00. mstatus_mpp <= wdata_update[12] || !U_MODE; mstatus_tw <= wdata_update[21] && U_MODE; - end else if (wen && debug_mode && addr == DCSR && U_MODE && DEBUG_SUPPORT) begin + end else if (wen_raw && debug_mode && addr == DCSR && U_MODE && DEBUG_SUPPORT) begin // Debugger can change/observe core state directly through // dcsr.prv (this doesn't affect debugger operation, as all // operations have an effective level of M-mode whilst the core @@ -438,7 +439,7 @@ always @ (posedge clk or negedge rst_n) begin if (addr == MINSTRET) minstret <= wdata_update & {XLEN{|CSR_COUNTER}}; if (addr == MCOUNTINHIBIT) begin - {mcountinhibit_ir, mcountinhibit_cy} <= {wdata_update[2], wdata_update[0]} & {2{|CSR_COUNTER}}; + {mcountinhibit_ir, mcountinhibit_cy} <= {wdata_update[2], wdata_update[0]} | {2{~|CSR_COUNTER}}; end end end @@ -492,8 +493,11 @@ always @ (posedge clk or negedge rst_n) begin dcsr_ebreaku <= 1'b0; dcsr_step <= 1'b0; dcsr_cause <= 3'h0; - end else if (DEBUG_SUPPORT) begin - if (debug_mode && wen && addr == DCSR) begin + end else begin + // Note we can use the ungated write enable in debug mode since a CSR + // write to a valid D-mode CSR address is guaranteed not to generate + // an exception (of any kind, including PMP) in D-mode. + if (debug_mode && wen_raw && addr == DCSR) begin {dcsr_ebreakm, dcsr_ebreaku, dcsr_step} <= { wdata_update[15], wdata_update[12] && U_MODE, @@ -510,12 +514,12 @@ end // 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; +assign debug_dpc_wdata = (debug_mode ? wdata_update : mepc_in) & (~X0 << 2 - EXTENSION_C); +assign debug_dpc_wen = debug_mode ? wen_raw && 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; +assign dbg_data0_wen = debug_mode && wen_raw && addr == DMDATA0; reg tcontrol_mte; reg tcontrol_mpte;