Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions hw/ip_templates/otp_ctrl/dv/env/otp_ctrl_env_pkg.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ package otp_ctrl_env_pkg;
parameter uint NUM_SRAM_EDN_REQ = 12;
parameter uint NUM_OTBN_EDN_REQ = 10;

// This is used to randomize CHECK_TIMEOUT in sequences, set to a low value
// so it will certainly cause a check error due to a timeout.
parameter uint CHK_TIMEOUT_CYC = 40;
// This is some slack for a timeout error propagation to become an alert.
parameter uint CHK_TIMEOUT_SLACK = 4;

// When fatal alert triggered, all partitions and the DAI & LCI go to error state and status will
// be set to 1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ class otp_ctrl_scoreboard #(type CFG_T = otp_ctrl_env_cfg)
exp_status[OtpCheckPendingIdx] = 1;
under_chk = 1;
if (check_timeout <= CHK_TIMEOUT_CYC) begin
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout));
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout) + CHK_TIMEOUT_SLACK);
predict_err(OtpTimeoutErrIdx);
end else begin
if (get_field_val(ral.check_trigger.consistency, item.a_data)) begin
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
<%
buffered_part_indices = [i for (i, part) in enumerate(otp_mmap["partitions"])
if part["variant"] == "Buffered"]
%>\

class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
`uvm_object_utils(otp_ctrl_common_vseq)
Expand Down Expand Up @@ -140,20 +144,22 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
string prim_otp_alert_name = "fatal_prim_otp_alert";
string integ_err_alert_name = "fatal_bus_integ_error";

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
if (is_prim_otp) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// Alerts coming from the `u_tlul_lc_gate` module will only trigger bus_integrity alerts, and
// bus_integrity related status.
// This error won't local escalate to OTP partitions.
end else if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, integ_err_alert_name);

exp_status_val[OtpBusIntegErrorIdx] = 1;
exp_status_val[OtpDaiIdleIdx] = 1;

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
end else if (is_prim_otp) begin
`uvm_info(`gfn, $sformatf("check otp_macro alert %s", if_proxy.sec_cm_type.name),
UVM_MEDIUM)
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// All other errors triggers normal fatal alerts, and will locally escalate to other
// partitions.
end else begin
Expand Down Expand Up @@ -207,17 +213,13 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
case (if_proxy.sec_cm_type)
SecCmPrimCount: begin
if (!enable) begin
$assertoff(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
% for i in buffered_part_indices:
$assertoff(0, "tb.dut.gen_partitions[${i}].gen_buffered.u_part_buf.ScrmblDataKnown_A");
% endfor
end else begin
$asserton(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
% for i in buffered_part_indices:
$asserton(0, "tb.dut.gen_partitions[${i}].gen_buffered.u_part_buf.ScrmblDataKnown_A");
% endfor
end
end
SecCmPrimSparseFsmFlop, SecCmPrimDoubleLfsr, SecCmPrimOnehot: begin
Expand All @@ -226,9 +228,10 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name))
endcase

// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if.
if (!uvm_re_match("*.u_otp.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if and to
// discriminate between ctrl vs. macro fsm error.
if (!uvm_re_match("*.otp_macro.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
endfunction: sec_cm_fi_ctrl_svas

endclass
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ package otp_ctrl_env_pkg;
parameter uint NUM_SRAM_EDN_REQ = 12;
parameter uint NUM_OTBN_EDN_REQ = 10;

// This is used to randomize CHECK_TIMEOUT in sequences, set to a low value
// so it will certainly cause a check error due to a timeout.
parameter uint CHK_TIMEOUT_CYC = 40;
// This is some slack for a timeout error propagation to become an alert.
parameter uint CHK_TIMEOUT_SLACK = 4;

// When fatal alert triggered, all partitions and the DAI & LCI go to error state and status will
// be set to 1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ class otp_ctrl_scoreboard #(type CFG_T = otp_ctrl_env_cfg)
exp_status[OtpCheckPendingIdx] = 1;
under_chk = 1;
if (check_timeout <= CHK_TIMEOUT_CYC) begin
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout));
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout) + CHK_TIMEOUT_SLACK);
predict_err(OtpTimeoutErrIdx);
end else begin
if (get_field_val(ral.check_trigger.consistency, item.a_data)) begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,22 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
string prim_otp_alert_name = "fatal_prim_otp_alert";
string integ_err_alert_name = "fatal_bus_integ_error";

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
if (is_prim_otp) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// Alerts coming from the `u_tlul_lc_gate` module will only trigger bus_integrity alerts, and
// bus_integrity related status.
// This error won't local escalate to OTP partitions.
end else if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, integ_err_alert_name);

exp_status_val[OtpBusIntegErrorIdx] = 1;
exp_status_val[OtpDaiIdleIdx] = 1;

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
end else if (is_prim_otp) begin
`uvm_info(`gfn, $sformatf("check otp_macro alert %s", if_proxy.sec_cm_type.name),
UVM_MEDIUM)
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// All other errors triggers normal fatal alerts, and will locally escalate to other
// partitions.
end else begin
Expand Down Expand Up @@ -203,17 +205,19 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
case (if_proxy.sec_cm_type)
SecCmPrimCount: begin
if (!enable) begin
$assertoff(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[15].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[16].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[17].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[18].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[19].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[20].gen_buffered.u_part_buf.ScrmblDataKnown_A");
end else begin
$asserton(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lifecycle is also a buffered partition; so isn't this asserton/assertoff still needed for the LC partition?

$asserton(0, "tb.dut.gen_partitions[15].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[16].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[17].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[18].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[19].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[20].gen_buffered.u_part_buf.ScrmblDataKnown_A");
end
end
SecCmPrimSparseFsmFlop, SecCmPrimDoubleLfsr, SecCmPrimOnehot: begin
Expand All @@ -222,9 +226,10 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name))
endcase

// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if.
if (!uvm_re_match("*.u_otp.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if and to
// discriminate between ctrl vs. macro fsm error.
if (!uvm_re_match("*.otp_macro.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
endfunction: sec_cm_fi_ctrl_svas

endclass
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ package otp_ctrl_env_pkg;
parameter uint NUM_SRAM_EDN_REQ = 12;
parameter uint NUM_OTBN_EDN_REQ = 10;

// This is used to randomize CHECK_TIMEOUT in sequences, set to a low value
// so it will certainly cause a check error due to a timeout.
parameter uint CHK_TIMEOUT_CYC = 40;
// This is some slack for a timeout error propagation to become an alert.
parameter uint CHK_TIMEOUT_SLACK = 4;

// When fatal alert triggered, all partitions and the DAI & LCI go to error state and status will
// be set to 1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ class otp_ctrl_scoreboard #(type CFG_T = otp_ctrl_env_cfg)
exp_status[OtpCheckPendingIdx] = 1;
under_chk = 1;
if (check_timeout <= CHK_TIMEOUT_CYC) begin
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout));
set_exp_alert("fatal_check_error", 1, `gmv(ral.check_timeout) + CHK_TIMEOUT_SLACK);
predict_err(OtpTimeoutErrIdx);
end else begin
if (get_field_val(ral.check_trigger.consistency, item.a_data)) begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,22 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
string prim_otp_alert_name = "fatal_prim_otp_alert";
string integ_err_alert_name = "fatal_bus_integ_error";

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
if (is_prim_otp) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// Alerts coming from the `u_tlul_lc_gate` module will only trigger bus_integrity alerts, and
// bus_integrity related status.
// This error won't local escalate to OTP partitions.
end else if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
if (!uvm_re_match("*.u_tlul_lc_gate*", if_proxy.path)) begin
check_sec_cm_alert(if_proxy.sec_cm_type.name, integ_err_alert_name);

exp_status_val[OtpBusIntegErrorIdx] = 1;
exp_status_val[OtpDaiIdleIdx] = 1;

// Alerts coming from the `otp_macro` module will only bypass OTP_CTRL, it won't affect the
// OTP_CTRL and will fire its own alerts.
end else if (is_prim_otp) begin
`uvm_info(`gfn, $sformatf("check otp_macro alert %s", if_proxy.sec_cm_type.name),
UVM_MEDIUM)
check_sec_cm_alert(if_proxy.sec_cm_type.name, prim_otp_alert_name);

// All other errors triggers normal fatal alerts, and will locally escalate to other
// partitions.
end else begin
Expand Down Expand Up @@ -205,17 +207,17 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
case (if_proxy.sec_cm_type)
SecCmPrimCount: begin
if (!enable) begin
$assertoff(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[7].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[8].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$assertoff(0, "tb.dut.gen_partitions[9].gen_buffered.u_part_buf.ScrmblDataKnown_A");
end else begin
$asserton(0, "tb.dut.gen_partitions[3].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[4].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[5].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[6].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[7].gen_lifecycle.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[7].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[8].gen_buffered.u_part_buf.ScrmblDataKnown_A");
$asserton(0, "tb.dut.gen_partitions[9].gen_buffered.u_part_buf.ScrmblDataKnown_A");
end
end
SecCmPrimSparseFsmFlop, SecCmPrimDoubleLfsr, SecCmPrimOnehot: begin
Expand All @@ -224,9 +226,10 @@ class otp_ctrl_common_vseq extends otp_ctrl_base_vseq;
default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name))
endcase

// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if.
if (!uvm_re_match("*.u_otp.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
// Set the flag to store if the error injection is on prim_tlul_if or core_tlul_if and to
// discriminate between ctrl vs. macro fsm error.
if (!uvm_re_match("*.otp_macro.*", if_proxy.path)) is_prim_otp = 1;
else is_prim_otp = 0;
endfunction: sec_cm_fi_ctrl_svas

endclass
Loading