mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
[dv] Allow full IRQ randomisation
`no_nmi` in irq_raise_seq and irq_raise_single_seq would always cause an NMI to be raised if it was set. This alters it to have the same behaviour as `no_fast`. Setting `no_nmi` prevents an NMI from being produced by the sequences, leaving it clears allows an NMI to be produced but doesn't force it. This allows tests which can deal with NMI along with other IRQs to fully randomise IRQs. A new `irq_raise_nmi_seq` is provided for tests that specifically want an NMI.
This commit is contained in:
parent
5711d4fc15
commit
f0a4042d6a
4 changed files with 52 additions and 4 deletions
3
dv/uvm/core_ibex/env/core_ibex_env_cfg.sv
vendored
3
dv/uvm/core_ibex/env/core_ibex_env_cfg.sv
vendored
|
@ -6,6 +6,7 @@ class core_ibex_env_cfg extends uvm_object;
|
|||
|
||||
bit enable_irq_single_seq;
|
||||
bit enable_irq_multiple_seq;
|
||||
bit enable_irq_nmi_seq;
|
||||
bit enable_nested_irq;
|
||||
bit enable_debug_seq;
|
||||
bit[31:0] max_interval;
|
||||
|
@ -16,6 +17,7 @@ class core_ibex_env_cfg extends uvm_object;
|
|||
`uvm_object_utils_begin(core_ibex_env_cfg)
|
||||
`uvm_field_int(enable_irq_single_seq, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_irq_multiple_seq, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_irq_nmi_seq, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_nested_irq, UVM_DEFAULT)
|
||||
`uvm_field_int(enable_debug_seq, UVM_DEFAULT)
|
||||
`uvm_field_int(max_interval, UVM_DEFAULT)
|
||||
|
@ -27,6 +29,7 @@ class core_ibex_env_cfg extends uvm_object;
|
|||
super.new(name);
|
||||
void'($value$plusargs("enable_irq_single_seq=%0d", enable_irq_single_seq));
|
||||
void'($value$plusargs("enable_irq_multiple_seq=%0d", enable_irq_multiple_seq));
|
||||
void'($value$plusargs("enable_irq_nmi_seq=%0d", enable_irq_nmi_seq));
|
||||
void'($value$plusargs("enable_nested_irq=%0d", enable_nested_irq));
|
||||
void'($value$plusargs("enable_debug_seq=%0d", enable_debug_seq));
|
||||
void'($value$plusargs("max_interval=%0d", max_interval));
|
||||
|
|
|
@ -99,7 +99,9 @@ class irq_raise_seq extends irq_base_seq;
|
|||
|
||||
virtual function void randomize_item(irq_seq_item irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt > 1;
|
||||
irq_nm == ~no_nmi;
|
||||
if (no_nmi) {
|
||||
irq_nm == 0;
|
||||
}
|
||||
if (no_fast) {
|
||||
irq_fast == '0;
|
||||
})
|
||||
|
@ -117,7 +119,9 @@ class irq_raise_single_seq extends irq_base_seq;
|
|||
|
||||
virtual function void randomize_item(irq_seq_item irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt == 1;
|
||||
irq_nm == ~no_nmi;
|
||||
if (no_nmi) {
|
||||
irq_nm == 0;
|
||||
}
|
||||
if (no_fast) {
|
||||
irq_fast == '0;
|
||||
})
|
||||
|
@ -125,6 +129,18 @@ class irq_raise_single_seq extends irq_base_seq;
|
|||
|
||||
endclass
|
||||
|
||||
class irq_raise_nmi_seq extends irq_base_seq;
|
||||
|
||||
`uvm_object_utils(irq_raise_nmi_seq)
|
||||
`uvm_object_new
|
||||
|
||||
virtual function void randomize_item(irq_seq_item irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt == 1;
|
||||
irq_nm == 1;)
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
// Irq sequence to deassert all interrupt lines, since Ibex interrupts are level sensitive
|
||||
class irq_drop_seq extends irq_base_seq;
|
||||
|
||||
|
|
|
@ -211,10 +211,20 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test;
|
|||
virtual task send_irq_stimulus_start(input bit no_nmi,
|
||||
input bit no_fast,
|
||||
output bit ret_val);
|
||||
bit irq_valid;
|
||||
// send the interrupt
|
||||
if (cfg.enable_irq_single_seq) vseq.start_irq_raise_single_seq(no_nmi, no_fast);
|
||||
else if (cfg.enable_irq_multiple_seq) vseq.start_irq_raise_seq(no_nmi, no_fast);
|
||||
|
||||
send_irq_stimulus_inner(ret_val);
|
||||
endtask
|
||||
|
||||
virtual task send_nmi_stimulus_start(output bit ret_val);
|
||||
vseq.start_nmi_raise_seq();
|
||||
send_irq_stimulus_inner(ret_val);
|
||||
endtask
|
||||
|
||||
virtual task send_irq_stimulus_inner(output bit ret_val);
|
||||
bit irq_valid;
|
||||
irq_collected_port.get(irq_txn);
|
||||
// Get the bit position of the highest priority interrupt - ibex will only handle this one if
|
||||
// there are multiple irqs asserted at once.
|
||||
|
@ -289,6 +299,12 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test;
|
|||
if (ret_val) send_irq_stimulus_end();
|
||||
endtask
|
||||
|
||||
virtual task send_nmi_stimulus();
|
||||
bit ret_val;
|
||||
send_nmi_stimulus_start(ret_val);
|
||||
if (ret_val) send_irq_stimulus_end();
|
||||
endtask
|
||||
|
||||
function int get_max_valid_irq_id(bit [irq_agent_pkg::DATA_WIDTH-1:0] irq);
|
||||
int i;
|
||||
// Ibex implementation of MIE does not mask NM interrupts, so need to check this separately
|
||||
|
|
|
@ -13,6 +13,7 @@ class core_ibex_vseq extends uvm_sequence;
|
|||
mem_model_pkg::mem_model mem;
|
||||
irq_raise_seq irq_raise_seq_h;
|
||||
irq_raise_single_seq irq_raise_single_seq_h;
|
||||
irq_raise_nmi_seq irq_raise_nmi_seq_h;
|
||||
irq_drop_seq irq_drop_seq_h;
|
||||
debug_seq debug_seq_stress_h;
|
||||
debug_seq debug_seq_single_h;
|
||||
|
@ -41,7 +42,14 @@ class core_ibex_vseq extends uvm_sequence;
|
|||
irq_raise_seq_h.max_delay = 500;
|
||||
irq_raise_seq_h.interval = 0;
|
||||
end
|
||||
if (cfg.enable_irq_single_seq || cfg.enable_irq_multiple_seq) begin
|
||||
if (cfg.enable_irq_nmi_seq) begin
|
||||
irq_raise_nmi_seq_h = irq_raise_nmi_seq::type_id::create("irq_raise_nmi_seq_h");
|
||||
irq_raise_nmi_seq_h.num_of_iterations = 1;
|
||||
irq_raise_nmi_seq_h.max_interval = 1;
|
||||
irq_raise_nmi_seq_h.max_delay = 500;
|
||||
irq_raise_nmi_seq_h.interval = 0;
|
||||
end
|
||||
if (cfg.enable_irq_single_seq || cfg.enable_irq_multiple_seq || cfg.enable_irq_nmi_seq) begin
|
||||
irq_drop_seq_h = irq_drop_seq::type_id::create("irq_drop_seq_h");
|
||||
irq_drop_seq_h.num_of_iterations = 1;
|
||||
irq_drop_seq_h.max_interval = 1;
|
||||
|
@ -105,8 +113,13 @@ class core_ibex_vseq extends uvm_sequence;
|
|||
irq_raise_seq_h.start(p_sequencer.irq_seqr);
|
||||
endtask
|
||||
|
||||
virtual task start_nmi_raise_seq();
|
||||
irq_raise_nmi_seq_h.start(p_sequencer.irq_seqr);
|
||||
endtask
|
||||
|
||||
virtual task start_irq_drop_seq();
|
||||
irq_drop_seq_h.start(p_sequencer.irq_seqr);
|
||||
endtask
|
||||
|
||||
|
||||
endclass
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue