[dv/alert_handler] Fix regression ping timeout error

Alert handler scb has a ping timeout checker to make sure the LFSR
functions correctly.
However, in regression there are some small timeout error because the
esc pings are ignored due to real escalation reqs come at the same time.
To avoid this issue, this PR directly probes design ping request signal.

Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/ip_templates/alert_handler/dv/env/alert_handler_if.sv b/hw/ip_templates/alert_handler/dv/env/alert_handler_if.sv
index 763833d..d585864 100644
--- a/hw/ip_templates/alert_handler/dv/env/alert_handler_if.sv
+++ b/hw/ip_templates/alert_handler/dv/env/alert_handler_if.sv
@@ -8,10 +8,14 @@
   import alert_pkg::*;
   import prim_mubi_pkg::*;
   import cip_base_pkg::*;
+  import alert_handler_env_pkg::*;
 
   mubi4_t [NLpg-1:0] lpg_cg_en;
   mubi4_t [NLpg-1:0] lpg_rst_en;
 
+  logic [NUM_ALERTS-1:0] alert_ping_reqs;
+  logic [NUM_ESCS-1:0]   esc_ping_reqs;
+
   string msg_id = "alert_handler_if";
 
   function automatic void init();
diff --git a/hw/ip_templates/alert_handler/dv/env/alert_handler_scoreboard.sv b/hw/ip_templates/alert_handler/dv/env/alert_handler_scoreboard.sv
index 29f767a..596391e 100644
--- a/hw/ip_templates/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/ip_templates/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -43,7 +43,7 @@
 
   bit [NUM_ALERT_CLASSES-1:0] crashdump_triggered = 0;
 
-  bit ping_triggered, ping_timer_en;
+  bit ping_timer_en;
 
   // TLM agent fifos
   uvm_tlm_analysis_fifo #(alert_esc_seq_item) alert_fifo[NUM_ALERTS];
@@ -99,7 +99,6 @@
             `DV_CHECK(alert_en, $sformatf("alert %0s ping triggered but not enabled", index))
             `DV_CHECK((`gmv(ral.alert_regwen[index]) == 0),
                       $sformatf("alert %0s ping triggered but not locked", index))
-            ping_triggered = 1;
           end
 
           if (alert_en) begin
@@ -144,7 +143,6 @@
             if (loc_alert_en) process_alert_sig(index, 1, LocalEscIntFail);
           // escalation ping timeout
           end else if (act_item.alert_esc_type == AlertEscPingTrans) begin
-            ping_triggered = 1;
             if (act_item.ping_timeout) begin
               bit loc_alert_en = ral.loc_alert_en_shadowed[LocalEscPingFail].get_mirrored_value();
               if (loc_alert_en) begin
@@ -496,7 +494,6 @@
           begin
             check_ping_triggered_cycles();
             num_checked_pings++;
-            ping_triggered = 0;
             if (cfg.en_cov) cov.num_checked_pings_cg.sample(num_checked_pings);
           end
         join_any
@@ -512,24 +509,24 @@
   // can not guarantee the random alert index is valid (exists), enabld, and locked.
   // However, esc ping timer should are always expected to trigger.
   // So the max wait time is 'hFFFF*2.
+  // This task also used the probed design signal instead of detected ping requests from monitor.
+  // Because if esc ping request and real esc request come at the same time, design will ignore the
+  // ping requests. But the probed signal will still set to 1.
   virtual task check_ping_triggered_cycles();
     int ping_wait_cycs;
-    fork begin : isolation_fork
-      fork
-        begin
-          while (ping_wait_cycs <= MAX_PING_WAIT_CYCLES * 2) begin
-            cfg.clk_rst_vif.wait_clks(1);
-            ping_wait_cycs++;
-          end
-          `uvm_error(`gfn, "Timeout occured waiting for a ping.");
-        end
-        begin
-          wait(ping_triggered);
-        end
-      join_any
-      disable fork;
-    end join
+    while (ping_wait_cycs <= MAX_PING_WAIT_CYCLES * 2) begin
+      if (cfg.alert_handler_vif.alert_ping_reqs > 0) break;
+      if (cfg.alert_handler_vif.esc_ping_reqs > 0) break;
+      cfg.clk_rst_vif.wait_clks(1);
+      ping_wait_cycs++;
+    end
+    if (ping_wait_cycs > MAX_PING_WAIT_CYCLES * 2) begin
+      `uvm_error(`gfn, "Timeout occured waiting for a ping.");
+    end
     if (cfg.en_cov) cov.cycles_between_pings_cg.sample(ping_wait_cycs);
+
+    // Wait for ping request to finish to avoid infinite loop.
+    wait (cfg.alert_handler_vif.alert_ping_reqs == 0 && cfg.alert_handler_vif.esc_ping_reqs == 0);
   endtask
 
   virtual task check_crashdump();
diff --git a/hw/ip_templates/alert_handler/dv/tb/tb.sv b/hw/ip_templates/alert_handler/dv/tb/tb.sv
index 69de1be..2687b98 100644
--- a/hw/ip_templates/alert_handler/dv/tb/tb.sv
+++ b/hw/ip_templates/alert_handler/dv/tb/tb.sv
@@ -46,19 +46,21 @@
     assign alert_host_if[k].alert_rx.ack_n  = alert_rx[k].ack_n;
     assign alert_host_if[k].alert_rx.ping_p = alert_rx[k].ping_p;
     assign alert_host_if[k].alert_rx.ping_n = alert_rx[k].ping_n;
+    assign alert_handler_if.alert_ping_reqs[k] = dut.gen_alerts[k].u_alert_receiver.ping_req_i;
     initial begin
       uvm_config_db#(virtual alert_esc_if)::set(null, $sformatf("*.env.alert_host_agent[%0d]", k),
                                                 "vif", alert_host_if[k]);
     end
   end
 
+
   for (genvar k = 0; k < NUM_ESCS; k++) begin : gen_esc_if
     assign esc_rx[k].resp_p = esc_device_if[k].esc_rx.resp_p;
     assign esc_rx[k].resp_n = esc_device_if[k].esc_rx.resp_n;
     assign esc_device_if[k].esc_tx.esc_p = esc_tx[k].esc_p;
     assign esc_device_if[k].esc_tx.esc_n = esc_tx[k].esc_n;
-    // TODO: add assertions to check the probed signal
     assign probe_if[k].esc_en = dut.esc_sig_req[k];
+    assign alert_handler_if.esc_ping_reqs[k] = dut.gen_esc_sev[k].u_esc_sender.ping_req_i;
     initial begin
       uvm_config_db#(virtual alert_esc_if)::set(null, $sformatf("*.env.esc_device_agent[%0d]", k),
                                                 "vif", esc_device_if[k]);
diff --git a/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_if.sv b/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_if.sv
index 763833d..d585864 100644
--- a/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_if.sv
+++ b/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_if.sv
@@ -8,10 +8,14 @@
   import alert_pkg::*;
   import prim_mubi_pkg::*;
   import cip_base_pkg::*;
+  import alert_handler_env_pkg::*;
 
   mubi4_t [NLpg-1:0] lpg_cg_en;
   mubi4_t [NLpg-1:0] lpg_rst_en;
 
+  logic [NUM_ALERTS-1:0] alert_ping_reqs;
+  logic [NUM_ESCS-1:0]   esc_ping_reqs;
+
   string msg_id = "alert_handler_if";
 
   function automatic void init();
diff --git a/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_scoreboard.sv b/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_scoreboard.sv
index 29f767a..596391e 100644
--- a/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/top_earlgrey/ip_autogen/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -43,7 +43,7 @@
 
   bit [NUM_ALERT_CLASSES-1:0] crashdump_triggered = 0;
 
-  bit ping_triggered, ping_timer_en;
+  bit ping_timer_en;
 
   // TLM agent fifos
   uvm_tlm_analysis_fifo #(alert_esc_seq_item) alert_fifo[NUM_ALERTS];
@@ -99,7 +99,6 @@
             `DV_CHECK(alert_en, $sformatf("alert %0s ping triggered but not enabled", index))
             `DV_CHECK((`gmv(ral.alert_regwen[index]) == 0),
                       $sformatf("alert %0s ping triggered but not locked", index))
-            ping_triggered = 1;
           end
 
           if (alert_en) begin
@@ -144,7 +143,6 @@
             if (loc_alert_en) process_alert_sig(index, 1, LocalEscIntFail);
           // escalation ping timeout
           end else if (act_item.alert_esc_type == AlertEscPingTrans) begin
-            ping_triggered = 1;
             if (act_item.ping_timeout) begin
               bit loc_alert_en = ral.loc_alert_en_shadowed[LocalEscPingFail].get_mirrored_value();
               if (loc_alert_en) begin
@@ -496,7 +494,6 @@
           begin
             check_ping_triggered_cycles();
             num_checked_pings++;
-            ping_triggered = 0;
             if (cfg.en_cov) cov.num_checked_pings_cg.sample(num_checked_pings);
           end
         join_any
@@ -512,24 +509,24 @@
   // can not guarantee the random alert index is valid (exists), enabld, and locked.
   // However, esc ping timer should are always expected to trigger.
   // So the max wait time is 'hFFFF*2.
+  // This task also used the probed design signal instead of detected ping requests from monitor.
+  // Because if esc ping request and real esc request come at the same time, design will ignore the
+  // ping requests. But the probed signal will still set to 1.
   virtual task check_ping_triggered_cycles();
     int ping_wait_cycs;
-    fork begin : isolation_fork
-      fork
-        begin
-          while (ping_wait_cycs <= MAX_PING_WAIT_CYCLES * 2) begin
-            cfg.clk_rst_vif.wait_clks(1);
-            ping_wait_cycs++;
-          end
-          `uvm_error(`gfn, "Timeout occured waiting for a ping.");
-        end
-        begin
-          wait(ping_triggered);
-        end
-      join_any
-      disable fork;
-    end join
+    while (ping_wait_cycs <= MAX_PING_WAIT_CYCLES * 2) begin
+      if (cfg.alert_handler_vif.alert_ping_reqs > 0) break;
+      if (cfg.alert_handler_vif.esc_ping_reqs > 0) break;
+      cfg.clk_rst_vif.wait_clks(1);
+      ping_wait_cycs++;
+    end
+    if (ping_wait_cycs > MAX_PING_WAIT_CYCLES * 2) begin
+      `uvm_error(`gfn, "Timeout occured waiting for a ping.");
+    end
     if (cfg.en_cov) cov.cycles_between_pings_cg.sample(ping_wait_cycs);
+
+    // Wait for ping request to finish to avoid infinite loop.
+    wait (cfg.alert_handler_vif.alert_ping_reqs == 0 && cfg.alert_handler_vif.esc_ping_reqs == 0);
   endtask
 
   virtual task check_crashdump();
diff --git a/hw/top_earlgrey/ip_autogen/alert_handler/dv/tb/tb.sv b/hw/top_earlgrey/ip_autogen/alert_handler/dv/tb/tb.sv
index 69de1be..2687b98 100644
--- a/hw/top_earlgrey/ip_autogen/alert_handler/dv/tb/tb.sv
+++ b/hw/top_earlgrey/ip_autogen/alert_handler/dv/tb/tb.sv
@@ -46,19 +46,21 @@
     assign alert_host_if[k].alert_rx.ack_n  = alert_rx[k].ack_n;
     assign alert_host_if[k].alert_rx.ping_p = alert_rx[k].ping_p;
     assign alert_host_if[k].alert_rx.ping_n = alert_rx[k].ping_n;
+    assign alert_handler_if.alert_ping_reqs[k] = dut.gen_alerts[k].u_alert_receiver.ping_req_i;
     initial begin
       uvm_config_db#(virtual alert_esc_if)::set(null, $sformatf("*.env.alert_host_agent[%0d]", k),
                                                 "vif", alert_host_if[k]);
     end
   end
 
+
   for (genvar k = 0; k < NUM_ESCS; k++) begin : gen_esc_if
     assign esc_rx[k].resp_p = esc_device_if[k].esc_rx.resp_p;
     assign esc_rx[k].resp_n = esc_device_if[k].esc_rx.resp_n;
     assign esc_device_if[k].esc_tx.esc_p = esc_tx[k].esc_p;
     assign esc_device_if[k].esc_tx.esc_n = esc_tx[k].esc_n;
-    // TODO: add assertions to check the probed signal
     assign probe_if[k].esc_en = dut.esc_sig_req[k];
+    assign alert_handler_if.esc_ping_reqs[k] = dut.gen_esc_sev[k].u_esc_sender.ping_req_i;
     initial begin
       uvm_config_db#(virtual alert_esc_if)::set(null, $sformatf("*.env.esc_device_agent[%0d]", k),
                                                 "vif", esc_device_if[k]);