single_step test : only drive debug_req_i after stepping finishes

This addresses a current testbench issue where asserting debug_req_i close to
when single_stepping over an instruction causes an incorrect 'cause' to be
recorded within DCSR.
This commit is contained in:
Harry Callahan 2022-09-29 17:42:47 +01:00
parent 377382fb78
commit 3c11ef10b9
3 changed files with 43 additions and 14 deletions

View file

@ -19,6 +19,7 @@ interface core_ibex_dut_probe_if(input logic clk);
logic debug_req;
ibex_pkg::priv_lvl_e priv_mode;
ibex_pkg::ctrl_fsm_e ctrl_fsm_cs;
logic debug_mode;
clocking dut_cb @(posedge clk);
output fetch_enable;
@ -36,6 +37,7 @@ interface core_ibex_dut_probe_if(input logic clk);
input alert_major_bus;
input priv_mode;
input ctrl_fsm_cs;
input debug_mode;
endclocking
initial begin

View file

@ -199,15 +199,16 @@ module core_ibex_tb_top;
// Irq interface connections
assign irq_vif.reset = ~rst_n;
// Dut_if interface connections
assign dut_if.ecall = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ecall_insn;
assign dut_if.wfi = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.wfi_insn;
assign dut_if.ebreak = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ebrk_insn;
assign dut_if.illegal_instr = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.illegal_insn_d;
assign dut_if.dret = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.dret_insn;
assign dut_if.mret = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.mret_insn;
assign dut_if.reset = ~rst_n;
assign dut_if.priv_mode = dut.u_ibex_top.u_ibex_core.priv_mode_id;
assign dut_if.ctrl_fsm_cs = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ctrl_fsm_cs;
assign dut_if.ecall = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ecall_insn;
assign dut_if.wfi = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.wfi_insn;
assign dut_if.ebreak = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ebrk_insn;
assign dut_if.illegal_instr = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.illegal_insn_d;
assign dut_if.dret = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.dret_insn;
assign dut_if.mret = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.mret_insn;
assign dut_if.reset = ~rst_n;
assign dut_if.priv_mode = dut.u_ibex_top.u_ibex_core.priv_mode_id;
assign dut_if.ctrl_fsm_cs = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.ctrl_fsm_cs;
assign dut_if.debug_mode = dut.u_ibex_top.u_ibex_core.id_stage_i.controller_i.debug_mode_q;
// Instruction monitor connections
assign instr_monitor_if.reset = ~rst_n;
assign instr_monitor_if.valid_id = dut.u_ibex_top.u_ibex_core.id_stage_i.instr_valid_i;

View file

@ -1125,12 +1125,38 @@ class core_ibex_debug_single_step_test extends core_ibex_directed_test;
`uvm_component_utils(core_ibex_debug_single_step_test)
`uvm_component_new
uvm_event e1;
int cnt;
int debug_mode_end_dwell_cycles = 3000;
virtual task check_stimulus();
forever begin
clk_vif.wait_clks(2000);
vseq.start_debug_single_seq();
wait_ret("dret", 50000);
end
e1 = new();
fork
begin
forever begin
// Create an event (e1) whenever we are out of debug_mode for a configurable length of time.
// This allows us to detect when the system has stopped single-stepping.
cnt = 0;
@(negedge dut_vif.dut_cb.debug_mode);
while (dut_vif.dut_cb.debug_mode == '0) begin
clk_vif.wait_clks(1);
cnt++;
if (cnt == debug_mode_end_dwell_cycles) begin
e1.trigger();
break;
end
end
end
end
begin
forever begin
clk_vif.wait_clks(2000);
vseq.start_debug_single_seq();
// Wait for the above event (e1) before sending another debug_req
e1.wait_trigger();
end
end
join_none
endtask
endclass