mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 12:57:13 -04:00
Commenting UVM testbench code, tidy formatting, minor refactoring
- Adds comments for quicker explanation of test and library functionality - Refactor types and naming of control knob signals for clarity - Move constraints from MEMBER to CLASS for more flexibility - Add missing license header Signed-off-by: Harry Callahan <hcallahan@lowrisc.org>
This commit is contained in:
parent
3459d7f8df
commit
806989a745
7 changed files with 168 additions and 117 deletions
|
@ -6,7 +6,7 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
|
|||
|
||||
// The virtual interface used to drive and view HDL signals.
|
||||
protected virtual irq_if vif;
|
||||
`uvm_component_utils(irq_request_driver)
|
||||
`uvm_component_utils(irq_request_driver)
|
||||
`uvm_component_new
|
||||
|
||||
function void build_phase(uvm_phase phase);
|
||||
|
@ -21,6 +21,8 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
|
|||
wait (vif.driver_cb.reset === 1'b0);
|
||||
forever begin
|
||||
fork : drive_irq
|
||||
// Setup a single get_REQ -> drive -> send_RSP long-running task.
|
||||
// This seq_item contains all signals on the interface at once.
|
||||
get_and_drive();
|
||||
wait (vif.driver_cb.reset === 1'b1);
|
||||
join_any
|
||||
|
@ -42,6 +44,8 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
|
|||
reset_signals();
|
||||
endtask
|
||||
|
||||
// Every cycle, check for a new REQ and drive it.
|
||||
// Simultaneously, return the same REQ as a RSP back to the sequence.
|
||||
virtual protected task get_and_drive();
|
||||
forever begin
|
||||
seq_item_port.try_next_item(req);
|
||||
|
|
2
dv/uvm/core_ibex/env/core_ibex_vseqr.sv
vendored
2
dv/uvm/core_ibex/env/core_ibex_vseqr.sv
vendored
|
@ -9,7 +9,7 @@ class core_ibex_vseqr extends uvm_sequencer;
|
|||
|
||||
ibex_mem_intf_response_sequencer data_if_seqr;
|
||||
ibex_mem_intf_response_sequencer instr_if_seqr;
|
||||
irq_request_sequencer irq_seqr;
|
||||
irq_request_sequencer irq_seqr;
|
||||
|
||||
`uvm_component_utils(core_ibex_vseqr)
|
||||
`uvm_component_new
|
||||
|
|
|
@ -210,11 +210,16 @@ class core_ibex_base_test extends uvm_test;
|
|||
virtual task wait_for_mem_txn(input bit[ibex_mem_intf_agent_pkg::ADDR_WIDTH-1:0] ref_addr,
|
||||
input signature_type_t ref_type);
|
||||
ibex_mem_intf_seq_item mem_txn;
|
||||
`uvm_info(`gfn, $sformatf("Awaiting riscv-dv handshake at 0x%0h, Type : %0s",
|
||||
ref_addr, ref_type), UVM_HIGH)
|
||||
forever begin
|
||||
// The first write to this address is guaranteed to contain the signature type in bits [7:0]
|
||||
item_collected_port.get(mem_txn);
|
||||
if (mem_txn.addr == ref_addr && mem_txn.data[7:0] === ref_type &&
|
||||
if (mem_txn.addr == ref_addr &&
|
||||
mem_txn.data[7:0] === ref_type &&
|
||||
mem_txn.read_write == WRITE) begin
|
||||
`uvm_info(`gfn, $sformatf("riscv-dv handshake received at 0x%0h, Type : %0s",
|
||||
ref_addr, ref_type), UVM_HIGH)
|
||||
signature_data = mem_txn.data;
|
||||
case (ref_type)
|
||||
// The very first write to the signature address in every test is guaranteed to be a write
|
||||
|
|
|
@ -1,72 +1,87 @@
|
|||
typedef enum bit [1:0] {
|
||||
SingleRun, // Singl iteration
|
||||
InfiniteRuns, // Run forever until stop is specified
|
||||
MultipleRuns, // Multiple runs with configurable or randomizable iteration count
|
||||
InvalidRuns // Default state
|
||||
} run_type_e;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
IsideErr, // Inject error in instruction side memory.
|
||||
DsideErr, // Inject error in data side memory.
|
||||
PickErr // Pick which memory to inject error in.
|
||||
} error_type_e;
|
||||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
class core_base_new_seq #(type REQ = uvm_sequence_item) extends uvm_sequence #(REQ);
|
||||
// Default set to 50% for zero delay to be picked. Set to 100 if zero delay is required always.
|
||||
int unsigned zero_delay_pct = 50;
|
||||
rand bit zero_delays;
|
||||
rand int delay = 0;
|
||||
int unsigned iteration_cnt = 0;
|
||||
int unsigned max_delay = 500;
|
||||
virtual clk_rst_if clk_vif;
|
||||
|
||||
// Virtual interfaces for driving stimulus directly
|
||||
virtual clk_rst_if clk_vif;
|
||||
virtual core_ibex_dut_probe_if dut_vif;
|
||||
|
||||
bit stop_seq;
|
||||
bit seq_finished;
|
||||
rand run_type_e num_of_iterations = InvalidRuns;
|
||||
virtual core_ibex_dut_probe_if dut_vif;
|
||||
// Use this bit to start any unique sequence once
|
||||
bit start_seq = 0;
|
||||
|
||||
rand bit zero_delays;
|
||||
// CONTROL_KNOB: Randomly override the delay between stimulus items to be zero
|
||||
// Default set to 50% for zero delay to be picked. Set to 100 if zero delay is required always.
|
||||
int unsigned zero_delay_pct = 50;
|
||||
constraint zero_delays_c {
|
||||
zero_delays dist {1 :/ zero_delay_pct,
|
||||
0 :/ 100 - zero_delay_pct};
|
||||
}
|
||||
|
||||
rand int unsigned stimulus_delay_cycles;
|
||||
// CONTROL_KNOB: Delay the start of each stimulus a randomized amount (transaction to transaction delay)
|
||||
// Can be randomly overwritten to no delay at all with 'zero_delays'
|
||||
int unsigned stimulus_delay_cycles_min = 200;
|
||||
int unsigned stimulus_delay_cycles_max = 400;
|
||||
constraint reasonable_delay_c {
|
||||
stimulus_delay_cycles inside {[stimulus_delay_cycles_min : stimulus_delay_cycles_max]};
|
||||
}
|
||||
|
||||
// CONTROL_KNOB: Set this per-instance to make the stimulus generation repeat : {Once, Multiple, Forever}
|
||||
run_type_e iteration_modes = MultipleRuns;
|
||||
|
||||
rand int unsigned iteration_cnt;
|
||||
// CONTROL_KNOB: This controls the number of stimulus items generated in a loop for {Multiple} cfg
|
||||
int unsigned iteration_cnt_max = 20;
|
||||
constraint iterations_cnt_c {
|
||||
iteration_cnt inside {[1:iteration_cnt_max]};
|
||||
}
|
||||
|
||||
`uvm_object_param_utils(core_base_new_seq#(REQ))
|
||||
|
||||
function new (string name = "");
|
||||
super.new(name);
|
||||
if(!uvm_config_db#(virtual clk_rst_if)::get(null, "", "clk_if", clk_vif)) begin
|
||||
`uvm_fatal(get_full_name(), "Cannot get clk_if")
|
||||
`uvm_fatal(`gfn, "Cannot get clk_if")
|
||||
end
|
||||
if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if", dut_vif)) begin
|
||||
`uvm_fatal(get_full_name(), "Cannot get dut_if")
|
||||
`uvm_fatal(`gfn, "Cannot get dut_if")
|
||||
end
|
||||
endfunction
|
||||
|
||||
constraint zero_delays_c {
|
||||
zero_delays dist {1 :/ zero_delay_pct,
|
||||
0 :/ 100 - zero_delay_pct};
|
||||
}
|
||||
constraint reasonable_delay_c {
|
||||
delay inside {[0 : max_delay]};
|
||||
}
|
||||
virtual task pre_body();
|
||||
// Randomize once before starting to ensure all unininitialized rand variables have a valid starting value
|
||||
this.randomize();
|
||||
endtask: pre_body
|
||||
|
||||
virtual task body();
|
||||
if(num_of_iterations == InvalidRuns) begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(num_of_iterations, num_of_iterations != InvalidRuns;)
|
||||
end
|
||||
`uvm_info(`gfn, $sformatf("Doing %s", num_of_iterations.name()), UVM_LOW)
|
||||
case (num_of_iterations)
|
||||
// core_base_new_seq::body() provides a flexible sequence scheduler, where
|
||||
// 'iteration_modes' allows different tests to change the frequency
|
||||
// stimulus is generated.
|
||||
|
||||
`uvm_info(`gfn, $sformatf("Running the \"%s\" schedule for stimulus generation",
|
||||
iteration_modes.name()), UVM_LOW)
|
||||
case (iteration_modes)
|
||||
SingleRun: begin
|
||||
drive_stimulus(delay);
|
||||
drive_stimulus();
|
||||
end
|
||||
MultipleRuns: begin
|
||||
// Randomize iteration_cnt if not specified externally by test
|
||||
if(iteration_cnt == 0) begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(iteration_cnt,
|
||||
iteration_cnt > 0 && iteration_cnt <= 20; )
|
||||
// with {"CONSTRAINTS"}
|
||||
iteration_cnt > 0;)
|
||||
end
|
||||
`uvm_info(`gfn, $sformatf("Number of stimulus iterations = %0d", iteration_cnt), UVM_LOW)
|
||||
for (int i = 0; i <= iteration_cnt; i++) begin
|
||||
drive_stimulus(delay);
|
||||
drive_stimulus();
|
||||
end
|
||||
end
|
||||
InfiniteRuns: begin
|
||||
while (!stop_seq) begin
|
||||
drive_stimulus(delay);
|
||||
drive_stimulus();
|
||||
end
|
||||
seq_finished = 1'b1;
|
||||
end
|
||||
|
@ -76,28 +91,30 @@ class core_base_new_seq #(type REQ = uvm_sequence_item) extends uvm_sequence #(R
|
|||
endcase
|
||||
endtask: body
|
||||
|
||||
task drive_stimulus(int unsigned delay);
|
||||
if(delay == 0) begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(zero_delays)
|
||||
if(zero_delays) begin
|
||||
delay = 0;
|
||||
end else begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
|
||||
end
|
||||
task drive_stimulus();
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(zero_delays)
|
||||
if(!zero_delays) begin
|
||||
// Delay for a randomized amount of cycles
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(stimulus_delay_cycles)
|
||||
`uvm_info(`gfn, $sformatf("stimulus_delay_cycles = %0d", stimulus_delay_cycles), UVM_HIGH)
|
||||
clk_vif.wait_clks(stimulus_delay_cycles);
|
||||
end
|
||||
clk_vif.wait_clks(delay);
|
||||
`uvm_info(get_full_name(), "Starting sequence...", UVM_MEDIUM)
|
||||
send_req();
|
||||
`uvm_info(get_full_name(), "Exiting sequence", UVM_MEDIUM)
|
||||
endtask: drive_stimulus
|
||||
|
||||
// Generate the stimulus with a sequence-specific request
|
||||
// Seqs can each implement send_req() differently, such as sending a seq_item,
|
||||
// or driving the interface directly.
|
||||
virtual task send_req();
|
||||
`uvm_fatal(get_full_name(), "This task must be implemented in the extended class")
|
||||
endtask
|
||||
|
||||
// Can be called by the sequencer to break out of infinite-loops in body()
|
||||
virtual task stop();
|
||||
stop_seq = 1'b1;
|
||||
`uvm_info(get_full_name(), "Stopping sequence", UVM_MEDIUM)
|
||||
`uvm_info(`gfn, "Stopping sequence", UVM_MEDIUM)
|
||||
wait (seq_finished == 1'b1);
|
||||
endtask
|
||||
|
||||
|
@ -108,13 +125,16 @@ class irq_new_seq extends core_base_new_seq #(irq_seq_item);
|
|||
`uvm_object_utils(irq_new_seq)
|
||||
`uvm_object_new
|
||||
|
||||
// Set these 'no_*' bits at the test-level to disable the randomizer from
|
||||
// generating each particular type of irq.
|
||||
bit no_nmi;
|
||||
bit no_fast;
|
||||
bit no_external;
|
||||
bit no_timer;
|
||||
bit no_software;
|
||||
int max_delay = 500;
|
||||
int min_delay = 50;
|
||||
|
||||
int unsigned max_delay = 500;
|
||||
int unsigned min_delay = 50;
|
||||
|
||||
rand int interval = min_delay;
|
||||
|
||||
|
@ -125,29 +145,25 @@ class irq_new_seq extends core_base_new_seq #(irq_seq_item);
|
|||
virtual task send_req();
|
||||
irq_seq_item irq;
|
||||
irq = irq_seq_item::type_id::create("irq");
|
||||
// Raise interrupts
|
||||
|
||||
// Raise randomized num of interrupts
|
||||
start_item(irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt > 1;
|
||||
if (no_nmi) {
|
||||
irq_nm == 0;
|
||||
}
|
||||
if (no_fast) {
|
||||
irq_fast == '0;
|
||||
}
|
||||
if (no_external) {
|
||||
irq_external == 0;
|
||||
}
|
||||
if (no_timer) {
|
||||
irq_timer == 0;
|
||||
}
|
||||
if (no_software) {
|
||||
irq_software == 0;
|
||||
})
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq,
|
||||
// with {"CONSTRAINTS"}
|
||||
num_of_interrupt inside {[1:5]};
|
||||
no_nmi -> irq_nm == 0;
|
||||
no_fast -> irq_fast == '0;
|
||||
no_external -> irq_external == 0;
|
||||
no_timer -> irq_timer == 0;
|
||||
no_software -> irq_software == 0;)
|
||||
finish_item(irq);
|
||||
get_response(irq);
|
||||
|
||||
// Delay a randomized amount while interrupts are active
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(interval)
|
||||
clk_vif.wait_clks(interval);
|
||||
// Drop interrupts
|
||||
|
||||
// Drop all interrupts
|
||||
start_item(irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt == 0;)
|
||||
finish_item(irq);
|
||||
|
@ -163,23 +179,24 @@ class debug_new_seq extends core_base_new_seq#(irq_seq_item);
|
|||
`uvm_object_utils(debug_new_seq)
|
||||
`uvm_object_new
|
||||
|
||||
int max_delay = 500;
|
||||
int min_delay = 75;
|
||||
rand int unsigned drop_delay = 0;
|
||||
rand int unsigned pulse_length_cycles;
|
||||
int unsigned pulse_length_cycles_min = 75;
|
||||
int unsigned pulse_length_cycles_max = 500;
|
||||
|
||||
constraint reasonable_pulse_length_c {
|
||||
pulse_length_cycles inside {[pulse_length_cycles_min : pulse_length_cycles_max]};
|
||||
}
|
||||
|
||||
virtual task body();
|
||||
dut_vif.dut_cb.debug_req <= 1'b0;
|
||||
if(drop_delay == 0) begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(drop_delay,
|
||||
drop_delay inside {[min_delay : max_delay]};)
|
||||
end
|
||||
super.body();
|
||||
endtask
|
||||
endtask: body
|
||||
|
||||
virtual task send_req();
|
||||
`uvm_info(get_full_name(), "Sending debug request", UVM_HIGH)
|
||||
`uvm_info(`gfn, "Sending debug request", UVM_HIGH)
|
||||
dut_vif.dut_cb.debug_req <= 1'b1;
|
||||
clk_vif.wait_clks(drop_delay);
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(pulse_length_cycles);
|
||||
clk_vif.wait_clks(pulse_length_cycles);
|
||||
dut_vif.dut_cb.debug_req <= 1'b0;
|
||||
endtask
|
||||
|
||||
|
@ -187,8 +204,10 @@ endclass
|
|||
|
||||
class memory_error_seq extends core_base_new_seq#(irq_seq_item);
|
||||
core_ibex_vseq vseq;
|
||||
rand error_type_e err_type = PickErr;
|
||||
rand bit choose_side;
|
||||
bit start_seq = 0; // Use this bit to start any unique sequence once
|
||||
|
||||
rand error_type_e err_type = PickErr;
|
||||
|
||||
`uvm_object_utils(memory_error_seq)
|
||||
`uvm_declare_p_sequencer(core_ibex_vseqr)
|
||||
|
@ -233,26 +252,28 @@ class fetch_enable_seq extends core_base_new_seq#(irq_seq_item);
|
|||
|
||||
ibex_pkg::fetch_enable_t fetch_enable;
|
||||
int unsigned on_bias_pc = 50;
|
||||
int max_delay = 500;
|
||||
int min_delay = 75;
|
||||
int unsigned max_delay = 500;
|
||||
int unsigned min_delay = 75;
|
||||
rand int unsigned off_delay = 0;
|
||||
|
||||
virtual task body();
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOn;
|
||||
if(off_delay == 0) begin
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(off_delay,
|
||||
off_delay inside {[min_delay : max_delay]};)
|
||||
// with {"CONSTRAINTS"}
|
||||
off_delay inside {[min_delay : max_delay]};)
|
||||
end
|
||||
super.body();
|
||||
endtask
|
||||
endtask: body
|
||||
|
||||
virtual task send_req();
|
||||
`uvm_info(get_full_name(), "Sending fetch enable request", UVM_LOW)
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(fetch_enable,
|
||||
fetch_enable dist {ibex_pkg::FetchEnableOn :/ on_bias_pc,
|
||||
[0:15] :/ 100 - on_bias_pc};
|
||||
)
|
||||
// with {"CONSTRAINTS"}
|
||||
fetch_enable dist {ibex_pkg::FetchEnableOn :/ on_bias_pc,
|
||||
[0:15] :/ 100 - on_bias_pc};)
|
||||
`uvm_info(`gfn, "Sending fetch enable request", UVM_LOW)
|
||||
`uvm_info(`gfn, $sformatf("fetch_enable = %d", fetch_enable), UVM_LOW)
|
||||
|
||||
dut_vif.dut_cb.fetch_enable <= fetch_enable;
|
||||
clk_vif.wait_clks(off_delay);
|
||||
dut_vif.dut_cb.fetch_enable <= ibex_pkg::FetchEnableOn;
|
||||
|
|
|
@ -36,6 +36,10 @@ class core_base_seq #(type REQ = uvm_sequence_item) extends uvm_sequence#(REQ);
|
|||
end
|
||||
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
|
||||
clk_vif.wait_clks(delay);
|
||||
|
||||
// Loop around until 'stop_seq' is set to 1 externally, or "num_of_iterations" times,
|
||||
// whichever is longer.
|
||||
// Send a request() each time with a randomized interval between items.
|
||||
`uvm_info(get_full_name(), "Starting sequence...", UVM_LOW)
|
||||
if (!is_started) is_started = 1'b1;
|
||||
while (!stop_seq) begin
|
||||
|
@ -98,17 +102,16 @@ class irq_raise_seq extends irq_base_seq;
|
|||
bit no_fast;
|
||||
|
||||
virtual function void randomize_item(irq_seq_item irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt > 1;
|
||||
if (no_nmi) {
|
||||
irq_nm == 0;
|
||||
}
|
||||
if (no_fast) {
|
||||
irq_fast == '0;
|
||||
})
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq,
|
||||
// with {"CONSTRAINTS"}
|
||||
num_of_interrupt > 1;
|
||||
no_nmi -> irq_nm == 0;
|
||||
no_fast -> irq_fast == '0;)
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
// Irq sequence that raises a single interrupt input signal
|
||||
class irq_raise_single_seq extends irq_base_seq;
|
||||
|
||||
`uvm_object_utils(irq_raise_single_seq)
|
||||
|
@ -118,25 +121,26 @@ class irq_raise_single_seq extends irq_base_seq;
|
|||
bit no_fast;
|
||||
|
||||
virtual function void randomize_item(irq_seq_item irq);
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq, num_of_interrupt == 1;
|
||||
if (no_nmi) {
|
||||
irq_nm == 0;
|
||||
}
|
||||
if (no_fast) {
|
||||
irq_fast == '0;
|
||||
})
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq,
|
||||
// with {"CONSTRAINTS"}
|
||||
num_of_interrupt == 1;
|
||||
no_nmi -> irq_nm == 0;
|
||||
no_fast -> irq_fast == '0;)
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
||||
// Irq sequence that ONLY raises the nmi signal
|
||||
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;)
|
||||
`DV_CHECK_RANDOMIZE_WITH_FATAL(irq,
|
||||
// with {"CONSTRAINTS"}
|
||||
num_of_interrupt == 1;
|
||||
irq_nm == 1;)
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
|
@ -25,6 +25,19 @@ package core_ibex_test_pkg;
|
|||
|
||||
typedef class core_ibex_vseq;
|
||||
|
||||
// For new_seq_lib...
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
SingleRun, // Single iteration
|
||||
InfiniteRuns, // Run forever until stop is specified
|
||||
MultipleRuns // Multiple runs with configurable or randomizable iteration count
|
||||
} run_type_e;
|
||||
typedef enum bit [1:0] {
|
||||
IsideErr, // Inject error in instruction side memory.
|
||||
DsideErr, // Inject error in data side memory.
|
||||
PickErr // Pick which memory to inject error in.
|
||||
} error_type_e;
|
||||
|
||||
`include "core_ibex_report_server.sv"
|
||||
`include "core_ibex_seq_lib.sv"
|
||||
`include "core_ibex_new_seq_lib.sv"
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
class core_ibex_vseq extends uvm_sequence;
|
||||
|
||||
ibex_mem_intf_response_seq instr_intf_seq;
|
||||
ibex_mem_intf_response_seq data_intf_seq;
|
||||
ibex_mem_intf_response_seq instr_intf_seq;
|
||||
ibex_mem_intf_response_seq data_intf_seq;
|
||||
mem_model_pkg::mem_model mem;
|
||||
irq_raise_seq irq_raise_seq_h;
|
||||
irq_raise_single_seq irq_raise_single_seq_h;
|
||||
|
@ -30,6 +30,16 @@ class core_ibex_vseq extends uvm_sequence;
|
|||
data_intf_seq.is_dmem_seq = 1'b1;
|
||||
endfunction
|
||||
|
||||
// Start the memory-model sequences, which run forever() loops to respond to bus events
|
||||
virtual task pre_body();
|
||||
instr_intf_seq.m_mem = mem;
|
||||
data_intf_seq.m_mem = mem;
|
||||
fork
|
||||
instr_intf_seq.start(p_sequencer.instr_if_seqr);
|
||||
data_intf_seq.start(p_sequencer.data_if_seqr);
|
||||
join_none
|
||||
endtask // pre_body
|
||||
|
||||
virtual task body();
|
||||
if (cfg.enable_irq_single_seq) begin
|
||||
irq_raise_single_seq_h = irq_raise_single_seq::type_id::create("irq_single_seq_h");
|
||||
|
@ -70,12 +80,6 @@ class core_ibex_vseq extends uvm_sequence;
|
|||
debug_seq_single_h.interval.rand_mode(0);
|
||||
debug_seq_single_h.interval = 0;
|
||||
end
|
||||
instr_intf_seq.m_mem = mem;
|
||||
data_intf_seq.m_mem = mem;
|
||||
fork
|
||||
instr_intf_seq.start(p_sequencer.instr_if_seqr);
|
||||
data_intf_seq.start(p_sequencer.data_if_seqr);
|
||||
join_none
|
||||
endtask
|
||||
|
||||
virtual task stop();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue