diff --git a/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv b/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv index 4152230d..60bd0104 100644 --- a/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv +++ b/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv @@ -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)); diff --git a/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv b/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv index dd6d0fc7..adc72bda 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv @@ -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; diff --git a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv index 2e4376e0..a84ca56e 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv @@ -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 diff --git a/dv/uvm/core_ibex/tests/core_ibex_vseq.sv b/dv/uvm/core_ibex/tests/core_ibex_vseq.sv index aaaac706..5522b7c6 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_vseq.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_vseq.sv @@ -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