From 96c69d0bb0d4b356f2374ef9e4f8a28bd50a31d5 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Tue, 1 Mar 2022 21:14:49 +0000 Subject: [PATCH] Cut in->out paths on debug halt/resume request Should be harmless, because in practice these should always be driven from a register in the DM, but still better to cut the path --- hdl/hazard3_csr.v | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/hdl/hazard3_csr.v b/hdl/hazard3_csr.v index 9d77422..b45f17a 100644 --- a/hdl/hazard3_csr.v +++ b/hdl/hazard3_csr.v @@ -837,21 +837,31 @@ assign illegal = (wen_soon || ren_soon) && !decode_match; // ---------------------------------------------------------------------------- // Debug run/halt +// req_resume_prev is to cut an in->out path from request to trap addr. reg have_just_reset; reg step_halt_req; +reg dbg_req_resume_prev; +reg dbg_req_halt_prev; reg pending_dbg_resume_prev; -wire pending_dbg_resume = (pending_dbg_resume_prev || dbg_req_resume) && debug_mode; +wire pending_dbg_resume = (pending_dbg_resume_prev || dbg_req_resume_prev) && debug_mode; always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin have_just_reset <= |DEBUG_SUPPORT; step_halt_req <= 1'b0; + dbg_req_resume_prev <= 1'b0; + dbg_req_halt_prev <= 1'b0; pending_dbg_resume_prev <= 1'b0; end else if (DEBUG_SUPPORT) begin if (instr_ret) have_just_reset <= 1'b0; + // Just a delayed version of the request from outside of the core. + // Delay is fine because the DM awaits ack before deasserting. + dbg_req_resume_prev <= dbg_req_resume; + dbg_req_halt_prev <= dbg_req_halt; + if (debug_mode) begin step_halt_req <= 1'b0; end else if (dcsr_step && (instr_ret || (trap_enter_vld && trap_enter_rdy))) begin @@ -898,7 +908,7 @@ wire want_halt_except = DEBUG_SUPPORT && !debug_mode && ( // load/store address phase) because at that point we can't suppress the bus // access.. wire want_halt_irq_if_no_exception = DEBUG_SUPPORT && !debug_mode && !want_halt_except && ( - (dbg_req_halt && !delay_irq_entry) || + (dbg_req_halt_prev && !delay_irq_entry) || (dbg_req_halt_on_reset && have_just_reset) || step_halt_req ); @@ -911,9 +921,9 @@ wire want_halt_irq = want_halt_irq_if_no_exception && !halt_delayed_by_exception assign dcause_next = // Trigger would be highest priority if implemented - except == EXCEPT_EBREAK ? 3'h1 : // ebreak (priority 3) - dbg_req_halt || (dbg_req_halt_on_reset && have_just_reset) ? 3'h3 : // halt or reset-halt (priority 1, 2) - 3'h4; // single-step (priority 0) + except == EXCEPT_EBREAK ? 3'h1 : // ebreak (priority 3) + 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;