[dv/alert_handler] random issue esc_clear
Random issue escalation clear registers during escalation
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
index e9e187b..76cee4b 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -7,10 +7,6 @@
{ral.class``i``_phase0_cyc, ral.class``i``_phase1_cyc, \
ral.class``i``_phase2_cyc, ral.class``i``_phase3_cyc};
-`define WAIT_CLK_AND_CHECK_RESET \
- @(cfg.clk_rst_vif.cb); \
- if (cfg.under_reset) break;
-
class alert_handler_scoreboard extends cip_base_scoreboard #(
.CFG_T(alert_handler_env_cfg),
.RAL_T(alert_handler_reg_block),
@@ -302,8 +298,8 @@
// if counter exceeds threshold, call predict_esc() function to calculate related esc
virtual task check_intr_timeout_trigger_esc();
for (int i = 0; i < NUM_ALERT_HANDLER_CLASSES; i++) begin
- automatic int class_i = i;
fork
+ automatic int class_i = i;
begin : intr_sig_counter
forever @(under_intr_classes[class_i] && !under_esc_classes[class_i]) begin
bit [TL_DW-1:0] timeout_cyc, class_ctrl;
@@ -341,36 +337,48 @@
fork
automatic int class_i = i;
begin : esc_phases_counter
- forever @(under_esc_classes[class_i]) begin
- for (int phase_i = 0; phase_i < NUM_ESC_PHASES; phase_i++) begin
- int phase_thresh = reg_esc_phase_cycs_per_class_q[class_i][phase_i]
- .get_mirrored_value();
- bit[TL_DW-1:0] class_ctrl = get_class_ctrl(class_i);
- int enabled_sig_q[$];
- for (int sig_i = 0; sig_i < NUM_ESC_SIGNALS; sig_i++) begin
- if (class_ctrl[sig_i*2+7 -: 2] == phase_i && class_ctrl[sig_i+2]) begin
- enabled_sig_q.push_back(sig_i);
+ forever @(!cfg.under_reset && under_esc_classes[class_i]) begin
+ fork
+ begin : inc_esc_cnt
+ for (int phase_i = 0; phase_i < NUM_ESC_PHASES; phase_i++) begin
+ int phase_thresh = reg_esc_phase_cycs_per_class_q[class_i][phase_i]
+ .get_mirrored_value();
+ bit[TL_DW-1:0] class_ctrl = get_class_ctrl(class_i);
+ int enabled_sig_q[$];
+ for (int sig_i = 0; sig_i < NUM_ESC_SIGNALS; sig_i++) begin
+ if (class_ctrl[sig_i*2+7 -: 2] == phase_i && class_ctrl[sig_i+2]) begin
+ enabled_sig_q.push_back(sig_i);
+ end
+ end
+ if (under_esc_classes[class_i]) begin
+ @(cfg.clk_rst_vif.cb);
+ intr_cnter_per_class[class_i] = 1;
+ incr_esc_sig_cnt(enabled_sig_q, class_i);
+ while (under_esc_classes[class_i] != 0 &&
+ intr_cnter_per_class[class_i] < phase_thresh) begin
+ @(cfg.clk_rst_vif.cb);
+ incr_esc_sig_cnt(enabled_sig_q, class_i);
+ intr_cnter_per_class[class_i]++;
+ end
+ incr_esc_sig_cnt(enabled_sig_q, class_i);
+ foreach (enabled_sig_q[i]) begin
+ int index = enabled_sig_q[i];
+ if (esc_sig_class[index] == (class_i + 1)) release_esc_signal(index);
+ end
+ end
+ end
+ @(cfg.clk_rst_vif.cb);
+ intr_cnter_per_class[class_i] = 0;
+ cfg.clk_rst_vif.wait_clks(2);
+ end
+ begin
+ wait(cfg.under_reset || !under_esc_classes[class_i]);
+ if (!under_esc_classes[class_i]) begin
+ cfg.clk_rst_vif.wait_clks(2);
end
end
- if (under_esc_classes[class_i]) begin
- `WAIT_CLK_AND_CHECK_RESET
- intr_cnter_per_class[class_i] = 1;
- incr_esc_sig_cnt(enabled_sig_q, class_i);
- while (under_esc_classes[class_i] != 0 &&
- intr_cnter_per_class[class_i] < phase_thresh) begin
- `WAIT_CLK_AND_CHECK_RESET
- incr_esc_sig_cnt(enabled_sig_q, class_i);
- intr_cnter_per_class[class_i]++;
- end
- incr_esc_sig_cnt(enabled_sig_q, class_i);
- foreach (enabled_sig_q[i]) begin
- int index = enabled_sig_q[i];
- if (esc_sig_class[index] == (class_i + 1)) release_esc_signal(index);
- end
- end
- end
- @(cfg.clk_rst_vif.cb);
- intr_cnter_per_class[class_i] = 0;
+ join_any
+ disable fork;
end // end forever
end
join_none
@@ -450,4 +458,3 @@
endclass
`undef ASSIGN_CLASS_PHASE_REGS
-`undef WAIT_CLK_AND_CHECK_RESET
diff --git a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
index 49ee3ed..31771e3 100644
--- a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
+++ b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
@@ -134,10 +134,12 @@
csr_rd(.ptr(ral.classd_esc_cnt), .value(accum_cnt));
endtask
- virtual task wait_alert_esc_handshake_done(int wait_clk_cycs_esc);
+ virtual task wait_alert_handshake_done();
cfg.clk_rst_vif.wait_clks(2);
foreach (cfg.alert_host_cfg[i]) cfg.alert_host_cfg[i].vif.wait_ack_complete();
+ endtask
+ virtual task wait_esc_handshake_done(int wait_clk_cycs_esc);
cfg.clk_rst_vif.wait_clks(wait_clk_cycs_esc);
foreach (cfg.esc_device_cfg[i]) cfg.esc_device_cfg[i].vif.wait_esc_complete();
endtask
diff --git a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
index 13781fe..b6bfa50 100644
--- a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
+++ b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
@@ -95,10 +95,21 @@
// read and check interrupt
clear_all_interrupts();
- // wait to ensure all escalation phases are done before clearing the esc class
- // TODO: replace with accurate status and cycle check
- wait_alert_esc_handshake_done(max_wait_phases_cyc);
-
+ wait_alert_handshake_done();
+ fork
+ begin : isolation_fork
+ fork
+ begin
+ wait_esc_handshake_done(max_wait_phases_cyc);
+ end
+ begin
+ cfg.clk_rst_vif.wait_clks($urandom_range(0, max_wait_phases_cyc*2));
+ do_clr_esc = 1;
+ end
+ join_any
+ disable fork;
+ end
+ join
read_alert_cause();
read_esc_status();
if (do_clr_esc) clear_esc();