From 7101cccf3b6ae378ff90d39b3dc4913ce7754713 Mon Sep 17 00:00:00 2001 From: Luke Wren <wren6991@gmail.com> Date: Thu, 19 Jan 2023 13:46:55 +0000 Subject: [PATCH] Cut through-path on reset halt request from debug module to bus --- hdl/hazard3_csr.v | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/hdl/hazard3_csr.v b/hdl/hazard3_csr.v index 047ee44..c2e030c 100644 --- a/hdl/hazard3_csr.v +++ b/hdl/hazard3_csr.v @@ -1126,6 +1126,7 @@ reg have_just_reset; reg step_halt_req; reg dbg_req_resume_prev; reg dbg_req_halt_prev; +reg dbg_req_halt_on_reset_sticky; reg pending_dbg_resume_prev; wire pending_dbg_resume = (pending_dbg_resume_prev || dbg_req_resume_prev) && debug_mode; @@ -1145,12 +1146,20 @@ end always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin have_just_reset <= |DEBUG_SUPPORT; + dbg_req_halt_on_reset_sticky <= 1'b0; step_halt_req <= 1'b0; dbg_req_resume_prev <= 1'b0; pending_dbg_resume_prev <= 1'b0; end else if (DEBUG_SUPPORT) begin - if (instr_ret) - have_just_reset <= 1'b0; + have_just_reset <= 1'b0; + + // One-cycle delay on assertion of reset halt req is harmless because + // of a matching delay on the first instruction fetch (reset_holdoff). + if (have_just_reset && dbg_req_halt_on_reset) begin + dbg_req_halt_on_reset_sticky <= 1'b1; + end else if (enter_debug_mode) begin + dbg_req_halt_on_reset_sticky <= 1'b0; + end dbg_req_resume_prev <= dbg_req_resume; @@ -1202,7 +1211,7 @@ wire want_halt_except = DEBUG_SUPPORT && !debug_mode && ( // access. Others are fine because they are never mid-instruction in stage 2. wire want_halt_irq_if_no_exception = DEBUG_SUPPORT && !debug_mode && !want_halt_except && ( (dbg_req_halt_prev && !delay_irq_entry) || - (dbg_req_halt_on_reset && have_just_reset) || + dbg_req_halt_on_reset_sticky || step_halt_req ); @@ -1213,10 +1222,10 @@ wire want_halt_irq_if_no_exception = DEBUG_SUPPORT && !debug_mode && !want_halt_ wire want_halt_irq = want_halt_irq_if_no_exception && !halt_delayed_by_exception; assign dcause_next = - except == EXCEPT_EBREAK && except_to_d_mode ? 3'h2 : // trigger (priority 4) - 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) + except == EXCEPT_EBREAK && except_to_d_mode ? 3'h2 : // trigger (priority 4) + except == EXCEPT_EBREAK ? 3'h1 : // ebreak (priority 3) + dbg_req_halt_prev || dbg_req_halt_on_reset ? 3'h3 : // halt or reset-halt (priority 1, 2) + 3'h4; // single-step (priority 0) 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; @@ -1229,7 +1238,8 @@ assign dbg_instr_caught_ebreak = debug_mode && except == EXCEPT_EBREAK && trap_e // Note we exclude ebreak from here regardless of dcsr.ebreakm, since we are // already in debug mode at this point -assign dbg_instr_caught_exception = debug_mode && except != EXCEPT_NONE && except != EXCEPT_EBREAK && trap_enter_rdy; +assign dbg_instr_caught_exception = debug_mode && except != EXCEPT_NONE && + except != EXCEPT_EBREAK && trap_enter_rdy; // ---------------------------------------------------------------------------- // Trap request generation