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:       T2 T4 T5 
531        1/1                  sys_clk_tpm_reg <= sys_tpm_reg;
           Tests:       T2 T4 T5 
532        1/1                  for (int unsigned i = 0 ; i < NumLocality ; i++) begin
           Tests:       T2 T4 T5 
533        1/1                    sys_active_locality[i] <=
           Tests:       T2 T4 T5 
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:       T4 T5 T15 
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:       T4 T5 T15 
558        1/1                cmdaddr_bitcnt <= cmdaddr_bitcnt + 5'h 1;
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T5 T15 
605        1/1                sck_cmdaddr_wdata_q <= sck_cmdaddr_wdata_d;
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T5 T15 
623                           // Shall assert when sck_st_q moves away from StAddr
624        1/1                isck_fifoaddr <= sck_cmdaddr_wdata_q[FifoRegSize-1:0];
           Tests:       T4 T5 T15 
625        1/1              end else if (isck_fifoaddr_inc) begin
           Tests:       T4 T5 T15 
626        1/1                isck_fifoaddr <= isck_fifoaddr + 1'b 1;
           Tests:       T4 T24 T26 
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:       T4 T5 T15 
651        1/1                wrdata_bitcnt <= wrdata_bitcnt + 3'h 1;
           Tests:       T5 T15 T25 
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:       T4 T5 T15 
661        1/1                wrdata_q <= wrdata_d;
           Tests:       T5 T15 T25 
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 T15 T25 
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 T15 T25 
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:       T4 T5 T6 
712        1/1                sck_wrfifo_busy <= 1'b1;
           Tests:       T5 T15 T25 
713        1/1              end else if (sck_wrfifo_release_req) begin
           Tests:       T4 T5 T6 
714        1/1                sck_wrfifo_busy <= 1'b0;
           Tests:       T5 T15 T25 
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:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T15 T24 
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:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T24 T26 
775        1/1                sck_hw_reg_idx <= sck_hw_reg_idx_d;
           Tests:       T4 T24 T26 
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:       T4 T5 T15 
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:       T4 T5 T15 
806        1/1                locality         <= addr[15:12];
           Tests:       T4 T15 T24 
807        1/1                invalid_locality <= (addr[15:12] < 4'(NumLocality)) ? 1'b 0: 1'b 1;
           Tests:       T4 T15 T24 
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:       T4 T5 T15 
816                           // latch at the very first SCK edge
817        1/1                cmd_type <= cmd_type_e'(sck_cmdaddr_wdata_d[0]);
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
826        1/1                xfer_size <= sck_cmdaddr_wdata_d[5:0];
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
835                           (sck_wrfifo_wvalid && wrdata_shift_en)) begin
836        1/1                xfer_bytes_q <= xfer_bytes_d;
           Tests:       T5 T15 T25 
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:       T2 T4 T5 
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 T15 T25 
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:       T2 T4 T5 
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 T15 T25 
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:       T4 T5 T15 
902                           end
903                     
904                           SelInvalid: begin
905        1/1                  isck_p2s_data = 8'h FF;
           Tests:       T26 T28 T103 
906                           end
907                     
908                           SelHwReg: begin
909        1/1                  isck_p2s_data = isck_hw_reg_byte;
           Tests:       T4 T24 T26 
910                           end
911                     
912                           SelRdFifo: begin
913        1/1                  isck_p2s_data = isck_sel_rdata;
           Tests:       T5 T15 T25 
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:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T5 T15 
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:       T4 T5 T15 
1067       1/1                sck_rdfifo_idx <= sck_rdfifo_idx + 1'b 1;
           Tests:       T5 T15 T25 
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:       T4 T5 T15 
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:       T4 T5 T15 
1148       1/1                      sck_st_d = StAddr;
           Tests:       T4 T5 T15 
1149                    
1150       1/1                      latch_xfer_size = 1'b 1;
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
1166                    
1167       1/1                  if (cmdaddr_bitcnt >= 5'h 18) begin
           Tests:       T4 T5 T15 
1168                              // Send Wait byte [18h:1Fh]
1169       1/1                    sck_p2s_valid = 1'b 1;
           Tests:       T4 T5 T15 
1170       1/1                    sck_data_sel  = SelWait;
           Tests:       T4 T5 T15 
1171                            end
                        MISSING_ELSE
1172                    
1173                            // Latch locality
1174       1/1                  if (cmdaddr_bitcnt == 5'h 1B) begin
           Tests:       T4 T5 T15 
1175       1/1                    check_locality = 1'b 1;
           Tests:       T4 T5 T15 
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:       T4 T5 T15 
1180       1/1                    if (!is_tpm_reg_q || sys_clk_tpm_cfg.tpm_mode) begin
           Tests:       T4 T5 T15 
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 T15 T25 
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 T15 T25 
1189       1/1                        sck_cmdaddr_wvalid = 1'b 1;
           Tests:       T5 T15 T25 
1190                                end
                        MISSING_ELSE
1191       1/1                    end else if (is_hw_reg) begin
           Tests:       T4 T24 T26 
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:       T4 T24 T26 
1195       1/1                    end else if (invalid_locality && sys_clk_tpm_cfg.invalid_locality) begin
           Tests:       T26 T28 T103 
1196                                // The read request is out of supported Localities.
1197                                // Return FFh
1198       1/1                      sck_st_d = StInvalid;
           Tests:       T26 T28 T103 
1199                              end else begin
1200                                // Other read command sends to Wait, till SW response
1201       1/1                      sck_st_d = StWait;
           Tests:       T37 T64 T104 
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:       T37 T64 T104 
1207       1/1                        sck_cmdaddr_wvalid = 1'b 1;
           Tests:       T37 T64 T104 
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:       T4 T5 T15 
1213       1/1                    if (!sck_wrfifo_busy && ~|sck_cmdaddr_wdepth) begin
           Tests:       T5 T15 T25 
1214                                // Write command and FIFO is empty. Ready to push
1215       1/1                      sck_st_d = StStartByte;
           Tests:       T5 T15 T25 
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:       T15 T27 T37 
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 T15 T25 
1226       1/1                  sck_data_sel = SelWait;
           Tests:       T5 T15 T25 
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 T15 T25 
1230       1/1                    sck_cmdaddr_wvalid = 1'b1;
           Tests:       T15 T27 T37 
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 T15 T25 
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 T15 T25 
1238                            end
                        MISSING_ELSE
1239                          end // StWait
1240                    
1241                          StStartByte: begin
1242       1/1                  sck_p2s_valid = 1'b 1;
           Tests:       T4 T5 T15 
1243       1/1                  sck_data_sel  = SelStart;
           Tests:       T4 T5 T15 
1244                    
1245       1/1                  if (isck_p2s_sent) begin
           Tests:       T4 T5 T15 
1246                              // Must move to next state as StartByte is a byte
1247       1/1                    if ((cmd_type == Read) && is_hw_reg) begin
           Tests:       T4 T5 T15 
1248       1/1                      sck_st_d = StReadHwReg;
           Tests:       T4 T24 T26 
1249       1/1                    end else if (cmd_type == Read) begin
           Tests:       T5 T15 T25 
1250       1/1                      sck_st_d = StReadFifo;
           Tests:       T5 T15 T25 
1251       1/1                    end else if (cmd_type == Write) begin
           Tests:       T5 T15 T25 
1252       1/1                      sck_st_d = StWrite;
           Tests:       T5 T15 T25 
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 T15 T25 
1259                    
1260       1/1                  sck_p2s_valid = 1'b 1;
           Tests:       T5 T15 T25 
1261       1/1                  sck_data_sel  = SelRdFifo;
           Tests:       T5 T15 T25 
1262                    
1263       1/1                  if (isck_p2s_sent && xfer_size_met) begin
           Tests:       T5 T15 T25 
1264       1/1                    sck_st_d = StEnd;
           Tests:       T5 T15 T25 
1265                            end
                        MISSING_ELSE
1266                          end // StReadFifo
1267                    
1268                          StReadHwReg: begin
1269       1/1                  sck_p2s_valid = 1'b 1;
           Tests:       T4 T24 T26 
1270       1/1                  sck_data_sel  = SelHwReg;
           Tests:       T4 T24 T26 
1271                    
1272                            // HW Reg slice? using index
1273                    
1274       1/1                  if (isck_p2s_sent && xfer_size_met) begin
           Tests:       T4 T24 T26 
1275       1/1                    sck_st_d = StEnd;
           Tests:       T26 T28 T103 
1276                            end
                        MISSING_ELSE
1277                          end // StReadHwReg
1278                    
1279                          StWrite: begin
1280       1/1                  wrdata_shift_en = 1'b 1;
           Tests:       T5 T15 T25 
1281                            // Processed by the logic. Does not have to do
1282                    
1283       1/1                  if (sck_wrfifo_wvalid && xfer_size_met) begin
           Tests:       T5 T15 T25 
1284                              // With complete command, upload for SW to process
1285       1/1                    sck_cmdaddr_wvalid = 1'b 1;
           Tests:       T5 T15 T25 
1286       1/1                    sck_st_d = StEnd;
           Tests:       T5 T15 T25 
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:       T26 T28 T103 
1293       1/1                    sck_p2s_valid = 1'b 1;
           Tests:       T26 T28 T103 
1294       1/1                    sck_data_sel  = SelInvalid;
           Tests:       T26 T28 T103 
1295                            end
                   ==>  MISSING_ELSE
1296                          end // StInvalid
1297                    
1298                          StEnd: begin // TERMINAL_STATE
1299       1/1                  if (cmd_type == Read) begin
           Tests:       T5 T15 T25 
1300       1/1                    sck_p2s_valid = 1'b 1;
           Tests:       T5 T15 T25 
1301       1/1                    sck_data_sel  = SelWait; // drive 0x00
           Tests:       T5 T15 T25 
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:       T2 T4 T5 
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 T15 T25 
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:       T4 T5 T6 
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:       T4 T5 T15 
1401       1/1              end else if (sck_cmdaddr_wvalid && (cmd_type == Read)) begin
           Tests:       T4 T5 T6 
1402       1/1                sck_rdfifo_cmd_pending <= 1'b1;
           Tests:       T5 T15 T25 
1403       1/1              end else if (isck_p2s_sent && xfer_size_met && (sck_st_q == StReadFifo)) begin
           Tests:       T4 T5 T6 
1404       1/1                sck_rdfifo_cmd_pending <= 1'b0;
           Tests:       T5 T15 T25 
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 T15 T25 
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 T15 T25 
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:       T4 T5 T15 
1473       1/1                sck_rdfifo_req_pending <= 1'b1;
           Tests:       T5 T15 T25 
1474       1/1              end else if (sck_sram_rvalid[SramRdFifo]) begin
           Tests:       T4 T5 T15 
1475       1/1                sck_rdfifo_req_pending <= 1'b0;
           Tests:       T5 T15 T25 
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:       T4 T5 T15 
1483       1/1                sck_rdfifo_offset <= sck_rdfifo_offset + 1;
           Tests:       T5 T15 T25 
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