Line split page
dashboard | hierarchy | modlist | groups | tests | asserts
Go back

345 always_comb begin 346 1/1 for (int i = 0 ; i < NumWordsPrefix; i++) begin Tests: T1 T2 T3  347 1/1 reg_ns_prefix[32*i+:32] = reg2hw.prefix[i].q; Tests: T1 T2 T3  348 end 349 end 350 351 // Create a lint error to reduce the risk of accidentally enabling this feature. 352 0/1 ==> `ASSERT_STATIC_LINT_ERROR(KmacSecCmdDelayNonDefault, SecCmdDelay == 0)
ASSERT_STATIC_LINT_ERROR(KmacSecCmdDelayNonDefault, SecCmdDelay == 0): 352.1 localparam int KmacSecCmdDelayNonDefault = (SecCmdDelay == 0) ? 1 : 2; 352.2 always_comb begin 352.3 logic unused_assert_static_lint_error; 352.4 0/1 ==> unused_assert_static_lint_error = KmacSecCmdDelayNonDefault'(1'b1); 352.5 end353 354 if (SecCmdDelay > 0) begin : gen_cmd_delay_buf 355 // Delay and buffer commands for SCA measurements. 356 localparam int unsigned WidthCounter = $clog2(SecCmdDelay+1); 357 logic [WidthCounter-1:0] count_d, count_q; 358 logic counting_d, counting_q; 359 logic cmd_buf_empty; 360 kmac_cmd_e cmd_buf_q; 361 362 assign cmd_buf_empty = (cmd_buf_q == CmdNone); 363 364 // When seeing a write to the cmd register, we start counting. We stop counting once the 365 // counter has expired and the command buffer is empty. 366 assign counting_d = reg2hw.cmd.cmd.qe ? 1'b1 : 367 cmd_update & cmd_buf_empty ? 1'b0 : counting_q; 368 369 // Clear counter upon writes to the cmd register or if the specified delay is reached. 370 assign count_d = reg2hw.cmd.cmd.qe ? '0 : 371 cmd_update ? '0 : 372 counting_q ? count_q + 1'b1 : count_q; 373 374 // The manual run command cannot be delayed. Software expects this to be triggered immediately 375 // and will poll the status register to wait for the SHA3 engine to return back to the squeeze 376 // state. 377 assign cmd_update = (cmd_q == CmdManualRun) ? 1'b1 : 378 (count_q == SecCmdDelay[WidthCounter-1:0]) ? 1'b1 : 1'b0; 379 380 always_ff @(posedge clk_i or negedge rst_ni) begin 381 if (!rst_ni) begin 382 count_q <= '0; 383 counting_q <= 1'b0; 384 end else begin 385 count_q <= count_d; 386 counting_q <= counting_d; 387 end 388 end 389 390 // cmd.q is valid while cmd.qe is high, meaning it needs to be registered. We buffer one 391 // additional command such that software can write START followed by PROCESS and then go to 392 // sleep. 393 always_ff @(posedge clk_i or negedge rst_ni) begin 394 if (!rst_ni) begin 395 cmd_q <= CmdNone; 396 cmd_buf_q <= CmdNone; 397 end else begin 398 if (reg2hw.cmd.cmd.qe && cmd_update) begin 399 // New write & counter expired. 400 cmd_q <= cmd_buf_q; 401 cmd_buf_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); 402 403 end else if (reg2hw.cmd.cmd.qe) begin 404 // New write. 405 if (counting_q == 1'b0) begin 406 cmd_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); 407 end else begin 408 cmd_buf_q <= kmac_cmd_e'(reg2hw.cmd.cmd.q); 409 end 410 411 end else if (cmd_update) begin 412 // Counter expired. 413 cmd_q <= cmd_buf_q; 414 cmd_buf_q <= CmdNone; 415 end 416 end 417 end 418 419 end else begin : gen_no_cmd_delay_buf 420 // Directly forward signals from register IF. 421 1/1 assign cmd_update = reg2hw.cmd.cmd.qe; Tests: T1 T2 T3  422 1/1 assign cmd_q = kmac_cmd_e'(reg2hw.cmd.cmd.q); Tests: T1 T2 T3  423 end 424 425 // Command signals 426 1/1 assign sw_cmd = (cmd_update) ? cmd_q : CmdNone; Tests: T1 T2 T3  427 `ASSERT_KNOWN(KmacCmd_A, sw_cmd) 428 always_comb begin 429 1/1 sha3_start = 1'b 0; Tests: T1 T2 T3  430 1/1 sha3_run = 1'b 0; Tests: T1 T2 T3  431 1/1 sha3_done_d = prim_mubi_pkg::MuBi4False; Tests: T1 T2 T3  432 1/1 reg2msgfifo_process = 1'b 0; Tests: T1 T2 T3  433 434 1/1 unique case (kmac_cmd) Tests: T1 T2 T3  435 CmdStart: begin 436 1/1 sha3_start = 1'b 1; Tests: T1 T2 T3  437 end 438 439 CmdProcess: begin 440 1/1 reg2msgfifo_process = 1'b 1; Tests: T1 T2 T3  441 end 442 443 CmdManualRun: begin 444 1/1 sha3_run = 1'b 1; Tests: T1 T14 T16  445 end 446 447 CmdDone: begin 448 1/1 sha3_done_d = prim_mubi_pkg::MuBi4True; Tests: T1 T2 T3  449 end 450 451 CmdNone: begin 452 // inactive state 453 end 454 455 default: begin 456 end 457 endcase 458 end 459 460 // Status register ========================================================== 461 // status.squeeze is valid only when SHA3 engine completes the Absorb and not 462 // running the manual keccak rounds. This status is for SW to determine when 463 // to read the STATE values. 464 1/1 assign hw2reg.status.sha3_idle.d = sha3_fsm == sha3_pkg::StIdle; Tests: T1 T2 T3  465 1/1 assign hw2reg.status.sha3_absorb.d = sha3_fsm == sha3_pkg::StAbsorb; Tests: T1 T2 T3  466 1/1 assign hw2reg.status.sha3_squeeze.d = sha3_fsm == sha3_pkg::StSqueeze; Tests: T1 T2 T3  467 468 // FIFO related status 469 1/1 assign hw2reg.status.fifo_depth.d[MsgFifoDepthW-1:0] = msgfifo_depth; Tests: T1 T2 T3  470 if ($bits(hw2reg.status.fifo_depth.d) != MsgFifoDepthW) begin : gen_fifo_depth_tie 471 assign hw2reg.status.fifo_depth.d[$bits(hw2reg.status.fifo_depth.d)-1:MsgFifoDepthW] = '0; 472 end 473 1/1 assign hw2reg.status.fifo_empty.d = msgfifo_empty; Tests: T1 T2 T3  474 1/1 assign hw2reg.status.fifo_full.d = msgfifo_full; Tests: T1 T2 T3  475 476 // Configuration Register 477 logic engine_stable; 478 1/1 assign engine_stable = sha3_fsm == sha3_pkg::StIdle; Tests: T1 T2 T3  479 480 // SEC_CM: CFG_SHADOWED.CONFIG.REGWEN 481 1/1 assign hw2reg.cfg_regwen.d = engine_stable; Tests: T1 T2 T3  482 483 // Secret Key 484 // Secret key is defined as external register. So the logic latches when SW 485 // writes to KEY_SHARE0 , KEY_SHARE1 registers. 486 // SEC_CM: SW_KEY.KEY.MASKING 487 always_ff @(posedge clk_i or negedge rst_ni) begin 488 1/1 if (!rst_ni) begin Tests: T1 T2 T3  489 1/1 sw_key_data_reg[0] <= '0; Tests: T1 T2 T3  490 1/1 end else if (engine_stable) begin Tests: T1 T2 T3  491 1/1 for (int j = 0 ; j < MaxKeyLen/32 ; j++) begin Tests: T1 T2 T3  492 1/1 if (reg2hw.key_share0[j].qe) begin Tests: T1 T2 T3  493 1/1 sw_key_data_reg[0][32*j+:32] <= reg2hw.key_share0[j].q; Tests: T1 T2 T3  494 end MISSING_ELSE 495 end // for j 496 end // else if engine_stable MISSING_ELSE 497 end // always_ff 498 499 if (EnMasking || SwKeyMasked) begin : gen_key_share1_reg 500 always_ff @(posedge clk_i or negedge rst_ni) begin 501 if (!rst_ni) begin 502 sw_key_data_reg[1] <= '0; 503 end else if (engine_stable) begin 504 for (int j = 0 ; j < MaxKeyLen/32 ; j++) begin 505 if (reg2hw.key_share1[j].qe) begin 506 sw_key_data_reg[1][32*j+:32] <= reg2hw.key_share1[j].q; 507 end 508 end // for j 509 end // else if engine_stable 510 end // always_ff 511 end else begin : gen_no_key_share1_reg 512 logic unused_key_share1; 513 1/1 assign unused_key_share1 = ^reg2hw.key_share1; Tests: T1 T2 T3  514 end 515 516 if (EnMasking || !SwKeyMasked) begin : gen_key_forward 517 // Forward all available key shares as is. 518 1/1 assign sw_key_data = sw_key_data_reg; Tests: T1 T2 T3  519 end else begin : gen_key_unmask 520 // Masking is disabled but the SW still provides the key in two shares. 521 // Unmask the key for processing. 522 assign sw_key_data[0] = sw_key_data_reg[0] ^ sw_key_data_reg[1]; 523 end 524 525 1/1 assign sw_key_len = key_len_e'(reg2hw.key_len.q); Tests: T1 T2 T3  526 527 // Entropy configurations 528 1/1 assign wait_timer_prescaler = reg2hw.entropy_period.prescaler.q; Tests: T1 T2 T3  529 1/1 assign wait_timer_limit = reg2hw.entropy_period.wait_timer.q; Tests: T1 T2 T3  530 1/1 assign entropy_refresh_req = reg2hw.cmd.entropy_req.q Tests: T1 T2 T3  531 && reg2hw.cmd.entropy_req.qe; 532 1/1 assign entropy_seed_update = reg2hw.entropy_seed.qe; Tests: T4 T5 T6  533 1/1 assign entropy_seed_data = reg2hw.entropy_seed.q; Tests: T1 T2 T3  534 535 1/1 assign entropy_hash_threshold = reg2hw.entropy_refresh_threshold_shadowed.q; Tests: T1 T2 T3  536 assign hw2reg.entropy_refresh_hash_cnt.de = 1'b 1; 537 unreachable assign hw2reg.entropy_refresh_hash_cnt.d = entropy_hash_cnt; 538 539 1/1 assign entropy_hash_clr = reg2hw.cmd.hash_cnt_clr.qe Tests: T1 T2 T3  540 && reg2hw.cmd.hash_cnt_clr.q; 541 542 // Entropy config 543 1/1 assign entropy_ready = reg2hw.cfg_shadowed.entropy_ready.q Tests: T1 T2 T3  544 & reg2hw.cfg_shadowed.entropy_ready.qe; 545 1/1 assign entropy_mode = entropy_mode_e'(reg2hw.cfg_shadowed.entropy_mode.q); Tests: T1 T2 T3  546 1/1 assign entropy_fast_process = reg2hw.cfg_shadowed.entropy_fast_process.q; Tests: T1 T2 T3  547 548 // msg_mask_en turns on the message LFSR when KMAC is enabled. 549 1/1 assign cfg_msg_mask = reg2hw.cfg_shadowed.msg_mask.q; Tests: T1 T2 T3  550 1/1 assign msg_mask_en = cfg_msg_mask & msg_valid & msg_ready; Tests: T1 T2 T3  551 552 // Enable unsupported mode & strength combination 553 1/1 assign cfg_en_unsupported_modestrength = Tests: T1 T2 T3  554 reg2hw.cfg_shadowed.en_unsupported_modestrength.q; 555 556 `ASSERT(EntropyReadyLatched_A, $rose(entropy_ready) |=> !entropy_ready) 557 558 // Idle control (registered output) 559 // The logic checks idle of SHA3 engine, MSG_FIFO, KMAC_CORE, KEYMGR interface 560 always_ff @(posedge clk_i or negedge rst_ni) begin 561 1/1 if (!rst_ni) begin Tests: T1 T2 T3  562 1/1 idle_o <= prim_mubi_pkg::MuBi4True; Tests: T1 T2 T3  563 1/1 end else if ((sha3_fsm == sha3_pkg::StIdle) && (msgfifo_empty || SecIdleAcceptSwMsg)) begin Tests: T1 T2 T3  564 1/1 idle_o <= prim_mubi_pkg::MuBi4True; Tests: T1 T2 T3  565 end else begin 566 1/1 idle_o <= prim_mubi_pkg::MuBi4False; Tests: T1 T2 T3  567 end 568 end 569 570 // Clear the error processed 571 1/1 assign err_processed = reg2hw.cmd.err_processed.q & reg2hw.cmd.err_processed.qe; Tests: T1 T2 T3  572 573 // Make sure the field has latch in reg_top 574 `ASSERT(ErrProcessedLatched_A, $rose(err_processed) |=> !err_processed) 575 576 // App mode, strength, kmac_en 577 1/1 assign reg_kmac_en = reg2hw.cfg_shadowed.kmac_en.q; Tests: T1 T2 T3  578 1/1 assign reg_sha3_mode = sha3_pkg::sha3_mode_e'(reg2hw.cfg_shadowed.mode.q); Tests: T1 T2 T3  579 1/1 assign reg_keccak_strength = sha3_pkg::keccak_strength_e'(reg2hw.cfg_shadowed.kstrength.q); Tests: T1 T2 T3  580 581 /////////////// 582 // Interrupt // 583 /////////////// 584 585 // Hash process absorbed interrupt 586 // Convert mubi4_t to logic to generate interrupts 587 1/1 assign event_absorbed = prim_mubi_pkg::mubi4_test_true_strict(app_absorbed); Tests: T1 T2 T3  588 589 prim_intr_hw #(.Width(1)) intr_kmac_done ( 590 .clk_i, 591 .rst_ni, 592 .event_intr_i (event_absorbed), 593 .reg2hw_intr_enable_q_i (reg2hw.intr_enable.kmac_done.q), 594 .reg2hw_intr_test_q_i (reg2hw.intr_test.kmac_done.q), 595 .reg2hw_intr_test_qe_i (reg2hw.intr_test.kmac_done.qe), 596 .reg2hw_intr_state_q_i (reg2hw.intr_state.kmac_done.q), 597 .hw2reg_intr_state_de_o (hw2reg.intr_state.kmac_done.de), 598 .hw2reg_intr_state_d_o (hw2reg.intr_state.kmac_done.d), 599 .intr_o (intr_kmac_done_o) 600 ); 601 602 `ASSERT(Sha3AbsorbedPulse_A, 603 $rose(prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed)) |=> 604 prim_mubi_pkg::mubi4_test_false_strict(sha3_absorbed)) 605 606 // Message FIFO empty interrupt 607 // 608 // The message FIFO empty interrupt is **not useful** for software if: 609 // - One of the hardware application interfaces is actively using the KMAC block. In this case 610 // the message FIFO is managed entirely by the application interface. 611 // - The SHA3 core is not in the Absorb state. Only in this state, the FIFO is writeable by 612 // software anyway. 613 // - Software has already written the Process command. The KMAC block will now empty the 614 // message FIFO and load its content into the SHA3 core, add the padding and then perfom 615 // the final absorption. Software cannot append the message further. 616 // 617 // The message FIFO empty interrupt can be **useful** for software in particular if: 618 // - The message FIFO was completely full previously. However, unless the KMAC block is currently 619 // processing a block or waiting for fresh entropy from EDN, it always empties the message FIFO 620 // faster than software can fill it up, meaning the message FIFO is empty most of the time. 621 // Note, the empty status is signaled only once after the FIFO was completely full. The FIFO 622 // needs to be full again for the empty status to be signaled again next time it's empty. 623 // 624 // For further details see also: 625 // https://opentitan.org/book/hw/ip/kmac/doc/theory_of_operation.html#fifo-depth-and-empty-status 626 logic status_msgfifo_empty, msgfifo_empty_gate; 627 logic msgfifo_empty_negedge, msgfifo_empty_q; 628 logic msgfifo_full_seen_d, msgfifo_full_seen_q; 629 1/1 assign msgfifo_empty_negedge = msgfifo_empty_q & ~msgfifo_empty; Tests: T1 T2 T3  630 631 // Track whether the message FIFO was full after being empty. We clear the tracking: 632 // - When receiving the Process command. This is to start over for the next message. 633 // - When seeing a negative edge on the empty signal. This signals that software has reacted to 634 // the interrupt and is filling up the FIFO again. 635 1/1 assign msgfifo_full_seen_d = Tests: T1 T2 T3  636 msgfifo_full ? 1'b 1 : 637 msgfifo_empty_negedge ? 1'b 0 : 638 msgfifo2kmac_process ? 1'b 0 : msgfifo_full_seen_q; 639 640 // The interrupt is gated unless software is performing an absorption operation (but not the 641 // final block) and the FIFO was full before. The msgfifo2kmac_process pulse is arriving from the 642 // FIFO together with the empty signal. 643 1/1 assign msgfifo_empty_gate = Tests: T1 T2 T3  644 app_active ? 1'b 1 : 645 sha3_fsm != sha3_pkg::StAbsorb ? 1'b 1 : 646 msgfifo2kmac_process ? 1'b 1 : ~msgfifo_full_seen_q; 647 648 1/1 assign status_msgfifo_empty = msgfifo_empty_gate ? 1'b 0 : msgfifo_empty; Tests: T1 T2 T3  649 650 always_ff @(posedge clk_i or negedge rst_ni) begin 651 1/1 if (!rst_ni) begin Tests: T1 T2 T3  652 1/1 msgfifo_empty_q <= 1'b 0; Tests: T1 T2 T3  653 1/1 msgfifo_full_seen_q <= 1'b 0; Tests: T1 T2 T3  654 end else begin 655 1/1 msgfifo_empty_q <= msgfifo_empty; Tests: T1 T2 T3  656 1/1 msgfifo_full_seen_q <= msgfifo_full_seen_d; Tests: T1 T2 T3  657 end 658 end 659 660 prim_intr_hw #( 661 .Width(1), 662 .IntrT("Status") 663 ) intr_fifo_empty ( 664 .clk_i, 665 .rst_ni, 666 .event_intr_i (status_msgfifo_empty), 667 .reg2hw_intr_enable_q_i (reg2hw.intr_enable.fifo_empty.q), 668 .reg2hw_intr_test_q_i (reg2hw.intr_test.fifo_empty.q), 669 .reg2hw_intr_test_qe_i (reg2hw.intr_test.fifo_empty.qe), 670 .reg2hw_intr_state_q_i (reg2hw.intr_state.fifo_empty.q), 671 .hw2reg_intr_state_de_o (hw2reg.intr_state.fifo_empty.de), 672 .hw2reg_intr_state_d_o (hw2reg.intr_state.fifo_empty.d), 673 .intr_o (intr_fifo_empty_o) 674 ); 675 676 // Error 677 678 logic event_error; 679 1/1 assign event_error = sha3_err.valid | app_err.valid Tests: T1 T2 T3  680 | entropy_err.valid | errchecker_err.valid 681 ; 682 683 // Assing error code to the register 684 1/1 assign hw2reg.err_code.de = event_error; Tests: T1 T2 T3  685 686 always_comb begin 687 1/1 hw2reg.err_code.d = '0; Tests: T1 T2 T3  688 689 1/1 priority case (1'b 1) Tests: T1 T2 T3  690 // app_err has the highest priority. If SW issues an incorrect command 691 // while app is in active state, the error from AppIntf is passed 692 // through. 693 app_err.valid: begin 694 1/1 hw2reg.err_code.d = {app_err.code, app_err.info}; Tests: T11 T4 T5  695 end 696 697 errchecker_err.valid: begin 698 1/1 hw2reg.err_code.d = {errchecker_err.code , errchecker_err.info}; Tests: T51 T31 T25  699 end 700 701 sha3_err.valid: begin 702 1/1 hw2reg.err_code.d = {sha3_err.code , sha3_err.info}; Tests: T16 T36 T37  703 end 704 705 entropy_err.valid: begin 706 0/1 ==> hw2reg.err_code.d = {entropy_err.code, entropy_err.info}; 707 end 708 709 msgfifo_err.valid: begin 710 0/1 ==> hw2reg.err_code.d = {msgfifo_err.code, msgfifo_err.info}; 711 end 712 713 default: begin 714 hw2reg.err_code.d = '0; 715 end 716 endcase 717 end 718 719 // Counter errors 720 logic counter_error, sha3_count_error, key_index_error; 721 logic msgfifo_counter_error; 722 logic kmac_entropy_hash_counter_error; 723 1/1 assign counter_error = sha3_count_error Tests: T1 T2 T3  724 | kmac_entropy_hash_counter_error 725 | key_index_error 726 | msgfifo_counter_error; 727 728 0/1 ==> assign msgfifo_counter_error = msgfifo_err.valid; 729 730 // State Errors 731 logic sparse_fsm_error; 732 logic sha3_state_error, kmac_errchk_state_error; 733 logic kmac_core_state_error, kmac_app_state_error; 734 logic kmac_entropy_state_error, kmac_state_error; 735 1/1 assign sparse_fsm_error = sha3_state_error Tests: T1 T2 T3  736 | kmac_errchk_state_error 737 | kmac_core_state_error 738 | kmac_app_state_error 739 | kmac_entropy_state_error 740 | kmac_state_error; 741 742 // Control Signal Integrity Errors 743 logic control_integrity_error; 744 logic sha3_storage_rst_error; 745 1/1 assign control_integrity_error = sha3_storage_rst_error; Tests: T1 T2 T3  746 747 prim_intr_hw #(.Width(1)) intr_kmac_err ( 748 .clk_i, 749 .rst_ni, 750 .event_intr_i (event_error), 751 .reg2hw_intr_enable_q_i (reg2hw.intr_enable.kmac_err.q), 752 .reg2hw_intr_test_q_i (reg2hw.intr_test.kmac_err.q), 753 .reg2hw_intr_test_qe_i (reg2hw.intr_test.kmac_err.qe), 754 .reg2hw_intr_state_q_i (reg2hw.intr_state.kmac_err.q), 755 .hw2reg_intr_state_de_o (hw2reg.intr_state.kmac_err.de), 756 .hw2reg_intr_state_d_o (hw2reg.intr_state.kmac_err.d), 757 .intr_o (intr_kmac_err_o) 758 ); 759 760 /////////////////// 761 // State Machine // 762 /////////////////// 763 764 // State FF 765 3/3 `PRIM_FLOP_SPARSE_FSM(u_state_regs, kmac_st_d, kmac_st, kmac_st_e, KmacIdle) Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
PRIM_FLOP_SPARSE_FSM(u_state_regs, kmac_st_d, kmac_st, kmac_st_e, KmacIdle): 765.1 `ifdef SIMULATION 765.2 prim_sparse_fsm_flop #( 765.3 .StateEnumT(kmac_st_e), 765.4 .Width($bits(kmac_st_e)), 765.5 .ResetValue($bits(kmac_st_e)'(KmacIdle)), 765.6 .EnableAlertTriggerSVA(1), 765.7 .CustomForceName("kmac_st") 765.8 ) u_state_regs ( 765.9 .clk_i ( clk_i ), 765.10 .rst_ni ( rst_ni ), 765.11 .state_i ( kmac_st_d ), 765.12 .state_o ( ) 765.13 ); 765.14 always_ff @(posedge clk_i or negedge rst_ni) begin 765.15 1/1 if (!rst_ni) begin Tests: T1 T2 T3  765.16 1/1 kmac_st <= KmacIdle; Tests: T1 T2 T3  765.17 end else begin 765.18 1/1 kmac_st <= kmac_st_d; Tests: T1 T2 T3  765.19 end 765.20 end 765.21 u_state_regs_A: assert property (@(posedge clk_i) disable iff ((!rst_ni) !== '0) (kmac_st === u_state_regs.state_o)) 765.22 else begin 765.23 `ifdef UVM 765.24 uvm_pkg::uvm_report_error("ASSERT FAILED", "u_state_regs_A", uvm_pkg::UVM_NONE, 765.25 "../src/lowrisc_ip_kmac_0.1/rtl/kmac.sv", 765, "", 1); 765.26 `else 765.27 $error("%0t: (%0s:%0d) [%m] [ASSERT FAILED] %0s", $time, `__FILE__, `__LINE__, 765.28 `PRIM_STRINGIFY(u_state_regs_A)); 765.29 `endif 765.30 end 765.31 `else 765.32 prim_sparse_fsm_flop #( 765.33 .StateEnumT(kmac_st_e), 765.34 .Width($bits(kmac_st_e)), 765.35 .ResetValue($bits(kmac_st_e)'(KmacIdle)), 765.36 .EnableAlertTriggerSVA(1) 765.37 ) u_state_regs ( 765.38 .clk_i ( `PRIM_FLOP_CLK ), 765.39 .rst_ni ( `PRIM_FLOP_RST ), 765.40 .state_i ( kmac_st_d ), 765.41 .state_o ( kmac_st ) 765.42 ); 765.43 `endif766 767 always_comb begin 768 // Default value 769 1/1 kmac_st_d = kmac_st; Tests: T1 T2 T3  770 771 1/1 entropy_in_keyblock = 1'b 0; Tests: T1 T2 T3  772 1/1 kmac_state_error = 1'b 0; Tests: T1 T2 T3  773 774 1/1 unique case (kmac_st) Tests: T1 T2 T3  775 KmacIdle: begin 776 1/1 if (kmac_cmd == CmdStart) begin Tests: T1 T2 T3  777 // If cSHAKE turned on 778 1/1 if (sha3_pkg::CShake == app_sha3_mode) begin Tests: T1 T2 T3  779 1/1 kmac_st_d = KmacPrefix; Tests: T1 T2 T3  780 end else begin 781 // Jump to Msg feed directly 782 1/1 kmac_st_d = KmacMsgFeed; Tests: T1 T14 T16  783 end 784 end else begin 785 1/1 kmac_st_d = KmacIdle; Tests: T1 T2 T3  786 end 787 end 788 789 KmacPrefix: begin 790 // Wait until SHA3 processes one block 791 1/1 if (sha3_block_processed) begin Tests: T1 T2 T3  792 1/1 kmac_st_d = (app_kmac_en) ? KmacKeyBlock : KmacMsgFeed ; Tests: T1 T2 T3  793 end else begin 794 1/1 kmac_st_d = KmacPrefix; Tests: T1 T2 T3  795 end 796 end 797 798 KmacKeyBlock: begin 799 1/1 entropy_in_keyblock = 1'b 1; Tests: T1 T2 T3  800 1/1 if (sha3_block_processed) begin Tests: T1 T2 T3  801 1/1 kmac_st_d = KmacMsgFeed; Tests: T1 T2 T3  802 end else begin 803 1/1 kmac_st_d = KmacKeyBlock; Tests: T1 T2 T3  804 end 805 end 806 807 KmacMsgFeed: begin 808 // If absorbed, move to Digest 809 1/1 if (prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed) && Tests: T1 T2 T3  810 prim_mubi_pkg::mubi4_test_true_strict(sha3_done)) begin 811 // absorbed and done can be asserted at a cycle if Applications have 812 // requested the hash operation. kmac_app FSM issues CmdDone command 813 // if it receives absorbed signal. 814 1/1 kmac_st_d = KmacIdle; Tests: T11 T13 T19  815 1/1 end else if (prim_mubi_pkg::mubi4_test_true_strict(sha3_absorbed) && Tests: T1 T2 T3  816 prim_mubi_pkg::mubi4_test_false_loose(sha3_done)) begin 817 1/1 kmac_st_d = KmacDigest; Tests: T1 T2 T3  818 end else begin 819 1/1 kmac_st_d = KmacMsgFeed; Tests: T1 T2 T3  820 end 821 end 822 823 KmacDigest: begin 824 // SW can manually run it, wait till done 825 1/1 if (prim_mubi_pkg::mubi4_test_true_strict(sha3_done)) begin Tests: T1 T2 T3  826 1/1 kmac_st_d = KmacIdle; Tests: T1 T2 T3  827 end else begin 828 1/1 kmac_st_d = KmacDigest; Tests: T1 T2 T3  829 end 830 end 831 832 KmacTerminalError: begin 833 //this state is terminal 834 1/1 kmac_st_d = KmacTerminalError; Tests: T4 T5 T6  835 1/1 kmac_state_error = 1'b 1; Tests: T4 T5 T6  836 end 837 838 default: begin 839 kmac_st_d = KmacTerminalError; 840 kmac_state_error = 1'b 1; 841 end 842 endcase 843 844 // SEC_CM: FSM.GLOBAL_ESC, FSM.LOCAL_ESC 845 // Unconditionally jump into the terminal error state 846 // if the life cycle controller triggers an escalation. 847 1/1 if (lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en[0])) begin Tests: T1 T2 T3  848 1/1 kmac_st_d = KmacTerminalError; Tests: T4 T5 T6  849 end MISSING_ELSE 850 end 851 `ASSERT_KNOWN(KmacStKnown_A, kmac_st) 852 853 /////////////// 854 // Instances // 855 /////////////// 856 857 // KMAC core 858 kmac_core #( 859 .EnMasking (EnMasking) 860 ) u_kmac_core ( 861 .clk_i, 862 .rst_ni, 863 864 // from Msg FIFO 865 .fifo_valid_i (msgfifo_valid), 866 .fifo_data_i (msgfifo_data ), 867 .fifo_strb_i (msgfifo_strb ), 868 .fifo_ready_o (msgfifo_ready), 869 870 // to SHA3 core 871 .msg_valid_o (msg_valid), 872 .msg_data_o (msg_data ), 873 .msg_strb_o (msg_strb ), 874 .msg_ready_i (msg_ready), 875 876 // Configurations 877 .kmac_en_i (app_kmac_en), 878 .mode_i (app_sha3_mode), 879 .strength_i (app_keccak_strength), 880 881 // Secret key interface 882 .key_data_i (key_data), 883 .key_len_i (key_len), 884 .key_valid_i (key_valid), 885 886 // Controls 887 .start_i (sha3_start ), 888 .process_i (msgfifo2kmac_process), 889 .done_i (sha3_done ), 890 .process_o (kmac2sha3_process ), 891 892 // LC escalation 893 .lc_escalate_en_i (lc_escalate_en[1]), 894 895 // Error detection 896 .sparse_fsm_error_o (kmac_core_state_error), 897 .key_index_error_o (key_index_error) 898 ); 899 900 // SHA3 hashing engine 901 902 // msg_data masking 903 if (EnMasking == 1) begin: g_msg_mask 904 logic [MsgWidth-1:0] msg_mask_permuted; 905 906 // Permute the LFSR output to avoid same lfsr applied to multiple times 907 always_comb begin 908 msg_mask_permuted = '0; 909 for (int unsigned i = 0 ; i < MsgWidth ; i++) begin 910 // Loop through the MsgPerm constant and swap between the bits 911 msg_mask_permuted[i] = msg_mask[RndCnstMsgPerm[i]]; 912 end 913 end 914 915 for (genvar i = 0 ; i < Share ; i++) begin: g_msg_data_mask 916 assign msg_data_masked[i] = msg_data[i] 917 ^ ({MsgWidth{cfg_msg_mask}} & msg_mask_permuted); 918 end : g_msg_data_mask 919 end else begin : g_no_msg_mask 920 1/1 assign msg_data_masked[0] = msg_data[0]; Tests: T1 T2 T3  921 922 logic unused_msgmask; 923 1/1 assign unused_msgmask = ^{msg_mask, cfg_msg_mask, msg_mask_en}; Tests: T1 T2 T3  924 end 925 sha3 #( 926 .EnMasking (EnMasking) 927 ) u_sha3 ( 928 .clk_i, 929 .rst_ni, 930 931 // MSG_FIFO interface (or from KMAC) 932 .msg_valid_i (msg_valid), 933 .msg_data_i (msg_data_masked ), 934 .msg_strb_i (msg_strb ), 935 .msg_ready_o (msg_ready), 936 937 // Entropy interface 938 .rand_valid_i (sha3_rand_valid), 939 .rand_early_i (sha3_rand_early), 940 .rand_data_i (sha3_rand_data), 941 .rand_aux_i (sha3_rand_aux), 942 .rand_update_o (sha3_rand_update), 943 .rand_consumed_o (sha3_rand_consumed), 944 945 // N, S: Used in cSHAKE mode 946 .ns_data_i (ns_prefix), 947 948 // Configurations 949 .mode_i (app_sha3_mode), 950 .strength_i (app_keccak_strength), 951 952 // Controls (CMD register) 953 .start_i (sha3_start ), 954 .process_i (kmac2sha3_process), 955 .run_i (sha3_run ), 956 .done_i (sha3_done ), 957 958 // LC escalation 959 .lc_escalate_en_i (lc_escalate_en[2]), 960 961 .absorbed_o (sha3_absorbed), 962 .squeezing_o (unused_sha3_squeeze), 963 964 .block_processed_o (sha3_block_processed), 965 966 .sha3_fsm_o (sha3_fsm), 967 968 .state_valid_o (state_valid), 969 .state_o (state), // [Share] 970 971 // REQ/ACK interface to avoid power spikes 972 .run_req_o ( ), // Not used 973 .run_ack_i (1'b 1), // The SHA3 core is always allowed to process. 974 975 .error_o (sha3_err), 976 .sparse_fsm_error_o (sha3_state_error), 977 .count_error_o (sha3_count_error), 978 .keccak_storage_rst_error_o (sha3_storage_rst_error) 979 ); 980 981 // MSG_FIFO window interface to FIFO interface =============================== 982 // Tie the read path 983 assign tlram_rvalid = 1'b 0; 984 assign tlram_rdata = '0; 985 assign tlram_rerror = '0; 986 987 // Convert endian here 988 // prim_packer always packs to the right(bit0). If the input DWORD is 989 // big-endian, it needs to be swapped to little-endian to maintain the 990 // order. Internal SHA3(Keccak) runs in little-endian in contrast to HMAC 991 // So, no endian-swap after prim_packer. 992 1/1 assign tlram_wdata_endian = conv_endian32(tlram_wdata, Tests: T1 T2 T3  993 reg2hw.cfg_shadowed.msg_endianness.q); 994 1/1 assign tlram_wmask_endian = conv_endian32(tlram_wmask, Tests: T1 T2 T3  995 reg2hw.cfg_shadowed.msg_endianness.q); 996 997 // TL Adapter 998 tlul_adapter_sram #( 999 .SramAw ($clog2(MsgWindowDepth)), 1000 .SramDw (MsgWindowWidth), 1001 .Outstanding (1), 1002 .ByteAccess (1), 1003 .ErrOnRead (1) 1004 ) u_tlul_adapter_msgfifo ( 1005 .clk_i, 1006 .rst_ni, 1007 .en_ifetch_i (prim_mubi_pkg::MuBi4False), 1008 .tl_i (tl_win_h2d[WinMsgFifo]), 1009 .tl_o (tl_win_d2h[WinMsgFifo]), 1010 1011 .req_o (tlram_req), 1012 .req_type_o (), 1013 .gnt_i (tlram_gnt), 1014 .we_o (tlram_we ), 1015 .addr_o (tlram_addr), 1016 .wdata_o (tlram_wdata), 1017 .wmask_o (tlram_wmask), 1018 .intg_error_o ( ), 1019 .rdata_i (tlram_rdata), 1020 .rvalid_i (tlram_rvalid), 1021 .rerror_i (tlram_rerror), 1022 .compound_txn_in_progress_o (), 1023 .readback_en_i (prim_mubi_pkg::MuBi4False), 1024 .readback_error_o (), 1025 .wr_collision_i (1'b0), 1026 .write_pending_i (1'b0) 1027 ); 1028 1029 1/1 assign sw_msg_valid = tlram_req & tlram_we ; Tests: T1 T2 T3  1030 if (MsgWidth == MsgWindowWidth) begin : gen_sw_msg_samewidth 1031 assign sw_msg_data = tlram_wdata_endian ; 1032 assign sw_msg_mask = tlram_wmask_endian ; 1033 end else begin : gen_sw_msg_diff 1034 1/1 assign sw_msg_data = {{MsgWidth-MsgWindowWidth{1'b0}}, tlram_wdata_endian}; Tests: T1 T2 T3  1035 1/1 assign sw_msg_mask = {{MsgWidth-MsgWindowWidth{1'b0}}, tlram_wmask_endian}; Tests: T1 T2 T3  1036 end 1037 1/1 assign tlram_gnt = sw_msg_ready ; Tests: T1 T2 T3  1038 1039 logic unused_tlram_addr; 1040 unreachable assign unused_tlram_addr = &{1'b0, tlram_addr}; 1041 1042 // Application interface Mux/Demux 1043 kmac_app #( 1044 .EnMasking(EnMasking), 1045 .SecIdleAcceptSwMsg(SecIdleAcceptSwMsg) 1046 ) u_app_intf ( 1047 .clk_i, 1048 .rst_ni, 1049 1050 .reg_key_data_i (sw_key_data), 1051 .reg_key_len_i (sw_key_len), 1052 1053 .reg_prefix_i (reg_ns_prefix), 1054 1055 .reg_kmac_en_i (reg_kmac_en), 1056 .reg_sha3_mode_i (reg_sha3_mode), 1057 .reg_keccak_strength_i (reg_keccak_strength), 1058 1059 // data from tl_adapter 1060 .sw_valid_i (sw_msg_valid), 1061 .sw_data_i (sw_msg_data), 1062 .sw_mask_i (sw_msg_mask), 1063 .sw_ready_o (sw_msg_ready), 1064 1065 // KeyMgr sideloaded key interface 1066 .keymgr_key_i, 1067 1068 // Application data in / digest out interface 1069 .app_i, 1070 .app_o, 1071 1072 // Secret Key output to KMAC Core 1073 .key_data_o (key_data), 1074 .key_len_o (key_len), 1075 .key_valid_o (key_valid), 1076 1077 // to MSG_FIFO 1078 .kmac_valid_o (mux2fifo_valid), 1079 .kmac_data_o (mux2fifo_data), 1080 .kmac_mask_o (mux2fifo_mask), 1081 .kmac_ready_i (mux2fifo_ready), 1082 1083 // to KMAC Core 1084 .kmac_en_o (app_kmac_en), 1085 1086 // to SHA3 Core 1087 .sha3_prefix_o (ns_prefix), 1088 .sha3_mode_o (app_sha3_mode), 1089 .keccak_strength_o (app_keccak_strength), 1090 1091 // Keccak state from SHA3 core 1092 .keccak_state_valid_i (state_valid), 1093 .keccak_state_i (state), 1094 1095 // to STATE TL Window 1096 .reg_state_valid_o (reg_state_valid), 1097 .reg_state_o (reg_state), 1098 1099 // Configuration: Sideloaded Key 1100 .keymgr_key_en_i (reg2hw.cfg_shadowed.sideload.q), 1101 1102 .absorbed_i (sha3_absorbed), // from SHA3 1103 .absorbed_o (app_absorbed), // to SW 1104 1105 .app_active_o(app_active), 1106 1107 .error_i (sha3_err.valid), 1108 .err_processed_i (err_processed), 1109 1110 .clear_after_error_o (clear_after_error), 1111 1112 // Command interface 1113 .sw_cmd_i (checked_sw_cmd), 1114 .cmd_o (kmac_cmd), 1115 1116 // Status 1117 .entropy_ready_i (entropy_configured), 1118 1119 // LC escalation 1120 .lc_escalate_en_i (lc_escalate_en[3]), 1121 1122 // Error report 1123 .error_o (app_err), 1124 .sparse_fsm_error_o (kmac_app_state_error) 1125 1126 ); 1127 1128 // Message FIFO 1129 kmac_msgfifo #( 1130 .OutWidth (kmac_pkg::MsgWidth), 1131 .MsgDepth (kmac_pkg::MsgFifoDepth), 1132 .EnMasking (EnMasking) 1133 ) u_msgfifo ( 1134 .clk_i, 1135 .rst_ni, 1136 1137 .fifo_valid_i (mux2fifo_valid), 1138 .fifo_data_i (mux2fifo_data), 1139 .fifo_mask_i (mux2fifo_mask), 1140 .fifo_ready_o (mux2fifo_ready), 1141 1142 .msg_valid_o (msgfifo_valid), 1143 .msg_data_o (msgfifo_data[0]), 1144 .msg_strb_o (msgfifo_strb), 1145 .msg_ready_i (msgfifo_ready), 1146 1147 .fifo_empty_o (msgfifo_empty), // intr and status 1148 .fifo_full_o (msgfifo_full), // connected to status only 1149 .fifo_depth_o (msgfifo_depth), 1150 1151 .clear_i (sha3_done), 1152 1153 .process_i (reg2msgfifo_process ), 1154 .process_o (msgfifo2kmac_process), 1155 1156 .err_o (msgfifo_err) 1157 ); 1158 1159 logic [sha3_pkg::StateW-1:0] reg_state_tl [Share]; 1160 always_comb begin 1161 1/1 for (int i = 0 ; i < Share; i++) begin Tests: T1 T2 T3  1162 1/1 reg_state_tl[i] = reg_state_valid ? reg_state[i] : 'b0; Tests: T1 T2 T3  1163 end 1164 end 1165 1166 // State (Digest) reader 1167 kmac_staterd #( 1168 .AddrW (9), // 512B 1169 .EnMasking (EnMasking) 1170 ) u_staterd ( 1171 .clk_i, 1172 .rst_ni, 1173 1174 .tl_i (tl_win_h2d[WinState]), 1175 .tl_o (tl_win_d2h[WinState]), 1176 1177 .state_i (reg_state_tl), 1178 1179 .endian_swap_i (reg2hw.cfg_shadowed.state_endianness.q) 1180 ); 1181 1182 // Error checker 1183 kmac_errchk #( 1184 .EnMasking (EnMasking) 1185 ) u_errchk ( 1186 .clk_i, 1187 .rst_ni, 1188 1189 // Configurations 1190 .cfg_mode_i (reg_sha3_mode ), 1191 .cfg_strength_i(reg_keccak_strength), 1192 1193 .kmac_en_i (reg_kmac_en ), 1194 .cfg_prefix_6B_i(reg_ns_prefix[47:0]), // first 6B of PREFIX 1195 1196 .cfg_en_unsupported_modestrength_i (cfg_en_unsupported_modestrength), 1197 1198 .entropy_ready_pulse_i (entropy_ready), 1199 1200 // SW commands 1201 .sw_cmd_i(sw_cmd), 1202 .sw_cmd_o(checked_sw_cmd), 1203 1204 // Status from KMAC_APP 1205 .app_active_i(app_active), 1206 1207 // Status from SHA3 core 1208 .sha3_absorbed_i(sha3_absorbed ), 1209 .keccak_done_i (sha3_block_processed), 1210 1211 // LC escalation 1212 .lc_escalate_en_i (lc_escalate_en[4]), 1213 1214 .err_processed_i (err_processed), 1215 .clear_after_error_i (clear_after_error), 1216 1217 .error_o (errchecker_err), 1218 .sparse_fsm_error_o (kmac_errchk_state_error) 1219 ); 1220 1221 // Entropy Generator 1222 if (EnMasking == 1) begin : gen_entropy 1223 1224 logic entropy_req, entropy_ack; 1225 logic [edn_pkg::ENDPOINT_BUS_WIDTH-1:0] entropy_data; 1226 logic unused_entropy_fips; 1227 1228 // Synchronize EDN interface 1229 prim_sync_reqack_data #( 1230 .Width(edn_pkg::ENDPOINT_BUS_WIDTH), 1231 .DataSrc2Dst(1'b0), 1232 .DataReg(1'b0) 1233 ) u_prim_sync_reqack_data ( 1234 .clk_src_i (clk_i), 1235 .rst_src_ni(rst_ni), 1236 .clk_dst_i (clk_edn_i), 1237 .rst_dst_ni(rst_edn_ni), 1238 .req_chk_i (1'b1), 1239 .src_req_i (entropy_req), 1240 .src_ack_o (entropy_ack), 1241 .dst_req_o (entropy_o.edn_req), 1242 .dst_ack_i (entropy_i.edn_ack), 1243 .data_i (entropy_i.edn_bus), 1244 .data_o (entropy_data) 1245 ); 1246 1247 // We don't track whether the entropy is pre-FIPS or not inside KMAC. 1248 assign unused_entropy_fips = entropy_i.edn_fips; 1249 1250 kmac_entropy #( 1251 .RndCnstLfsrPerm(RndCnstLfsrPerm), 1252 .RndCnstLfsrSeed(RndCnstLfsrSeed), 1253 .RndCnstBufferLfsrSeed(RndCnstBufferLfsrSeed) 1254 ) u_entropy ( 1255 .clk_i, 1256 .rst_ni, 1257 1258 // EDN interface 1259 .entropy_req_o (entropy_req), 1260 .entropy_ack_i (entropy_ack), 1261 .entropy_data_i(entropy_data), 1262 1263 // Entropy to internal logic (DOM AND) 1264 .rand_valid_o (sha3_rand_valid), 1265 .rand_early_o (sha3_rand_early), 1266 .rand_data_o (sha3_rand_data), 1267 .rand_aux_o (sha3_rand_aux), 1268 .rand_update_i (sha3_rand_update), 1269 .rand_consumed_i (sha3_rand_consumed), 1270 1271 // Status from internal logic 1272 //// KMAC secret block handling indicator 1273 .in_keyblock_i (entropy_in_keyblock), 1274 1275 // Configuration 1276 .mode_i (entropy_mode), 1277 .entropy_ready_i (entropy_ready), 1278 .fast_process_i (entropy_fast_process), 1279 1280 //// Entropy refresh period in clk cycles 1281 .wait_timer_prescaler_i (wait_timer_prescaler), 1282 .wait_timer_limit_i (wait_timer_limit), 1283 1284 //// Message Masking 1285 .msg_mask_en_i (msg_mask_en), 1286 .msg_mask_o (msg_mask), 1287 1288 //// SW update of seed 1289 .seed_update_i (entropy_seed_update), 1290 .seed_data_i (entropy_seed_data), 1291 .entropy_refresh_req_i (entropy_refresh_req), 1292 1293 // Status 1294 .hash_cnt_o (entropy_hash_cnt), 1295 .hash_cnt_clr_i (entropy_hash_clr), 1296 .hash_threshold_i (entropy_hash_threshold), 1297 1298 .entropy_configured_o (entropy_configured), 1299 1300 // LC escalation 1301 .lc_escalate_en_i (lc_escalate_en[5]), 1302 1303 // Error 1304 .err_o (entropy_err), 1305 .sparse_fsm_error_o (kmac_entropy_state_error), 1306 .count_error_o (kmac_entropy_hash_counter_error), 1307 .err_processed_i (err_processed) 1308 ); 1309 end else begin : gen_empty_entropy 1310 // If Masking is not used, no need of entropy. Ignore inputs and config; tie output to 0. 1311 edn_pkg::edn_rsp_t unused_entropy_input; 1312 entropy_mode_e unused_entropy_mode; 1313 logic unused_entropy_fast_process; 1314 1315 0/1 ==> assign unused_entropy_input = entropy_i; 1316 1/1 assign unused_entropy_mode = entropy_mode; Tests: T1 T2 T3  1317 1/1 assign unused_entropy_fast_process = entropy_fast_process; Tests: T1 T2 T3  1318 1319 assign entropy_o = '{default: '0}; 1320 1321 logic unused_sha3_rand_update; 1322 logic unused_sha3_rand_consumed; 1323 assign sha3_rand_valid = 1'b 1; 1324 assign sha3_rand_early = 1'b 1; 1325 assign sha3_rand_data = '0; 1326 assign sha3_rand_aux = '0; 1327 1/1 assign unused_sha3_rand_update = sha3_rand_update; Tests: T1 T2 T3  1328 1/1 assign unused_sha3_rand_consumed = sha3_rand_consumed; Tests: T1 T2 T3  1329 1330 logic unused_seed_update; 1331 logic [31:0] unused_seed_data; 1332 logic [31:0] unused_refresh_period; 1333 logic unused_entropy_refresh_req; 1334 1/1 assign unused_seed_data = entropy_seed_data; Tests: T1 T2 T3  1335 1/1 assign unused_seed_update = entropy_seed_update; Tests: T4 T5 T6  1336 1/1 assign unused_refresh_period = ^{wait_timer_limit, wait_timer_prescaler}; Tests: T1 T2 T3  1337 1/1 assign unused_entropy_refresh_req = entropy_refresh_req; Tests: T21 T6 T9  1338 1339 logic unused_entropy_hash; 1340 1/1 assign unused_entropy_hash = ^{entropy_hash_clr, entropy_hash_threshold}; Tests: T1 T2 T3  1341 assign entropy_hash_cnt = '0; 1342 1343 assign entropy_err = '{valid: 1'b 0, code: ErrNone, info: '0}; 1344 1345 assign kmac_entropy_state_error = 1'b 0; 1346 assign kmac_entropy_hash_counter_error = 1'b 0; 1347 1348 logic [1:0] unused_entropy_status; 1349 1/1 assign unused_entropy_status = entropy_in_keyblock; Tests: T1 T2 T3  1350 1351 // If Masking is off, always entropy configured 1352 assign entropy_configured = prim_mubi_pkg::MuBi4True; 1353 end 1354 1355 // MUBI4 buf 1356 prim_mubi4_sender #( 1357 .AsyncOn (0) 1358 ) u_sha3_done_sender ( 1359 .clk_i, 1360 .rst_ni, 1361 .mubi_i (sha3_done_d), 1362 .mubi_o (sha3_done) 1363 ); 1364 1365 // Register top 1366 logic [NumAlerts-1:0] alert_test, alerts, alerts_q; 1367 1368 logic shadowed_storage_err, shadowed_update_err; 1369 kmac_reg_top u_reg ( 1370 .clk_i, 1371 .rst_ni, 1372 .rst_shadowed_ni, 1373 1374 .tl_i, 1375 .tl_o, 1376 1377 .tl_win_o (tl_win_h2d), 1378 .tl_win_i (tl_win_d2h), 1379 1380 .reg2hw, 1381 .hw2reg, 1382 1383 // SEC_CM: CFG_SHADOWED.CONFIG.SHADOW 1384 .shadowed_storage_err_o (shadowed_storage_err), 1385 .shadowed_update_err_o (shadowed_update_err), 1386 // SEC_CM: BUS.INTEGRITY 1387 .intg_err_o (alert_intg_err) 1388 ); 1389 1390 logic unused_cfg_shadowed_qe; 1391 1/1 assign unused_cfg_shadowed_qe = ^{ Tests: T1 T2 T3  1392 reg2hw.cfg_shadowed.kmac_en.qe , 1393 reg2hw.cfg_shadowed.kstrength.qe , 1394 reg2hw.cfg_shadowed.mode.qe , 1395 reg2hw.cfg_shadowed.msg_endianness.qe , 1396 reg2hw.cfg_shadowed.state_endianness.qe , 1397 reg2hw.cfg_shadowed.sideload.qe , 1398 reg2hw.cfg_shadowed.entropy_mode.qe , 1399 reg2hw.cfg_shadowed.entropy_fast_process.qe , 1400 reg2hw.cfg_shadowed.msg_mask.qe , 1401 reg2hw.cfg_shadowed.en_unsupported_modestrength.qe 1402 }; 1403 1404 // Alerts 1405 1/1 assign alert_test = { Tests: T1 T2 T3  1406 reg2hw.alert_test.fatal_fault_err.q 1407 & reg2hw.alert_test.fatal_fault_err.qe, // [1] 1408 reg2hw.alert_test.recov_operation_err.q 1409 & reg2hw.alert_test.recov_operation_err.qe // [0] 1410 }; 1411 1412 1/1 assign alerts = { Tests: T1 T2 T3  1413 alert_fatal, // Alerts[1] 1414 alert_recov_operation // Alerts[0] 1415 }; 1416 1417 1/1 assign alert_recov_operation = shadowed_update_err; Tests: T1 T2 T3  1418 1419 // The recoverable alert is observable via status register until the KMAC operation is restarted 1420 // by re-writing the Control Register. 1421 logic status_alert_recov_ctrl_update_err; 1422 always_ff @(posedge clk_i or negedge rst_ni) begin 1423 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1424 1/1 status_alert_recov_ctrl_update_err <= 1'b 0; Tests: T1 T2 T3  1425 1/1 end else if (alert_recov_operation) begin Tests: T1 T2 T3  1426 0/1 ==> status_alert_recov_ctrl_update_err <= 1'b 1; 1427 1/1 end else if (err_processed) begin Tests: T1 T2 T3  1428 1/1 status_alert_recov_ctrl_update_err <= 1'b 0; Tests: T11 T19 T20  1429 end MISSING_ELSE 1430 end 1431 1432 1/1 assign hw2reg.status.alert_recov_ctrl_update_err.d = status_alert_recov_ctrl_update_err; Tests: T1 T2 T3  1433 1434 1/1 assign alert_fatal = shadowed_storage_err Tests: T1 T2 T3  1435 | alert_intg_err 1436 | sparse_fsm_error 1437 | counter_error 1438 | control_integrity_error 1439 ; 1440 1441 // Make the fatal alert observable via status register. 1442 // Cannot be reset except the hardware reset 1443 logic status_alert_fatal_fault; 1444 1445 always_ff @(posedge clk_i or negedge rst_ni) begin 1446 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1447 1/1 status_alert_fatal_fault <= 1'b 0; Tests: T1 T2 T3  1448 1/1 end else if (alert_fatal) begin Tests: T1 T2 T3  1449 1/1 status_alert_fatal_fault <= 1'b 1; Tests: T4 T5 T6  1450 end MISSING_ELSE 1451 end 1452 1/1 assign hw2reg.status.alert_fatal_fault.d = status_alert_fatal_fault; Tests: T1 T2 T3  1453 1454 for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx 1455 prim_alert_sender #( 1456 .AsyncOn(AlertAsyncOn[i]), 1457 .IsFatal(i) 1458 ) u_prim_alert_sender ( 1459 .clk_i, 1460 .rst_ni, 1461 .alert_test_i ( alert_test[i] ), 1462 .alert_req_i ( alerts[i] ), 1463 .alert_ack_o ( ), 1464 .alert_state_o ( ), 1465 .alert_rx_i ( alert_rx_i[i] ), 1466 .alert_tx_o ( alert_tx_o[i] ) 1467 ); 1468 end 1469 1470 // Below assumes NumAlerts == 2 1471 `ASSERT_INIT(NumAlerts2_A, NumAlerts == 2) 1472 1473 always_ff @(posedge clk_i or negedge rst_ni) begin 1474 // break up the combinatorial path for local escalation 1475 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1476 1/1 alerts_q[1] <= 1'b0; Tests: T1 T2 T3  1477 1/1 end else if (alerts[1]) begin Tests: T1 T2 T3  1478 // fatal alerts cannot be cleared 1479 1/1 alerts_q[1] <= 1'b1; Tests: T4 T5 T6  1480 end MISSING_ELSE 1481 end 1482 1483 always_ff @(posedge clk_i or negedge rst_ni) begin 1484 // break up the combinatorial path for local escalation 1485 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1486 1/1 alerts_q[0] <= 1'b0; Tests: T1 T2 T3  1487 end else begin 1488 // recoverable alerts can be cleared so just latch the value 1489 1/1 alerts_q[0] <= alerts[0]; Tests: T1 T2 T3  1490 end 1491 end 1492 1493 // Latched recoverable alert[0] is not used. Rather removing above, 1494 // keep alert_q[1:0] and make alert_q[0] unused (lint waive). 1495 logic unused_alerts_q0; 1496 1/1 assign unused_alerts_q0 = alerts_q[0]; Tests: T1 T2 T3  1497 1498 // SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI, FSM.GLOBAL_ESC, FSM.LOCAL_ESC 1499 lc_ctrl_pkg::lc_tx_t alert_to_lc_tx; 1500 1/1 assign alert_to_lc_tx = lc_ctrl_pkg::lc_tx_bool_to_lc_tx(alerts_q[1]); Tests: T1 T2 T3  1501 for (genvar i = 0; i < NumLcSyncCopies; i++) begin : gen_or_alert_lc_sync 1502 6/6 assign lc_escalate_en[i] = lc_ctrl_pkg::lc_tx_or_hi(alert_to_lc_tx, lc_escalate_en_sync[i]); Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%