Line split page
dashboard | hierarchy | modlist | groups | tests | asserts
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: T3 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 T9 T10  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 T9 T10  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: T12 T15 T16  849 1/1 sub_sram_m2l[IoModeReadCmd] = flash_sram_m2l; Tests: T12 T15 T16  850 end 851 852 DpUpload: begin 853 1/1 flash_sram_l2m = sub_sram_l2m[IoModeUpload]; Tests: T20 T60 T50  854 1/1 sub_sram_m2l[IoModeUpload] = flash_sram_m2l; Tests: T20 T60 T50  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: T1 T6 T9  887 1/1 flash_sram_m2l = mem_b_m2l; Tests: T1 T6 T9  888 1/1 end else if (cfg_tpm_en) begin Tests: T1 T2 T3  889 1/1 mem_b_l2m = tpm_sram_l2m; Tests: T3 T5 T38  890 1/1 tpm_sram_m2l = mem_b_m2l; Tests: T3 T5 T38  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: T12 T15 T16  912 913 1/1 p2s_valid = sub_p2s_valid[IoModeReadCmd]; Tests: T12 T15 T16  914 1/1 p2s_data = sub_p2s_data[IoModeReadCmd]; Tests: T12 T15 T16  915 1/1 sub_p2s_sent[IoModeReadCmd] = p2s_sent; Tests: T12 T15 T16  916 end 917 DpReadStatus: begin 918 1/1 io_mode = sub_iomode[IoModeStatus]; Tests: T20 T55 T60  919 920 1/1 p2s_valid = sub_p2s_valid[IoModeStatus]; Tests: T20 T55 T60  921 1/1 p2s_data = sub_p2s_data[IoModeStatus]; Tests: T20 T55 T60  922 1/1 sub_p2s_sent[IoModeStatus] = p2s_sent; Tests: T20 T55 T60  923 924 end 925 926 DpReadJEDEC: begin 927 1/1 io_mode = sub_iomode[IoModeJedec]; Tests: T91 T50 T62  928 929 1/1 p2s_valid = sub_p2s_valid[IoModeJedec]; Tests: T91 T50 T62  930 1/1 p2s_data = sub_p2s_data[IoModeJedec]; Tests: T91 T50 T62  931 1/1 sub_p2s_sent[IoModeJedec] = p2s_sent; Tests: T91 T50 T62  932 end 933 934 DpUpload: begin 935 1/1 io_mode = sub_iomode[IoModeUpload]; Tests: T20 T60 T50  936 937 1/1 p2s_valid = sub_p2s_valid[IoModeUpload]; Tests: T20 T60 T50  938 1/1 p2s_data = sub_p2s_data[IoModeUpload]; Tests: T20 T60 T50  939 1/1 sub_p2s_sent[IoModeUpload] = p2s_sent; Tests: T20 T60 T50  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: T12 T15 T16  1030 1/1 internal_sd_en_out = internal_sd_en_stg2; Tests: T12 T15 T16  1031 1/1 intercept_en_out = intercept_en_stg2; Tests: T12 T15 T16  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: T3 T5 T13  1047 1/1 cio_sd_en_o = {2'b 00, tpm_miso_en, 1'b 0}; Tests: T3 T5 T13  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 T9 T10  1059 1/1 cio_sd_o = internal_sd_out; Tests: T20 T39 T55  1060 1/1 cio_sd_en_o = internal_sd_en_out; Tests: T20 T39 T55  1061 end else begin 1062 1/1 cio_sd_o = passthrough_sd; Tests: T6 T9 T10  1063 1/1 cio_sd_en_o = passthrough_sd_en; Tests: T6 T9 T10  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 T9 T10  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: T9 T12 T15  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: T20 T60 T50  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: T20 T60 T50  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: T20 T50 T62  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 T14 T29  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 T14 T29  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 T14 T20  1739 1/1 sys_sram_fw_gnt[SPI_DEVICE_EGRESS_BUFFER_IDX] = 1'b0; Tests: T5 T14 T20  1740 1/1 sys_sram_req[SysSramFwIngress] = 1'b0; Tests: T5 T14 T20  1741 1/1 sys_sram_fw_gnt[SPI_DEVICE_INGRESS_BUFFER_IDX] = 1'b0; Tests: T5 T14 T20  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 T2 T3  | T1 T2 T3  | 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: T4 T5 T25  | T4 T5 T25  | T4 T5 T25  | T4 T5 T25  | T4 T5 T25  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 T12 T14  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 
0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%