[DV] Enable cov comp creation iff cov is enabled

In our DV base classes (`hw/dv/sv/dv_lib`), the `en_cov` cfg bit is set
to 1 by default, for both, the agents and the env. The original
motivation for this was to enable coverage-driven stimulus generation.
This is something we are not doing at the moment. Even if we decide to
do something like that, it can be enabled on a per test / vseq basis.

This change sets the `en_cov` bit at the env cfg level to 0 and enables
this setting to be retrieved via plusarg in `dv_base_test`. In all env
classes, this cfg setting is then passed on the the downstream agent cfg
objects. This change is applied to `uvmdvgen` env template as well.

In `hw/dv/tools/dvsim/common_modes.hjson` the `+en_cov=1` plusarg is
set, so that if coverage collection is enabled, the coverage collection
component is created (previously, the coverage component was created
regardless of whether the coverage was enabled or not).

With this change, simulations run without coverage collection enabled
should see roughly 10-30% improvement in runtime, which directly impacts
the private CI runtime (which has been inching closer to the 20 min
timeout as more DUTs are added to the regression list).

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/dv/sv/cip_lib/cip_base_env.sv b/hw/dv/sv/cip_lib/cip_base_env.sv
index 9ab62cc..b6604c5 100644
--- a/hw/dv/sv/cip_lib/cip_base_env.sv
+++ b/hw/dv/sv/cip_lib/cip_base_env.sv
@@ -19,25 +19,8 @@
 
   virtual function void build_phase(uvm_phase phase);
     super.build_phase(phase);
-    if (cfg.zero_delays) begin
-      cfg.m_tl_agent_cfg.a_valid_delay_min = 0;
-      cfg.m_tl_agent_cfg.a_valid_delay_max = 0;
-      cfg.m_tl_agent_cfg.d_valid_delay_min = 0;
-      cfg.m_tl_agent_cfg.d_valid_delay_max = 0;
-      cfg.m_tl_agent_cfg.a_ready_delay_min = 0;
-      cfg.m_tl_agent_cfg.a_ready_delay_max = 0;
-      cfg.m_tl_agent_cfg.d_ready_delay_min = 0;
-      cfg.m_tl_agent_cfg.d_ready_delay_max = 0;
 
-      foreach (cfg.m_alert_agent_cfg[i]) begin
-        cfg.m_alert_agent_cfg[i].alert_delay_min = 0;
-        cfg.m_alert_agent_cfg[i].alert_delay_max = 0;
-      end
-
-      if (cfg.has_edn) cfg.m_edn_pull_agent_cfg.zero_delays = 1;
-    end
-
-    // get vifs
+    // Retrieve the virtual interfaces from uvm_config_db.
     if (!uvm_config_db#(intr_vif)::get(this, "", "intr_vif", cfg.intr_vif) &&
         cfg.num_interrupts > 0) begin
       `uvm_fatal(get_full_name(), "failed to get intr_vif from uvm_config_db")
@@ -47,33 +30,54 @@
       `uvm_fatal(get_full_name(), "failed to get devmode_vif from uvm_config_db")
     end
 
-    // create tl agent and set cfg
+    // Create & configure the TL agent.
     m_tl_agent = tl_agent::type_id::create("m_tl_agent", this);
     m_tl_reg_adapter = tl_reg_adapter#()::type_id::create("m_tl_reg_adapter");
     m_tl_reg_adapter.cfg = cfg.m_tl_agent_cfg;
     uvm_config_db#(tl_agent_cfg)::set(this, "m_tl_agent*", "cfg", cfg.m_tl_agent_cfg);
+    cfg.m_tl_agent_cfg.en_cov = cfg.en_cov;
 
-    // create alert agents and set cfgs
+    // Create & configure the alert agents.
     foreach(cfg.list_of_alerts[i]) begin
       string alert_name = cfg.list_of_alerts[i];
       string agent_name = {"m_alert_agent_", alert_name};
       m_alert_agent[alert_name] = alert_esc_agent::type_id::create(agent_name, this);
       uvm_config_db#(alert_esc_agent_cfg)::set(this, agent_name, "cfg",
           cfg.m_alert_agent_cfg[alert_name]);
+      cfg.m_alert_agent_cfg[alert_name].en_cov = cfg.en_cov;
     end
 
-    // create edn pull agent, set cfg and set clk freq
+    // Create and configure the EDN agent if available.
     if (cfg.has_edn) begin
       m_edn_pull_agent = push_pull_agent#(.DeviceDataWidth(EDN_DATA_WIDTH))::type_id::create(
                          "m_edn_pull_agent", this);
       uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(EDN_DATA_WIDTH)))::set(
                      this, "m_edn_pull_agent", "cfg", cfg.m_edn_pull_agent_cfg);
+      cfg.m_edn_pull_agent_cfg.en_cov = cfg.en_cov;
 
       if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", "edn_clk_rst_vif",
           cfg.edn_clk_rst_vif)) begin
         `uvm_fatal(get_full_name(), "failed to get edn_clk_rst_vif from uvm_config_db")
       end
-      cfg.clk_rst_vif.set_freq_mhz(cfg.edn_clk_freq_mhz);
+      // TODO: is this correct?
+      cfg.edn_clk_rst_vif.set_freq_mhz(cfg.edn_clk_freq_mhz);
+    end
+
+    // Pass on the zero_delays setting.
+    if (cfg.zero_delays) begin
+      cfg.m_tl_agent_cfg.a_valid_delay_min = 0;
+      cfg.m_tl_agent_cfg.a_valid_delay_max = 0;
+      cfg.m_tl_agent_cfg.d_valid_delay_min = 0;
+      cfg.m_tl_agent_cfg.d_valid_delay_max = 0;
+      cfg.m_tl_agent_cfg.a_ready_delay_min = 0;
+      cfg.m_tl_agent_cfg.a_ready_delay_max = 0;
+      cfg.m_tl_agent_cfg.d_ready_delay_min = 0;
+      cfg.m_tl_agent_cfg.d_ready_delay_max = 0;
+      foreach (cfg.m_alert_agent_cfg[i]) begin
+        cfg.m_alert_agent_cfg[i].alert_delay_min = 0;
+        cfg.m_alert_agent_cfg[i].alert_delay_max = 0;
+      end
+      if (cfg.has_edn) cfg.m_edn_pull_agent_cfg.zero_delays = 1;
     end
   endfunction
 
diff --git a/hw/dv/sv/cip_lib/cip_base_env_cfg.sv b/hw/dv/sv/cip_lib/cip_base_env_cfg.sv
index 8b1ba58..d973645 100644
--- a/hw/dv/sv/cip_lib/cip_base_env_cfg.sv
+++ b/hw/dv/sv/cip_lib/cip_base_env_cfg.sv
@@ -3,15 +3,15 @@
 // SPDX-License-Identifier: Apache-2.0
 
 class cip_base_env_cfg #(type RAL_T = dv_base_reg_block) extends dv_base_env_cfg #(RAL_T);
-  // ext component cfgs
-  rand tl_agent_cfg        m_tl_agent_cfg;
-  alert_esc_agent_cfg      m_alert_agent_cfg[string];
+  // Downstream agent cfg objects.
+  rand tl_agent_cfg   m_tl_agent_cfg;
+  alert_esc_agent_cfg m_alert_agent_cfg[string];
   push_pull_agent_cfg#(.DeviceDataWidth(EDN_DATA_WIDTH)) m_edn_pull_agent_cfg;
 
-  // edn clk freq
+  // EDN clk freq setting, if EDN is present.
   rand clk_freq_mhz_e edn_clk_freq_mhz;
 
-  // common interfaces - intrrupts, alerts, edn clk
+  // Common interfaces - intrrupts, alerts, edn clk.
   intr_vif    intr_vif;
   devmode_vif devmode_vif;
   virtual clk_rst_if  edn_clk_rst_vif;
@@ -38,18 +38,17 @@
 
   virtual function void initialize(bit [BUS_AW-1:0] csr_base_addr = '1);
     super.initialize(csr_base_addr);
-    // create tl agent config obj
+    // Create downstream agent cfg objects.
     m_tl_agent_cfg = tl_agent_cfg::type_id::create("m_tl_agent_cfg");
     m_tl_agent_cfg.if_mode = dv_utils_pkg::Host;
-    // host can't support device same cycle response and host may drive d_ready=0 when a_valid=1
+    // TL host cannot support device same cycle response. Host may drive d_ready=0 when a_valid=1.
     m_tl_agent_cfg.host_can_stall_rsp_when_a_valid_high = $urandom_range(0, 1);
 
     if (list_of_alerts.size() > 0) begin
       check_alert_configs();
-
       foreach(list_of_alerts[i]) begin
         string alert_name = list_of_alerts[i];
-        // create alert_esc_agent_cfg if the module has alerts
+        // TODO: fix obj name
         m_alert_agent_cfg[alert_name] = alert_esc_agent_cfg::type_id::create("m_alert_agent_cfg");
         `DV_CHECK_RANDOMIZE_FATAL(m_alert_agent_cfg[alert_name])
         m_alert_agent_cfg[alert_name].if_mode = dv_utils_pkg::Device;
@@ -72,7 +71,7 @@
     dv_base_reg_block sub_blks[$];
     ral.get_dv_base_reg_blocks(sub_blks);
 
-    // for top-level, check alert_configs by each sub-block that triggers alerts
+    // For top-level, check alert_configs by each sub-block that triggers alerts.
     if (sub_blks.size() > 0) begin
       foreach(sub_blks[i]) begin
         // top-level alert name is consist of ${block_name}_${alert_name}
@@ -89,28 +88,24 @@
         if (alerts_q.size() > 0) check_alert_configs_by_block(sub_blks[i], alerts_q);
       end
     end else begin
-      // for IP level testbench, directly use ral as dv_base_reg_block object
+      // For IP level testbench, directly use ral as dv_base_reg_block object.
       string alerts_q[$] = list_of_alerts;
       check_alert_configs_by_block(ral, alerts_q);
     end
   endfunction
 
-  // this function checks if hardcoded cfg.list_of_alerts array matches the information in
-  // corresponding alert_test register
+  // Checks if the hardcoded cfg.list_of_alerts array matches the information in corresponding
+  // alert_test register.
   virtual function void check_alert_configs_by_block(dv_base_reg_block blk,
                                                      const ref string  alert_names[$]);
     dv_base_reg alert_test_csr;
     alert_test_csr = blk.get_dv_base_reg_by_name("alert_test");
-
-    // check alert_test csr exists
     `DV_CHECK_NE_FATAL(alert_test_csr, null,
                        $sformatf("cannot find alert_test csr in %0s", blk.get_name()))
 
-    // check number of field matches number of alert name in the list
     `DV_CHECK_EQ(alert_test_csr.get_n_used_bits(), alert_names.size(),
                  "alert_test field number and list_of_alerts size mismatch")
 
-    // check if alert name matches alert_test field name
     foreach(alert_names[i]) begin
       uvm_reg_field alert_test_field = blk.get_field_by_name(alert_names[i]);
       `DV_CHECK_NE_FATAL(alert_test_field, null, $sformatf("cannot find field %s", alert_names[i]))
diff --git a/hw/dv/sv/dv_lib/dv_base_env_cfg.sv b/hw/dv/sv/dv_lib/dv_base_env_cfg.sv
index 27afc14..717f1db 100644
--- a/hw/dv/sv/dv_lib/dv_base_env_cfg.sv
+++ b/hw/dv/sv/dv_lib/dv_base_env_cfg.sv
@@ -8,9 +8,10 @@
   bit en_scb            = 1; // can be changed at run-time
   bit en_scb_tl_err_chk = 1;
   bit en_scb_mem_chk    = 1;
-  bit en_cov            = 1;
+  bit en_cov            = 0; // Enable via plusarg, only if coverage collection is turned on.
   bit has_ral           = 1;
   bit under_reset       = 0;
+  bit is_initialized;        // Indicates that the initialize() method has been called.
 
   // bit to configure all uvcs with zero delays to create high bw test
   rand bit zero_delays;
@@ -40,8 +41,12 @@
 
   `uvm_object_new
 
+  function void pre_randomize();
+    `DV_CHECK_FATAL(is_initialized, "Please invoke initialize() before randomizing this object.")
+  endfunction
+
   virtual function void initialize(bit [bus_params_pkg::BUS_AW-1:0] csr_base_addr = '1);
-    import bus_params_pkg::*;
+    is_initialized = 1'b1;
 
     // build the ral model
     if (has_ral) begin
@@ -63,7 +68,7 @@
       // correctly handle the case where a bus address is narrower than a uvm_reg_addr_t).
       base_addr = (&csr_base_addr ?
                    {`UVM_REG_ADDR_WIDTH{1'b1}} :
-                   {{(`UVM_REG_ADDR_WIDTH - BUS_AW){1'b0}}, csr_base_addr});
+                   {{(`UVM_REG_ADDR_WIDTH - bus_params_pkg::BUS_AW){1'b0}}, csr_base_addr});
       ral.set_base_addr(base_addr);
 
       // Get list of valid csr addresses (useful in seq to randomize addr as well as in scb checks)
diff --git a/hw/dv/sv/dv_lib/dv_base_test.sv b/hw/dv/sv/dv_lib/dv_base_test.sv
index 5435b82..fc0e92a 100644
--- a/hw/dv/sv/dv_lib/dv_base_test.sv
+++ b/hw/dv/sv/dv_lib/dv_base_test.sv
@@ -25,17 +25,20 @@
 
     env = ENV_T::type_id::create("env", this);
     cfg = CFG_T::type_id::create("cfg", this);
-    // don't add args for initialize. Use default value instead
     cfg.initialize();
     `DV_CHECK_RANDOMIZE_FATAL(cfg)
     uvm_config_db#(CFG_T)::set(this, "env", "cfg", cfg);
 
-    // knob to en/dis scb (enabled by default)
+    // Enable scoreboard (and sub-scoreboard checks) via plusarg.
     void'($value$plusargs("en_scb=%0b", cfg.en_scb));
     void'($value$plusargs("en_scb_tl_err_chk=%0b", cfg.en_scb_tl_err_chk));
     void'($value$plusargs("en_scb_mem_chk=%0b", cfg.en_scb_mem_chk));
-    // knob to cfg all agents with zero delays
+
+    // Enable fastest design performance by configuring zero delays in all agents.
     void'($value$plusargs("zero_delays=%0b", cfg.zero_delays));
+
+    // Enable coverage collection.
+    void'($value$plusargs("en_cov=%0b", cfg.en_cov));
   endfunction : build_phase
 
   virtual function void end_of_elaboration_phase(uvm_phase phase);
@@ -53,13 +56,15 @@
     if (run_test_seq) begin
       run_seq(test_seq_s, phase);
     end
-    // TODO: add hook for end of test checking
+    // TODO: add hook for end of test checking.
   endtask : run_phase
 
   virtual task run_seq(string test_seq_s, uvm_phase phase);
     uvm_sequence test_seq = create_seq_by_name(test_seq_s);
 
-    // provide virtual_sequencer earlier, so we may use the p_sequencer in constraint
+    // Setting the sequencer before the sequence is randomized is mandatory. We do this so that the
+    // sequence has access to the UVM environment's cfg handle via the p_sequencer handle within the
+    // randomization constraints.
     test_seq.set_sequencer(env.virtual_sequencer);
     `DV_CHECK_RANDOMIZE_FATAL(test_seq)
 
@@ -70,7 +75,7 @@
     `uvm_info(`gfn, {"Finished test sequence ", test_seq_s}, UVM_MEDIUM)
   endtask
 
-  // TODO: add default report_phase implementation
+  // TODO: Add default report_phase implementation.
 
 endclass : dv_base_test
 
diff --git a/hw/dv/tools/dvsim/common_modes.hjson b/hw/dv/tools/dvsim/common_modes.hjson
index 6730dd1..16b9e68 100644
--- a/hw/dv/tools/dvsim/common_modes.hjson
+++ b/hw/dv/tools/dvsim/common_modes.hjson
@@ -16,6 +16,9 @@
       name: cov
       is_sim_mode: 1
       en_build_modes: ["{tool}_cov"]
+      // This plusarg is retrieved in `hw/dv/sv/dv_lib/dv_base_test.sv`. If not set, the coverage
+      // collection components are not created.
+      run_opts: ["+en_cov=1"]
     }
     {
       name: profile
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_env.sv b/hw/ip/alert_handler/dv/env/alert_handler_env.sv
index 8fe8df1..9db70bb 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_env.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_env.sv
@@ -25,6 +25,7 @@
           $sformatf("alert_host_agent[%0d]", i), this);
       uvm_config_db#(alert_esc_agent_cfg)::set(this,
           $sformatf("alert_host_agent[%0d]", i), "cfg", cfg.alert_host_cfg[i]);
+      cfg.alert_host_cfg[i].en_cov = cfg.en_cov;
       cfg.alert_host_cfg[i].clk_freq_mhz = int'(cfg.clk_freq_mhz);
     end
     // build escalator agents
@@ -35,6 +36,7 @@
           $sformatf("esc_device_agent[%0d]", i), this);
       uvm_config_db#(alert_esc_agent_cfg)::set(this,
           $sformatf("esc_device_agent[%0d]", i), "cfg", cfg.esc_device_cfg[i]);
+      cfg.esc_device_cfg[i].en_cov = cfg.en_cov;
     end
     // get vifs
     if (!uvm_config_db#(entropy_vif)::get(this, "", "entropy_vif", cfg.entropy_vif)) begin
diff --git a/hw/ip/csrng/dv/env/csrng_env.sv b/hw/ip/csrng/dv/env/csrng_env.sv
index 727a4cf..4c497d1 100644
--- a/hw/ip/csrng/dv/env/csrng_env.sv
+++ b/hw/ip/csrng/dv/env/csrng_env.sv
@@ -24,11 +24,13 @@
     uvm_config_db#(push_pull_agent_cfg#(.HostDataWidth(entropy_src_pkg::FIPS_CSRNG_BUS_WIDTH)))
                           ::set(this, "m_entropy_src_agent*", "cfg", cfg.m_entropy_src_agent_cfg);
     cfg.m_entropy_src_agent_cfg.agent_type = push_pull_agent_pkg::PullAgent;
-    cfg.m_entropy_src_agent_cfg.if_mode    = dv_utils_pkg::Device;
+    cfg.m_entropy_src_agent_cfg.if_mode = dv_utils_pkg::Device;
+    cfg.m_entropy_src_agent_cfg.en_cov = cfg.en_cov;
 
     m_csrng_agent = csrng_agent::type_id::create("m_csrng_agent", this);
     uvm_config_db#(csrng_agent_cfg)::set(this, "m_csrng_agent*", "cfg", cfg.m_csrng_agent_cfg);
     cfg.m_csrng_agent_cfg.if_mode = dv_utils_pkg::Host;
+    cfg.m_csrng_agent_cfg.en_cov = cfg.en_cov;
 
     if (!uvm_config_db#(virtual pins_if)::get(this, "", "efuse_sw_app_enable_vif",
          cfg.efuse_sw_app_enable_vif)) begin
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
index 64cca42..874b4f8 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env.sv
@@ -47,6 +47,7 @@
     m_eflash_tl_reg_adapter = tl_reg_adapter#()::type_id::create("m_eflash_tl_reg_adapter");
     uvm_config_db#(tl_agent_cfg)::set(
         this, "m_eflash_tl_agent*", "cfg", cfg.m_eflash_tl_agent_cfg);
+    cfg.m_eflash_tl_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/i2c/dv/env/i2c_env.sv b/hw/ip/i2c/dv/env/i2c_env.sv
index 5d91633..0f3cc0d 100644
--- a/hw/ip/i2c/dv/env/i2c_env.sv
+++ b/hw/ip/i2c/dv/env/i2c_env.sv
@@ -18,6 +18,7 @@
     super.build_phase(phase);
     m_i2c_agent = i2c_agent::type_id::create("m_i2c_agent", this);
     uvm_config_db#(i2c_agent_cfg)::set(this, "m_i2c_agent*", "cfg", cfg.m_i2c_agent_cfg);
+    cfg.m_i2c_agent_cfg.en_cov = cfg.en_cov;
   endfunction : build_phase
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/keymgr/dv/env/keymgr_env.sv b/hw/ip/keymgr/dv/env/keymgr_env.sv
index bd9eb1c..a4997fe 100644
--- a/hw/ip/keymgr/dv/env/keymgr_env.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_env.sv
@@ -21,7 +21,7 @@
     m_keymgr_kmac_agent = keymgr_kmac_agent::type_id::create("m_keymgr_kmac_agent", this);
     uvm_config_db#(keymgr_kmac_agent_cfg)::set(this, "m_keymgr_kmac_agent", "cfg",
                                              cfg.m_keymgr_kmac_agent_cfg);
-
+    cfg.m_keymgr_kmac_agent_cfg.en_cov = cfg.en_cov;
     if (!uvm_config_db#(keymgr_vif)::get(this, "", "keymgr_vif", cfg.keymgr_vif)) begin
       `uvm_fatal(`gfn, "failed to get keymgr_vif from uvm_config_db")
     end
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
index 424b170..8d74797 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_env.sv
@@ -33,23 +33,29 @@
     m_esc_wipe_secrets_agent = alert_esc_agent::type_id::create("m_esc_wipe_secrets_agent", this);
     uvm_config_db#(alert_esc_agent_cfg)::set(this, "m_esc_wipe_secrets_agent", "cfg",
                                              cfg.m_esc_wipe_secrets_agent_cfg);
+    cfg.m_esc_wipe_secrets_agent_cfg.en_cov = cfg.en_cov;
+
     m_esc_scrap_state_agent = alert_esc_agent::type_id::create("m_esc_scrap_state_agent", this);
     uvm_config_db#(alert_esc_agent_cfg)::set(this, "m_esc_scrap_state_agent", "cfg",
                                              cfg.m_esc_scrap_state_agent_cfg);
+    cfg.m_esc_scrap_state_agent_cfg.en_cov = cfg.en_cov;
 
     m_jtag_agent = jtag_agent::type_id::create("m_jtag_agent", this);
     uvm_config_db#(jtag_agent_cfg)::set(this, "m_jtag_agent", "cfg", cfg.m_jtag_agent_cfg);
+    cfg.m_jtag_agent_cfg.en_cov = cfg.en_cov;
 
     m_otp_prog_pull_agent = push_pull_agent#(.HostDataWidth(OTP_PROG_HDATA_WIDTH),
         .DeviceDataWidth(OTP_PROG_DDATA_WIDTH))::type_id::create("m_otp_prog_pull_agent", this);
     uvm_config_db#(push_pull_agent_cfg#(.HostDataWidth(OTP_PROG_HDATA_WIDTH),
         .DeviceDataWidth(OTP_PROG_DDATA_WIDTH)))::set(this, "m_otp_prog_pull_agent", "cfg",
         cfg.m_otp_prog_pull_agent_cfg);
+    cfg.m_otp_prog_pull_agent_cfg.en_cov = cfg.en_cov;
 
     m_otp_token_pull_agent = push_pull_agent#(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth))::type_id::
         create("m_otp_token_pull_agent", this);
     uvm_config_db#(push_pull_agent_cfg#(.HostDataWidth(lc_ctrl_pkg::LcTokenWidth)))::set(this,
         "m_otp_token_pull_agent", "cfg", cfg.m_otp_token_pull_agent_cfg);
+    cfg.m_otp_token_pull_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/otbn/dv/uvm/env/otbn_env.sv b/hw/ip/otbn/dv/uvm/env/otbn_env.sv
index 9161166..b827644 100644
--- a/hw/ip/otbn/dv/uvm/env/otbn_env.sv
+++ b/hw/ip/otbn/dv/uvm/env/otbn_env.sv
@@ -22,6 +22,7 @@
 
     model_agent = otbn_model_agent::type_id::create("model_agent", this);
     uvm_config_db#(otbn_model_agent_cfg)::set(this, "model_agent*", "cfg", cfg.model_agent_cfg);
+    cfg.model_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/pattgen/dv/env/pattgen_env.sv b/hw/ip/pattgen/dv/env/pattgen_env.sv
index afc0195..812a7f5 100644
--- a/hw/ip/pattgen/dv/env/pattgen_env.sv
+++ b/hw/ip/pattgen/dv/env/pattgen_env.sv
@@ -18,6 +18,7 @@
     m_pattgen_agent = pattgen_agent::type_id::create("m_pattgen_agent", this);
     uvm_config_db#(pattgen_agent_cfg)::set(this, "m_pattgen_agent*", "cfg",
                                            cfg.m_pattgen_agent_cfg);
+    cfg.m_pattgen_agent_cfg.en_cov = cfg.en_cov;
   endfunction : build_phase
 
   virtual function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/rv_dm/dv/env/rv_dm_env.sv b/hw/ip/rv_dm/dv/env/rv_dm_env.sv
index b7a2384..11e44d2 100644
--- a/hw/ip/rv_dm/dv/env/rv_dm_env.sv
+++ b/hw/ip/rv_dm/dv/env/rv_dm_env.sv
@@ -46,14 +46,17 @@
     // create components
     m_jtag_agent = jtag_agent::type_id::create("m_jtag_agent", this);
     uvm_config_db#(jtag_agent_cfg)::set(this, "m_jtag_agent*", "cfg", cfg.m_jtag_agent_cfg);
+    cfg.m_jtag_agent_cfg.en_cov = cfg.en_cov;
 
     m_tl_host_agent = tl_agent::type_id::create("m_tl_host_agent", this);
     uvm_config_db#(tl_agent_cfg)::set(this, "m_tl_host_agent*", "cfg",
                                       cfg.m_tl_host_agent_cfg);
+    cfg.m_tl_host_agent_cfg.en_cov = cfg.en_cov;
 
     m_tl_device_agent = tl_agent::type_id::create("m_tl_device_agent", this);
     uvm_config_db#(tl_agent_cfg)::set(this, "m_tl_device_agent*", "cfg",
                                       cfg.m_tl_device_agent_cfg);
+    cfg.m_tl_device_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/spi_device/dv/env/spi_device_env.sv b/hw/ip/spi_device/dv/env/spi_device_env.sv
index 166df9d..4531ecd 100644
--- a/hw/ip/spi_device/dv/env/spi_device_env.sv
+++ b/hw/ip/spi_device/dv/env/spi_device_env.sv
@@ -19,6 +19,7 @@
     // build child components
     m_spi_agent = spi_agent::type_id::create("m_spi_agent", this);
     uvm_config_db#(spi_agent_cfg)::set(this, "m_spi_agent*", "cfg", cfg.m_spi_agent_cfg);
+    cfg.m_spi_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/sram_ctrl/dv/env/sram_ctrl_env.sv b/hw/ip/sram_ctrl/dv/env/sram_ctrl_env.sv
index f3198bd..fab5b7b 100644
--- a/hw/ip/sram_ctrl/dv/env/sram_ctrl_env.sv
+++ b/hw/ip/sram_ctrl/dv/env/sram_ctrl_env.sv
@@ -42,13 +42,14 @@
     m_sram_tl_agent = tl_agent::type_id::create("m_sram_tl_agent", this);
     uvm_config_db#(tl_agent_cfg)::set(this,
       "m_sram_tl_agent", "cfg", cfg.m_sram_cfg);
+    cfg.m_sram_cfg.en_cov = cfg.en_cov;
 
     // Build the KDI agent
     m_kdi_agent = push_pull_agent#(.DeviceDataWidth(KDI_DATA_SIZE))::type_id
       ::create("m_kdi_agent", this);
     uvm_config_db#(push_pull_agent_cfg#(.DeviceDataWidth(KDI_DATA_SIZE)))::set(
       this, "m_kdi_agent", "cfg", cfg.m_kdi_cfg);
-
+    cfg.m_kdi_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/tlul/generic_dv/env/xbar_env.sv b/hw/ip/tlul/generic_dv/env/xbar_env.sv
index 0092255..d198eee 100644
--- a/hw/ip/tlul/generic_dv/env/xbar_env.sv
+++ b/hw/ip/tlul/generic_dv/env/xbar_env.sv
@@ -28,6 +28,7 @@
                       $sformatf("%0s_agent", xbar_hosts[i].host_name), this);
       uvm_config_db#(tl_agent_cfg)::set(this,
         $sformatf("*%0s*", xbar_hosts[i].host_name),"cfg", cfg.host_agent_cfg[i]);
+      cfg.host_agent_cfg[i].en_cov = cfg.en_cov;
     end
     device_agent = new[cfg.num_devices];
     foreach (device_agent[i]) begin
@@ -35,6 +36,7 @@
                       $sformatf("%0s_agent", xbar_devices[i].device_name), this);
       uvm_config_db#(tl_agent_cfg)::set(this,
         $sformatf("*%0s*", xbar_devices[i].device_name), "cfg", cfg.device_agent_cfg[i]);
+      cfg.device_agent_cfg[i].en_cov = cfg.en_cov;
     end
 
     // this clock isn't connected to design but only used for TB, like measure timeout, drive long
diff --git a/hw/ip/tlul/generic_dv/env/xbar_env_cfg.sv b/hw/ip/tlul/generic_dv/env/xbar_env_cfg.sv
index 8e271a2..c0f5570 100644
--- a/hw/ip/tlul/generic_dv/env/xbar_env_cfg.sv
+++ b/hw/ip/tlul/generic_dv/env/xbar_env_cfg.sv
@@ -41,6 +41,7 @@
   `uvm_object_new
 
   virtual function void initialize(bit [TL_AW-1:0] csr_base_addr = '1);
+    is_initialized = 1'b1;
     has_ral = 0; // no csr in xbar
     // Host TL agent cfg
     num_hosts             = xbar_hosts.size();
diff --git a/hw/ip/uart/dv/env/uart_env.sv b/hw/ip/uart/dv/env/uart_env.sv
index 823a74b..e1829bf 100644
--- a/hw/ip/uart/dv/env/uart_env.sv
+++ b/hw/ip/uart/dv/env/uart_env.sv
@@ -17,6 +17,7 @@
 
     m_uart_agent = uart_agent::type_id::create("m_uart_agent", this);
     uvm_config_db#(uart_agent_cfg)::set(this, "m_uart_agent*", "cfg", cfg.m_uart_agent_cfg);
+    cfg.m_uart_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/hw/ip/usbdev/dv/env/usbdev_env.sv b/hw/ip/usbdev/dv/env/usbdev_env.sv
index 21fd26a..3acd134 100644
--- a/hw/ip/usbdev/dv/env/usbdev_env.sv
+++ b/hw/ip/usbdev/dv/env/usbdev_env.sv
@@ -26,6 +26,7 @@
     // create components
     m_usb20_agent = usb20_agent::type_id::create("m_usb20_agent", this);
     uvm_config_db#(usb20_agent_cfg)::set(this, "m_usb20_agent*", "cfg", cfg.m_usb20_agent_cfg);
+    cfg.m_usb20_agent_cfg.en_cov = cfg.en_cov;
   endfunction
 
   function void connect_phase(uvm_phase phase);
diff --git a/util/uvmdvgen/env.sv.tpl b/util/uvmdvgen/env.sv.tpl
index 230a612..cb2f185 100644
--- a/util/uvmdvgen/env.sv.tpl
+++ b/util/uvmdvgen/env.sv.tpl
@@ -28,6 +28,7 @@
     // create components
     m_${agent}_agent = ${agent}_agent::type_id::create("m_${agent}_agent", this);
     uvm_config_db#(${agent}_agent_cfg)::set(this, "m_${agent}_agent*", "cfg", cfg.m_${agent}_agent_cfg);
+    cfg.m_${agent}_agent_cfg.en_cov = cfg.en_cov;
 % endfor
   endfunction