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 | 124 | 77.50 |
CONT_ASSIGN | 182 | 1 | 1 | 100.00 |
CONT_ASSIGN | 193 | 1 | 1 | 100.00 |
ALWAYS | 206 | 140 | 104 | 74.29 |
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: T30 T31 T32
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T33 T34 T35
287 1/1 error_d = otp_err;
Tests: T33 T34 T35
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 T13 T36
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T13 T36
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: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 1/1 base_sel = DigOffset;
Tests: T6 T13 T36
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
369 1/1 state_d = IdleSt;
Tests: T6 T13 T36
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T37
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T38 T39 T40
406 1/1 error_d = otp_err;
Tests: T38 T39 T40
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T38 T39 T40
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 T13 T36
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T41 T42 T43
561 1/1 error_d = CheckFailError;
Tests: T41 T42 T43
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T41 T42 T43
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T11
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: T44 T45 T46
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T47 T48 T49
287 1/1 error_d = otp_err;
Tests: T47 T48 T49
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 T13 T36
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T13 T36
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: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 1/1 base_sel = DigOffset;
Tests: T6 T13 T36
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
369 1/1 state_d = IdleSt;
Tests: T6 T13 T36
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T50 T51 T52
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T50 T53 T54
406 1/1 error_d = otp_err;
Tests: T50 T53 T54
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T50 T53 T54
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 T13 T36
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T11 T55 T56
561 1/1 error_d = CheckFailError;
Tests: T11 T55 T56
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T11 T55 T56
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T12
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: T33 T30 T44
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T31 T32 T57
287 1/1 error_d = otp_err;
Tests: T31 T32 T57
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 T13 T36
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T13 T36
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: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 1/1 base_sel = DigOffset;
Tests: T6 T13 T36
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
369 1/1 state_d = IdleSt;
Tests: T6 T13 T36
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T53 T58 T59
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T60 T51 T61
406 1/1 error_d = otp_err;
Tests: T60 T51 T61
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T60 T51 T61
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 T13 T36
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T62 T63 T64
561 1/1 error_d = CheckFailError;
Tests: T62 T63 T64
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T62 T63 T64
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T11
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 | 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: T65 T66 T67
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T30 T46 T68
287 1/1 error_d = otp_err;
Tests: T30 T46 T68
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 T13 T36
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T13 T36
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: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 1/1 base_sel = DigOffset;
Tests: T6 T13 T36
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
369 1/1 state_d = IdleSt;
Tests: T6 T13 T36
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T69 T70 T39
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T71 T59 T72
406 1/1 error_d = otp_err;
Tests: T71 T59 T72
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T71 T59 T72
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 T13 T36
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T73 T74 T75
561 1/1 error_d = CheckFailError;
Tests: T73 T74 T75
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T73 T74 T75
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T11
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: T66 T67
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T65 T76 T77
287 1/1 error_d = otp_err;
Tests: T65 T76 T77
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 T13 T36
326 1/1 state_d = IntegDigClrSt;
Tests: T6 T13 T36
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: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 1/1 base_sel = DigOffset;
Tests: T6 T13 T36
350 end
==> MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
369 1/1 state_d = IdleSt;
Tests: T6 T13 T36
370 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T78 T79 T80
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T81 T53 T82
406 1/1 error_d = otp_err;
Tests: T81 T53 T82
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T81 T53 T82
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 T13 T36
557 end
558 // Error out and lock the partition if this check fails.
559 end else begin
560 1/1 state_d = ErrorSt;
Tests: T83 T84
561 1/1 error_d = CheckFailError;
Tests: T83 T84
562 // The check has finished and found an error.
563 1/1 integ_chk_ack_o = 1'b1;
Tests: T83 T84
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T11
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: T33 T30 T68
284 end
MISSING_ELSE
285 end else begin
286 1/1 state_d = ErrorSt;
Tests: T85 T44 T86
287 1/1 error_d = otp_err;
Tests: T85 T44 T86
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 T13 T36
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 T13 T36
332 end
333 1/1 end else if (cnsty_chk_req_i) begin
Tests: T1 T2 T3
334 1/1 state_d = CnstyReadSt;
Tests: T6 T13 T36
335 1/1 cnt_clr = 1'b1;
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
349 unreachable base_sel = DigOffset;
350 end
MISSING_ELSE
351 1/1 if (otp_gnt_i) begin
Tests: T6 T13 T36
352 1/1 state_d = CnstyReadWaitSt;
Tests: T6 T13 T36
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: T6 T13 T36
363 1/1 if (otp_err inside {NoError, MacroEccCorrError}) begin
Tests: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
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: T6 T13 T36
386 1/1 state_d = IdleSt;
Tests: T6 T13 T36
387 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T6 T13 T36
388 // Need to go back and read out more blocks.
389 end else begin
390 1/1 state_d = CnstyReadSt;
Tests: T6 T13 T36
391 1/1 cnt_en = 1'b1;
Tests: T6 T13 T36
392 end
393 end else begin
394 1/1 state_d = ErrorSt;
Tests: T87 T66 T67
395 1/1 error_d = CheckFailError;
Tests: T87 T66 T67
396 // The check has finished and found an error.
397 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T87 T66 T67
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: T6 T13 T36
402 1/1 error_d = MacroEccCorrError;
Tests: T88 T58 T89
403 end
MISSING_ELSE
404 end else begin
405 1/1 state_d = ErrorSt;
Tests: T38 T40
406 1/1 error_d = otp_err;
Tests: T38 T40
407 // The check has finished and found an error.
408 1/1 cnsty_chk_ack_o = 1'b1;
Tests: T38 T40
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 T11
573 1/1 if (error_q == NoError) begin
Tests: T2 T4 T11
574 1/1 error_d = FsmStateError;
Tests: T27 T28 T29
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 T11
579 1/1 integ_chk_ack_o = 1'b1;
Tests: T2 T4 T11
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 T11
604 1/1 fsm_err_o = 1'b1;
Tests: T2 T4 T11
605 1/1 if (state_q != ErrorSt) begin
Tests: T2 T4 T11
606 1/1 error_d = FsmStateError;
Tests: T2 T4 T11
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 | 40 | 83.33 |
Logical | 48 | 40 | 83.33 |
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 | T30,T31,T32 |
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 | T24,T90,T91 |
1 | 0 | Covered | T36,T92,T93 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T24,T90,T91 |
1 | Covered | T6,T13,T36 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T92,T93 |
1 | Covered | T6,T13,T94 |
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 | T6,T13,T36 |
1 | Covered | T37 |
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 | T41,T42,T43 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T3,T5,T6 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T5,T6 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T3,T5,T6 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T11 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11001111000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
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,T5,T6 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T3,T5,T6 |
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 | T66,T67 |
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 | T24,T91,T95 |
1 | 0 | Covered | T36,T93,T96 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T24,T91,T95 |
1 | Covered | T6,T13,T36 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T93,T96 |
1 | Covered | T6,T13,T94 |
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 | T6,T13,T36 |
1 | Covered | T78,T79,T80 |
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 | T83,T84 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T36,T94,T97 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T36,T94,T97 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T94,T97 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T11 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11101010000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
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 | T36,T94,T97 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T36,T94,T97 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T36,T94,T97 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T36,T94,T97 |
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 | T44,T45,T46 |
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 | T24,T98,T91 |
1 | 0 | Covered | T36,T93,T18 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T24,T98,T91 |
1 | Covered | T6,T13,T36 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T93,T18 |
1 | Covered | T6,T13,T94 |
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 | T6,T13,T36 |
1 | Covered | T50,T51,T52 |
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 | T11,T55,T56 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T5,T11,T13 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T12 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011000000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
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,T11,T13 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T11,T13 |
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 | T33,T30,T44 |
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 | T24,T90,T98 |
1 | 0 | Covered | T36,T92,T99 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T24,T90,T98 |
1 | Covered | T6,T13,T36 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T92,T99 |
1 | Covered | T6,T13,T94 |
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 | T6,T13,T36 |
1 | Covered | T53,T58,T59 |
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 | T62,T63,T64 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T5,T13,T36 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T11 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011010000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
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,T13,T36 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
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 | T33,T30,T68 |
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 | T6,T13,T36 |
1 | Covered | T6,T13,T36 |
LINE 401
EXPRESSION (otp_err != NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T6,T13,T36 |
1 | Covered | T88,T58,T89 |
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,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T11 |
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 | T65,T66,T67 |
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 | T24,T90,T98 |
1 | 0 | Covered | T36,T93,T99 |
LINE 368
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T24,T90,T98 |
1 | Covered | T6,T13,T36 |
LINE 368
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T36,T93,T99 |
1 | Covered | T6,T13,T94 |
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 | T6,T13,T36 |
1 | Covered | T69,T70,T39 |
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 | T73,T74,T75 |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == data_mux)
-----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 547
SUB-EXPRESSION (digest_o == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T5,T13,T36 |
1 | Covered | T1,T2,T3 |
LINE 573
EXPRESSION (error_q == NoError)
----------1---------
-1- | Status | Tests |
0 | Covered | T2,T4,T11 |
1 | Covered | T27,T28,T29 |
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,T11 |
1 | Covered | T2,T4,T11 |
LINE 636
EXPRESSION ((base_sel == DigOffset) ? DigestOffset : 11'b11011111000)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
LINE 636
SUB-EXPRESSION (base_sel == DigOffset)
-----------1-----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T6,T13,T36 |
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,T13,T36 |
LINE 709
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 729
EXPRESSION ((digest_o != '0) ? MuBi8True : MuBi8False)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
LINE 729
SUB-EXPRESSION (digest_o != '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T5,T13,T36 |
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 |
T6,T13,T36 |
CnstyReadWaitSt |
352 |
Covered |
T6,T13,T36 |
ErrorSt |
286 |
Covered |
T2,T4,T11 |
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 |
T6,T13,T36 |
CnstyReadSt->ErrorSt |
596 |
Covered |
T100,T9,T101 |
CnstyReadWaitSt->CnstyReadSt |
390 |
Covered |
T6,T13,T36 |
CnstyReadWaitSt->ErrorSt |
373 |
Covered |
T100,T9,T101 |
CnstyReadWaitSt->IdleSt |
369 |
Covered |
T6,T13,T36 |
IdleSt->CnstyReadSt |
334 |
Covered |
T6,T13,T36 |
IdleSt->ErrorSt |
596 |
Covered |
T4,T12,T102 |
IdleSt->IntegDigClrSt |
326 |
Covered |
T6,T13,T36 |
InitDescrSt->ErrorSt |
596 |
Covered |
T11,T85,T41 |
InitDescrSt->InitDescrWaitSt |
303 |
Covered |
T1,T2,T3 |
InitDescrWaitSt->ErrorSt |
596 |
Covered |
T11,T41,T33 |
InitDescrWaitSt->InitSt |
315 |
Covered |
T1,T2,T3 |
InitSt->ErrorSt |
596 |
Covered |
T2,T11,T103 |
InitSt->InitWaitSt |
256 |
Covered |
T1,T2,T3 |
InitWaitSt->ErrorSt |
286 |
Covered |
T11,T85,T103 |
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 |
T100,T104,T9 |
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 |
T105,T77 |
IntegDigFinSt->IntegDigWaitSt |
532 |
Covered |
T1,T2,T3 |
IntegDigPadSt->ErrorSt |
596 |
Not Covered |
|
IntegDigPadSt->IntegDigFinSt |
520 |
Covered |
T1,T2,T3 |
IntegDigSt->ErrorSt |
596 |
Covered |
T100,T104,T106 |
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 |
T11,T85,T41 |
IntegDigWaitSt->IdleSt |
548 |
Covered |
T1,T2,T3 |
IntegScrSt->ErrorSt |
596 |
Covered |
T107,T73,T108 |
IntegScrSt->IntegScrWaitSt |
460 |
Covered |
T1,T2,T3 |
IntegScrWaitSt->ErrorSt |
596 |
Covered |
T100,T104,T9 |
IntegScrWaitSt->IntegDigSt |
470 |
Covered |
T1,T2,T3 |
ResetSt->ErrorSt |
596 |
Covered |
T109,T110,T111 |
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 |
T11,T41,T55 |
FsmStateError |
574 |
Covered |
T2,T4,T11 |
MacroEccCorrError |
283 |
Covered |
T37,T50,T33 |
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 |
T67 |
MacroEccCorrError->FsmStateError |
606 |
Covered |
T33,T30,T44 |
NoError->CheckFailError |
374 |
Covered |
T11,T41,T55 |
NoError->FsmStateError |
574 |
Covered |
T2,T4,T11 |
NoError->MacroEccCorrError |
283 |
Covered |
T37,T50,T33 |
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 |
T6,T13,T36 |
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 |
T5,T13,T36 |
0 |
Covered |
T1,T2,T3 |
729 assign digest_locked = (digest_o != '0) ? MuBi8True : MuBi8False;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T5,T13,T36 |
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 |
T33,T30,T44 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T30,T31,T32 |
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,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
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 |
T78,T79,T53 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T60,T81,T53 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
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,T13,T36 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
Covered |
T73,T62,T63 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T27,T28,T29 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T11 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T27,T28,T29 |
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,T11 |
1 |
0 |
Covered |
T2,T4,T11 |
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 |
55 |
78.57 |
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 |
39 |
75.00 |
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 |
T6,T13,T36 |
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 |
T30,T44,T31 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T47,T33,T48 |
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,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
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 |
T37,T50,T51 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T50,T53,T38 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
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,T13,T36 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
Covered |
T11,T41,T55 |
IntegDigWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
Covered |
T1,T2,T3 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
Covered |
T27,T28,T29 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T11 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T27,T28,T29 |
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,T11 |
1 |
0 |
Covered |
T2,T4,T11 |
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 |
T33,T30,T68 |
InitWaitSt |
- |
- |
1 |
1 |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
InitWaitSt |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T85,T44,T86 |
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,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
IdleSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Unreachable |
|
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
0 |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T87,T66,T67 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T88,T58,T89 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T38,T40 |
CnstyReadWaitSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T6,T13,T36 |
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 |
T27,T28,T29 |
ErrorSt |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
Covered |
T2,T4,T11 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T27,T28,T29 |
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,T11 |
1 |
0 |
Covered |
T2,T4,T11 |
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 |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
BypassEnable0_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
299036829 |
0 |
0 |
T1 |
14082 |
13902 |
0 |
0 |
T2 |
37185 |
36486 |
0 |
0 |
T3 |
41757 |
40974 |
0 |
0 |
T4 |
44097 |
43347 |
0 |
0 |
T5 |
71718 |
70596 |
0 |
0 |
T6 |
71280 |
70554 |
0 |
0 |
T10 |
12396 |
12171 |
0 |
0 |
T11 |
45765 |
44952 |
0 |
0 |
T12 |
74163 |
73467 |
0 |
0 |
T13 |
105657 |
103992 |
0 |
0 |
BypassEnable1_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
498394715 |
0 |
0 |
T1 |
23470 |
23170 |
0 |
0 |
T2 |
61975 |
60810 |
0 |
0 |
T3 |
69595 |
68290 |
0 |
0 |
T4 |
73495 |
72245 |
0 |
0 |
T5 |
119530 |
117660 |
0 |
0 |
T6 |
118800 |
117590 |
0 |
0 |
T10 |
20660 |
20285 |
0 |
0 |
T11 |
76275 |
74920 |
0 |
0 |
T12 |
123605 |
122445 |
0 |
0 |
T13 |
176095 |
173320 |
0 |
0 |
CnstyChkAckKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
DataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
DigestKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
DigestOffsetMustBeRepresentable_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6732 |
6732 |
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 |
T10 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
T13 |
6 |
6 |
0 |
0 |
EccErrorState_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
0 |
0 |
0 |
ErrorKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
InitDoneKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
InitReadLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
163716268 |
0 |
0 |
T1 |
28164 |
7560 |
0 |
0 |
T2 |
74370 |
34344 |
0 |
0 |
T3 |
83514 |
15342 |
0 |
0 |
T4 |
88194 |
56315 |
0 |
0 |
T5 |
143436 |
45543 |
0 |
0 |
T6 |
142560 |
20475 |
0 |
0 |
T10 |
24792 |
7920 |
0 |
0 |
T11 |
91530 |
48869 |
0 |
0 |
T12 |
148326 |
112158 |
0 |
0 |
T13 |
211314 |
36015 |
0 |
0 |
InitWriteLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
163716268 |
0 |
0 |
T1 |
28164 |
7560 |
0 |
0 |
T2 |
74370 |
34344 |
0 |
0 |
T3 |
83514 |
15342 |
0 |
0 |
T4 |
88194 |
56315 |
0 |
0 |
T5 |
143436 |
45543 |
0 |
0 |
T6 |
142560 |
20475 |
0 |
0 |
T10 |
24792 |
7920 |
0 |
0 |
T11 |
91530 |
48869 |
0 |
0 |
T12 |
148326 |
112158 |
0 |
0 |
T13 |
211314 |
36015 |
0 |
0 |
IntegChkAckKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
OffsetMustBeBlockAligned_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6732 |
6732 |
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 |
T10 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
T13 |
6 |
6 |
0 |
0 |
OtpAddrKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
OtpCmdKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
OtpErrorState_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
100520911 |
9 |
0 |
0 |
T7 |
42380 |
0 |
0 |
0 |
T18 |
107019 |
0 |
0 |
0 |
T38 |
0 |
1 |
0 |
0 |
T40 |
0 |
1 |
0 |
0 |
T44 |
0 |
1 |
0 |
0 |
T45 |
0 |
1 |
0 |
0 |
T85 |
13582 |
1 |
0 |
0 |
T86 |
0 |
1 |
0 |
0 |
T96 |
32312 |
0 |
0 |
0 |
T100 |
255596 |
0 |
0 |
0 |
T104 |
77386 |
0 |
0 |
0 |
T112 |
0 |
1 |
0 |
0 |
T113 |
0 |
1 |
0 |
0 |
T114 |
0 |
1 |
0 |
0 |
T115 |
17776 |
0 |
0 |
0 |
T116 |
12640 |
0 |
0 |
0 |
T117 |
15846 |
0 |
0 |
0 |
T118 |
180581 |
0 |
0 |
0 |
OtpPartBufSize_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6732 |
6732 |
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 |
T10 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
T13 |
6 |
6 |
0 |
0 |
OtpReqKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
OtpSizeKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
OtpWdataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ReadLockImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
498394715 |
0 |
0 |
T1 |
23470 |
23170 |
0 |
0 |
T2 |
61975 |
60810 |
0 |
0 |
T3 |
69595 |
68290 |
0 |
0 |
T4 |
73495 |
72245 |
0 |
0 |
T5 |
119530 |
117660 |
0 |
0 |
T6 |
118800 |
117590 |
0 |
0 |
T10 |
20660 |
20285 |
0 |
0 |
T11 |
76275 |
74920 |
0 |
0 |
T12 |
123605 |
122445 |
0 |
0 |
T13 |
176095 |
173320 |
0 |
0 |
ReadLockPropagation_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
140117975 |
0 |
0 |
T1 |
9388 |
4634 |
0 |
0 |
T2 |
24790 |
12162 |
0 |
0 |
T3 |
27838 |
13658 |
0 |
0 |
T4 |
29398 |
14449 |
0 |
0 |
T5 |
47812 |
23532 |
0 |
0 |
T6 |
47520 |
23518 |
0 |
0 |
T10 |
8264 |
4057 |
0 |
0 |
T11 |
30510 |
14984 |
0 |
0 |
T12 |
49442 |
24489 |
0 |
0 |
T13 |
70438 |
34664 |
0 |
0 |
T17 |
7076 |
0 |
0 |
0 |
T18 |
0 |
18902 |
0 |
0 |
T20 |
0 |
61789 |
0 |
0 |
T36 |
143198 |
6636 |
0 |
0 |
T92 |
39162 |
0 |
0 |
0 |
T93 |
112634 |
0 |
0 |
0 |
T94 |
67966 |
0 |
0 |
0 |
T97 |
23574 |
0 |
0 |
0 |
T99 |
265764 |
26008 |
0 |
0 |
T100 |
0 |
7317 |
0 |
0 |
T102 |
37222 |
0 |
0 |
0 |
T119 |
0 |
18710 |
0 |
0 |
T120 |
0 |
46112 |
0 |
0 |
T121 |
0 |
40561 |
0 |
0 |
T122 |
0 |
4634 |
0 |
0 |
T123 |
0 |
2406 |
0 |
0 |
T124 |
0 |
6190 |
0 |
0 |
T125 |
141950 |
0 |
0 |
0 |
T126 |
101100 |
0 |
0 |
0 |
ScrambledImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
299036829 |
0 |
0 |
T1 |
14082 |
13902 |
0 |
0 |
T2 |
37185 |
36486 |
0 |
0 |
T3 |
41757 |
40974 |
0 |
0 |
T4 |
44097 |
43347 |
0 |
0 |
T5 |
71718 |
70596 |
0 |
0 |
T6 |
71280 |
70554 |
0 |
0 |
T10 |
12396 |
12171 |
0 |
0 |
T11 |
45765 |
44952 |
0 |
0 |
T12 |
74163 |
73467 |
0 |
0 |
T13 |
105657 |
103992 |
0 |
0 |
ScrmblCmdKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ScrmblDataKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
599309270 |
594343732 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ScrmblModeKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ScrmblMtxReqKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ScrmblSelKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
ScrmblValidKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |
SizeMustBeBlockAligned_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
6732 |
6732 |
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 |
T10 |
6 |
6 |
0 |
0 |
T11 |
6 |
6 |
0 |
0 |
T12 |
6 |
6 |
0 |
0 |
T13 |
6 |
6 |
0 |
0 |
WriteLockImpliesDigest_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
299036829 |
0 |
0 |
T1 |
14082 |
13902 |
0 |
0 |
T2 |
37185 |
36486 |
0 |
0 |
T3 |
41757 |
40974 |
0 |
0 |
T4 |
44097 |
43347 |
0 |
0 |
T5 |
71718 |
70596 |
0 |
0 |
T6 |
71280 |
70554 |
0 |
0 |
T10 |
12396 |
12171 |
0 |
0 |
T11 |
45765 |
44952 |
0 |
0 |
T12 |
74163 |
73467 |
0 |
0 |
T13 |
105657 |
103992 |
0 |
0 |
WriteLockPropagation_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
147987308 |
0 |
0 |
T1 |
4694 |
4634 |
0 |
0 |
T2 |
12395 |
12162 |
0 |
0 |
T3 |
13919 |
13658 |
0 |
0 |
T4 |
14699 |
14449 |
0 |
0 |
T5 |
23906 |
23532 |
0 |
0 |
T6 |
23760 |
23518 |
0 |
0 |
T10 |
4132 |
4057 |
0 |
0 |
T11 |
15255 |
14984 |
0 |
0 |
T12 |
24721 |
24489 |
0 |
0 |
T13 |
35219 |
34664 |
0 |
0 |
T17 |
3538 |
0 |
0 |
0 |
T18 |
0 |
36008 |
0 |
0 |
T19 |
0 |
6321 |
0 |
0 |
T20 |
0 |
101846 |
0 |
0 |
T36 |
71599 |
6770 |
0 |
0 |
T85 |
13582 |
0 |
0 |
0 |
T92 |
19581 |
0 |
0 |
0 |
T93 |
112634 |
7527 |
0 |
0 |
T94 |
33983 |
0 |
0 |
0 |
T96 |
0 |
3443 |
0 |
0 |
T97 |
11787 |
0 |
0 |
0 |
T99 |
265764 |
0 |
0 |
0 |
T102 |
18611 |
0 |
0 |
0 |
T118 |
0 |
18782 |
0 |
0 |
T119 |
0 |
4976 |
0 |
0 |
T121 |
0 |
42679 |
0 |
0 |
T125 |
70975 |
0 |
0 |
0 |
T126 |
50550 |
0 |
0 |
0 |
T127 |
0 |
8608 |
0 |
0 |
T128 |
0 |
2996 |
0 |
0 |
gen_digest_read_lock.DigestReadLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
301562733 |
79183352 |
0 |
0 |
T5 |
47812 |
5842 |
0 |
0 |
T6 |
47520 |
0 |
0 |
0 |
T11 |
30510 |
0 |
0 |
0 |
T12 |
49442 |
0 |
0 |
0 |
T13 |
70438 |
17084 |
0 |
0 |
T17 |
3538 |
0 |
0 |
0 |
T18 |
0 |
93088 |
0 |
0 |
T36 |
214797 |
104882 |
0 |
0 |
T92 |
19581 |
13622 |
0 |
0 |
T93 |
56317 |
36666 |
0 |
0 |
T94 |
101949 |
32689 |
0 |
0 |
T96 |
0 |
25997 |
0 |
0 |
T97 |
35361 |
3814 |
0 |
0 |
T99 |
132882 |
226803 |
0 |
0 |
T100 |
0 |
1748 |
0 |
0 |
T102 |
18611 |
0 |
0 |
0 |
T104 |
0 |
43753 |
0 |
0 |
T115 |
0 |
9688 |
0 |
0 |
T117 |
0 |
13840 |
0 |
0 |
T125 |
212925 |
0 |
0 |
0 |
T126 |
50550 |
0 |
0 |
0 |
T129 |
76870 |
0 |
0 |
0 |
gen_digest_write_lock.DigestWriteLocksPartition_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
502604555 |
146707857 |
0 |
0 |
T3 |
13919 |
2597 |
0 |
0 |
T4 |
14699 |
0 |
0 |
0 |
T5 |
95624 |
14961 |
0 |
0 |
T6 |
95040 |
4993 |
0 |
0 |
T10 |
4132 |
0 |
0 |
0 |
T11 |
61020 |
3745 |
0 |
0 |
T12 |
98884 |
0 |
0 |
0 |
T13 |
140876 |
34764 |
0 |
0 |
T17 |
3538 |
0 |
0 |
0 |
T18 |
0 |
159004 |
0 |
0 |
T36 |
357995 |
161275 |
0 |
0 |
T92 |
19581 |
23633 |
0 |
0 |
T93 |
56317 |
81372 |
0 |
0 |
T94 |
135932 |
76872 |
0 |
0 |
T96 |
0 |
41206 |
0 |
0 |
T97 |
47148 |
3814 |
0 |
0 |
T99 |
132882 |
285711 |
0 |
0 |
T100 |
0 |
242900 |
0 |
0 |
T102 |
18611 |
0 |
0 |
0 |
T104 |
0 |
43753 |
0 |
0 |
T115 |
0 |
15256 |
0 |
0 |
T117 |
0 |
13840 |
0 |
0 |
T125 |
283900 |
0 |
0 |
0 |
T126 |
50550 |
0 |
0 |
0 |
T129 |
153740 |
0 |
0 |
0 |
u_state_regs_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
603125466 |
598073658 |
0 |
0 |
T1 |
28164 |
27804 |
0 |
0 |
T2 |
74370 |
72972 |
0 |
0 |
T3 |
83514 |
81948 |
0 |
0 |
T4 |
88194 |
86694 |
0 |
0 |
T5 |
143436 |
141192 |
0 |
0 |
T6 |
142560 |
141108 |
0 |
0 |
T10 |
24792 |
24342 |
0 |
0 |
T11 |
91530 |
89904 |
0 |
0 |
T12 |
148326 |
146934 |
0 |
0 |
T13 |
211314 |
207984 |
0 |
0 |