[xbar/dv] Add stress and reset tests

1. Add stress and stress with reset tests
2. change scb to extend dv_base_scoreboard in order to reuse reset
features
3. fix tl_host_driver for reset
diff --git a/hw/dv/sv/scoreboard/scoreboard.core b/hw/dv/sv/scoreboard/scoreboard.core
index c7ae67f..57ed585 100644
--- a/hw/dv/sv/scoreboard/scoreboard.core
+++ b/hw/dv/sv/scoreboard/scoreboard.core
@@ -7,6 +7,8 @@
 
 filesets:
   files_dv:
+    depend:
+      - lowrisc:dv:dv_lib
     files:
       - scoreboard_pkg.sv
       - scoreboard_queue.sv: {is_include_file: true}
diff --git a/hw/dv/sv/scoreboard/scoreboard.sv b/hw/dv/sv/scoreboard/scoreboard.sv
index bca36db..4f26d18 100644
--- a/hw/dv/sv/scoreboard/scoreboard.sv
+++ b/hw/dv/sv/scoreboard/scoreboard.sv
@@ -10,20 +10,23 @@
 // - Support multi-cast
 // - Support data transform from source to destination
 
-class scoreboard#(type SEQ_ITEM = uvm_object) extends uvm_component;
+class scoreboard#(type ITEM_T = uvm_object,
+                  type RAL_T  = dv_base_reg_block,
+                  type CFG_T  = dv_base_env_cfg,
+                  type COV_T  = dv_base_env_cov) extends dv_base_scoreboard#(RAL_T, CFG_T, COV_T);
 
-  uvm_tlm_analysis_fifo #(SEQ_ITEM) item_fifos[string];
+  uvm_tlm_analysis_fifo #(ITEM_T)   item_fifos[string];
   // Port direction
   port_dir_e                        port_dir[string];
   // Queues for pending items
-  scoreboard_queue#(SEQ_ITEM)       item_queues[string];
+  scoreboard_queue#(ITEM_T)         item_queues[string];
   int unsigned                      timeout_cycle_limit = 10000;
   bit [63:0]                        ref_timer;
   bit [63:0]                        last_activity_cycle;
   int unsigned                      num_of_exp_item;
   int unsigned                      num_of_act_item;
   int unsigned                      timeout_check_cycle_interval = 100;
-  bit                               enable_logging = 1'b1;
+  bit                               enable_logging = 1'b0;
   uvm_phase                         run_phase_h;
   bit                               objection_raised;
   semaphore                         token;
@@ -33,7 +36,8 @@
   bit                               allow_packet_drop;
   bit                               disable_scoreboard;
 
-  `uvm_component_param_utils(scoreboard#(SEQ_ITEM))
+  `uvm_component_param_utils(scoreboard#(ITEM_T, dv_base_reg_block,
+                                         dv_base_env_cfg, dv_base_env_cov))
 
   function new (string name, uvm_component parent);
     super.new(name, parent);
@@ -41,6 +45,7 @@
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
+    void'($value$plusargs("scb_logging=%d", enable_logging));
     if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", "clk_rst_vif", clk_vif)) begin
       `uvm_fatal(get_full_name(), "Cannot get clk interface")
     end
@@ -74,12 +79,13 @@
     end
     `uvm_info(get_full_name(), $sformatf(
               "Adding queue :%0s(%0s)", queue_name, policy.name()), UVM_HIGH)
-    item_queues[queue_name] = scoreboard_queue#(SEQ_ITEM)::type_id::
+    item_queues[queue_name] = scoreboard_queue#(ITEM_T)::type_id::
                               create($sformatf("%0s_%0s", get_full_name(), queue_name));
     item_queues[queue_name].policy = policy;
   endfunction
 
   task run_phase(uvm_phase phase);
+    super.run_phase(phase);
     run_phase_h = phase;
     if (disable_scoreboard) return;
     fork
@@ -97,8 +103,8 @@
 
   // Collect items from analysis FIFO, send to corresponding queues
   virtual task port_monitor(string port_name);
-    SEQ_ITEM tr;
-    SEQ_ITEM transformed_tr[$];
+    ITEM_T tr;
+    ITEM_T transformed_tr[$];
     string queue_name;
     while(1) begin
       item_fifos[port_name].get(tr);
@@ -124,7 +130,7 @@
           item_queues[queue_name].add_expected_item(transformed_tr[i], ref_timer);
         end
       end else begin
-        SEQ_ITEM tr_modified;
+        ITEM_T tr_modified;
         queue_name = get_queue_name(tr, port_name);
         // destination ports
         if (!item_queues.exists(queue_name)) begin
@@ -177,22 +183,22 @@
   // - Support multi-cast original transaction to multiple destinations
   // This step is optional, the default implementation is pass through the original
   // transaction without any modification.
-  virtual function void process_src_packet(input SEQ_ITEM  tr,
-                                           input string    port_name,
-                                           output SEQ_ITEM transformed_tr[$]);
+  virtual function void process_src_packet(input ITEM_T  tr,
+                                           input string  port_name,
+                                           output ITEM_T transformed_tr[$]);
     transformed_tr = {tr};
   endfunction
 
   // Process the destination packet before comparing
-  virtual function void process_dst_packet(input SEQ_ITEM  tr,
-                                           input string    port_name,
-                                           output SEQ_ITEM transformed_tr);
+  virtual function void process_dst_packet(input ITEM_T  tr,
+                                           input string  port_name,
+                                           output ITEM_T transformed_tr);
     transformed_tr = tr;
   endfunction
 
   // Get scoreboard queue name based on the transaction and port name
   // This function should be implemented with actual transaction to queue mapping
-  virtual function string get_queue_name(SEQ_ITEM tr, string port_name);
+  virtual function string get_queue_name(ITEM_T tr, string port_name);
     return "default";
   endfunction
 
@@ -234,4 +240,13 @@
     end
   endtask
 
+  virtual function void reset(string kind = "HARD");
+    last_activity_cycle = ref_timer;
+    foreach (item_fifos[i])  item_fifos[i].flush();
+    foreach (item_queues[i]) item_queues[i].reset();
+    num_of_act_item = 0;
+    num_of_exp_item = 0;
+    handle_objection();
+  endfunction
+
 endclass
diff --git a/hw/dv/sv/scoreboard/scoreboard_pkg.sv b/hw/dv/sv/scoreboard/scoreboard_pkg.sv
index ced853a..4614c94 100644
--- a/hw/dv/sv/scoreboard/scoreboard_pkg.sv
+++ b/hw/dv/sv/scoreboard/scoreboard_pkg.sv
@@ -5,6 +5,7 @@
 package scoreboard_pkg;
 
   import uvm_pkg::*;
+  import dv_lib_pkg::*;
 
   typedef enum bit {
     kSrcPort = 1'b0,
diff --git a/hw/dv/sv/scoreboard/scoreboard_queue.sv b/hw/dv/sv/scoreboard/scoreboard_queue.sv
index 454cfa0..f045671 100644
--- a/hw/dv/sv/scoreboard/scoreboard_queue.sv
+++ b/hw/dv/sv/scoreboard/scoreboard_queue.sv
@@ -126,4 +126,12 @@
     `uvm_fatal(get_full_name(), "custom_check must be implemented for kCustomCheck policy")
   endfunction
 
+  // delete all the queues once reset
+  virtual function void reset();
+    expected_items.delete();
+    actual_items.delete();
+    expected_items_timestamp.delete();
+    actual_items_timestamp.delete();
+  endfunction
+
 endclass
diff --git a/hw/dv/sv/tl_agent/tl_host_driver.sv b/hw/dv/sv/tl_agent/tl_host_driver.sv
index 206ffd0..87a55e3 100644
--- a/hw/dv/sv/tl_agent/tl_host_driver.sv
+++ b/hw/dv/sv/tl_agent/tl_host_driver.sv
@@ -126,18 +126,20 @@
             rsp = pending_a_req[i];
             rsp.d_opcode = vif.host_cb.d2h.d_opcode;
             rsp.d_data   = vif.host_cb.d2h.d_data;
-            rsp.d_source = vif.host_cb.d2h.d_source;
             rsp.d_param  = vif.host_cb.d2h.d_param;
             rsp.d_error  = vif.host_cb.d2h.d_error;
             rsp.d_sink   = vif.host_cb.d2h.d_sink;
             rsp.d_size   = vif.host_cb.d2h.d_size;
             rsp.d_user   = vif.host_cb.d2h.d_user;
+            // make sure every req has a rsp with same source even during reset
+            if (reset_asserted) rsp.d_source = rsp.a_source;
+            else                rsp.d_source = vif.host_cb.d2h.d_source;
             req_found = 1'b1;
             seq_item_port.put_response(rsp);
             pending_a_req.delete(i);
             `uvm_info(get_full_name(), $sformatf("Got response %0s, pending req:%0d",
                                        rsp.convert2string(), pending_a_req.size()), UVM_HIGH)
-            if (!reset_asserted) break;
+            break;
           end
         end
 
diff --git a/hw/dv/sv/tl_agent/tl_seq_lib.sv b/hw/dv/sv/tl_agent/tl_seq_lib.sv
index d24c3bf..13605cc 100644
--- a/hw/dv/sv/tl_agent/tl_seq_lib.sv
+++ b/hw/dv/sv/tl_agent/tl_seq_lib.sv
@@ -15,6 +15,7 @@
   tl_seq_item       pending_req[$];
   int               min_req_delay = 0;
   int               max_req_delay = 10;
+  int               max_outstanding = 8;
 
   `uvm_object_utils(tl_host_seq)
   `uvm_object_new
@@ -47,6 +48,7 @@
       begin : request_thread
         `uvm_info(`gfn, $sformatf("Start sending %0d host requests", req_cnt), UVM_HIGH)
         for (int i = 0; i < req_cnt; i++) begin
+          wait(pending_req.size < max_outstanding);
           req = tl_seq_item::type_id::create("req");
           start_item(req);
           randomize_req(req, i);
@@ -72,6 +74,12 @@
   virtual function void process_response(tl_seq_item req, tl_seq_item rsp);
   endfunction
 
+  virtual function void set_max_outstanding(int value);
+    max_outstanding = value;
+    set_response_queue_depth(value);
+    `uvm_info(`gfn, $sformatf("Max outstanding: %0d", value), UVM_HIGH)
+  endfunction
+
 endclass : tl_host_seq
 
 // extend host seq to send single specific item constructed by the caller
diff --git a/hw/ip/tlul/dv/Makefile b/hw/ip/tlul/dv/Makefile
index 3780a80..aa602de 100644
--- a/hw/ip/tlul/dv/Makefile
+++ b/hw/ip/tlul/dv/Makefile
@@ -107,6 +107,24 @@
   UVM_TEST_SEQ   = xbar_unmapped_addr_vseq
 endif
 
+ifeq (${TEST_NAME},xbar_stress_all)
+  UVM_TEST_SEQ   = xbar_stress_all_vseq
+endif
+
+ifeq (${TEST_NAME},xbar_stress_all_with_error)
+  UVM_TEST       = xbar_error_test
+  UVM_TEST_SEQ   = xbar_stress_all_vseq
+endif
+
+ifeq (${TEST_NAME},xbar_stress_all_with_reset)
+  UVM_TEST_SEQ   = xbar_stress_all_with_reset_vseq
+endif
+
+ifeq (${TEST_NAME},xbar_stress_all_with_reset_error)
+  UVM_TEST       = xbar_error_test
+  UVM_TEST_SEQ   = xbar_stress_all_with_reset_vseq
+endif
+
 ####################################################################################################
 ## Include the tool Makefile below                                                                ##
 ## Dont add anything else below it!                                                               ##
diff --git a/hw/ip/tlul/dv/env/seq_lib/xbar_base_vseq.sv b/hw/ip/tlul/dv/env/seq_lib/xbar_base_vseq.sv
index 2b89c52..5709300 100644
--- a/hw/ip/tlul/dv/env/seq_lib/xbar_base_vseq.sv
+++ b/hw/ip/tlul/dv/env/seq_lib/xbar_base_vseq.sv
@@ -16,6 +16,9 @@
   uint                   min_req_cnt = 100;
   uint                   max_req_cnt = 200;
 
+  // if seq crosses with the other seq, only need to enable device rsp thread
+  bit                    do_device_rsp = 1;
+
   constraint req_cnt_c {
     foreach (host_seq[i]) {
       host_seq[i].req_cnt inside {[min_req_cnt : max_req_cnt]};
@@ -37,6 +40,7 @@
     foreach (host_seq[i]) begin
       host_seq[i] = xbar_tl_host_seq::type_id::create(
                     $sformatf("%0s_seq", xbar_hosts[i].host_name));
+      host_seq[i].set_max_outstanding(1 << VALID_HOST_ID_WIDTH);
       // Default only send request to valid devices that is accessible by the host
       foreach (xbar_devices[j]) begin
         if (is_valid_path(xbar_hosts[i].host_name, xbar_devices[j].device_name)) begin
@@ -53,12 +57,14 @@
   endfunction : seq_init
 
   virtual task run_all_device_seq_nonblocking(bit out_of_order_rsp = 1);
-    foreach (device_seq[i]) begin
-      fork
-        automatic int device_id = i;
-        device_seq[device_id].out_of_order_rsp = out_of_order_rsp;
-        device_seq[device_id].start(p_sequencer.device_seqr[device_id]);
-      join_none
+    if (do_device_rsp) begin
+      foreach (device_seq[i]) begin
+        fork
+          automatic int device_id = i;
+          device_seq[device_id].out_of_order_rsp = out_of_order_rsp;
+          device_seq[device_id].start(p_sequencer.device_seqr[device_id]);
+        join_none
+      end
     end
   endtask
 
diff --git a/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_vseq.sv b/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_vseq.sv
new file mode 100644
index 0000000..bf8a6b0
--- /dev/null
+++ b/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_vseq.sv
@@ -0,0 +1,61 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// combine all xbar seqs in one seq to run in parallel for mutiply times
+class xbar_stress_all_vseq extends xbar_base_vseq;
+  `uvm_object_utils(xbar_stress_all_vseq)
+
+  // reduce num_trans
+  constraint num_trans_c {
+    num_trans inside {[1:5]};
+  }
+
+  `uvm_object_new
+
+  task body();
+    string seq_names[] = {"xbar_sanity_vseq",
+                          "xbar_random_vseq",
+                          "xbar_access_same_device_vseq",
+                          "xbar_same_source_vseq",
+                          "xbar_unmapped_addr_vseq"};
+    run_all_device_seq_nonblocking();
+    for (int i = 1; i <= num_trans; i++) fork
+      begin // isolation thread
+        foreach (seq_names[i]) begin
+          automatic int seq_idx = i;
+          fork
+            if ($urandom_range(0, 1)) begin
+              uvm_sequence   seq;
+              xbar_base_vseq xbar_vseq;
+              uint           dly_to_start_seq;
+
+              seq = create_seq_by_name(seq_names[seq_idx]);
+              `downcast(xbar_vseq, seq)
+
+              // dut_init (reset) is done in xbar_stress_all_vseq
+              xbar_vseq.do_dut_init = 0;
+              // rsp thread is created in xbar_stress_all_vseq at line 22
+              xbar_vseq.do_device_rsp = 0;
+
+              xbar_vseq.set_sequencer(p_sequencer);
+              `DV_CHECK_RANDOMIZE_FATAL(xbar_vseq)
+              `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(dly_to_start_seq,
+                                                 dly_to_start_seq dist {
+                                                   0           :/ 1,
+                                                   [1:100]     :/ 1,
+                                                   [101:1000]  :/ 1
+                                                 };)
+              cfg.clk_rst_vif.wait_clks(dly_to_start_seq);
+              xbar_vseq.start(p_sequencer);
+            end
+          join_none
+        end
+        wait fork;
+        if ($urandom_range(0, 1)) dut_init();
+        `uvm_info(`gfn, $sformatf("finished run %0d/%0d", i, num_trans), UVM_LOW)
+      end // isolation thread
+    join
+  endtask : body
+
+endclass
diff --git a/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_with_reset_vseq.sv b/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_with_reset_vseq.sv
new file mode 100644
index 0000000..1a3534d
--- /dev/null
+++ b/hw/ip/tlul/dv/env/seq_lib/xbar_stress_all_with_reset_vseq.sv
@@ -0,0 +1,62 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// one thread running the hmac_stress_all sequence
+// another thread randomly insert reset
+class xbar_stress_all_with_reset_vseq extends xbar_base_vseq;
+  `uvm_object_utils(xbar_stress_all_with_reset_vseq)
+
+  rand uint delay;
+
+  `uvm_object_new
+
+  constraint delay_c {
+    delay dist {
+      0                   :/ 1,
+      [1      :100]       :/ 1,
+      [101    :10_000]    :/ 8,
+      [10_001 :1_000_000] :/ 1
+    };
+  }
+
+  task body();
+    for (int i = 1; i <= num_trans; i++) begin
+      bit reset_ongoing;
+      fork
+        begin : seq_wo_reset
+          xbar_stress_all_vseq xbar_vseq;
+          xbar_vseq = xbar_stress_all_vseq::type_id::create("xbar_stress_all_vseq");
+
+          xbar_vseq.do_dut_init = 0;
+          xbar_vseq.set_sequencer(p_sequencer);
+          `DV_CHECK_RANDOMIZE_FATAL(xbar_vseq)
+          xbar_vseq.start(p_sequencer);
+          // once reset starts, need to wait until reset is done
+          wait (reset_ongoing == 0);
+          `uvm_info(`gfn, $sformatf("Finished run %0d/%0d w/o reset", i, num_trans), UVM_LOW)
+        end
+
+        begin : reset
+          `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(delay,
+                                             delay dist {
+                                                 1                   :/ 1,
+                                                 [2      :100]       :/ 1,
+                                                 [101    :10_000]    :/ 8,
+                                                 [10_001 :1_000_000] :/ 1
+                                             };)
+          cfg.clk_rst_vif.wait_clks(delay);
+          reset_ongoing = 1;
+          apply_reset("HARD");
+          reset_ongoing = 0;
+          `uvm_info(`gfn, $sformatf("Reset is issued for run %0d/%0d", i, num_trans), UVM_LOW)
+        end
+      join_any
+      disable fork;
+      // delay to avoid race condition when sending item and checking no item after reset occur at
+      // the same time
+      #1ps;
+    end // end for loop
+  endtask : body
+
+endclass
diff --git a/hw/ip/tlul/dv/env/seq_lib/xbar_vseq_list.sv b/hw/ip/tlul/dv/env/seq_lib/xbar_vseq_list.sv
index 420c052..aef1331 100644
--- a/hw/ip/tlul/dv/env/seq_lib/xbar_vseq_list.sv
+++ b/hw/ip/tlul/dv/env/seq_lib/xbar_vseq_list.sv
@@ -10,3 +10,5 @@
 `include "xbar_access_same_device_vseq.sv"
 `include "xbar_same_source_vseq.sv"
 `include "xbar_unmapped_addr_vseq.sv"
+`include "xbar_stress_all_vseq.sv"
+`include "xbar_stress_all_with_reset_vseq.sv"
diff --git a/hw/ip/tlul/dv/env/xbar_scoreboard.sv b/hw/ip/tlul/dv/env/xbar_scoreboard.sv
index 25b989e..bcf2ccd 100644
--- a/hw/ip/tlul/dv/env/xbar_scoreboard.sv
+++ b/hw/ip/tlul/dv/env/xbar_scoreboard.sv
@@ -7,10 +7,10 @@
 // Extend from common multi-streams scoreboard
 // Use the device address map to determine the queue ID
 // ------------------------------------------------------------------------
-class xbar_scoreboard extends scoreboard_pkg::scoreboard#(tl_seq_item);
-
-  xbar_env_cfg cfg;
-  xbar_env_cov cov;
+class xbar_scoreboard extends scoreboard_pkg::scoreboard #(.ITEM_T(tl_seq_item),
+                                                           .RAL_T (dv_base_reg_block),
+                                                           .CFG_T (xbar_env_cfg),
+                                                           .COV_T (xbar_env_cov));
   int          chan_prefix_len = 7;
 
   `uvm_component_utils(xbar_scoreboard)