mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 12:57:13 -04:00
[dv] Fix issues with timeout on WFI
riscv_interrupt_instr_test and riscv_debug_instr_test aim to produce interrupt and debug requests once per unique instruction they've seen. One exception to this is WFI instructions, as these always require an interrupt or debug request to wake the core. This fixes two timeout issues with WFI instructions. 1. The return value of `decode_instruction` is used to determine whether an instruction should have an interrupt or debug request generated for it. For WFI this must always happen or the test will hang. 2. Before calling check_stimulus in a test the testbench waits for 50 clock cycles. For the riscv_interrupt_instr_test and riscv_debug_instr_test if a WFI is executed during these 50 cycles the test will hang. This adds a check to see if the core has gone to sleep in those tests and if so sends interrupt/debug stimulus to wake it up.
This commit is contained in:
parent
e749d8fe3d
commit
d8b2cb0a68
1 changed files with 22 additions and 9 deletions
|
@ -539,7 +539,7 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test;
|
|||
// explicitly set is_seen to 0 and return on WFI instructions,
|
||||
// as if we don't interrupt them, every test will timeout.
|
||||
if (funct3 == 3'b000 && system_imm == 12'h105) begin
|
||||
return 0;
|
||||
return 1;
|
||||
end else if (funct3 == 3'b000 && system_imm != 12'h001) begin
|
||||
// raise is_seen if ecall/mret/dret is detected,
|
||||
// we exclude them for now (this leads to nested traps).
|
||||
|
@ -655,12 +655,19 @@ class core_ibex_interrupt_instr_test extends core_ibex_directed_test;
|
|||
vseq.irq_raise_single_seq_h.max_delay = 0;
|
||||
vseq.irq_raise_single_seq_h.max_interval = 0;
|
||||
forever begin
|
||||
// hold until we see a valid instruction in the ID stage of the pipeline.
|
||||
wait (instr_vif.instr_cb.valid_id && !(instr_vif.instr_cb.err_id || dut_vif.illegal_instr));
|
||||
// hold until we see a valid instruction in the ID stage of the pipeline or the core goes to
|
||||
// sleep
|
||||
wait ((instr_vif.instr_cb.valid_id && !(instr_vif.instr_cb.err_id || dut_vif.illegal_instr))
|
||||
|| dut_vif.core_sleep);
|
||||
|
||||
// We don't want to send fast interrupts, as due to the random setup of MIE,
|
||||
// there's no guarantee that the interrupt will actually be taken.
|
||||
if (instr_vif.instr_cb.is_compressed_id) begin
|
||||
if (dut_vif.core_sleep) begin
|
||||
// Testbench waits for 50 clocks before calling check_stimulus. If a WFI is executed during
|
||||
// these 50 clocks the test would sleep forever, so if the core enters sleep send irq
|
||||
// stimulus to wake it up.
|
||||
send_irq_stimulus(.no_fast(1'b1));
|
||||
end else if (instr_vif.instr_cb.is_compressed_id) begin
|
||||
if (decode_compressed_instr(instr_vif.instr_cb.instr_compressed_id)) begin
|
||||
send_irq_stimulus(.no_fast(1'b1));
|
||||
end
|
||||
|
@ -826,12 +833,18 @@ class core_ibex_debug_instr_test extends core_ibex_directed_test;
|
|||
vseq.debug_seq_single_h.max_delay = 0;
|
||||
vseq.debug_seq_single_h.max_interval = 0;
|
||||
forever begin
|
||||
// hold until we see a valid instruction in the ID stage of the pipeline.
|
||||
wait (instr_vif.instr_cb.valid_id && !(instr_vif.instr_cb.err_id || dut_vif.illegal_instr));
|
||||
// hold until we see a valid instruction in the ID stage of the pipeline or the core goes to
|
||||
// sleep
|
||||
wait ((instr_vif.instr_cb.valid_id && !(instr_vif.instr_cb.err_id || dut_vif.illegal_instr)) || dut_vif.core_sleep);
|
||||
|
||||
// We don't want to send fast interrupts, as due to the random setup of MIE,
|
||||
// there's no guarantee that the interrupt will actually be taken.
|
||||
if (instr_vif.instr_cb.is_compressed_id) begin
|
||||
if (dut_vif.core_sleep) begin
|
||||
// Testbench waits for 50 clocks before calling check_stimulus. If a WFI is executed during
|
||||
// these 50 clocks the test would sleep forever, so if the core enters sleep send debug
|
||||
// stimulus to wake it up.
|
||||
send_debug_stimulus(init_operating_mode,
|
||||
$sformatf("Did not jump into debug mode after instruction[0x%0x]",
|
||||
instr_vif.instr_cb.instr_compressed_id));
|
||||
end else if (instr_vif.instr_cb.is_compressed_id) begin
|
||||
if (decode_compressed_instr(instr_vif.instr_cb.instr_compressed_id)) begin
|
||||
send_debug_stimulus(init_operating_mode,
|
||||
$sformatf("Did not jump into debug mode after instruction[0x%0x]",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue