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