[xbar/dv] Add multiple test to control delay and add out of order

1. add tests for zero delay, large delay, device slow response
2. add out of order response in TL device seq
diff --git a/hw/dv/sv/tl_agent/tl_seq_lib.sv b/hw/dv/sv/tl_agent/tl_seq_lib.sv
index 17eec33..591d55c 100644
--- a/hw/dv/sv/tl_agent/tl_seq_lib.sv
+++ b/hw/dv/sv/tl_agent/tl_seq_lib.sv
@@ -119,50 +119,64 @@
 // Device sequence, currently support in-order response
 class tl_device_seq extends uvm_sequence#(.REQ(tl_seq_item));
 
-  int unsigned             rsp_cnt;
   int                      min_rsp_delay = 0;
   int                      max_rsp_delay = 10;
   mem_model_pkg::mem_model mem;
+  tl_seq_item              req_q[$];
+  bit                      out_of_order_rsp = 0;
 
   `uvm_object_utils(tl_device_seq)
   `uvm_declare_p_sequencer(tl_sequencer)
-
-  function new (string name = "");
-    super.new(name);
-  endfunction : new
+  `uvm_object_new
 
   virtual task body();
-    tl_seq_item req;
-    tl_seq_item rsp;
-    forever begin
-      p_sequencer.a_chan_req_fifo.get(req);
-      rsp = randomize_rsp(req);
-      `uvm_info(`gfn, $sformatf("Sent rsp[%0d] : %0s, req: %0s",
-                                 rsp_cnt, rsp.convert2string(), req.convert2string()), UVM_HIGH)
-      start_item(rsp);
-      finish_item(rsp);
-      `uvm_info(`gfn, $sformatf("Sent rsp[%0d] : %0s",
-                                 rsp_cnt, rsp.convert2string()), UVM_HIGH)
-      rsp_cnt++;
-    end
+    fork
+      forever begin // collect req thread
+        int         req_cnt;
+        tl_seq_item req;
+
+        p_sequencer.a_chan_req_fifo.get(req);
+        req_q.push_back(req);
+        `uvm_info(`gfn, $sformatf("Received req[%0d] : %0s",
+                                   req_cnt, req.convert2string()), UVM_HIGH)
+        req_cnt++;
+      end
+      forever begin // response thread
+        int         rsp_cnt;
+        tl_seq_item req, rsp;
+
+        wait (req_q.size > 0);
+        if (out_of_order_rsp) req_q.shuffle();
+        req = req_q.pop_front();
+        $cast(rsp, req.clone());
+        randomize_rsp(rsp);
+        update_mem(rsp);
+        start_item(rsp);
+        finish_item(rsp);
+        `uvm_info(`gfn, $sformatf("Sent rsp[%0d] : %0s, req: %0s",
+                                   rsp_cnt, rsp.convert2string(), req.convert2string()), UVM_HIGH)
+        rsp_cnt++;
+      end
+    join
   endtask
 
-  virtual function tl_seq_item randomize_rsp(tl_seq_item req);
-    tl_seq_item rsp;
-    $cast(rsp, req.clone());
+  virtual function void randomize_rsp(tl_seq_item rsp);
     rsp.disable_a_chan_randomization();
     if (!(rsp.randomize() with
            {rsp.d_valid_delay inside {[min_rsp_delay : max_rsp_delay]};
-            if (rsp.a_opcode inside {PutFullData, PutPartialData}) {
-              rsp.d_opcode == tlul_pkg::AccessAck;
-            } else {
+            if (rsp.a_opcode == tlul_pkg::Get) {
               rsp.d_opcode == tlul_pkg::AccessAckData;
+            } else {
+              rsp.d_opcode == tlul_pkg::AccessAck;
             }
             rsp.d_size == rsp.a_size;
             rsp.d_user == '0; // TODO: Not defined yet, tie it to zero
             rsp.d_source == rsp.a_source;})) begin
       `uvm_fatal(`gfn, "Cannot randomize rsp")
     end
+  endfunction
+
+  virtual function void update_mem(tl_seq_item rsp);
     if (mem != null) begin
       if (req.a_opcode inside {PutFullData, PutPartialData}) begin
         bit [tl_agent_pkg::DataWidth-1:0] data;
@@ -180,7 +194,6 @@
         end
       end
     end
-    return rsp;
   endfunction
 
 endclass : tl_device_seq
diff --git a/hw/ip/tlul/dv/Makefile b/hw/ip/tlul/dv/Makefile
index ce7d26c..c29b52b 100644
--- a/hw/ip/tlul/dv/Makefile
+++ b/hw/ip/tlul/dv/Makefile
@@ -27,11 +27,53 @@
 UVM_TEST_SEQ    ?= xbar_base_vseq
 
 ifeq (${TEST_NAME},xbar_sanity)
-  UVM_TEST_SEQ    = xbar_sanity_vseq
+  UVM_TEST_SEQ   = xbar_sanity_vseq
+endif
+
+ifeq (${TEST_NAME},xbar_sanity_zero_delays)
+  UVM_TEST_SEQ   = xbar_sanity_vseq
+  RUN_OPTS      += +zero_delays=1
+endif
+
+ifeq (${TEST_NAME},xbar_sanity_large_delays)
+  UVM_TEST_SEQ   = xbar_sanity_vseq
+  RUN_OPTS      += +min_req_delay=0
+  RUN_OPTS      += +max_req_delay=1000
+  RUN_OPTS      += +min_rsp_delay=0
+  RUN_OPTS      += +max_rsp_delay=1000
+endif
+
+ifeq (${TEST_NAME},xbar_sanity_slow_rsp)
+  UVM_TEST_SEQ   = xbar_sanity_vseq
+  RUN_OPTS      += +min_req_delay=0
+  RUN_OPTS      += +max_req_delay=10
+  RUN_OPTS      += +min_rsp_delay=0
+  RUN_OPTS      += +max_rsp_delay=1000
 endif
 
 ifeq (${TEST_NAME},xbar_random)
-  UVM_TEST_SEQ    = xbar_random_vseq
+  UVM_TEST_SEQ   = xbar_random_vseq
+endif
+
+ifeq (${TEST_NAME},xbar_random_zero_delays)
+  UVM_TEST_SEQ   = xbar_random_vseq
+  RUN_OPTS      += +zero_delays=1
+endif
+
+ifeq (${TEST_NAME},xbar_random_large_delays)
+  UVM_TEST_SEQ   = xbar_random_vseq
+  RUN_OPTS      += +min_req_delay=0
+  RUN_OPTS      += +max_req_delay=1000
+  RUN_OPTS      += +min_rsp_delay=0
+  RUN_OPTS      += +max_rsp_delay=1000
+endif
+
+ifeq (${TEST_NAME},xbar_random_slow_rsp)
+  UVM_TEST_SEQ   = xbar_random_vseq
+  RUN_OPTS      += +min_req_delay=0
+  RUN_OPTS      += +max_req_delay=10
+  RUN_OPTS      += +min_rsp_delay=0
+  RUN_OPTS      += +max_rsp_delay=1000
 endif
 
 ####################################################################################################
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 f15eae8..637f520 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
@@ -50,10 +50,11 @@
     end
   endfunction : pre_randomize
 
-  virtual task run_device_seq_nonblocking();
+  virtual task run_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
     end
diff --git a/hw/ip/tlul/dv/env/seq_lib/xbar_sanity_vseq.sv b/hw/ip/tlul/dv/env/seq_lib/xbar_sanity_vseq.sv
index 2f293fc..53ad5ae 100644
--- a/hw/ip/tlul/dv/env/seq_lib/xbar_sanity_vseq.sv
+++ b/hw/ip/tlul/dv/env/seq_lib/xbar_sanity_vseq.sv
@@ -3,13 +3,14 @@
 // SPDX-License-Identifier: Apache-2.0
 
 // Sequentially test each host to access any device
+// device will respond in order
 class xbar_sanity_vseq extends xbar_base_vseq;
 
   `uvm_object_utils(xbar_sanity_vseq)
   `uvm_object_new
 
   virtual task body();
-    run_device_seq_nonblocking();
+    run_device_seq_nonblocking(.out_of_order_rsp(0));
     foreach (host_seq[i]) begin
       run_host_seq(i);
     end
diff --git a/hw/ip/tlul/dv/env/xbar_env_cfg.sv b/hw/ip/tlul/dv/env/xbar_env_cfg.sv
index ebce290..2ca7a9b 100644
--- a/hw/ip/tlul/dv/env/xbar_env_cfg.sv
+++ b/hw/ip/tlul/dv/env/xbar_env_cfg.sv
@@ -28,11 +28,6 @@
   virtual function void initialize(bit [TL_AW-1:0] csr_base_addr = '1,
                                    bit [TL_AW-1:0] csr_addr_map_size = 2048);
     has_ral = 0; // no csr in xbar
-    void'($value$plusargs("min_req_delay=%d", min_req_delay));
-    void'($value$plusargs("max_req_delay=%d", max_req_delay));
-    void'($value$plusargs("min_rsp_delay=%d", min_rsp_delay));
-    void'($value$plusargs("max_rsp_delay=%d", max_rsp_delay));
-
     // Host TL agent cfg
     num_of_hosts = xbar_hosts.size();
     host_agent_cfg = new[num_of_hosts];
@@ -40,6 +35,7 @@
       host_agent_cfg[i] = tl_agent_cfg::type_id::
                           create($sformatf("%0s_agent_cfg", xbar_hosts[i].host_name));
       host_agent_cfg[i].is_host = 1;
+      host_agent_cfg[i].use_seq_item_a_valid_delay = 1;
     end
     // Device TL agent cfg
     num_of_devices = xbar_devices.size();
@@ -48,6 +44,7 @@
       device_agent_cfg[i] = tl_agent_cfg::type_id::
                             create($sformatf("%0s_agent_cfg", xbar_devices[i].device_name));
       device_agent_cfg[i].is_host = 0;
+      device_agent_cfg[i].use_seq_item_d_valid_delay = 1;
     end
   endfunction
 endclass
diff --git a/hw/ip/tlul/dv/tests/xbar_base_test.sv b/hw/ip/tlul/dv/tests/xbar_base_test.sv
index d2068ff..b71d163 100644
--- a/hw/ip/tlul/dv/tests/xbar_base_test.sv
+++ b/hw/ip/tlul/dv/tests/xbar_base_test.sv
@@ -10,6 +10,17 @@
     max_quit_count  = 50;
     test_timeout_ns = 600_000_000; // 600ms
     super.build_phase(phase);
+
+    void'($value$plusargs("min_req_delay=%d", cfg.min_req_delay));
+    void'($value$plusargs("max_req_delay=%d", cfg.max_req_delay));
+    void'($value$plusargs("min_rsp_delay=%d", cfg.min_rsp_delay));
+    void'($value$plusargs("max_rsp_delay=%d", cfg.max_rsp_delay));
+    if (cfg.zero_delays) begin
+      cfg.min_req_delay = 0;
+      cfg.max_req_delay = 0;
+      cfg.min_rsp_delay = 0;
+      cfg.max_rsp_delay = 0;
+    end
   endfunction : build_phase
 
 endclass : xbar_base_test