[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"