[pattgen, dv] Add pattgen_stress_all test
Signed-off-by: Tung Hoang <hoang.tung@wdc.com>
diff --git a/hw/dv/sv/pattgen_agent/pattgen_monitor.sv b/hw/dv/sv/pattgen_agent/pattgen_monitor.sv
index f1e3547..05c1066 100644
--- a/hw/dv/sv/pattgen_agent/pattgen_monitor.sv
+++ b/hw/dv/sv/pattgen_agent/pattgen_monitor.sv
@@ -43,6 +43,7 @@
pattgen_item dut_item;
forever begin
+ wait(cfg.en_monitor);
dut_item = pattgen_item::type_id::create("dut_item");
bit_cnt = 0;
fork
@@ -51,7 +52,7 @@
// capture pattern bits
begin
do begin
- wait(cfg.en_monitor);
+ wait(cfg.vif.rst_ni);
get_pattgen_bit(channel, bit_data);
`uvm_info(`gfn, $sformatf("\n--> monitor: channel %0d, polar %b, data[%0d] %b",
channel, cfg.polarity[channel], bit_cnt, bit_data), UVM_DEBUG)
@@ -82,6 +83,10 @@
@(negedge cfg.vif.rst_ni);
reset_asserted = 1'b1;
// implement other clean-up actions under reset here
+ for (uint i = 0; i < NUM_PATTGEN_CHANNELS; i++) begin
+ cfg.error_injected[i]= 1'b0;
+ cfg.length[i] = 0;
+ end
@(posedge cfg.vif.rst_ni);
reset_asserted = 1'b0;
end
diff --git a/hw/ip/pattgen/dv/env/pattgen_channel_cfg.sv b/hw/ip/pattgen/dv/env/pattgen_channel_cfg.sv
index 5051df5..579aba3 100644
--- a/hw/ip/pattgen/dv/env/pattgen_channel_cfg.sv
+++ b/hw/ip/pattgen/dv/env/pattgen_channel_cfg.sv
@@ -16,14 +16,19 @@
rand bit [5:0] len;
rand bit [9:0] reps;
- // functions
- virtual function void reset_channel_config();
+ virtual function void reset_channel_config(string kind = "");
start = 1'b0;
stop = 1'b0;
enable = 1'b0;
+ if (kind == "HARD") begin
+ polarity = 1'b0;
+ len = 0;
+ reps = 0;
+ prediv = 0;
+ data = 0;
+ end
endfunction : reset_channel_config
- // this function print channel configuration for debug
virtual function string convert2string();
string str;
@@ -40,4 +45,4 @@
return str;
endfunction : convert2string
-endclass : pattgen_channel_cfg
\ No newline at end of file
+endclass : pattgen_channel_cfg
diff --git a/hw/ip/pattgen/dv/env/pattgen_env.core b/hw/ip/pattgen/dv/env/pattgen_env.core
index c1734c3..c8d1529 100644
--- a/hw/ip/pattgen/dv/env/pattgen_env.core
+++ b/hw/ip/pattgen/dv/env/pattgen_env.core
@@ -26,6 +26,7 @@
- seq_lib/pattgen_smoke_vseq.sv: {is_include_file: true}
- seq_lib/pattgen_perf_vseq.sv: {is_include_file: true}
- seq_lib/pattgen_error_vseq.sv: {is_include_file: true}
+ - seq_lib/pattgen_stress_all_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
generate:
diff --git a/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv b/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
index e92b22f..2726bbc 100644
--- a/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
+++ b/hw/ip/pattgen/dv/env/pattgen_scoreboard.sv
@@ -110,8 +110,8 @@
// channel is operating but incorrectly disabled -> error injected
if (!channel_cfg[i].enable && channel_cfg[i].start && !channel_cfg[i].stop) begin
channel_cfg[i].stop = 1'b1;
- `uvm_info(`gfn, $sformatf("\n scb: channel %0d is abnormally stopped\n%s",
- i, channel_cfg[i].convert2string()), UVM_DEBUG);
+ `uvm_info(`gfn, $sformatf("\n scb: channel config %0d\n%s",
+ i, channel_cfg[i].convert2string()), UVM_DEBUG)
generate_exp_items(.channel(i), .error_injected(1'b1));
end
end
@@ -206,7 +206,7 @@
end else begin
`uvm_info(`gfn, $sformatf("\n--> scb: drop exp_item for channel %0d", channel), UVM_DEBUG)
end
- channel_cfg[channel].reset_channel_config;
+ channel_cfg[channel].reset_channel_config();
end
endfunction : generate_exp_items
@@ -215,7 +215,7 @@
for (uint i = 0; i < NUM_PATTGEN_CHANNELS; i++) begin
item_fifo[i].flush();
exp_item_q[i].delete();
- channel_cfg[i].reset_channel_config();
+ channel_cfg[i].reset_channel_config(kind);
end
endfunction : reset
diff --git a/hw/ip/pattgen/dv/env/seq_lib/pattgen_base_vseq.sv b/hw/ip/pattgen/dv/env/seq_lib/pattgen_base_vseq.sv
index 602a79e..734407d 100644
--- a/hw/ip/pattgen/dv/env/seq_lib/pattgen_base_vseq.sv
+++ b/hw/ip/pattgen/dv/env/seq_lib/pattgen_base_vseq.sv
@@ -31,7 +31,6 @@
// if start_all_channels bit is set: both channels can start simmultaneously
rand bit start_all_channels;
rand bit do_error_injected;
- rand bit [NUM_PATTGEN_CHANNELS-1:0] reset_channels;
// constraints
constraint num_trans_c {
@@ -91,24 +90,38 @@
while (num_pattern_req < num_trans || // not send all pattern configs
num_pattern_gen < num_trans || // not get all pattern done interrupts
channel_start) begin // at least one channel is running
+ wait(cfg.clk_rst_vif.rst_n); // wait until reset is de-asserted
fork
- // all channels are completely independent (programm, start w/ or wo/ sync, and stop)
- setup_pattgen_channel_0();
- setup_pattgen_channel_1();
- start_pattgen_channels();
- stop_pattgen_channels();
+ begin : isolation_thread
+ fork
+ process_reset();
+ fork
+ // all channels are completely independent (programm, start w/ or wo/ sync, and stop)
+ setup_pattgen_channel_0();
+ setup_pattgen_channel_1();
+ start_pattgen_channels();
+ stop_pattgen_channels();
+ join
+ join_any
+ disable fork;
+ end : isolation_thread
join
end
- `uvm_info(`gfn, $sformatf("\n--> channel_setup %b", channel_setup), UVM_DEBUG)
- `uvm_info(`gfn, $sformatf("\n--> channel_start %b", channel_start), UVM_DEBUG)
`uvm_info(`gfn, "\n--> end of sequence", UVM_DEBUG)
endtask : body
- // TODO: can setup_pattgen_channel task be parameterized?
- // e.g. index the regster groups of channels before entering while-loop in body task
+ virtual task process_reset();
+ // when reset is asserted, all threads for channels are stopped
+ @(negedge cfg.clk_rst_vif.rst_n);
+ channel_setup = 'h0;
+ channel_start = 'h0;
+ channel_grant = 'h1;
+ `uvm_info(`gfn, "\n process_reset is called", UVM_DEBUG)
+ endtask : process_reset
+
virtual task setup_pattgen_channel_0();
if (num_pattern_req < num_trans &&
- channel_grant[0] && // ch0 setup is granted
+ channel_grant[0] && // ch0 setup is granted
!channel_setup[0] && // ch0 has not been programmed
!channel_start[1]) begin // ch1 is not under start (avoid re-programming regs)
wait_for_channel_ready(Channel0);
@@ -296,9 +309,9 @@
if (status == Enable) begin
num_pattern_req += 2;
`uvm_info(`gfn, $sformatf("\n sync channel 0: request %0d/%0d\n%s",
- num_pattern_req - 1, num_trans, channel_cfg[0].convert2string()), UVM_DEBUG);
+ num_pattern_req - 1, num_trans, channel_cfg[0].convert2string()), UVM_DEBUG)
`uvm_info(`gfn, $sformatf("\n sync channel 1: request %0d/%0d\n%s",
- num_pattern_req, num_trans, channel_cfg[1].convert2string()), UVM_DEBUG);
+ num_pattern_req, num_trans, channel_cfg[0].convert2string()), UVM_DEBUG)
end
end
endcase
@@ -373,7 +386,6 @@
x = {x[NUM_PATTGEN_CHANNELS-2:0], x[NUM_PATTGEN_CHANNELS-1]};
endfunction : right_rotation
- // TODO: this task is reserved for the next PR
task wait_host_for_idle();
csr_spinwait(.ptr(ral.ctrl.enable_ch0), .exp_data(1'b0));
csr_spinwait(.ptr(ral.ctrl.enable_ch1), .exp_data(1'b0));
diff --git a/hw/ip/pattgen/dv/env/seq_lib/pattgen_stress_all_vseq.sv b/hw/ip/pattgen/dv/env/seq_lib/pattgen_stress_all_vseq.sv
new file mode 100644
index 0000000..f3ecdd0
--- /dev/null
+++ b/hw/ip/pattgen/dv/env/seq_lib/pattgen_stress_all_vseq.sv
@@ -0,0 +1,95 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// combine all pattgen seqs (except below vseqs) in one seq to run sequentially
+// 1. override_vseq requires scb and monitor to be disabled
+// 1. csr seq, which requires scb to be disabled
+class pattgen_stress_all_vseq extends pattgen_base_vseq;
+ `uvm_object_utils(pattgen_stress_all_vseq)
+
+ `uvm_object_new
+
+ local string str, seq_name;
+ local int seq_run_hist[string];
+
+ string seq_names[] = {
+ "pattgen_common_vseq", // for intr_test
+ "pattgen_smoke_vseq",
+ "pattgen_perf_vseq",
+ "pattgen_error_vseq"
+ };
+
+ virtual task body();
+
+ `uvm_info(`gfn, "\n=> start pattgen_stress_all_vseq", UVM_LOW)
+ print_seq_names(seq_names);
+ for (int i = 1; i <= seq_names.size(); i++) begin
+ seq_run_hist[seq_names[i-1]] = 0;
+ end
+
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(num_runs)
+ for (int i = 1; i <= num_runs; i++) begin
+ uvm_sequence seq;
+ pattgen_base_vseq pattgen_vseq;
+ uint seq_idx = $urandom_range(0, seq_names.size() - 1);
+
+ seq_name = seq_names[seq_idx];
+ `uvm_info(`gfn, $sformatf("\n\n=> start stressing vseq %s (%0d/%0d)",
+ seq_name, i, num_runs), UVM_LOW)
+ seq = create_seq_by_name(seq_name);
+ `downcast(pattgen_vseq, seq)
+
+ // if upper seq disables do_apply_reset for this seq, then can't issue reset
+ // as upper seq may drive reset
+ if (do_apply_reset) begin
+ pattgen_vseq.do_apply_reset = $urandom_range(0, 1);
+ if (pattgen_vseq.do_apply_reset) begin
+ `uvm_info(`gfn, "\n *reset is randomly issued with stress_test", UVM_LOW)
+ end
+ end else begin
+ pattgen_vseq.do_apply_reset = 0;
+ `uvm_info(`gfn, "\n *upper_seq may drive reset thus not issue reset", UVM_DEBUG)
+ end
+
+ pattgen_vseq.set_sequencer(p_sequencer);
+ `DV_CHECK_RANDOMIZE_FATAL(pattgen_vseq)
+ case (seq_name)
+ "pattgen_common_vseq": begin
+ pattgen_common_vseq common_vseq;
+ `downcast(common_vseq, pattgen_vseq);
+ common_vseq.common_seq_type = "intr_test";
+ cfg.en_scb = 1'b0;
+ end
+ default: begin
+ cfg.en_scb = 1'b1;
+ end
+ endcase
+ // run vseq
+ pattgen_vseq.start(p_sequencer);
+ seq_run_hist[seq_name]++;
+ `uvm_info(`gfn, $sformatf("\n end stressing vseq %s", seq_name), UVM_LOW)
+ end
+ wait_host_for_idle();
+ `uvm_info(`gfn, "\n=> end of pattgen_stress_all_vseq", UVM_LOW)
+
+ // get the histogram of vseq running
+ str = {str, "\n\n=> vseq run histogram:"};
+ for (int i = 0; i < seq_names.size(); i++) begin
+ seq_name = seq_names[i];
+ str = {str, $sformatf("\n %-25s %2d / %2d", seq_name, seq_run_hist[seq_name], num_runs)};
+ end
+ `uvm_info(`gfn, $sformatf("%s\n", str), UVM_LOW)
+ endtask : body
+
+ virtual function void print_seq_names(const ref string seq_names[]);
+ string str;
+
+ `uvm_info(`gfn, $sformatf("\n list of %0d vseqs are stressed", seq_names.size()), UVM_LOW)
+ for (int i = 1; i <= seq_names.size(); i++) begin
+ str = {str, $sformatf("\n %s", seq_names[i-1])};
+ end
+ `uvm_info(`gfn, $sformatf("%s", str), UVM_LOW)
+ endfunction : print_seq_names
+
+endclass : pattgen_stress_all_vseq
diff --git a/hw/ip/pattgen/dv/env/seq_lib/pattgen_vseq_list.sv b/hw/ip/pattgen/dv/env/seq_lib/pattgen_vseq_list.sv
index 239d136..39a9e9b 100644
--- a/hw/ip/pattgen/dv/env/seq_lib/pattgen_vseq_list.sv
+++ b/hw/ip/pattgen/dv/env/seq_lib/pattgen_vseq_list.sv
@@ -7,3 +7,4 @@
`include "pattgen_smoke_vseq.sv"
`include "pattgen_perf_vseq.sv"
`include "pattgen_error_vseq.sv"
+`include "pattgen_stress_all_vseq.sv"