Line Coverage for Module :
keymgr_sideload_key_ctrl
| Line No. | Total | Covered | Percent |
TOTAL | | 50 | 50 | 100.00 |
ALWAYS | 66 | 3 | 3 | 100.00 |
CONT_ASSIGN | 71 | 1 | 1 | 100.00 |
CONT_ASSIGN | 71 | 1 | 1 | 100.00 |
CONT_ASSIGN | 78 | 1 | 1 | 100.00 |
CONT_ASSIGN | 84 | 1 | 1 | 100.00 |
CONT_ASSIGN | 85 | 1 | 1 | 100.00 |
CONT_ASSIGN | 86 | 1 | 1 | 100.00 |
CONT_ASSIGN | 89 | 1 | 1 | 100.00 |
ALWAYS | 92 | 13 | 13 | 100.00 |
CONT_ASSIGN | 144 | 1 | 1 | 100.00 |
CONT_ASSIGN | 145 | 1 | 1 | 100.00 |
CONT_ASSIGN | 146 | 1 | 1 | 100.00 |
ALWAYS | 193 | 6 | 6 | 100.00 |
ALWAYS | 193 | 6 | 6 | 100.00 |
ALWAYS | 193 | 6 | 6 | 100.00 |
CONT_ASSIGN | 205 | 1 | 1 | 100.00 |
CONT_ASSIGN | 206 | 1 | 1 | 100.00 |
CONT_ASSIGN | 207 | 1 | 1 | 100.00 |
CONT_ASSIGN | 214 | 1 | 1 | 100.00 |
CONT_ASSIGN | 217 | 1 | 1 | 100.00 |
CONT_ASSIGN | 220 | 1 | 1 | 100.00 |
65 // flops in order to prevent FSM state encoding optimizations.
66 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, keymgr_sideload_e, StSideloadReset)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, keymgr_sideload_e, StSideloadReset):
66.1 `ifdef SIMULATION
66.2 prim_sparse_fsm_flop #(
66.3 .StateEnumT(keymgr_sideload_e),
66.4 .Width($bits(keymgr_sideload_e)),
66.5 .ResetValue($bits(keymgr_sideload_e)'(StSideloadReset)),
66.6 .EnableAlertTriggerSVA(1),
66.7 .CustomForceName("state_q")
66.8 ) u_state_regs (
66.9 .clk_i ( clk_i ),
66.10 .rst_ni ( rst_ni ),
66.11 .state_i ( state_d ),
66.12 .state_o ( )
66.13 );
66.14 always_ff @(posedge clk_i or negedge rst_ni) begin
66.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
66.16 1/1 state_q <= StSideloadReset;
Tests: T1 T2 T3
66.17 end else begin
66.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
66.19 end
66.20 end
66.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
66.22 else begin
66.23 `ifdef UVM
66.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
66.25 "../src/lowrisc_ip_keymgr_0.1/rtl/keymgr_sideload_key_ctrl.sv", 66, "", 1);
66.26 `else
66.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
66.28 `PRIM_STRINGIFY(u_state_regs_A));
66.29 `endif
66.30 end
66.31 `else
66.32 prim_sparse_fsm_flop #(
66.33 .StateEnumT(keymgr_sideload_e),
66.34 .Width($bits(keymgr_sideload_e)),
66.35 .ResetValue($bits(keymgr_sideload_e)'(StSideloadReset)),
66.36 .EnableAlertTriggerSVA(1)
66.37 ) u_state_regs (
66.38 .clk_i ( `PRIM_FLOP_CLK ),
66.39 .rst_ni ( `PRIM_FLOP_RST ),
66.40 .state_i ( state_d ),
66.41 .state_o ( state_q )
66.42 );
66.43 `endif67
68 logic keys_en;
69 logic [Shares-1:0][KeyWidth-1:0] data_truncated;
70 for(genvar i = 0; i < Shares; i++) begin : gen_truncate_data
71 2/2 assign data_truncated[i] = data_i[i][KeyWidth-1:0];
Tests: T1 T2 T3 | T1 T2 T3
72 end
73
74 // clear all keys when selected by software, or when
75 // wipe command is received
76 logic clr_all_keys;
77 logic [LastIdx-1:0] slot_clr;
78 1/1 assign clr_all_keys = wipe_key_i |
Tests: T1 T2 T3
79 !(clr_key_i inside {SideLoadClrIdle,
80 SideLoadClrAes,
81 SideLoadClrKmac,
82 SideLoadClrOtbn});
83
84 1/1 assign slot_clr[AesIdx] = clr_all_keys | (clr_key_i == SideLoadClrAes);
Tests: T1 T2 T3
85 1/1 assign slot_clr[KmacIdx] = clr_all_keys | (clr_key_i == SideLoadClrKmac);
Tests: T1 T2 T3
86 1/1 assign slot_clr[OtbnIdx] = clr_all_keys | (clr_key_i == SideLoadClrOtbn);
Tests: T1 T2 T3
87
88 logic clr;
89 1/1 assign clr = |slot_clr;
Tests: T1 T2 T3
90
91 always_comb begin
92 1/1 keys_en = 1'b0;
Tests: T1 T2 T3
93 1/1 state_d = state_q;
Tests: T1 T2 T3
94 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
95
96 1/1 unique case (state_q)
Tests: T1 T2 T3
97 StSideloadReset: begin
98 1/1 if (init_i) begin
Tests: T1 T2 T3
99 1/1 state_d = StSideloadIdle;
Tests: T1 T2 T3
100 end
MISSING_ELSE
101 end
102
103 // when clear is received, delete the selected key
104 // when wipe is received, delete the key and disable sideload until reboot.
105 StSideloadIdle: begin
106 1/1 keys_en = 1'b1;
Tests: T1 T2 T3
107 1/1 if (wipe_key_i) begin
Tests: T1 T2 T3
108 1/1 state_d = StSideloadWipe;
Tests: T14 T15 T37
109 end
MISSING_ELSE
110 end
111
112 StSideloadWipe: begin
113 1/1 keys_en = 1'b0;
Tests: T14 T15 T37
114 1/1 if (!wipe_key_i) begin
Tests: T14 T15 T37
115 1/1 state_d = StSideloadStop;
Tests: T14 T15 T37
116 end
MISSING_ELSE
117 end
118
119 // intentional terminal state
120 StSideloadStop: begin
121 1/1 keys_en = 1'b0;
Tests: T14 T15 T37
122 end
123
124 default: begin
125 fsm_err_o = 1'b1;
126 end
127
128 endcase // unique case (state_q)
129 end
130
131 import prim_mubi_pkg::mubi4_test_true_strict;
132 prim_mubi_pkg::mubi4_t [LastIdx-1:0] hw_key_sel;
133 prim_mubi4_sync #(
134 .NumCopies(int'(LastIdx)),
135 .AsyncOn(0) // clock/reset below is only used for SVAs.
136 ) u_mubi_buf (
137 .clk_i,
138 .rst_ni,
139 .mubi_i(hw_key_sel_i),
140 .mubi_o(hw_key_sel)
141 );
142
143 logic [LastIdx-1:0] slot_sel;
144 1/1 assign slot_sel[AesIdx] = (dest_sel_i == Aes) & mubi4_test_true_strict(hw_key_sel[AesIdx]);
Tests: T1 T2 T3
145 1/1 assign slot_sel[KmacIdx] = (dest_sel_i == Kmac) & mubi4_test_true_strict(hw_key_sel[KmacIdx]);
Tests: T1 T2 T3
146 1/1 assign slot_sel[OtbnIdx] = (dest_sel_i == Otbn) & mubi4_test_true_strict(hw_key_sel[OtbnIdx]);
Tests: T1 T2 T3
147
148 keymgr_sideload_key u_aes_key (
149 .clk_i,
150 .rst_ni,
151 .en_i(keys_en),
152 .set_en_i(data_en_i),
153 .set_i(data_valid_i & slot_sel[AesIdx]),
154 .clr_i(slot_clr[AesIdx]),
155 .entropy_i(entropy_i),
156 .key_i(data_truncated),
157 .valid_o(aes_key_o.valid),
158 .key_o(aes_key_o.key)
159 );
160
161 keymgr_sideload_key #(
162 .Width(OtbnKeyWidth)
163 ) u_otbn_key (
164 .clk_i,
165 .rst_ni,
166 .en_i(keys_en),
167 .set_en_i(data_en_i),
168 .set_i(data_valid_i & slot_sel[OtbnIdx]),
169 .clr_i(slot_clr[OtbnIdx]),
170 .entropy_i(entropy_i),
171 .key_i(data_i),
172 .valid_o(otbn_key_o.valid),
173 .key_o(otbn_key_o.key)
174 );
175
176 hw_key_req_t kmac_sideload_key;
177 keymgr_sideload_key u_kmac_key (
178 .clk_i,
179 .rst_ni,
180 .en_i(keys_en),
181 .set_en_i(data_en_i),
182 .set_i(data_valid_i & slot_sel[KmacIdx]),
183 .clr_i(slot_clr[KmacIdx]),
184 .entropy_i(entropy_i),
185 .key_i(data_truncated),
186 .valid_o(kmac_sideload_key.valid),
187 .key_o(kmac_sideload_key.key)
188 );
189
190 logic [LastIdx-1:0] valid_tracking_q;
191 for (genvar i = int'(AesIdx); i < LastIdx; i++) begin : gen_tracking_valid
192 always_ff @(posedge clk_i or negedge rst_ni) begin
193 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
194 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T2 T3
195 1/1 end else if (slot_clr[i]) begin
Tests: T1 T2 T3
196 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T3 T4
197 1/1 end else if (slot_sel[i])begin
Tests: T1 T2 T3
198 1/1 valid_tracking_q[i] <= 1'b1;
Tests: T14 T17 T18
199 end
MISSING_ELSE
***repeat 1
193 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
194 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T2 T3
195 1/1 end else if (slot_clr[i]) begin
Tests: T1 T2 T3
196 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T3 T4
197 1/1 end else if (slot_sel[i])begin
Tests: T1 T2 T3
198 1/1 valid_tracking_q[i] <= 1'b1;
Tests: T1 T3 T4
199 end
MISSING_ELSE
***repeat 2
193 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
194 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T2 T3
195 1/1 end else if (slot_clr[i]) begin
Tests: T1 T2 T3
196 1/1 valid_tracking_q[i] <= '0;
Tests: T1 T3 T4
197 1/1 end else if (slot_sel[i])begin
Tests: T1 T2 T3
198 1/1 valid_tracking_q[i] <= 1'b1;
Tests: T15 T17 T18
199 end
MISSING_ELSE
200 end
201 end
202
203 // SEC_CM: SIDE_LOAD_SEL.CTRL.CONSISTENCY
204 logic [LastIdx-1:0] valids;
205 1/1 assign valids[AesIdx] = aes_key_o.valid;
Tests: T1 T2 T3
206 1/1 assign valids[KmacIdx] = kmac_sideload_key.valid;
Tests: T1 T2 T3
207 1/1 assign valids[OtbnIdx] = otbn_key_o.valid;
Tests: T1 T2 T3
208
209 // If valid tracking claims a valid should be 0 but 1 is observed, it is
210 // an error.
211 // Note the sideload error is not a direct constant comparision. Instead
212 // it provides hint when valids is allowed to be valid. If valid becomes
213 // 1 outside that window, then an error is triggered.
214 1/1 assign sideload_sel_err_o = |(~valid_tracking_q & valids);
Tests: T1 T2 T3
215
216 // when directed by keymgr_ctrl, switch over to internal key and feed to kmac
217 1/1 assign kmac_key_o = key_i.valid ? key_i : kmac_sideload_key;
Tests: T1 T2 T3
218
219 // when clearing, request prng
220 1/1 assign prng_en_o = clr;
Tests: T1 T2 T3
Cond Coverage for Module :
keymgr_sideload_key_ctrl
| Total | Covered | Percent |
Conditions | 29 | 29 | 100.00 |
Logical | 29 | 29 | 100.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 78
EXPRESSION (wipe_key_i | ((!(clr_key_i inside {SideLoadClrIdle, SideLoadClrAes, SideLoadClrKmac, SideLoadClrOtbn}))))
-----1---- ---------------------------------------------2---------------------------------------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T1,T3,T4 |
1 | 0 | Covered | T14,T15,T37 |
LINE 84
EXPRESSION (clr_all_keys | (clr_key_i == SideLoadClrAes))
------1----- --------------2--------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T1,T3,T4 |
1 | 0 | Covered | T1,T3,T4 |
LINE 84
SUB-EXPRESSION (clr_key_i == SideLoadClrAes)
--------------1--------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T3,T4 |
LINE 85
EXPRESSION (clr_all_keys | (clr_key_i == SideLoadClrKmac))
------1----- ---------------2--------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T3,T14,T18 |
1 | 0 | Covered | T1,T3,T4 |
LINE 85
SUB-EXPRESSION (clr_key_i == SideLoadClrKmac)
---------------1--------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T14,T18 |
LINE 86
EXPRESSION (clr_all_keys | (clr_key_i == SideLoadClrOtbn))
------1----- ---------------2--------------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T3,T15,T17 |
1 | 0 | Covered | T1,T3,T4 |
LINE 86
SUB-EXPRESSION (clr_key_i == SideLoadClrOtbn)
---------------1--------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T15,T17 |
LINE 148
EXPRESSION (data_valid_i & slot_sel[AesIdx])
------1----- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T14,T15,T17 |
1 | 0 | Covered | T1,T2,T3 |
1 | 1 | Covered | T15,T17,T18 |
LINE 163
EXPRESSION (data_valid_i & slot_sel[OtbnIdx])
------1----- --------2--------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T4,T15,T17 |
1 | 0 | Covered | T1,T2,T3 |
1 | 1 | Covered | T17,T18,T35 |
LINE 177
EXPRESSION (data_valid_i & slot_sel[KmacIdx])
------1----- --------2--------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T3,T4 |
1 | 0 | Covered | T1,T2,T4 |
1 | 1 | Covered | T1,T3,T4 |
LINE 217
EXPRESSION (key_i.valid ? key_i : kmac_sideload_key)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
FSM Coverage for Module :
keymgr_sideload_key_ctrl
Summary for FSM :: state_q
| Total | Covered | Percent | |
States |
4 |
4 |
100.00 |
(Not included in score) |
Transitions |
3 |
3 |
100.00 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: state_q
states | Line No. | Covered | Tests |
StSideloadIdle |
99 |
Covered |
T1,T2,T3 |
StSideloadReset |
97 |
Covered |
T1,T2,T3 |
StSideloadStop |
115 |
Covered |
T14,T15,T37 |
StSideloadWipe |
108 |
Covered |
T14,T15,T37 |
transitions | Line No. | Covered | Tests |
StSideloadIdle->StSideloadWipe |
108 |
Covered |
T14,T15,T37 |
StSideloadReset->StSideloadIdle |
99 |
Covered |
T1,T2,T3 |
StSideloadWipe->StSideloadStop |
115 |
Covered |
T14,T15,T37 |
Branch Coverage for Module :
keymgr_sideload_key_ctrl
| Line No. | Total | Covered | Percent |
Branches |
|
24 |
24 |
100.00 |
TERNARY |
217 |
2 |
2 |
100.00 |
IF |
66 |
2 |
2 |
100.00 |
CASE |
96 |
8 |
8 |
100.00 |
IF |
193 |
4 |
4 |
100.00 |
IF |
193 |
4 |
4 |
100.00 |
IF |
193 |
4 |
4 |
100.00 |
217 assign kmac_key_o = key_i.valid ? key_i : kmac_sideload_key;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
66 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, keymgr_sideload_e, StSideloadReset)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
96 unique case (state_q)
-1-
97 StSideloadReset: begin
98 if (init_i) begin
-2-
99 state_d = StSideloadIdle;
==>
100 end
MISSING_ELSE
==>
101 end
102
103 // when clear is received, delete the selected key
104 // when wipe is received, delete the key and disable sideload until reboot.
105 StSideloadIdle: begin
106 keys_en = 1'b1;
107 if (wipe_key_i) begin
-3-
108 state_d = StSideloadWipe;
==>
109 end
MISSING_ELSE
==>
110 end
111
112 StSideloadWipe: begin
113 keys_en = 1'b0;
114 if (!wipe_key_i) begin
-4-
115 state_d = StSideloadStop;
==>
116 end
MISSING_ELSE
==>
117 end
118
119 // intentional terminal state
120 StSideloadStop: begin
121 keys_en = 1'b0;
==>
122 end
123
124 default: begin
125 fsm_err_o = 1'b1;
==>
Branches:
-1- | -2- | -3- | -4- | Status | Tests |
StSideloadReset |
1 |
- |
- |
Covered |
T1,T2,T3 |
StSideloadReset |
0 |
- |
- |
Covered |
T1,T2,T3 |
StSideloadIdle |
- |
1 |
- |
Covered |
T14,T15,T37 |
StSideloadIdle |
- |
0 |
- |
Covered |
T1,T2,T3 |
StSideloadWipe |
- |
- |
1 |
Covered |
T14,T15,T37 |
StSideloadWipe |
- |
- |
0 |
Covered |
T37,T74,T39 |
StSideloadStop |
- |
- |
- |
Covered |
T14,T15,T37 |
default |
- |
- |
- |
Covered |
T10,T11,T12 |
193 if (!rst_ni) begin
-1-
194 valid_tracking_q[i] <= '0;
==>
195 end else if (slot_clr[i]) begin
-2-
196 valid_tracking_q[i] <= '0;
==>
197 end else if (slot_sel[i])begin
-3-
198 valid_tracking_q[i] <= 1'b1;
==>
199 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T1,T3,T4 |
0 |
0 |
1 |
Covered |
T14,T17,T18 |
0 |
0 |
0 |
Covered |
T1,T2,T3 |
193 if (!rst_ni) begin
-1-
194 valid_tracking_q[i] <= '0;
==>
195 end else if (slot_clr[i]) begin
-2-
196 valid_tracking_q[i] <= '0;
==>
197 end else if (slot_sel[i])begin
-3-
198 valid_tracking_q[i] <= 1'b1;
==>
199 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T1,T3,T4 |
0 |
0 |
1 |
Covered |
T1,T3,T4 |
0 |
0 |
0 |
Covered |
T1,T2,T3 |
193 if (!rst_ni) begin
-1-
194 valid_tracking_q[i] <= '0;
==>
195 end else if (slot_clr[i]) begin
-2-
196 valid_tracking_q[i] <= '0;
==>
197 end else if (slot_sel[i])begin
-3-
198 valid_tracking_q[i] <= 1'b1;
==>
199 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T1,T3,T4 |
0 |
0 |
1 |
Covered |
T15,T17,T18 |
0 |
0 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Module :
keymgr_sideload_key_ctrl
Assertion Details
KmacKeySource_a
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
21588661 |
10526 |
0 |
0 |
T1 |
5456 |
7 |
0 |
0 |
T2 |
18058 |
7 |
0 |
0 |
T3 |
17046 |
7 |
0 |
0 |
T4 |
5438 |
4 |
0 |
0 |
T13 |
1307 |
0 |
0 |
0 |
T14 |
4324 |
0 |
0 |
0 |
T15 |
4964 |
8 |
0 |
0 |
T16 |
4832 |
7 |
0 |
0 |
T17 |
9788 |
8 |
0 |
0 |
T18 |
11952 |
17 |
0 |
0 |
T35 |
0 |
7 |
0 |
0 |
T36 |
0 |
7 |
0 |
0 |
u_state_regs_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
21705443 |
21550665 |
0 |
0 |
T1 |
5456 |
5398 |
0 |
0 |
T2 |
18058 |
17959 |
0 |
0 |
T3 |
17046 |
16955 |
0 |
0 |
T4 |
5438 |
5384 |
0 |
0 |
T13 |
1307 |
1207 |
0 |
0 |
T14 |
4324 |
4161 |
0 |
0 |
T15 |
4964 |
4817 |
0 |
0 |
T16 |
4832 |
4772 |
0 |
0 |
T17 |
9788 |
9733 |
0 |
0 |
T18 |
11952 |
11877 |
0 |
0 |