Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1720,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 160 | 127 | 79.38 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 107 | 76.43 |
CONT_ASSIGN | 636 | 1 | 1 | 100.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 709 | 1 | 1 | 100.00 |
CONT_ASSIGN | 743 | 1 | 1 | 100.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 unreachable state_d = InitDescrSt;
277 end else begin
278 1/1 state_d = InitSt;
Tests: T1 T2 T3
279 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T25 T26 T27
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T28 T29 T30
287 1/1 error_d = otp_err;
Tests: T28 T29 T30
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 0/1 ==> scrmbl_mtx_req_o = 1'b1;
299 0/1 ==> scrmbl_valid_o = 1'b1;
300 0/1 ==> scrmbl_cmd_o = Decrypt;
301 0/1 ==> scrmbl_sel_o = Info.key_sel;
302 0/1 ==> if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
303 0/1 ==> state_d = InitDescrWaitSt;
304 end
==> MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 0/1 ==> scrmbl_mtx_req_o = 1'b1;
312 0/1 ==> scrmbl_sel_o = Info.key_sel;
313 0/1 ==> data_sel = ScrmblData;
314 0/1 ==> if (scrmbl_valid_i) begin
315 0/1 ==> state_d = InitSt;
316 0/1 ==> buffer_reg_en = 1'b1;
317 0/1 ==> cnt_en = 1'b1;
318 end
==> MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T12 T31
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 unreachable integ_chk_ack_o = 1'b1;
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 1/1 base_sel = DigOffset;
Tests: T3 T4 T5
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T3 T4 T5
369 1/1 state_d = IdleSt;
Tests: T3 T4 T5
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
371 // Error out and lock the partition if this check fails.
372 end else begin
373 1/1 state_d = ErrorSt;
Tests: T32
374 1/1 error_d = CheckFailError;
Tests: T32
375 // The check has finished and found an error.
376 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T32
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 unreachable if (scrmbl_data_o == data_mux ||
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 unreachable if (cnt == LastScrmblBlock) begin
386 unreachable state_d = IdleSt;
387 unreachable cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 unreachable state_d = CnstyReadSt;
391 unreachable cnt_en = 1'b1;
392 end
393 end else begin
394 unreachable state_d = ErrorSt;
395 unreachable error_d = CheckFailError;
396 // The check has finished and found an error.
397 unreachable cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T33 T34 T35
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T33 T36 T37
406 1/1 error_d = otp_err;
Tests: T33 T36 T37
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T33 T36 T37
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
419 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
420 1/1 cnt_clr = 1'b1;
Tests: T1 T2 T3
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 1/1 scrmbl_cmd_o = DigestInit;
Tests: T1 T2 T3
424 1/1 if (Info.secret) begin
Tests: T1 T2 T3
425 unreachable scrmbl_mode_o = ChainedMode;
426 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
427 unreachable state_d = IntegScrSt;
428 end
==> MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
433 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
434 1/1 state_d = IntegDigSt;
Tests: T1 T2 T3
435 end
MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 unreachable state_d = IdleSt;
444 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
445 unreachable dout_locked_d = MuBi8False;
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 0/1 ==> scrmbl_mtx_req_o = 1'b1;
456 0/1 ==> scrmbl_valid_o = 1'b1;
457 0/1 ==> scrmbl_cmd_o = Encrypt;
458 0/1 ==> scrmbl_sel_o = Info.key_sel;
459 0/1 ==> if (scrmbl_ready_i) begin
460 0/1 ==> state_d = IntegScrWaitSt;
461 end
==> MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 0/1 ==> scrmbl_mtx_req_o = 1'b1;
468 0/1 ==> scrmbl_sel_o = Info.key_sel;
469 0/1 ==> if (scrmbl_valid_i) begin
470 0/1 ==> state_d = IntegDigSt;
471 end
==> MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
481 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
482 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
483 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
484 // No need to digest the digest value itself
485 1/1 if (cnt == PenultimateScrmblBlock) begin
Tests: T1 T2 T3
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
490 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
491 1/1 state_d = IntegDigFinSt;
Tests: T1 T2 T3
492 end else begin
493 0/1 ==> state_d = IntegDigPadSt;
494 0/1 ==> cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
499 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
500 end
MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 1/1 if (Info.secret) begin
Tests: T1 T2 T3
504 unreachable state_d = IntegScrSt;
505 end
MISSING_ELSE
506 end
507 end
MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 0/1 ==> scrmbl_mtx_req_o = 1'b1;
517 0/1 ==> scrmbl_valid_o = 1'b1;
518 0/1 ==> scrmbl_cmd_o = Digest;
519 0/1 ==> if (scrmbl_ready_i) begin
520 0/1 ==> state_d = IntegDigFinSt;
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
529 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
530 1/1 scrmbl_cmd_o = DigestFinalize;
Tests: T1 T2 T3
531 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
532 1/1 state_d = IntegDigWaitSt;
Tests: T1 T2 T3
533 end
MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
543 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
544 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T1 T2 T3
548 1/1 state_d = IdleSt;
Tests: T1 T2 T3
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
552 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T38 T39 T40
561 1/1 error_d = CheckFailError;
Tests: T38 T39 T40
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T38 T39 T40
564 end
565 end
MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T8
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 1/1 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
Tests: T1 T2 T3
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 1/1 assign access_o.read_lock = access_pre.read_lock;
Tests: T1 T2 T3
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=1,DigestOffset=1736,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 160 | 126 | 78.75 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 106 | 75.71 |
CONT_ASSIGN | 636 | 1 | 1 | 100.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 709 | 1 | 1 | 100.00 |
CONT_ASSIGN | 743 | 1 | 1 | 100.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 unreachable state_d = InitDescrSt;
277 end else begin
278 1/1 state_d = InitSt;
Tests: T1 T2 T3
279 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T41 T26 T30
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T42 T43 T44
287 1/1 error_d = otp_err;
Tests: T42 T43 T44
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 0/1 ==> scrmbl_mtx_req_o = 1'b1;
299 0/1 ==> scrmbl_valid_o = 1'b1;
300 0/1 ==> scrmbl_cmd_o = Decrypt;
301 0/1 ==> scrmbl_sel_o = Info.key_sel;
302 0/1 ==> if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
303 0/1 ==> state_d = InitDescrWaitSt;
304 end
==> MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 0/1 ==> scrmbl_mtx_req_o = 1'b1;
312 0/1 ==> scrmbl_sel_o = Info.key_sel;
313 0/1 ==> data_sel = ScrmblData;
314 0/1 ==> if (scrmbl_valid_i) begin
315 0/1 ==> state_d = InitSt;
316 0/1 ==> buffer_reg_en = 1'b1;
317 0/1 ==> cnt_en = 1'b1;
318 end
==> MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T12 T31
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 unreachable integ_chk_ack_o = 1'b1;
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 1/1 base_sel = DigOffset;
Tests: T3 T4 T5
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T3 T4 T5
369 1/1 state_d = IdleSt;
Tests: T3 T4 T5
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
371 // Error out and lock the partition if this check fails.
372 end else begin
373 0/1 ==> state_d = ErrorSt;
374 0/1 ==> error_d = CheckFailError;
375 // The check has finished and found an error.
376 0/1 ==> cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 unreachable if (scrmbl_data_o == data_mux ||
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 unreachable if (cnt == LastScrmblBlock) begin
386 unreachable state_d = IdleSt;
387 unreachable cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 unreachable state_d = CnstyReadSt;
391 unreachable cnt_en = 1'b1;
392 end
393 end else begin
394 unreachable state_d = ErrorSt;
395 unreachable error_d = CheckFailError;
396 // The check has finished and found an error.
397 unreachable cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T45 T46
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T47 T48
406 1/1 error_d = otp_err;
Tests: T47 T48
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T47 T48
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
419 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
420 1/1 cnt_clr = 1'b1;
Tests: T1 T2 T3
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 1/1 scrmbl_cmd_o = DigestInit;
Tests: T1 T2 T3
424 1/1 if (Info.secret) begin
Tests: T1 T2 T3
425 unreachable scrmbl_mode_o = ChainedMode;
426 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
427 unreachable state_d = IntegScrSt;
428 end
==> MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
433 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
434 1/1 state_d = IntegDigSt;
Tests: T1 T2 T3
435 end
MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 unreachable state_d = IdleSt;
444 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
445 unreachable dout_locked_d = MuBi8False;
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 0/1 ==> scrmbl_mtx_req_o = 1'b1;
456 0/1 ==> scrmbl_valid_o = 1'b1;
457 0/1 ==> scrmbl_cmd_o = Encrypt;
458 0/1 ==> scrmbl_sel_o = Info.key_sel;
459 0/1 ==> if (scrmbl_ready_i) begin
460 0/1 ==> state_d = IntegScrWaitSt;
461 end
==> MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 0/1 ==> scrmbl_mtx_req_o = 1'b1;
468 0/1 ==> scrmbl_sel_o = Info.key_sel;
469 0/1 ==> if (scrmbl_valid_i) begin
470 0/1 ==> state_d = IntegDigSt;
471 end
==> MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
481 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
482 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
483 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
484 // No need to digest the digest value itself
485 1/1 if (cnt == PenultimateScrmblBlock) begin
Tests: T1 T2 T3
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
490 0/1 ==> scrmbl_cmd_o = Digest;
491 0/1 ==> state_d = IntegDigFinSt;
492 end else begin
493 1/1 state_d = IntegDigPadSt;
Tests: T1 T2 T3
494 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 0/1 ==> if (cnt[0]) begin
499 0/1 ==> scrmbl_cmd_o = Digest;
500 end
==> MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 0/1 ==> if (Info.secret) begin
504 unreachable state_d = IntegScrSt;
505 end
==> MISSING_ELSE
506 end
507 end
==> MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
517 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
518 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
519 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
520 1/1 state_d = IntegDigFinSt;
Tests: T1 T2 T3
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
529 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
530 1/1 scrmbl_cmd_o = DigestFinalize;
Tests: T1 T2 T3
531 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
532 1/1 state_d = IntegDigWaitSt;
Tests: T1 T2 T3
533 end
MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
543 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
544 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T1 T2 T3
548 1/1 state_d = IdleSt;
Tests: T1 T2 T3
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
552 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T49 T50 T51
561 1/1 error_d = CheckFailError;
Tests: T49 T50 T51
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T49 T50 T51
564 end
565 end
MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T8
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 1/1 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
Tests: T1 T2 T3
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 1/1 assign access_o.read_lock = access_pre.read_lock;
Tests: T1 T2 T3
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=3,DigestOffset=1776,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 160 | 147 | 91.88 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 127 | 90.71 |
CONT_ASSIGN | 636 | 1 | 1 | 100.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 709 | 1 | 1 | 100.00 |
CONT_ASSIGN | 729 | 1 | 1 | 100.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 1/1 state_d = InitDescrSt;
Tests: T1 T2 T3
277 end else begin
278 unreachable state_d = InitSt;
279 unreachable cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T29 T52 T53
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T41 T54 T27
287 1/1 error_d = otp_err;
Tests: T41 T54 T27
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
299 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
300 1/1 scrmbl_cmd_o = Decrypt;
Tests: T1 T2 T3
301 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
302 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
303 1/1 state_d = InitDescrWaitSt;
Tests: T1 T2 T3
304 end
MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
312 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
313 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
314 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
315 1/1 state_d = InitSt;
Tests: T1 T2 T3
316 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
317 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
318 end
MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T12 T31
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 unreachable integ_chk_ack_o = 1'b1;
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 1/1 base_sel = DigOffset;
Tests: T3 T4 T5
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T3 T4 T5
369 1/1 state_d = IdleSt;
Tests: T3 T4 T5
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
371 // Error out and lock the partition if this check fails.
372 end else begin
373 0/1 ==> state_d = ErrorSt;
374 0/1 ==> error_d = CheckFailError;
375 // The check has finished and found an error.
376 0/1 ==> cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 unreachable if (scrmbl_data_o == data_mux ||
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 unreachable if (cnt == LastScrmblBlock) begin
386 unreachable state_d = IdleSt;
387 unreachable cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 unreachable state_d = CnstyReadSt;
391 unreachable cnt_en = 1'b1;
392 end
393 end else begin
394 unreachable state_d = ErrorSt;
395 unreachable error_d = CheckFailError;
396 // The check has finished and found an error.
397 unreachable cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T55 T36 T34
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T45 T56 T57
406 1/1 error_d = otp_err;
Tests: T45 T56 T57
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T45 T56 T57
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
419 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
420 1/1 cnt_clr = 1'b1;
Tests: T1 T2 T3
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 1/1 scrmbl_cmd_o = DigestInit;
Tests: T1 T2 T3
424 1/1 if (Info.secret) begin
Tests: T1 T2 T3
425 1/1 scrmbl_mode_o = ChainedMode;
Tests: T1 T2 T3
426 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
427 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
428 end
MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 unreachable scrmbl_mode_o = StandardMode;
433 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
434 unreachable state_d = IntegDigSt;
435 end
==> MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 unreachable state_d = IdleSt;
444 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
445 unreachable dout_locked_d = MuBi8False;
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
456 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
457 1/1 scrmbl_cmd_o = Encrypt;
Tests: T1 T2 T3
458 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
459 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
460 1/1 state_d = IntegScrWaitSt;
Tests: T1 T2 T3
461 end
MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
468 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
469 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
470 1/1 state_d = IntegDigSt;
Tests: T1 T2 T3
471 end
MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
481 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
482 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
483 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
484 // No need to digest the digest value itself
485 1/1 if (cnt == PenultimateScrmblBlock) begin
Tests: T1 T2 T3
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
490 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
491 1/1 state_d = IntegDigFinSt;
Tests: T1 T2 T3
492 end else begin
493 0/1 ==> state_d = IntegDigPadSt;
494 0/1 ==> cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
499 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
500 end
MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 1/1 if (Info.secret) begin
Tests: T1 T2 T3
504 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
505 end
==> MISSING_ELSE
506 end
507 end
==> MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 0/1 ==> scrmbl_mtx_req_o = 1'b1;
517 0/1 ==> scrmbl_valid_o = 1'b1;
518 0/1 ==> scrmbl_cmd_o = Digest;
519 0/1 ==> if (scrmbl_ready_i) begin
520 0/1 ==> state_d = IntegDigFinSt;
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
529 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
530 1/1 scrmbl_cmd_o = DigestFinalize;
Tests: T1 T2 T3
531 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
532 1/1 state_d = IntegDigWaitSt;
Tests: T1 T2 T3
533 end
MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
543 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
544 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T1 T2 T3
548 1/1 state_d = IdleSt;
Tests: T1 T2 T3
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
552 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T58 T59 T60
561 1/1 error_d = CheckFailError;
Tests: T58 T59 T60
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T58 T59 T60
564 end
565 end
MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T8
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 1/1 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
Tests: T1 T2 T3
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 assign access_o.read_lock = access_pre.read_lock;
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1864,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 160 | 144 | 90.00 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 124 | 88.57 |
CONT_ASSIGN | 636 | 1 | 1 | 100.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 709 | 1 | 1 | 100.00 |
CONT_ASSIGN | 729 | 1 | 1 | 100.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 1/1 state_d = InitDescrSt;
Tests: T1 T2 T3
277 end else begin
278 unreachable state_d = InitSt;
279 unreachable cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T61 T62 T63
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T64 T65 T52
287 1/1 error_d = otp_err;
Tests: T64 T65 T52
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
299 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
300 1/1 scrmbl_cmd_o = Decrypt;
Tests: T1 T2 T3
301 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
302 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
303 1/1 state_d = InitDescrWaitSt;
Tests: T1 T2 T3
304 end
MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
312 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
313 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
314 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
315 1/1 state_d = InitSt;
Tests: T1 T2 T3
316 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
317 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
318 end
MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T12 T31
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 unreachable integ_chk_ack_o = 1'b1;
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 1/1 base_sel = DigOffset;
Tests: T3 T4 T5
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T3 T4 T5
369 1/1 state_d = IdleSt;
Tests: T3 T4 T5
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
371 // Error out and lock the partition if this check fails.
372 end else begin
373 0/1 ==> state_d = ErrorSt;
374 0/1 ==> error_d = CheckFailError;
375 // The check has finished and found an error.
376 0/1 ==> cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 unreachable if (scrmbl_data_o == data_mux ||
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 unreachable if (cnt == LastScrmblBlock) begin
386 unreachable state_d = IdleSt;
387 unreachable cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 unreachable state_d = CnstyReadSt;
391 unreachable cnt_en = 1'b1;
392 end
393 end else begin
394 unreachable state_d = ErrorSt;
395 unreachable error_d = CheckFailError;
396 // The check has finished and found an error.
397 unreachable cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T56 T66
403 end
MISSING_ELSE
404 end else begin
405 0/1 ==> state_d = ErrorSt;
406 0/1 ==> error_d = otp_err;
407 // The check has finished and found an error.
408 0/1 ==> cnsty_chk_ack_o = 1'b1;
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
419 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
420 1/1 cnt_clr = 1'b1;
Tests: T1 T2 T3
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 1/1 scrmbl_cmd_o = DigestInit;
Tests: T1 T2 T3
424 1/1 if (Info.secret) begin
Tests: T1 T2 T3
425 1/1 scrmbl_mode_o = ChainedMode;
Tests: T1 T2 T3
426 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
427 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
428 end
MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 unreachable scrmbl_mode_o = StandardMode;
433 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
434 unreachable state_d = IntegDigSt;
435 end
==> MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 unreachable state_d = IdleSt;
444 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
445 unreachable dout_locked_d = MuBi8False;
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
456 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
457 1/1 scrmbl_cmd_o = Encrypt;
Tests: T1 T2 T3
458 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
459 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
460 1/1 state_d = IntegScrWaitSt;
Tests: T1 T2 T3
461 end
MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
468 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
469 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
470 1/1 state_d = IntegDigSt;
Tests: T1 T2 T3
471 end
MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
481 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
482 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
483 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
484 // No need to digest the digest value itself
485 1/1 if (cnt == PenultimateScrmblBlock) begin
Tests: T1 T2 T3
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
490 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
491 1/1 state_d = IntegDigFinSt;
Tests: T1 T2 T3
492 end else begin
493 0/1 ==> state_d = IntegDigPadSt;
494 0/1 ==> cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
499 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
500 end
MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 1/1 if (Info.secret) begin
Tests: T1 T2 T3
504 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
505 end
==> MISSING_ELSE
506 end
507 end
==> MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 0/1 ==> scrmbl_mtx_req_o = 1'b1;
517 0/1 ==> scrmbl_valid_o = 1'b1;
518 0/1 ==> scrmbl_cmd_o = Digest;
519 0/1 ==> if (scrmbl_ready_i) begin
520 0/1 ==> state_d = IntegDigFinSt;
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
529 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
530 1/1 scrmbl_cmd_o = DigestFinalize;
Tests: T1 T2 T3
531 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
532 1/1 state_d = IntegDigWaitSt;
Tests: T1 T2 T3
533 end
MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
543 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
544 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T1 T2 T3
548 1/1 state_d = IdleSt;
Tests: T1 T2 T3
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
552 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T67 T68 T69
561 1/1 error_d = CheckFailError;
Tests: T67 T68 T69
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T67 T68 T69
564 end
565 end
MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T8
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 1/1 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
Tests: T1 T2 T3
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 assign access_o.read_lock = access_pre.read_lock;
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1952,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 160 | 147 | 91.88 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 127 | 90.71 |
CONT_ASSIGN | 636 | 1 | 1 | 100.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 709 | 1 | 1 | 100.00 |
CONT_ASSIGN | 729 | 1 | 1 | 100.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 1/1 state_d = InitDescrSt;
Tests: T1 T2 T3
277 end else begin
278 unreachable state_d = InitSt;
279 unreachable cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T70 T32 T71
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T72 T73 T74
287 1/1 error_d = otp_err;
Tests: T72 T73 T74
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
299 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
300 1/1 scrmbl_cmd_o = Decrypt;
Tests: T1 T2 T3
301 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
302 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
303 1/1 state_d = InitDescrWaitSt;
Tests: T1 T2 T3
304 end
MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
312 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
313 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
314 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
315 1/1 state_d = InitSt;
Tests: T1 T2 T3
316 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
317 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
318 end
MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T12 T31
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 unreachable integ_chk_ack_o = 1'b1;
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 1/1 base_sel = DigOffset;
Tests: T3 T4 T5
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T3 T4 T5
369 1/1 state_d = IdleSt;
Tests: T3 T4 T5
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
371 // Error out and lock the partition if this check fails.
372 end else begin
373 0/1 ==> state_d = ErrorSt;
374 0/1 ==> error_d = CheckFailError;
375 // The check has finished and found an error.
376 0/1 ==> cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 unreachable if (scrmbl_data_o == data_mux ||
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 unreachable if (cnt == LastScrmblBlock) begin
386 unreachable state_d = IdleSt;
387 unreachable cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 unreachable state_d = CnstyReadSt;
391 unreachable cnt_en = 1'b1;
392 end
393 end else begin
394 unreachable state_d = ErrorSt;
395 unreachable error_d = CheckFailError;
396 // The check has finished and found an error.
397 unreachable cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T33 T37 T75
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T55 T76 T77
406 1/1 error_d = otp_err;
Tests: T55 T76 T77
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T55 T76 T77
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
419 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
420 1/1 cnt_clr = 1'b1;
Tests: T1 T2 T3
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 1/1 scrmbl_cmd_o = DigestInit;
Tests: T1 T2 T3
424 1/1 if (Info.secret) begin
Tests: T1 T2 T3
425 1/1 scrmbl_mode_o = ChainedMode;
Tests: T1 T2 T3
426 1/1 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
Tests: T1 T2 T3
427 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
428 end
MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 unreachable scrmbl_mode_o = StandardMode;
433 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
434 unreachable state_d = IntegDigSt;
435 end
==> MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 unreachable state_d = IdleSt;
444 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
445 unreachable dout_locked_d = MuBi8False;
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
456 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
457 1/1 scrmbl_cmd_o = Encrypt;
Tests: T1 T2 T3
458 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
459 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
460 1/1 state_d = IntegScrWaitSt;
Tests: T1 T2 T3
461 end
MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
468 1/1 scrmbl_sel_o = Info.key_sel;
Tests: T1 T2 T3
469 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
470 1/1 state_d = IntegDigSt;
Tests: T1 T2 T3
471 end
MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
481 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
482 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
483 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
484 // No need to digest the digest value itself
485 1/1 if (cnt == PenultimateScrmblBlock) begin
Tests: T1 T2 T3
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
490 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
491 1/1 state_d = IntegDigFinSt;
Tests: T1 T2 T3
492 end else begin
493 0/1 ==> state_d = IntegDigPadSt;
494 0/1 ==> cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 1/1 if (cnt[0]) begin
Tests: T1 T2 T3
499 1/1 scrmbl_cmd_o = Digest;
Tests: T1 T2 T3
500 end
MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 1/1 if (Info.secret) begin
Tests: T1 T2 T3
504 1/1 state_d = IntegScrSt;
Tests: T1 T2 T3
505 end
==> MISSING_ELSE
506 end
507 end
==> MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 0/1 ==> scrmbl_mtx_req_o = 1'b1;
517 0/1 ==> scrmbl_valid_o = 1'b1;
518 0/1 ==> scrmbl_cmd_o = Digest;
519 0/1 ==> if (scrmbl_ready_i) begin
520 0/1 ==> state_d = IntegDigFinSt;
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
529 1/1 scrmbl_valid_o = 1'b1;
Tests: T1 T2 T3
530 1/1 scrmbl_cmd_o = DigestFinalize;
Tests: T1 T2 T3
531 1/1 if (scrmbl_ready_i) begin
Tests: T1 T2 T3
532 1/1 state_d = IntegDigWaitSt;
Tests: T1 T2 T3
533 end
MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 1/1 scrmbl_mtx_req_o = 1'b1;
Tests: T1 T2 T3
543 1/1 data_sel = ScrmblData;
Tests: T1 T2 T3
544 1/1 if (scrmbl_valid_i) begin
Tests: T1 T2 T3
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 1/1 if (digest_o == data_mux || digest_o == '0) begin
Tests: T1 T2 T3
548 1/1 state_d = IdleSt;
Tests: T1 T2 T3
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
552 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T78 T79
561 1/1 error_d = CheckFailError;
Tests: T78 T79
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T78 T79
564 end
565 end
MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T8
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 1/1 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
Tests: T1 T2 T3
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 1/1 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
Tests: T1 T2 T3
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 assign access_o.read_lock = access_pre.read_lock;
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Line Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=2040,StateWidth=12 )
Line Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
TOTAL | | 131 | 94 | 71.76 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 111 | 77 | 69.37 |
CONT_ASSIGN | 636 | 1 | 0 | 0.00 |
CONT_ASSIGN | 641 | 1 | 1 | 100.00 |
CONT_ASSIGN | 642 | 1 | 1 | 100.00 |
CONT_ASSIGN | 646 | 1 | 1 | 100.00 |
CONT_ASSIGN | 652 | 1 | 1 | 100.00 |
CONT_ASSIGN | 675 | 1 | 1 | 100.00 |
CONT_ASSIGN | 678 | 1 | 1 | 100.00 |
CONT_ASSIGN | 680 | 1 | 1 | 100.00 |
CONT_ASSIGN | 723 | 1 | 0 | 0.00 |
CONT_ASSIGN | 743 | 1 | 0 | 0.00 |
ALWAYS | 750 | 3 | 3 | 100.00 |
ALWAYS | 753 | 5 | 5 | 100.00 |
181 // Output partition error state.
182 1/1 assign error_o = error_q;
Tests: T1 T2 T3
183
184 // This partition cannot do any write accesses, hence we tie this
185 // constantly off.
186 assign otp_wdata_o = '0;
187 // Depending on the partition configuration, the wrapper is instructed to ignore integrity
188 // calculations and checks. To be on the safe side, the partition filters error responses at this
189 // point and does not report any integrity errors if integrity is disabled.
190 otp_err_e otp_err;
191 if (Info.integrity) begin : gen_integrity
192 assign otp_cmd_o = prim_otp_pkg::Read;
193 1/1 assign otp_err = otp_err_e'(otp_err_i);
Tests: T1 T2 T3
194 end else begin : gen_no_integrity
195 assign otp_cmd_o = prim_otp_pkg::ReadRaw;
196 always_comb begin
197 if (otp_err_e'(otp_err_i) inside {MacroEccCorrError, MacroEccUncorrError}) begin
198 otp_err = NoError;
199 end else begin
200 otp_err = otp_err_e'(otp_err_i);
201 end
202 end
203 end
204
205 always_comb begin : p_fsm
206 1/1 state_d = state_q;
Tests: T1 T2 T3
207
208 // Redundantly encoded lock signal for buffer regs.
209 1/1 dout_locked_d = dout_locked_q;
Tests: T1 T2 T3
210
211 // OTP signals
212 1/1 otp_req_o = 1'b0;
Tests: T1 T2 T3
213
214 // Scrambling mutex
215 1/1 scrmbl_mtx_req_o = 1'b0;
Tests: T1 T2 T3
216
217 // Scrambling datapath
218 1/1 scrmbl_cmd_o = LoadShadow;
Tests: T1 T2 T3
219 1/1 scrmbl_sel_o = CnstyDigest;
Tests: T1 T2 T3
220 1/1 scrmbl_mode_o = StandardMode;
Tests: T1 T2 T3
221 1/1 scrmbl_valid_o = 1'b0;
Tests: T1 T2 T3
222
223 // Counter
224 1/1 cnt_en = 1'b0;
Tests: T1 T2 T3
225 1/1 cnt_clr = 1'b0;
Tests: T1 T2 T3
226 1/1 base_sel = PartOffset;
Tests: T1 T2 T3
227
228 // Buffer register
229 1/1 buffer_reg_en = 1'b0;
Tests: T1 T2 T3
230 1/1 data_sel = OtpData;
Tests: T1 T2 T3
231
232 // Error Register
233 1/1 error_d = error_q;
Tests: T1 T2 T3
234 1/1 fsm_err_o = 1'b0;
Tests: T1 T2 T3
235
236 // Integrity/Consistency check responses
237 1/1 cnsty_chk_ack_o = 1'b0;
Tests: T1 T2 T3
238 1/1 integ_chk_ack_o = 1'b0;
Tests: T1 T2 T3
239
240 1/1 unique case (state_q)
Tests: T1 T2 T3
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 1/1 if (init_req_i) begin
Tests: T1 T2 T3
246 1/1 state_d = InitSt;
Tests: T1 T2 T3
247 end
MISSING_ELSE
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 1/1 otp_req_o = 1'b1;
Tests: T1 T2 T3
255 1/1 if (otp_gnt_i) begin
Tests: T1 T2 T3
256 1/1 state_d = InitWaitSt;
Tests: T1 T2 T3
257 end
MISSING_ELSE
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 1/1 if (otp_rvalid_i) begin
Tests: T1 T2 T3
266 1/1 buffer_reg_en = 1'b1;
Tests: T1 T2 T3
267 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T1 T2 T3
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 1/1 if (cnt == LastScrmblBlock) begin
Tests: T1 T2 T3
272 1/1 state_d = IntegDigClrSt;
Tests: T1 T2 T3
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 1/1 end else if (Info.secret) begin
Tests: T1 T2 T3
276 unreachable state_d = InitDescrSt;
277 end else begin
278 1/1 state_d = InitSt;
Tests: T1 T2 T3
279 1/1 cnt_en = 1'b1;
Tests: T1 T2 T3
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 1/1 if (otp_err != NoError) begin
Tests: T1 T2 T3
283 1/1 error_d = MacroEccCorrError;
Tests: T26 T72 T61
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T2 T25 T80
287 1/1 error_d = otp_err;
Tests: T2 T25 T80
288 end
289 end
MISSING_ELSE
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 0/1 ==> scrmbl_mtx_req_o = 1'b1;
299 0/1 ==> scrmbl_valid_o = 1'b1;
300 0/1 ==> scrmbl_cmd_o = Decrypt;
301 0/1 ==> scrmbl_sel_o = Info.key_sel;
302 0/1 ==> if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
303 unreachable state_d = InitDescrWaitSt;
304 end
==> MISSING_ELSE
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 0/1 ==> scrmbl_mtx_req_o = 1'b1;
312 0/1 ==> scrmbl_sel_o = Info.key_sel;
313 0/1 ==> data_sel = ScrmblData;
314 0/1 ==> if (scrmbl_valid_i) begin
315 unreachable state_d = InitSt;
316 unreachable buffer_reg_en = 1'b1;
317 unreachable cnt_en = 1'b1;
318 end
==> MISSING_ELSE
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 1/1 if (integ_chk_req_i) begin
Tests: T1 T2 T3
325 1/1 if (Info.hw_digest) begin
Tests: T6 T12 T31
326 unreachable state_d = IntegDigClrSt;
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 1/1 integ_chk_ack_o = 1'b1;
Tests: T6 T12 T31
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
335 1/1 cnt_clr = 1'b1;
Tests: T3 T4 T5
336 end
MISSING_ELSE
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 1/1 otp_req_o = 1'b1;
Tests: T3 T4 T5
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
349 unreachable base_sel = DigOffset;
350 end
MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T3 T4 T5
352 1/1 state_d = CnstyReadWaitSt;
Tests: T3 T4 T5
353 end
MISSING_ELSE
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 1/1 if (otp_rvalid_i) begin
Tests: T3 T4 T5
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T3 T4 T5
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 1/1 if (Info.hw_digest) begin
Tests: T3 T4 T5
367 // Note that we ignore this check if the digest is still blank.
368 unreachable if (digest_o == data_mux || digest_o == '0) begin
369 unreachable state_d = IdleSt;
370 unreachable cnsty_chk_ack_o = 1'b1;
371 // Error out and lock the partition if this check fails.
372 end else begin
373 unreachable state_d = ErrorSt;
374 unreachable error_d = CheckFailError;
375 // The check has finished and found an error.
376 unreachable cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 1/1 if (scrmbl_data_o == data_mux ||
Tests: T3 T4 T5
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 1/1 if (cnt == LastScrmblBlock) begin
Tests: T3 T4 T5
386 1/1 state_d = IdleSt;
Tests: T3 T4 T5
387 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T3 T4 T5
388 // Need to go back and read out more blocks.
389 end else begin
390 1/1 state_d = CnstyReadSt;
Tests: T3 T4 T5
391 1/1 cnt_en = 1'b1;
Tests: T3 T4 T5
392 end
393 end else begin
394 1/1 state_d = ErrorSt;
Tests: T26 T81 T53
395 1/1 error_d = CheckFailError;
Tests: T26 T81 T53
396 // The check has finished and found an error.
397 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T26 T81 T53
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 1/1 if (otp_err != NoError) begin
Tests: T3 T4 T5
402 1/1 error_d = MacroEccCorrError;
Tests: T82 T55 T56
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T82 T83 T84
406 1/1 error_d = otp_err;
Tests: T82 T83 T84
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T82 T83 T84
409 end
410 end
MISSING_ELSE
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 1/1 if (Info.hw_digest) begin
Tests: T1 T2 T3
418 unreachable scrmbl_mtx_req_o = 1'b1;
419 unreachable scrmbl_valid_o = 1'b1;
420 unreachable cnt_clr = 1'b1;
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 unreachable scrmbl_cmd_o = DigestInit;
424 unreachable if (Info.secret) begin
425 unreachable scrmbl_mode_o = ChainedMode;
426 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
427 unreachable state_d = IntegScrSt;
428 end
==> MISSING_ELSE
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 unreachable scrmbl_mode_o = StandardMode;
433 unreachable if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
434 unreachable state_d = IntegDigSt;
435 end
==> MISSING_ELSE
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 1/1 state_d = IdleSt;
Tests: T1 T2 T3
444 1/1 if (mubi8_test_true_strict(dout_locked_q)) begin
Tests: T1 T2 T3
445 1/1 dout_locked_d = MuBi8False;
Tests: T1 T2 T3
446 end
==> MISSING_ELSE
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 0/1 ==> scrmbl_mtx_req_o = 1'b1;
456 0/1 ==> scrmbl_valid_o = 1'b1;
457 0/1 ==> scrmbl_cmd_o = Encrypt;
458 0/1 ==> scrmbl_sel_o = Info.key_sel;
459 0/1 ==> if (scrmbl_ready_i) begin
460 unreachable state_d = IntegScrWaitSt;
461 end
==> MISSING_ELSE
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 0/1 ==> scrmbl_mtx_req_o = 1'b1;
468 0/1 ==> scrmbl_sel_o = Info.key_sel;
469 0/1 ==> if (scrmbl_valid_i) begin
470 unreachable state_d = IntegDigSt;
471 end
==> MISSING_ELSE
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 0/1 ==> scrmbl_mtx_req_o = 1'b1;
481 0/1 ==> scrmbl_valid_o = 1'b1;
482 0/1 ==> if (scrmbl_ready_i) begin
483 unreachable cnt_en = 1'b1;
484 // No need to digest the digest value itself
485 unreachable if (cnt == PenultimateScrmblBlock) begin
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 unreachable if (cnt[0]) begin
490 unreachable scrmbl_cmd_o = Digest;
491 unreachable state_d = IntegDigFinSt;
492 end else begin
493 unreachable state_d = IntegDigPadSt;
494 unreachable cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 unreachable if (cnt[0]) begin
499 unreachable scrmbl_cmd_o = Digest;
500 end
==> MISSING_ELSE
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 unreachable if (Info.secret) begin
504 unreachable state_d = IntegScrSt;
505 end
==> MISSING_ELSE
506 end
507 end
==> MISSING_ELSE
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 0/1 ==> scrmbl_mtx_req_o = 1'b1;
517 0/1 ==> scrmbl_valid_o = 1'b1;
518 0/1 ==> scrmbl_cmd_o = Digest;
519 0/1 ==> if (scrmbl_ready_i) begin
520 unreachable state_d = IntegDigFinSt;
521 end
==> MISSING_ELSE
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 0/1 ==> scrmbl_mtx_req_o = 1'b1;
529 0/1 ==> scrmbl_valid_o = 1'b1;
530 0/1 ==> scrmbl_cmd_o = DigestFinalize;
531 0/1 ==> if (scrmbl_ready_i) begin
532 unreachable state_d = IntegDigWaitSt;
533 end
==> MISSING_ELSE
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 0/1 ==> scrmbl_mtx_req_o = 1'b1;
543 0/1 ==> data_sel = ScrmblData;
544 0/1 ==> if (scrmbl_valid_i) begin
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 unreachable if (digest_o == data_mux || digest_o == '0) begin
548 unreachable state_d = IdleSt;
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 unreachable if (mubi8_test_true_strict(dout_locked_q)) begin
552 unreachable dout_locked_d = MuBi8False;
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 unreachable integ_chk_ack_o = 1'b1;
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 unreachable state_d = ErrorSt;
561 unreachable error_d = CheckFailError;
562 // The check has finished and found an error.
563 unreachable integ_chk_ack_o = 1'b1;
564 end
565 end
==> MISSING_ELSE
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 1/1 dout_locked_d = MuBi8True;
Tests: T2 T4 T8
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T8
574 1/1 error_d = FsmStateError;
Tests: T22 T23 T24
575 end
MISSING_ELSE
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T2 T4 T8
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T8
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
586 fsm_err_o = 1'b1;
587 end
588 ///////////////////////////////////////////////////////////////////
589 endcase // state_q
590
591
592 // Unconditionally jump into the terminal error state in case of
593 // an ECC error or escalation, and lock access to the partition down.
594 // SEC_CM: PART.FSM.LOCAL_ESC
595 1/1 if (ecc_err) begin
Tests: T1 T2 T3
596 0/1 ==> state_d = ErrorSt;
597 0/1 ==> if (state_q != ErrorSt) begin
598 0/1 ==> error_d = CheckFailError;
599 end
==> MISSING_ELSE
600 end
MISSING_ELSE
601 // SEC_CM: PART.FSM.LOCAL_ESC, PART.FSM.GLOBAL_ESC
602 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
Tests: T1 T2 T3
603 1/1 state_d = ErrorSt;
Tests: T2 T4 T8
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T8
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T8
606 1/1 error_d = FsmStateError;
Tests: T4 T8 T85
607 end
MISSING_ELSE
608 end
MISSING_ELSE
609 end
610
611 ////////////////////////////
612 // Address Calc and Muxes //
613 ////////////////////////////
614
615 // Address counter - this is only used for computing a digest, hence the increment is
616 // fixed to 8 byte.
617 // SEC_CM: PART.CTR.REDUN
618 prim_count #(
619 .Width(CntWidth)
620 ) u_prim_count (
621 .clk_i,
622 .rst_ni,
623 .clr_i(cnt_clr),
624 .set_i(1'b0),
625 .set_cnt_i('0),
626 .incr_en_i(cnt_en),
627 .decr_en_i(1'b0),
628 .step_i(CntWidth'(1)),
629 .commit_i(1'b1),
630 .cnt_o(cnt),
631 .cnt_after_commit_o(),
632 .err_o(cnt_err)
633 );
634
635 logic [OtpByteAddrWidth-1:0] addr_base;
636 0/1 ==> assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
637
638 // Note that OTP works on halfword (16bit) addresses, hence need to
639 // shift the addresses appropriately.
640 logic [OtpByteAddrWidth-1:0] addr_calc;
641 1/1 assign addr_calc = OtpByteAddrWidth'({cnt, {$clog2(ScrmblBlockWidth/8){1'b0}}}) + addr_base;
Tests: T1 T2 T3
642 1/1 assign otp_addr_o = addr_calc[OtpByteAddrWidth-1:OtpAddrShift];
Tests: T1 T2 T3
643
644 if (OtpAddrShift > 0) begin : gen_unused
645 logic unused_bits;
646 1/1 assign unused_bits = ^addr_calc[OtpAddrShift-1:0];
Tests: T1 T2 T3
647 end
648
649 // Always transfer 64bit blocks.
650 assign otp_size_o = OtpSizeWidth'(unsigned'(ScrmblBlockWidth / OtpWidth) - 1);
651
652 1/1 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
Tests: T1 T2 T3
653
654 /////////////////
655 // Buffer Regs //
656 /////////////////
657
658 // SEC_CM: PART.DATA_REG.INTEGRITY
659 logic [Info.size*8-1:0] data;
660 otp_ctrl_ecc_reg #(
661 .Width ( ScrmblBlockWidth ),
662 .Depth ( NumScrmblBlocks )
663 ) u_otp_ctrl_ecc_reg (
664 .clk_i,
665 .rst_ni,
666 .wren_i ( buffer_reg_en ),
667 .addr_i ( cnt ),
668 .wdata_i ( data_mux ),
669 .rdata_o ( scrmbl_data_o ),
670 .data_o ( data ),
671 .ecc_err_o ( ecc_err )
672 );
673
674 // We have successfully initialized the partition once it has been unlocked.
675 1/1 assign init_done_o = mubi8_test_false_strict(dout_locked_q);
Tests: T1 T2 T3
676 // Hardware output gating.
677 // Note that this is decoupled from the DAI access rules further below.
678 1/1 assign data_o = (init_done_o) ? data : DataDefault;
Tests: T1 T2 T3
679 // The digest does not have to be gated.
680 1/1 assign digest_o = data[$high(data_o) -: ScrmblBlockWidth];
Tests: T1 T2 T3
681
682 ////////////////////////
683 // DAI Access Control //
684 ////////////////////////
685
686 // Aggregate all possible DAI write /readlocks. The partition is also locked when uninitialized.
687 // Note that the locks are redundantly encoded values.
688 part_access_t access_pre;
689 prim_mubi8_sender #(
690 .AsyncOn(0)
691 ) u_prim_mubi8_sender_write_lock_pre (
692 .clk_i,
693 .rst_ni,
694 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.write_lock)),
695 .mubi_o(access_pre.write_lock)
696 );
697 prim_mubi8_sender #(
698 .AsyncOn(0)
699 ) u_prim_mubi8_sender_read_lock_pre (
700 .clk_i,
701 .rst_ni,
702 .mubi_i(mubi8_and_lo(dout_locked_q, access_i.read_lock)),
703 .mubi_o(access_pre.read_lock)
704 );
705
706 // SEC_CM: PART.MEM.SW_UNWRITABLE
707 if (Info.write_lock) begin : gen_digest_write_lock
708 mubi8_t digest_locked;
709 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
710
711 // This prevents the synthesis tool from optimizing the multibit signal.
712 prim_mubi8_sender #(
713 .AsyncOn(0)
714 ) u_prim_mubi8_sender_write_lock (
715 .clk_i,
716 .rst_ni,
717 .mubi_i(mubi8_and_lo(access_pre.write_lock, digest_locked)),
718 .mubi_o(access_o.write_lock)
719 );
720
721 `ASSERT(DigestWriteLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.write_lock))
722 end else begin : gen_no_digest_write_lock
723 0/1 ==> assign access_o.write_lock = access_pre.write_lock;
724 end
725
726 // SEC_CM: PART.MEM.SW_UNREADABLE
727 if (Info.read_lock) begin : gen_digest_read_lock
728 mubi8_t digest_locked;
729 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
730
731 // This prevents the synthesis tool from optimizing the multibit signal.
732 prim_mubi8_sender #(
733 .AsyncOn(0)
734 ) u_prim_mubi8_sender_read_lock (
735 .clk_i,
736 .rst_ni,
737 .mubi_i(mubi8_and_lo(access_pre.read_lock, digest_locked)),
738 .mubi_o(access_o.read_lock)
739 );
740
741 `ASSERT(DigestReadLocksPartition_A, digest_o |-> mubi8_test_true_loose(access_o.read_lock))
742 end else begin : gen_no_digest_read_lock
743 0/1 ==> assign access_o.read_lock = access_pre.read_lock;
744 end
745
746 ///////////////
747 // Registers //
748 ///////////////
749
750 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3
PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt):
750.1 `ifdef SIMULATION
750.2 prim_sparse_fsm_flop #(
750.3 .StateEnumT(state_e),
750.4 .Width($bits(state_e)),
750.5 .ResetValue($bits(state_e)'(ResetSt)),
750.6 .EnableAlertTriggerSVA(1),
750.7 .CustomForceName("state_q")
750.8 ) u_state_regs (
750.9 .clk_i ( clk_i ),
750.10 .rst_ni ( rst_ni ),
750.11 .state_i ( state_d ),
750.12 .state_o ( )
750.13 );
750.14 always_ff @(posedge clk_i or negedge rst_ni) begin
750.15 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
750.16 1/1 state_q <= ResetSt;
Tests: T1 T2 T3
750.17 end else begin
750.18 1/1 state_q <= state_d;
Tests: T1 T2 T3
750.19 end
750.20 end
750.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (state_q === u_state_regs.state_o))
750.22 else begin
750.23 `ifdef UVM
750.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE,
750.25 "../src/lowrisc_ip_otp_ctrl_1.0/rtl/otp_ctrl_part_buf.sv", 750, "", 1);
750.26 `else
750.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__,
750.28 `PRIM_STRINGIFY(u_state_regs_A));
750.29 `endif
750.30 end
750.31 `else
750.32 prim_sparse_fsm_flop #(
750.33 .StateEnumT(state_e),
750.34 .Width($bits(state_e)),
750.35 .ResetValue($bits(state_e)'(ResetSt)),
750.36 .EnableAlertTriggerSVA(1)
750.37 ) u_state_regs (
750.38 .clk_i ( `PRIM_FLOP_CLK ),
750.39 .rst_ni ( `PRIM_FLOP_RST ),
750.40 .state_i ( state_d ),
750.41 .state_o ( state_q )
750.42 );
750.43 `endif751
752 always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
753 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
754 1/1 error_q <= NoError;
Tests: T1 T2 T3
755 // data output is locked by default
756 1/1 dout_locked_q <= MuBi8True;
Tests: T1 T2 T3
757 end else begin
758 1/1 error_q <= error_d;
Tests: T1 T2 T3
759 1/1 dout_locked_q <= dout_locked_d;
Tests: T1 T2 T3
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1720,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 48 | 41 | 85.42 |
Logical | 48 | 41 | 85.42 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T25,T26,T27 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Not Covered | |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T32 |
0 | 1 | Covered | T13,T15,T86 |
1 | 0 | Covered | T6,T31,T87 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T15,T86 |
1 | Covered | T3,T4,T5 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T31,T87 |
1 | Covered | T3,T4,T5 |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T33,T34,T35 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T38,T39,T40 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T3,T6,T31 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T31 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T3,T6,T31 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T2,T4,T8 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11001111000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 709
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T31 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T31 |
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1952,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 52 | 45 | 86.54 |
Logical | 52 | 45 | 86.54 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T70,T32,T71 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Covered | T13,T14,T88 |
1 | 0 | Covered | T6,T31,T87 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T14,T88 |
1 | Covered | T3,T4,T5 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T31,T87 |
1 | Covered | T3,T4,T5 |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T33,T37,T75 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T78,T79 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T3,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T3,T6,T89 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T2,T4,T8 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11101010000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 709
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T89 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T89 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T89 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T6,T89 |
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=1,DigestOffset=1736,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 48 | 39 | 81.25 |
Logical | 48 | 39 | 81.25 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T41,T26,T30 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Not Covered | |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Covered | T13,T14,T15 |
1 | 0 | Covered | T6,T31,T16 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T3,T4,T5 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T31,T16 |
1 | Covered | T3,T4,T5 |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T45,T46 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T1,T2,T3 |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T49,T50,T51 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T5,T6,T89 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T2,T4,T8 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011000000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 709
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=3,DigestOffset=1776,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 52 | 45 | 86.54 |
Logical | 52 | 45 | 86.54 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T29,T52,T53 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Covered | T13,T14,T15 |
1 | 0 | Covered | T6,T31,T87 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T3,T4,T5 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T31,T87 |
1 | Covered | T3,T4,T5 |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T55,T36,T34 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T58,T59,T60 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T6,T89,T31 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T89,T31 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T89,T31 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T2,T4,T8 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011010000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 709
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T89,T31 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T89,T31 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T89,T31 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T89,T31 |
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=2040,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 24 | 18 | 75.00 |
Logical | 24 | 18 | 75.00 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T26,T72,T61 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Unreachable | |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T3,T4,T5 |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T82,T55,T56 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Unreachable | |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T4,T8,T85 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11110101000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Not Covered | |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
Cond Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1864,StateWidth=12 )
Cond Coverage for Module self-instances :
| Total | Covered | Percent |
Conditions | 52 | 45 | 86.54 |
Logical | 52 | 45 | 86.54 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 282
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T61,T62,T63 |
LINE 302
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 368
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Not Covered | |
0 | 1 | Covered | T13,T14,T15 |
1 | 0 | Covered | T6,T31,T16 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T3,T4,T5 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T6,T31,T16 |
1 | Covered | T3,T4,T5 |
LINE 385
EXPRESSION (cnt == LastScrmblBlock)
------------1-----------
-1- | Status | Tests |
0 | Unreachable | |
1 | Unreachable | |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T3,T4,T5 |
1 | Covered | T56,T66 |
LINE 426
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T1,T2,T3 |
LINE 433
EXPRESSION (scrmbl_mtx_gnt_i && scrmbl_ready_i)
--------1------- -------2------
-1- | -2- | Status | Tests |
0 | 1 | Unreachable | |
1 | 0 | Unreachable | |
1 | 1 | Unreachable | |
LINE 485
EXPRESSION (cnt == PenultimateScrmblBlock)
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 547
EXPRESSION ((digest_o == data_mux) || (digest_o == '0))
-----------1---------- --------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T67,T68,T69 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T5,T6,T89 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T22,T23,T24 |
LINE 597
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Not Covered | |
1 | Not Covered | |
LINE 605
EXPRESSION (state_q != ErrorSt)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T8 |
1 | Covered | T2,T4,T8 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011111000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T4,T5 |
LINE 652
EXPRESSION ((data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 652
SUB-EXPRESSION (data_sel == ScrmblData)
------------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 678
EXPRESSION (init_done_o ? data : DataDefault)
-----1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 709
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T6,T89 |
FSM Coverage for Module :
otp_ctrl_part_buf
Summary for FSM :: state_q
| Total | Covered | Percent | |
States |
16 |
16 |
100.00 |
(Not included in score) |
Transitions |
38 |
37 |
97.37 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: state_q
states | Line No. | Covered | Tests |
CnstyReadSt |
334 |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
352 |
Covered |
T3,T4,T5 |
ErrorSt |
286 |
Covered |
T2,T4,T8 |
IdleSt |
369 |
Covered |
T1,T2,T3 |
InitDescrSt |
276 |
Covered |
T1,T2,T3 |
InitDescrWaitSt |
303 |
Covered |
T1,T2,T3 |
InitSt |
246 |
Covered |
T1,T2,T3 |
InitWaitSt |
256 |
Covered |
T1,T2,T3 |
IntegDigClrSt |
272 |
Covered |
T1,T2,T3 |
IntegDigFinSt |
491 |
Covered |
T1,T2,T3 |
IntegDigPadSt |
493 |
Covered |
T1,T2,T3 |
IntegDigSt |
434 |
Covered |
T1,T2,T3 |
IntegDigWaitSt |
532 |
Covered |
T1,T2,T3 |
IntegScrSt |
427 |
Covered |
T1,T2,T3 |
IntegScrWaitSt |
460 |
Covered |
T1,T2,T3 |
ResetSt |
244 |
Covered |
T1,T2,T3 |
transitions | Line No. | Covered | Tests |
CnstyReadSt->CnstyReadWaitSt |
352 |
Covered |
T3,T4,T5 |
CnstyReadSt->ErrorSt |
596 |
Covered |
T87,T45,T33 |
CnstyReadWaitSt->CnstyReadSt |
390 |
Covered |
T3,T4,T5 |
CnstyReadWaitSt->ErrorSt |
373 |
Covered |
T87,T45,T33 |
CnstyReadWaitSt->IdleSt |
369 |
Covered |
T3,T4,T5 |
IdleSt->CnstyReadSt |
334 |
Covered |
T3,T4,T5 |
IdleSt->ErrorSt |
596 |
Covered |
T2,T4,T8 |
IdleSt->IntegDigClrSt |
326 |
Covered |
T6,T12,T31 |
InitDescrSt->ErrorSt |
596 |
Covered |
T2,T90,T58 |
InitDescrSt->InitDescrWaitSt |
303 |
Covered |
T1,T2,T3 |
InitDescrWaitSt->ErrorSt |
596 |
Covered |
T2,T58,T25 |
InitDescrWaitSt->InitSt |
315 |
Covered |
T1,T2,T3 |
InitSt->ErrorSt |
596 |
Covered |
T2,T85,T91 |
InitSt->InitWaitSt |
256 |
Covered |
T1,T2,T3 |
InitWaitSt->ErrorSt |
286 |
Covered |
T2,T91,T41 |
InitWaitSt->InitDescrSt |
276 |
Covered |
T1,T2,T3 |
InitWaitSt->InitSt |
278 |
Covered |
T1,T2,T3 |
InitWaitSt->IntegDigClrSt |
272 |
Covered |
T1,T2,T3 |
IntegDigClrSt->ErrorSt |
596 |
Covered |
T31,T58,T92 |
IntegDigClrSt->IdleSt |
443 |
Covered |
T1,T2,T3 |
IntegDigClrSt->IntegDigSt |
434 |
Covered |
T1,T2,T3 |
IntegDigClrSt->IntegScrSt |
427 |
Covered |
T1,T2,T3 |
IntegDigFinSt->ErrorSt |
596 |
Covered |
T93,T94,T95 |
IntegDigFinSt->IntegDigWaitSt |
532 |
Covered |
T1,T2,T3 |
IntegDigPadSt->ErrorSt |
596 |
Not Covered |
|
IntegDigPadSt->IntegDigFinSt |
520 |
Covered |
T1,T2,T3 |
IntegDigSt->ErrorSt |
596 |
Covered |
T90,T96,T97 |
IntegDigSt->IntegDigFinSt |
491 |
Covered |
T1,T2,T3 |
IntegDigSt->IntegDigPadSt |
493 |
Covered |
T1,T2,T3 |
IntegDigSt->IntegScrSt |
504 |
Covered |
T1,T2,T3 |
IntegDigWaitSt->ErrorSt |
560 |
Covered |
T58,T49,T50 |
IntegDigWaitSt->IdleSt |
548 |
Covered |
T1,T2,T3 |
IntegScrSt->ErrorSt |
596 |
Covered |
T92,T98,T67 |
IntegScrSt->IntegScrWaitSt |
460 |
Covered |
T1,T2,T3 |
IntegScrWaitSt->ErrorSt |
596 |
Covered |
T31,T45,T99 |
IntegScrWaitSt->IntegDigSt |
470 |
Covered |
T1,T2,T3 |
ResetSt->ErrorSt |
596 |
Covered |
T100,T101,T102 |
ResetSt->InitSt |
246 |
Covered |
T1,T2,T3 |
Summary for FSM :: error_q
| Total | Covered | Percent | |
States |
4 |
4 |
100.00 |
(Not included in score) |
Transitions |
9 |
5 |
55.56 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: error_q
states | Line No. | Covered | Tests |
CheckFailError |
374 |
Covered |
T58,T49,T50 |
FsmStateError |
574 |
Covered |
T2,T4,T8 |
MacroEccCorrError |
283 |
Covered |
T45,T33,T41 |
NoError |
573 |
Covered |
T1,T2,T3 |
transitions | Line No. | Covered | Tests |
CheckFailError->FsmStateError |
606 |
Not Covered |
|
CheckFailError->MacroEccCorrError |
283 |
Not Covered |
|
FsmStateError->CheckFailError |
374 |
Not Covered |
|
FsmStateError->MacroEccCorrError |
283 |
Not Covered |
|
MacroEccCorrError->CheckFailError |
374 |
Covered |
T26,T61,T63 |
MacroEccCorrError->FsmStateError |
606 |
Covered |
T41,T25,T29 |
NoError->CheckFailError |
374 |
Covered |
T58,T49,T50 |
NoError->FsmStateError |
574 |
Covered |
T2,T4,T8 |
NoError->MacroEccCorrError |
283 |
Covered |
T45,T33,T41 |
Branch Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=3,DigestOffset=1776,StateWidth=12 + Info=-1,CntWidth=4,DigestOffset=1864,StateWidth=12 + Info=-1,CntWidth=4,DigestOffset=1952,StateWidth=12 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
73 |
62 |
84.93 |
TERNARY |
636 |
2 |
2 |
100.00 |
TERNARY |
652 |
2 |
2 |
100.00 |
TERNARY |
678 |
2 |
2 |
100.00 |
TERNARY |
709 |
2 |
2 |
100.00 |
TERNARY |
729 |
2 |
2 |
100.00 |
CASE |
240 |
53 |
44 |
83.02 |
IF |
595 |
3 |
1 |
33.33 |
IF |
602 |
3 |
3 |
100.00 |
IF |
750 |
2 |
2 |
100.00 |
IF |
753 |
2 |
2 |
100.00 |
636 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T3,T4,T5 |
0 |
Covered |
T1,T2,T3 |
652 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
678 assign data_o = (init_done_o) ? data : DataDefault;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
709 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T3,T5,T6 |
0 |
Covered |
T1,T2,T3 |
729 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T3,T5,T6 |
0 |
Covered |
T1,T2,T3 |
240 unique case (state_q)
-1-
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 if (init_req_i) begin
-2-
246 state_d = InitSt;
==>
247 end
MISSING_ELSE
==>
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 otp_req_o = 1'b1;
255 if (otp_gnt_i) begin
-3-
256 state_d = InitWaitSt;
==>
257 end
MISSING_ELSE
==>
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 if (otp_rvalid_i) begin
-4-
266 buffer_reg_en = 1'b1;
267 if (otp_err inside {NoError, MacroEccCorrError}) begin
-5-
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 if (cnt == LastScrmblBlock) begin
-6-
272 state_d = IntegDigClrSt;
==>
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 end else if (Info.secret) begin
-7-
276 state_d = InitDescrSt;
==>
277 end else begin
278 state_d = InitSt;
==> (Unreachable)
279 cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 if (otp_err != NoError) begin
-8-
283 error_d = MacroEccCorrError;
==>
284 end
MISSING_ELSE
==>
285 end else begin
286 state_d = ErrorSt;
==>
287 error_d = otp_err;
288 end
289 end
MISSING_ELSE
==>
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 scrmbl_mtx_req_o = 1'b1;
299 scrmbl_valid_o = 1'b1;
300 scrmbl_cmd_o = Decrypt;
301 scrmbl_sel_o = Info.key_sel;
302 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-9-
303 state_d = InitDescrWaitSt;
==>
304 end
MISSING_ELSE
==>
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 scrmbl_mtx_req_o = 1'b1;
312 scrmbl_sel_o = Info.key_sel;
313 data_sel = ScrmblData;
314 if (scrmbl_valid_i) begin
-10-
315 state_d = InitSt;
==>
316 buffer_reg_en = 1'b1;
317 cnt_en = 1'b1;
318 end
MISSING_ELSE
==>
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 if (integ_chk_req_i) begin
-11-
325 if (Info.hw_digest) begin
-12-
326 state_d = IntegDigClrSt;
==>
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 integ_chk_ack_o = 1'b1;
==> (Unreachable)
332 end
333 end else if (cnsty_chk_req_i) begin
-13-
334 state_d = CnstyReadSt;
==>
335 cnt_clr = 1'b1;
336 end
MISSING_ELSE
==>
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 otp_req_o = 1'b1;
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 if (Info.hw_digest) begin
-14-
349 base_sel = DigOffset;
==>
350 end
MISSING_ELSE
==>
351 if (otp_gnt_i) begin
-15-
352 state_d = CnstyReadWaitSt;
==>
353 end
MISSING_ELSE
==>
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 if (otp_rvalid_i) begin
-16-
363 if (otp_err inside {NoError, MacroEccCorrError}) begin
-17-
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 if (Info.hw_digest) begin
-18-
367 // Note that we ignore this check if the digest is still blank.
368 if (digest_o == data_mux || digest_o == '0) begin
-19-
369 state_d = IdleSt;
==>
370 cnsty_chk_ack_o = 1'b1;
371 // Error out and lock the partition if this check fails.
372 end else begin
373 state_d = ErrorSt;
==>
374 error_d = CheckFailError;
375 // The check has finished and found an error.
376 cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 if (scrmbl_data_o == data_mux ||
-20-
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 if (cnt == LastScrmblBlock) begin
-21-
386 state_d = IdleSt;
==> (Unreachable)
387 cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 state_d = CnstyReadSt;
==> (Unreachable)
391 cnt_en = 1'b1;
392 end
393 end else begin
394 state_d = ErrorSt;
==> (Unreachable)
395 error_d = CheckFailError;
396 // The check has finished and found an error.
397 cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 if (otp_err != NoError) begin
-22-
402 error_d = MacroEccCorrError;
==>
403 end
MISSING_ELSE
==>
404 end else begin
405 state_d = ErrorSt;
==>
406 error_d = otp_err;
407 // The check has finished and found an error.
408 cnsty_chk_ack_o = 1'b1;
409 end
410 end
MISSING_ELSE
==>
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 if (Info.hw_digest) begin
-23-
418 scrmbl_mtx_req_o = 1'b1;
419 scrmbl_valid_o = 1'b1;
420 cnt_clr = 1'b1;
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 scrmbl_cmd_o = DigestInit;
424 if (Info.secret) begin
-24-
425 scrmbl_mode_o = ChainedMode;
426 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-25-
427 state_d = IntegScrSt;
==>
428 end
MISSING_ELSE
==>
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 scrmbl_mode_o = StandardMode;
433 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-26-
434 state_d = IntegDigSt;
==> (Unreachable)
435 end
MISSING_ELSE
==>
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 state_d = IdleSt;
444 if (mubi8_test_true_strict(dout_locked_q)) begin
-27-
445 dout_locked_d = MuBi8False;
==> (Unreachable)
446 end
MISSING_ELSE
==>
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 scrmbl_mtx_req_o = 1'b1;
456 scrmbl_valid_o = 1'b1;
457 scrmbl_cmd_o = Encrypt;
458 scrmbl_sel_o = Info.key_sel;
459 if (scrmbl_ready_i) begin
-28-
460 state_d = IntegScrWaitSt;
==>
461 end
MISSING_ELSE
==>
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 scrmbl_mtx_req_o = 1'b1;
468 scrmbl_sel_o = Info.key_sel;
469 if (scrmbl_valid_i) begin
-29-
470 state_d = IntegDigSt;
==>
471 end
MISSING_ELSE
==>
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 scrmbl_mtx_req_o = 1'b1;
481 scrmbl_valid_o = 1'b1;
482 if (scrmbl_ready_i) begin
-30-
483 cnt_en = 1'b1;
484 // No need to digest the digest value itself
485 if (cnt == PenultimateScrmblBlock) begin
-31-
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 if (cnt[0]) begin
-32-
490 scrmbl_cmd_o = Digest;
==>
491 state_d = IntegDigFinSt;
492 end else begin
493 state_d = IntegDigPadSt;
==>
494 cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 if (cnt[0]) begin
-33-
499 scrmbl_cmd_o = Digest;
==>
500 end
MISSING_ELSE
==>
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 if (Info.secret) begin
-34-
504 state_d = IntegScrSt;
==>
505 end
MISSING_ELSE
==>
506 end
507 end
MISSING_ELSE
==>
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 scrmbl_mtx_req_o = 1'b1;
517 scrmbl_valid_o = 1'b1;
518 scrmbl_cmd_o = Digest;
519 if (scrmbl_ready_i) begin
-35-
520 state_d = IntegDigFinSt;
==>
521 end
MISSING_ELSE
==>
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 scrmbl_mtx_req_o = 1'b1;
529 scrmbl_valid_o = 1'b1;
530 scrmbl_cmd_o = DigestFinalize;
531 if (scrmbl_ready_i) begin
-36-
532 state_d = IntegDigWaitSt;
==>
533 end
MISSING_ELSE
==>
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 scrmbl_mtx_req_o = 1'b1;
543 data_sel = ScrmblData;
544 if (scrmbl_valid_i) begin
-37-
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 if (digest_o == data_mux || digest_o == '0) begin
-38-
548 state_d = IdleSt;
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 if (mubi8_test_true_strict(dout_locked_q)) begin
-39-
552 dout_locked_d = MuBi8False;
==>
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 integ_chk_ack_o = 1'b1;
==>
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 state_d = ErrorSt;
==>
561 error_d = CheckFailError;
562 // The check has finished and found an error.
563 integ_chk_ack_o = 1'b1;
564 end
565 end
MISSING_ELSE
==>
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 dout_locked_d = MuBi8True;
573 if (error_q == NoError) begin
-40-
574 error_d = FsmStateError;
==>
575 end
MISSING_ELSE
==>
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 cnsty_chk_ack_o = 1'b1;
579 integ_chk_ack_o = 1'b1;
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | -18- | -19- | -20- | -21- | -22- | -23- | -24- | -25- | -26- | -27- | -28- | -29- | -30- | -31- | -32- | -33- | -34- | -35- | -36- | -37- | -38- | -39- | -40- | Status | Tests |
ResetSt |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
ResetSt |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T29,T52,T53 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T41,T54,T64 |
InitWaitSt |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T12,T31 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T33,T55,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T45,T55,T76 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
Covered |
T1,T2,T3 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
Covered |
T6,T12,T31 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
Covered |
T58,T59,T60 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T22,T23,T24 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T8 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T22,T23,T24 |
595 if (ecc_err) begin
-1-
596 state_d = ErrorSt;
597 if (state_q != ErrorSt) begin
-2-
598 error_d = CheckFailError;
==>
599 end
MISSING_ELSE
==>
600 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Not Covered |
|
1 |
0 |
Not Covered |
|
0 |
- |
Covered |
T1,T2,T3 |
602 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
-1-
603 state_d = ErrorSt;
604 fsm_err_o = 1'b1;
605 if (state_q != ErrorSt) begin
-2-
606 error_d = FsmStateError;
==>
607 end
MISSING_ELSE
==>
608 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Covered |
T2,T4,T8 |
1 |
0 |
Covered |
T2,T4,T8 |
0 |
- |
Covered |
T1,T2,T3 |
750 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
753 if (!rst_ni) begin
-1-
754 error_q <= NoError;
==>
755 // data output is locked by default
756 dout_locked_q <= MuBi8True;
757 end else begin
758 error_q <= error_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Branch Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=1720,StateWidth=12 + Info=-1,CntWidth=1,DigestOffset=1736,StateWidth=12 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
70 |
56 |
80.00 |
TERNARY |
636 |
2 |
2 |
100.00 |
TERNARY |
652 |
2 |
2 |
100.00 |
TERNARY |
678 |
2 |
2 |
100.00 |
TERNARY |
709 |
2 |
2 |
100.00 |
CASE |
240 |
52 |
40 |
76.92 |
IF |
595 |
3 |
1 |
33.33 |
IF |
602 |
3 |
3 |
100.00 |
IF |
750 |
2 |
2 |
100.00 |
IF |
753 |
2 |
2 |
100.00 |
636 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T3,T4,T5 |
0 |
Covered |
T1,T2,T3 |
652 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
678 assign data_o = (init_done_o) ? data : DataDefault;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
709 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T3,T5,T6 |
0 |
Covered |
T1,T2,T3 |
240 unique case (state_q)
-1-
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 if (init_req_i) begin
-2-
246 state_d = InitSt;
==>
247 end
MISSING_ELSE
==>
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 otp_req_o = 1'b1;
255 if (otp_gnt_i) begin
-3-
256 state_d = InitWaitSt;
==>
257 end
MISSING_ELSE
==>
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 if (otp_rvalid_i) begin
-4-
266 buffer_reg_en = 1'b1;
267 if (otp_err inside {NoError, MacroEccCorrError}) begin
-5-
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 if (cnt == LastScrmblBlock) begin
-6-
272 state_d = IntegDigClrSt;
==>
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 end else if (Info.secret) begin
-7-
276 state_d = InitDescrSt;
==> (Unreachable)
277 end else begin
278 state_d = InitSt;
==>
279 cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 if (otp_err != NoError) begin
-8-
283 error_d = MacroEccCorrError;
==>
284 end
MISSING_ELSE
==>
285 end else begin
286 state_d = ErrorSt;
==>
287 error_d = otp_err;
288 end
289 end
MISSING_ELSE
==>
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 scrmbl_mtx_req_o = 1'b1;
299 scrmbl_valid_o = 1'b1;
300 scrmbl_cmd_o = Decrypt;
301 scrmbl_sel_o = Info.key_sel;
302 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-9-
303 state_d = InitDescrWaitSt;
==>
304 end
MISSING_ELSE
==>
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 scrmbl_mtx_req_o = 1'b1;
312 scrmbl_sel_o = Info.key_sel;
313 data_sel = ScrmblData;
314 if (scrmbl_valid_i) begin
-10-
315 state_d = InitSt;
==>
316 buffer_reg_en = 1'b1;
317 cnt_en = 1'b1;
318 end
MISSING_ELSE
==>
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 if (integ_chk_req_i) begin
-11-
325 if (Info.hw_digest) begin
-12-
326 state_d = IntegDigClrSt;
==>
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 integ_chk_ack_o = 1'b1;
==> (Unreachable)
332 end
333 end else if (cnsty_chk_req_i) begin
-13-
334 state_d = CnstyReadSt;
==>
335 cnt_clr = 1'b1;
336 end
MISSING_ELSE
==>
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 otp_req_o = 1'b1;
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 if (Info.hw_digest) begin
-14-
349 base_sel = DigOffset;
==>
350 end
MISSING_ELSE
==>
351 if (otp_gnt_i) begin
-15-
352 state_d = CnstyReadWaitSt;
==>
353 end
MISSING_ELSE
==>
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 if (otp_rvalid_i) begin
-16-
363 if (otp_err inside {NoError, MacroEccCorrError}) begin
-17-
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 if (Info.hw_digest) begin
-18-
367 // Note that we ignore this check if the digest is still blank.
368 if (digest_o == data_mux || digest_o == '0) begin
-19-
369 state_d = IdleSt;
==>
370 cnsty_chk_ack_o = 1'b1;
371 // Error out and lock the partition if this check fails.
372 end else begin
373 state_d = ErrorSt;
==>
374 error_d = CheckFailError;
375 // The check has finished and found an error.
376 cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 if (scrmbl_data_o == data_mux ||
-20-
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 if (cnt == LastScrmblBlock) begin
-21-
386 state_d = IdleSt;
==> (Unreachable)
387 cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 state_d = CnstyReadSt;
==> (Unreachable)
391 cnt_en = 1'b1;
392 end
393 end else begin
394 state_d = ErrorSt;
==> (Unreachable)
395 error_d = CheckFailError;
396 // The check has finished and found an error.
397 cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 if (otp_err != NoError) begin
-22-
402 error_d = MacroEccCorrError;
==>
403 end
MISSING_ELSE
==>
404 end else begin
405 state_d = ErrorSt;
==>
406 error_d = otp_err;
407 // The check has finished and found an error.
408 cnsty_chk_ack_o = 1'b1;
409 end
410 end
MISSING_ELSE
==>
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 if (Info.hw_digest) begin
-23-
418 scrmbl_mtx_req_o = 1'b1;
419 scrmbl_valid_o = 1'b1;
420 cnt_clr = 1'b1;
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 scrmbl_cmd_o = DigestInit;
424 if (Info.secret) begin
-24-
425 scrmbl_mode_o = ChainedMode;
426 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-25-
427 state_d = IntegScrSt;
==> (Unreachable)
428 end
MISSING_ELSE
==>
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 scrmbl_mode_o = StandardMode;
433 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-26-
434 state_d = IntegDigSt;
==>
435 end
MISSING_ELSE
==>
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 state_d = IdleSt;
444 if (mubi8_test_true_strict(dout_locked_q)) begin
-27-
445 dout_locked_d = MuBi8False;
==> (Unreachable)
446 end
MISSING_ELSE
==>
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 scrmbl_mtx_req_o = 1'b1;
456 scrmbl_valid_o = 1'b1;
457 scrmbl_cmd_o = Encrypt;
458 scrmbl_sel_o = Info.key_sel;
459 if (scrmbl_ready_i) begin
-28-
460 state_d = IntegScrWaitSt;
==>
461 end
MISSING_ELSE
==>
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 scrmbl_mtx_req_o = 1'b1;
468 scrmbl_sel_o = Info.key_sel;
469 if (scrmbl_valid_i) begin
-29-
470 state_d = IntegDigSt;
==>
471 end
MISSING_ELSE
==>
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 scrmbl_mtx_req_o = 1'b1;
481 scrmbl_valid_o = 1'b1;
482 if (scrmbl_ready_i) begin
-30-
483 cnt_en = 1'b1;
484 // No need to digest the digest value itself
485 if (cnt == PenultimateScrmblBlock) begin
-31-
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 if (cnt[0]) begin
-32-
490 scrmbl_cmd_o = Digest;
==>
491 state_d = IntegDigFinSt;
492 end else begin
493 state_d = IntegDigPadSt;
==>
494 cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 if (cnt[0]) begin
-33-
499 scrmbl_cmd_o = Digest;
==>
500 end
MISSING_ELSE
==>
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 if (Info.secret) begin
-34-
504 state_d = IntegScrSt;
==> (Unreachable)
505 end
MISSING_ELSE
==>
506 end
507 end
MISSING_ELSE
==>
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 scrmbl_mtx_req_o = 1'b1;
517 scrmbl_valid_o = 1'b1;
518 scrmbl_cmd_o = Digest;
519 if (scrmbl_ready_i) begin
-35-
520 state_d = IntegDigFinSt;
==>
521 end
MISSING_ELSE
==>
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 scrmbl_mtx_req_o = 1'b1;
529 scrmbl_valid_o = 1'b1;
530 scrmbl_cmd_o = DigestFinalize;
531 if (scrmbl_ready_i) begin
-36-
532 state_d = IntegDigWaitSt;
==>
533 end
MISSING_ELSE
==>
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 scrmbl_mtx_req_o = 1'b1;
543 data_sel = ScrmblData;
544 if (scrmbl_valid_i) begin
-37-
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 if (digest_o == data_mux || digest_o == '0) begin
-38-
548 state_d = IdleSt;
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 if (mubi8_test_true_strict(dout_locked_q)) begin
-39-
552 dout_locked_d = MuBi8False;
==>
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 integ_chk_ack_o = 1'b1;
==>
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 state_d = ErrorSt;
==>
561 error_d = CheckFailError;
562 // The check has finished and found an error.
563 integ_chk_ack_o = 1'b1;
564 end
565 end
MISSING_ELSE
==>
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 dout_locked_d = MuBi8True;
573 if (error_q == NoError) begin
-40-
574 error_d = FsmStateError;
==>
575 end
MISSING_ELSE
==>
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 cnsty_chk_ack_o = 1'b1;
579 integ_chk_ack_o = 1'b1;
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | -18- | -19- | -20- | -21- | -22- | -23- | -24- | -25- | -26- | -27- | -28- | -29- | -30- | -31- | -32- | -33- | -34- | -35- | -36- | -37- | -38- | -39- | -40- | Status | Tests |
ResetSt |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
ResetSt |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
InitWaitSt |
- |
- |
1 |
1 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T41,T25,T26 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T28,T29,T30 |
InitWaitSt |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T12,T31 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T32 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T45,T33,T34 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T33,T47,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
Covered |
T1,T2,T3 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
Covered |
T6,T12,T31 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
Covered |
T49,T50,T51 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T22,T23,T24 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T8 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T22,T23,T24 |
595 if (ecc_err) begin
-1-
596 state_d = ErrorSt;
597 if (state_q != ErrorSt) begin
-2-
598 error_d = CheckFailError;
==>
599 end
MISSING_ELSE
==>
600 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Not Covered |
|
1 |
0 |
Not Covered |
|
0 |
- |
Covered |
T1,T2,T3 |
602 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
-1-
603 state_d = ErrorSt;
604 fsm_err_o = 1'b1;
605 if (state_q != ErrorSt) begin
-2-
606 error_d = FsmStateError;
==>
607 end
MISSING_ELSE
==>
608 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Covered |
T2,T4,T8 |
1 |
0 |
Covered |
T2,T4,T8 |
0 |
- |
Covered |
T1,T2,T3 |
750 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
753 if (!rst_ni) begin
-1-
754 error_q <= NoError;
==>
755 // data output is locked by default
756 dout_locked_q <= MuBi8True;
757 end else begin
758 error_q <= error_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Branch Coverage for Module :
otp_ctrl_part_buf ( parameter Info=-1,CntWidth=4,DigestOffset=2040,StateWidth=12 )
Branch Coverage for Module self-instances :
| Line No. | Total | Covered | Percent |
Branches |
|
56 |
39 |
69.64 |
TERNARY |
636 |
2 |
1 |
50.00 |
TERNARY |
652 |
2 |
1 |
50.00 |
TERNARY |
678 |
2 |
2 |
100.00 |
CASE |
240 |
40 |
27 |
67.50 |
IF |
595 |
3 |
1 |
33.33 |
IF |
602 |
3 |
3 |
100.00 |
IF |
750 |
2 |
2 |
100.00 |
IF |
753 |
2 |
2 |
100.00 |
636 assign addr_base = (base_sel == DigOffset) ? DigestOffset : Info.offset;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Not Covered |
|
0 |
Covered |
T1,T2,T3 |
652 assign data_mux = (data_sel == ScrmblData) ? scrmbl_data_i : otp_rdata_i;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Not Covered |
|
0 |
Covered |
T1,T2,T3 |
678 assign data_o = (init_done_o) ? data : DataDefault;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
240 unique case (state_q)
-1-
241 ///////////////////////////////////////////////////////////////////
242 // State right after reset. Wait here until we get a an
243 // initialization request.
244 ResetSt: begin
245 if (init_req_i) begin
-2-
246 state_d = InitSt;
==>
247 end
MISSING_ELSE
==>
248 end
249 ///////////////////////////////////////////////////////////////////
250 // Initialization reads out the digest only in unbuffered
251 // partitions. Wait here until the OTP request has been granted.
252 // And then wait until the OTP word comes back.
253 InitSt: begin
254 otp_req_o = 1'b1;
255 if (otp_gnt_i) begin
-3-
256 state_d = InitWaitSt;
==>
257 end
MISSING_ELSE
==>
258 end
259 ///////////////////////////////////////////////////////////////////
260 // Wait for OTP response and write to buffer register, then go to
261 // descrambling state. In case an OTP transaction fails, latch the
262 // OTP error code and jump to a
263 // terminal error state.
264 InitWaitSt: begin
265 if (otp_rvalid_i) begin
-4-
266 buffer_reg_en = 1'b1;
267 if (otp_err inside {NoError, MacroEccCorrError}) begin
-5-
268 // Once we've read and descrambled the whole partition, we can go to integrity
269 // verification. Note that the last block is the digest value, which does not
270 // have to be descrambled.
271 if (cnt == LastScrmblBlock) begin
-6-
272 state_d = IntegDigClrSt;
==>
273 // Only need to descramble if this is a scrambled partition.
274 // Otherwise, we can just go back to InitSt and read the next block.
275 end else if (Info.secret) begin
-7-
276 state_d = InitDescrSt;
==> (Unreachable)
277 end else begin
278 state_d = InitSt;
==>
279 cnt_en = 1'b1;
280 end
281 // At this point the only error that we could have gotten are correctable ECC errors.
282 if (otp_err != NoError) begin
-8-
283 error_d = MacroEccCorrError;
==>
284 end
MISSING_ELSE
==>
285 end else begin
286 state_d = ErrorSt;
==>
287 error_d = otp_err;
288 end
289 end
MISSING_ELSE
==>
290 end
291 ///////////////////////////////////////////////////////////////////
292 // Descrambling state. This first acquires the scrambling
293 // datapath mutex. Note that once the mutex is acquired, we have
294 // exclusive access to the scrambling datapath until we release
295 // the mutex by deasserting scrmbl_mtx_req_o.
296 // SEC_CM: SECRET.MEM.SCRAMBLE
297 InitDescrSt: begin
298 scrmbl_mtx_req_o = 1'b1;
299 scrmbl_valid_o = 1'b1;
300 scrmbl_cmd_o = Decrypt;
301 scrmbl_sel_o = Info.key_sel;
302 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-9-
303 state_d = InitDescrWaitSt;
==> (Unreachable)
304 end
MISSING_ELSE
==>
305 end
306 ///////////////////////////////////////////////////////////////////
307 // Wait for the descrambled data to return. Note that we release
308 // the mutex lock upon leaving this state.
309 // SEC_CM: SECRET.MEM.SCRAMBLE
310 InitDescrWaitSt: begin
311 scrmbl_mtx_req_o = 1'b1;
312 scrmbl_sel_o = Info.key_sel;
313 data_sel = ScrmblData;
314 if (scrmbl_valid_i) begin
-10-
315 state_d = InitSt;
==> (Unreachable)
316 buffer_reg_en = 1'b1;
317 cnt_en = 1'b1;
318 end
MISSING_ELSE
==>
319 end
320 ///////////////////////////////////////////////////////////////////
321 // Idle state. We basically wait for integrity and consistency check
322 // triggers in this state.
323 IdleSt: begin
324 if (integ_chk_req_i) begin
-11-
325 if (Info.hw_digest) begin
-12-
326 state_d = IntegDigClrSt;
==> (Unreachable)
327 // In case there is nothing to check we can just
328 // acknowledge the request right away, without going to the
329 // integrity check.
330 end else begin
331 integ_chk_ack_o = 1'b1;
==>
332 end
333 end else if (cnsty_chk_req_i) begin
-13-
334 state_d = CnstyReadSt;
==>
335 cnt_clr = 1'b1;
336 end
MISSING_ELSE
==>
337 end
338 ///////////////////////////////////////////////////////////////////
339 // Read the digest. Wait here until the OTP request has been granted.
340 // And then wait until the OTP word comes back.
341 // SEC_CM: PART.DATA_REG.BKGN_CHK
342 CnstyReadSt: begin
343 otp_req_o = 1'b1;
344 // In case this partition has a hardware digest, we only have to read
345 // and compare the digest value. In that case we select the digest offset here.
346 // Otherwise we have to read and compare the whole partition, in which case we
347 // select the partition offset, which is the default assignment of base_sel.
348 if (Info.hw_digest) begin
-14-
349 base_sel = DigOffset;
==> (Unreachable)
350 end
MISSING_ELSE
==>
351 if (otp_gnt_i) begin
-15-
352 state_d = CnstyReadWaitSt;
==>
353 end
MISSING_ELSE
==>
354 end
355 ///////////////////////////////////////////////////////////////////
356 // Wait for OTP response and compare the digest. In case there is
357 // a mismatch, lock down the partition and go into the terminal error
358 // state. In case an OTP transaction fails, latch the OTP error code
359 // and jump to a terminal error state.
360 // SEC_CM: PART.DATA_REG.BKGN_CHK
361 CnstyReadWaitSt: begin
362 if (otp_rvalid_i) begin
-16-
363 if (otp_err inside {NoError, MacroEccCorrError}) begin
-17-
364 // Check whether we need to compare the digest or the full partition
365 // contents here.
366 if (Info.hw_digest) begin
-18-
367 // Note that we ignore this check if the digest is still blank.
368 if (digest_o == data_mux || digest_o == '0) begin
-19-
369 state_d = IdleSt;
==> (Unreachable)
370 cnsty_chk_ack_o = 1'b1;
371 // Error out and lock the partition if this check fails.
372 end else begin
373 state_d = ErrorSt;
==> (Unreachable)
374 error_d = CheckFailError;
375 // The check has finished and found an error.
376 cnsty_chk_ack_o = 1'b1;
377 end
378 end else begin
379 // Check whether the read data corresponds with the data buffered in regs.
380 // Note that this particular check can be bypassed in case a transition is ongoing.
381 if (scrmbl_data_o == data_mux ||
-20-
382 lc_ctrl_pkg::lc_tx_test_true_strict(check_byp_en_i)) begin
383 // Can go back to idle and acknowledge the
384 // request if this is the last block.
385 if (cnt == LastScrmblBlock) begin
-21-
386 state_d = IdleSt;
==>
387 cnsty_chk_ack_o = 1'b1;
388 // Need to go back and read out more blocks.
389 end else begin
390 state_d = CnstyReadSt;
==>
391 cnt_en = 1'b1;
392 end
393 end else begin
394 state_d = ErrorSt;
==>
395 error_d = CheckFailError;
396 // The check has finished and found an error.
397 cnsty_chk_ack_o = 1'b1;
398 end
399 end
400 // At this point the only error that we could have gotten are correctable ECC errors.
401 if (otp_err != NoError) begin
-22-
402 error_d = MacroEccCorrError;
==>
403 end
MISSING_ELSE
==>
404 end else begin
405 state_d = ErrorSt;
==>
406 error_d = otp_err;
407 // The check has finished and found an error.
408 cnsty_chk_ack_o = 1'b1;
409 end
410 end
MISSING_ELSE
==>
411 end
412 ///////////////////////////////////////////////////////////////////
413 // First, acquire the mutex for the digest and clear the digest state.
414 // SEC_CM: PART.DATA_REG.BKGN_CHK
415 IntegDigClrSt: begin
416 // Check whether this partition requires checking at all.
417 if (Info.hw_digest) begin
-23-
418 scrmbl_mtx_req_o = 1'b1;
419 scrmbl_valid_o = 1'b1;
420 cnt_clr = 1'b1;
421 // Need to reset the digest state and set it to chained
422 // mode if this partition is scrambled.
423 scrmbl_cmd_o = DigestInit;
424 if (Info.secret) begin
-24-
425 scrmbl_mode_o = ChainedMode;
426 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-25-
427 state_d = IntegScrSt;
==> (Unreachable)
428 end
MISSING_ELSE
==>
429 // If this partition is not scrambled, we can just directly
430 // jump to the digest state.
431 end else begin
432 scrmbl_mode_o = StandardMode;
433 if (scrmbl_mtx_gnt_i && scrmbl_ready_i) begin
-26-
434 state_d = IntegDigSt;
==> (Unreachable)
435 end
MISSING_ELSE
==>
436 end
437 // Otherwise, if this partition is not digest protected,
438 // we can just go to idle, since there is nothing to check.
439 // Note that we do not come back to this state in case there is no
440 // digest, and hence it is safe to unlock the buffer regs at this point.
441 // This is the only way the buffer regs can get unlocked.
442 end else begin
443 state_d = IdleSt;
444 if (mubi8_test_true_strict(dout_locked_q)) begin
-27-
445 dout_locked_d = MuBi8False;
==>
446 end
MISSING_ELSE
==>
447 end
448 end
449 ///////////////////////////////////////////////////////////////////
450 // Scramble buffered data (which is held in plaintext form).
451 // This moves the previous scrambling result into the shadow reg
452 // for later use.
453 // SEC_CM: PART.DATA_REG.BKGN_CHK
454 IntegScrSt: begin
455 scrmbl_mtx_req_o = 1'b1;
456 scrmbl_valid_o = 1'b1;
457 scrmbl_cmd_o = Encrypt;
458 scrmbl_sel_o = Info.key_sel;
459 if (scrmbl_ready_i) begin
-28-
460 state_d = IntegScrWaitSt;
==> (Unreachable)
461 end
MISSING_ELSE
==>
462 end
463 ///////////////////////////////////////////////////////////////////
464 // Wait for the scrambled data to return.
465 // SEC_CM: PART.DATA_REG.BKGN_CHK
466 IntegScrWaitSt: begin
467 scrmbl_mtx_req_o = 1'b1;
468 scrmbl_sel_o = Info.key_sel;
469 if (scrmbl_valid_i) begin
-29-
470 state_d = IntegDigSt;
==> (Unreachable)
471 end
MISSING_ELSE
==>
472 end
473 ///////////////////////////////////////////////////////////////////
474 // Push the word read into the scrambling datapath. The last
475 // block is repeated in case the number blocks in this partition
476 // is odd.
477 // SEC_CM: PART.MEM.DIGEST
478 // SEC_CM: PART.DATA_REG.BKGN_CHK
479 IntegDigSt: begin
480 scrmbl_mtx_req_o = 1'b1;
481 scrmbl_valid_o = 1'b1;
482 if (scrmbl_ready_i) begin
-30-
483 cnt_en = 1'b1;
484 // No need to digest the digest value itself
485 if (cnt == PenultimateScrmblBlock) begin
-31-
486 // Note that the digest operates on 128bit blocks since the data is fed in via the
487 // PRESENT key input. Therefore, we only trigger a digest update on every second
488 // 64bit block that is pushed into the scrambling datapath.
489 if (cnt[0]) begin
-32-
490 scrmbl_cmd_o = Digest;
==> (Unreachable)
491 state_d = IntegDigFinSt;
492 end else begin
493 state_d = IntegDigPadSt;
==> (Unreachable)
494 cnt_en = 1'b0;
495 end
496 end else begin
497 // Trigger digest round in case this is the second block in a row.
498 if (cnt[0]) begin
-33-
499 scrmbl_cmd_o = Digest;
==> (Unreachable)
500 end
MISSING_ELSE
==>
501 // Go back and scramble the next data block if this is
502 // a scrambled partition. Otherwise just stay here.
503 if (Info.secret) begin
-34-
504 state_d = IntegScrSt;
==> (Unreachable)
505 end
MISSING_ELSE
==>
506 end
507 end
MISSING_ELSE
==>
508 end
509 ///////////////////////////////////////////////////////////////////
510 // Padding state. When we get here, we've copied the last encryption
511 // result into the shadow register such that we've effectively
512 // repeated the last block twice in order to pad the data to 128bit.
513 // SEC_CM: PART.MEM.DIGEST
514 // SEC_CM: PART.DATA_REG.BKGN_CHK
515 IntegDigPadSt: begin
516 scrmbl_mtx_req_o = 1'b1;
517 scrmbl_valid_o = 1'b1;
518 scrmbl_cmd_o = Digest;
519 if (scrmbl_ready_i) begin
-35-
520 state_d = IntegDigFinSt;
==> (Unreachable)
521 end
MISSING_ELSE
==>
522 end
523 ///////////////////////////////////////////////////////////////////
524 // Trigger digest finalization and go wait for the result.
525 // SEC_CM: PART.MEM.DIGEST
526 // SEC_CM: PART.DATA_REG.BKGN_CHK
527 IntegDigFinSt: begin
528 scrmbl_mtx_req_o = 1'b1;
529 scrmbl_valid_o = 1'b1;
530 scrmbl_cmd_o = DigestFinalize;
531 if (scrmbl_ready_i) begin
-36-
532 state_d = IntegDigWaitSt;
==> (Unreachable)
533 end
MISSING_ELSE
==>
534 end
535 ///////////////////////////////////////////////////////////////////
536 // Wait for the digest to return, and double check whether the digest
537 // matches. If yes, unlock the partition. Otherwise, go into the terminal
538 // error state, where the partition will be locked down.
539 // SEC_CM: PART.MEM.DIGEST
540 // SEC_CM: PART.DATA_REG.BKGN_CHK
541 IntegDigWaitSt: begin
542 scrmbl_mtx_req_o = 1'b1;
543 data_sel = ScrmblData;
544 if (scrmbl_valid_i) begin
-37-
545 // This is the only way the buffer regs can get unlocked.
546 // Note that we ignore this check if the digest is still blank.
547 if (digest_o == data_mux || digest_o == '0) begin
-38-
548 state_d = IdleSt;
549 // If the partition is still locked, this is the first integrity check after
550 // initialization. This is the only way the buffer regs can get unlocked.
551 if (mubi8_test_true_strict(dout_locked_q)) begin
-39-
552 dout_locked_d = MuBi8False;
==> (Unreachable)
553 // Otherwise, this integrity check has requested by the LFSR timer, and we have
554 // to acknowledge its completion.
555 end else begin
556 integ_chk_ack_o = 1'b1;
==> (Unreachable)
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 state_d = ErrorSt;
==> (Unreachable)
561 error_d = CheckFailError;
562 // The check has finished and found an error.
563 integ_chk_ack_o = 1'b1;
564 end
565 end
MISSING_ELSE
==>
566 end
567 ///////////////////////////////////////////////////////////////////
568 // Terminal Error State. This locks access to the partition.
569 // Make sure the partition signals an error state if no error
570 // code has been latched so far, and lock the buffer regs down.
571 ErrorSt: begin
572 dout_locked_d = MuBi8True;
573 if (error_q == NoError) begin
-40-
574 error_d = FsmStateError;
==>
575 end
MISSING_ELSE
==>
576 // If we are in error state, we cannot execute the checks anymore.
577 // Hence the acknowledgements are returned immediately.
578 cnsty_chk_ack_o = 1'b1;
579 integ_chk_ack_o = 1'b1;
580 end
581 ///////////////////////////////////////////////////////////////////
582 // We should never get here. If we do (e.g. via a malicious
583 // glitch), error out immediately.
584 default: begin
585 state_d = ErrorSt;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | -18- | -19- | -20- | -21- | -22- | -23- | -24- | -25- | -26- | -27- | -28- | -29- | -30- | -31- | -32- | -33- | -34- | -35- | -36- | -37- | -38- | -39- | -40- | Status | Tests |
ResetSt |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
ResetSt |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitSt |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
InitWaitSt |
- |
- |
1 |
1 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T26,T72,T61 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T2,T25,T80 |
InitWaitSt |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
InitDescrSt |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
InitDescrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T12,T31 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T26,T81,T53 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T82,T55,T56 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T82,T83,T84 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T3,T4,T5 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
IntegDigClrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegScrSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegScrWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
Unreachable |
|
IntegDigPadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
Not Covered |
|
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
Unreachable |
|
IntegDigFinSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
Not Covered |
|
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
- |
Unreachable |
|
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
Unreachable |
|
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
Unreachable |
|
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Not Covered |
|
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T22,T23,T24 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T8 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T22,T23,T24 |
595 if (ecc_err) begin
-1-
596 state_d = ErrorSt;
597 if (state_q != ErrorSt) begin
-2-
598 error_d = CheckFailError;
==>
599 end
MISSING_ELSE
==>
600 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Not Covered |
|
1 |
0 |
Not Covered |
|
0 |
- |
Covered |
T1,T2,T3 |
602 if (lc_ctrl_pkg::lc_tx_test_true_loose(escalate_en_i) || cnt_err) begin
-1-
603 state_d = ErrorSt;
604 fsm_err_o = 1'b1;
605 if (state_q != ErrorSt) begin
-2-
606 error_d = FsmStateError;
==>
607 end
MISSING_ELSE
==>
608 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
1 |
Covered |
T4,T8,T85 |
1 |
0 |
Covered |
T2,T4,T8 |
0 |
- |
Covered |
T1,T2,T3 |
750 `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, ResetSt)
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
753 if (!rst_ni) begin
-1-
754 error_q <= NoError;
==>
755 // data output is locked by default
756 dout_locked_q <= MuBi8True;
757 end else begin
758 error_q <= error_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T1,T2,T3 |
Assert Coverage for Module :
otp_ctrl_part_buf
Assertion Details
AccessKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
BypassEnable0_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
256747746 |
0 |
0 |
T1 |
13935 |
13725 |
0 |
0 |
T2 |
37089 |
36279 |
0 |
0 |
T3 |
73071 |
72222 |
0 |
0 |
T4 |
72366 |
71541 |
0 |
0 |
T5 |
47481 |
46707 |
0 |
0 |
T6 |
144579 |
141567 |
0 |
0 |
T7 |
61374 |
61140 |
0 |
0 |
T8 |
92508 |
91812 |
0 |
0 |
T11 |
15273 |
15099 |
0 |
0 |
T12 |
43986 |
43161 |
0 |
0 |
BypassEnable1_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
427912910 |
0 |
0 |
T1 |
23225 |
22875 |
0 |
0 |
T2 |
61815 |
60465 |
0 |
0 |
T3 |
121785 |
120370 |
0 |
0 |
T4 |
120610 |
119235 |
0 |
0 |
T5 |
79135 |
77845 |
0 |
0 |
T6 |
240965 |
235945 |
0 |
0 |
T7 |
102290 |
101900 |
0 |
0 |
T8 |
154180 |
153020 |
0 |
0 |
T11 |
25455 |
25165 |
0 |
0 |
T12 |
73310 |
71935 |
0 |
0 |
CnstyChkAckKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
DataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
DigestKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
DigestOffsetMustBeRepresentable_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6786 |
6786 |
0 |
0 |
T1 |
6 |
6 |
0 |
0 |
T2 |
6 |
6 |
0 |
0 |
T3 |
6 |
6 |
0 |
0 |
T4 |
6 |
6 |
0 |
0 |
T5 |
6 |
6 |
0 |
0 |
T6 |
6 |
6 |
0 |
0 |
T7 |
6 |
6 |
0 |
0 |
T8 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
EccErrorState_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
0 |
0 |
0 |
ErrorKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
InitDoneKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
InitReadLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
157509570 |
0 |
0 |
T1 |
27870 |
7572 |
0 |
0 |
T2 |
74178 |
32892 |
0 |
0 |
T3 |
146142 |
22277 |
0 |
0 |
T4 |
144732 |
124698 |
0 |
0 |
T5 |
94962 |
27716 |
0 |
0 |
T6 |
289158 |
81694 |
0 |
0 |
T7 |
122748 |
7512 |
0 |
0 |
T8 |
185016 |
115809 |
0 |
0 |
T11 |
30546 |
7830 |
0 |
0 |
T12 |
87972 |
22831 |
0 |
0 |
InitWriteLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
157509570 |
0 |
0 |
T1 |
27870 |
7572 |
0 |
0 |
T2 |
74178 |
32892 |
0 |
0 |
T3 |
146142 |
22277 |
0 |
0 |
T4 |
144732 |
124698 |
0 |
0 |
T5 |
94962 |
27716 |
0 |
0 |
T6 |
289158 |
81694 |
0 |
0 |
T7 |
122748 |
7512 |
0 |
0 |
T8 |
185016 |
115809 |
0 |
0 |
T11 |
30546 |
7830 |
0 |
0 |
T12 |
87972 |
22831 |
0 |
0 |
IntegChkAckKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
OffsetMustBeBlockAligned_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6786 |
6786 |
0 |
0 |
T1 |
6 |
6 |
0 |
0 |
T2 |
6 |
6 |
0 |
0 |
T3 |
6 |
6 |
0 |
0 |
T4 |
6 |
6 |
0 |
0 |
T5 |
6 |
6 |
0 |
0 |
T6 |
6 |
6 |
0 |
0 |
T7 |
6 |
6 |
0 |
0 |
T8 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
OtpAddrKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
OtpCmdKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
OtpErrorState_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
86402046 |
22 |
0 |
0 |
T2 |
12363 |
1 |
0 |
0 |
T3 |
24357 |
0 |
0 |
0 |
T4 |
24122 |
0 |
0 |
0 |
T5 |
15827 |
0 |
0 |
0 |
T6 |
48193 |
0 |
0 |
0 |
T7 |
20458 |
0 |
0 |
0 |
T8 |
30836 |
0 |
0 |
0 |
T11 |
5091 |
0 |
0 |
0 |
T12 |
14662 |
0 |
0 |
0 |
T25 |
0 |
1 |
0 |
0 |
T34 |
0 |
1 |
0 |
0 |
T75 |
0 |
1 |
0 |
0 |
T80 |
0 |
1 |
0 |
0 |
T82 |
0 |
1 |
0 |
0 |
T83 |
0 |
1 |
0 |
0 |
T84 |
0 |
1 |
0 |
0 |
T85 |
12853 |
0 |
0 |
0 |
T103 |
0 |
1 |
0 |
0 |
T104 |
0 |
1 |
0 |
0 |
OtpPartBufSize_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6786 |
6786 |
0 |
0 |
T1 |
6 |
6 |
0 |
0 |
T2 |
6 |
6 |
0 |
0 |
T3 |
6 |
6 |
0 |
0 |
T4 |
6 |
6 |
0 |
0 |
T5 |
6 |
6 |
0 |
0 |
T6 |
6 |
6 |
0 |
0 |
T7 |
6 |
6 |
0 |
0 |
T8 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
OtpReqKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
OtpSizeKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
OtpWdataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ReadLockImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
427912910 |
0 |
0 |
T1 |
23225 |
22875 |
0 |
0 |
T2 |
61815 |
60465 |
0 |
0 |
T3 |
121785 |
120370 |
0 |
0 |
T4 |
120610 |
119235 |
0 |
0 |
T5 |
79135 |
77845 |
0 |
0 |
T6 |
240965 |
235945 |
0 |
0 |
T7 |
102290 |
101900 |
0 |
0 |
T8 |
154180 |
153020 |
0 |
0 |
T11 |
25455 |
25165 |
0 |
0 |
T12 |
73310 |
71935 |
0 |
0 |
ReadLockPropagation_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
120686528 |
0 |
0 |
T1 |
9290 |
4575 |
0 |
0 |
T2 |
24726 |
12093 |
0 |
0 |
T3 |
48714 |
24074 |
0 |
0 |
T4 |
48244 |
23847 |
0 |
0 |
T5 |
31654 |
15569 |
0 |
0 |
T6 |
192772 |
51773 |
0 |
0 |
T7 |
40916 |
20380 |
0 |
0 |
T8 |
123344 |
30604 |
0 |
0 |
T11 |
10182 |
5033 |
0 |
0 |
T12 |
58648 |
14387 |
0 |
0 |
T16 |
191338 |
0 |
0 |
0 |
T18 |
0 |
2180 |
0 |
0 |
T19 |
0 |
4925 |
0 |
0 |
T31 |
121304 |
14199 |
0 |
0 |
T33 |
0 |
43762 |
0 |
0 |
T45 |
0 |
3589 |
0 |
0 |
T85 |
25706 |
0 |
0 |
0 |
T87 |
0 |
2356 |
0 |
0 |
T89 |
29226 |
0 |
0 |
0 |
T90 |
30184 |
0 |
0 |
0 |
T99 |
0 |
9335 |
0 |
0 |
T105 |
0 |
3557 |
0 |
0 |
T106 |
0 |
2569 |
0 |
0 |
T107 |
0 |
1232 |
0 |
0 |
T108 |
0 |
568 |
0 |
0 |
T109 |
141880 |
0 |
0 |
0 |
T110 |
27936 |
0 |
0 |
0 |
ScrambledImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
256747746 |
0 |
0 |
T1 |
13935 |
13725 |
0 |
0 |
T2 |
37089 |
36279 |
0 |
0 |
T3 |
73071 |
72222 |
0 |
0 |
T4 |
72366 |
71541 |
0 |
0 |
T5 |
47481 |
46707 |
0 |
0 |
T6 |
144579 |
141567 |
0 |
0 |
T7 |
61374 |
61140 |
0 |
0 |
T8 |
92508 |
91812 |
0 |
0 |
T11 |
15273 |
15099 |
0 |
0 |
T12 |
43986 |
43161 |
0 |
0 |
ScrmblCmdKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ScrmblDataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
514582890 |
509752892 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ScrmblModeKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ScrmblMtxReqKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ScrmblSelKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
ScrmblValidKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |
SizeMustBeBlockAligned_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6786 |
6786 |
0 |
0 |
T1 |
6 |
6 |
0 |
0 |
T2 |
6 |
6 |
0 |
0 |
T3 |
6 |
6 |
0 |
0 |
T4 |
6 |
6 |
0 |
0 |
T5 |
6 |
6 |
0 |
0 |
T6 |
6 |
6 |
0 |
0 |
T7 |
6 |
6 |
0 |
0 |
T8 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
WriteLockImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
256747746 |
0 |
0 |
T1 |
13935 |
13725 |
0 |
0 |
T2 |
37089 |
36279 |
0 |
0 |
T3 |
73071 |
72222 |
0 |
0 |
T4 |
72366 |
71541 |
0 |
0 |
T5 |
47481 |
46707 |
0 |
0 |
T6 |
144579 |
141567 |
0 |
0 |
T7 |
61374 |
61140 |
0 |
0 |
T8 |
92508 |
91812 |
0 |
0 |
T11 |
15273 |
15099 |
0 |
0 |
T12 |
43986 |
43161 |
0 |
0 |
WriteLockPropagation_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
124666018 |
0 |
0 |
T1 |
4645 |
4575 |
0 |
0 |
T2 |
12363 |
12093 |
0 |
0 |
T3 |
24357 |
24074 |
0 |
0 |
T4 |
24122 |
23847 |
0 |
0 |
T5 |
15827 |
15569 |
0 |
0 |
T6 |
96386 |
49481 |
0 |
0 |
T7 |
20458 |
20380 |
0 |
0 |
T8 |
61672 |
30604 |
0 |
0 |
T9 |
75683 |
0 |
0 |
0 |
T11 |
5091 |
5033 |
0 |
0 |
T12 |
29324 |
14387 |
0 |
0 |
T18 |
24751 |
2180 |
0 |
0 |
T31 |
0 |
6333 |
0 |
0 |
T33 |
0 |
43885 |
0 |
0 |
T85 |
12853 |
0 |
0 |
0 |
T92 |
11772 |
0 |
0 |
0 |
T105 |
78316 |
767 |
0 |
0 |
T106 |
0 |
3407 |
0 |
0 |
T107 |
0 |
9203 |
0 |
0 |
T111 |
34877 |
3278 |
0 |
0 |
T112 |
0 |
2435 |
0 |
0 |
T113 |
0 |
7823 |
0 |
0 |
T114 |
0 |
15497 |
0 |
0 |
T115 |
0 |
25208 |
0 |
0 |
T116 |
32350 |
0 |
0 |
0 |
T117 |
118908 |
0 |
0 |
0 |
T118 |
45186 |
0 |
0 |
0 |
T119 |
18054 |
0 |
0 |
0 |
T120 |
10532 |
0 |
0 |
0 |
gen_digest_read_lock.DigestReadLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
259206138 |
67035608 |
0 |
0 |
T3 |
24357 |
2297 |
0 |
0 |
T4 |
24122 |
0 |
0 |
0 |
T5 |
31654 |
3905 |
0 |
0 |
T6 |
144579 |
71587 |
0 |
0 |
T7 |
20458 |
0 |
0 |
0 |
T8 |
92508 |
0 |
0 |
0 |
T11 |
5091 |
0 |
0 |
0 |
T12 |
43986 |
0 |
0 |
0 |
T16 |
191338 |
110518 |
0 |
0 |
T18 |
0 |
28524 |
0 |
0 |
T31 |
121304 |
129028 |
0 |
0 |
T58 |
0 |
2609 |
0 |
0 |
T85 |
38559 |
0 |
0 |
0 |
T87 |
0 |
49902 |
0 |
0 |
T89 |
29226 |
14990 |
0 |
0 |
T90 |
45276 |
0 |
0 |
0 |
T105 |
0 |
87562 |
0 |
0 |
T106 |
0 |
27136 |
0 |
0 |
T109 |
141880 |
0 |
0 |
0 |
T110 |
13968 |
0 |
0 |
0 |
T116 |
0 |
3693 |
0 |
0 |
T117 |
0 |
15515 |
0 |
0 |
T121 |
0 |
7999 |
0 |
0 |
gen_digest_write_lock.DigestWriteLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
432010230 |
119784210 |
0 |
0 |
T3 |
48714 |
5369 |
0 |
0 |
T4 |
48244 |
0 |
0 |
0 |
T5 |
63308 |
10144 |
0 |
0 |
T6 |
240965 |
127837 |
0 |
0 |
T7 |
40916 |
0 |
0 |
0 |
T8 |
154180 |
0 |
0 |
0 |
T11 |
10182 |
0 |
0 |
0 |
T12 |
73310 |
0 |
0 |
0 |
T16 |
287007 |
200085 |
0 |
0 |
T18 |
0 |
46047 |
0 |
0 |
T31 |
181956 |
200553 |
0 |
0 |
T58 |
0 |
8150 |
0 |
0 |
T85 |
64265 |
0 |
0 |
0 |
T87 |
0 |
91568 |
0 |
0 |
T89 |
43839 |
21814 |
0 |
0 |
T90 |
75460 |
0 |
0 |
0 |
T105 |
0 |
87562 |
0 |
0 |
T106 |
0 |
27136 |
0 |
0 |
T109 |
212820 |
0 |
0 |
0 |
T110 |
13968 |
3308 |
0 |
0 |
T116 |
0 |
15636 |
0 |
0 |
T117 |
0 |
38235 |
0 |
0 |
T121 |
0 |
11625 |
0 |
0 |
u_state_regs_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
518412276 |
513495492 |
0 |
0 |
T1 |
27870 |
27450 |
0 |
0 |
T2 |
74178 |
72558 |
0 |
0 |
T3 |
146142 |
144444 |
0 |
0 |
T4 |
144732 |
143082 |
0 |
0 |
T5 |
94962 |
93414 |
0 |
0 |
T6 |
289158 |
283134 |
0 |
0 |
T7 |
122748 |
122280 |
0 |
0 |
T8 |
185016 |
183624 |
0 |
0 |
T11 |
30546 |
30198 |
0 |
0 |
T12 |
87972 |
86322 |
0 |
0 |