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

334 335 1/1 assign sys_tpm_cfg = '{ Tests: T1 T2 T3  336 tpm_en: cfg_tpm_en_i, 337 tpm_mode: cfg_tpm_mode_i, 338 hw_reg_dis: cfg_tpm_hw_reg_dis_i, 339 invalid_locality: cfg_tpm_invalid_locality_i, 340 tpm_reg_chk_dis: cfg_tpm_reg_chk_dis_i 341 }; 342 343 tpm_reg_t sys_tpm_reg; 344 tpm_reg_t sys_clk_tpm_reg; 345 346 347 logic [NumLocality-1:0] sys_active_locality; // TPM_ACCESS_x[5] 348 349 1/1 assign sys_tpm_reg = '{ Tests: T1 T2 T3  350 access: sys_access_reg_i, 351 int_enable: sys_int_enable_reg_i, 352 int_vector: sys_int_vector_reg_i, 353 int_status: sys_int_status_reg_i, 354 intf_capacity: sys_intf_capability_reg_i, 355 status: sys_status_reg_i, 356 id: sys_id_reg_i, 357 rid: sys_rid_reg_i 358 }; 359 360 // FIFOs 361 tpm_cmdaddr_t sys_cmdaddr; 362 logic sck_cmdaddr_wvalid, sck_cmdaddr_wready; 363 logic [CmdAddrSize-1:0] sck_cmdaddr_wdata_q, sck_cmdaddr_wdata_d; 364 logic [CmdAddrPtrW-1:0] sys_cmdaddr_rdepth, sck_cmdaddr_wdepth; 365 366 logic [FifoRegSize-1:0] isck_fifoaddr; // latched from sck_cmdaddr_wdata_d 367 logic sck_fifoaddr_latch; 368 // isck_fifoaddr_latch converts sck_fifoaddr_latch by half SPI_CLK period. 369 logic isck_fifoaddr_latch; 370 371 logic isck_fifoaddr_inc; 372 373 // (sys_cmdaddr_rdepth > 0) 374 1/1 assign sys_cmdaddr_notempty_o = |sys_cmdaddr_rdepth; Tests: T1 T2 T3  375 376 // *_wrfifo_busy indicates that the wrfifo is unavailable to write the 377 // payload of a new command. SW must first release the buffer. 378 logic sys_wrfifo_busy, sck_wrfifo_busy; 379 logic sys_wrfifo_release_req, sck_wrfifo_release_req; 380 logic sys_wrfifo_release_ack, sck_wrfifo_release_ack; 381 logic sck_wrfifo_wvalid, sck_wrfifo_wready; 382 logic [NumBits-1:0] sck_wrfifo_wdata; 383 384 // Read FIFO 385 logic sck_rdfifo_rvalid, sck_rdfifo_rready; 386 logic [RdFifoIdxW-1:0] sck_rdfifo_offset; 387 logic sck_rdfifo_full; 388 logic [RdFifoWidth-1:0] sck_rdfifo_rdata; 389 390 logic [RdFifoOffsetW-1:0] sck_rdfifo_idx; 391 logic isck_rd_byte_sent; 392 393 // If NumBytes != 1, then the logic selects a byte from sck_rdfifo_rdata 394 logic [NumBits-1:0] isck_sel_rdata; 395 396 // Assume the NumBytes is power of two 397 `ASSERT_INIT(RdFifoNumBytesPoT_A, 398 (2**RdFifoOffsetW == RdFifoNumBytes) || (RdFifoNumBytes == 1)) 399 `ASSERT_INIT(RdFifoDepthPoT_A, 2**$clog2(RdFifoDepth) == RdFifoDepth) 400 401 // If cmdaddr_shift_en is 1, the logic stacks the incoming MOSI into cmdaddr 402 // register. 403 logic cmdaddr_shift_en; 404 logic [4:0] cmdaddr_bitcnt; 405 406 logic [23:0] addr; // used temporary while shifting the cmd address 407 408 // Write Data Latch Enable: Latch and generate a pulse when a byte is stacked. 409 logic wrdata_shift_en; 410 logic [2:0] wrdata_bitcnt; 411 412 logic [7:0] wrdata_q, wrdata_d; 413 414 // Read FIFO is in inverted SCK domain (clk_out) 415 logic sck_rddata_shift_en; 416 417 // Track whether the read command has been written to the cmdaddr FIFO, and 418 // clear this again either when that read command completes its data phase 419 // or when half of the *next* command's command/address phase completes. 420 // sck_rdfifo_cmd_pending is held steady from the end of the transaction 421 // until that latter clearing point, so the sys_clk domain may sample it and 422 // determine whether RdFIFO data was dropped. 423 logic sck_rdfifo_cmd_pending; 424 425 // Indicate if the received address is FIFO/CRB register. Should start with 426 // D4_xxxx 427 logic is_tpm_reg_d, is_tpm_reg_q; 428 429 // If the received command falls into the return-by-HW registers, then 430 // `is_hw_reg` is set. 431 logic is_hw_reg; 432 hw_reg_idx_e sck_hw_reg_idx, isck_hw_reg_idx; 433 434 logic [31:0] isck_hw_reg_word; 435 logic [7:0] isck_hw_reg_byte; 436 437 // Set this signal when the received address bits are enough, which should 438 // be address[23:2] or bigger. 439 logic check_hw_reg; 440 441 // When the address shifted up to addr[12] (cmdaddr_bitcnt == 5'h 13), the 442 // module can decide if the received address is in the Locality or not. If 443 // it is not in the locality, the logic may return the invalid and discard 444 // the request. However, this check actually happens at cmdaddr_bitcnt of 445 // 5'h1b. 446 logic check_locality; 447 448 // bit[15:12] in the received address is the locality if the address is FIFO 449 // addr. 450 logic [3:0] locality; 451 452 // Indicate the locality is greater than or equal to NumLocality. 453 // with tpm_cfg.invalid_locality, the logic returns FFh if host sends read 454 // requests to unsupported locality. 455 logic invalid_locality; 456 457 458 // The first bit of the command (Command[7]) indicates the command direction. 459 logic latch_cmd_type; 460 cmd_type_e cmd_type; 461 462 // xfer_size: Command[5:0] is the command xfer size. currently the logic 463 // supports up to WrFifoDepth. 464 logic latch_xfer_size; 465 logic [5:0] xfer_size; 466 logic [5:0] xfer_bytes_q, xfer_bytes_d; 467 logic xfer_size_met; 468 469 // Indicating that the Read FIFO has enough data to send to the host. 470 logic enough_payload_in_rdfifo; 471 472 // Output MISO 473 typedef enum logic [2:0] { 474 SelWait = 3'h 0, // 0x00 475 SelStart = 3'h 1, // 0x01 476 SelInvalid = 3'h 2, // 0xFF 477 SelHwReg = 3'h 3, // depends on hw_reg_idx 478 SelRdFifo = 3'h 4 // from RdFifo 479 } tpm_data_sel_e; 480 481 logic sck_p2s_valid; 482 483 logic isck_p2s_valid; 484 logic [7:0] isck_p2s_data; 485 logic isck_p2s_sent; 486 487 tpm_data_sel_e sck_data_sel, isck_data_sel; 488 489 logic isck_miso_en; 490 logic isck_miso; 491 492 1/1 assign miso_en_o = isck_miso_en; Tests: T1 T2 T3  493 1/1 assign miso_o = isck_miso; Tests: T1 T2 T3  494 495 ///////// 496 // CDC // 497 ///////// 498 499 // Includes 2FF sync for sys_tpm_rst_ni, which asserts asynchronously to 500 // sys_clk_i. The synchronizer output feeds logic that determines when to 501 // release the RdFIFO to SW. The posedge_pulse output is used to latch the TPM 502 // configuration and return-by-hw register values for use in the current 503 // command. 504 // The outputs of the edge detector are thus delayed another 2 SYS_CLK cycles 505 // after the prim_rst_sync. The configuration latches into SYS_CLK below, 506 // and those outputs are used on the 24th bit of the SPI clock. So, SYS_CLK 507 // must be at least 1/4 the frequency as the SPI clock. 508 prim_edge_detector #( 509 .Width (1), 510 .ResetValue (1'b 0), 511 .EnSync (1'b 1) 512 ) u_csb_sync_rst ( 513 .clk_i (sys_clk_i), 514 .rst_ni (sys_rst_ni), 515 .d_i (sys_tpm_rst_ni), 516 .q_sync_o (), 517 .q_posedge_pulse_o (sys_csb_asserted_pulse), 518 .q_negedge_pulse_o (sys_csb_deasserted_pulse) 519 ); 520 521 1/1 assign sys_clk_tpm_en = cfg_tpm_en_i; Tests: T1 T2 T3  522 523 // Configuration latched into sys_clk 524 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 525 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  526 1/1 sys_clk_tpm_cfg <= '{default: '0}; Tests: T1 T2 T3  527 1/1 sys_clk_tpm_reg <= '{default: '0}; Tests: T1 T2 T3  528 end else begin 529 1/1 if (sys_csb_asserted_pulse) begin Tests: T1 T2 T3  530 1/1 sys_clk_tpm_cfg <= sys_tpm_cfg; Tests: T1 T3 T4  531 1/1 sys_clk_tpm_reg <= sys_tpm_reg; Tests: T1 T3 T4  532 1/1 for (int unsigned i = 0 ; i < NumLocality ; i++) begin Tests: T1 T3 T4  533 1/1 sys_active_locality[i] <= Tests: T1 T3 T4  534 sys_tpm_reg.access[AccessRegSize*i + ActiveLocalityBitPos]; 535 end 536 end MISSING_ELSE 537 end 538 end 539 540 // data_sel (sck -> isck) 541 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 542 1/1 if (!rst_out_ni) begin Tests: T1 T2 T3  543 1/1 isck_data_sel <= SelWait; Tests: T1 T2 T3  544 end else begin 545 1/1 isck_data_sel <= sck_data_sel; Tests: T3 T4 T5  546 end 547 end 548 549 ////////////// 550 // Datapath // 551 ////////////// 552 553 // command, addr latch 554 always_ff @(posedge clk_in_i or negedge rst_ni) begin 555 1/1 if (!rst_ni) begin Tests: T1 T2 T3  556 1/1 cmdaddr_bitcnt <= 5'h 0; Tests: T1 T2 T3  557 1/1 end else if (cmdaddr_shift_en) begin Tests: T3 T4 T5  558 1/1 cmdaddr_bitcnt <= cmdaddr_bitcnt + 5'h 1; Tests: T3 T4 T5  559 end MISSING_ELSE 560 end 561 562 // Control signals: 563 // latch_cmd_type 564 1/1 assign latch_cmd_type = (cmdaddr_bitcnt == 5'h 0) && (sck_st_q == StIdle); Tests: T1 T2 T3  565 566 1/1 assign check_hw_reg = (cmdaddr_bitcnt == 5'h 1D); Tests: T1 T2 T3  567 568 // sck_fifoaddr_latch & isck_fifoaddr_latch. 569 // 570 // isck_fifoaddr_latch is used to latch `isck_fifoaddr` as the name implies. 571 // The sck_fifoaddr_latch is high at the last beat of the address field as 572 // shown below. 573 // _ _ _ _ _ 574 // SPI_CLK _/ \_/ \_/ \_/ \_/ \_ 575 // ___ ___ ___ ___ ___ 576 // bitcnt X 0 X ..X 1EX 1FX 577 // 578 // But the data is valid second half of the 'h 1F phase. However, the 579 // latching logic latches @ clk_out_i (Inverted SPI_CLK). So it latches at 580 // a cycle earlier. 581 // 582 // | err here 583 // _ _ _ _ _ 584 // iSPI_CLK _/ \_/ \_/ \_/ \_/ \_ 585 // ___ ___ ___ ___ ___ 586 // bitcnt X 0 X ..X 1EX 1FX 587 // 588 // 589 // isck_fifoaddr_latch delays sck_fifoaddr_latch for the logic latches the 590 // address correctly. 591 1/1 assign sck_fifoaddr_latch = (cmdaddr_bitcnt == 5'h 1F); Tests: T1 T2 T3  592 593 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 594 1/1 if (!rst_out_ni) begin Tests: T1 T2 T3  595 1/1 isck_fifoaddr_latch <= 1'b 0; Tests: T1 T2 T3  596 end else begin 597 1/1 isck_fifoaddr_latch <= sck_fifoaddr_latch; Tests: T3 T4 T5  598 end 599 end 600 601 always_ff @(posedge clk_in_i or negedge rst_ni) begin 602 1/1 if (!rst_ni) begin Tests: T1 T2 T3  603 1/1 sck_cmdaddr_wdata_q <= '0; Tests: T1 T2 T3  604 1/1 end else if (cmdaddr_shift_en) begin Tests: T3 T4 T5  605 1/1 sck_cmdaddr_wdata_q <= sck_cmdaddr_wdata_d; Tests: T3 T4 T5  606 end MISSING_ELSE 607 end 608 609 always_comb begin 610 1/1 if (cmdaddr_shift_en) begin Tests: T1 T2 T3  611 1/1 sck_cmdaddr_wdata_d = {sck_cmdaddr_wdata_q[0+:CmdAddrSize-1], mosi_i}; Tests: T1 T2 T3  612 end else begin 613 1/1 sck_cmdaddr_wdata_d = sck_cmdaddr_wdata_q; Tests: T3 T4 T5  614 end 615 end 616 617 // fifoaddr latch 618 // clk_out (iSCK) 619 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 620 1/1 if (!rst_out_ni) begin Tests: T1 T2 T3  621 1/1 isck_fifoaddr <= '0; Tests: T1 T2 T3  622 1/1 end else if (isck_fifoaddr_latch) begin Tests: T3 T4 T5  623 // Shall assert when sck_st_q moves away from StAddr 624 1/1 isck_fifoaddr <= sck_cmdaddr_wdata_q[FifoRegSize-1:0]; Tests: T3 T4 T5  625 1/1 end else if (isck_fifoaddr_inc) begin Tests: T3 T4 T5  626 1/1 isck_fifoaddr <= isck_fifoaddr + 1'b 1; Tests: T3 T4 T25  627 end MISSING_ELSE 628 end 629 `ASSERT(SckFifoAddrLatchCondition_A, 630 sck_fifoaddr_latch |=> 631 $past(sck_st_q) == StAddr && (sck_st_q inside {StWait, StStartByte} 632 || invalid_locality), 633 clk_in_i, !rst_ni) 634 635 // only fifoaddr[1:0] is used in this version. 636 logic unused_fifoaddr; 637 1/1 assign unused_fifoaddr = ^isck_fifoaddr[FifoRegSize-1:2]; Tests: T1 T2 T3  638 639 // fifoaddr_inc @ iSCK :: SCK is not useful at all. SW can compute the 640 // address with the xfer_size and input address in CmdAddr buffer. 641 // 642 // Increase the address only when HwReg is selected (for now) 643 // Other cases have no usecase as of now. 644 1/1 assign isck_fifoaddr_inc = isck_p2s_sent && (isck_data_sel == SelHwReg); Tests: T1 T2 T3  645 646 // Write Data Latch 647 always_ff @(posedge clk_in_i or negedge rst_ni) begin 648 1/1 if (!rst_ni) begin Tests: T1 T2 T3  649 1/1 wrdata_bitcnt <= '0; Tests: T1 T2 T3  650 1/1 end else if (wrdata_shift_en) begin Tests: T3 T4 T5  651 1/1 wrdata_bitcnt <= wrdata_bitcnt + 3'h 1; Tests: T5 T9 T26  652 end MISSING_ELSE 653 end 654 655 1/1 assign sck_wrfifo_wvalid = (wrdata_bitcnt == 3'h 7); Tests: T1 T2 T3  656 657 always_ff @(posedge clk_in_i or negedge rst_ni) begin 658 1/1 if (!rst_ni) begin Tests: T1 T2 T3  659 1/1 wrdata_q <= 8'h 0; Tests: T1 T2 T3  660 1/1 end else if (wrdata_shift_en) begin Tests: T3 T4 T5  661 1/1 wrdata_q <= wrdata_d; Tests: T5 T9 T26  662 end MISSING_ELSE 663 end 664 665 1/1 assign wrdata_d = {wrdata_q[6:0], mosi_i}; Tests: T1 T2 T3  666 667 1/1 assign sck_wrfifo_wdata = wrdata_d; Tests: T1 T2 T3  668 669 // Pass control of the WrFIFO from hardware to software when write commands 670 // are written into the CmdAddrFIFO, and release it back from software to 671 // hardware when software issues the instruction. 672 prim_flop_2sync #( 673 .Width (1) 674 ) u_wrfifo_busy_sync ( 675 .clk_i (sys_clk_i), 676 .rst_ni (sys_rst_ni), 677 .d_i (sck_wrfifo_busy), 678 .q_o (sys_wrfifo_busy) 679 ); 680 1/1 assign sys_wrfifo_pending_o = sys_wrfifo_busy; Tests: T1 T2 T3  681 682 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 683 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  684 1/1 sys_wrfifo_release_req <= 1'b0; Tests: T1 T2 T3  685 1/1 end else if (sys_wrfifo_release_i) begin Tests: T1 T2 T3  686 1/1 sys_wrfifo_release_req <= 1'b1; Tests: T5 T9 T26  687 1/1 end else if (sys_wrfifo_release_ack) begin Tests: T1 T2 T3  688 1/1 sys_wrfifo_release_req <= 1'b0; Tests: T5 T9 T26  689 end MISSING_ELSE 690 end 691 692 prim_sync_reqack u_wrfifo_release_reqack ( 693 .clk_src_i (sys_clk_i), 694 .rst_src_ni (sys_rst_ni), 695 .clk_dst_i (clk_in_i), 696 .rst_dst_ni (sys_rst_ni), 697 698 .req_chk_i (1'b1), 699 700 .src_req_i (sys_wrfifo_release_req), 701 .src_ack_o (sys_wrfifo_release_ack), 702 .dst_req_o (sck_wrfifo_release_req), 703 .dst_ack_i (sck_wrfifo_release_ack) 704 ); 705 706 1/1 assign sck_wrfifo_release_ack = sck_wrfifo_release_req; Tests: T1 T2 T3  707 708 always_ff @(posedge clk_in_i or negedge sys_rst_ni) begin 709 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  710 1/1 sck_wrfifo_busy <= 1'b0; Tests: T1 T2 T3  711 1/1 end else if (sck_cmdaddr_wvalid && cmd_type == Write) begin Tests: T3 T4 T5  712 1/1 sck_wrfifo_busy <= 1'b1; Tests: T5 T9 T26  713 1/1 end else if (sck_wrfifo_release_req) begin Tests: T3 T4 T5  714 1/1 sck_wrfifo_busy <= 1'b0; Tests: T5 T9 T26  715 end MISSING_ELSE 716 end 717 718 // Address: This is a comb logic that shows correct address value when the 719 // address is compared with other logics 720 always_comb begin 721 1/1 addr = 24'h 00_0000; Tests: T1 T2 T3  722 1/1 unique case (1'b 1) Tests: T1 T2 T3  723 // locality in the TPM transaction is in addr[15:12]. 724 // check_locality is asserted at the 24th beat. 725 // Look at the assertion LocalityLatchCondition_A 726 check_locality: begin 727 1/1 addr = {sck_cmdaddr_wdata_d[19:0], 4'h 0}; Tests: T3 T4 T5  728 end 729 730 check_hw_reg: begin 731 // In Return-by-HW Reg check stage, the lower 2 bits were not arrived. 732 // Look at the assertion HwRegCondition_A 733 1/1 addr = {sck_cmdaddr_wdata_d[21:0], 2'b 00}; Tests: T3 T4 T5  734 end 735 736 default: addr = 24'h 00_0000; 737 endcase 738 end 739 740 // When enough address bits arrive, check if the address is for FIFO/CRB. 741 // If the checker is turned off, `is_tpm_reg` becomes 1 regardless of addr. 742 always_comb begin 743 1/1 is_tpm_reg_d = is_tpm_reg_q; Tests: T1 T2 T3  744 1/1 if (check_locality && Tests: T1 T2 T3  745 (sys_clk_tpm_cfg.tpm_reg_chk_dis || (addr[23:16] == TpmAddr))) begin 746 1/1 is_tpm_reg_d = 1'b1; Tests: T3 T4 T5  747 end MISSING_ELSE 748 end 749 750 always_ff @(posedge clk_in_i or negedge rst_ni) begin 751 1/1 if (!rst_ni) begin Tests: T1 T2 T3  752 1/1 is_tpm_reg_q <= 1'b 0; Tests: T1 T2 T3  753 end else begin 754 1/1 is_tpm_reg_q <= is_tpm_reg_d; Tests: T3 T4 T5  755 end 756 end 757 758 // Return-by-HW register check 759 logic is_hw_reg_d; 760 hw_reg_idx_e sck_hw_reg_idx_d; 761 762 always_ff @(posedge clk_in_i or negedge rst_ni) begin 763 1/1 if (!rst_ni) begin Tests: T1 T2 T3  764 1/1 is_hw_reg <= 1'b 0; Tests: T1 T2 T3  765 1/1 sck_hw_reg_idx <= RegAccess; Tests: T1 T2 T3  766 1/1 end else if (!sys_clk_tpm_cfg.tpm_mode && check_hw_reg && (cmd_type == Read) Tests: T3 T4 T5  767 && is_tpm_reg_q && !invalid_locality && !sys_clk_tpm_cfg.hw_reg_dis) begin 768 // HW register is set only when the following conditions are met: 769 // 770 // 1. TPM is in FIFO mode 771 // 2. The command received is a Read command. 772 // 3. Is TPM register (starting with 0xD4_XXXX) or tpm_reg_chk_dis is set 773 // 4. Received locality is in the range of supported Locality. 774 1/1 is_hw_reg <= is_hw_reg_d; Tests: T3 T4 T25  775 1/1 sck_hw_reg_idx <= sck_hw_reg_idx_d; Tests: T3 T4 T25  776 end // if check_hw_reg MISSING_ELSE 777 end 778 779 always_comb begin 780 1/1 is_hw_reg_d = 1'b 0; Tests: T1 T2 T3  781 1/1 sck_hw_reg_idx_d = hw_reg_idx_e'(0); Tests: T1 T2 T3  782 // check_hw_reg asserts when cmdaddr_bitcnt is 29. 783 1/1 for (int i = 0 ; i < NumHwReg; i ++) begin Tests: T1 T2 T3  784 1/1 if (TpmReturnByHwAddr[i][11:2] == addr[11:2]) begin Tests: T1 T2 T3  785 1/1 is_hw_reg_d = 1'b 1; Tests: T1 T2 T3  786 1/1 sck_hw_reg_idx_d = hw_reg_idx_e'(i); Tests: T1 T2 T3  787 end MISSING_ELSE 788 end // for 789 end 790 791 // hw_reg_idx (sck -> isck) 792 // Remember that the logic chooses only one HwReg at a transaction. 793 // It does not send continuously even the transfer size is greater than the 794 // word boundary. 795 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 796 2/2 if (!rst_out_ni) isck_hw_reg_idx <= RegAccess; Tests: T1 T2 T3  | T1 T2 T3  797 1/1 else isck_hw_reg_idx <= sck_hw_reg_idx; Tests: T3 T4 T5  798 end 799 800 // locality store 801 always_ff @(posedge clk_in_i or negedge rst_ni) begin 802 1/1 if (!rst_ni) begin Tests: T1 T2 T3  803 1/1 locality <= '0; Tests: T1 T2 T3  804 1/1 invalid_locality <= 1'b 0; Tests: T1 T2 T3  805 1/1 end else if (check_locality && is_tpm_reg_d) begin Tests: T3 T4 T5  806 1/1 locality <= addr[15:12]; Tests: T3 T4 T5  807 1/1 invalid_locality <= (addr[15:12] < 4'(NumLocality)) ? 1'b 0: 1'b 1; Tests: T3 T4 T5  808 end MISSING_ELSE 809 end 810 811 // cmd_type 812 always_ff @(posedge clk_in_i or negedge rst_ni) begin 813 1/1 if (!rst_ni) begin Tests: T1 T2 T3  814 1/1 cmd_type <= Write; Tests: T1 T2 T3  815 1/1 end else if (latch_cmd_type) begin Tests: T3 T4 T5  816 // latch at the very first SCK edge 817 1/1 cmd_type <= cmd_type_e'(sck_cmdaddr_wdata_d[0]); Tests: T3 T4 T5  818 end MISSING_ELSE 819 end 820 821 // xfer_size 822 always_ff @(posedge clk_in_i or negedge rst_ni) begin 823 1/1 if (!rst_ni) begin Tests: T1 T2 T3  824 1/1 xfer_size <= 6'h 0; Tests: T1 T2 T3  825 1/1 end else if (latch_xfer_size) begin Tests: T3 T4 T5  826 1/1 xfer_size <= sck_cmdaddr_wdata_d[5:0]; Tests: T3 T4 T5  827 end MISSING_ELSE 828 end 829 830 // Xfer size count 831 always_ff @(posedge clk_in_i or negedge rst_ni) begin 832 1/1 if (!rst_ni) begin Tests: T1 T2 T3  833 1/1 xfer_bytes_q <= '0; Tests: T1 T2 T3  834 1/1 end else if ((isck_p2s_sent && sck_rddata_shift_en) || Tests: T3 T4 T5  835 (sck_wrfifo_wvalid && wrdata_shift_en)) begin 836 1/1 xfer_bytes_q <= xfer_bytes_d; Tests: T5 T9 T26  837 end MISSING_ELSE 838 end 839 1/1 assign xfer_bytes_d = xfer_bytes_q + 6'h 1; Tests: T1 T2 T3  840 1/1 assign xfer_size_met = xfer_bytes_q == xfer_size; Tests: T1 T2 T3  841 842 // The sys_clk domain signals the SPI domain when there is enough data in 843 // the RdFIFO buffer for the current command. The expected transfer size 844 // resets to a value greater than a command could possibly request whenever 845 // a new transaction begins. It then adjusts to the real value once the 846 // cmdaddr FIFO is read, to pass the command from hardware to software. 847 logic [RdFifoPtrW-1:0] sys_rdfifo_wdepth; 848 logic [5:0] sys_xfer_size; 849 logic sys_enough_payload_in_rdfifo; 850 851 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 852 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  853 1/1 sys_rdfifo_wdepth <= '0; Tests: T1 T2 T3  854 1/1 end else if (sys_csb_asserted_pulse) begin Tests: T1 T2 T3  855 1/1 sys_rdfifo_wdepth <= '0; Tests: T1 T3 T4  856 1/1 end else if (sys_rdfifo_wvalid_i & sys_rdfifo_wready_o) begin Tests: T1 T2 T3  857 1/1 sys_rdfifo_wdepth <= sys_rdfifo_wdepth + 1; Tests: T5 T9 T26  858 end MISSING_ELSE 859 end 860 861 // xfer_size is 0 based. FIFO depth is 1 based. GTE -> Greater than 862 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 863 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  864 1/1 sys_xfer_size <= '1; Tests: T1 T2 T3  865 1/1 end else if (sys_csb_asserted_pulse) begin Tests: T1 T2 T3  866 1/1 sys_xfer_size <= '1; Tests: T1 T3 T4  867 1/1 end else if (sys_cmdaddr_rvalid_o & sys_cmdaddr_rready_i) begin Tests: T1 T2 T3  868 1/1 sys_xfer_size <= sys_cmdaddr.xfer_size_minus_one; Tests: T5 T9 T26  869 end MISSING_ELSE 870 end 871 872 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 873 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  874 1/1 sys_enough_payload_in_rdfifo <= 1'b0; Tests: T1 T2 T3  875 end else begin 876 1/1 sys_enough_payload_in_rdfifo <= Tests: T1 T2 T3  877 (7'({sys_rdfifo_wdepth, RdFifoBytesW'(0)}) > {1'b 0, sys_xfer_size}); 878 end 879 end 880 881 prim_flop_2sync #( 882 .Width (1) 883 ) u_rdfifo_ready ( 884 .clk_i (clk_in_i), 885 .rst_ni, 886 .d_i (sys_enough_payload_in_rdfifo), 887 .q_o (enough_payload_in_rdfifo) 888 ); 889 890 // Output data mux 891 `ASSERT_KNOWN(DataSelKnown_A, isck_data_sel, clk_out_i, !rst_out_ni) 892 always_comb begin 893 1/1 isck_p2s_data = 8'h 00; Tests: T1 T2 T3  894 895 1/1 unique case (isck_data_sel) Tests: T1 T2 T3  896 SelWait: begin 897 1/1 isck_p2s_data = 8'h 00; Tests: T1 T2 T3  898 end 899 900 SelStart: begin 901 1/1 isck_p2s_data = 8'h 01; Tests: T3 T4 T5  902 end 903 904 SelInvalid: begin 905 1/1 isck_p2s_data = 8'h FF; Tests: T3 T27 T29  906 end 907 908 SelHwReg: begin 909 1/1 isck_p2s_data = isck_hw_reg_byte; Tests: T3 T4 T25  910 end 911 912 SelRdFifo: begin 913 1/1 isck_p2s_data = isck_sel_rdata; Tests: T5 T9 T26  914 end 915 916 default: begin 917 isck_p2s_data = 8'h 00; 918 end 919 endcase 920 end 921 922 // HW REG mux 923 prim_slicer #( 924 .InW (32), 925 .OutW (8), 926 .IndexW (2) 927 ) u_hw_reg_slice ( 928 .sel_i (isck_fifoaddr[1:0]), 929 .data_i (isck_hw_reg_word), 930 .data_o (isck_hw_reg_byte) 931 ); 932 933 `ASSERT_KNOWN(HwRegIdxKnown_A, isck_hw_reg_idx, clk_out_i, !rst_out_ni) 934 always_comb begin : hw_reg_mux 935 1/1 isck_hw_reg_word = 32'h FFFF_FFFF; Tests: T1 T2 T3  936 937 1/1 unique case (isck_hw_reg_idx) Tests: T1 T2 T3  938 RegAccess: begin 939 1/1 for (int unsigned i = 0 ; i < NumLocality ; i++) begin Tests: T1 T2 T3  940 1/1 if (!invalid_locality && (4'(i) == locality)) begin Tests: T1 T2 T3  941 1/1 isck_hw_reg_word = { {(32-AccessRegSize){1'b1}}, Tests: T1 T2 T3  942 sys_clk_tpm_reg.access[AccessRegSize*i+:AccessRegSize]}; 943 end MISSING_ELSE 944 end 945 end 946 947 RegIntEn: begin 948 1/1 isck_hw_reg_word = sys_clk_tpm_reg.int_enable; Tests: T1 T2 T3  949 end 950 951 RegIntVect: begin 952 1/1 isck_hw_reg_word = {24'h FFFFFF, sys_clk_tpm_reg.int_vector}; Tests: T1 T2 T3  953 end 954 955 RegIntSts: begin 956 1/1 isck_hw_reg_word = sys_clk_tpm_reg.int_status; Tests: T1 T2 T3  957 end 958 959 RegIntfCap: begin 960 1/1 isck_hw_reg_word = sys_clk_tpm_reg.intf_capacity; Tests: T1 T2 T3  961 end 962 963 RegSts: begin 964 // Check locality to return FFh or correct value 965 1/1 if (!invalid_locality && sys_active_locality[locality[2:0]]) begin Tests: T1 T2 T3  966 // return data 967 1/1 isck_hw_reg_word = sys_clk_tpm_reg.status; Tests: T1 T2 T3  968 end else begin 969 1/1 isck_hw_reg_word = 32'h FFFF_FFFF; Tests: T1 T2 T3  970 end 971 end 972 973 RegHashStart: begin 974 1/1 isck_hw_reg_word = 32'h FFFF_FFFF; Tests: T1 T2 T3  975 end 976 977 RegId: begin 978 1/1 isck_hw_reg_word = sys_clk_tpm_reg.id; Tests: T1 T2 T3  979 end 980 981 RegRid: begin 982 1/1 isck_hw_reg_word = {24'h FFFFFF, sys_clk_tpm_reg.rid}; Tests: T1 T2 T3  983 end 984 985 default: begin 986 isck_hw_reg_word = 32'h FFFF_FFFF; 987 end 988 endcase 989 end : hw_reg_mux 990 991 // Parallel to Serial (Output) 992 // 993 // Parallel to Serial datapath in the TPM submodule differs from spi_p2s 994 // module used in the SPI_DEVICE. 995 // 996 // The logic in the TPM always works as byte granularity. The logic loops 997 // 8 stage. Each stage sends the bit of the input p2s_data from 7 to 0. 998 // Even the p2s_valid is asserted not in the byte granularity (e.g: 999 // asserted when bit position is 4), the logic directly sends the 1000 // p2s_data[4] and turns on the output enable signal. 1001 // 1002 // The single IO characteristic of the TPM submodule simplifies the logic 1003 // above. 1004 // 1005 // The p2s logic does not have the problem that spi_fwmode has. As SPI TPM 1006 // does not support Mode 3, there's no case that the CSb de-asserted 1007 // without the 8th negedge of SCK. So, the logic asserts the FIFO pop 1008 // signal (`rready`) at the 8th beat. 1009 logic [2:0] isck_p2s_bitcnt; // loop from 7 to 0 1010 1011 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 1012 1/1 if (!rst_out_ni) begin Tests: T1 T2 T3  1013 1/1 isck_p2s_bitcnt <= 3'h 7; Tests: T1 T2 T3  1014 end else begin 1015 1/1 isck_p2s_bitcnt <= isck_p2s_bitcnt - 1'b 1; Tests: T3 T4 T5  1016 end 1017 end 1018 1019 // p2s_valid & p2s_sent & p2s_data 1020 // ~|isck_p2s_bitcnt 1021 1/1 assign isck_p2s_sent = isck_p2s_valid && (isck_p2s_bitcnt == '0); Tests: T1 T2 T3  1022 1023 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 1024 2/2 if (!rst_out_ni) isck_p2s_valid <= 1'b 0; Tests: T1 T2 T3  | T1 T2 T3  1025 1/1 else isck_p2s_valid <= sck_p2s_valid; Tests: T3 T4 T5  1026 end 1027 1028 // Decided to implement 8-to-1 mux rather than conventional shift out for 1029 // Parallel-to-Serial. It is to support sending StartByte in StAddr phase. 1030 // This logic affects the timing. If the logic cannot meet the timing 1031 // requirement, the FSM must not send Start Byte at the last byte of the 1032 // address phase and change the logic to shift out logic. 1033 // 1034 // The datapath can be reduced to use 3-to-1 mux. The condition of sending 1035 // Start/Wait bit is determined at the addr[2] beat. It means, the MISO data 1036 // comes from: 1037 // 1038 // - registered_data[7] 1039 // - input p2s_data[7] 1040 // - input p2s_data[2] 1041 // 1042 // The logic, however, introduces more limitation and gains little benefit. 1043 // The logic depth is just one depth less than the original implementation. 1044 1/1 assign isck_miso = isck_p2s_data[isck_p2s_bitcnt]; Tests: T1 T2 T3  1045 1/1 assign isck_miso_en = isck_p2s_valid; Tests: T1 T2 T3  1046 1047 1048 // Read FIFO data selection and FIFO ready 1049 1/1 assign isck_rd_byte_sent = isck_p2s_sent && (isck_data_sel == SelRdFifo); Tests: T1 T2 T3  1050 // Select RdFIFO RDATA 1051 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin 1052 1/1 if (!rst_out_ni) begin Tests: T1 T2 T3  1053 1/1 isck_sel_rdata <= '0; Tests: T1 T2 T3  1054 end else begin 1055 1/1 isck_sel_rdata <= sck_rdfifo_rdata[NumBits*sck_rdfifo_idx+:NumBits]; Tests: T3 T4 T5  1056 end 1057 end 1058 1059 // Index increases happen on the same clock as the FIFO, so both the wider 1060 // data output and the selection index are prepared on the sampling edge, so 1061 // the particular output byte can be sampled and latched on the shifting 1062 // edge. isck_p2s_bitcnt selects the bit within that byte. 1063 always_ff @(posedge clk_in_i or negedge rst_ni) begin 1064 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1065 1/1 sck_rdfifo_idx <= '0; Tests: T1 T2 T3  1066 1/1 end else if (isck_rd_byte_sent) begin Tests: T3 T4 T5  1067 1/1 sck_rdfifo_idx <= sck_rdfifo_idx + 1'b 1; Tests: T5 T9 T26  1068 end MISSING_ELSE 1069 end 1070 1071 // Only when sck_rdfifo_idx reaches the end byte, pop the FIFO entry. 1072 // The isck_p2s_bitcnt of 1 is used to accommodate the SRAM latency. 1073 1/1 assign sck_rdfifo_rready = (&sck_rdfifo_idx) && (isck_data_sel == SelRdFifo) && Tests: T1 T2 T3  1074 sck_p2s_valid && (isck_p2s_bitcnt == 1); 1075 1076 /////////////////// 1077 // State Machine // 1078 /////////////////// 1079 1080 // Inputs 1081 // - CFG: (tpm_en, tpm_hw_reg_dis, tpm_invalid_locality) 1082 // - is_hw_reg 1083 // 1084 // Outputs 1085 // - latch_cmd_type 1086 // - latch_xfer_size 1087 // - latch_locality 1088 // - check_hw_reg 1089 // - cmdaddr_shift_en 1090 // - wrdata_shift_en 1091 // - p2s_valid 1092 // - sck_data_sel 1093 1094 always_ff @(posedge clk_in_i or negedge rst_ni) begin 1095 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1096 1/1 sck_st_q <= StIdle; Tests: T1 T2 T3  1097 end else begin 1098 1/1 sck_st_q <= sck_st_d; Tests: T3 T4 T5  1099 end 1100 end 1101 1102 // Notes on synchronizing between the SPI clock and SYS clock domains: 1103 // Read process 1104 // 0. RdFIFO is held in reset. It must be empty and can't be written yet. 1105 // 1. HW waits for SW to empty the command FIFO. 1106 // 2. HW writes the read command to the command FIFO. This should happen 1107 // basically instantly for software (relative to the command FIFO 1108 // emptying). 1109 // 4. Software reads the command FIFO to lift the RdFIFO reset. This gate 1110 // prevents SW from writing stale data. 1111 // 5. HW waits for the RdFIFO to have enough data. 1112 // 6. HW completes the command. 1113 // 7. HW puts the RdFIFO back in reset once CSB de-asserts. 1114 // 1115 // Write process 1116 // 1. HW waits for the command FIFO to be empty and for the payload buffer 1117 // to be released. 1118 // 2. HW proceeds past wait states until just before the last posedge for 1119 // the last bit specified by the command's byte count (xfer_size_met). 1120 // 3. HW writes the command to the command FIFO on that last posedge. The 1121 // SRAM is also written here for the payload. 1122 always_comb begin : next_state 1123 1/1 sck_st_d = sck_st_q; Tests: T1 T2 T3  1124 1125 // Default output values 1126 1/1 latch_xfer_size = 1'b 0; Tests: T1 T2 T3  1127 1/1 check_locality = 1'b 0; Tests: T1 T2 T3  1128 1129 1/1 cmdaddr_shift_en = 1'b 0; Tests: T1 T2 T3  1130 1/1 wrdata_shift_en = 1'b 0; Tests: T1 T2 T3  1131 1/1 sck_rddata_shift_en = 1'b 0; Tests: T1 T2 T3  1132 1133 1/1 sck_p2s_valid = 1'b 0; Tests: T1 T2 T3  1134 1/1 sck_data_sel = SelWait; Tests: T1 T2 T3  1135 1136 // Upload commands when HW needs SW returning data. 1137 // 1138 // if host issues to invalid locality or return-by-HW registers, TPM HW 1139 // does not push the command and address to FIFO. 1140 1/1 sck_cmdaddr_wvalid = 1'b 0; Tests: T1 T2 T3  1141 1142 1/1 unique case (sck_st_q) Tests: T1 T2 T3  1143 StIdle: begin 1144 1/1 cmdaddr_shift_en = 1'b 1; Tests: T1 T2 T3  1145 1146 1/1 if (cmdaddr_bitcnt == 5'h 7) begin Tests: T1 T2 T3  1147 1/1 if (sys_clk_tpm_en) begin Tests: T3 T4 T5  1148 1/1 sck_st_d = StAddr; Tests: T3 T4 T5  1149 1150 1/1 latch_xfer_size = 1'b 1; Tests: T3 T4 T5  1151 end else begin 1152 // Stop processing and move to End state. 1153 // sys_clk_tpm_cfg.tpm_en cannot be compared right after reset. Due 1154 // to the absent of the SCK, the configuration cannot be 1155 // synchronized into SCK domain at the first 3 clock cycle. 1156 // So, the enable signal is checked when the state is about to 1157 // move to StAddr. 1158 0/1 ==> sck_st_d = StEnd; 1159 end 1160 end // cmdaddr_bitcnt == 5'h 7 MISSING_ELSE 1161 end // StIdle 1162 1163 StAddr: begin 1164 // NOTE: The coding style in this state is ugly. How can we improve? 1165 1/1 cmdaddr_shift_en = 1'b 1; Tests: T3 T4 T5  1166 1167 1/1 if (cmdaddr_bitcnt >= 5'h 18) begin Tests: T3 T4 T5  1168 // Send Wait byte [18h:1Fh] 1169 1/1 sck_p2s_valid = 1'b 1; Tests: T3 T4 T5  1170 1/1 sck_data_sel = SelWait; Tests: T3 T4 T5  1171 end MISSING_ELSE 1172 1173 // Latch locality 1174 1/1 if (cmdaddr_bitcnt == 5'h 1B) begin Tests: T3 T4 T5  1175 1/1 check_locality = 1'b 1; Tests: T3 T4 T5  1176 end MISSING_ELSE 1177 1178 // Next state: if is_tpm_reg 1 && !cfg_hw_reg_dis 1179 1/1 if (cmdaddr_bitcnt == 5'h 1F && cmd_type == Read) begin Tests: T3 T4 T5  1180 1/1 if (!is_tpm_reg_q || sys_clk_tpm_cfg.tpm_mode) begin Tests: T3 T4 T5  1181 // If out of TPM register (not staring with 0xD4_XXXX) or 1182 // TPM mode is CRB, always processed by SW 1183 1/1 sck_st_d = StWait; Tests: T5 T9 T26  1184 1185 // Only write the command if the FIFO is empty, else back-to-back 1186 // commands may cause ambiguity about which command is getting 1187 // a response. 1188 1/1 if (sck_cmdaddr_wdepth == '0) begin Tests: T5 T9 T26  1189 1/1 sck_cmdaddr_wvalid = 1'b 1; Tests: T5 T9 T26  1190 end MISSING_ELSE 1191 1/1 end else if (is_hw_reg) begin Tests: T3 T4 T25  1192 // If read command and HW REG, then return by HW 1193 // is_hw_reg contains (is_tpm_reg_q && (locality < NumLocality)) 1194 1/1 sck_st_d = StStartByte; Tests: T3 T4 T25  1195 1/1 end else if (invalid_locality && sys_clk_tpm_cfg.invalid_locality) begin Tests: T3 T27 T29  1196 // The read request is out of supported Localities. 1197 // Return FFh 1198 1/1 sck_st_d = StInvalid; Tests: T3 T27 T29  1199 end else begin 1200 // Other read command sends to Wait, till SW response 1201 1/1 sck_st_d = StWait; Tests: T44 T47 T49  1202 1203 // Only write the command if the FIFO is empty, else back-to-back 1204 // commands may cause ambiguity about which command is getting 1205 // a response. 1206 1/1 if (sck_cmdaddr_wdepth == '0) begin Tests: T44 T47 T49  1207 1/1 sck_cmdaddr_wvalid = 1'b 1; Tests: T44 T47 T49  1208 end MISSING_ELSE 1209 end 1210 end // cmdaddr_bitcnt == 5'h 1F MISSING_ELSE 1211 1212 1/1 if (cmdaddr_bitcnt == 5'h 1F && cmd_type == Write) begin Tests: T3 T4 T5  1213 1/1 if (!sck_wrfifo_busy && ~|sck_cmdaddr_wdepth) begin Tests: T5 T9 T26  1214 // Write command and FIFO is empty. Ready to push 1215 1/1 sck_st_d = StStartByte; Tests: T5 T9 T26  1216 end else begin 1217 // FIFO is not empty. Move to StWait and waits for the empty write 1218 // fifo. 1219 1/1 sck_st_d = StWait; Tests: T9 T44 T47  1220 end 1221 end // cmd_type == Write MISSING_ELSE 1222 end // StAddr 1223 1224 StWait: begin 1225 1/1 sck_p2s_valid = 1'b 1; Tests: T5 T9 T26  1226 1/1 sck_data_sel = SelWait; Tests: T5 T9 T26  1227 1228 // Write the Read command if it hasn't been yet. 1229 1/1 if ((cmd_type == Read) && !sck_rdfifo_cmd_pending && ~|sck_cmdaddr_wdepth) begin Tests: T5 T9 T26  1230 1/1 sck_cmdaddr_wvalid = 1'b1; Tests: T9 T44 T47  1231 end MISSING_ELSE 1232 1233 // at every LSB of a byte, check the next state condition 1234 1/1 if (isck_p2s_sent && Tests: T5 T9 T26  1235 (((cmd_type == Read) && enough_payload_in_rdfifo) || 1236 ((cmd_type == Write) && !sck_wrfifo_busy && ~|sck_cmdaddr_wdepth))) begin 1237 1/1 sck_st_d = StStartByte; Tests: T5 T9 T26  1238 end MISSING_ELSE 1239 end // StWait 1240 1241 StStartByte: begin 1242 1/1 sck_p2s_valid = 1'b 1; Tests: T3 T4 T5  1243 1/1 sck_data_sel = SelStart; Tests: T3 T4 T5  1244 1245 1/1 if (isck_p2s_sent) begin Tests: T3 T4 T5  1246 // Must move to next state as StartByte is a byte 1247 1/1 if ((cmd_type == Read) && is_hw_reg) begin Tests: T3 T4 T5  1248 1/1 sck_st_d = StReadHwReg; Tests: T3 T4 T25  1249 1/1 end else if (cmd_type == Read) begin Tests: T5 T9 T26  1250 1/1 sck_st_d = StReadFifo; Tests: T5 T9 T26  1251 1/1 end else if (cmd_type == Write) begin Tests: T5 T9 T26  1252 1/1 sck_st_d = StWrite; Tests: T5 T9 T26  1253 end ==> MISSING_ELSE 1254 end MISSING_ELSE 1255 end // StStartByte 1256 1257 StReadFifo: begin 1258 1/1 sck_rddata_shift_en = 1'b 1; Tests: T5 T9 T26  1259 1260 1/1 sck_p2s_valid = 1'b 1; Tests: T5 T9 T26  1261 1/1 sck_data_sel = SelRdFifo; Tests: T5 T9 T26  1262 1263 1/1 if (isck_p2s_sent && xfer_size_met) begin Tests: T5 T9 T26  1264 1/1 sck_st_d = StEnd; Tests: T5 T9 T26  1265 end MISSING_ELSE 1266 end // StReadFifo 1267 1268 StReadHwReg: begin 1269 1/1 sck_p2s_valid = 1'b 1; Tests: T3 T4 T25  1270 1/1 sck_data_sel = SelHwReg; Tests: T3 T4 T25  1271 1272 // HW Reg slice? using index 1273 1274 1/1 if (isck_p2s_sent && xfer_size_met) begin Tests: T3 T4 T25  1275 1/1 sck_st_d = StEnd; Tests: T3 T27 T29  1276 end MISSING_ELSE 1277 end // StReadHwReg 1278 1279 StWrite: begin 1280 1/1 wrdata_shift_en = 1'b 1; Tests: T5 T9 T26  1281 // Processed by the logic. Does not have to do 1282 1283 1/1 if (sck_wrfifo_wvalid && xfer_size_met) begin Tests: T5 T9 T26  1284 // With complete command, upload for SW to process 1285 1/1 sck_cmdaddr_wvalid = 1'b 1; Tests: T5 T9 T26  1286 1/1 sck_st_d = StEnd; Tests: T5 T9 T26  1287 end MISSING_ELSE 1288 end // StWrite 1289 1290 StInvalid: begin // TERMINAL_STATE 1291 // Send FFh 1292 1/1 if (cmd_type == Read) begin Tests: T3 T27 T29  1293 1/1 sck_p2s_valid = 1'b 1; Tests: T3 T27 T29  1294 1/1 sck_data_sel = SelInvalid; Tests: T3 T27 T29  1295 end ==> MISSING_ELSE 1296 end // StInvalid 1297 1298 StEnd: begin // TERMINAL_STATE 1299 1/1 if (cmd_type == Read) begin Tests: T3 T5 T9  1300 1/1 sck_p2s_valid = 1'b 1; Tests: T3 T5 T9  1301 1/1 sck_data_sel = SelWait; // drive 0x00 Tests: T3 T5 T9  1302 end MISSING_ELSE 1303 end // StEnd 1304 1305 default: begin 1306 sck_st_d = StIdle; 1307 end 1308 endcase 1309 1310 end : next_state 1311 1312 ////////////// 1313 // Instance // 1314 ////////////// 1315 prim_fifo_async #( 1316 .Width (CmdAddrSize), 1317 .Depth (CmdAddrFifoDepth), 1318 .OutputZeroIfEmpty (1'b 1) 1319 ) u_cmdaddr_buffer ( 1320 .clk_wr_i (clk_in_i), 1321 .rst_wr_ni (sys_rst_ni), 1322 .wvalid_i (sck_cmdaddr_wvalid), 1323 .wready_o (sck_cmdaddr_wready), 1324 .wdata_i (sck_cmdaddr_wdata_d), 1325 .wdepth_o (sck_cmdaddr_wdepth), 1326 1327 .clk_rd_i (sys_clk_i), 1328 .rst_rd_ni (sys_rst_ni), 1329 .rvalid_o (sys_cmdaddr_rvalid_o), 1330 .rready_i (sys_cmdaddr_rready_i), 1331 .rdata_o (sys_cmdaddr_rdata_o), 1332 .rdepth_o (sys_cmdaddr_rdepth) 1333 ); 1334 1335 // Write Buffer 1336 spid_fifo2sram_adapter #( 1337 .FifoWidth (NumBits), // 1 byte 1338 .FifoDepth (WrFifoDepth), // 64 bytes 1339 1340 .SramAw (SramAw), 1341 .SramDw (SramDw), 1342 .SramBaseAddr (SramTpmWrFifoIdx), 1343 1344 // CFG 1345 .EnPack (1'b1) 1346 ) u_tpm_wr_buffer ( 1347 .clk_i (clk_in_i), 1348 .rst_ni, 1349 .clr_i (1'b0), 1350 1351 .wvalid_i (sck_wrfifo_wvalid), 1352 .wready_o (sck_wrfifo_wready), 1353 .wdata_i (sck_wrfifo_wdata), 1354 1355 // Does not use wdepth from the buffer as it is reset by CSb. 1356 .wdepth_o (), 1357 1358 .sram_req_o (sck_sram_req [SramWrFifo]), 1359 .sram_gnt_i (sck_sram_gnt [SramWrFifo]), 1360 .sram_write_o (sck_sram_write [SramWrFifo]), 1361 .sram_addr_o (sck_sram_addr [SramWrFifo]), 1362 .sram_wdata_o (sck_sram_wdata [SramWrFifo]), 1363 .sram_wmask_o (sck_sram_wmask [SramWrFifo]), 1364 .sram_rvalid_i (sck_sram_rvalid [SramWrFifo]), 1365 .sram_rdata_i (sck_sram_rdata [SramWrFifo]), 1366 .sram_rerror_i (sck_sram_rerror [SramWrFifo]) 1367 ); 1368 1369 // The content inside the Read FIFO needs to be flush out when a TPM 1370 // transaction is completed (CSb deasserted). So, everytime CSb is 1371 // deasserted --> rst_ni asserted. So, reset the read FIFO. In addition, the 1372 // reset is extended until a read command is drawn from the FIFO. 1373 1/1 assign sys_cmdaddr = tpm_cmdaddr_t'(sys_cmdaddr_rdata_o); Tests: T1 T2 T3  1374 logic unused_sys_cmdaddr; 1375 1/1 assign unused_sys_cmdaddr = ^{ Tests: T1 T2 T3  1376 sys_cmdaddr.address, 1377 sys_cmdaddr.rsvd 1378 }; 1379 1380 logic sys_rdfifo_sync_clr; 1381 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 1382 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  1383 1/1 sys_rdfifo_sync_clr <= 1'b1; Tests: T1 T2 T3  1384 1/1 end else if (sys_csb_deasserted_pulse) begin Tests: T1 T2 T3  1385 1/1 sys_rdfifo_sync_clr <= 1'b1; Tests: T1 T3 T4  1386 1/1 end else if (sys_cmdaddr.rnw & sys_cmdaddr_rvalid_o & sys_cmdaddr_rready_i) begin Tests: T1 T2 T3  1387 1/1 sys_rdfifo_sync_clr <= 1'b0; Tests: T5 T9 T26  1388 end MISSING_ELSE 1389 end 1390 1391 // sck_rdfifo_cmd_pending tracks whether a RdFIFO command was not fully 1392 // completed in the SCK domain. 1393 always_ff @(posedge clk_in_i or negedge sys_rst_ni) begin 1394 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  1395 1/1 sck_rdfifo_cmd_pending <= 1'b0; Tests: T1 T2 T3  1396 1/1 end else if (cmdaddr_bitcnt == 5'h0f) begin Tests: T3 T4 T5  1397 // Clearing the command pending bit here should give at least the 16 SPI 1398 // cycles for the sys_clk domain to sample the event, timed by 1399 // sys_tpm_rst_ni falling edge (after a 2FF sync). 1400 1/1 sck_rdfifo_cmd_pending <= 1'b0; Tests: T3 T4 T5  1401 1/1 end else if (sck_cmdaddr_wvalid && (cmd_type == Read)) begin Tests: T3 T4 T5  1402 1/1 sck_rdfifo_cmd_pending <= 1'b1; Tests: T5 T9 T26  1403 1/1 end else if (isck_p2s_sent && xfer_size_met && (sck_st_q == StReadFifo)) begin Tests: T3 T4 T5  1404 1/1 sck_rdfifo_cmd_pending <= 1'b0; Tests: T5 T9 T26  1405 end MISSING_ELSE 1406 end 1407 1408 always_ff @(posedge sys_clk_i or negedge sys_rst_ni) begin 1409 1/1 if (!sys_rst_ni) begin Tests: T1 T2 T3  1410 1/1 sys_rdfifo_aborted_o <= 1'b0; Tests: T1 T2 T3  1411 1/1 end else if (sys_csb_deasserted_pulse & !sys_rdfifo_sync_clr) begin Tests: T1 T2 T3  1412 // Sample the command pending bit on the CSB de-assertion edge, which 1413 // has a safe timing as long as sys_clk_i is fast enough to handle the 1414 // CSB CDC + this flop in the 16 SPI cycles. sck_rdfifo_cmd_pending will 1415 // be held steady for at least that long, including however long since the 1416 // last SPI clock edge of the *previous* command. 1417 1/1 sys_rdfifo_aborted_o <= sck_rdfifo_cmd_pending; Tests: T5 T9 T26  1418 1/1 end else if (sys_cmdaddr_rvalid_o & sys_cmdaddr_rready_i) begin Tests: T1 T2 T3  1419 1/1 sys_rdfifo_aborted_o <= 1'b0; Tests: T5 T9 T26  1420 end MISSING_ELSE 1421 end 1422 1423 // The end of a command doesn't necessarily mean that it completed. 1424 // sys_rdfifo_cmd_aborted may be observed for that. 1425 1/1 assign sys_rdfifo_cmd_end_o = sys_csb_deasserted_pulse & !sys_rdfifo_sync_clr; Tests: T1 T2 T3  1426 1427 logic [SramDw-1:0] sys_sram_wmask; 1428 0/1 ==> assign sys_sram_o.wstrb = sram_mask2strb(sys_sram_wmask); 1429 1430 // Read Buffer 1431 spid_fifo2sram_adapter #( 1432 .FifoWidth (RdFifoWidth), // 4 bytes 1433 .FifoDepth (RdFifoDepth), // 64 bytes 1434 1435 .SramAw (SramAw), 1436 .SramDw (SramDw), 1437 .SramBaseAddr (SramTpmRdFifoIdx) 1438 ) u_tpm_rd_buffer ( 1439 .clk_i (sys_clk_i), 1440 .rst_ni (sys_rst_ni), 1441 .clr_i (sys_rdfifo_sync_clr), 1442 1443 .wvalid_i (sys_rdfifo_wvalid_i), 1444 .wready_o (sys_rdfifo_wready_o), 1445 .wdata_i (sys_rdfifo_wdata_i), 1446 .wdepth_o (), 1447 1448 .sram_req_o (sys_sram_o.req ), 1449 .sram_gnt_i (sys_sram_gnt_i ), 1450 .sram_write_o (sys_sram_o.we ), 1451 .sram_addr_o (sys_sram_o.addr ), 1452 .sram_wdata_o (sys_sram_o.wdata ), 1453 .sram_wmask_o (sys_sram_wmask ), 1454 .sram_rvalid_i (sys_sram_i.rvalid), 1455 .sram_rdata_i (sys_sram_i.rdata ), 1456 .sram_rerror_i (sys_sram_i.rerror) 1457 ); 1458 1459 1/1 assign sys_tpm_rdfifo_drop_o = sys_rdfifo_wvalid_i & !sys_rdfifo_wready_o; Tests: T1 T2 T3  1460 1461 // RdFIFO SRAM logic. Due to the SRAM latency, the requests need to be 1462 // prepared in the output FIFO at least a cycle before the data is used. The 1463 // SRAM requests thus must begin even in the StStartByte state. 1464 logic rdfifo_active; 1465 1/1 assign rdfifo_active = enough_payload_in_rdfifo && Tests: T1 T2 T3  1466 (sck_st_q == StReadFifo || sck_st_q == StStartByte); 1467 1468 logic sck_rdfifo_req_pending; 1469 always_ff @(posedge clk_in_i or negedge rst_ni) begin 1470 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1471 1/1 sck_rdfifo_req_pending <= 1'b0; Tests: T1 T2 T3  1472 1/1 end else if (sck_sram_req[SramRdFifo] & sck_sram_gnt[SramRdFifo]) begin Tests: T3 T4 T5  1473 1/1 sck_rdfifo_req_pending <= 1'b1; Tests: T5 T9 T26  1474 1/1 end else if (sck_sram_rvalid[SramRdFifo]) begin Tests: T3 T4 T5  1475 1/1 sck_rdfifo_req_pending <= 1'b0; Tests: T5 T9 T26  1476 end MISSING_ELSE 1477 end 1478 1479 always_ff @(posedge clk_in_i or negedge rst_ni) begin 1480 1/1 if (!rst_ni) begin Tests: T1 T2 T3  1481 1/1 sck_rdfifo_offset <= '0; Tests: T1 T2 T3  1482 1/1 end else if (sck_sram_req[SramRdFifo] & sck_sram_gnt[SramRdFifo]) begin Tests: T3 T4 T5  1483 1/1 sck_rdfifo_offset <= sck_rdfifo_offset + 1; Tests: T5 T9 T26  1484 end MISSING_ELSE 1485 end 1486 1487 // Since sck_rdfifo_full only responds once the data arrives and is 1488 // committed to the FIFO, avoid sending back-to-back requests. 1489 1/1 assign sck_sram_req[SramRdFifo] = rdfifo_active && !sck_rdfifo_req_pending && !sck_rdfifo_full; Tests: T1 T2 T3  1490 1/1 assign sck_sram_addr[SramRdFifo] = SramTpmRdFifoIdx | SramAw'({1'b0, sck_rdfifo_offset}); Tests: T1 T2 T3  1491 assign sck_sram_write[SramRdFifo] = 1'b0; 1492 assign sck_sram_wdata[SramRdFifo] = '0; 1493 assign sck_sram_wmask[SramRdFifo] = '0; 1494 1495 // Shallow FIFO to hold the wide SRAM output. 1496 prim_fifo_sync #( 1497 .Width ($bits(sram_data_t)), 1498 .Pass (1'b 1), 1499 .Depth (1), 1500 .OutputZeroIfEmpty (1'b 0) 1501 ) u_sram_fifo ( 1502 .clk_i (clk_in_i), 1503 .rst_ni, 1504 1505 .clr_i (1'b 0), 1506 1507 .wvalid_i (sck_sram_rvalid[SramRdFifo]), 1508 .wready_o (), 1509 .wdata_i (sck_sram_rdata[SramRdFifo]), 1510 1511 .rvalid_o (sck_rdfifo_rvalid), 1512 .rready_i (sck_rdfifo_rready), 1513 .rdata_o (sck_rdfifo_rdata), 1514 1515 .full_o (sck_rdfifo_full), 1516 .depth_o (), 1517 .err_o () 1518 ); 1519 1520 // SRAM interconnect for the SPI domain 1521 logic [SramDw-1:0] sck_sram_o_wmask; 1522 1/1 assign sck_sram_o.wstrb = sram_mask2strb(sck_sram_o_wmask); Tests: T1 T2 T3  1523 1524 prim_sram_arbiter #( 1525 .N (NumSramIntf), 1526 .SramDw (SramDw), 1527 .SramAw (SramAw), 1528 .EnMask (1'b 1) 1529 ) u_arbiter ( 1530 .clk_i (clk_in_i), 1531 .rst_ni, 1532 1533 .req_i (sck_sram_req), 1534 .req_addr_i (sck_sram_addr), 1535 .req_write_i (sck_sram_write), 1536 .req_wdata_i (sck_sram_wdata), 1537 .req_wmask_i (sck_sram_wmask), 1538 .gnt_o (sck_sram_gnt), 1539 1540 .rsp_rvalid_o (sck_sram_rvalid), 1541 .rsp_rdata_o (sck_sram_rdata), 1542 .rsp_error_o (sck_sram_rerror), 1543 1544 .sram_req_o (sck_sram_o.req), 1545 .sram_addr_o (sck_sram_o.addr), 1546 .sram_write_o (sck_sram_o.we), 1547 .sram_wdata_o (sck_sram_o.wdata), 1548 .sram_wmask_o (sck_sram_o_wmask), 1549 .sram_rvalid_i (sck_sram_i.rvalid), 1550 .sram_rdata_i (sck_sram_i.rdata), 1551 .sram_rerror_i (sck_sram_i.rerror) 1552 ); 1553 1554 // Logic Not Used 1555 logic unused_logic; 1556 1/1 assign unused_logic = ^{ sck_cmdaddr_wready, Tests: T1 T2 T3 
0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%