[dv/alert] Support LPG in alert_sender/receiver pair
This PR supports LPG in prim_alert testbench by randomly issue
init_trigger_i in alert_receiver side when alert handshake is on-going.
This PR implements part of the TODO in issue #8814.
Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/ip/prim/dv/prim_alert/data/prim_alert_testplan.hjson b/hw/ip/prim/dv/prim_alert/data/prim_alert_testplan.hjson
index 009d6c6..33c588e 100644
--- a/hw/ip/prim/dv/prim_alert/data/prim_alert_testplan.hjson
+++ b/hw/ip/prim/dv/prim_alert/data/prim_alert_testplan.hjson
@@ -35,6 +35,24 @@
}
{
+ name: prim_alert_init_trigger_test
+ desc: '''Verify init_trigger input from prim_alert_receiver.
+
+ Based on the prim_alert_test, this test adds a parallel sequence to randomly drive
+ init_trigger_i in prim_alert_receiver.
+
+ Check if alert sender/receiver pairs can resume normal handshake after init_trigger_i
+ is set.
+ For fatal alert, check if fatal alerts keep firing until reset is issued.
+ '''
+ milestone: V1
+ tests: ["prim_async_alert",
+ "prim_async_fatal_alert",
+ "prim_sync_alert",
+ "prim_sync_fatal_alert"]
+ }
+
+ {
name: prim_alert_ping_request_test
desc: '''Verify ping request from prim_alert_sender.
diff --git a/hw/ip/prim/dv/prim_alert/prim_alert_sim_cfg.hjson b/hw/ip/prim/dv/prim_alert/prim_alert_sim_cfg.hjson
index dc450da..e4cbe68 100644
--- a/hw/ip/prim/dv/prim_alert/prim_alert_sim_cfg.hjson
+++ b/hw/ip/prim/dv/prim_alert/prim_alert_sim_cfg.hjson
@@ -24,7 +24,7 @@
import_cfgs: ["{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson"]
// Default iterations for all tests - each test entry can override this.
- reseed: 1
+ reseed: 20
build_modes: [
{
diff --git a/hw/ip/prim/dv/prim_alert/tb/prim_alert_tb.sv b/hw/ip/prim/dv/prim_alert/tb/prim_alert_tb.sv
index e77bb74..de1ce51 100644
--- a/hw/ip/prim/dv/prim_alert/tb/prim_alert_tb.sv
+++ b/hw/ip/prim/dv/prim_alert/tb/prim_alert_tb.sv
@@ -40,7 +40,7 @@
localparam int MinHandshakeWait = 2 + WaitCycle;
// Clock cycles for alert init handshake to finish.
- localparam int WaitAlertInitDone = 20;
+ localparam int WaitAlertInitDone = 30;
typedef enum bit [3:0]{
AlertSet,
@@ -74,7 +74,7 @@
logic ping_req, ping_ok, integ_fail, alert_o;
prim_alert_pkg::alert_rx_t alert_rx;
prim_alert_pkg::alert_tx_t alert_tx;
-
+ prim_mubi_pkg::mubi4_t init_trig = prim_mubi_pkg::MuBi4False;
prim_alert_sender #(
.AsyncOn(IsAsync),
.IsFatal(IsFatal)
@@ -94,8 +94,7 @@
) i_alert_receiver (
.clk_i(clk),
.rst_ni(rst_n),
- // TODO: randomly trigger this
- .init_trig_i(prim_mubi_pkg::MuBi4False),
+ .init_trig_i(init_trig),
.ping_req_i(ping_req),
.ping_ok_o(ping_ok),
.integ_fail_o(integ_fail),
@@ -209,30 +208,51 @@
main_clk.wait_clks(WaitAlertInitDone);
// Sequence 1). Alert request sequence.
- main_clk.wait_clks($urandom_range(0, 10));
- alert_req = 1;
- fork
- begin
+ for (int num_trans = 1; num_trans <= 10; num_trans++) begin
+ int rand_wait_alert_req = $urandom_range(MinHandshakeWait, 10);
+ int rand_wait_init_trig = $urandom_range(0, 30);
+ fork
+ begin
+ main_clk.wait_clks(rand_wait_alert_req);
+ alert_req = 1;
+ fork
+ begin
+ main_clk.wait_clks(1);
+ check_alert_handshake(.exp_ping_value(0));
+ end
+ // While waiting to check alert handshake, reset alert_req as soon as alert is acked to
+ // avoid triggering multiple alert requests.
+ begin
+ wait (alert_ack == 1);
+ alert_req = 0;
+ end
+ join
+ end
+ begin
+ main_clk.wait_clks(rand_wait_init_trig);
+ init_trig = prim_mubi_pkg::MuBi4True;
+ end
+ join_any
+ disable fork;
+ if (init_trig == prim_mubi_pkg::MuBi4True) begin
+ alert_req = 0;
+ main_clk.wait_clks($urandom_range(0, 10));
+ init_trig = prim_mubi_pkg::MuBi4False;
+ main_clk.wait_clks(WaitAlertInitDone);
+ end
+ // For fatal alert, ensure alert keeps firing until reset.
+ // This check is valid if the alert is fatal, and alert is requested before init request.
+ if (IsFatal && (rand_wait_alert_req + 1) <= rand_wait_init_trig) begin
+ main_clk.wait_clks($urandom_range(10, 100));
+ wait (alert_tx.alert_p == 0);
+ wait (alert_tx.alert_p == 1);
main_clk.wait_clks(1);
check_alert_handshake(.exp_ping_value(0));
+ main_clk.apply_reset();
+ main_clk.wait_clks(WaitAlertInitDone);
end
- begin
- wait (alert_ack == 1);
- alert_req = 0;
- end
- join
-
- // If alert is fatal, check alert will continuously fire until reset.
- if (IsFatal) begin
- main_clk.wait_clks($urandom_range(10, 1000));
- wait (alert_tx.alert_p == 0);
- wait (alert_tx.alert_p == 1);
- main_clk.wait_clks(1);
- check_alert_handshake(.exp_ping_value(0));
- main_clk.apply_reset();
- main_clk.wait_clks(WaitAlertInitDone);
+ $display("Alert request sequence %0d/10 finished!", num_trans);
end
- $display("Alert request sequence finished!");
// Sequence 2). Alert test sequence.
main_clk.wait_clks($urandom_range(MinHandshakeWait, 10));