From edfe7f601e73b715b9dcb941188a937c7ffe7341 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sun, 26 Jun 2022 21:55:51 +0100 Subject: [PATCH] Clear local monitor on non-debug trap entry/exit --- hdl/hazard3_core.v | 27 +++++++++++++++++---------- hdl/hazard3_csr.v | 4 +++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/hdl/hazard3_core.v b/hdl/hazard3_core.v index ecf6320..f70d69c 100644 --- a/hdl/hazard3_core.v +++ b/hdl/hazard3_core.v @@ -277,6 +277,7 @@ wire x_alu_cmp; wire [W_DATA-1:0] m_trap_addr; wire m_trap_is_irq; +wire m_trap_is_debug_entry; wire m_trap_enter_vld; wire m_trap_enter_soon; wire m_trap_enter_rdy = f_jump_rdy; @@ -900,6 +901,7 @@ hazard3_csr #( // Trap signalling .trap_addr (m_trap_addr), .trap_is_irq (m_trap_is_irq), + .m_trap_is_debug_entry (m_trap_is_debug_entry), .trap_enter_soon (m_trap_enter_soon), .trap_enter_vld (m_trap_enter_vld), .trap_enter_rdy (m_trap_enter_rdy), @@ -1086,21 +1088,26 @@ end // Local monitor update. // - Set on a load-reserved with good response from global monitor // - Cleared by any store-conditional -// - Not affected by trap entry (permitted by RISC-V spec) +// - Cleared by non-debug-related trap entry/exit always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin mw_local_exclusive_reserved <= 1'b0; - end else if (|EXTENSION_A && (!m_stall || bus_dph_err_d)) begin - if (d_memop_is_amo) begin + end else begin + if (|EXTENSION_A && (!m_stall || bus_dph_err_d)) begin + if (d_memop_is_amo) begin + mw_local_exclusive_reserved <= 1'b0; + end else if (xm_memop == MEMOP_SC_W && (bus_dph_ready_d || bus_dph_err_d)) begin + mw_local_exclusive_reserved <= 1'b0; + end else if (xm_memop == MEMOP_LR_W && bus_dph_ready_d) begin + // In theory, the bus should never report HEXOKAY when HRESP is asserted. + // Still might happen (e.g. if HEXOKAY is tied high), so mask HEXOKAY with + // HREADY to be sure a failed lr.w clears the monitor. + mw_local_exclusive_reserved <= bus_dph_exokay_d && !bus_dph_err_d; + end + end + if (m_trap_enter_vld && m_trap_enter_rdy && !(debug_mode || m_trap_is_debug_entry)) begin mw_local_exclusive_reserved <= 1'b0; - end else if (xm_memop == MEMOP_SC_W && (bus_dph_ready_d || bus_dph_err_d)) begin - mw_local_exclusive_reserved <= 1'b0; - end else if (xm_memop == MEMOP_LR_W && bus_dph_ready_d) begin - // In theory, the bus should never report HEXOKAY when HRESP is asserted. - // Still might happen (e.g. if HEXOKAY is tied high), so mask HEXOKAY with - // HREADY to be sure a failed lr.w clears the monitor. - mw_local_exclusive_reserved <= bus_dph_exokay_d && !bus_dph_err_d; end end end diff --git a/hdl/hazard3_csr.v b/hdl/hazard3_csr.v index 7ba6abf..a9af60c 100644 --- a/hdl/hazard3_csr.v +++ b/hdl/hazard3_csr.v @@ -67,6 +67,7 @@ module hazard3_csr #( // case we lower trap_enter_vld. output wire [XLEN-1:0] trap_addr, output wire trap_is_irq, + output wire trap_is_debug_entry, output wire trap_enter_vld, input wire trap_enter_rdy, // True when we are about to trap, but are waiting for an excepting or @@ -1068,7 +1069,8 @@ assign dcause_next = dbg_req_halt_prev || (dbg_req_halt_on_reset && have_just_reset) ? 3'h3 : // halt or reset-halt (priority 1, 2) 3'h4; // single-step (priority 0) -assign enter_debug_mode = !debug_mode && (want_halt_irq || want_halt_except) && trap_enter_rdy; +assign trap_is_debug_entry = |DEBUG_SUPPORT && !debug_mode && (want_halt_irq || want_halt_except); +assign enter_debug_mode = trap_is_debug_entry && trap_enter_rdy; assign exit_debug_mode = debug_mode && pending_dbg_resume && trap_enter_rdy;