Skip to content

Commit fb6f11b

Browse files
committed
[dv] Hold debug_req until the hart has halted
debug_seq pulsed debug_req for a fixed 75 cycles. A request that wakes the core from WFI needs longer than that to reach the debug ROM: the clock restarts, the instruction after the WFI is refetched into ID, debug entry flushes it and the halt address is fetched. RVFI attaches a captured request to the first instruction entering ID, which is the flushed one, and the debug ROM's first instruction then reports the live debug_req, already low. The cosim never learns of the request and steps Spike past the WFI: riscv_debug_single_step_test seed 12 with real stepping failed with "DUT retired 80000000 but the ISS retired 800035f4". A debug module keeps haltreq asserted until the hart reports halted, which the debug ROM does with its first instructions. Do the same: after the pulse, keep debug_req high until RVFI has reported a retirement that carries the request (debug_mode alone rises at debug entry, before the halt address is fetched, so it is too early). Not seeing one within 5000 cycles is an error. debug_new_seq is left alone: its only user, riscv_assorted_traps_interrupts_debug_test, runs with +no_wfi=1 and pulses for 3000-5000 cycles. Signed-off-by: Kulan Palanichamy <kulan.palanichamy@opentitan.org>
1 parent 200dbeb commit fb6f11b

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

‎dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,17 @@ class debug_seq extends core_base_seq#(irq_seq_item);
175175
`uvm_object_new
176176

177177
int unsigned drop_delay = 75;
178+
// Longest time the request is held waiting for the core to enter debug mode.
179+
int unsigned hold_timeout_cycles = 5000;
180+
virtual core_ibex_rvfi_if rvfi_vif;
178181

179182
virtual task body();
180183
if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if", dut_vif)) begin
181184
`uvm_fatal(get_full_name(), "Cannot get dut_if")
182185
end
186+
if (!uvm_config_db#(virtual core_ibex_rvfi_if)::get(null, "", "rvfi_if", rvfi_vif)) begin
187+
`uvm_fatal(get_full_name(), "Cannot get rvfi_if")
188+
end
183189
dut_vif.dut_cb.debug_req <= 1'b0;
184190
super.body();
185191
endtask
@@ -188,6 +194,22 @@ class debug_seq extends core_base_seq#(irq_seq_item);
188194
`uvm_info(get_full_name(), "Sending debug request", UVM_HIGH)
189195
dut_vif.dut_cb.debug_req <= 1'b1;
190196
clk_vif.wait_clks(drop_delay);
197+
// A debug module keeps haltreq asserted until the hart reports halted, which the debug ROM does
198+
// with its first instructions. Keep the request up until the core has retired an instruction
199+
// that reports the request on RVFI (the first debug ROM instruction, or the next retirement if
200+
// the core was already in debug mode), so a request that wakes the core from WFI is still
201+
// asserted when that instruction enters ID, where RVFI samples it for the cosim.
202+
`DV_SPINWAIT_EXIT(begin
203+
wait (dut_vif.dut_cb.debug_mode == 1'b1);
204+
do @(rvfi_vif.monitor_cb);
205+
while (!(rvfi_vif.monitor_cb.valid && rvfi_vif.monitor_cb.ext_debug_req));
206+
end,
207+
begin
208+
clk_vif.wait_clks(hold_timeout_cycles);
209+
`uvm_error(get_full_name(),
210+
"No retirement reported the debug request before the hold timeout")
211+
end,
212+
"")
191213
dut_vif.dut_cb.debug_req <= 1'b0;
192214
endtask
193215

0 commit comments

Comments
 (0)