Go 
back
172                     
173        1/1            assign payload_notempty = payload_depth != '0;
           Tests:       T1 T2 T3 
174                     
175                       /////////////////////
176                       // Control signals //
177                       /////////////////////
178                     
179                       logic txorder; // TX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7)
180                       logic rxorder; // RX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7)
181                     
182                       logic sys_csb_syncd;
183                     
184                       spi_mode_e spi_mode;
185                       logic cfg_addr_4b_en;
186                       logic cmd_sync_addr_4b_en;
187                     
188                       // Address 3B/ 4B tracker related signals
189                       //
190                       // EN4B/ EX4B change internal status by HW. If SW is involved into the
191                       // process, the latency is long. As EN4B/ EX4B commands do not assert BUSY
192                       // bit, the host system issues next read commands without any delays. SW
193                       // process latency cannot meet the requirement.
194                       //
195                       // `spid_addr_4b` submodule processes the broadcasting signal
196                       // `cfg_addr_4b_en`. The command parser recognizes the commands and triggers
197                       // the `spid_addr_4b` submodule to change the internal status.
198                       //
199                       // The opcodes of the commands SW may configure via CMD_INFO_EN4B,
200                       // CMD_INFO_EX4B.
201                       logic cmd_en4b_pulse, cmd_ex4b_pulse;
202                     
203                       // SPI S2P signals
204                       // io_mode: Determine s2p/p2s behavior.
205                       // io_mode is changed at the negedge of SPI_CLK (based on the SPI protocol).
206                       // sub_iomode originates from the clk_spi_in domain, with flop values that
207                       // may have changed based on the input of SPI. The sub_iomode is selected
208                       // and sampled on the clk_spi_out domain.
209                       io_mode_e           io_mode, io_mode_outclk;
210                       io_mode_e           sub_iomode[IoModeEnd];
211                       logic               s2p_data_valid;
212                       spi_byte_t          s2p_data;
213                     
214                       logic        p2s_valid;
215                       spi_byte_t   p2s_data;
216                       logic        p2s_sent;
217                     
218                       logic        sub_p2s_valid[IoModeEnd];
219                       spi_byte_t   sub_p2s_data[IoModeEnd];
220                       logic        sub_p2s_sent[IoModeEnd];
221                     
222                       // Read commands related signals
223                       logic [31:0] readbuf_addr_sck;
224                       logic [31:0] readbuf_addr_busclk;
225                     
226                       // CMD interface
227                       sel_datapath_e cmd_dp_sel, cmd_only_dp_sel;
228                     
229                       // Mailbox in Passthrough needs to take SPI if readcmd hits mailbox address
230                       logic intercept_en, intercept_en_out;
231                     
232                       logic cfg_mailbox_en;
233                       logic [31:0] mailbox_addr;
234                     
235                       // Intercept
236                       typedef struct packed {
237                         logic status;
238                         logic jedec;
239                         logic sfdp;
240                         logic mbx;
241                       } intercept_t;
242                       intercept_t cfg_intercept_en;
243                       intercept_t intercept; // Assume signals
244                     
245                       // Threshold value of a buffer in bytes
246                       logic [BufferAw:0] readbuf_threshold;
247                     
248                       // Synchronous clear of read buffer tracking.
249                       logic readbuf_clr;
250                     
251                       // Passthrouth config signals
252                       logic [255:0] cmd_filter;
253                     
254                       logic [31:0] addr_swap_mask;
255                       logic [31:0] addr_swap_data;
256                     
257                       logic [31:0] payload_swap_mask;
258                       logic [31:0] payload_swap_data;
259                     
260                       // Additional 2-stage read pipeline configuration
261                       logic cmd_read_pipeline_sel;
262                     
263                       // Command Info structure
264                       cmd_info_t [NumTotalCmdInfo-1:0] cmd_info;
265                       // Broadcasted cmd_info. cmdparse compares the opcode up to CmdInfoReadCmdEnd
266                       // and latches the cmd_info and broadcast to submodules
267                       cmd_info_t                  cmd_info_broadcast;
268                       logic [CmdInfoIdxW-1:0]     cmd_info_idx_broadcast;
269                       // Combinatorial output of selected cmd_info, to be used with modules that
270                       // need the values before the 8th posedge of the command.
271                       cmd_info_t                  cmd_only_info_broadcast;
272                       logic [CmdInfoIdxW-1:0]     cmd_only_info_idx_broadcast;
273                     
274                       // Synchronization pulse indicating that the 8th bit of the command is
275                       // arriving. This is used to time the transfer of some data to/from the sys
276                       // domain.
277                       logic                       cmd_sync_pulse;
278                     
279                       // CSb edge detector in the system clock and SPI input clock
280                       // SYS clock assertion can be detected but no usage for the event yet.
281                       // SPI clock de-assertion cannot be detected as no SCK at the time is given.
282                       logic sys_csb_deasserted_pulse;
283                     
284                       // Important status bits for tracking in the upload module
285                       logic cmd_sync_status_busy;
286                       logic cmd_sync_status_wel;
287                       logic sck_status_busy;
288                     
289                       // Read Status input and broadcast
290                       logic sck_status_busy_set;       // set by HW (upload)
291                       logic csb_status_busy_broadcast; // from spid_status
292                     
293                       // WREN / WRDI HW signal
294                       logic sck_status_wr_set;
295                       logic sck_status_wr_clr;
296                     
297                       // Jedec ID
298                       jedec_cfg_t jedec_cfg;
299                     
300                       // Interrupts in Flash mode
301                       logic intr_upload_cmdfifo_not_empty, intr_upload_payload_not_empty;
302                       logic intr_upload_payload_overflow;
303                       logic intr_readbuf_watermark, intr_readbuf_flip;
304                       logic flash_sck_readbuf_watermark, flash_sck_readbuf_flip;
305                     
306                       // TPM ===============================================================
307                       // Interface
308                       logic tpm_mosi, tpm_miso, tpm_miso_en;
309        1/1            assign tpm_mosi = cio_sd_i[0];
           Tests:       T4 T5 T6 
310                     
311                       // Return-by-HW registers
312                       logic [8*spi_device_reg_pkg::NumLocality-1:0] tpm_access;
313                       logic [31:0]                                  tpm_int_enable;
314                       logic [7:0]                                   tpm_int_vector;
315                       logic [31:0]                                  tpm_int_status;
316                       logic [31:0]                                  tpm_intf_capability;
317                       logic [31:0]                                  tpm_status;
318                       logic [31:0]                                  tpm_did_vid;
319                       logic [7:0]                                   tpm_rid;
320                     
321                       // Buffer and FIFO signals
322                       sram_l2m_t                  tpm_sram_l2m;
323                       sram_m2l_t                  tpm_sram_m2l;
324                       logic                       tpm_cmdaddr_rvalid, tpm_cmdaddr_rready;
325                       logic [31:0]                tpm_cmdaddr_rdata;
326                       logic                       tpm_rdfifo_wvalid, tpm_rdfifo_wready;
327                       logic [TpmRdFifoWidth-1:0]  tpm_rdfifo_wdata;
328                       logic                       tpm_event_rdfifo_cmd_end;
329                       logic                       tpm_event_rdfifo_drop;
330                     
331                       tpm_cap_t tpm_cap;
332                     
333                       // TPM CFG
334                       logic cfg_tpm_en, cfg_tpm_mode, cfg_tpm_hw_reg_dis;
335                       logic cfg_tpm_invalid_locality, cfg_tpm_reg_chk_dis;
336                     
337                       // TPM_STATUS
338                       logic tpm_status_cmdaddr_notempty;
339                       logic tpm_status_wrfifo_pending;
340                       logic tpm_status_wrfifo_release;
341                       logic tpm_status_rdfifo_aborted;
342                     
343                       // TPM ---------------------------------------------------------------
344                     
345                       /////////////////
346                       // CSb Buffers //
347                       /////////////////
348                       // Split the CSB into multiple explicit buffers. One for reset, two for each
349                       // clock domains.
350                       logic clk_csb_buf, rst_csb_buf, sys_csb, sck_csb;
351                       prim_buf #(
352                         .Width (4)
353                       ) u_csb_buf (
354                         .in_i  ({4{cio_csb_i}}),
355                         .out_o ({clk_csb_buf, rst_csb_buf, sys_csb, sck_csb})
356                       );
357                     
358                       // Split TPM CSB into explicit reset and data.
359                       logic rst_tpm_csb_buf, sys_tpm_csb_buf, sck_tpm_csb_buf;
360                       logic sys_tpm_csb_syncd; // synchronized prior to be connected to reg
361                       prim_buf #(
362                         .Width (3)
363                       ) u_tpm_csb_buf (
364                         .in_i  ({3{cio_tpm_csb_i}}),
365                         .out_o ({rst_tpm_csb_buf, sys_tpm_csb_buf, sck_tpm_csb_buf})
366                       );
367                     
368                       //////////////////////////////////////////////////////////////////////
369                       // Connect phase (between control signals above and register module //
370                       //////////////////////////////////////////////////////////////////////
371                     
372        1/1            assign txorder = reg2hw.cfg.tx_order.q;
           Tests:       T1 T2 T3 
373        1/1            assign rxorder = reg2hw.cfg.rx_order.q;
           Tests:       T1 T2 T3 
374                     
375                       // CSb : after 2stage synchronizer
376        1/1            assign hw2reg.status.csb.d     = sys_csb_syncd;
           Tests:       T1 T2 T3 
377        1/1            assign hw2reg.status.tpm_csb.d = sys_tpm_csb_syncd;
           Tests:       T1 T2 T3 
378                     
379        1/1            assign spi_mode = spi_mode_e'(reg2hw.control.mode.q);
           Tests:       T1 T2 T3 
380                     
381                       prim_edge_detector #(
382                         .Width (2),
383                         .EnSync(1'b 0)
384                       ) u_intr_upload_edge (
385                         .clk_i,
386                         .rst_ni,
387                     
388                         .d_i               ({payload_notempty, payload_overflow}),
389                         .q_sync_o          (),
390                         .q_posedge_pulse_o ({intr_upload_payload_not_empty,
391                                              intr_upload_payload_overflow}),
392                         .q_negedge_pulse_o ()
393                       );
394        1/1            assign intr_upload_cmdfifo_not_empty = cmdfifo_set_pulse;
           Tests:       T1 T2 T3 
395                     
396                       prim_intr_hw #(.Width(1)) u_intr_cmdfifo_not_empty (
397                         .clk_i,
398                         .rst_ni,
399                         .event_intr_i           (intr_upload_cmdfifo_not_empty                ),
400                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.upload_cmdfifo_not_empty.q),
401                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.upload_cmdfifo_not_empty.q  ),
402                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.upload_cmdfifo_not_empty.qe ),
403                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.upload_cmdfifo_not_empty.q ),
404                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.upload_cmdfifo_not_empty.d ),
405                         .hw2reg_intr_state_de_o (hw2reg.intr_state.upload_cmdfifo_not_empty.de),
406                         .intr_o                 (intr_upload_cmdfifo_not_empty_o              )
407                       );
408                     
409                       prim_intr_hw #(.Width(1)) u_intr_payload_not_empty (
410                         .clk_i,
411                         .rst_ni,
412                         .event_intr_i           (intr_upload_payload_not_empty                ),
413                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.upload_payload_not_empty.q),
414                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.upload_payload_not_empty.q  ),
415                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.upload_payload_not_empty.qe ),
416                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.upload_payload_not_empty.q ),
417                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.upload_payload_not_empty.d ),
418                         .hw2reg_intr_state_de_o (hw2reg.intr_state.upload_payload_not_empty.de),
419                         .intr_o                 (intr_upload_payload_not_empty_o              )
420                       );
421                     
422                       prim_intr_hw #(.Width(1)) u_intr_payload_overflow (
423                         .clk_i,
424                         .rst_ni,
425                         .event_intr_i           (intr_upload_payload_overflow                ),
426                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.upload_payload_overflow.q),
427                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.upload_payload_overflow.q  ),
428                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.upload_payload_overflow.qe ),
429                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.upload_payload_overflow.q ),
430                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.upload_payload_overflow.d ),
431                         .hw2reg_intr_state_de_o (hw2reg.intr_state.upload_payload_overflow.de),
432                         .intr_o                 (intr_upload_payload_overflow_o              )
433                       );
434                     
435                     
436                       prim_pulse_sync u_flash_readbuf_watermark_pulse_sync (
437                         .clk_src_i   (clk_spi_in_buf             ),
438                         .rst_src_ni  (rst_ni                     ),
439                         .src_pulse_i (flash_sck_readbuf_watermark),
440                         .clk_dst_i   (clk_i                      ),
441                         .rst_dst_ni  (rst_ni                     ),
442                         .dst_pulse_o (intr_readbuf_watermark     )
443                       );
444                       prim_intr_hw #(.Width(1)) u_intr_readbuf_watermark (
445                         .clk_i,
446                         .rst_ni,
447                         .event_intr_i           (intr_readbuf_watermark                ),
448                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.readbuf_watermark.q),
449                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.readbuf_watermark.q  ),
450                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.readbuf_watermark.qe ),
451                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.readbuf_watermark.q ),
452                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.readbuf_watermark.d ),
453                         .hw2reg_intr_state_de_o (hw2reg.intr_state.readbuf_watermark.de),
454                         .intr_o                 (intr_readbuf_watermark_o              )
455                       );
456                     
457                       prim_pulse_sync u_flash_readbuf_flip_pulse_sync (
458                         .clk_src_i   (clk_spi_in_buf        ),
459                         .rst_src_ni  (rst_ni                ),
460                         .src_pulse_i (flash_sck_readbuf_flip),
461                         .clk_dst_i   (clk_i                 ),
462                         .rst_dst_ni  (rst_ni                ),
463                         .dst_pulse_o (intr_readbuf_flip     )
464                       );
465                       prim_intr_hw #(.Width(1)) u_intr_readbuf_flip (
466                         .clk_i,
467                         .rst_ni,
468                         .event_intr_i           (intr_readbuf_flip                ),
469                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.readbuf_flip.q),
470                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.readbuf_flip.q  ),
471                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.readbuf_flip.qe ),
472                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.readbuf_flip.q ),
473                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.readbuf_flip.d ),
474                         .hw2reg_intr_state_de_o (hw2reg.intr_state.readbuf_flip.de),
475                         .intr_o                 (intr_readbuf_flip_o              )
476                       );
477                     
478                       prim_intr_hw #(
479                         .Width (1       ),
480                         .IntrT ("Status")
481                       ) u_intr_tpm_cmdaddr_notempty (
482                         .clk_i,
483                         .rst_ni,
484                         .event_intr_i           (tpm_status_cmdaddr_notempty              ),
485                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tpm_header_not_empty.q),
486                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.tpm_header_not_empty.q  ),
487                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.tpm_header_not_empty.qe ),
488                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.tpm_header_not_empty.q ),
489                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.tpm_header_not_empty.d ),
490                         .hw2reg_intr_state_de_o (hw2reg.intr_state.tpm_header_not_empty.de),
491                         .intr_o                 (intr_tpm_header_not_empty_o              )
492                       );
493                     
494                       prim_intr_hw #(
495                         .Width (1      ),
496                         .IntrT ("Event")
497                       ) u_intr_tpm_rdfifo_cmd_end (
498                         .clk_i,
499                         .rst_ni,
500                         .event_intr_i           (tpm_event_rdfifo_cmd_end               ),
501                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tpm_rdfifo_cmd_end.q),
502                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.tpm_rdfifo_cmd_end.q  ),
503                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.tpm_rdfifo_cmd_end.qe ),
504                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.tpm_rdfifo_cmd_end.q ),
505                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.tpm_rdfifo_cmd_end.d ),
506                         .hw2reg_intr_state_de_o (hw2reg.intr_state.tpm_rdfifo_cmd_end.de),
507                         .intr_o                 (intr_tpm_rdfifo_cmd_end_o              )
508                       );
509                     
510                       prim_intr_hw #(
511                         .Width (1      ),
512                         .IntrT ("Event")
513                       ) u_intr_tpm_rdfifo_drop (
514                         .clk_i,
515                         .rst_ni,
516                         .event_intr_i           (tpm_event_rdfifo_drop               ),
517                         .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tpm_rdfifo_drop.q),
518                         .reg2hw_intr_test_q_i   (reg2hw.intr_test.tpm_rdfifo_drop.q  ),
519                         .reg2hw_intr_test_qe_i  (reg2hw.intr_test.tpm_rdfifo_drop.qe ),
520                         .reg2hw_intr_state_q_i  (reg2hw.intr_state.tpm_rdfifo_drop.q ),
521                         .hw2reg_intr_state_d_o  (hw2reg.intr_state.tpm_rdfifo_drop.d ),
522                         .hw2reg_intr_state_de_o (hw2reg.intr_state.tpm_rdfifo_drop.de),
523                         .intr_o                 (intr_tpm_rdfifo_drop_o              )
524                       );
525                       // SPI Flash commands registers
526                     
527        1/1            assign cfg_intercept_en = '{
           Tests:       T1 T2 T3 
528                         status:  reg2hw.intercept_en.status.q,
529                         jedec:   reg2hw.intercept_en.jedec.q,
530                         sfdp:    reg2hw.intercept_en.sfdp.q,
531                         mbx:     reg2hw.intercept_en.mbx.q
532                       };
533                       logic unused_cfg_intercept_en;
534        1/1            assign unused_cfg_intercept_en = ^cfg_intercept_en;
           Tests:       T1 T2 T3 
535                     
536        1/1            assign hw2reg.last_read_addr.d = readbuf_addr_busclk;
           Tests:       T1 T2 T3 
537                     
538                       always_ff @(posedge clk_i or negedge rst_ni) begin
539        1/1              if (!rst_ni) begin
           Tests:       T1 T2 T3 
540        1/1                readbuf_addr_busclk <= '0;
           Tests:       T1 T2 T3 
541        1/1              end else if (sys_csb_deasserted_pulse) begin
           Tests:       T1 T2 T3 
542        1/1                readbuf_addr_busclk <= readbuf_addr_sck;
           Tests:       T6 T7 T8 
543                         end
                        MISSING_ELSE
544                       end
545                     
546                       // Jedec ID
547        1/1            assign jedec_cfg = '{ num_cc:    reg2hw.jedec_cc.num_cc.q,
           Tests:       T1 T2 T3 
548                                             cc:        reg2hw.jedec_cc.cc.q,
549                                             jedec_id:  reg2hw.jedec_id.mf.q,
550                                             device_id: reg2hw.jedec_id.id.q
551                                           };
552                     
553        1/1            assign readbuf_threshold = reg2hw.read_threshold.q[BufferAw:0];
           Tests:       T1 T2 T3 
554        1/1            assign readbuf_clr = reg2hw.control.flash_read_buffer_clr.q;
           Tests:       T1 T2 T3 
555                       assign hw2reg.control.flash_read_buffer_clr.d  = '0;
556                       assign hw2reg.control.flash_read_buffer_clr.de = 1'b1;
557                     
558                       localparam int unsigned MailboxAw = $clog2(SramMailboxDepth*SramDw/8);
559        1/1            assign cfg_mailbox_en = reg2hw.cfg.mailbox_en.q;
           Tests:       T1 T2 T3 
560        1/1            assign mailbox_addr   = { reg2hw.mailbox_addr.q[31:MailboxAw],
           Tests:       T1 T2 T3 
561                                                 {MailboxAw{1'b0}}
562                                               };
563                       logic unused_mailbox_addr;
564        1/1            assign unused_mailbox_addr = ^reg2hw.mailbox_addr.q[MailboxAw-1:0];
           Tests:       T1 T2 T3 
565                     
566                       // Passthrough config: value shall be stable while SPI transaction is active
567                       //assign cmd_filter = reg2hw.cmd_filter.q;
568                       always_comb begin
569        1/1              for (int unsigned i = 0 ; i < 256 ; i++) begin
           Tests:       T1 T2 T3 
570        1/1                cmd_filter[i] = reg2hw.cmd_filter[i].q;
           Tests:       T1 T2 T3 
571                         end
572                       end
573                     
574        1/1            assign addr_swap_mask = reg2hw.addr_swap_mask.q;
           Tests:       T1 T2 T3 
575        1/1            assign addr_swap_data = reg2hw.addr_swap_data.q;
           Tests:       T1 T2 T3 
576                     
577                       // payload_swap_mask and _data are big-endian to calculate easily.
578                       assign payload_swap_mask = {<<8{reg2hw.payload_swap_mask.q}};
579                       assign payload_swap_data = {<<8{reg2hw.payload_swap_data.q}};
580                     
581                       // Connect command info
582                       always_comb begin
583        1/1              for (int unsigned i = 0 ; i < spi_device_reg_pkg::NumCmdInfo ; i++) begin
           Tests:       T1 T2 T3 
584        1/1                cmd_info[i] = '{
           Tests:       T1 T2 T3 
585                             valid:                 reg2hw.cmd_info[i].valid.q,
586                             opcode:                reg2hw.cmd_info[i].opcode.q,
587                             addr_mode:             addr_mode_e'(reg2hw.cmd_info[i].addr_mode.q),
588                             addr_swap_en:          reg2hw.cmd_info[i].addr_swap_en.q,
589                             mbyte_en:              reg2hw.cmd_info[i].mbyte_en.q,
590                             dummy_en:              reg2hw.cmd_info[i].dummy_en.q,
591                             dummy_size:            reg2hw.cmd_info[i].dummy_size.q,
592                             payload_en:            reg2hw.cmd_info[i].payload_en.q,
593                             payload_dir:           payload_dir_e'(reg2hw.cmd_info[i].payload_dir.q),
594                             payload_swap_en:       reg2hw.cmd_info[i].payload_swap_en.q,
595                             read_pipeline_mode:    read_pipeline_mode_e'(reg2hw.cmd_info[i].read_pipeline_mode.q),
596                             upload:                reg2hw.cmd_info[i].upload.q,
597                             busy:                  reg2hw.cmd_info[i].busy.q
598                           };
599                         end
600                     
601                         // Manual addition to cmd_info list
602                         // Default Input mode
603        1/1              for (int unsigned i = CmdInfoReserveEnd + 1; i < NumTotalCmdInfo; i++) begin
           Tests:       T1 T2 T3 
604        1/1                cmd_info[i] = CmdInfoInput;
           Tests:       T1 T2 T3 
605                         end
606                     
607                         // Hand crafted command information slots
608        1/1              cmd_info[CmdInfoEn4B].valid  = reg2hw.cmd_info_en4b.valid.q;
           Tests:       T1 T2 T3 
609        1/1              cmd_info[CmdInfoEn4B].opcode = reg2hw.cmd_info_en4b.opcode.q;
           Tests:       T1 T2 T3 
610                     
611        1/1              cmd_info[CmdInfoEx4B].valid  = reg2hw.cmd_info_ex4b.valid.q;
           Tests:       T1 T2 T3 
612        1/1              cmd_info[CmdInfoEx4B].opcode = reg2hw.cmd_info_ex4b.opcode.q;
           Tests:       T1 T2 T3 
613                     
614        1/1              cmd_info[CmdInfoWrEn].valid  = reg2hw.cmd_info_wren.valid.q;
           Tests:       T1 T2 T3 
615        1/1              cmd_info[CmdInfoWrEn].opcode = reg2hw.cmd_info_wren.opcode.q;
           Tests:       T1 T2 T3 
616                     
617        1/1              cmd_info[CmdInfoWrDi].valid  = reg2hw.cmd_info_wrdi.valid.q;
           Tests:       T1 T2 T3 
618        1/1              cmd_info[CmdInfoWrDi].opcode = reg2hw.cmd_info_wrdi.opcode.q;
           Tests:       T1 T2 T3 
619                     
620                       end
621                     
622                       ///////////////////////////
623                       // Clock & reset control //
624                       ///////////////////////////
625                       logic sck_n;
626                       logic rst_spi_n;
627                       prim_mubi_pkg::mubi4_t [ScanModeUseLast-1:0] scanmode;
628                     
629                       prim_mubi4_sync #(
630                         .NumCopies(int'(ScanModeUseLast)),
631                         .AsyncOn(0) // clock/reset below is only used for SVAs.
632                       ) u_scanmode_sync  (
633                         .clk_i,
634                         .rst_ni,
635                         .mubi_i(scanmode_i),
636                         .mubi_o(scanmode)
637                       );
638                     
639                       prim_clock_inv #(
640                         .NoFpgaBufG(1'b1)
641                       ) u_clk_spi (
642                         .clk_i(cio_sck_i),
643                         .clk_no(sck_n),
644                         .scanmode_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkInvSel]))
645                       );
646                     
647        1/1            assign sck_monitor_o = cio_sck_i;
           Tests:       T1 T2 T3 
648        1/1            assign clk_spi_in    = cio_sck_i;
           Tests:       T1 T2 T3 
649        1/1            assign clk_spi_out   = sck_n;
           Tests:       T1 T2 T3 
650                     
651                       prim_clock_mux2 #(
652                         .NoFpgaBufG(1'b1)
653                       ) u_clk_spi_in_mux (
654                         .clk0_i(clk_spi_in),
655                         .clk1_i(scan_clk_i),
656                         .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkMuxSel]) | mbist_en_i),
657                         .clk_o(clk_spi_in_muxed)
658                       );
659                     
660                       prim_clock_buf #(
661                         .RegionSel(1'b1)
662                       ) u_clk_spi_in_buf(
663                         .clk_i (clk_spi_in_muxed),
664                         .clk_o (clk_spi_in_buf)
665                       );
666                     
667                       prim_clock_mux2 #(
668                         .NoFpgaBufG(1'b1)
669                       ) u_clk_spi_out_mux (
670                         .clk0_i(clk_spi_out),
671                         .clk1_i(scan_clk_i),
672                         .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkMuxSel])),
673                         .clk_o(clk_spi_out_muxed)
674                       );
675                     
676                       prim_clock_buf #(
677                         .RegionSel(1'b1)
678                       ) u_clk_spi_out_buf(
679                         .clk_i (clk_spi_out_muxed),
680                         .clk_o (clk_spi_out_buf)
681                       );
682                     
683                       // CSb muxed to scan clock
684                       prim_clock_mux2 #(
685                         .NoFpgaBufG(1'b 1)
686                       ) u_clk_csb_mux (
687                         .clk0_i (clk_csb_buf),
688                         .clk1_i (scan_clk_i ),
689                         .sel_i  (prim_mubi_pkg::mubi4_test_true_strict(scanmode[ClkMuxSel])),
690                         .clk_o  (clk_csb_muxed)
691                       );
692                     
693                       prim_clock_buf #(
694                         .NoFpgaBuf (1'b 1)
695                       ) u_clk_csb_buf (
696                         .clk_i (clk_csb_muxed),
697                         .clk_o (clk_csb      )
698                       );
699                     
700                       prim_clock_mux2 #(
701                         .NoFpgaBufG(1'b1)
702                       ) u_csb_rst_scan_mux (
703                         .clk0_i(rst_ni & ~rst_csb_buf),
704                         .clk1_i(scan_rst_ni),
705                         .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[CsbRstMuxSel])),
706                         .clk_o(rst_spi_n)
707                       );
708                     
709                       logic rst_spi_in_n, rst_spi_out_sync_n, rst_spi_out_n;
710        1/1            assign rst_spi_in_n = rst_spi_n;
           Tests:       T1 T2 T3 
711                     
712                       // Synchronizes reset de-assertion to safely occur in the outclk domain.
713                       prim_flop #(
714                         .Width      (1),
715                         .ResetValue (1'b0)
716                       ) u_rst_spi_out_sync (
717                         .clk_i (clk_spi_in_buf),
718                         .rst_ni(rst_spi_n),
719                         .d_i   (1'b1),
720                         .q_o   (rst_spi_out_sync_n)
721                       );
722                     
723                       prim_clock_mux2 #(
724                         .NoFpgaBufG(1'b1)
725                       ) u_csb_rst_out_scan_mux (
726                         .clk0_i(rst_spi_out_sync_n),
727                         .clk1_i(scan_rst_ni),
728                         .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[CsbRstMuxSel])),
729                         .clk_o(rst_spi_out_n)
730                       );
731                     
732                       logic tpm_rst_in_n, tpm_rst_out_sync_n, tpm_rst_out_n, sys_tpm_rst_n;
733                     
734                       prim_clock_mux2 #(
735                         .NoFpgaBufG(1'b1)
736                       ) u_tpm_csb_rst_scan_mux (
737                         .clk0_i (rst_ni & ~rst_tpm_csb_buf),
738                         .clk1_i (scan_rst_ni),
739                         .sel_i  (prim_mubi_pkg::mubi4_test_true_strict(scanmode[TpmRstSel])),
740                         .clk_o  (tpm_rst_in_n)
741                       );
742                     
743                       // Synchronizes reset de-assertion to safely occur in the outclk domain.
744                       prim_flop #(
745                         .Width      (1),
746                         .ResetValue (1'b0)
747                       ) u_tpm_rst_out_sync (
748                         .clk_i (clk_spi_in_buf),
749                         .rst_ni(tpm_rst_in_n),
750                         .d_i   (1'b1),
751                         .q_o   (tpm_rst_out_sync_n)
752                       );
753                     
754                       prim_clock_mux2 #(
755                         .NoFpgaBufG(1'b1)
756                       ) u_tpm_rst_out_scan_mux (
757                         .clk0_i (tpm_rst_out_sync_n),
758                         .clk1_i (scan_rst_ni),
759                         .sel_i  (prim_mubi_pkg::mubi4_test_true_strict(scanmode[TpmRstSel])),
760                         .clk_o  (tpm_rst_out_n)
761                       );
762                     
763                       // TPM Read FIFO uses TPM CSb as a reset.
764                       // The write port is clocked at SYS_CLK. Metastability may occur as CSb may
765                       // be asserted, de-asserted independent of SYS_CLK. This reset synchronizer
766                       // (sync to SYS_CLK), may delay the reset signal by 2 SYS_CLK when TPM_CSb
767                       // is de-asserted.
768                       prim_rst_sync #(
769                         .ActiveHigh (1'b 0),
770                         .SkipScan   (1'b 0)
771                       ) u_tpm_csb_rst_sync (
772                         .clk_i,
773                         .d_i   (tpm_rst_in_n),
774                         .q_o   (sys_tpm_rst_n),
775                     
776                         .scan_rst_ni,
777                         .scanmode_i (scanmode[TpmRstSel])
778                       );
779                     
780                       // CSb edge on the system clock
781                       spid_csb_sync u_spid_csb_sync (
782                         .clk_i,
783                         .rst_ni,
784                         .sck_i                     (clk_spi_in_buf),
785                         .sck_pulse_en_i            (1'b1),
786                         .csb_i                     (clk_csb),
787                         .csb_deasserted_pulse_o    (sys_csb_deasserted_pulse)
788                       );
789                     
790                       prim_flop_2sync #(
791                         .Width       (1)
792                       ) u_sys_csb_syncd (
793                         .clk_i,
794                         .rst_ni,
795                         .d_i       (sys_csb),
796                         .q_o       (sys_csb_syncd)
797                       );
798                     
799                       // TPM CSb 2FF sync to SYS_CLK
800                       prim_flop_2sync #(
801                         .Width      (1    ),
802                         .ResetValue (1'b 1)
803                       ) u_sys_tpm_csb_sync (
804                         .clk_i,
805                         .rst_ni,
806                     
807                         .d_i (sys_tpm_csb_buf),
808                         .q_o (sys_tpm_csb_syncd)
809                       );
810                     
811                       //////////////////////////////
812                       // SPI_DEVICE mode selector //
813                       //////////////////////////////
814                       // This logic chooses appropriate signals based on input SPI_DEVICE mode.
815                       // Assume spi_mode does not change dynamically
816                     
817                       // io_mode to spi_s2p io_mode should be affected at the negedge of SPI_CLK
818                       // based on SPI protocol. the internal io_mode signal is generated by SPI
819                       // input signals. So, the io_mode should be latched at clk_spi_out to not
820                       // introduce the timing loop.
821                       //
822                       // example: cmdparse triggers sel_dp at 8th beat of CMD bit.
823                       //       -> readcmd activates, it also changes IoMode if opcode is DualIO
824                       //          or QuadIO commands
825                       //       -> changed io_mode affects spi_s2p module, which again affects
826                       //          cmdparse module.
827                       always_ff @(posedge clk_spi_out_buf or negedge rst_spi_out_n) begin
828        2/2              if (!rst_spi_out_n) io_mode_outclk <= SingleIO;
           Tests:       T1 T2 T3  | T1 T2 T3 
829        1/1              else                io_mode_outclk <= io_mode;
           Tests:       T6 T7 T8 
830                       end
831                     
832                       // SCK clock domain MUX for SRAM access for Flash and Passthrough
833                       always_comb begin
834        1/1              flash_sram_l2m = '{ default: '0 };
           Tests:       T1 T2 T3 
835                     
836        1/1              for (int unsigned i = IoModeCmdParse ; i < IoModeEnd ; i++) begin
           Tests:       T1 T2 T3 
837        1/1                sub_sram_m2l[i] = '{
           Tests:       T1 T2 T3 
838                             rvalid: 1'b 0,
839                             rdata: '0,
840                             rerror: '{uncorr: 1'b 0, corr: 1'b 0}
841                           };
842                         end
843                     
844        1/1              unique case (cmd_dp_sel)
           Tests:       T1 T2 T3 
845                           DpReadCmd, DpReadSFDP: begin
846                             // SRAM:: Remember this has glitch
847                             // switch should happen only when clock gate is disabled.
848        1/1                  flash_sram_l2m = sub_sram_l2m[IoModeReadCmd];
           Tests:       T7 T8 T9 
849        1/1                  sub_sram_m2l[IoModeReadCmd] = flash_sram_m2l;
           Tests:       T7 T8 T9 
850                           end
851                     
852                           DpUpload: begin
853        1/1                  flash_sram_l2m = sub_sram_l2m[IoModeUpload];
           Tests:       T12 T50 T38 
854        1/1                  sub_sram_m2l[IoModeUpload] = flash_sram_m2l;
           Tests:       T12 T50 T38 
855                           end
856                     
857                           default: begin
858                             if (cmd_only_dp_sel == DpUpload) begin
859                               // Be ready to upload commands on the 8th command bit, when directed
860                               flash_sram_l2m = sub_sram_l2m[IoModeUpload];
861                               sub_sram_m2l[IoModeUpload] = flash_sram_m2l;
862                             end else begin
863                               // DpNone, DpReadStatus, DpReadJEDEC
864                               flash_sram_l2m = '{default: '0 };
865                             end
866                           end
867                         endcase
868                       end
869                     
870                       always_comb begin
871                         // SRAM comb logic is in SCK clock domain
872        1/1              mem_b_l2m = '{ default: '0 };
           Tests:       T1 T2 T3 
873                     
874        1/1              flash_sram_m2l = '{
           Tests:       T1 T2 T3 
875                           rvalid: 1'b 0,
876                           rdata: '0,
877                           rerror: '{uncorr: 1'b 0, corr: 1'b 0}
878                         };
879        1/1              tpm_sram_m2l = '{
           Tests:       T1 T2 T3 
880                           rvalid: 1'b 0,
881                           rdata: '0,
882                           rerror: '{uncorr: 1'b 0, corr: 1'b 0}
883                         };
884                     
885        1/1              if (!sck_csb && ((spi_mode == FlashMode) || (spi_mode == PassThrough))) begin
           Tests:       T1 T2 T3 
886        1/1                mem_b_l2m = flash_sram_l2m;
           Tests:       T2 T6 T7 
887        1/1                flash_sram_m2l = mem_b_m2l;
           Tests:       T2 T6 T7 
888        1/1              end else if (cfg_tpm_en) begin
           Tests:       T1 T2 T3 
889        1/1                mem_b_l2m = tpm_sram_l2m;
           Tests:       T4 T5 T15 
890        1/1                tpm_sram_m2l = mem_b_m2l;
           Tests:       T4 T5 T15 
891                         end
                        MISSING_ELSE
892                       end
893                     
894                       // inverted SCK clock domain MUX for IO Mode and P2S
895                       always_comb begin
896        1/1              io_mode = SingleIO;
           Tests:       T1 T2 T3 
897        1/1              p2s_valid = 1'b 0;
           Tests:       T1 T2 T3 
898        1/1              p2s_data  = 8'h 0;
           Tests:       T1 T2 T3 
899        1/1              sub_p2s_sent = '{default: 1'b 0};
           Tests:       T1 T2 T3 
900                     
901        1/1              unique case (spi_mode)
           Tests:       T1 T2 T3 
902                           FlashMode, PassThrough: begin
903        1/1                  unique case (cmd_dp_sel)
           Tests:       T1 T2 T3 
904                               DpNone: begin
905        1/1                      io_mode = sub_iomode[IoModeCmdParse];
           Tests:       T1 T2 T3 
906                     
907        1/1                      sub_p2s_sent[IoModeCmdParse] = p2s_sent;
           Tests:       T1 T2 T3 
908                     
909                               end
910                               DpReadCmd, DpReadSFDP: begin
911        1/1                      io_mode = sub_iomode[IoModeReadCmd];
           Tests:       T7 T8 T9 
912                     
913        1/1                      p2s_valid = sub_p2s_valid[IoModeReadCmd];
           Tests:       T7 T8 T9 
914        1/1                      p2s_data  = sub_p2s_data[IoModeReadCmd];
           Tests:       T7 T8 T9 
915        1/1                      sub_p2s_sent[IoModeReadCmd] = p2s_sent;
           Tests:       T7 T8 T9 
916                               end
917                               DpReadStatus: begin
918        1/1                      io_mode = sub_iomode[IoModeStatus];
           Tests:       T8 T12 T88 
919                     
920        1/1                      p2s_valid = sub_p2s_valid[IoModeStatus];
           Tests:       T8 T12 T88 
921        1/1                      p2s_data  = sub_p2s_data[IoModeStatus];
           Tests:       T8 T12 T88 
922        1/1                      sub_p2s_sent[IoModeStatus] = p2s_sent;
           Tests:       T8 T12 T88 
923                     
924                               end
925                     
926                               DpReadJEDEC: begin
927        1/1                      io_mode = sub_iomode[IoModeJedec];
           Tests:       T17 T38 T40 
928                     
929        1/1                      p2s_valid = sub_p2s_valid[IoModeJedec];
           Tests:       T17 T38 T40 
930        1/1                      p2s_data  = sub_p2s_data[IoModeJedec];
           Tests:       T17 T38 T40 
931        1/1                      sub_p2s_sent[IoModeJedec] = p2s_sent;
           Tests:       T17 T38 T40 
932                               end
933                     
934                               DpUpload: begin
935        1/1                      io_mode = sub_iomode[IoModeUpload];
           Tests:       T12 T50 T38 
936                     
937        1/1                      p2s_valid = sub_p2s_valid[IoModeUpload];
           Tests:       T12 T50 T38 
938        1/1                      p2s_data  = sub_p2s_data[IoModeUpload];
           Tests:       T12 T50 T38 
939        1/1                      sub_p2s_sent[IoModeUpload] = p2s_sent;
           Tests:       T12 T50 T38 
940                               end
941                               // DpUnknown:
942                               default: begin
943                                 io_mode = sub_iomode[IoModeCmdParse];
944                     
945                                 sub_p2s_sent[IoModeCmdParse] = p2s_sent;
946                               end
947                             endcase
948                           end
949                     
950                           default: begin
951                             io_mode = SingleIO;
952                           end
953                         endcase
954                       end
955                       `ASSERT_KNOWN(SpiModeKnown_A, spi_mode)
956                     
957                       // Add 2-cycle delay to flash read data when requested.
958                       // This mechanism should only be deployed on read commands with dummy cycles,
959                       // so omit delaying the output enable.
960                       logic [3:0] internal_sd_stg1_d, internal_sd_stg1_q;
961                       logic [3:0] internal_sd_stg2_d, internal_sd_stg2_q;
962                       logic [3:0] internal_sd_en_stg1, internal_sd_en_stg2;
963                       logic intercept_en_stg1, intercept_en_stg2;
964        1/1            assign internal_sd_stg1_d = internal_sd;
           Tests:       T1 T2 T3 
965        1/1            assign internal_sd_stg2_d = internal_sd_stg1_q;
           Tests:       T1 T2 T3 
966                     
967                       prim_flop #(
968                         .Width         ($bits(internal_sd_stg1_d)),
969                         .ResetValue    ('0)
970                       ) u_read_pipe_stg1 (
971                         .clk_i     (clk_spi_out_buf),
972                         .rst_ni    (rst_spi_out_n),
973                         .d_i       (internal_sd_stg1_d),
974                         .q_o       (internal_sd_stg1_q)
975                       );
976                     
977                       prim_flop #(
978                         .Width         ($bits(internal_sd_stg2_d)),
979                         .ResetValue    ('0)
980                       ) u_read_pipe_stg2 (
981                         .clk_i     (clk_spi_out_buf),
982                         .rst_ni    (rst_spi_out_n),
983                         .d_i       (internal_sd_stg2_d),
984                         .q_o       (internal_sd_stg2_q)
985                       );
986                     
987                       prim_flop #(
988                         .Width         ($bits(internal_sd_en)),
989                         .ResetValue    ('0)
990                       ) u_read_en_pipe_stg1 (
991                         .clk_i     (clk_spi_out_buf),
992                         .rst_ni    (rst_spi_out_n),
993                         .d_i       (internal_sd_en),
994                         .q_o       (internal_sd_en_stg1)
995                       );
996                     
997                       prim_flop #(
998                         .Width         ($bits(internal_sd_en_stg1)),
999                         .ResetValue    ('0)
1000                      ) u_read_en_pipe_stg2 (
1001                        .clk_i     (clk_spi_out_buf),
1002                        .rst_ni    (rst_spi_out_n),
1003                        .d_i       (internal_sd_en_stg1),
1004                        .q_o       (internal_sd_en_stg2)
1005                      );
1006                    
1007                      prim_flop #(
1008                        .Width         (1),
1009                        .ResetValue    ('0)
1010                      ) u_read_intercept_pipe_stg1 (
1011                        .clk_i     (clk_spi_out_buf),
1012                        .rst_ni    (rst_spi_out_n),
1013                        .d_i       (intercept_en),
1014                        .q_o       (intercept_en_stg1)
1015                      );
1016                    
1017                      prim_flop #(
1018                        .Width         (1),
1019                        .ResetValue    ('0)
1020                      ) u_read_intercept_pipe_stg2 (
1021                        .clk_i     (clk_spi_out_buf),
1022                        .rst_ni    (rst_spi_out_n),
1023                        .d_i       (intercept_en_stg1),
1024                        .q_o       (intercept_en_stg2)
1025                      );
1026                    
1027                      always_comb begin
1028       1/1              if (cmd_read_pipeline_sel) begin
           Tests:       T1 T2 T3 
1029       1/1                internal_sd_out = internal_sd_stg2_q;
           Tests:       T7 T8 T11 
1030       1/1                internal_sd_en_out = internal_sd_en_stg2;
           Tests:       T7 T8 T11 
1031       1/1                intercept_en_out = intercept_en_stg2;
           Tests:       T7 T8 T11 
1032                        end else begin
1033       1/1                internal_sd_out = internal_sd;
           Tests:       T1 T2 T3 
1034       1/1                internal_sd_en_out = internal_sd_en;
           Tests:       T1 T2 T3 
1035       1/1                intercept_en_out = intercept_en;
           Tests:       T1 T2 T3 
1036                        end
1037                      end
1038                    
1039                    
1040                      always_comb begin
1041       1/1              cio_sd_o    = internal_sd_out;
           Tests:       T1 T2 T3 
1042       1/1              cio_sd_en_o = internal_sd_en_out;
           Tests:       T1 T2 T3 
1043                    
1044       1/1              if (cfg_tpm_en && !sck_tpm_csb_buf) begin : miso_tpm
           Tests:       T1 T2 T3 
1045                          // TPM transaction is on-going. MOSI, MISO is being used by TPM
1046       1/1                cio_sd_o    = {2'b 00, tpm_miso,    1'b 0};
           Tests:       T4 T5 T15 
1047       1/1                cio_sd_en_o = {2'b 00, tpm_miso_en, 1'b 0};
           Tests:       T4 T5 T15 
1048                    
1049                        end else begin : spi_out_flash_passthrough
1050                          // SPI Flash, Passthrough modes
1051       1/1                unique case (spi_mode)
           Tests:       T1 T2 T3 
1052                            FlashMode: begin
1053       1/1                    cio_sd_o    = internal_sd_out;
           Tests:       T1 T2 T3 
1054       1/1                    cio_sd_en_o = internal_sd_en_out;
           Tests:       T1 T2 T3 
1055                            end
1056                    
1057                            PassThrough: begin
1058       1/1                    if (intercept_en_out) begin
           Tests:       T6 T7 T8 
1059       1/1                      cio_sd_o    = internal_sd_out;
           Tests:       T8 T12 T17 
1060       1/1                      cio_sd_en_o = internal_sd_en_out;
           Tests:       T8 T12 T17 
1061                              end else begin
1062       1/1                      cio_sd_o    = passthrough_sd;
           Tests:       T6 T7 T8 
1063       1/1                      cio_sd_en_o = passthrough_sd_en;
           Tests:       T6 T7 T8 
1064                              end
1065                            end
1066                    
1067                            default: begin
1068                              cio_sd_o    = internal_sd;
1069                              cio_sd_en_o = internal_sd_en;
1070                            end
1071                          endcase
1072                        end
1073                      end
1074                    
1075                      // Assume `intercept` is registered (SPI_IN).
1076                      // passthrough assumed signal shall be registered in (SPI_OUT)
1077                      always_ff @(posedge clk_spi_out_buf or negedge rst_spi_out_n) begin
1078       2/2              if (!rst_spi_out_n) intercept_en <= 1'b 0;
           Tests:       T1 T2 T3  | T1 T2 T3 
1079       1/1              else                intercept_en <= |intercept;
           Tests:       T6 T7 T8 
1080                      end
1081                      // intercept_en shall not be de-asserted except mailbox
1082                      `ASSUME(InterceptLevel_M,
1083                        $rose(|{intercept.status, intercept.jedec, intercept.sfdp}) |=>
1084                          ##1 $stable(intercept_en) until !rst_spi_out_n,
1085                        clk_spi_out_buf, !rst_spi_out_n)
1086                    
1087                      ////////////////////////////
1088                      // SPI Serial to Parallel //
1089                      ////////////////////////////
1090                      spi_s2p u_s2p (
1091                        .clk_i        (clk_spi_in_buf),
1092                        .rst_ni       (rst_spi_in_n),
1093                    
1094                        // SPI interface
1095                        .s_i          (cio_sd_i),
1096                    
1097                        .data_valid_o (s2p_data_valid),
1098                        .data_o       (s2p_data      ),
1099                    
1100                        // Config (changed dynamically)
1101                        .order_i      (rxorder),
1102                        .io_mode_i    (io_mode_outclk)
1103                      );
1104                    
1105                      spi_p2s u_p2s (
1106                        .clk_i        (clk_spi_out_buf),
1107                        .rst_ni       (rst_spi_out_n),
1108                    
1109                        .data_valid_i (p2s_valid),
1110                        .data_i       (p2s_data),
1111                        .data_sent_o  (p2s_sent),
1112                    
1113                        .csb_i        (sck_csb),
1114                        .s_en_o       (internal_sd_en),
1115                        .s_o          (internal_sd),
1116                    
1117                        .order_i      (txorder),
1118                        .io_mode_i    (io_mode_outclk)
1119                      );
1120                    
1121                      ////////////////////
1122                      // SPI Flash Mode //
1123                      ////////////////////
1124                    
1125                      spi_cmdparse u_cmdparse (
1126                        .clk_i  (clk_spi_in_buf),
1127                        .rst_ni (rst_spi_in_n),
1128                    
1129                        .data_valid_i (s2p_data_valid),
1130                        .data_i       (s2p_data),
1131                    
1132                        .spi_mode_i   (spi_mode),
1133                    
1134                        .cmd_info_i   (cmd_info),
1135                    
1136                        .sck_status_busy_i(sck_status_busy),
1137                    
1138                        .io_mode_o    (sub_iomode[IoModeCmdParse]),
1139                    
1140                        .sel_dp_o          (cmd_dp_sel),
1141                        .cmd_only_sel_dp_o (cmd_only_dp_sel),
1142                        .cmd_info_o        (cmd_info_broadcast),
1143                        .cmd_info_idx_o    (cmd_info_idx_broadcast),
1144                        .cmd_only_info_o     (cmd_only_info_broadcast),
1145                        .cmd_only_info_idx_o (cmd_only_info_idx_broadcast),
1146                        .cmd_sync_pulse_o  (cmd_sync_pulse),
1147                    
1148                        .cmd_read_pipeline_sel_o (cmd_read_pipeline_sel),
1149                    
1150                        .cfg_intercept_en_status_i (cfg_intercept_en.status),
1151                        .cfg_intercept_en_jedec_i  (cfg_intercept_en.jedec),
1152                        .cfg_intercept_en_sfdp_i   (cfg_intercept_en.sfdp),
1153                    
1154                        .intercept_status_o (intercept.status),
1155                        .intercept_jedec_o  (intercept.jedec),
1156                        .intercept_sfdp_o   (intercept.sfdp),
1157                    
1158                        // Not used for now
1159                        .cmd_config_req_o (),
1160                        .cmd_config_idx_o ()
1161                      );
1162                    
1163                      spi_readcmd u_readcmd (
1164                        .clk_i  (clk_spi_in_buf),
1165                        .rst_ni (rst_spi_in_n),
1166                    
1167                        .clk_out_i  (clk_spi_out_buf),
1168                        .rst_out_ni (rst_spi_out_n),
1169                    
1170                        .sys_clk_i  (clk_i),
1171                        .sys_rst_ni (rst_ni),
1172                    
1173                        .sel_dp_i   (cmd_dp_sel),
1174                    
1175                        // SRAM interface
1176                        .sram_l2m_o (sub_sram_l2m[IoModeReadCmd]),
1177                        .sram_m2l_i (sub_sram_m2l[IoModeReadCmd]),
1178                    
1179                        // S2P
1180                        .s2p_valid_i   (s2p_data_valid),
1181                        .s2p_byte_i    (s2p_data),
1182                    
1183                        // P2S
1184                        .p2s_valid_o   (sub_p2s_valid [IoModeReadCmd]),
1185                        .p2s_byte_o    (sub_p2s_data  [IoModeReadCmd]),
1186                        .p2s_sent_i    (sub_p2s_sent  [IoModeReadCmd]),
1187                    
1188                        .spi_mode_i       (spi_mode),
1189                    
1190                        .cmd_info_i     (cmd_info_broadcast),
1191                        .cmd_info_idx_i (cmd_info_idx_broadcast),
1192                    
1193                        .readbuf_threshold_i (readbuf_threshold),
1194                        .sys_readbuf_clr_i   (readbuf_clr),
1195                    
1196                        .addr_4b_en_i (cfg_addr_4b_en),
1197                    
1198                        .mailbox_en_i           (cfg_mailbox_en ),
1199                        .cfg_intercept_en_mbx_i (cfg_intercept_en.mbx),
1200                    
1201                        .mailbox_addr_i    (mailbox_addr   ),
1202                        .mailbox_assumed_o (intercept.mbx  ),
1203                    
1204                        .readbuf_address_o (readbuf_addr_sck),
1205                    
1206                        .io_mode_o (sub_iomode [IoModeReadCmd]),
1207                    
1208                        .sck_read_watermark_o (flash_sck_readbuf_watermark),
1209                        .sck_read_flip_o      (flash_sck_readbuf_flip)
1210                      );
1211                    
1212                      // Begin: Read Status ==============================================
1213                      logic readstatus_qe;
1214                      logic [23:0] readstatus_q;
1215                      logic [23:0] readstatus_d;
1216                    
1217       1/1            assign readstatus_qe =  reg2hw.flash_status.busy.qe &&
           Tests:       T6 T8 T9 
1218                                              reg2hw.flash_status.wel.qe &&
1219                                              reg2hw.flash_status.status.qe;
1220       1/1            assign readstatus_q = { reg2hw.flash_status.status.q,
           Tests:       T1 T2 T3 
1221                                              reg2hw.flash_status.wel.q,
1222                                              reg2hw.flash_status.busy.q
1223                                            };
1224       1/1            assign hw2reg.flash_status.busy.d   = readstatus_d[0];
           Tests:       T1 T2 T3 
1225       1/1            assign hw2reg.flash_status.wel.d    = readstatus_d[1];
           Tests:       T1 T2 T3 
1226       1/1            assign hw2reg.flash_status.status.d = readstatus_d[23:2];
           Tests:       T1 T2 T3 
1227                    
1228       1/1            assign sck_status_wr_set = (cmd_only_dp_sel == DpWrEn);
           Tests:       T1 T2 T3 
1229       1/1            assign sck_status_wr_clr = (cmd_only_dp_sel == DpWrDi);
           Tests:       T1 T2 T3 
1230                    
1231                      logic flash_status_sync_fifo_clr;
1232       1/1            assign flash_status_sync_fifo_clr = reg2hw.control.flash_status_fifo_clr.q;
           Tests:       T1 T2 T3 
1233                      assign hw2reg.control.flash_status_fifo_clr.d  = '0;
1234                      assign hw2reg.control.flash_status_fifo_clr.de = 1'b1;
1235                    
1236                      spid_status u_spid_status (
1237                        .clk_i  (clk_spi_in_buf),
1238                        .rst_ni (rst_spi_in_n),
1239                    
1240                        .clk_out_i  (clk_spi_out_buf),
1241                        .rst_out_ni (rst_spi_out_n),
1242                    
1243                        .clk_csb_i (clk_csb),
1244                    
1245                        .sys_clk_i  (clk_i),
1246                        .sys_rst_ni (rst_ni),
1247                    
1248                        .sys_csb_deasserted_pulse_i (sys_csb_deasserted_pulse),
1249                    
1250                        .sys_update_clr_i(flash_status_sync_fifo_clr),
1251                    
1252                        .sys_status_we_i (readstatus_qe),
1253                        .sys_status_i    (readstatus_q),
1254                        .sys_status_o    (readstatus_d),
1255                    
1256                        .sel_dp_i       (cmd_dp_sel),
1257                        .cmd_info_i     (cmd_info_broadcast),
1258                        .cmd_info_idx_i (cmd_info_idx_broadcast),
1259                    
1260                        .outclk_p2s_valid_o (sub_p2s_valid[IoModeStatus]),
1261                        .outclk_p2s_byte_o  (sub_p2s_data[IoModeStatus]),
1262                        .outclk_p2s_sent_i  (sub_p2s_sent[IoModeStatus]),
1263                    
1264                        .io_mode_o   (sub_iomode[IoModeStatus]),
1265                    
1266                        .inclk_busy_set_i  (sck_status_busy_set), // SCK domain
1267                    
1268                        .inclk_we_set_i (sck_status_wr_set),
1269                        .inclk_we_clr_i (sck_status_wr_clr),
1270                    
1271                        .inclk_status_commit_i  (s2p_data_valid),
1272                        .cmd_sync_status_busy_o (cmd_sync_status_busy),
1273                        .cmd_sync_status_wel_o  (cmd_sync_status_wel),
1274                        .sck_status_busy_o      (sck_status_busy),
1275                        .csb_busy_broadcast_o   (csb_status_busy_broadcast), // SCK domain
1276                        .scan_rst_ni,
1277                        .scanmode_i             (scanmode[StatusFifoRstSel])
1278                      );
1279                    
1280                      // Tie unused
1281                      logic unused_sub_sram_status;
1282       0/1     ==>    assign unused_sub_sram_status = ^{
1283                        sub_sram_l2m[IoModeStatus],
1284                        sub_sram_m2l[IoModeStatus]
1285                      };
1286                      assign sub_sram_l2m[IoModeStatus] = '0;
1287                    
1288                      // End: Read Status ------------------------------------------------
1289                    
1290                      spid_jedec u_jedec (
1291                        .clk_i  (clk_spi_in_buf),
1292                        .rst_ni (rst_spi_in_n),
1293                    
1294                        .clk_out_i  (clk_spi_out_buf),
1295                        .rst_out_ni (rst_spi_out_n),
1296                    
1297                        .cmd_sync_pulse_i (cmd_sync_pulse),
1298                    
1299                        .sys_jedec_i (jedec_cfg),
1300                    
1301                        .io_mode_o (sub_iomode[IoModeJedec]),
1302                    
1303                        .sel_dp_i       (cmd_dp_sel),
1304                        .cmd_info_i     (cmd_info_broadcast),
1305                        .cmd_info_idx_i (cmd_info_idx_broadcast),
1306                    
1307                        .outclk_p2s_valid_o (sub_p2s_valid[IoModeJedec]),
1308                        .outclk_p2s_byte_o  (sub_p2s_data[IoModeJedec]),
1309                        .outclk_p2s_sent_i  (sub_p2s_sent[IoModeJedec])
1310                      );
1311                      // Tie unused
1312                      logic unused_sub_sram_jedec;
1313       0/1     ==>    assign unused_sub_sram_jedec = ^{
1314                        sub_sram_l2m[IoModeJedec],
1315                        sub_sram_m2l[IoModeJedec]
1316                      };
1317                      assign sub_sram_l2m[IoModeJedec] = '0;
1318                    
1319                      // Begin: Upload ===================================================
1320                      spid_upload #(
1321                        .CmdFifoBaseAddr  (SramCmdFifoIdx),
1322                        .CmdFifoDepth     (SramCmdFifoDepth),
1323                        .AddrFifoBaseAddr (SramAddrFifoIdx),
1324                        .AddrFifoDepth    (SramAddrFifoDepth),
1325                        .PayloadBaseAddr  (SramPayloadIdx),
1326                        .PayloadDepth     (SramPayloadDepth),
1327                    
1328                        .SpiByte ($bits(spi_byte_t))
1329                      ) u_upload (
1330                        .clk_i  (clk_spi_in_buf),
1331                        .rst_ni (rst_spi_in_n),
1332                    
1333                        .sys_clk_i  (clk_i),
1334                        .sys_rst_ni (rst_ni),
1335                    
1336                        .clk_csb_i (clk_csb),
1337                    
1338                        .sel_dp_i          (cmd_dp_sel),
1339                        .cmd_only_sel_dp_i (cmd_only_dp_sel),
1340                    
1341                        .sck_sram_o (sub_sram_l2m[IoModeUpload]),
1342                        .sck_sram_i (sub_sram_m2l[IoModeUpload]),
1343                    
1344                        .sys_cmdfifo_sram_o (sys_sram_l2m[SysSramCmdFifo]),
1345                        .sys_cmdfifo_sram_i (sys_sram_m2l[SysSramCmdFifo]),
1346                        .sys_cmdfifo_gnt_i  (sys_sram_gnt[SysSramCmdFifo]),
1347                    
1348                        .sys_addrfifo_sram_o (sys_sram_l2m[SysSramAddrFifo]),
1349                        .sys_addrfifo_sram_i (sys_sram_m2l[SysSramAddrFifo]),
1350                        .sys_addrfifo_gnt_i  (sys_sram_gnt[SysSramAddrFifo]),
1351                    
1352                        // SYS clock FIFO interface
1353                        .sys_cmdfifo_rvalid_o (cmdfifo_rvalid),
1354                        .sys_cmdfifo_rready_i (cmdfifo_rready),
1355                        .sys_cmdfifo_rdata_o  (cmdfifo_rdata),
1356                    
1357                        .sys_addrfifo_rvalid_o (addrfifo_rvalid),
1358                        .sys_addrfifo_rready_i (addrfifo_rready),
1359                        .sys_addrfifo_rdata_o  (addrfifo_rdata),
1360                    
1361                        // Interface: SPI to Parallel
1362                        .s2p_valid_i  (s2p_data_valid),
1363                        .s2p_byte_i   (s2p_data),
1364                    
1365                        // Interface: Parallel to SPI
1366                        .p2s_valid_o (sub_p2s_valid[IoModeUpload]),
1367                        .p2s_data_o  (sub_p2s_data [IoModeUpload]),
1368                        .p2s_sent_i  (sub_p2s_sent [IoModeUpload]),
1369                    
1370                        .spi_mode_i (spi_mode),
1371                    
1372                        .cmd_sync_cfg_addr_4b_en_i (cmd_sync_addr_4b_en),
1373                        .cmd_sync_status_wel_i     (cmd_sync_status_wel),
1374                        .cmd_sync_status_busy_i    (cmd_sync_status_busy),
1375                    
1376                        .cmd_only_info_i     (cmd_only_info_broadcast),
1377                        .cmd_only_info_idx_i (cmd_only_info_idx_broadcast),
1378                    
1379                        .io_mode_o (sub_iomode[IoModeUpload]),
1380                    
1381                        .set_busy_o (sck_status_busy_set),
1382                    
1383                        .sys_cmdfifo_set_o       (cmdfifo_set_pulse),
1384                        .sys_cmdfifo_notempty_o  (cmdfifo_notempty),
1385                        .sys_cmdfifo_full_o      (), // not used
1386                        .sys_addrfifo_notempty_o (addrfifo_notempty),
1387                        .sys_addrfifo_full_o     (), // not used
1388                        .sys_payload_overflow_o  (payload_overflow),
1389                    
1390                        .sys_cmdfifo_depth_o     (cmdfifo_depth),
1391                        .sys_addrfifo_depth_o    (addrfifo_depth),
1392                        .sys_payload_depth_o     (payload_depth),
1393                        .sys_payload_start_idx_o (payload_start_idx)
1394                      );
1395                      // FIFO connect
1396       1/1            assign cmdfifo_rready = reg2hw.upload_cmdfifo.data.re;
           Tests:       T12 T50 T38 
1397       1/1            assign hw2reg.upload_cmdfifo.data.d = cmdfifo_rdata[7:0];
           Tests:       T1 T2 T3 
1398       1/1            assign hw2reg.upload_cmdfifo.busy.d = cmdfifo_rdata[13];
           Tests:       T1 T2 T3 
1399       1/1            assign hw2reg.upload_cmdfifo.wel.d = cmdfifo_rdata[14];
           Tests:       T1 T2 T3 
1400       1/1            assign hw2reg.upload_cmdfifo.addr4b_mode.d = cmdfifo_rdata[15];
           Tests:       T1 T2 T3 
1401                      logic unused_cmdfifo_re;
1402       1/1            assign unused_cmdfifo_re = ^{reg2hw.upload_cmdfifo.busy.re,
           Tests:       T12 T50 T38 
1403                                                   reg2hw.upload_cmdfifo.wel.re,
1404                                                   reg2hw.upload_cmdfifo.addr4b_mode.re};
1405                      logic unused_cmdfifo_q;
1406       1/1            assign unused_cmdfifo_q = ^{reg2hw.upload_cmdfifo.data.q,
           Tests:       T1 T2 T3 
1407                                                  reg2hw.upload_cmdfifo.busy.q,
1408                                                  reg2hw.upload_cmdfifo.wel.q,
1409                                                  reg2hw.upload_cmdfifo.addr4b_mode.q,
1410                                                  cmdfifo_rdata[12:8],
1411                                                  cmdfifo_rvalid};
1412                    
1413       1/1            assign addrfifo_rready = reg2hw.upload_addrfifo.re;
           Tests:       T12 T50 T38 
1414       1/1            assign hw2reg.upload_addrfifo.d = addrfifo_rdata;
           Tests:       T1 T2 T3 
1415                      logic unused_addrfifo_q;
1416       1/1            assign unused_addrfifo_q = ^{reg2hw.upload_addrfifo.q, addrfifo_rvalid};
           Tests:       T1 T2 T3 
1417                    
1418                      // Connect UPLOAD_STATUS
1419                      assign hw2reg.upload_status.cmdfifo_depth.de = 1'b1;
1420       1/1            assign hw2reg.upload_status.cmdfifo_depth.d  = cmdfifo_depth;
           Tests:       T1 T2 T3 
1421                    
1422                      assign hw2reg.upload_status.cmdfifo_notempty.de = 1'b1;
1423       1/1            assign hw2reg.upload_status.cmdfifo_notempty.d  = cmdfifo_notempty;
           Tests:       T1 T2 T3 
1424                    
1425                      assign hw2reg.upload_status.addrfifo_depth.de = 1'b 1;
1426       1/1            assign hw2reg.upload_status.addrfifo_depth.d  = addrfifo_depth;
           Tests:       T1 T2 T3 
1427                    
1428                      assign hw2reg.upload_status.addrfifo_notempty.de = 1'b 1;
1429       1/1            assign hw2reg.upload_status.addrfifo_notempty.d  = addrfifo_notempty;
           Tests:       T1 T2 T3 
1430                    
1431                      assign hw2reg.upload_status2.payload_depth.de = 1'b 1;
1432       1/1            assign hw2reg.upload_status2.payload_depth.d  = payload_depth;
           Tests:       T1 T2 T3 
1433                    
1434                      assign hw2reg.upload_status2.payload_start_idx.de = 1'b 1;
1435       1/1            assign hw2reg.upload_status2.payload_start_idx.d = payload_start_idx;
           Tests:       T1 T2 T3 
1436                      `ASSERT_INIT(PayloadStartIdxWidthMatch_A,
1437                        $bits(hw2reg.upload_status2.payload_start_idx.d) == PayloadIdxW)
1438                    
1439                      // End:   Upload ---------------------------------------------------
1440                    
1441                      // Begin: Address 3B/4B Tracker ====================================
1442       1/1            assign cmd_en4b_pulse = cmd_only_dp_sel == DpEn4B;
           Tests:       T1 T2 T3 
1443       1/1            assign cmd_ex4b_pulse = cmd_only_dp_sel == DpEx4B;
           Tests:       T1 T2 T3 
1444                      spid_addr_4b u_spid_addr_4b (
1445                        .sys_clk_i  (clk_i ),
1446                        .sys_rst_ni (rst_ni),
1447                    
1448                        .spi_clk_i  (clk_spi_in_buf),
1449                    
1450                        .cmd_sync_pulse_i (cmd_sync_pulse),
1451                    
1452                        .reg2hw_addr_mode_addr_4b_en_q_i   (reg2hw.addr_mode.addr_4b_en.q),
1453                        .reg2hw_addr_mode_addr_4b_en_qe_i  (reg2hw.addr_mode.addr_4b_en.qe),
1454                        .hw2reg_addr_mode_pending_d_o      (hw2reg.addr_mode.pending.d),
1455                        .hw2reg_addr_mode_addr_4b_en_d_o   (hw2reg.addr_mode.addr_4b_en.d),
1456                    
1457                        .spi_cfg_addr_4b_en_o      (cfg_addr_4b_en), // broadcast
1458                        .cmd_sync_cfg_addr_4b_en_o (cmd_sync_addr_4b_en), // early output for upload
1459                    
1460                        .spi_addr_4b_set_i (cmd_en4b_pulse), // EN4B command
1461                        .spi_addr_4b_clr_i (cmd_ex4b_pulse)  // EX4B command
1462                      );
1463                      // End:   Address 3B/4B Tracker ------------------------------------
1464                    
1465                      /////////////////////
1466                      // SPI Passthrough //
1467                      /////////////////////
1468                    
1469                      // Passthrough block
1470                      // signal: sys_csb_syncd -> sysclock 2FF CSb
1471                      // signal: sys_busy  -> output of u_status readstatus_d[0]
1472                      //              set by CSb deassertion pulse & BUSY(SCK)
1473                      //              clr by CSb = 1 & SW writing 0
1474                      //
1475                      // NOTE: there will be a gap between the actual assertion of CSb and the CSb
1476                      //   syncd event visible in the u_status BUSY logic (2FF @ SYS_CLK). So,
1477                      //   there's chance that the SW may clear the BUSY right at the CSb
1478                      //   assertion event. If that happens, passthrough block may set during SPI
1479                      //   transaction. The behavior of the SPI_DEVICE in this scenario is
1480                      //   undeterminstic.
1481                      logic  passthrough_block;
1482       1/1            assign passthrough_block = csb_status_busy_broadcast;
           Tests:       T1 T2 T3 
1483                    
1484                      spi_passthrough u_passthrough (
1485                        .clk_i     (clk_spi_in_buf),
1486                        .rst_ni    (rst_spi_in_n),
1487                        .clk_out_i (clk_spi_out_buf),
1488                        .rst_out_ni(rst_spi_out_n),
1489                    
1490                        .cfg_cmd_filter_i (cmd_filter),
1491                    
1492                        .cfg_addr_mask_i  (addr_swap_mask),
1493                        .cfg_addr_value_i (addr_swap_data),
1494                    
1495                        .cfg_payload_mask_i (payload_swap_mask),
1496                        .cfg_payload_data_i (payload_swap_data),
1497                    
1498                        .cfg_addr_4b_en_i (cfg_addr_4b_en),
1499                    
1500                        .cmd_info_i (cmd_info),
1501                    
1502                        .spi_mode_i       (spi_mode),
1503                    
1504                        // Control: BUSY block
1505                        .passthrough_block_i (passthrough_block),
1506                    
1507                        // Host SPI
1508                        .host_sck_i  (cio_sck_i),
1509                        .host_csb_i  (cio_csb_i),
1510                        .host_s_i    (cio_sd_i),
1511                        .host_s_o    (passthrough_sd),
1512                        .host_s_en_o (passthrough_sd_en),
1513                    
1514                        // Passthrough to SPI_HOST HWIP
1515                        .passthrough_o,
1516                        .passthrough_i,
1517                    
1518                        .event_cmd_filtered_o ()
1519                      );
1520                    
1521                      //////////////////
1522                      // TPM over SPI //
1523                      //////////////////
1524                      // Instance of spi_tpm
1525                      spi_tpm #(
1526                        // CmdAddrFifoDepth
1527                        .EnLocality  (1)
1528                      ) u_spi_tpm (
1529                        .clk_in_i  (clk_spi_in_buf ),
1530                        .clk_out_i (clk_spi_out_buf),
1531                        .rst_ni    (tpm_rst_in_n ),
1532                        .rst_out_ni(tpm_rst_out_n),
1533                    
1534                        .sys_clk_i (clk_i),
1535                        .sys_rst_ni(rst_ni       ),
1536                    
1537                        .sys_tpm_rst_ni(sys_tpm_rst_n),
1538                    
1539                        .csb_i     (sck_tpm_csb_buf), // used as data only
1540                        .mosi_i    (tpm_mosi       ),
1541                        .miso_o    (tpm_miso       ),
1542                        .miso_en_o (tpm_miso_en    ),
1543                    
1544                        .tpm_cap_o (tpm_cap),
1545                        .cfg_tpm_en_i               (cfg_tpm_en              ),
1546                        .cfg_tpm_mode_i             (cfg_tpm_mode            ),
1547                        .cfg_tpm_hw_reg_dis_i       (cfg_tpm_hw_reg_dis      ),
1548                        .cfg_tpm_reg_chk_dis_i      (cfg_tpm_reg_chk_dis     ),
1549                        .cfg_tpm_invalid_locality_i (cfg_tpm_invalid_locality),
1550                    
1551                        .sys_access_reg_i          (tpm_access         ),
1552                        .sys_int_enable_reg_i      (tpm_int_enable     ),
1553                        .sys_int_vector_reg_i      (tpm_int_vector     ),
1554                        .sys_int_status_reg_i      (tpm_int_status     ),
1555                        .sys_intf_capability_reg_i (tpm_intf_capability),
1556                        .sys_status_reg_i          (tpm_status         ),
1557                        .sys_id_reg_i              (tpm_did_vid        ),
1558                        .sys_rid_reg_i             (tpm_rid            ),
1559                    
1560                        .sck_sram_o                (tpm_sram_l2m),
1561                        .sck_sram_i                (tpm_sram_m2l),
1562                        .sys_sram_o                (sys_sram_l2m[SysSramTpmRdFifo]),
1563                        .sys_sram_i                (sys_sram_m2l[SysSramTpmRdFifo]),
1564                        .sys_sram_gnt_i            (sys_sram_gnt[SysSramTpmRdFifo]),
1565                    
1566                        .sys_cmdaddr_rvalid_o (tpm_cmdaddr_rvalid),
1567                        .sys_cmdaddr_rdata_o  (tpm_cmdaddr_rdata ),
1568                        .sys_cmdaddr_rready_i (tpm_cmdaddr_rready),
1569                    
1570                        .sys_rdfifo_wvalid_i  (tpm_rdfifo_wvalid       ),
1571                        .sys_rdfifo_wdata_i   (tpm_rdfifo_wdata        ),
1572                        .sys_rdfifo_wready_o  (tpm_rdfifo_wready       ),
1573                        .sys_rdfifo_cmd_end_o (tpm_event_rdfifo_cmd_end),
1574                        .sys_tpm_rdfifo_drop_o(tpm_event_rdfifo_drop   ),
1575                    
1576                        .sys_wrfifo_release_i(tpm_status_wrfifo_release),
1577                    
1578                        .sys_cmdaddr_notempty_o (tpm_status_cmdaddr_notempty),
1579                        .sys_wrfifo_pending_o   (tpm_status_wrfifo_pending),
1580                        .sys_rdfifo_aborted_o   (tpm_status_rdfifo_aborted)
1581                      );
1582                    
1583                      // Register connection
1584                      //  TPM_CAP:
1585       0/1     ==>    assign hw2reg.tpm_cap = '{
1586                        rev:         '{ de: 1'b 1, d: tpm_cap.rev         },
1587                        locality:    '{ de: 1'b 1, d: tpm_cap.locality    },
1588                        max_wr_size: '{ de: 1'b 1, d: tpm_cap.max_wr_size },
1589                        max_rd_size: '{ de: 1'b 1, d: tpm_cap.max_rd_size }
1590                      };
1591                    
1592                      //  CFG:
1593       1/1            assign cfg_tpm_en               = reg2hw.tpm_cfg.en.q;
           Tests:       T1 T2 T3 
1594       1/1            assign cfg_tpm_mode             = reg2hw.tpm_cfg.tpm_mode.q;
           Tests:       T1 T2 T3 
1595       1/1            assign cfg_tpm_hw_reg_dis       = reg2hw.tpm_cfg.hw_reg_dis.q;
           Tests:       T1 T2 T3 
1596       1/1            assign cfg_tpm_reg_chk_dis      = reg2hw.tpm_cfg.tpm_reg_chk_dis.q;
           Tests:       T1 T2 T3 
1597       1/1            assign cfg_tpm_invalid_locality = reg2hw.tpm_cfg.invalid_locality.q;
           Tests:       T1 T2 T3 
1598                    
1599                      //  STATUS:
1600       1/1            assign hw2reg.tpm_status = '{
           Tests:       T1 T2 T3 
1601                        rdfifo_aborted:   '{ d: tpm_status_rdfifo_aborted },
1602                        wrfifo_pending:   '{ d: tpm_status_wrfifo_pending },
1603                        cmdaddr_notempty: '{ d: tpm_status_cmdaddr_notempty }
1604                      };
1605                    
1606                      // wrfifo_release is RW0C
1607       1/1            assign tpm_status_wrfifo_release = reg2hw.tpm_status.wrfifo_pending.qe &
           Tests:       T1 T2 T3 
1608                                                         ~reg2hw.tpm_status.wrfifo_pending.q;
1609                    
1610                      //  Return-by-HW registers:
1611                      //    TPM_ACCESS_x, TPM_STS_x, TPM_INT_ENABLE, TPM_INT_VECTOR,
1612                      //    TPM_INT_STATUS, TPM_INTF_CAPABILITY, TPM_DID_VID, TPM_RID
1613                      for (genvar i = 0 ; i < spi_device_reg_pkg::NumLocality ; i++) begin : g_tpm_access
1614       5/5              assign tpm_access[8*i+:8] = reg2hw.tpm_access[i].q;
           Tests:       T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
1615                      end : g_tpm_access
1616                    
1617       1/1            assign tpm_int_enable      = reg2hw.tpm_int_enable.q;
           Tests:       T1 T2 T3 
1618       1/1            assign tpm_int_vector      = reg2hw.tpm_int_vector.q;
           Tests:       T1 T2 T3 
1619       1/1            assign tpm_int_status      = reg2hw.tpm_int_status.q;
           Tests:       T1 T2 T3 
1620       1/1            assign tpm_intf_capability = reg2hw.tpm_intf_capability.q;
           Tests:       T1 T2 T3 
1621       1/1            assign tpm_status          = reg2hw.tpm_sts.q;
           Tests:       T1 T2 T3 
1622       1/1            assign tpm_did_vid         = { reg2hw.tpm_did_vid.did.q ,
           Tests:       T1 T2 T3 
1623                                                     reg2hw.tpm_did_vid.vid.q };
1624       1/1            assign tpm_rid             = reg2hw.tpm_rid.q;
           Tests:       T1 T2 T3 
1625                    
1626                      // Command / Address Buffer
1627                      logic  unused_tpm_cmdaddr;
1628       1/1            assign unused_tpm_cmdaddr = ^{tpm_cmdaddr_rvalid, reg2hw.tpm_cmd_addr};
           Tests:       T1 T2 T3 
1629                    
1630       1/1            assign tpm_cmdaddr_rready  = reg2hw.tpm_cmd_addr.cmd.re;
           Tests:       T5 T15 T25 
1631       1/1            assign hw2reg.tpm_cmd_addr = '{
           Tests:       T1 T2 T3 
1632                        addr: tpm_cmdaddr_rdata[23: 0],
1633                        cmd:  tpm_cmdaddr_rdata[31:24]
1634                      };
1635                    
1636                      // Read FIFO (write by SW)
1637                      logic  unused_tpm_rdfifo;
1638       1/1            assign unused_tpm_rdfifo= tpm_rdfifo_wready;
           Tests:       T1 T2 T3 
1639                    
1640       1/1            assign tpm_rdfifo_wvalid = reg2hw.tpm_read_fifo.qe;
           Tests:       T5 T15 T25 
1641       1/1            assign tpm_rdfifo_wdata  = reg2hw.tpm_read_fifo.q;
           Tests:       T1 T2 T3 
1642                    
1643                      // END: TPM over SPI --------------------------------------------------------
1644                    
1645                      ////////////////////
1646                      // Common modules //
1647                      ////////////////////
1648                    
1649                      logic [SramDw-1:0] sys_sram_l2m_fw_wmask[2];
1650       1/1            assign tl_sram_egress_h2d = tl_sram_h2d[SPI_DEVICE_EGRESS_BUFFER_IDX];
           Tests:       T1 T2 T3 
1651       1/1            assign tl_sram_d2h[SPI_DEVICE_EGRESS_BUFFER_IDX] = tl_sram_egress_d2h;
           Tests:       T1 T2 T3 
1652       1/1            assign tl_sram_ingress_h2d = tl_sram_h2d[SPI_DEVICE_INGRESS_BUFFER_IDX];
           Tests:       T1 T2 T3 
1653       1/1            assign tl_sram_d2h[SPI_DEVICE_INGRESS_BUFFER_IDX] = tl_sram_ingress_d2h;
           Tests:       T1 T2 T3 
1654                    
1655                      tlul_adapter_sram #(
1656                        .SramAw      (SramAw),
1657                        .SramDw      (SramDw),
1658                        .Outstanding (1),
1659                        .ErrOnRead   (1), // write-only memory window
1660                        .ByteAccess  (0)
1661                      ) u_tlul2sram_egress (
1662                        .clk_i,
1663                        .rst_ni,
1664                    
1665                        .tl_i                       (tl_sram_egress_h2d),
1666                        .tl_o                       (tl_sram_egress_d2h),
1667                        .en_ifetch_i                (prim_mubi_pkg::MuBi4False),
1668                        .req_o                      (sys_sram_l2m[SysSramFwEgress].req),
1669                        .req_type_o                 (),
1670                        .gnt_i                      (sys_sram_fw_gnt[SPI_DEVICE_EGRESS_BUFFER_IDX]),
1671                        .we_o                       (sys_sram_l2m[SysSramFwEgress].we),
1672                        .addr_o                     (sys_sram_l2m[SysSramFwEgress].addr),
1673                        .wdata_o                    (sys_sram_l2m[SysSramFwEgress].wdata),
1674                        .wmask_o                    (sys_sram_l2m_fw_wmask[SPI_DEVICE_EGRESS_BUFFER_IDX]),  // Not used
1675                        .intg_error_o               (),
1676                        .rdata_i                    (sys_sram_m2l[SysSramFwEgress].rdata),
1677                        .rvalid_i                   (sys_sram_m2l[SysSramFwEgress].rvalid),
1678                        .rerror_i                   (sys_sram_m2l[SysSramFwEgress].rerror),
1679                        .compound_txn_in_progress_o (),
1680                        .readback_en_i              (prim_mubi_pkg::MuBi4False),
1681                        .readback_error_o           (),
1682                        .wr_collision_i             (1'b0),
1683                        .write_pending_i            (1'b0)
1684                      );
1685                    
1686                      tlul_adapter_sram #(
1687                        .SramAw      (SramAw),
1688                        .SramDw      (SramDw),
1689                        .Outstanding (1),
1690                        .ErrOnWrite  (1), // read-only memory window
1691                        .ByteAccess  (0)
1692                      ) u_tlul2sram_ingress (
1693                        .clk_i,
1694                        .rst_ni,
1695                    
1696                        .tl_i                       (tl_sram_ingress_h2d),
1697                        .tl_o                       (tl_sram_ingress_d2h),
1698                        .en_ifetch_i                (prim_mubi_pkg::MuBi4False),
1699                        .req_o                      (sys_sram_l2m[SysSramFwIngress].req),
1700                        .req_type_o                 (),
1701                        .gnt_i                      (sys_sram_fw_gnt[SPI_DEVICE_INGRESS_BUFFER_IDX]),
1702                        .we_o                       (sys_sram_l2m[SysSramFwIngress].we),
1703                        .addr_o                     (sys_sram_l2m[SysSramFwIngress].addr),
1704                        .wdata_o                    (sys_sram_l2m[SysSramFwIngress].wdata),
1705                        .wmask_o                    (sys_sram_l2m_fw_wmask[SPI_DEVICE_INGRESS_BUFFER_IDX]),  // Not used
1706                        .intg_error_o               (),
1707                        .rdata_i                    (sys_sram_m2l[SysSramFwIngress].rdata),
1708                        .rvalid_i                   (sys_sram_m2l[SysSramFwIngress].rvalid),
1709                        .rerror_i                   (sys_sram_m2l[SysSramFwIngress].rerror),
1710                        .compound_txn_in_progress_o (),
1711                        .readback_en_i              (prim_mubi_pkg::MuBi4False),
1712                        .readback_error_o           (),
1713                        .wr_collision_i             (1'b0),
1714                        .write_pending_i            (1'b0)
1715                      );
1716       1/1            assign sys_sram_l2m[SysSramFwEgress].wstrb =
           Tests:       T1 T2 T3 
1717                        sram_mask2strb(sys_sram_l2m_fw_wmask[SPI_DEVICE_EGRESS_BUFFER_IDX]);
1718       1/1            assign sys_sram_l2m[SysSramFwIngress].wstrb =
           Tests:       T1 T2 T3 
1719                        sram_mask2strb(sys_sram_l2m_fw_wmask[SPI_DEVICE_INGRESS_BUFFER_IDX]);
1720                    
1721                      logic sys_sram_hw_req;
1722                      always_comb begin
1723       1/1              sys_sram_hw_req = 1'b0;
           Tests:       T1 T2 T3 
1724       1/1              for (int unsigned i = 0; i < SysSramEnd; i++) begin
           Tests:       T1 T2 T3 
1725       1/1                if ((i != SysSramFwEgress) && (i != SysSramFwIngress)) begin
           Tests:       T1 T2 T3 
1726       1/1                  sys_sram_hw_req |= sys_sram_l2m[i].req;
           Tests:       T1 T2 T3 
1727                          end
                        MISSING_ELSE
1728                        end
1729                      end
1730                    
1731                      always_comb begin
1732       1/1              for (int unsigned i = 0; i < SysSramEnd; i++) begin
           Tests:       T1 T2 T3 
1733       1/1                sys_sram_req[i] = sys_sram_l2m[i].req;
           Tests:       T1 T2 T3 
1734                        end
1735       1/1              if (sys_sram_hw_req) begin
           Tests:       T1 T2 T3 
1736                          // Fixed low priority. (Discussed in #10065)
1737                          // When HW requests the SRAM access, lower the SW requests (and grant)
1738       1/1                sys_sram_req[SysSramFwEgress] = 1'b0;
           Tests:       T5 T12 T15 
1739       1/1                sys_sram_fw_gnt[SPI_DEVICE_EGRESS_BUFFER_IDX] = 1'b0;
           Tests:       T5 T12 T15 
1740       1/1                sys_sram_req[SysSramFwIngress] = 1'b0;
           Tests:       T5 T12 T15 
1741       1/1                sys_sram_fw_gnt[SPI_DEVICE_INGRESS_BUFFER_IDX] = 1'b0;
           Tests:       T5 T12 T15 
1742                        end else begin
1743       1/1                sys_sram_fw_gnt[SPI_DEVICE_EGRESS_BUFFER_IDX] = sys_sram_gnt[SysSramFwEgress];
           Tests:       T1 T2 T3 
1744       1/1                sys_sram_fw_gnt[SPI_DEVICE_INGRESS_BUFFER_IDX] = sys_sram_gnt[SysSramFwIngress];
           Tests:       T1 T2 T3 
1745                        end
1746                      end
1747                    
1748                      for (genvar i = 0 ; i < SysSramEnd ; i++) begin : g_sram_connect
1749       5/5              assign sys_sram_addr  [i] = sys_sram_l2m[i].addr;
           Tests:       T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
1750       2/5     ==>      assign sys_sram_write [i] = sys_sram_l2m[i].we;
           Tests:       T1 T2 T3  | T1 T2 T3 
1751       3/5     ==>      assign sys_sram_wdata [i] = sys_sram_l2m[i].wdata;
           Tests:       T1 T3 T4  | T1 T3 T4  | T1 T2 T3 
1752       2/5     ==>      assign sys_sram_wmask [i] = sram_strb2mask(sys_sram_l2m[i].wstrb);
           Tests:       T1 T2 T3  | T1 T2 T3 
1753                    
1754       5/5              assign sys_sram_m2l[i].rvalid = sys_sram_rvalid[i];
           Tests:       T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
1755       5/5              assign sys_sram_m2l[i].rdata  = sys_sram_rdata[i];
           Tests:       T5 T12 T15  | T5 T12 T15  | T5 T12 T15  | T5 T12 T15  | T5 T12 T15 
1756       5/5              assign sys_sram_m2l[i].rerror = sys_sram_rerror[i];
           Tests:       T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3 
1757                    
1758                        // There is only ever a single source of requests on the SYS port (SW), so
1759                        // requests should always be granted.
1760                        `ASSERT(ReqAlwaysAccepted_A, sys_sram_req[i] |-> sys_sram_gnt[i])
1761                      end : g_sram_connect
1762                    
1763                      prim_sram_arbiter #(
1764                        .N      (SysSramEnd),
1765                        .SramDw (SramDw),
1766                        .SramAw (SramAw),
1767                    
1768                        .EnMask (1'b 1)
1769                      ) u_sys_sram_arbiter (
1770                        .clk_i,
1771                        .rst_ni,
1772                    
1773                        .req_i       (sys_sram_req),
1774                        .req_addr_i  (sys_sram_addr),
1775                        .req_write_i (sys_sram_write),
1776                        .req_wdata_i (sys_sram_wdata),
1777                        .req_wmask_i (sys_sram_wmask),
1778                        .gnt_o       (sys_sram_gnt),
1779                    
1780                        .rsp_rvalid_o (sys_sram_rvalid),
1781                        .rsp_rdata_o  (sys_sram_rdata),
1782                        .rsp_error_o  (sys_sram_rerror),
1783                    
1784                        .sram_req_o    (mem_a_req),
1785                        .sram_addr_o   (mem_a_addr),
1786                        .sram_write_o  (mem_a_write),
1787                        .sram_wdata_o  (mem_a_wdata),
1788                        .sram_wmask_o  (mem_a_wmask),
1789                        .sram_rvalid_i (mem_a_rvalid),
1790                        .sram_rdata_i  (mem_a_rdata),
1791                        .sram_rerror_i (mem_a_rerror)
1792                      );
1793                    
1794                      // SRAM Wrapper
1795                      // The SRAM should only be reset if both modes are inactive.
1796                      logic spi_dpram_rst_n;
1797       1/1            assign spi_dpram_rst_n = tpm_rst_in_n | rst_spi_in_n;
           Tests:       T1 T2 T3 
1798                    
1799       1/1            assign mem_b_req   = mem_b_l2m.req;
           Tests:       T1 T2 T3 
1800       1/1            assign mem_b_write = mem_b_l2m.we;
           Tests:       T1 T2 T3 
1801       1/1            assign mem_b_addr  = mem_b_l2m.addr;
           Tests:       T1 T2 T3 
1802       1/1            assign mem_b_wdata = mem_b_l2m.wdata;
           Tests:       T1 T2 T3 
1803       1/1            assign mem_b_wmask = sram_strb2mask(mem_b_l2m.wstrb);
           Tests:       T1 T2 T3 
1804                    
1805       1/1            assign mem_b_m2l.rvalid = mem_b_rvalid;
           Tests:       T1 T2 T3 
1806       1/1            assign mem_b_m2l.rdata  = mem_b_rdata;
           Tests:       T5 T7 T8 
1807       1/1            assign mem_b_m2l.rerror = mem_b_rerror;
           Tests:       T1 T2 T3 
1808                    
1809                      spid_dpram #(
1810                        .SramType            (SramType),
1811                        .EnableECC           (0),
1812                        .EnableParity        (1),
1813                        .EnableInputPipeline (0),
1814                        .EnableOutputPipeline(0)
1815                      ) u_spid_dpram (
1816                        .clk_sys_i      (clk_i),
1817                        .rst_sys_ni     (rst_ni),
1818                    
1819                        .clk_spi_i      (clk_spi_in_buf),
1820                        .rst_spi_ni     (spi_dpram_rst_n),
1821                    
1822                        .sys_req_i      (mem_a_req),
1823                        .sys_write_i    (mem_a_write),
1824                        .sys_addr_i     (mem_a_addr),
1825                        .sys_wdata_i    (mem_a_wdata),
1826                        .sys_wmask_i    (mem_a_wmask),
1827                        .sys_rvalid_o   (mem_a_rvalid),
1828                        .sys_rdata_o    (mem_a_rdata),
1829                        .sys_rerror_o   (mem_a_rerror),
1830                    
1831                        .spi_req_i      (mem_b_req),
1832                        .spi_write_i    (mem_b_write),
1833                        .spi_addr_i     (mem_b_addr),
1834                        .spi_wdata_i    (mem_b_wdata),
1835                        .spi_wmask_i    (mem_b_wmask),
1836                        .spi_rvalid_o   (mem_b_rvalid),
1837                        .spi_rdata_o    (mem_b_rdata),
1838                        .spi_rerror_o   (mem_b_rerror),
1839                    
1840                        .cfg_i          (ram_cfg_i)
1841                      );
1842                    
1843                      // Register module
1844                      logic [NumAlerts-1:0] alert_test, alerts;
1845                      spi_device_reg_top u_reg (
1846                        .clk_i,
1847                        .rst_ni,
1848                    
1849                        .tl_i (tl_i),
1850                        .tl_o (tl_o),
1851                    
1852                        .tl_win_o (tl_sram_h2d),
1853                        .tl_win_i (tl_sram_d2h),
1854                    
1855                        .reg2hw,
1856                        .hw2reg,
1857                    
1858                        // SEC_CM: BUS.INTEGRITY
1859                        .intg_err_o (alerts[0])
1860                      );
1861                    
1862                      // Alerts
1863       1/1            assign alert_test = {
           Tests:       T1 T2 T3