[LC_CTRL/dv] Fixed up tests
- Updated FSM backdoor path
- Corrected KMAC I/F FSM backdoor read and write tasks.
- Selectively disabling assertions
- Fixed V2S testplan
- Added missing constraint token_digest_err_inj_c to lc_ctrl_errors_vseq.sv
- Added asserion disabling for sec_cm tests in lc_ctrl_common_vseq
- Moved to using prim_sparse_fsm_flop_if_proxy for backdoor error injection rather than tasks in lc_ctrl_if
Signed-off-by: Nigel Scales <nigel.scales@gmail.com>
diff --git a/hw/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson b/hw/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson
index 5e9f293..617af91 100644
--- a/hw/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson
+++ b/hw/ip/lc_ctrl/data/lc_ctrl_sec_cm_testplan.hjson
@@ -43,7 +43,7 @@
mutex).
'''
milestone: V2S
- tests: []
+ tests: ["lc_ctrl_regwen_during_op"]
}
{
name: sec_cm_manuf_state_sparse
@@ -53,7 +53,7 @@
Verify this countermeasure with a standardized test.
'''
milestone: V2S
- tests: []
+ tests: ["lc_ctrl_sec_cm", "lc_ctrl_state_failure"]
}
{
name: sec_cm_transition_ctr_sparse
diff --git a/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv b/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
index ab7031e..cb1651d 100644
--- a/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
+++ b/hw/ip/lc_ctrl/dv/env/lc_ctrl_if.sv
@@ -4,26 +4,6 @@
//
// interface for input data from OTP
-`ifndef LC_CTRL_FSM_STATE_REGS_PATH
-`define LC_CTRL_FSM_STATE_REGS_PATH \
- tb.dut.u_lc_ctrl_fsm.u_fsm_state_regs.u_state_flop.gen_generic.u_impl_generic.q_o
-`endif
-
-`ifndef LC_CTRL_KMAC_FSM_STATE_REGS_PATH
-`define LC_CTRL_KMAC_FSM_STATE_REGS_PATH \
- tb.dut.u_lc_ctrl_kmac_if.u_state_regs.u_state_flop.gen_generic.u_impl_generic.q_o
-`endif
-
-`ifndef LC_CTRL_STATE_PATH
-`define LC_CTRL_STATE_PATH \
- tb.dut.otp_lc_data_i.state
-`endif
-
-`ifndef LC_CTRL_COUNT_PATH
-`define LC_CTRL_COUNT_PATH \
- tb.dut.otp_lc_data_i.count
-`endif
-
`ifndef LC_CTRL_FSM_PATH
`define LC_CTRL_FSM_PATH tb.dut.u_lc_ctrl_fsm
`endif
@@ -139,8 +119,6 @@
end
join_none
- release `LC_CTRL_FSM_STATE_REGS_PATH;
-
endtask
task automatic set_clk_byp_ack(lc_tx_t val);
@@ -157,96 +135,6 @@
otp_vendor_test_status_i = 0;
endfunction
- //
- // The functions below must be static because of the force statement
- //
-
- // Force lc_ctrl_fsm state registers
- function static void lc_fsm_state_backdoor_write(input logic [FsmStateWidth-1:0] val = 'hdead,
- input int delay_clocks = 0,
- input int force_clocks = 5);
- `dv_info($sformatf("Backdoor write to state registers"))
- fork
- begin : force_state_proc
- repeat (delay_clocks) @(posedge clk);
- ->lc_fsm_state_backdoor_write_ev;
- force `LC_CTRL_FSM_STATE_REGS_PATH = val;
- repeat (force_clocks) @(posedge clk);
- release `LC_CTRL_FSM_STATE_REGS_PATH;
- end : force_state_proc
- join_none
- endfunction
-
- // Read lc_ctrl_fsm state registers
- function automatic logic [FsmStateWidth-1:0] lc_fsm_state_backdoor_read();
- ->lc_fsm_state_backdoor_read_ev;
- return `LC_CTRL_FSM_STATE_REGS_PATH;
- endfunction
-
- // Force kmac i/f fsm state registers
- function static void kmac_fsm_state_backdoor_write(
- input logic [lc_ctrl_env_pkg::KMAC_FSM_WIDTH-1:0] val = 'hde, input int delay_clocks = 0,
- input int force_clocks = 5);
- `dv_info($sformatf("Backdoor write to kmac i/f state registers = %h", val))
- fork
- begin : force_state_proc
- repeat (delay_clocks) @(posedge clk);
- ->kmac_fsm_state_backdoor_write_ev;
- force `LC_CTRL_FSM_STATE_REGS_PATH = val;
- repeat (force_clocks) @(posedge clk);
- release `LC_CTRL_FSM_STATE_REGS_PATH;
- end : force_state_proc
- join_none
- endfunction
-
- // Read kmac i/f fsm state registers
- function automatic logic [lc_ctrl_env_pkg::KMAC_FSM_WIDTH-1:0] kmac_fsm_state_backdoor_read();
- ->kmac_fsm_state_backdoor_read_ev;
- return `LC_CTRL_FSM_STATE_REGS_PATH;
- endfunction
-
- // Force OTP state input
- function static void state_backdoor_write(input logic [LcStateWidth-1:0] val = 'hdead,
- input int delay_clocks = 0, input int force_clocks = 5);
- `dv_info($sformatf("Backdoor write to OTP state input = %h", val))
- fork
- begin : force_state_proc
- repeat (delay_clocks) @(posedge clk);
- ->state_backdoor_write_ev;
- force `LC_CTRL_STATE_PATH = val;
- repeat (force_clocks) @(posedge clk);
- release `LC_CTRL_STATE_PATH;
- end : force_state_proc
- join_none
- endfunction
-
- // Read OTP state input
- function automatic logic [LcStateWidth-1:0] state_backdoor_read();
- ->state_backdoor_read_ev;
- return `LC_CTRL_STATE_PATH;
- endfunction
-
- // Force OTP count input
- function static void count_backdoor_write(input logic [LcCountWidth-1:0] val = 'hdead,
- input int delay_clocks = 0, input int force_clocks = 5);
- `dv_info($sformatf("Backdoor write to OTP count input = %h", val))
- fork
- begin : force_count_proc
- repeat (delay_clocks) @(posedge clk);
- ->count_backdoor_write_ev;
- force `LC_CTRL_COUNT_PATH = val;
- repeat (force_clocks) @(posedge clk);
- release `LC_CTRL_COUNT_PATH;
- end : force_count_proc
- join_none
- endfunction
-
- // Read OTP count input
- function automatic logic [LcCountWidth-1:0] count_backdoor_read();
- ->count_backdoor_read_ev;
- return `LC_CTRL_COUNT_PATH;
- endfunction
-
function automatic void set_test_sequence_typename(string name);
test_sequence_typename = name;
endfunction
@@ -293,6 +181,4 @@
endinterface
-`undef LC_CTRL_FSM_STATE_REGS_PATH
-`undef LC_CTRL_COUNT_PATH
`undef LC_CTRL_FSM_PATH
diff --git a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv
index b726554..c65ada2 100644
--- a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv
+++ b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_base_vseq.sv
@@ -243,4 +243,14 @@
), UVM_MEDIUM)
endfunction
+
+ // Find sec_cm_base_if_proxy for a given path
+ virtual function sec_cm_base_if_proxy find_sec_cm_base_if_proxy(string path);
+ sec_cm_base_if_proxy proxies[$];
+ // Search singleton queue of proxies in sec_cm_pkg
+ proxies = sec_cm_pkg::sec_cm_if_proxy_q.find_first() with (item.path == path);
+ if (proxies.size > 0) return proxies[0];
+ else `uvm_fatal(`gfn, $sformatf("find_sec_cm_base_if_proxy: no proxy with path %s", path))
+ endfunction
+
endclass : lc_ctrl_base_vseq
diff --git a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv
index 1353240..962f928 100644
--- a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv
+++ b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_common_vseq.sv
@@ -12,6 +12,21 @@
run_common_vseq_wrapper(num_trans);
endtask : body
+ virtual function void sec_cm_fi_ctrl_svas(sec_cm_base_if_proxy if_proxy, bit enable);
+ case (if_proxy.sec_cm_type)
+ SecCmPrimSparseFsmFlop: begin
+ `DV_ASSERT_CTRL_REQ("StateRegs_A", enable)
+ `DV_ASSERT_CTRL_REQ("CountRegs_A", enable)
+ `DV_ASSERT_CTRL_REQ("FsmStateRegs_A", enable)
+ `DV_ASSERT_CTRL_REQ("KmacFsmStateRegs_A", enable)
+ end
+ SecCmPrimCount: begin
+ // No need to disable any assertion
+ end
+ default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name))
+ endcase
+ endfunction : sec_cm_fi_ctrl_svas
+
virtual task check_sec_cm_fi_resp(sec_cm_base_if_proxy if_proxy);
// Expected state error bit of status register
bit exp_state_error = 0;
diff --git a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv
index ef0da31..464138b 100644
--- a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv
+++ b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_errors_vseq.sv
@@ -126,6 +126,8 @@
constraint tokem_mux_err_inj_c {err_inj.token_mux_ctrl_redun_err == 0;}
+ constraint token_digest_err_inj_c {err_inj.token_mux_digest_err == 0;}
+
virtual task post_start();
`uvm_info(`gfn, "post_start: Task called for lc_ctrl_errors_vseq", UVM_MEDIUM)
@@ -150,6 +152,10 @@
`DV_ASSERT_CTRL_REQ("OtpProgReqHighUntilAck_A", 1)
`DV_ASSERT_CTRL_REQ("OtpProgAckAssertedOnlyWhenReqAsserted_A", 1)
`DV_ASSERT_CTRL_REQ("KmacIfSyncReqAckAckNeedsReq", 1)
+ `DV_ASSERT_CTRL_REQ("StateRegs_A", 1)
+ `DV_ASSERT_CTRL_REQ("FsmStateRegs_A", 1)
+ `DV_ASSERT_CTRL_REQ("CountRegs_A", 1)
+
// Kill sub processes
disable handle_alerts;
@@ -394,16 +400,27 @@
`DV_ASSERT_CTRL_REQ("OtpProgReqHighUntilAck_A", 0)
`DV_ASSERT_CTRL_REQ("OtpProgAckAssertedOnlyWhenReqAsserted_A", 0)
`DV_ASSERT_CTRL_REQ("KmacIfSyncReqAckAckNeedsReq", 0)
- assertions_disabled = 1;
- end else if (assertions_disabled) begin
- // Reenable assertions if they had been disabled
+ end else begin
`DV_ASSERT_CTRL_REQ("OtpProgH_DataStableWhenBidirectionalAndReq_A", 1)
`DV_ASSERT_CTRL_REQ("OtpProgReqHighUntilAck_A", 1)
`DV_ASSERT_CTRL_REQ("OtpProgAckAssertedOnlyWhenReqAsserted_A", 1)
`DV_ASSERT_CTRL_REQ("KmacIfSyncReqAckAckNeedsReq", 1)
- assertions_disabled = 0;
end
+ if (err_inj.state_err || err_inj.state_illegal_err || err_inj.state_backdoor_err) begin
+ `DV_ASSERT_CTRL_REQ("StateRegs_A", 0)
+ end else `DV_ASSERT_CTRL_REQ("StateRegs_A", 1)
+
+ if (err_inj.count_err || err_inj.count_illegal_err || err_inj.count_backdoor_err) begin
+ `DV_ASSERT_CTRL_REQ("CountRegs_A", 0)
+ end else `DV_ASSERT_CTRL_REQ("CountRegs_A", 1)
+
+ if (err_inj.lc_fsm_backdoor_err) `DV_ASSERT_CTRL_REQ("FsmStateRegs_A", 0)
+ else `DV_ASSERT_CTRL_REQ("FsmStateRegs_A", 1)
+
+ if (err_inj.kmac_fsm_backdoor_err) `DV_ASSERT_CTRL_REQ("KmacFsmStateRegs_A", 0)
+ else `DV_ASSERT_CTRL_REQ("KmacFsmStateRegs_A", 1)
+
endtask
@@ -716,34 +733,37 @@
// Flip bits in LC FSM registers
protected virtual task lc_fsm_backdoor_err_inj();
logic [FsmStateWidth-1:0] state;
- state = cfg.lc_ctrl_vif.lc_fsm_state_backdoor_read();
- state ^= lc_fsm_state_invert_bits;
- cfg.lc_ctrl_vif.lc_fsm_state_backdoor_write(state, 0, lc_fsm_state_err_inj_period);
+ sec_cm_base_if_proxy if_proxy = find_sec_cm_base_if_proxy(
+ "tb.dut.u_lc_ctrl_fsm.u_fsm_state_regs"
+ );
+
+ if_proxy.inject_fault();
endtask
// Flip bits in KMAC FSM registers
protected virtual task kmac_fsm_backdoor_err_inj();
logic [KMAC_FSM_WIDTH-1:0] state;
- state = cfg.lc_ctrl_vif.kmac_fsm_state_backdoor_read();
- state ^= kmac_fsm_state_invert_bits;
- cfg.lc_ctrl_vif.kmac_fsm_state_backdoor_write(state, 0, lc_fsm_state_err_inj_period);
- endtask
+ sec_cm_base_if_proxy if_proxy = find_sec_cm_base_if_proxy(
+ "tb.dut.u_lc_ctrl_kmac_if.u_state_regs"
+ );
+ if_proxy.inject_fault();
+ endtask
// Flip bits in OTP State input
protected virtual task state_backdoor_err_inj();
logic [LcStateWidth-1:0] state;
- state = cfg.lc_ctrl_vif.count_backdoor_read();
- state ^= state_invert_bits;
- cfg.lc_ctrl_vif.count_backdoor_write(state, 0, state_err_inj_period);
+ sec_cm_base_if_proxy if_proxy = find_sec_cm_base_if_proxy("tb.dut.u_lc_ctrl_fsm.u_state_regs");
+
+ if_proxy.inject_fault();
endtask
// Flip bits OTP Count input
protected virtual task count_backdoor_err_inj();
logic [LcCountWidth-1:0] count;
- count = cfg.lc_ctrl_vif.count_backdoor_read();
- count ^= count_invert_bits;
- cfg.lc_ctrl_vif.count_backdoor_write(count, 0, count_err_inj_period);
+ sec_cm_base_if_proxy if_proxy = find_sec_cm_base_if_proxy("tb.dut.u_lc_ctrl_fsm.u_cnt_regs");
+
+ if_proxy.inject_fault();
endtask
// Send an escalate alert
diff --git a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv
index 3501a3d..4346d5c 100644
--- a/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv
+++ b/hw/ip/lc_ctrl/dv/env/seq_lib/lc_ctrl_sec_token_digest_vseq.sv
@@ -21,7 +21,7 @@
err_inj.otp_partition_err == 0;
}
- constraint lc_token_digest_c {
+ constraint lc_token_digest_err_inj_c {
$onehot(
{
// Either wrong token for transition
diff --git a/hw/ip/lc_ctrl/dv/tb.sv b/hw/ip/lc_ctrl/dv/tb.sv
index 0bfd8ac..4f020d3 100644
--- a/hw/ip/lc_ctrl/dv/tb.sv
+++ b/hw/ip/lc_ctrl/dv/tb.sv
@@ -249,5 +249,13 @@
`DV_ASSERT_CTRL("FsmClkFlashRmaAckSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_flash_rma_ack)
`DV_ASSERT_CTRL("FsmOtpTestTokensValidSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_test_token_valid)
`DV_ASSERT_CTRL("FsmOtpRmaTokenValidSync", dut.u_lc_ctrl_fsm.u_prim_lc_sync_rma_token_valid)
-
+ `DV_ASSERT_CTRL("StateRegs_A", tb.dut.u_lc_ctrl_fsm.u_state_regs_A)
+ `DV_ASSERT_CTRL("StateRegs_A", tb.dut.FpvSecCmCtrlLcStateCheck_A)
+ `DV_ASSERT_CTRL("FsmStateRegs_A", tb.dut.u_lc_ctrl_fsm.u_fsm_state_regs_A)
+ `DV_ASSERT_CTRL("FsmStateRegs_A", tb.dut.FpvSecCmCtrlLcFsmCheck_A)
+ `DV_ASSERT_CTRL("CountRegs_A", tb.dut.u_lc_ctrl_fsm.u_cnt_regs_A)
+ `DV_ASSERT_CTRL("CountRegs_A", tb.dut.FpvSecCmCtrlLcCntCheck_A)
+ `DV_ASSERT_CTRL("KmacFsmStateRegs_A", tb.dut.u_lc_ctrl_kmac_if.u_state_regs_A)
+ `DV_ASSERT_CTRL("KmacFsmStateRegs_A", tb.dut.FpvSecCmCtrlKmacIfFsmCheck_A)
+ `DV_ASSERT_CTRL("EscStaysOnOnceAsserted_A", tb.dut.u_lc_ctrl_fsm.EscStaysOnOnceAsserted_A)
endmodule