[dv] make dv_base_agent work for high-level agent

Tried to create a high-level agent but then I found it's not much
different from dv_base_agent. So, I feel it's better to add what we need
for high-level agent in dv_base_agent
1. 2 mon2sqr port/fifo, which can be used for re-active driver. Modified
i2c to use the mon2sqr_req_fifo for re-active driver
2. add knob en_driver for high-level agent which doesn't need a driver

Next step will update uvmdvgen to generate agent with a low-level agent
and connect those monitors

Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/dv/sv/csrng_agent/csrng_agent.sv b/hw/dv/sv/csrng_agent/csrng_agent.sv
index 67f0729..f69f7f3 100644
--- a/hw/dv/sv/csrng_agent/csrng_agent.sv
+++ b/hw/dv/sv/csrng_agent/csrng_agent.sv
@@ -40,10 +40,12 @@
                                    create("m_genbits_push_agent_cfg");
     cfg.m_genbits_push_agent_cfg.is_active  = cfg.is_active;
     cfg.m_genbits_push_agent_cfg.agent_type = PushAgent;
-    if (cfg.if_mode == dv_utils_pkg::Host)
+    if (cfg.if_mode == dv_utils_pkg::Host) begin
+      cfg.has_req_fifo = 1;
       cfg.m_genbits_push_agent_cfg.if_mode = dv_utils_pkg::Device;
-    else
+    end else begin
       cfg.m_genbits_push_agent_cfg.if_mode = dv_utils_pkg::Host;
+    end
 
     cfg.vif.if_mode = cfg.if_mode;
 
@@ -64,7 +66,7 @@
 
     if (cfg.is_active) begin
       if (cfg.if_mode == dv_utils_pkg::Device) begin
-        monitor.req_port.connect(sequencer.cmd_req_fifo.analysis_export);
+        monitor.req_analysis_port.connect(sequencer.req_analysis_fifo.analysis_export);
         sequencer.m_genbits_push_sequencer = m_genbits_push_agent.sequencer;
       end
     end
diff --git a/hw/dv/sv/csrng_agent/csrng_monitor.sv b/hw/dv/sv/csrng_agent/csrng_monitor.sv
index f9dd17b..03e20e1 100644
--- a/hw/dv/sv/csrng_agent/csrng_monitor.sv
+++ b/hw/dv/sv/csrng_agent/csrng_monitor.sv
@@ -14,21 +14,9 @@
   // csrng_agent_cov: cov
   // uvm_analysis_port #(csrng_item): analysis_port
 
-  // item will be sent to this port when req phase is done (last is set)
-  uvm_analysis_port#(csrng_item) req_port;
-  // item will be sent to this port when rsp phase is done (rsp_done is set)
-  uvm_analysis_port#(csrng_item) rsp_port;
-
   `uvm_component_new
   bit in_reset;
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-
-    req_port  = new("req_port", this);
-    rsp_port  = new("rsp_port", this);
-  endfunction
-
   task run_phase(uvm_phase phase);
     @(posedge cfg.vif.rst_n);
     fork
@@ -70,7 +58,7 @@
         item = csrng_item::type_id::create("item");
         item.acmd = cfg.vif.mon_cb.cmd_req.csrng_req_bus[3:0];
         `uvm_info(`gfn, $sformatf("Captured item: %s", item.convert2string()), UVM_HIGH)
-        req_port.write(item);
+        req_analysis_port.write(item);
         // After picking up a request, wait until a response is sent before
         // detecting another request, as this is not a pipelined protocol.
         `DV_SPINWAIT_EXIT(while (!cfg.vif.mon_cb.cmd_rsp.csrng_rsp_ack) @(cfg.vif.mon_cb);,
diff --git a/hw/dv/sv/csrng_agent/csrng_sequencer.sv b/hw/dv/sv/csrng_agent/csrng_sequencer.sv
index 602d691..71c7771 100644
--- a/hw/dv/sv/csrng_agent/csrng_sequencer.sv
+++ b/hw/dv/sv/csrng_agent/csrng_sequencer.sv
@@ -11,17 +11,6 @@
   push_pull_sequencer#(.HostDataWidth(csrng_pkg::CSRNG_CMD_WIDTH))          m_req_push_sequencer;
   push_pull_sequencer#(.HostDataWidth(csrng_pkg::FIPS_GENBITS_BUS_WIDTH))   m_genbits_push_sequencer;
 
-  // Analysis port through which device monitors can send transactions
-  // to the sequencer.
-  uvm_tlm_analysis_fifo#(csrng_item)   cmd_req_fifo;
-
   `uvm_component_new
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-    if (cfg.if_mode == dv_utils_pkg::Device) begin
-      cmd_req_fifo = new("cmd_req_fifo", this);
-    end
-  endfunction
-
 endclass
diff --git a/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv b/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv
index 4f0e0a4..1659af1 100644
--- a/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv
+++ b/hw/dv/sv/csrng_agent/seq_lib/csrng_device_seq.sv
@@ -18,7 +18,7 @@
     fork
       forever begin
         csrng_item   req;
-        p_sequencer.cmd_req_fifo.get(req);
+        p_sequencer.req_analysis_fifo.get(req);
         req_q.push_back(req);
       end
 
diff --git a/hw/dv/sv/dv_lib/dv_base_agent.sv b/hw/dv/sv/dv_lib/dv_base_agent.sv
index 9e70ea5..a909aa1 100644
--- a/hw/dv/sv/dv_lib/dv_base_agent.sv
+++ b/hw/dv/sv/dv_lib/dv_base_agent.sv
@@ -43,17 +43,25 @@
       sequencer = SEQUENCER_T::type_id::create("sequencer", this);
       sequencer.cfg = cfg;
 
-      if (cfg.if_mode == Host)  driver = HOST_DRIVER_T::type_id::create("driver", this);
-      else                      driver = DEVICE_DRIVER_T::type_id::create("driver", this);
-      driver.cfg = cfg;
+      if (cfg.has_driver) begin
+        if (cfg.if_mode == Host)  driver = HOST_DRIVER_T::type_id::create("driver", this);
+        else                      driver = DEVICE_DRIVER_T::type_id::create("driver", this);
+        driver.cfg = cfg;
+      end
     end
   endfunction
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
-    if (cfg.is_active) begin
+    if (cfg.is_active && cfg.has_driver) begin
       driver.seq_item_port.connect(sequencer.seq_item_export);
     end
+    if (cfg.has_req_fifo) begin
+      monitor.req_analysis_port.connect(sequencer.req_analysis_fifo.analysis_export);
+    end
+    if (cfg.has_rsp_fifo) begin
+      monitor.rsp_analysis_port.connect(sequencer.rsp_analysis_fifo.analysis_export);
+    end
   endfunction
 
 endclass
diff --git a/hw/dv/sv/dv_lib/dv_base_agent_cfg.sv b/hw/dv/sv/dv_lib/dv_base_agent_cfg.sv
index b9f0eaa..2a2e1f9 100644
--- a/hw/dv/sv/dv_lib/dv_base_agent_cfg.sv
+++ b/hw/dv/sv/dv_lib/dv_base_agent_cfg.sv
@@ -5,17 +5,27 @@
 class dv_base_agent_cfg extends uvm_object;
 
   // agent cfg knobs
-  bit         is_active = 1'b1;   // active driver or passive monitor
+  bit         is_active = 1'b1;   // active driver/sequencer or passive monitor
   bit         en_cov    = 1'b1;   // enable coverage
   if_mode_e   if_mode;            // interface mode - Host or Device
 
+  // indicate to create and connet driver to sequencer or not
+  // if this is a high-level agent, we may just call lower-level agent to send item in seq, then
+  // driver isn't needed
+  bit         has_driver = 1'b1;
+  // indicate if these fifo and ports exist or not
+  bit         has_req_fifo = 1'b0;
+  bit         has_rsp_fifo = 1'b0;
+
   // use for phase_ready_to_end to add additional delay after ok_to_end is set
   int ok_to_end_delay_ns = 1000;
 
   `uvm_object_utils_begin(dv_base_agent_cfg)
-    `uvm_field_int (is_active,          UVM_DEFAULT)
-    `uvm_field_int (en_cov,             UVM_DEFAULT)
-    `uvm_field_enum(if_mode_e, if_mode, UVM_DEFAULT)
+    `uvm_field_int (is_active,            UVM_DEFAULT)
+    `uvm_field_int (en_cov,               UVM_DEFAULT)
+    `uvm_field_enum(if_mode_e, if_mode,   UVM_DEFAULT)
+    `uvm_field_int (has_req_fifo,         UVM_DEFAULT)
+    `uvm_field_int (has_rsp_fifo,         UVM_DEFAULT)
   `uvm_object_utils_end
 
   `uvm_object_new
diff --git a/hw/dv/sv/dv_lib/dv_base_monitor.sv b/hw/dv/sv/dv_lib/dv_base_monitor.sv
index ca353fd..3e2173d 100644
--- a/hw/dv/sv/dv_lib/dv_base_monitor.sv
+++ b/hw/dv/sv/dv_lib/dv_base_monitor.sv
@@ -20,11 +20,18 @@
   // Analysis port for the collected transfer.
   uvm_analysis_port #(ITEM_T) analysis_port;
 
+  // item will be sent to this port for seq when req phase is done (last is set)
+  uvm_analysis_port #(ITEM_T) req_analysis_port;
+  // item will be sent to this port for seq when rsp phase is done (rsp_done is set)
+  uvm_analysis_port #(ITEM_T) rsp_analysis_port;
+
   `uvm_component_new
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
     analysis_port = new("analysis_port", this);
+    req_analysis_port = new("req_analysis_port", this);
+    rsp_analysis_port = new("rsp_analysis_port", this);
   endfunction
 
   virtual task run_phase(uvm_phase phase);
diff --git a/hw/dv/sv/dv_lib/dv_base_sequencer.sv b/hw/dv/sv/dv_lib/dv_base_sequencer.sv
index 15aec1e..8830d4e 100644
--- a/hw/dv/sv/dv_lib/dv_base_sequencer.sv
+++ b/hw/dv/sv/dv_lib/dv_base_sequencer.sv
@@ -11,8 +11,21 @@
                                                  .CFG_T      (CFG_T),
                                                  .RSP_ITEM_T (RSP_ITEM_T)))
 
+  // These fifos collects items when req/rsp is received, which are used to communicate between
+  // monitor and sequences. These fifos are optional
+  // When device is re-active, it gets items from req_analysis_fifo and send rsp to driver
+  // When this is a high-level agent, monitors put items to these 2 fifos for high-level seq
+  uvm_tlm_analysis_fifo #(ITEM_T) req_analysis_fifo;
+  uvm_tlm_analysis_fifo #(ITEM_T) rsp_analysis_fifo;
+
   CFG_T cfg;
 
   `uvm_component_new
 
+  function void build_phase(uvm_phase phase);
+    super.build_phase(phase);
+    if (cfg.has_req_fifo) req_analysis_fifo = new("req_analysis_fifo", this);
+    if (cfg.has_rsp_fifo) rsp_analysis_fifo = new("rsp_analysis_fifo", this);
+  endfunction : build_phase
+
 endclass
diff --git a/hw/dv/sv/i2c_agent/i2c_agent.sv b/hw/dv/sv/i2c_agent/i2c_agent.sv
index bd7dfce..a154414 100644
--- a/hw/dv/sv/i2c_agent/i2c_agent.sv
+++ b/hw/dv/sv/i2c_agent/i2c_agent.sv
@@ -21,13 +21,12 @@
     if (!uvm_config_db#(virtual i2c_if)::get(this, "", "vif", cfg.vif)) begin
       `uvm_fatal(`gfn, "failed to get i2c_if handle from uvm_config_db")
     end
+    if (cfg.if_mode == dv_utils_pkg::Device) cfg.has_req_fifo = 1;
   endfunction : build_phase
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
-    if (cfg.if_mode == dv_utils_pkg::Device) begin
-      monitor.mon_item_port.connect(sequencer.mon_item_fifo.analysis_export);
-    end else begin
+    if (!cfg.if_mode == dv_utils_pkg::Device) begin
       `uvm_fatal(`gfn, "failed to connect driver to sequencer")
     end
   endfunction : connect_phase
diff --git a/hw/dv/sv/i2c_agent/i2c_monitor.sv b/hw/dv/sv/i2c_agent/i2c_monitor.sv
index c6c6d27..a7e15b5 100644
--- a/hw/dv/sv/i2c_agent/i2c_monitor.sv
+++ b/hw/dv/sv/i2c_agent/i2c_monitor.sv
@@ -9,7 +9,6 @@
   );
   `uvm_component_utils(i2c_monitor)
 
-  uvm_analysis_port #(i2c_item) mon_item_port;  // used to send partial rd/wr_tran to driver
   uvm_analysis_port #(i2c_item) wr_item_port;   // used to send complete wr_tran to sb
   uvm_analysis_port #(i2c_item) rd_item_port;   // used to send complete rd_tran to sb
 
@@ -21,7 +20,6 @@
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
-    mon_item_port = new("mon_item_port", this);
     wr_item_port  = new("wr_item_port", this);
     rd_item_port  = new("rd_item_port", this);
     mon_dut_item  = i2c_item::type_id::create("mon_dut_item", this);
@@ -102,7 +100,7 @@
     // get ack after transmitting address
     mon_dut_item.drv_type = DevAck;
     `downcast(clone_item, mon_dut_item.clone());
-    mon_item_port.write(clone_item);
+    req_analysis_port.write(clone_item);
     cfg.vif.wait_for_device_ack(cfg.timing_cfg);
     `uvm_info(`gfn, $sformatf("\nmonitor, address, detect TARGET ACK"), UVM_DEBUG)
   endtask : address_thread
@@ -118,7 +116,7 @@
       // ask driver response read data
       mon_dut_item.drv_type = RdData;
       `downcast(clone_item, mon_dut_item.clone());
-      mon_item_port.write(clone_item);
+      req_analysis_port.write(clone_item);
       // sample read data
       for (int i = 7; i >= 0; i--) begin
         cfg.vif.get_bit_data("device", cfg.timing_cfg, mon_data[i]);
@@ -159,7 +157,7 @@
               // ask driver's response a write request
               mon_dut_item.drv_type = WrData;
               `downcast(clone_item, mon_dut_item.clone());
-              mon_item_port.write(clone_item);
+              req_analysis_port.write(clone_item);
               for (int i = 7; i >= 0; i--) begin
                 cfg.vif.get_bit_data("host", cfg.timing_cfg, mon_data[i]);
               end
@@ -167,7 +165,7 @@
               mon_dut_item.data_q.push_back(mon_data);
               mon_dut_item.drv_type = DevAck;
               `downcast(clone_item, mon_dut_item.clone());
-              mon_item_port.write(clone_item);
+              req_analysis_port.write(clone_item);
               cfg.vif.wait_for_device_ack(cfg.timing_cfg);
             end
             begin
diff --git a/hw/dv/sv/i2c_agent/i2c_sequencer.sv b/hw/dv/sv/i2c_agent/i2c_sequencer.sv
index 40be6c7..55a6dce 100644
--- a/hw/dv/sv/i2c_agent/i2c_sequencer.sv
+++ b/hw/dv/sv/i2c_agent/i2c_sequencer.sv
@@ -4,14 +4,6 @@
 
 class i2c_sequencer extends dv_base_sequencer#(i2c_item, i2c_agent_cfg);
   `uvm_component_utils(i2c_sequencer)
-
-  uvm_tlm_analysis_fifo #(i2c_item) mon_item_fifo;
-
   `uvm_component_new
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-    mon_item_fifo = new("mon_item_fifo", this);
-  endfunction : build_phase
-
 endclass : i2c_sequencer
diff --git a/hw/dv/sv/i2c_agent/seq_lib/i2c_device_seq.sv b/hw/dv/sv/i2c_agent/seq_lib/i2c_device_seq.sv
index 4ed25e6..e8c0558 100644
--- a/hw/dv/sv/i2c_agent/seq_lib/i2c_device_seq.sv
+++ b/hw/dv/sv/i2c_agent/seq_lib/i2c_device_seq.sv
@@ -16,7 +16,7 @@
     fork
       forever begin
         i2c_item  req;
-        p_sequencer.mon_item_fifo.get(req);
+        p_sequencer.req_analysis_fifo.get(req);
         req_q.push_back(req);
       end
       forever begin
@@ -28,4 +28,4 @@
       end
     join
   endtask
-endclass : i2c_device_seq
\ No newline at end of file
+endclass : i2c_device_seq
diff --git a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_agent.sv b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_agent.sv
index 6f16046..4a8b73a 100644
--- a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_agent.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_agent.sv
@@ -19,6 +19,10 @@
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
+
+    // use for mon-seq connection
+    cfg.has_req_fifo = 1;
+
     // get keymgr_kmac_intf handle
     if (!uvm_config_db#(virtual keymgr_kmac_intf)::get(this, "", "vif", cfg.vif)) begin
       `uvm_fatal(`gfn, "failed to get keymgr_kmac_intf handle from uvm_config_db")
@@ -48,7 +52,7 @@
       if (cfg.if_mode == dv_utils_pkg::Host) begin
         sequencer.m_push_pull_sequencer = m_data_push_agent.sequencer;
       end else begin
-        monitor.req_port.connect(sequencer.req_data_fifo.analysis_export);
+        monitor.req_analysis_port.connect(sequencer.req_analysis_fifo.analysis_export);
       end
     end
 
diff --git a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
index 756298c..fdc8ae8 100644
--- a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_monitor.sv
@@ -14,20 +14,12 @@
   // keymgr_kmac_agent_cov: cov
   // uvm_analysis_port #(keymgr_kmac_item): analysis_port
 
-  // item will be sent to this port when req phase is done (last is set)
-  uvm_analysis_port #(keymgr_kmac_item) req_port;
-  // item will be sent to this port when rsp phase is done (rsp_done is set)
-  uvm_analysis_port #(keymgr_kmac_item) rsp_port;
-  // connect to push_pull_monitor analysis_port, to get push_pull_item when valid-ready handshake
-  // is done
   uvm_tlm_analysis_fifo#(push_pull_item#(`CONNECT_DATA_WIDTH)) data_fifo;
 
   `uvm_component_new
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
-    req_port  = new("req_port", this);
-    rsp_port  = new("rsp_port", this);
     data_fifo = new("data_fifo", this);
   endfunction
 
@@ -67,7 +59,7 @@
         end
         if (last) break;
       end
-      req_port.write(req);
+      req_analysis_port.write(req);
       `uvm_info(`gfn, $sformatf("Write req item:\n%0s", req.sprint()), UVM_HIGH)
 
       `downcast(rsp, req.clone())
@@ -75,7 +67,7 @@
       rsp.rsp_error         = cfg.vif.rsp_error;
       rsp.rsp_digest_share0 = cfg.vif.rsp_digest_share0;
       rsp.rsp_digest_share1 = cfg.vif.rsp_digest_share1;
-      rsp_port.write(rsp);
+      analysis_port.write(rsp);
       `uvm_info(`gfn, $sformatf("Write rsp item:\n%0s", rsp.sprint()), UVM_HIGH)
       ok_to_end = 1;
     end
diff --git a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_sequencer.sv b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_sequencer.sv
index 35ee943..3c08e61 100644
--- a/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_sequencer.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/keymgr_kmac_sequencer.sv
@@ -10,17 +10,6 @@
 
   push_pull_sequencer#(`CONNECT_DATA_WIDTH) m_push_pull_sequencer;
 
-  // Analysis port through which device monitors can send transactions
-  // to the sequencer.
-  uvm_tlm_analysis_fifo #(keymgr_kmac_item) req_data_fifo;
-
   `uvm_component_new
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-    if (cfg.if_mode == dv_utils_pkg::Device) begin
-      req_data_fifo = new("req_data_fifo", this);
-    end
-  endfunction : build_phase
-
 endclass
diff --git a/hw/dv/sv/keymgr_kmac_agent/seq_lib/keymgr_kmac_device_seq.sv b/hw/dv/sv/keymgr_kmac_agent/seq_lib/keymgr_kmac_device_seq.sv
index 9c5b89b..d990485 100644
--- a/hw/dv/sv/keymgr_kmac_agent/seq_lib/keymgr_kmac_device_seq.sv
+++ b/hw/dv/sv/keymgr_kmac_agent/seq_lib/keymgr_kmac_device_seq.sv
@@ -8,7 +8,7 @@
 
   virtual task body();
     forever begin
-      p_sequencer.req_data_fifo.get(req);
+      p_sequencer.req_analysis_fifo.get(req);
       $cast(rsp, req.clone());
       start_item(rsp);
       randomize_item(rsp);
diff --git a/hw/dv/sv/push_pull_agent/push_pull_agent.sv b/hw/dv/sv/push_pull_agent/push_pull_agent.sv
index d2dc7b7..a4edbaa 100644
--- a/hw/dv/sv/push_pull_agent/push_pull_agent.sv
+++ b/hw/dv/sv/push_pull_agent/push_pull_agent.sv
@@ -20,6 +20,10 @@
 
   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
+
+    // use for reactive device
+    cfg.has_req_fifo = 1;
+
     // get push_pull_if handle
     if (!uvm_config_db#(virtual push_pull_if#(HostDataWidth, DeviceDataWidth))::get(this, "", "vif",
                                                                                     cfg.vif)) begin
@@ -33,7 +37,7 @@
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
     if (cfg.if_mode == dv_utils_pkg::Device) begin
-      monitor.req_port.connect(sequencer.push_pull_req_fifo.analysis_export);
+      monitor.req_analysis_port.connect(sequencer.req_analysis_fifo.analysis_export);
     end
   endfunction
 
diff --git a/hw/dv/sv/push_pull_agent/push_pull_monitor.sv b/hw/dv/sv/push_pull_agent/push_pull_monitor.sv
index 1d39b62..79892d1 100644
--- a/hw/dv/sv/push_pull_agent/push_pull_monitor.sv
+++ b/hw/dv/sv/push_pull_agent/push_pull_monitor.sv
@@ -14,19 +14,12 @@
   // the base class provides the following handles for use:
   // push_pull_agent_cfg: cfg
   // push_pull_agent_cov: cov
-  // uvm_analysis_port #(push_pull_item): analysis_port
-
-  // connected to sequencer to send request responses
-  uvm_analysis_port #(push_pull_item#(HostDataWidth, DeviceDataWidth)) req_port;
+  // uvm_analysis_port #(ITEM_T): analysis_port
+  // uvm_analysis_port #(ITEM_T): req_analysis_port;
 
   `uvm_component_new
   bit in_reset;
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-    req_port = new("req_port", this);
-  endfunction
-
   task run_phase(uvm_phase phase);
     @(posedge cfg.vif.rst_n);
     fork
@@ -96,7 +89,7 @@
         `uvm_info(`gfn, "detected pull request", UVM_HIGH)
         // TODO: sample any covergroups
         item = push_pull_item#(HostDataWidth, DeviceDataWidth)::type_id::create("item");
-        req_port.write(item);
+        req_analysis_port.write(item);
         // After picking up a request, wait until a response is sent before
         // detecting another request, as this is not a pipelined protocol.
         `DV_SPINWAIT_EXIT(while (!cfg.vif.mon_cb.ack) @(cfg.vif.mon_cb);,
diff --git a/hw/dv/sv/push_pull_agent/push_pull_sequencer.sv b/hw/dv/sv/push_pull_agent/push_pull_sequencer.sv
index abec317..06c6459 100644
--- a/hw/dv/sv/push_pull_agent/push_pull_sequencer.sv
+++ b/hw/dv/sv/push_pull_agent/push_pull_sequencer.sv
@@ -9,18 +9,6 @@
     .CFG_T  (push_pull_agent_cfg#(HostDataWidth, DeviceDataWidth))
 );
   `uvm_component_param_utils(push_pull_sequencer#(HostDataWidth, DeviceDataWidth))
-
-  // Analysis port through which device monitors can send transactions
-  // to the sequencer.
-  uvm_tlm_analysis_fifo #(push_pull_item#(HostDataWidth, DeviceDataWidth)) push_pull_req_fifo;
-
   `uvm_component_new
 
-  function void build_phase(uvm_phase phase);
-    super.build_phase(phase);
-    if (cfg.if_mode == dv_utils_pkg::Device) begin
-      push_pull_req_fifo = new("push_pull_req_fifo", this);
-    end
-  endfunction : build_phase
-
 endclass
diff --git a/hw/dv/sv/push_pull_agent/seq_lib/push_pull_device_seq.sv b/hw/dv/sv/push_pull_agent/seq_lib/push_pull_device_seq.sv
index 04c6dbc..49382e9 100644
--- a/hw/dv/sv/push_pull_agent/seq_lib/push_pull_device_seq.sv
+++ b/hw/dv/sv/push_pull_agent/seq_lib/push_pull_device_seq.sv
@@ -43,7 +43,7 @@
       fork
         forever begin : collect_req
           // We indefinitely poll for any traffic sent from the monitor and store it to a mailbox.
-          p_sequencer.push_pull_req_fifo.get(req);
+          p_sequencer.req_analysis_fifo.get(req);
           req_mailbox.put(req);
         end : collect_req
         forever begin : send_req
diff --git a/hw/ip/keymgr/dv/env/keymgr_env.sv b/hw/ip/keymgr/dv/env/keymgr_env.sv
index a4997fe..228599b 100644
--- a/hw/ip/keymgr/dv/env/keymgr_env.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_env.sv
@@ -29,8 +29,8 @@
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
-    m_keymgr_kmac_agent.monitor.req_port.connect(scoreboard.req_fifo.analysis_export);
-    m_keymgr_kmac_agent.monitor.rsp_port.connect(scoreboard.rsp_fifo.analysis_export);
+    m_keymgr_kmac_agent.monitor.req_analysis_port.connect(scoreboard.req_fifo.analysis_export);
+    m_keymgr_kmac_agent.monitor.analysis_port.connect(scoreboard.rsp_fifo.analysis_export);
   endfunction
 
 endclass
diff --git a/hw/ip/kmac/dv/env/kmac_env.sv b/hw/ip/kmac/dv/env/kmac_env.sv
index 4c89280..636adae 100644
--- a/hw/ip/kmac/dv/env/kmac_env.sv
+++ b/hw/ip/kmac/dv/env/kmac_env.sv
@@ -31,8 +31,8 @@
 
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
-    m_kdf_agent.monitor.req_port.connect(scoreboard.kdf_req_fifo.analysis_export);
-    m_kdf_agent.monitor.rsp_port.connect(scoreboard.kdf_rsp_fifo.analysis_export);
+    m_kdf_agent.monitor.req_analysis_port.connect(scoreboard.kdf_req_fifo.analysis_export);
+    m_kdf_agent.monitor.analysis_port.connect(scoreboard.kdf_rsp_fifo.analysis_export);
 
     virtual_sequencer.kdf_sequencer_h = m_kdf_agent.sequencer;
   endfunction
diff --git a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent.sv b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent.sv
index 7840419..2c1c133 100644
--- a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent.sv
+++ b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent.sv
@@ -4,7 +4,9 @@
 
 class otbn_model_agent extends dv_base_agent #(
   .CFG_T          (otbn_model_agent_cfg),
-  .MONITOR_T      (otbn_model_monitor)
+  .MONITOR_T      (otbn_model_monitor),
+  .DRIVER_T       (otbn_dummy_driver),
+  .SEQUENCER_T    (otbn_dummy_sequencer)
 );
 
   `uvm_component_utils(otbn_model_agent)
diff --git a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent_pkg.sv b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent_pkg.sv
index d4a858f..1671e5c 100644
--- a/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent_pkg.sv
+++ b/hw/ip/otbn/dv/uvm/otbn_model_agent/otbn_model_agent_pkg.sv
@@ -17,6 +17,14 @@
   `include "uvm_macros.svh"
   `include "dv_macros.svh"
 
+  typedef otbn_model_item;
+  typedef otbn_model_agent_cfg;
+  // driver and sequencer are not used in this agent. Create these dummy components to avoid compile
+  // error due to the TLM connection between monitor and sequencer in dv_base_*.
+  // Both TLM fifo/port need to use the same item object (otbn_model_item)
+  typedef dv_base_sequencer #(otbn_model_item, otbn_model_agent_cfg) otbn_dummy_sequencer;
+  typedef dv_base_driver #(otbn_model_item, otbn_model_agent_cfg) otbn_dummy_driver;
+
   // package sources
   `include "otbn_model_item.sv"