[entropy_src/dv] Only monitor HT diagnostics when the DUT is disabled

Once #10227 is resolved, the health test (HT) diagnostic registers will
not spontaneously  self-clear when the entropy_src is disabled.

This is good because previous entropy_src simulations were halting
when these registers are read at the same time as the predictions
for these registers are being updated.

This commit:

- Updates the entropy_src scoreboard to reflect the new behavior of
  these registers.
- Restructures the monitoring of the HT diagnostic registers to only
  happen during disabled periods
- Fixes two minor bugs:
   - Adjusts the predicted delay between RNG data assertion and the
     disablement of the DUT. (1 cycle is now confirmed to be the
     correct value)
   - Properly models the behavior of HT failure counters on overflow

Signed-off-by: Martin Lueker-Boden <martin.lueker-boden@wdc.com>
diff --git a/hw/ip/entropy_src/dv/env/entropy_src_env_cfg.sv b/hw/ip/entropy_src/dv/env/entropy_src_env_cfg.sv
index bbc5270..4ed3a45 100644
--- a/hw/ip/entropy_src/dv/env/entropy_src_env_cfg.sv
+++ b/hw/ip/entropy_src/dv/env/entropy_src_env_cfg.sv
@@ -78,7 +78,7 @@
 
   // Number of clock cycles between a TLUL disable signal, and deassertion
   // of enable on the RNG bus.
-  int  tlul2rng_disable_delay = 2;
+  int  tlul2rng_disable_delay = 1;
 
   // Constraints
   constraint c_regwen {regwen dist {
diff --git a/hw/ip/entropy_src/dv/env/entropy_src_scoreboard.sv b/hw/ip/entropy_src/dv/env/entropy_src_scoreboard.sv
index 0315987..49519fc 100644
--- a/hw/ip/entropy_src/dv/env/entropy_src_scoreboard.sv
+++ b/hw/ip/entropy_src/dv/env/entropy_src_scoreboard.sv
@@ -57,10 +57,11 @@
   uvm_tlm_analysis_fifo#(push_pull_item#(.HostDataWidth(RNG_BUS_WIDTH)))
       rng_fifo;
 
-  // Clearing the enable is a soft form of reset.
+  // Enabling, disabling and reset all have some effect in clearing the state of the DUT
   typedef enum int {
     HardReset,
-    Disable
+    Disable,
+    Enable
   } reset_event_e;
 
   `uvm_component_new
@@ -94,7 +95,7 @@
   // Health check test routines
   //
 
-  task update_repcnts(rng_val_t rng_val);
+  function void update_repcnts(rng_val_t rng_val);
     for (int i = 0; i < RNG_BUS_WIDTH; i++) begin
       if (rng_val[i] == prev_rng_val[i]) begin
         repcnt[i]++;
@@ -110,7 +111,7 @@
     end
     prev_rng_val = rng_val;
     max_repcnt_symbol = (repcnt_symbol > max_repcnt_symbol) ? repcnt_symbol : max_repcnt_symbol;
-  endtask
+  endfunction
 
   // TODO: Revisit after resolution of #9759
   function int calc_adaptp_test(queue_of_rng_val_t window);
@@ -314,8 +315,12 @@
     alert_cnt  =  alert_cnt_field.get_mirrored_value();
 
     if (failure) begin
-      alert_cnt++;
-      fail_total++;
+      if (!&alert_cnt) begin
+        alert_cnt++;
+      end
+      if (!&fail_total) begin
+        fail_total++;
+      end
     end
 
     fmt = "Threshold for \"%s\" test (FIPS? %d): %04h";
@@ -602,10 +607,12 @@
   endfunction
 
   // Clear all relevant prediction variables for
-  // Reset and disable events.
+  // Reset,  disable and enable events.
   function void handle_disable_reset(reset_event_e rst_type);
+    if (rst_type == Enable) begin
+      clear_ht_stat_predictions();
+    end
     threshold_alert_active = 0;
-    clear_ht_stat_predictions();
     seed_idx = 0;
     seed_tl_read_cnt = 0;
     if( rst_type == HardReset ) begin
@@ -622,8 +629,6 @@
     // TODO: should we flush the CSRNG fifo?
     //csrng_fifo.flush();
 
-    // Communicate this event to the process_entropy process
-    // with a possible delay.
     `uvm_info(`gfn, $sformatf("%s Detected", rst_type.name), UVM_MEDIUM)
   endfunction
 
@@ -659,6 +664,7 @@
               dut_pipeline_enabled = 1;
               fork
                 begin
+                  handle_disable_reset(Enable);
                   collect_entropy();
                   handle_disable_reset(Disable);
                 end
diff --git a/hw/ip/entropy_src/dv/env/seq_lib/entropy_src_rng_vseq.sv b/hw/ip/entropy_src/dv/env/seq_lib/entropy_src_rng_vseq.sv
index 21622be..b0d54d8 100644
--- a/hw/ip/entropy_src/dv/env/seq_lib/entropy_src_rng_vseq.sv
+++ b/hw/ip/entropy_src/dv/env/seq_lib/entropy_src_rng_vseq.sv
@@ -151,20 +151,21 @@
     cfg.clk_rst_vif.wait_clks(dly_to_access_intr);
     csr_rd(.ptr(ral.recov_alert_sts.es_main_sm_alert), .value(alert_sts));
     if (alert_sts) begin
+      `uvm_info(`gfn, "Clearing ES SM Alerts", UVM_HIGH)
       `uvm_info(`gfn, "Identified main_sm alert", UVM_HIGH)
+      `DV_CHECK_MEMBER_RANDOMIZE_FATAL(dly_to_access_alert_sts)
+      cfg.clk_rst_vif.wait_clks(dly_to_access_alert_sts);
+      csr_wr(.ptr(ral.conf.enable), .value(prim_mubi_pkg::MuBi4False));
+      csr_wr(.ptr(ral.recov_alert_sts.es_main_sm_alert), .value(1'b1));
       `DV_CHECK_MEMBER_RANDOMIZE_FATAL(do_check_ht_diag)
       if (do_check_ht_diag) begin
+        `DV_CHECK_MEMBER_RANDOMIZE_FATAL(dly_to_access_alert_sts)
+        cfg.clk_rst_vif.wait_clks(dly_to_access_alert_sts);
         // read all health check values
         `uvm_info(`gfn, "Checking_ht_values", UVM_HIGH)
         check_ht_diagnostics();
         `uvm_info(`gfn, "ht value check complete", UVM_HIGH)
       end
-      `DV_CHECK_MEMBER_RANDOMIZE_FATAL(dly_to_access_alert_sts)
-      cfg.clk_rst_vif.wait_clks(dly_to_access_alert_sts);
-      `uvm_info(`gfn, "Clearing ES SM Alerts", UVM_HIGH)
-      csr_wr(.ptr(ral.conf.enable), .value(prim_mubi_pkg::MuBi4False));
-      `uvm_info(`gfn, "DUT disabled", UVM_HIGH)
-      csr_wr(.ptr(ral.recov_alert_sts.es_main_sm_alert), .value(1'b1));
       csr_wr(.ptr(ral.conf.enable), .value(prim_mubi_pkg::MuBi4True));
     end
   endtask
diff --git a/hw/ip/entropy_src/dv/tests/entropy_src_rng_test.sv b/hw/ip/entropy_src/dv/tests/entropy_src_rng_test.sv
index 4f553f1..df2792f 100644
--- a/hw/ip/entropy_src/dv/tests/entropy_src_rng_test.sv
+++ b/hw/ip/entropy_src/dv/tests/entropy_src_rng_test.sv
@@ -17,7 +17,7 @@
     cfg.bypass_window_size          = 384;
     cfg.boot_mode_retry_limit       = 10;
     cfg.entropy_data_reg_enable_pct = 100;
-    cfg.sim_duration                = 10ms;
+    cfg.sim_duration                = 100ms;
     cfg.hard_mtbf                   = 100s;
     cfg.soft_mtbf                   = 7500us;
     cfg.adaptp_sigma_min            = 1.0;