Line Coverage for Module :
keccak_round
| Line No. | Total | Covered | Percent |
TOTAL | | 97 | 64 | 65.98 |
CONT_ASSIGN | 177 | 0 | 0 | |
ALWAYS | 180 | 3 | 3 | 100.00 |
ALWAYS | 186 | 67 | 35 | 52.24 |
CONT_ASSIGN | 407 | 1 | 1 | 100.00 |
CONT_ASSIGN | 439 | 1 | 1 | 100.00 |
CONT_ASSIGN | 450 | 1 | 1 | 100.00 |
ALWAYS | 468 | 6 | 6 | 100.00 |
CONT_ASSIGN | 477 | 1 | 1 | 100.00 |
ALWAYS | 485 | 7 | 7 | 100.00 |
ALWAYS | 507 | 4 | 3 | 75.00 |
CONT_ASSIGN | 518 | 1 | 1 | 100.00 |
CONT_ASSIGN | 548 | 1 | 1 | 100.00 |
CONT_ASSIGN | 549 | 1 | 1 | 100.00 |
CONT_ASSIGN | 551 | 0 | 0 | |
ALWAYS | 575 | 3 | 3 | 100.00 |
176 // state inputs
177 unreachable assign rnd_eq_end = (int'(round) == MaxRound - 1);
178
179 keccak_st_e keccak_st, keccak_st_d;
180 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle):
180.1 `ifdef SIMULATION
180.2 prim_sparse_fsm_flop #(
180.3 .StateEnumT(keccak_st_e),
180.4 .Width($bits(keccak_st_e)),
180.5 .ResetValue($bits(keccak_st_e)'(KeccakStIdle)),
180.6 .EnableAlertTriggerSVA(1),
180.7 .CustomForceName("keccak_st")
180.8 ) u_state_regs (
180.9 .clk_i ( clk_i ),
180.10 .rst_ni ( rst_ni ),
180.11 .state_i ( keccak_st_d ),
180.12 .state_o ( )
180.13 );
180.14 always_ff @(posedge clk_i or negedge rst_ni) begin
180.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
180.16 1/1 keccak_st <= KeccakStIdle;
Tests: T1 T2 T3
180.17 end else begin
180.18 1/1 keccak_st <= keccak_st_d;
Tests: T1 T2 T3
180.19 end
180.20 end
180.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (keccak_st === u_state_regs.state_o))
180.22 else begin
180.23 `ifdef UVM
180.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
180.25 "../src/lowrisc_ip_sha3_0.1/rtl/keccak_round.sv", 180, "", 1);
180.26 `else
180.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
180.28 `PRIM_STRINGIFY(u_state_regs_A));
180.29 `endif
180.30 end
180.31 `else
180.32 prim_sparse_fsm_flop #(
180.33 .StateEnumT(keccak_st_e),
180.34 .Width($bits(keccak_st_e)),
180.35 .ResetValue($bits(keccak_st_e)'(KeccakStIdle)),
180.36 .EnableAlertTriggerSVA(1)
180.37 ) u_state_regs (
180.38 .clk_i ( `PRIM_FLOP_CLK ),
180.39 .rst_ni ( `PRIM_FLOP_RST ),
180.40 .state_i ( keccak_st_d ),
180.41 .state_o ( keccak_st )
180.42 );
180.43 `endif181
182 // Next state logic and output logic
183 // SEC_CM: FSM.SPARSE
184 always_comb begin
185 // Default values
186 1/1 keccak_st_d = keccak_st;
Tests: T1 T2 T3
187
188 1/1 xor_message = 1'b 0;
Tests: T1 T2 T3
189 1/1 update_storage = 1'b 0;
Tests: T1 T2 T3
190 1/1 rst_storage = 1'b 0;
Tests: T1 T2 T3
191
192 1/1 inc_rnd_num = 1'b 0;
Tests: T1 T2 T3
193 1/1 rst_rnd_num = 1'b 0;
Tests: T1 T2 T3
194
195 1/1 keccak_rand_update = 1'b 0;
Tests: T1 T2 T3
196 1/1 keccak_rand_consumed = 1'b 0;
Tests: T1 T2 T3
197
198 1/1 phase_sel = MuBi4False;
Tests: T1 T2 T3
199 1/1 low_then_high_d = low_then_high_q;
Tests: T1 T2 T3
200 1/1 dom_in_low_d = dom_in_low_q;
Tests: T1 T2 T3
201 1/1 dom_in_rand_ext_d = dom_in_rand_ext_q;
Tests: T1 T2 T3
202 1/1 dom_update = 1'b 0;
Tests: T1 T2 T3
203
204 1/1 complete_d = 1'b 0;
Tests: T1 T2 T3
205
206 1/1 sparse_fsm_error_o = 1'b 0;
Tests: T1 T2 T3
207
208 1/1 unique case (keccak_st)
Tests: T1 T2 T3
209 KeccakStIdle: begin
210 1/1 if (valid_i) begin
Tests: T1 T2 T3
211 // State machine allows Sponge Absorbing only in Idle state.
212 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T4
213
214 1/1 xor_message = 1'b 1;
Tests: T1 T2 T4
215 1/1 update_storage = 1'b 1;
Tests: T1 T2 T4
216 1/1 end else if (prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin
Tests: T1 T2 T3
217 // Opt1. State machine allows resetting the storage only in Idle
218 // Opt2. storage resets regardless of states but clear_i
219 // Both are added in the design at this time. Will choose the
220 // direction later.
221 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T5
222
223 1/1 rst_storage = 1'b 1;
Tests: T1 T2 T5
224 1/1 end else if (EnMasking && run_i) begin
Tests: T1 T2 T3
225 // Masked version of Keccak handling
226 unreachable keccak_st_d = KeccakStPhase1;
227
228 // Drive DOM multiplier I/O mux signals for Phase 1.
229 unreachable dom_in_low_d = low_then_high_q;
230 unreachable dom_in_rand_ext_d = 1'b 0;
231 1/1 end else if (!EnMasking && run_i) begin
Tests: T1 T2 T3
232 // Unmasked version of Keccak handling
233 1/1 keccak_st_d = KeccakStActive;
Tests: T1 T2 T4
234 end else begin
235 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T3
236 end
237 end
238
239 KeccakStActive: begin
240 // Run Keccak single round logic until it reaches MaxRound - 1
241 1/1 update_storage = 1'b 1;
Tests: T1 T2 T4
242
243 1/1 if (rnd_eq_end) begin
Tests: T1 T2 T4
244 unreachable keccak_st_d = KeccakStIdle;
245
246 unreachable rst_rnd_num = 1'b 1;
247 unreachable complete_d = 1'b 1;
248 end else begin
249 1/1 keccak_st_d = KeccakStActive;
Tests: T1 T2 T4
250
251 1/1 inc_rnd_num = 1'b 1;
Tests: T1 T2 T4
252 end
253 end
254
255 KeccakStPhase1: begin
256 // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at
257 // all: their inputs are driven by the first lane halves (same values
258 // as in Phase2Cycle3 of the last round). Also, the intermediate
259 // results we already had in Phase2Cycle3 didn't change.
260 0/1 ==> phase_sel = MuBi4False;
261 0/1 ==> dom_update = 1'b 0;
262
263 // Only update the state and move on once we know the auxiliary
264 // randomness required for Phase2 will be available in the next clock
265 // cycle.
266 //
267 // It's important that the DOM multipliers inside keccak_2share are
268 // presented the new state (updated with update_storage) at the same
269 // time as the new randomness (updated with rand_update_o). Otherwise,
270 // stale entropy is paired with fresh data or vice versa. This could
271 // lead to undesired SCA leakage.
272 0/1 ==> if (rand_early_i || rand_valid_i) begin
273 0/1 ==> keccak_st_d = KeccakStPhase2Cycle1;
274 0/1 ==> update_storage = 1'b 1;
275 0/1 ==> keccak_rand_update = 1'b 1;
276
277 // Update lane halves processing order for this round.
278 0/1 ==> low_then_high_d = rand_aux_i;
279
280 // Drive DOM multiplier I/O mux signals for next phase.
281 0/1 ==> dom_in_low_d = low_then_high_d;
282 0/1 ==> dom_in_rand_ext_d = 1'b 1;
283 end else begin
284 unreachable keccak_st_d = KeccakStPhase1;
285 end
286 end
287
288 KeccakStPhase2Cycle1: begin
289 // Compute first stage of Chi for first lane halves using the DOM
290 // multipliers. Use the fresh randomness provided by the PRNG for
291 // remasking.
292 0/1 ==> phase_sel = MuBi4True;
293 0/1 ==> dom_update = 1'b 1;
294
295 // Trigger randomness update for next cycle.
296 // It's important that the DOM multipliers inside keccak_2share are
297 // presented the second lane halves at the same time as the new
298 // randomness (updated with rand_update_o). Otherwise, stale entropy
299 // is paired with fresh data or vice versa. This could lead to
300 // undesired SCA leakage.
301 0/1 ==> keccak_rand_update = 1'b 1;
302
303 // Unconditionally move to next phase/cycle.
304 0/1 ==> keccak_st_d = KeccakStPhase2Cycle2;
305
306 // Drive DOM multiplier I/O mux signals for next phase.
307 0/1 ==> dom_in_low_d = ~low_then_high_q;
308 0/1 ==> dom_in_rand_ext_d = 1'b 1;
309 end
310
311 KeccakStPhase2Cycle2: begin
312 // Chi Stage 1 for second lane halves.
313 // Chi Stage 2 and Iota for first lane halves.
314 // Compute second stage of Chi and Iota for first lane halves.
315 // Compute first stage of Chi for second lane halves. Use the fresh
316 // randomness provided by the PRNG for remasking the DOM multipliers.
317 0/1 ==> phase_sel = MuBi4True;
318 0/1 ==> dom_update = 1'b 1;
319
320 // Trigger randomness update for next cycle.
321 // It's important that the DOM multipliers inside keccak_2share are
322 // presented the updated state at the same as the new randomness
323 // (updated with rand_update_o) - even if the DOM multipliers don't
324 // update the pipeline registers in the next cycle. Otherwise, stale
325 // entropy is paired with fresh data or vice versa. This could lead to
326 // undesired SCA leakage.
327 0/1 ==> keccak_rand_update = 1'b 1;
328
329 // Trigger auxiliary randomness update for next round. The rand_aux_i
330 // signal is actually going to change in 2 clock cycles from now
331 // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3)
332 // in which the DOM multipliers don't update the pipeline registers.
333 0/1 ==> keccak_rand_consumed = 1'b 1;
334
335 // Update first lane halves.
336 0/1 ==> update_storage = 1'b 1;
337
338 // Unconditionally move to next phase/cycle.
339 0/1 ==> keccak_st_d = KeccakStPhase2Cycle3;
340
341 // Drive DOM multiplier I/O mux signals for next phase.
342 0/1 ==> dom_in_low_d = low_then_high_q;
343 0/1 ==> dom_in_rand_ext_d = 1'b 0;
344 end
345
346 KeccakStPhase2Cycle3: begin
347 // Compute second stage of Chi and Iota for second lane halves.
348 // Feed again first lane halves to DOM multiplier inputs (now
349 // the updated values become visible) together with intermediate
350 // results of Phase2Cycle2. Don't update the register stage inside
351 // the DOM multipliers.
352 0/1 ==> phase_sel = MuBi4True;
353 0/1 ==> dom_update = 1'b 0;
354
355 // Update second lane halves.
356 // We don't need fresh randomness for the next cycle as the DOM
357 // multipliers inside keccak_2share will keep seeing the first
358 // lane halves in the next cycle. If we updated the randomness,
359 // old data got combined with frash randomness which is not
360 // desirable as it could lead to SCA leakage.
361 0/1 ==> update_storage = 1'b 1;
362
363 0/1 ==> if (rnd_eq_end) begin
364 // We're done.
365 unreachable keccak_st_d = KeccakStIdle;
366
367 unreachable rst_rnd_num = 1'b 1;
368 unreachable complete_d = 1'b 1;
369 end else begin
370 // Continue to the next round.
371 0/1 ==> keccak_st_d = KeccakStPhase1;
372
373 0/1 ==> inc_rnd_num = 1'b 1;
374
375 // Drive DOM multiplier I/O mux signals for next phase.
376 0/1 ==> dom_in_low_d = low_then_high_q;
377 0/1 ==> dom_in_rand_ext_d = 1'b 0;
378 end
379 end
380
381 KeccakStError: begin
382 0/1 ==> keccak_st_d = KeccakStError;
383 end
384
385 KeccakStTerminalError: begin
386 //this state is terminal
387 1/1 keccak_st_d = keccak_st;
Tests: T4 T6 T7
388 1/1 sparse_fsm_error_o = 1'b 1;
Tests: T4 T6 T7
389 end
390
391 default: begin
392 keccak_st_d = KeccakStTerminalError;
393 sparse_fsm_error_o = 1'b 1;
394 end
395 endcase
396
397 // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC
398 // Unconditionally jump into the terminal error state
399 // if the life cycle controller triggers an escalation.
400 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin
Tests: T1 T2 T3
401 1/1 keccak_st_d = KeccakStTerminalError;
Tests: T4 T6 T7
402 end
MISSING_ELSE
403 end
404
405 // When taking the lower lane halves in, the upper lane halves are output and
406 // vice versa.
407 1/1 assign dom_out_low_d = ~dom_in_low_d;
Tests: T1 T2 T3
408
409 if (EnMasking) begin : gen_regs_dom_ctrl
410 always_ff @(posedge clk_i or negedge rst_ni) begin
411 if (!rst_ni) begin
412 low_then_high_q <= 1'b 0;
413 dom_out_low_q <= 1'b 0;
414 dom_in_low_q <= 1'b 0;
415 end else begin
416 low_then_high_q <= low_then_high_d;
417 dom_out_low_q <= dom_out_low_d;
418 dom_in_low_q <= dom_in_low_d;
419 end
420 end
421
422 if (!ForceRandExt) begin : gen_reg_dom_in_rand_ext
423 always_ff @(posedge clk_i or negedge rst_ni) begin
424 if (!rst_ni) begin
425 dom_in_rand_ext_q <= 1'b 0;
426 end else begin
427 dom_in_rand_ext_q <= dom_in_rand_ext_d;
428 end
429 end
430 end else begin : gen_force_dom_in_rand_ext
431 // Always forward the externally provided randomness.
432 assign dom_in_rand_ext_q = 1'b 1;
433 // Tie off unused signals.
434 logic unused_dom_in_rand_ext;
435 assign unused_dom_in_rand_ext = dom_in_rand_ext_d;
436 end
437 end else begin : gen_no_regs_dom_ctrl
438 logic unused_dom_ctrl;
439 1/1 assign unused_dom_ctrl =
Tests: T1 T2 T3
440 ^{low_then_high_d, dom_out_low_d, dom_in_low_d, dom_in_rand_ext_d};
441 assign low_then_high_q = 1'b 0;
442 assign dom_out_low_q = 1'b 0;
443 assign dom_in_low_q = 1'b 0;
444 assign dom_in_rand_ext_q = 1'b 0;
445 end
446
447 // Ready indicates the keccak_round is able to receive new message.
448 // While keccak_round is processing the data, it blocks the new message to be
449 // XORed into the current state.
450 1/1 assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0;
Tests: T1 T2 T3
451
452 ////////////////////////////
453 // Keccak state registers //
454 ////////////////////////////
455
456 // SEC_CM: LOGIC.INTEGRITY
457 logic rst_n;
458 prim_sec_anchor_buf #(
459 .Width(1)
460 ) u_prim_sec_anchor_buf (
461 .in_i(rst_ni),
462 .out_o(rst_n)
463 );
464
465 logic [Width-1:0] storage [Share];
466 logic [Width-1:0] storage_d [Share];
467 always_ff @(posedge clk_i or negedge rst_n) begin
468 1/1 if (!rst_n) begin
Tests: T1 T2 T3
469 1/1 storage <= '{default:'0};
Tests: T1 T2 T3
470 1/1 end else if (rst_storage) begin
Tests: T1 T2 T3
471 1/1 storage <= '{default:'0};
Tests: T1 T2 T5
472 1/1 end else if (update_storage) begin
Tests: T1 T2 T3
473 1/1 storage <= storage_d;
Tests: T1 T2 T4
474 end
MISSING_ELSE
475 end
476
477 1/1 assign state_o = storage;
Tests: T1 T2 T3
478
479 // Storage register input
480 // The incoming message is XORed with the existing storage registers.
481 // The logic can accept not a block size incoming message chunk but
482 // the size defined in `DInWidth` parameter with its position.
483
484 always_comb begin
485 1/1 storage_d = keccak_out;
Tests: T1 T2 T3
486 1/1 if (xor_message) begin
Tests: T1 T2 T3
487 1/1 for (int j = 0 ; j < Share ; j++) begin
Tests: T1 T2 T4
488 1/1 for (int unsigned i = 0 ; i < DInEntry ; i++) begin
Tests: T1 T2 T4
489 // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth
490 // Currently it is not allowed to have partial write
491 // Please see the Assertion `WidthDivisableByDInWidth_A`
492 1/1 if (addr_i == i[DInAddr-1:0]) begin
Tests: T1 T2 T4
493 1/1 storage_d[j][i*DInWidth+:DInWidth] =
Tests: T1 T2 T4
494 storage[j][i*DInWidth+:DInWidth] ^ data_i[j];
495 end else begin
496 1/1 storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth];
Tests: T1 T2 T4
497 end
498 end // for i
499 end // for j
500 end // if xor_message
MISSING_ELSE
501 end
502
503 // Check the rst_storage integrity
504 logic rst_storage_error;
505
506 always_comb begin : chk_rst_storage
507 1/1 rst_storage_error = 1'b 0;
Tests: T1 T2 T3
508
509 1/1 if (rst_storage) begin
Tests: T1 T2 T3
510 // FSM should be in KeccakStIdle and clear_i should be high
511 1/1 if ((keccak_st != KeccakStIdle) ||
Tests: T1 T2 T5
512 prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin
513 0/1 ==> rst_storage_error = 1'b 1;
514 end
MISSING_ELSE
515 end
MISSING_ELSE
516 end : chk_rst_storage
517
518 1/1 assign rst_storage_error_o = rst_storage_error ;
Tests: T1 T2 T3
519
520 //////////////
521 // Datapath //
522 //////////////
523 keccak_2share #(
524 .Width(Width),
525 .EnMasking(EnMasking),
526 .ForceRandExt(ForceRandExt)
527 ) u_keccak_p (
528 .clk_i,
529 .rst_ni,
530
531 .lc_escalate_en_i,
532
533 .rnd_i(round),
534
535 .phase_sel_i (phase_sel),
536 .dom_out_low_i (dom_out_low_q),
537 .dom_in_low_i (dom_in_low_q),
538 .dom_in_rand_ext_i(dom_in_rand_ext_q),
539 .dom_update_i (dom_update),
540
541 .rand_i(keccak_rand_data),
542
543 .s_i(storage),
544 .s_o(keccak_out)
545 );
546
547 // keccak entropy handling
548 1/1 assign rand_update_o = keccak_rand_update;
Tests: T1 T2 T3
549 1/1 assign rand_consumed_o = keccak_rand_consumed;
Tests: T1 T2 T3
550
551 unreachable assign keccak_rand_data = rand_data_i;
552
553 // Round number
554 // This primitive is used to place a hardened counter
555 // SEC_CM: CTR.REDUN
556 prim_count #(
557 .Width(RndW)
558 ) u_round_count (
559 .clk_i,
560 .rst_ni,
561 .clr_i(rst_rnd_num),
562 .set_i(1'b0),
563 .set_cnt_i('0),
564 .incr_en_i(inc_rnd_num),
565 .decr_en_i(1'b0),
566 .step_i(RndW'(1)),
567 .commit_i(1'b1),
568 .cnt_o(round),
569 .cnt_after_commit_o(),
570 .err_o(round_count_error_o)
571 );
572
573 // completion signal
574 always_ff @(posedge clk_i or negedge rst_ni) begin
575 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
576 1/1 complete_o <= 1'b 0;
Tests: T1 T2 T3
577 end else begin
578 1/1 complete_o <= complete_d;
Tests: T1 T2 T3
Cond Coverage for Module :
keccak_round
| Total | Covered | Percent |
Conditions | 9 | 9 | 100.00 |
Logical | 9 | 9 | 100.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 177
EXPRESSION (int'(round) == (MaxRound - 1))
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Unreachable | T1,T2,T5 |
LINE 231
EXPRESSION (((!EnMasking)) && run_i)
-------1------ --2--
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T2,T4 |
LINE 272
EXPRESSION (rand_early_i || rand_valid_i)
------1----- ------2-----
-1- | -2- | Status | Tests |
0 | 0 | Unreachable | |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
LINE 450
EXPRESSION ((keccak_st == KeccakStIdle) ? 1'b1 : 1'b0)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T1,T2,T4 |
1 | Covered | T1,T2,T3 |
LINE 450
SUB-EXPRESSION (keccak_st == KeccakStIdle)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 492
EXPRESSION (addr_i == i[(DInAddr - 1):0])
---------------1--------------
-1- | Status | Tests |
0 | Covered | T1,T2,T4 |
1 | Covered | T1,T2,T4 |
FSM Coverage for Module :
keccak_round
Summary for FSM :: keccak_st
| Total | Covered | Percent | |
States |
8 |
3 |
37.50 |
(Not included in score) |
Transitions |
15 |
4 |
26.67 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: keccak_st
states | Line No. | Covered | Tests |
KeccakStActive |
233 |
Covered |
T1,T2,T4 |
KeccakStError |
382 |
Not Covered |
|
KeccakStIdle |
212 |
Covered |
T1,T2,T3 |
KeccakStPhase1 |
226 |
Not Covered |
|
KeccakStPhase2Cycle1 |
273 |
Not Covered |
|
KeccakStPhase2Cycle2 |
304 |
Not Covered |
|
KeccakStPhase2Cycle3 |
339 |
Not Covered |
|
KeccakStTerminalError |
401 |
Covered |
T4,T6,T7 |
transitions | Line No. | Covered | Tests |
KeccakStActive->KeccakStIdle |
244 |
Covered |
T1,T2,T5 |
KeccakStActive->KeccakStTerminalError |
401 |
Covered |
T4,T7,T8 |
KeccakStError->KeccakStTerminalError |
401 |
Not Covered |
|
KeccakStIdle->KeccakStActive |
233 |
Covered |
T1,T2,T4 |
KeccakStIdle->KeccakStPhase1 |
226 |
Not Covered |
|
KeccakStIdle->KeccakStTerminalError |
401 |
Covered |
T6,T9,T10 |
KeccakStPhase1->KeccakStPhase2Cycle1 |
273 |
Not Covered |
|
KeccakStPhase1->KeccakStTerminalError |
401 |
Not Covered |
|
KeccakStPhase2Cycle1->KeccakStPhase2Cycle2 |
304 |
Not Covered |
|
KeccakStPhase2Cycle1->KeccakStTerminalError |
401 |
Not Covered |
|
KeccakStPhase2Cycle2->KeccakStPhase2Cycle3 |
339 |
Not Covered |
|
KeccakStPhase2Cycle2->KeccakStTerminalError |
401 |
Not Covered |
|
KeccakStPhase2Cycle3->KeccakStIdle |
365 |
Not Covered |
|
KeccakStPhase2Cycle3->KeccakStPhase1 |
371 |
Not Covered |
|
KeccakStPhase2Cycle3->KeccakStTerminalError |
401 |
Not Covered |
|
Branch Coverage for Module :
keccak_round
| Line No. | Total | Covered | Percent |
Branches |
|
29 |
23 |
79.31 |
TERNARY |
450 |
2 |
2 |
100.00 |
IF |
180 |
2 |
2 |
100.00 |
CASE |
208 |
12 |
7 |
58.33 |
IF |
400 |
2 |
2 |
100.00 |
IF |
468 |
4 |
4 |
100.00 |
IF |
486 |
2 |
2 |
100.00 |
IF |
509 |
3 |
2 |
66.67 |
IF |
575 |
2 |
2 |
100.00 |
450 assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T4 |
180 `PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
208 unique case (keccak_st)
-1-
209 KeccakStIdle: begin
210 if (valid_i) begin
-2-
211 // State machine allows Sponge Absorbing only in Idle state.
212 keccak_st_d = KeccakStIdle;
==>
213
214 xor_message = 1'b 1;
215 update_storage = 1'b 1;
216 end else if (prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin
-3-
217 // Opt1. State machine allows resetting the storage only in Idle
218 // Opt2. storage resets regardless of states but clear_i
219 // Both are added in the design at this time. Will choose the
220 // direction later.
221 keccak_st_d = KeccakStIdle;
==>
222
223 rst_storage = 1'b 1;
224 end else if (EnMasking && run_i) begin
-4-
225 // Masked version of Keccak handling
226 keccak_st_d = KeccakStPhase1;
==> (Unreachable)
227
228 // Drive DOM multiplier I/O mux signals for Phase 1.
229 dom_in_low_d = low_then_high_q;
230 dom_in_rand_ext_d = 1'b 0;
231 end else if (!EnMasking && run_i) begin
-5-
232 // Unmasked version of Keccak handling
233 keccak_st_d = KeccakStActive;
==>
234 end else begin
235 keccak_st_d = KeccakStIdle;
==>
236 end
237 end
238
239 KeccakStActive: begin
240 // Run Keccak single round logic until it reaches MaxRound - 1
241 update_storage = 1'b 1;
242
243 if (rnd_eq_end) begin
-6-
244 keccak_st_d = KeccakStIdle;
==> (Unreachable)
245
246 rst_rnd_num = 1'b 1;
247 complete_d = 1'b 1;
248 end else begin
249 keccak_st_d = KeccakStActive;
==>
250
251 inc_rnd_num = 1'b 1;
252 end
253 end
254
255 KeccakStPhase1: begin
256 // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at
257 // all: their inputs are driven by the first lane halves (same values
258 // as in Phase2Cycle3 of the last round). Also, the intermediate
259 // results we already had in Phase2Cycle3 didn't change.
260 phase_sel = MuBi4False;
261 dom_update = 1'b 0;
262
263 // Only update the state and move on once we know the auxiliary
264 // randomness required for Phase2 will be available in the next clock
265 // cycle.
266 //
267 // It's important that the DOM multipliers inside keccak_2share are
268 // presented the new state (updated with update_storage) at the same
269 // time as the new randomness (updated with rand_update_o). Otherwise,
270 // stale entropy is paired with fresh data or vice versa. This could
271 // lead to undesired SCA leakage.
272 if (rand_early_i || rand_valid_i) begin
-7-
273 keccak_st_d = KeccakStPhase2Cycle1;
==>
274 update_storage = 1'b 1;
275 keccak_rand_update = 1'b 1;
276
277 // Update lane halves processing order for this round.
278 low_then_high_d = rand_aux_i;
279
280 // Drive DOM multiplier I/O mux signals for next phase.
281 dom_in_low_d = low_then_high_d;
282 dom_in_rand_ext_d = 1'b 1;
283 end else begin
284 keccak_st_d = KeccakStPhase1;
==> (Unreachable)
285 end
286 end
287
288 KeccakStPhase2Cycle1: begin
289 // Compute first stage of Chi for first lane halves using the DOM
290 // multipliers. Use the fresh randomness provided by the PRNG for
291 // remasking.
292 phase_sel = MuBi4True;
==>
293 dom_update = 1'b 1;
294
295 // Trigger randomness update for next cycle.
296 // It's important that the DOM multipliers inside keccak_2share are
297 // presented the second lane halves at the same time as the new
298 // randomness (updated with rand_update_o). Otherwise, stale entropy
299 // is paired with fresh data or vice versa. This could lead to
300 // undesired SCA leakage.
301 keccak_rand_update = 1'b 1;
302
303 // Unconditionally move to next phase/cycle.
304 keccak_st_d = KeccakStPhase2Cycle2;
305
306 // Drive DOM multiplier I/O mux signals for next phase.
307 dom_in_low_d = ~low_then_high_q;
308 dom_in_rand_ext_d = 1'b 1;
309 end
310
311 KeccakStPhase2Cycle2: begin
312 // Chi Stage 1 for second lane halves.
313 // Chi Stage 2 and Iota for first lane halves.
314 // Compute second stage of Chi and Iota for first lane halves.
315 // Compute first stage of Chi for second lane halves. Use the fresh
316 // randomness provided by the PRNG for remasking the DOM multipliers.
317 phase_sel = MuBi4True;
==>
318 dom_update = 1'b 1;
319
320 // Trigger randomness update for next cycle.
321 // It's important that the DOM multipliers inside keccak_2share are
322 // presented the updated state at the same as the new randomness
323 // (updated with rand_update_o) - even if the DOM multipliers don't
324 // update the pipeline registers in the next cycle. Otherwise, stale
325 // entropy is paired with fresh data or vice versa. This could lead to
326 // undesired SCA leakage.
327 keccak_rand_update = 1'b 1;
328
329 // Trigger auxiliary randomness update for next round. The rand_aux_i
330 // signal is actually going to change in 2 clock cycles from now
331 // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3)
332 // in which the DOM multipliers don't update the pipeline registers.
333 keccak_rand_consumed = 1'b 1;
334
335 // Update first lane halves.
336 update_storage = 1'b 1;
337
338 // Unconditionally move to next phase/cycle.
339 keccak_st_d = KeccakStPhase2Cycle3;
340
341 // Drive DOM multiplier I/O mux signals for next phase.
342 dom_in_low_d = low_then_high_q;
343 dom_in_rand_ext_d = 1'b 0;
344 end
345
346 KeccakStPhase2Cycle3: begin
347 // Compute second stage of Chi and Iota for second lane halves.
348 // Feed again first lane halves to DOM multiplier inputs (now
349 // the updated values become visible) together with intermediate
350 // results of Phase2Cycle2. Don't update the register stage inside
351 // the DOM multipliers.
352 phase_sel = MuBi4True;
353 dom_update = 1'b 0;
354
355 // Update second lane halves.
356 // We don't need fresh randomness for the next cycle as the DOM
357 // multipliers inside keccak_2share will keep seeing the first
358 // lane halves in the next cycle. If we updated the randomness,
359 // old data got combined with frash randomness which is not
360 // desirable as it could lead to SCA leakage.
361 update_storage = 1'b 1;
362
363 if (rnd_eq_end) begin
-8-
364 // We're done.
365 keccak_st_d = KeccakStIdle;
==> (Unreachable)
366
367 rst_rnd_num = 1'b 1;
368 complete_d = 1'b 1;
369 end else begin
370 // Continue to the next round.
371 keccak_st_d = KeccakStPhase1;
==>
372
373 inc_rnd_num = 1'b 1;
374
375 // Drive DOM multiplier I/O mux signals for next phase.
376 dom_in_low_d = low_then_high_q;
377 dom_in_rand_ext_d = 1'b 0;
378 end
379 end
380
381 KeccakStError: begin
382 keccak_st_d = KeccakStError;
==>
383 end
384
385 KeccakStTerminalError: begin
386 //this state is terminal
387 keccak_st_d = keccak_st;
==>
388 sparse_fsm_error_o = 1'b 1;
389 end
390
391 default: begin
392 keccak_st_d = KeccakStTerminalError;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | Status | Tests |
KeccakStIdle |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T4 |
KeccakStIdle |
0 |
1 |
- |
- |
- |
- |
- |
Covered |
T1,T2,T5 |
KeccakStIdle |
0 |
0 |
1 |
- |
- |
- |
- |
Unreachable |
|
KeccakStIdle |
0 |
0 |
0 |
1 |
- |
- |
- |
Covered |
T1,T2,T4 |
KeccakStIdle |
0 |
0 |
0 |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
KeccakStActive |
- |
- |
- |
- |
1 |
- |
- |
Unreachable |
T1,T2,T5 |
KeccakStActive |
- |
- |
- |
- |
0 |
- |
- |
Covered |
T1,T2,T4 |
KeccakStPhase1 |
- |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
KeccakStPhase1 |
- |
- |
- |
- |
- |
0 |
- |
Unreachable |
|
KeccakStPhase2Cycle1 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStPhase2Cycle2 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStPhase2Cycle3 |
- |
- |
- |
- |
- |
- |
1 |
Unreachable |
|
KeccakStPhase2Cycle3 |
- |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
KeccakStError |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStTerminalError |
- |
- |
- |
- |
- |
- |
- |
Covered |
T4,T6,T7 |
default |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T9,T11 |
400 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin
-1-
401 keccak_st_d = KeccakStTerminalError;
==>
402 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T4,T6,T7 |
0 |
Covered |
T1,T2,T3 |
468 if (!rst_n) begin
-1-
469 storage <= '{default:'0};
==>
470 end else if (rst_storage) begin
-2-
471 storage <= '{default:'0};
==>
472 end else if (update_storage) begin
-3-
473 storage <= storage_d;
==>
474 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T1,T2,T5 |
0 |
0 |
1 |
Covered |
T1,T2,T4 |
0 |
0 |
0 |
Covered |
T1,T2,T3 |
486 if (xor_message) begin
-1-
487 for (int j = 0 ; j < Share ; j++) begin
==>
488 for (int unsigned i = 0 ; i < DInEntry ; i++) begin
489 // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth
490 // Currently it is not allowed to have partial write
491 // Please see the Assertion `WidthDivisableByDInWidth_A`
492 if (addr_i == i[DInAddr-1:0]) begin
493 storage_d[j][i*DInWidth+:DInWidth] =
494 storage[j][i*DInWidth+:DInWidth] ^ data_i[j];
495 end else begin
496 storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth];
497 end
498 end // for i
499 end // for j
500 end // if xor_message
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T4 |
0 |
Covered |
T1,T2,T3 |
509 if (rst_storage) begin
-1-
510 // FSM should be in KeccakStIdle and clear_i should be high
511 if ((keccak_st != KeccakStIdle) ||
-2-
512 prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin
513 rst_storage_error = 1'b 1;
==>
514 end
MISSING_ELSE
==>
515 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Not Covered |
|
1 |
0 |
Covered |
T1,T2,T5 |
0 |
- |
Covered |
T1,T2,T3 |
575 if (!rst_ni) begin
-1-
576 complete_o <= 1'b 0;
==>
577 end else begin
578 complete_o <= complete_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Module :
keccak_round
Assertion Details
ClearAssertStIdle_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
55012 |
0 |
0 |
T1 |
2648 |
3 |
0 |
0 |
T2 |
5465 |
3 |
0 |
0 |
T3 |
933 |
0 |
0 |
0 |
T4 |
2633 |
0 |
0 |
0 |
T5 |
11640 |
1 |
0 |
0 |
T12 |
117788 |
12 |
0 |
0 |
T13 |
61338 |
5 |
0 |
0 |
T14 |
5366 |
3 |
0 |
0 |
T15 |
36858 |
72 |
0 |
0 |
T16 |
238280 |
59 |
0 |
0 |
T17 |
0 |
3 |
0 |
0 |
T18 |
0 |
83 |
0 |
0 |
OneHot0ValidAndRun_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |
ValidRunAssertStIdle_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
15575101 |
0 |
0 |
T1 |
2648 |
220 |
0 |
0 |
T2 |
5465 |
220 |
0 |
0 |
T3 |
933 |
0 |
0 |
0 |
T4 |
2633 |
22 |
0 |
0 |
T5 |
11640 |
112 |
0 |
0 |
T12 |
117788 |
648 |
0 |
0 |
T13 |
61338 |
519 |
0 |
0 |
T14 |
5366 |
220 |
0 |
0 |
T15 |
36858 |
3261 |
0 |
0 |
T16 |
238280 |
6598 |
0 |
0 |
T17 |
0 |
198 |
0 |
0 |
WidthDivisableByDInWidth_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
669 |
669 |
0 |
0 |
T1 |
1 |
1 |
0 |
0 |
T2 |
1 |
1 |
0 |
0 |
T3 |
1 |
1 |
0 |
0 |
T4 |
1 |
1 |
0 |
0 |
T5 |
1 |
1 |
0 |
0 |
T12 |
1 |
1 |
0 |
0 |
T13 |
1 |
1 |
0 |
0 |
T14 |
1 |
1 |
0 |
0 |
T15 |
1 |
1 |
0 |
0 |
T16 |
1 |
1 |
0 |
0 |
gen_unmask_st_chk.UnmaskValidStates_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |
u_state_regs_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |
Line Coverage for Instance : tb.dut.u_sha3.u_keccak
| Line No. | Total | Covered | Percent |
TOTAL | | 97 | 64 | 65.98 |
CONT_ASSIGN | 177 | 0 | 0 | |
ALWAYS | 180 | 3 | 3 | 100.00 |
ALWAYS | 186 | 67 | 35 | 52.24 |
CONT_ASSIGN | 407 | 1 | 1 | 100.00 |
CONT_ASSIGN | 439 | 1 | 1 | 100.00 |
CONT_ASSIGN | 450 | 1 | 1 | 100.00 |
ALWAYS | 468 | 6 | 6 | 100.00 |
CONT_ASSIGN | 477 | 1 | 1 | 100.00 |
ALWAYS | 485 | 7 | 7 | 100.00 |
ALWAYS | 507 | 4 | 3 | 75.00 |
CONT_ASSIGN | 518 | 1 | 1 | 100.00 |
CONT_ASSIGN | 548 | 1 | 1 | 100.00 |
CONT_ASSIGN | 549 | 1 | 1 | 100.00 |
CONT_ASSIGN | 551 | 0 | 0 | |
ALWAYS | 575 | 3 | 3 | 100.00 |
176 // state inputs
177 unreachable assign rnd_eq_end = (int'(round) == MaxRound - 1);
178
179 keccak_st_e keccak_st, keccak_st_d;
180 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle):
180.1 `ifdef SIMULATION
180.2 prim_sparse_fsm_flop #(
180.3 .StateEnumT(keccak_st_e),
180.4 .Width($bits(keccak_st_e)),
180.5 .ResetValue($bits(keccak_st_e)'(KeccakStIdle)),
180.6 .EnableAlertTriggerSVA(1),
180.7 .CustomForceName("keccak_st")
180.8 ) u_state_regs (
180.9 .clk_i ( clk_i ),
180.10 .rst_ni ( rst_ni ),
180.11 .state_i ( keccak_st_d ),
180.12 .state_o ( )
180.13 );
180.14 always_ff @(posedge clk_i or negedge rst_ni) begin
180.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
180.16 1/1 keccak_st <= KeccakStIdle;
Tests: T1 T2 T3
180.17 end else begin
180.18 1/1 keccak_st <= keccak_st_d;
Tests: T1 T2 T3
180.19 end
180.20 end
180.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (keccak_st === u_state_regs.state_o))
180.22 else begin
180.23 `ifdef UVM
180.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
180.25 "../src/lowrisc_ip_sha3_0.1/rtl/keccak_round.sv", 180, "", 1);
180.26 `else
180.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
180.28 `PRIM_STRINGIFY(u_state_regs_A));
180.29 `endif
180.30 end
180.31 `else
180.32 prim_sparse_fsm_flop #(
180.33 .StateEnumT(keccak_st_e),
180.34 .Width($bits(keccak_st_e)),
180.35 .ResetValue($bits(keccak_st_e)'(KeccakStIdle)),
180.36 .EnableAlertTriggerSVA(1)
180.37 ) u_state_regs (
180.38 .clk_i ( `PRIM_FLOP_CLK ),
180.39 .rst_ni ( `PRIM_FLOP_RST ),
180.40 .state_i ( keccak_st_d ),
180.41 .state_o ( keccak_st )
180.42 );
180.43 `endif181
182 // Next state logic and output logic
183 // SEC_CM: FSM.SPARSE
184 always_comb begin
185 // Default values
186 1/1 keccak_st_d = keccak_st;
Tests: T1 T2 T3
187
188 1/1 xor_message = 1'b 0;
Tests: T1 T2 T3
189 1/1 update_storage = 1'b 0;
Tests: T1 T2 T3
190 1/1 rst_storage = 1'b 0;
Tests: T1 T2 T3
191
192 1/1 inc_rnd_num = 1'b 0;
Tests: T1 T2 T3
193 1/1 rst_rnd_num = 1'b 0;
Tests: T1 T2 T3
194
195 1/1 keccak_rand_update = 1'b 0;
Tests: T1 T2 T3
196 1/1 keccak_rand_consumed = 1'b 0;
Tests: T1 T2 T3
197
198 1/1 phase_sel = MuBi4False;
Tests: T1 T2 T3
199 1/1 low_then_high_d = low_then_high_q;
Tests: T1 T2 T3
200 1/1 dom_in_low_d = dom_in_low_q;
Tests: T1 T2 T3
201 1/1 dom_in_rand_ext_d = dom_in_rand_ext_q;
Tests: T1 T2 T3
202 1/1 dom_update = 1'b 0;
Tests: T1 T2 T3
203
204 1/1 complete_d = 1'b 0;
Tests: T1 T2 T3
205
206 1/1 sparse_fsm_error_o = 1'b 0;
Tests: T1 T2 T3
207
208 1/1 unique case (keccak_st)
Tests: T1 T2 T3
209 KeccakStIdle: begin
210 1/1 if (valid_i) begin
Tests: T1 T2 T3
211 // State machine allows Sponge Absorbing only in Idle state.
212 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T4
213
214 1/1 xor_message = 1'b 1;
Tests: T1 T2 T4
215 1/1 update_storage = 1'b 1;
Tests: T1 T2 T4
216 1/1 end else if (prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin
Tests: T1 T2 T3
217 // Opt1. State machine allows resetting the storage only in Idle
218 // Opt2. storage resets regardless of states but clear_i
219 // Both are added in the design at this time. Will choose the
220 // direction later.
221 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T5
222
223 1/1 rst_storage = 1'b 1;
Tests: T1 T2 T5
224 1/1 end else if (EnMasking && run_i) begin
Tests: T1 T2 T3
225 // Masked version of Keccak handling
226 unreachable keccak_st_d = KeccakStPhase1;
227
228 // Drive DOM multiplier I/O mux signals for Phase 1.
229 unreachable dom_in_low_d = low_then_high_q;
230 unreachable dom_in_rand_ext_d = 1'b 0;
231 1/1 end else if (!EnMasking && run_i) begin
Tests: T1 T2 T3
232 // Unmasked version of Keccak handling
233 1/1 keccak_st_d = KeccakStActive;
Tests: T1 T2 T4
234 end else begin
235 1/1 keccak_st_d = KeccakStIdle;
Tests: T1 T2 T3
236 end
237 end
238
239 KeccakStActive: begin
240 // Run Keccak single round logic until it reaches MaxRound - 1
241 1/1 update_storage = 1'b 1;
Tests: T1 T2 T4
242
243 1/1 if (rnd_eq_end) begin
Tests: T1 T2 T4
244 unreachable keccak_st_d = KeccakStIdle;
245
246 unreachable rst_rnd_num = 1'b 1;
247 unreachable complete_d = 1'b 1;
248 end else begin
249 1/1 keccak_st_d = KeccakStActive;
Tests: T1 T2 T4
250
251 1/1 inc_rnd_num = 1'b 1;
Tests: T1 T2 T4
252 end
253 end
254
255 KeccakStPhase1: begin
256 // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at
257 // all: their inputs are driven by the first lane halves (same values
258 // as in Phase2Cycle3 of the last round). Also, the intermediate
259 // results we already had in Phase2Cycle3 didn't change.
260 0/1 ==> phase_sel = MuBi4False;
261 0/1 ==> dom_update = 1'b 0;
262
263 // Only update the state and move on once we know the auxiliary
264 // randomness required for Phase2 will be available in the next clock
265 // cycle.
266 //
267 // It's important that the DOM multipliers inside keccak_2share are
268 // presented the new state (updated with update_storage) at the same
269 // time as the new randomness (updated with rand_update_o). Otherwise,
270 // stale entropy is paired with fresh data or vice versa. This could
271 // lead to undesired SCA leakage.
272 0/1 ==> if (rand_early_i || rand_valid_i) begin
273 0/1 ==> keccak_st_d = KeccakStPhase2Cycle1;
274 0/1 ==> update_storage = 1'b 1;
275 0/1 ==> keccak_rand_update = 1'b 1;
276
277 // Update lane halves processing order for this round.
278 0/1 ==> low_then_high_d = rand_aux_i;
279
280 // Drive DOM multiplier I/O mux signals for next phase.
281 0/1 ==> dom_in_low_d = low_then_high_d;
282 0/1 ==> dom_in_rand_ext_d = 1'b 1;
283 end else begin
284 unreachable keccak_st_d = KeccakStPhase1;
285 end
286 end
287
288 KeccakStPhase2Cycle1: begin
289 // Compute first stage of Chi for first lane halves using the DOM
290 // multipliers. Use the fresh randomness provided by the PRNG for
291 // remasking.
292 0/1 ==> phase_sel = MuBi4True;
293 0/1 ==> dom_update = 1'b 1;
294
295 // Trigger randomness update for next cycle.
296 // It's important that the DOM multipliers inside keccak_2share are
297 // presented the second lane halves at the same time as the new
298 // randomness (updated with rand_update_o). Otherwise, stale entropy
299 // is paired with fresh data or vice versa. This could lead to
300 // undesired SCA leakage.
301 0/1 ==> keccak_rand_update = 1'b 1;
302
303 // Unconditionally move to next phase/cycle.
304 0/1 ==> keccak_st_d = KeccakStPhase2Cycle2;
305
306 // Drive DOM multiplier I/O mux signals for next phase.
307 0/1 ==> dom_in_low_d = ~low_then_high_q;
308 0/1 ==> dom_in_rand_ext_d = 1'b 1;
309 end
310
311 KeccakStPhase2Cycle2: begin
312 // Chi Stage 1 for second lane halves.
313 // Chi Stage 2 and Iota for first lane halves.
314 // Compute second stage of Chi and Iota for first lane halves.
315 // Compute first stage of Chi for second lane halves. Use the fresh
316 // randomness provided by the PRNG for remasking the DOM multipliers.
317 0/1 ==> phase_sel = MuBi4True;
318 0/1 ==> dom_update = 1'b 1;
319
320 // Trigger randomness update for next cycle.
321 // It's important that the DOM multipliers inside keccak_2share are
322 // presented the updated state at the same as the new randomness
323 // (updated with rand_update_o) - even if the DOM multipliers don't
324 // update the pipeline registers in the next cycle. Otherwise, stale
325 // entropy is paired with fresh data or vice versa. This could lead to
326 // undesired SCA leakage.
327 0/1 ==> keccak_rand_update = 1'b 1;
328
329 // Trigger auxiliary randomness update for next round. The rand_aux_i
330 // signal is actually going to change in 2 clock cycles from now
331 // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3)
332 // in which the DOM multipliers don't update the pipeline registers.
333 0/1 ==> keccak_rand_consumed = 1'b 1;
334
335 // Update first lane halves.
336 0/1 ==> update_storage = 1'b 1;
337
338 // Unconditionally move to next phase/cycle.
339 0/1 ==> keccak_st_d = KeccakStPhase2Cycle3;
340
341 // Drive DOM multiplier I/O mux signals for next phase.
342 0/1 ==> dom_in_low_d = low_then_high_q;
343 0/1 ==> dom_in_rand_ext_d = 1'b 0;
344 end
345
346 KeccakStPhase2Cycle3: begin
347 // Compute second stage of Chi and Iota for second lane halves.
348 // Feed again first lane halves to DOM multiplier inputs (now
349 // the updated values become visible) together with intermediate
350 // results of Phase2Cycle2. Don't update the register stage inside
351 // the DOM multipliers.
352 0/1 ==> phase_sel = MuBi4True;
353 0/1 ==> dom_update = 1'b 0;
354
355 // Update second lane halves.
356 // We don't need fresh randomness for the next cycle as the DOM
357 // multipliers inside keccak_2share will keep seeing the first
358 // lane halves in the next cycle. If we updated the randomness,
359 // old data got combined with frash randomness which is not
360 // desirable as it could lead to SCA leakage.
361 0/1 ==> update_storage = 1'b 1;
362
363 0/1 ==> if (rnd_eq_end) begin
364 // We're done.
365 unreachable keccak_st_d = KeccakStIdle;
366
367 unreachable rst_rnd_num = 1'b 1;
368 unreachable complete_d = 1'b 1;
369 end else begin
370 // Continue to the next round.
371 0/1 ==> keccak_st_d = KeccakStPhase1;
372
373 0/1 ==> inc_rnd_num = 1'b 1;
374
375 // Drive DOM multiplier I/O mux signals for next phase.
376 0/1 ==> dom_in_low_d = low_then_high_q;
377 0/1 ==> dom_in_rand_ext_d = 1'b 0;
378 end
379 end
380
381 KeccakStError: begin
382 0/1 ==> keccak_st_d = KeccakStError;
383 end
384
385 KeccakStTerminalError: begin
386 //this state is terminal
387 1/1 keccak_st_d = keccak_st;
Tests: T4 T6 T7
388 1/1 sparse_fsm_error_o = 1'b 1;
Tests: T4 T6 T7
389 end
390
391 default: begin
392 keccak_st_d = KeccakStTerminalError;
393 sparse_fsm_error_o = 1'b 1;
394 end
395 endcase
396
397 // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC
398 // Unconditionally jump into the terminal error state
399 // if the life cycle controller triggers an escalation.
400 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin
Tests: T1 T2 T3
401 1/1 keccak_st_d = KeccakStTerminalError;
Tests: T4 T6 T7
402 end
MISSING_ELSE
403 end
404
405 // When taking the lower lane halves in, the upper lane halves are output and
406 // vice versa.
407 1/1 assign dom_out_low_d = ~dom_in_low_d;
Tests: T1 T2 T3
408
409 if (EnMasking) begin : gen_regs_dom_ctrl
410 always_ff @(posedge clk_i or negedge rst_ni) begin
411 if (!rst_ni) begin
412 low_then_high_q <= 1'b 0;
413 dom_out_low_q <= 1'b 0;
414 dom_in_low_q <= 1'b 0;
415 end else begin
416 low_then_high_q <= low_then_high_d;
417 dom_out_low_q <= dom_out_low_d;
418 dom_in_low_q <= dom_in_low_d;
419 end
420 end
421
422 if (!ForceRandExt) begin : gen_reg_dom_in_rand_ext
423 always_ff @(posedge clk_i or negedge rst_ni) begin
424 if (!rst_ni) begin
425 dom_in_rand_ext_q <= 1'b 0;
426 end else begin
427 dom_in_rand_ext_q <= dom_in_rand_ext_d;
428 end
429 end
430 end else begin : gen_force_dom_in_rand_ext
431 // Always forward the externally provided randomness.
432 assign dom_in_rand_ext_q = 1'b 1;
433 // Tie off unused signals.
434 logic unused_dom_in_rand_ext;
435 assign unused_dom_in_rand_ext = dom_in_rand_ext_d;
436 end
437 end else begin : gen_no_regs_dom_ctrl
438 logic unused_dom_ctrl;
439 1/1 assign unused_dom_ctrl =
Tests: T1 T2 T3
440 ^{low_then_high_d, dom_out_low_d, dom_in_low_d, dom_in_rand_ext_d};
441 assign low_then_high_q = 1'b 0;
442 assign dom_out_low_q = 1'b 0;
443 assign dom_in_low_q = 1'b 0;
444 assign dom_in_rand_ext_q = 1'b 0;
445 end
446
447 // Ready indicates the keccak_round is able to receive new message.
448 // While keccak_round is processing the data, it blocks the new message to be
449 // XORed into the current state.
450 1/1 assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0;
Tests: T1 T2 T3
451
452 ////////////////////////////
453 // Keccak state registers //
454 ////////////////////////////
455
456 // SEC_CM: LOGIC.INTEGRITY
457 logic rst_n;
458 prim_sec_anchor_buf #(
459 .Width(1)
460 ) u_prim_sec_anchor_buf (
461 .in_i(rst_ni),
462 .out_o(rst_n)
463 );
464
465 logic [Width-1:0] storage [Share];
466 logic [Width-1:0] storage_d [Share];
467 always_ff @(posedge clk_i or negedge rst_n) begin
468 1/1 if (!rst_n) begin
Tests: T1 T2 T3
469 1/1 storage <= '{default:'0};
Tests: T1 T2 T3
470 1/1 end else if (rst_storage) begin
Tests: T1 T2 T3
471 1/1 storage <= '{default:'0};
Tests: T1 T2 T5
472 1/1 end else if (update_storage) begin
Tests: T1 T2 T3
473 1/1 storage <= storage_d;
Tests: T1 T2 T4
474 end
MISSING_ELSE
475 end
476
477 1/1 assign state_o = storage;
Tests: T1 T2 T3
478
479 // Storage register input
480 // The incoming message is XORed with the existing storage registers.
481 // The logic can accept not a block size incoming message chunk but
482 // the size defined in `DInWidth` parameter with its position.
483
484 always_comb begin
485 1/1 storage_d = keccak_out;
Tests: T1 T2 T3
486 1/1 if (xor_message) begin
Tests: T1 T2 T3
487 1/1 for (int j = 0 ; j < Share ; j++) begin
Tests: T1 T2 T4
488 1/1 for (int unsigned i = 0 ; i < DInEntry ; i++) begin
Tests: T1 T2 T4
489 // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth
490 // Currently it is not allowed to have partial write
491 // Please see the Assertion `WidthDivisableByDInWidth_A`
492 1/1 if (addr_i == i[DInAddr-1:0]) begin
Tests: T1 T2 T4
493 1/1 storage_d[j][i*DInWidth+:DInWidth] =
Tests: T1 T2 T4
494 storage[j][i*DInWidth+:DInWidth] ^ data_i[j];
495 end else begin
496 1/1 storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth];
Tests: T1 T2 T4
497 end
498 end // for i
499 end // for j
500 end // if xor_message
MISSING_ELSE
501 end
502
503 // Check the rst_storage integrity
504 logic rst_storage_error;
505
506 always_comb begin : chk_rst_storage
507 1/1 rst_storage_error = 1'b 0;
Tests: T1 T2 T3
508
509 1/1 if (rst_storage) begin
Tests: T1 T2 T3
510 // FSM should be in KeccakStIdle and clear_i should be high
511 1/1 if ((keccak_st != KeccakStIdle) ||
Tests: T1 T2 T5
512 prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin
513 0/1 ==> rst_storage_error = 1'b 1;
514 end
MISSING_ELSE
515 end
MISSING_ELSE
516 end : chk_rst_storage
517
518 1/1 assign rst_storage_error_o = rst_storage_error ;
Tests: T1 T2 T3
519
520 //////////////
521 // Datapath //
522 //////////////
523 keccak_2share #(
524 .Width(Width),
525 .EnMasking(EnMasking),
526 .ForceRandExt(ForceRandExt)
527 ) u_keccak_p (
528 .clk_i,
529 .rst_ni,
530
531 .lc_escalate_en_i,
532
533 .rnd_i(round),
534
535 .phase_sel_i (phase_sel),
536 .dom_out_low_i (dom_out_low_q),
537 .dom_in_low_i (dom_in_low_q),
538 .dom_in_rand_ext_i(dom_in_rand_ext_q),
539 .dom_update_i (dom_update),
540
541 .rand_i(keccak_rand_data),
542
543 .s_i(storage),
544 .s_o(keccak_out)
545 );
546
547 // keccak entropy handling
548 1/1 assign rand_update_o = keccak_rand_update;
Tests: T1 T2 T3
549 1/1 assign rand_consumed_o = keccak_rand_consumed;
Tests: T1 T2 T3
550
551 unreachable assign keccak_rand_data = rand_data_i;
552
553 // Round number
554 // This primitive is used to place a hardened counter
555 // SEC_CM: CTR.REDUN
556 prim_count #(
557 .Width(RndW)
558 ) u_round_count (
559 .clk_i,
560 .rst_ni,
561 .clr_i(rst_rnd_num),
562 .set_i(1'b0),
563 .set_cnt_i('0),
564 .incr_en_i(inc_rnd_num),
565 .decr_en_i(1'b0),
566 .step_i(RndW'(1)),
567 .commit_i(1'b1),
568 .cnt_o(round),
569 .cnt_after_commit_o(),
570 .err_o(round_count_error_o)
571 );
572
573 // completion signal
574 always_ff @(posedge clk_i or negedge rst_ni) begin
575 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
576 1/1 complete_o <= 1'b 0;
Tests: T1 T2 T3
577 end else begin
578 1/1 complete_o <= complete_d;
Tests: T1 T2 T3
Cond Coverage for Instance : tb.dut.u_sha3.u_keccak
| Total | Covered | Percent |
Conditions | 9 | 9 | 100.00 |
Logical | 9 | 9 | 100.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 177
EXPRESSION (int'(round) == (MaxRound - 1))
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Unreachable | T1,T2,T5 |
LINE 231
EXPRESSION (((!EnMasking)) && run_i)
-------1------ --2--
-1- | -2- | Status | Tests |
- | 0 | Covered | T1,T2,T3 |
- | 1 | Covered | T1,T2,T4 |
LINE 272
EXPRESSION (rand_early_i || rand_valid_i)
------1----- ------2-----
-1- | -2- | Status | Tests |
0 | 0 | Unreachable | |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
LINE 450
EXPRESSION ((keccak_st == KeccakStIdle) ? 1'b1 : 1'b0)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T1,T2,T4 |
1 | Covered | T1,T2,T3 |
LINE 450
SUB-EXPRESSION (keccak_st == KeccakStIdle)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 492
EXPRESSION (addr_i == i[(DInAddr - 1):0])
---------------1--------------
-1- | Status | Tests |
0 | Covered | T1,T2,T4 |
1 | Covered | T1,T2,T4 |
FSM Coverage for Instance : tb.dut.u_sha3.u_keccak
Summary for FSM :: keccak_st
| Total | Covered | Percent | |
States |
8 |
3 |
37.50 |
(Not included in score) |
Transitions |
10 |
4 |
40.00 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: keccak_st
states | Line No. | Covered | Tests |
KeccakStActive |
233 |
Covered |
T1,T2,T4 |
KeccakStError |
382 |
Excluded |
|
KeccakStIdle |
212 |
Covered |
T1,T2,T3 |
KeccakStPhase1 |
226 |
Not Covered |
|
KeccakStPhase2Cycle1 |
273 |
Not Covered |
|
KeccakStPhase2Cycle2 |
304 |
Not Covered |
|
KeccakStPhase2Cycle3 |
339 |
Not Covered |
|
KeccakStTerminalError |
401 |
Covered |
T4,T6,T7 |
transitions | Line No. | Covered | Tests | Exclude Annotation |
KeccakStActive->KeccakStIdle |
244 |
Covered |
T1,T2,T5 |
|
KeccakStActive->KeccakStTerminalError |
401 |
Covered |
T4,T7,T8 |
|
KeccakStError->KeccakStTerminalError |
401 |
Excluded |
|
[LOW_RISK] The transition from any state to error_terminal state is fully verified in FPV. |
KeccakStIdle->KeccakStActive |
233 |
Covered |
T1,T2,T4 |
|
KeccakStIdle->KeccakStPhase1 |
226 |
Not Covered |
|
|
KeccakStIdle->KeccakStTerminalError |
401 |
Covered |
T6,T9,T10 |
|
KeccakStPhase1->KeccakStPhase2Cycle1 |
273 |
Not Covered |
|
|
KeccakStPhase1->KeccakStTerminalError |
401 |
Excluded |
|
[LOW_RISK] The transition from any state to error_terminal state is fully verified in FPV. |
KeccakStPhase2Cycle1->KeccakStPhase2Cycle2 |
304 |
Not Covered |
|
|
KeccakStPhase2Cycle1->KeccakStTerminalError |
401 |
Excluded |
|
[LOW_RISK] The transition from any state to error_terminal state is fully verified in FPV. |
KeccakStPhase2Cycle2->KeccakStPhase2Cycle3 |
339 |
Not Covered |
|
|
KeccakStPhase2Cycle2->KeccakStTerminalError |
401 |
Excluded |
|
[LOW_RISK] The transition from any state to error_terminal state is fully verified in FPV. |
KeccakStPhase2Cycle3->KeccakStIdle |
365 |
Not Covered |
|
|
KeccakStPhase2Cycle3->KeccakStPhase1 |
371 |
Not Covered |
|
|
KeccakStPhase2Cycle3->KeccakStTerminalError |
401 |
Excluded |
|
[LOW_RISK] The transition from any state to error_terminal state is fully verified in FPV. |
Branch Coverage for Instance : tb.dut.u_sha3.u_keccak
| Line No. | Total | Covered | Percent |
Branches |
|
29 |
23 |
79.31 |
TERNARY |
450 |
2 |
2 |
100.00 |
IF |
180 |
2 |
2 |
100.00 |
CASE |
208 |
12 |
7 |
58.33 |
IF |
400 |
2 |
2 |
100.00 |
IF |
468 |
4 |
4 |
100.00 |
IF |
486 |
2 |
2 |
100.00 |
IF |
509 |
3 |
2 |
66.67 |
IF |
575 |
2 |
2 |
100.00 |
450 assign ready_o = (keccak_st == KeccakStIdle) ? 1'b 1 : 1'b 0;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T4 |
180 `PRIM_FLOP_SPARSE_FSM(u_state_regs, keccak_st_d, keccak_st, keccak_st_e, KeccakStIdle)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
208 unique case (keccak_st)
-1-
209 KeccakStIdle: begin
210 if (valid_i) begin
-2-
211 // State machine allows Sponge Absorbing only in Idle state.
212 keccak_st_d = KeccakStIdle;
==>
213
214 xor_message = 1'b 1;
215 update_storage = 1'b 1;
216 end else if (prim_mubi_pkg::mubi4_test_true_strict(clear_i)) begin
-3-
217 // Opt1. State machine allows resetting the storage only in Idle
218 // Opt2. storage resets regardless of states but clear_i
219 // Both are added in the design at this time. Will choose the
220 // direction later.
221 keccak_st_d = KeccakStIdle;
==>
222
223 rst_storage = 1'b 1;
224 end else if (EnMasking && run_i) begin
-4-
225 // Masked version of Keccak handling
226 keccak_st_d = KeccakStPhase1;
==> (Unreachable)
227
228 // Drive DOM multiplier I/O mux signals for Phase 1.
229 dom_in_low_d = low_then_high_q;
230 dom_in_rand_ext_d = 1'b 0;
231 end else if (!EnMasking && run_i) begin
-5-
232 // Unmasked version of Keccak handling
233 keccak_st_d = KeccakStActive;
==>
234 end else begin
235 keccak_st_d = KeccakStIdle;
==>
236 end
237 end
238
239 KeccakStActive: begin
240 // Run Keccak single round logic until it reaches MaxRound - 1
241 update_storage = 1'b 1;
242
243 if (rnd_eq_end) begin
-6-
244 keccak_st_d = KeccakStIdle;
==> (Unreachable)
245
246 rst_rnd_num = 1'b 1;
247 complete_d = 1'b 1;
248 end else begin
249 keccak_st_d = KeccakStActive;
==>
250
251 inc_rnd_num = 1'b 1;
252 end
253 end
254
255 KeccakStPhase1: begin
256 // Compute Theta, Rho, Pi - The DOM multipliers are not evaluated at
257 // all: their inputs are driven by the first lane halves (same values
258 // as in Phase2Cycle3 of the last round). Also, the intermediate
259 // results we already had in Phase2Cycle3 didn't change.
260 phase_sel = MuBi4False;
261 dom_update = 1'b 0;
262
263 // Only update the state and move on once we know the auxiliary
264 // randomness required for Phase2 will be available in the next clock
265 // cycle.
266 //
267 // It's important that the DOM multipliers inside keccak_2share are
268 // presented the new state (updated with update_storage) at the same
269 // time as the new randomness (updated with rand_update_o). Otherwise,
270 // stale entropy is paired with fresh data or vice versa. This could
271 // lead to undesired SCA leakage.
272 if (rand_early_i || rand_valid_i) begin
-7-
273 keccak_st_d = KeccakStPhase2Cycle1;
==>
274 update_storage = 1'b 1;
275 keccak_rand_update = 1'b 1;
276
277 // Update lane halves processing order for this round.
278 low_then_high_d = rand_aux_i;
279
280 // Drive DOM multiplier I/O mux signals for next phase.
281 dom_in_low_d = low_then_high_d;
282 dom_in_rand_ext_d = 1'b 1;
283 end else begin
284 keccak_st_d = KeccakStPhase1;
==> (Unreachable)
285 end
286 end
287
288 KeccakStPhase2Cycle1: begin
289 // Compute first stage of Chi for first lane halves using the DOM
290 // multipliers. Use the fresh randomness provided by the PRNG for
291 // remasking.
292 phase_sel = MuBi4True;
==>
293 dom_update = 1'b 1;
294
295 // Trigger randomness update for next cycle.
296 // It's important that the DOM multipliers inside keccak_2share are
297 // presented the second lane halves at the same time as the new
298 // randomness (updated with rand_update_o). Otherwise, stale entropy
299 // is paired with fresh data or vice versa. This could lead to
300 // undesired SCA leakage.
301 keccak_rand_update = 1'b 1;
302
303 // Unconditionally move to next phase/cycle.
304 keccak_st_d = KeccakStPhase2Cycle2;
305
306 // Drive DOM multiplier I/O mux signals for next phase.
307 dom_in_low_d = ~low_then_high_q;
308 dom_in_rand_ext_d = 1'b 1;
309 end
310
311 KeccakStPhase2Cycle2: begin
312 // Chi Stage 1 for second lane halves.
313 // Chi Stage 2 and Iota for first lane halves.
314 // Compute second stage of Chi and Iota for first lane halves.
315 // Compute first stage of Chi for second lane halves. Use the fresh
316 // randomness provided by the PRNG for remasking the DOM multipliers.
317 phase_sel = MuBi4True;
==>
318 dom_update = 1'b 1;
319
320 // Trigger randomness update for next cycle.
321 // It's important that the DOM multipliers inside keccak_2share are
322 // presented the updated state at the same as the new randomness
323 // (updated with rand_update_o) - even if the DOM multipliers don't
324 // update the pipeline registers in the next cycle. Otherwise, stale
325 // entropy is paired with fresh data or vice versa. This could lead to
326 // undesired SCA leakage.
327 keccak_rand_update = 1'b 1;
328
329 // Trigger auxiliary randomness update for next round. The rand_aux_i
330 // signal is actually going to change in 2 clock cycles from now
331 // (Phase1) based on the PRNG output in the next cycle (Phase2Cycle3)
332 // in which the DOM multipliers don't update the pipeline registers.
333 keccak_rand_consumed = 1'b 1;
334
335 // Update first lane halves.
336 update_storage = 1'b 1;
337
338 // Unconditionally move to next phase/cycle.
339 keccak_st_d = KeccakStPhase2Cycle3;
340
341 // Drive DOM multiplier I/O mux signals for next phase.
342 dom_in_low_d = low_then_high_q;
343 dom_in_rand_ext_d = 1'b 0;
344 end
345
346 KeccakStPhase2Cycle3: begin
347 // Compute second stage of Chi and Iota for second lane halves.
348 // Feed again first lane halves to DOM multiplier inputs (now
349 // the updated values become visible) together with intermediate
350 // results of Phase2Cycle2. Don't update the register stage inside
351 // the DOM multipliers.
352 phase_sel = MuBi4True;
353 dom_update = 1'b 0;
354
355 // Update second lane halves.
356 // We don't need fresh randomness for the next cycle as the DOM
357 // multipliers inside keccak_2share will keep seeing the first
358 // lane halves in the next cycle. If we updated the randomness,
359 // old data got combined with frash randomness which is not
360 // desirable as it could lead to SCA leakage.
361 update_storage = 1'b 1;
362
363 if (rnd_eq_end) begin
-8-
364 // We're done.
365 keccak_st_d = KeccakStIdle;
==> (Unreachable)
366
367 rst_rnd_num = 1'b 1;
368 complete_d = 1'b 1;
369 end else begin
370 // Continue to the next round.
371 keccak_st_d = KeccakStPhase1;
==>
372
373 inc_rnd_num = 1'b 1;
374
375 // Drive DOM multiplier I/O mux signals for next phase.
376 dom_in_low_d = low_then_high_q;
377 dom_in_rand_ext_d = 1'b 0;
378 end
379 end
380
381 KeccakStError: begin
382 keccak_st_d = KeccakStError;
==>
383 end
384
385 KeccakStTerminalError: begin
386 //this state is terminal
387 keccak_st_d = keccak_st;
==>
388 sparse_fsm_error_o = 1'b 1;
389 end
390
391 default: begin
392 keccak_st_d = KeccakStTerminalError;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | Status | Tests |
KeccakStIdle |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T4 |
KeccakStIdle |
0 |
1 |
- |
- |
- |
- |
- |
Covered |
T1,T2,T5 |
KeccakStIdle |
0 |
0 |
1 |
- |
- |
- |
- |
Unreachable |
|
KeccakStIdle |
0 |
0 |
0 |
1 |
- |
- |
- |
Covered |
T1,T2,T4 |
KeccakStIdle |
0 |
0 |
0 |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
KeccakStActive |
- |
- |
- |
- |
1 |
- |
- |
Unreachable |
T1,T2,T5 |
KeccakStActive |
- |
- |
- |
- |
0 |
- |
- |
Covered |
T1,T2,T4 |
KeccakStPhase1 |
- |
- |
- |
- |
- |
1 |
- |
Not Covered |
|
KeccakStPhase1 |
- |
- |
- |
- |
- |
0 |
- |
Unreachable |
|
KeccakStPhase2Cycle1 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStPhase2Cycle2 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStPhase2Cycle3 |
- |
- |
- |
- |
- |
- |
1 |
Unreachable |
|
KeccakStPhase2Cycle3 |
- |
- |
- |
- |
- |
- |
0 |
Not Covered |
|
KeccakStError |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
KeccakStTerminalError |
- |
- |
- |
- |
- |
- |
- |
Covered |
T4,T6,T7 |
default |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T9,T11 |
400 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) begin
-1-
401 keccak_st_d = KeccakStTerminalError;
==>
402 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T4,T6,T7 |
0 |
Covered |
T1,T2,T3 |
468 if (!rst_n) begin
-1-
469 storage <= '{default:'0};
==>
470 end else if (rst_storage) begin
-2-
471 storage <= '{default:'0};
==>
472 end else if (update_storage) begin
-3-
473 storage <= storage_d;
==>
474 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T1,T2,T5 |
0 |
0 |
1 |
Covered |
T1,T2,T4 |
0 |
0 |
0 |
Covered |
T1,T2,T3 |
486 if (xor_message) begin
-1-
487 for (int j = 0 ; j < Share ; j++) begin
==>
488 for (int unsigned i = 0 ; i < DInEntry ; i++) begin
489 // ICEBOX(#18029): handle If Width is not integer divisable by DInWidth
490 // Currently it is not allowed to have partial write
491 // Please see the Assertion `WidthDivisableByDInWidth_A`
492 if (addr_i == i[DInAddr-1:0]) begin
493 storage_d[j][i*DInWidth+:DInWidth] =
494 storage[j][i*DInWidth+:DInWidth] ^ data_i[j];
495 end else begin
496 storage_d[j][i*DInWidth+:DInWidth] = storage[j][i*DInWidth+:DInWidth];
497 end
498 end // for i
499 end // for j
500 end // if xor_message
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T4 |
0 |
Covered |
T1,T2,T3 |
509 if (rst_storage) begin
-1-
510 // FSM should be in KeccakStIdle and clear_i should be high
511 if ((keccak_st != KeccakStIdle) ||
-2-
512 prim_mubi_pkg::mubi4_test_false_loose(clear_i)) begin
513 rst_storage_error = 1'b 1;
==>
514 end
MISSING_ELSE
==>
515 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Not Covered |
|
1 |
0 |
Covered |
T1,T2,T5 |
0 |
- |
Covered |
T1,T2,T3 |
575 if (!rst_ni) begin
-1-
576 complete_o <= 1'b 0;
==>
577 end else begin
578 complete_o <= complete_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Instance : tb.dut.u_sha3.u_keccak
Assertion Details
ClearAssertStIdle_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
55012 |
0 |
0 |
T1 |
2648 |
3 |
0 |
0 |
T2 |
5465 |
3 |
0 |
0 |
T3 |
933 |
0 |
0 |
0 |
T4 |
2633 |
0 |
0 |
0 |
T5 |
11640 |
1 |
0 |
0 |
T12 |
117788 |
12 |
0 |
0 |
T13 |
61338 |
5 |
0 |
0 |
T14 |
5366 |
3 |
0 |
0 |
T15 |
36858 |
72 |
0 |
0 |
T16 |
238280 |
59 |
0 |
0 |
T17 |
0 |
3 |
0 |
0 |
T18 |
0 |
83 |
0 |
0 |
OneHot0ValidAndRun_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |
ValidRunAssertStIdle_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
15575101 |
0 |
0 |
T1 |
2648 |
220 |
0 |
0 |
T2 |
5465 |
220 |
0 |
0 |
T3 |
933 |
0 |
0 |
0 |
T4 |
2633 |
22 |
0 |
0 |
T5 |
11640 |
112 |
0 |
0 |
T12 |
117788 |
648 |
0 |
0 |
T13 |
61338 |
519 |
0 |
0 |
T14 |
5366 |
220 |
0 |
0 |
T15 |
36858 |
3261 |
0 |
0 |
T16 |
238280 |
6598 |
0 |
0 |
T17 |
0 |
198 |
0 |
0 |
WidthDivisableByDInWidth_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
669 |
669 |
0 |
0 |
T1 |
1 |
1 |
0 |
0 |
T2 |
1 |
1 |
0 |
0 |
T3 |
1 |
1 |
0 |
0 |
T4 |
1 |
1 |
0 |
0 |
T5 |
1 |
1 |
0 |
0 |
T12 |
1 |
1 |
0 |
0 |
T13 |
1 |
1 |
0 |
0 |
T14 |
1 |
1 |
0 |
0 |
T15 |
1 |
1 |
0 |
0 |
T16 |
1 |
1 |
0 |
0 |
gen_unmask_st_chk.UnmaskValidStates_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |
u_state_regs_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
681450550 |
681319314 |
0 |
0 |
T1 |
2648 |
2589 |
0 |
0 |
T2 |
5465 |
5367 |
0 |
0 |
T3 |
933 |
874 |
0 |
0 |
T4 |
2633 |
2509 |
0 |
0 |
T5 |
11640 |
11560 |
0 |
0 |
T12 |
117788 |
117728 |
0 |
0 |
T13 |
61338 |
61258 |
0 |
0 |
T14 |
5366 |
5291 |
0 |
0 |
T15 |
36858 |
36770 |
0 |
0 |
T16 |
238280 |
238218 |
0 |
0 |