[dv/otp_ctrl] check timeout failure
This PR supports one kind of check failure - the timeout failure.
The timoeut failure is triggered by setting the timeout value to a small
value. The timeout failure will send out a fatal alert and status
timeout error bit will be set.
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
index cfbd683..4d3daed 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
+++ b/hw/ip/otp_ctrl/data/otp_ctrl_testplan.hjson
@@ -69,7 +69,7 @@
- Check if the error_code register is set correctly
'''
milestone: V2
- tests: []
+ tests: ["otp_ctrl_check_fail"]
}
{
name: regwen_during_otp_init
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
index c360c00..8c815ab 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env.core
@@ -28,6 +28,7 @@
- seq_lib/otp_ctrl_dai_lock_vseq.sv: {is_include_file: true}
- seq_lib/otp_ctrl_dai_errs_vseq.sv: {is_include_file: true}
- seq_lib/otp_ctrl_macro_errs_vseq.sv: {is_include_file: true}
+ - seq_lib/otp_ctrl_check_fail_vseq.sv: {is_include_file: true}
- seq_lib/otp_ctrl_parallel_base_vseq.sv: {is_include_file: true}
- seq_lib/otp_ctrl_regwen_vseq.sv: {is_include_file: true}
- seq_lib/otp_ctrl_parallel_key_req_vseq.sv: {is_include_file: true}
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
index 6580e83..fd55a0e 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv
@@ -86,6 +86,8 @@
parameter uint NUM_SRAM_EDN_REQ = 10;
parameter uint NUM_OTBN_EDN_REQ = 16;
+ parameter uint CHK_TIMEOUT_CYC = 40;
+
// lc does not have digest
parameter int PART_BASE_ADDRS [NumPart-1] = {
CreatorSwCfgOffset,
diff --git a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
index 3be3eb1..313e92f 100644
--- a/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
+++ b/hw/ip/otp_ctrl/dv/env/otp_ctrl_scoreboard.sv
@@ -547,7 +547,10 @@
// update status mask
status_mask = 0;
// Mask out check_pending field - we do not know how long it takes to process checks.
- if (under_chk) status_mask[OtpCheckPendingIdx] = 1;
+ // Check failure can trigger all kinds of errors.
+ if (under_chk) status_mask = '1;
+
+ if (!under_chk && `gmv(ral.status.check_pending)) status_mask[OtpTimeoutErrIdx] = 1;
// Mask out otp_dai access related field - we do not know how long it takes to finish
// DAI access.
@@ -590,6 +593,10 @@
"check_trigger": begin
if (addr_phase_write && `gmv(ral.check_trigger_regwen) && item.a_data inside {[1:3]}) begin
exp_status[OtpCheckPendingIdx] = 1;
+ if (`gmv(ral.check_timeout) > 0 && `gmv(ral.check_timeout) <= CHK_TIMEOUT_CYC) begin
+ set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout));
+ predict_status_err(.timeout_err(1));
+ end
end
end
"hw_cfg_digest_0", "hw_cfg_digest_1", "", "secret0_digest_0", "secret0_digest_1",
@@ -858,13 +865,14 @@
dai_addr >> 2;
endfunction
- virtual function void predict_status_err(bit dai_err = 0, bit lc_err = 0);
+ virtual function void predict_status_err(bit dai_err = 0, bit lc_err = 0, bit timeout_err = 0);
void'(ral.intr_state.otp_error.predict(.value(1), .kind(UVM_PREDICT_READ)));
if (dai_err) begin
exp_status[OtpDaiIdleIdx] = 1;
exp_status[OtpDaiErrIdx] = 1;
end
if (lc_err) exp_status[OtpLciErrIdx] = 1;
+ if (timeout_err) exp_status[OtpTimeoutErrIdx] = 1;
endfunction
virtual function void predict_dai_idle_status_wo_err();
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv
new file mode 100644
index 0000000..cd9f21f
--- /dev/null
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_check_fail_vseq.sv
@@ -0,0 +1,18 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// This sequence creates the following check failure scenarios:
+// 1. Check timeout
+// 2. TODO: add when support
+class otp_ctrl_check_fail_vseq extends otp_ctrl_dai_errs_vseq;
+ `uvm_object_utils(otp_ctrl_check_fail_vseq)
+
+ `uvm_object_new
+
+ // 50% chance of having a check timeout
+ constraint check_timeout_val_c {
+ check_timeout_val dist {[1 : CHK_TIMEOUT_CYC] :/ 1,
+ [100_000 :'1] :/ 1};
+ }
+endclass
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
index 717839f..de3cde6 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_smoke_vseq.sv
@@ -90,7 +90,9 @@
// set consistency and integrity checks
csr_wr(ral.check_regwen, check_regwen_val);
csr_wr(ral.check_trigger_regwen, check_trigger_regwen_val);
- csr_wr(ral.check_timeout, check_timeout_val);
+ if (check_trigger_val && `gmv(ral.check_trigger_regwen)) begin
+ csr_wr(ral.check_timeout, check_timeout_val);
+ end
trigger_checks(.val(check_trigger_val), .wait_done(1));
if (do_req_keys) begin
diff --git a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv
index 8b685d6..c6e9dd0 100644
--- a/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv
+++ b/hw/ip/otp_ctrl/dv/env/seq_lib/otp_ctrl_vseq_list.sv
@@ -10,6 +10,7 @@
`include "otp_ctrl_dai_lock_vseq.sv"
`include "otp_ctrl_dai_errs_vseq.sv"
`include "otp_ctrl_macro_errs_vseq.sv"
+`include "otp_ctrl_check_fail_vseq.sv"
`include "otp_ctrl_parallel_base_vseq.sv"
`include "otp_ctrl_parallel_key_req_vseq.sv"
`include "otp_ctrl_parallel_lc_req_vseq.sv"
diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
index 7641690..fe6d41e 100644
--- a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
+++ b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
@@ -81,6 +81,11 @@
}
{
+ name: otp_ctrl_check_fail
+ uvm_test_seq: otp_ctrl_check_fail_vseq
+ }
+
+ {
name: otp_ctrl_macro_errs
uvm_test_seq: otp_ctrl_macro_errs_vseq
}