hw/ip/spi_device/rtl/spi_device.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   3: // SPDX-License-Identifier: Apache-2.0
   4: //
   5: // Serial Peripheral Interface (SPI) Device module.
   6: //
   7: //
   8: 
   9: module spi_device #(
  10:   parameter int SramAw = 9, // 2kB, SRAM Width is DW
  11:   parameter int SramDw = 32
  12: ) (
  13:   input clk_i,
  14:   input rst_ni,
  15: 
  16:   // Register interface
  17:   input  tlul_pkg::tl_h2d_t tl_i,
  18:   output tlul_pkg::tl_d2h_t tl_o,
  19: 
  20:   // SPI Interface
  21:   input              cio_sck_i,
  22:   input              cio_csb_i,
  23:   output logic       cio_miso_o,
  24:   output logic       cio_miso_en_o,
  25:   input              cio_mosi_i,
  26: 
  27:   // Interrupts
  28:   output logic intr_rxf_o,         // RX FIFO Full
  29:   output logic intr_rxlvl_o,       // RX FIFO above level
  30:   output logic intr_txlvl_o,       // TX FIFO below level
  31:   output logic intr_rxerr_o,       // RX Frame error
  32:   output logic intr_rxoverflow_o,  // RX Async FIFO Overflow
  33:   output logic intr_txunderflow_o, // TX Async FIFO Underflow
  34: 
  35:   input scanmode_i
  36: );
  37: 
  38:   import spi_device_pkg::*;
  39:   import spi_device_reg_pkg::*;
  40: 
  41:   localparam int FifoWidth = $bits(spi_byte_t);
  42:   localparam int FifoDepth = 8; // 2 DWords
  43:   localparam int SDW = $clog2(SramDw/FifoWidth);
  44:   localparam int PtrW = SramAw + 1 + SDW;
  45:   localparam int AsFifoDepthW = $clog2(FifoDepth+1);
  46: 
  47:   logic clk_spi_in;   // clock for latch MOSI
  48:   logic clk_spi_out;  // clock for driving MISO
  49: 
  50:   spi_device_reg2hw_t reg2hw;
  51:   spi_device_hw2reg_t hw2reg;
  52: 
  53:   tlul_pkg::tl_h2d_t tl_sram_h2d [1];
  54:   tlul_pkg::tl_d2h_t tl_sram_d2h [1];
  55: 
  56:   // Dual-port SRAM Interface: Refer prim_ram_2p_wrapper.sv
  57:   logic              mem_a_req;
  58:   logic              mem_a_write;
  59:   logic [SramAw-1:0] mem_a_addr;
  60:   logic [SramDw-1:0] mem_a_wdata;
  61:   logic              mem_a_rvalid;
  62:   logic [SramDw-1:0] mem_a_rdata;
  63:   logic [1:0]        mem_a_rerror;
  64: 
  65:   logic              mem_b_req;
  66:   logic              mem_b_write;
  67:   logic [SramAw-1:0] mem_b_addr;
  68:   logic [SramDw-1:0] mem_b_wdata;
  69:   logic              mem_b_rvalid;
  70:   logic [SramDw-1:0] mem_b_rdata;
  71:   logic [1:0]        mem_b_rerror;
  72: 
  73:   /////////////////////
  74:   // Control signals //
  75:   /////////////////////
  76: 
  77:   logic cpol; // Clock polarity
  78:   logic cpha; // Phase : Not complete
  79:   logic txorder; // TX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7)
  80:   logic rxorder; // RX bitstream order: 0(bit 7 to 0), 1(bit 0 to 7)
  81: 
  82:   logic abort;  // Abort current operations (txf only at this time)
  83:                 // Think how FW knows abort is done.
  84:   //logic abort_done; // TODO: Not implemented yet
  85: 
  86:   logic csb_syncd;
  87: 
  88:   logic rst_txfifo_n, rst_rxfifo_n;
  89:   logic rst_txfifo_reg, rst_rxfifo_reg;
  90: 
  91:   //spi_addr_size_e addr_size; // Not used in fwmode
  92:   spi_mode_e spi_mode;
  93:   //spi_byte_t fw_dummy_byte;
  94: 
  95:   logic intr_sram_rxf_full, intr_fwm_rxerr;
  96:   logic intr_fwm_rxlvl, rxlvl, rxlvl_d, intr_fwm_txlvl, txlvl, txlvl_d;
  97:   logic intr_fwm_rxoverflow, intr_fwm_txunderflow;
  98: 
  99:   // RX Async FIFO Signals
 100:   //  Write: SCK positive edge
 101:   logic      rxf_wvalid, rxf_wready;
 102:   spi_byte_t rxf_wdata;
 103:   logic      rxf_overflow;
 104:   //  Read: Main clock
 105:   logic      rxf_rvalid, rxf_rready;
 106:   spi_byte_t rxf_rdata;
 107:   logic      rxf_full_syncd;
 108: 
 109:   // TX Async FIFO Signals
 110:   //   Read: SCK negative edge
 111:   logic      txf_rvalid, txf_rready;
 112:   spi_byte_t txf_rdata;
 113:   logic      txf_underflow;
 114:   //   Write: Main clock
 115:   logic      txf_wvalid, txf_wready;
 116:   spi_byte_t txf_wdata;
 117:   logic      txf_empty_syncd;
 118: 
 119:   // SRAM FIFO control
 120:   typedef enum int {
 121:     FwModeRxFifo = 0,
 122:     FwModeTxFifo = 1
 123:   } fwm_fifo_e;
 124:   logic        [7:0] timer_v;   // Wait timer inside rxf control
 125:   logic   [PtrW-1:0] sram_rxf_rptr, sram_rxf_wptr;
 126:   logic   [PtrW-1:0] sram_txf_rptr, sram_txf_wptr;
 127:   logic   [PtrW-1:0] sram_rxf_depth, sram_txf_depth;
 128: 
 129:   logic [SramAw-1:0] sram_rxf_bindex, sram_txf_bindex;
 130:   logic [SramAw-1:0] sram_rxf_lindex, sram_txf_lindex;
 131:   logic        [1:0] fwm_sram_req;
 132:   logic [SramAw-1:0] fwm_sram_addr  [2];
 133:   logic              fwm_sram_write [2];
 134:   logic [SramDw-1:0] fwm_sram_wdata [2];
 135:   logic        [1:0] fwm_sram_gnt;
 136:   logic        [1:0] fwm_sram_rvalid;    // RXF doesn't use
 137:   logic [SramDw-1:0] fwm_sram_rdata [2]; // RXF doesn't use
 138:   logic        [1:0] fwm_sram_error [2];
 139: 
 140:   logic [AsFifoDepthW-1:0] as_txfifo_depth, as_rxfifo_depth;
 141: 
 142: 
 143:   //////////////////////////////////////////////////////////////////////
 144:   // Connect phase (between control signals above and register module //
 145:   //////////////////////////////////////////////////////////////////////
 146: 
 147:   assign cpol = reg2hw.cfg.cpol.q;
 148:   assign cpha = reg2hw.cfg.cpha.q;
 149:   assign txorder = reg2hw.cfg.tx_order.q;
 150:   assign rxorder = reg2hw.cfg.rx_order.q;
 151: 
 152:   assign rst_txfifo_reg = reg2hw.control.rst_txfifo.q;
 153:   assign rst_rxfifo_reg = reg2hw.control.rst_rxfifo.q;
 154: 
 155:   assign timer_v = reg2hw.cfg.timer_v.q;
 156: 
 157:   assign sram_rxf_bindex = reg2hw.rxf_addr.base.q[SDW+:SramAw];
 158:   assign sram_rxf_lindex = reg2hw.rxf_addr.limit.q[SDW+:SramAw];
 159:   assign sram_txf_bindex = reg2hw.txf_addr.base.q[SDW+:SramAw];
 160:   assign sram_txf_lindex = reg2hw.txf_addr.limit.q[SDW+:SramAw];
 161: 
 162:   assign sram_rxf_rptr = reg2hw.rxf_ptr.rptr.q[PtrW-1:0];
 163:   assign hw2reg.rxf_ptr.wptr.d = {{(16-PtrW){1'b0}}, sram_rxf_wptr};
 164:   assign hw2reg.rxf_ptr.wptr.de = 1'b1;
 165: 
 166:   assign sram_txf_wptr = reg2hw.txf_ptr.wptr.q[PtrW-1:0];
 167:   assign hw2reg.txf_ptr.rptr.d = {{(16-PtrW){1'b0}}, sram_txf_rptr};
 168:   assign hw2reg.txf_ptr.rptr.de = 1'b1;
 169: 
 170:   assign abort = reg2hw.control.abort.q;
 171:   assign hw2reg.status.abort_done.d  = 1'b1;
 172: 
 173:   assign hw2reg.status.rxf_empty.d = ~rxf_rvalid;
 174:   assign hw2reg.status.txf_full.d  = ~txf_wready;
 175: 
 176:   // SYNC logic required
 177:   assign hw2reg.status.rxf_full.d = rxf_full_syncd;
 178:   assign hw2reg.status.txf_empty.d = txf_empty_syncd;
 179: 
 180:   // CSb : after 2stage synchronizer
 181:   assign hw2reg.status.csb.d = csb_syncd;
 182:   prim_flop_2sync #(.Width(1)) u_sync_csb (
 183:     .clk_i,
 184:     .rst_ni,
 185:     .d(cio_csb_i),
 186:     .q(csb_syncd)
 187:   );
 188: 
 189:   logic rxf_full_q, txf_empty_q;
 190:   always_ff @(posedge clk_spi_in)  rxf_full_q  <= ~rxf_wready;
 191:   always_ff @(posedge clk_spi_out) txf_empty_q <= ~txf_rvalid;
 192:   prim_flop_2sync #(.Width(1)) u_sync_rxf (
 193:     .clk_i,
 194:     .rst_ni,
 195:     .d(rxf_full_q),
 196:     .q(rxf_full_syncd)
 197:   );
 198:   prim_flop_2sync #(.Width(1), .ResetValue(1'b1)) u_sync_txe (
 199:     .clk_i,
 200:     .rst_ni,
 201:     .d(txf_empty_q),
 202:     .q(txf_empty_syncd)
 203:   );
 204: 
 205:   assign spi_mode = spi_mode_e'(reg2hw.control.mode.q);
 206: 
 207:   // Async FIFO level
 208:   //  rx rdepth, tx wdepth to be in main clock domain
 209:   assign hw2reg.async_fifo_level.txlvl.d  = {{(8-AsFifoDepthW){1'b0}}, as_txfifo_depth};
 210:   assign hw2reg.async_fifo_level.rxlvl.d  = {{(8-AsFifoDepthW){1'b0}}, as_rxfifo_depth};
 211: 
 212:   // Interrupt
 213: 
 214:   // Edge
 215:   logic sram_rxf_full_q, fwm_rxerr_q;
 216:   logic sram_rxf_full  , fwm_rxerr  ;
 217: 
 218:   // TODO: Check if CE# deasserted in the middle of bit transfer
 219:   assign fwm_rxerr = 1'b0;
 220: 
 221:   always_ff @(posedge clk_i or negedge rst_ni) begin
 222:     if (!rst_ni) begin
 223:       sram_rxf_full_q <= 1'b0;
 224:       fwm_rxerr_q     <= 1'b0;
 225:     end else begin
 226:       sram_rxf_full_q <= sram_rxf_full;
 227:       fwm_rxerr_q     <= fwm_rxerr;
 228:     end
 229:   end
 230: 
 231:   // Interrupt
 232:   assign intr_sram_rxf_full = ~sram_rxf_full_q & sram_rxf_full;
 233:   assign intr_fwm_rxerr     = ~fwm_rxerr_q & fwm_rxerr;
 234: 
 235:   assign rxlvl_d = (sram_rxf_depth >= reg2hw.fifo_level.rxlvl.q[PtrW-1:0]) ;
 236:   assign txlvl_d = (sram_txf_depth <  reg2hw.fifo_level.txlvl.q[PtrW-1:0]) ;
 237: 
 238:   always_ff @(posedge clk_i or negedge rst_ni) begin
 239:     if (!rst_ni) begin
 240:       rxlvl <= 1'b0;
 241:       txlvl <= 1'b0;
 242:     end else begin
 243:       rxlvl <= rxlvl_d;
 244:       txlvl <= txlvl_d;
 245:     end
 246:   end
 247:   assign intr_fwm_rxlvl = ~rxlvl && rxlvl_d;
 248:   assign intr_fwm_txlvl = ~txlvl && txlvl_d;
 249: 
 250:   // rxf_overflow
 251:   //    Could trigger lint error for input clock.
 252:   //    It's unavoidable due to the characteristics of SPI intf
 253:   prim_pulse_sync u_rxf_overflow (
 254:     .clk_src_i   (clk_spi_in         ),
 255:     .rst_src_ni  (rst_ni             ),
 256:     .src_pulse_i (rxf_overflow       ),
 257:     .clk_dst_i   (clk_i              ),
 258:     .rst_dst_ni  (rst_ni             ),
 259:     .dst_pulse_o (intr_fwm_rxoverflow)
 260:   );
 261: 
 262:   // txf_underflow
 263:   //    Could trigger lint error for input clock.
 264:   //    It's unavoidable due to the characteristics of SPI intf
 265:   prim_pulse_sync u_txf_underflow (
 266:     .clk_src_i   (clk_spi_out         ),
 267:     .rst_src_ni  (rst_ni              ),
 268:     .src_pulse_i (txf_underflow       ),
 269:     .clk_dst_i   (clk_i               ),
 270:     .rst_dst_ni  (rst_ni              ),
 271:     .dst_pulse_o (intr_fwm_txunderflow)
 272:   );
 273: 
 274:   assign intr_rxlvl_o       = reg2hw.intr_enable.rxlvl.q       & reg2hw.intr_state.rxlvl.q;
 275:   assign intr_txlvl_o       = reg2hw.intr_enable.txlvl.q       & reg2hw.intr_state.txlvl.q;
 276:   assign intr_rxf_o         = reg2hw.intr_enable.rxf.q         & reg2hw.intr_state.rxf.q;
 277:   assign intr_rxerr_o       = reg2hw.intr_enable.rxerr.q       & reg2hw.intr_state.rxerr.q;
 278:   assign intr_rxoverflow_o  = reg2hw.intr_enable.rxoverflow.q  & reg2hw.intr_state.rxoverflow.q;
 279:   assign intr_txunderflow_o = reg2hw.intr_enable.txunderflow.q & reg2hw.intr_state.txunderflow.q;
 280: 
 281:   assign hw2reg.intr_state.rxf.d    = 1'b1;
 282:   assign hw2reg.intr_state.rxf.de   = intr_sram_rxf_full |
 283:                                       (reg2hw.intr_test.rxf.qe   & reg2hw.intr_test.rxf.q);
 284:   assign hw2reg.intr_state.rxerr.d  = 1'b1;
 285:   assign hw2reg.intr_state.rxerr.de = intr_fwm_rxerr |
 286:                                       (reg2hw.intr_test.rxerr.qe & reg2hw.intr_test.rxerr.q);
 287:   assign hw2reg.intr_state.rxlvl.d  = 1'b1;
 288:   assign hw2reg.intr_state.rxlvl.de = intr_fwm_rxlvl |
 289:                                       (reg2hw.intr_test.rxlvl.qe & reg2hw.intr_test.rxlvl.q);
 290:   assign hw2reg.intr_state.txlvl.d  = 1'b1;
 291:   assign hw2reg.intr_state.txlvl.de = intr_fwm_txlvl |
 292:                                       (reg2hw.intr_test.txlvl.qe & reg2hw.intr_test.txlvl.q);
 293:   assign hw2reg.intr_state.rxoverflow.d   = 1'b1;
 294:   assign hw2reg.intr_state.rxoverflow.de  = intr_fwm_rxoverflow |
 295:       (reg2hw.intr_test.rxoverflow.qe  & reg2hw.intr_test.rxoverflow.q);
 296:   assign hw2reg.intr_state.txunderflow.d  = 1'b1;
 297:   assign hw2reg.intr_state.txunderflow.de = intr_fwm_txunderflow |
 298:       (reg2hw.intr_test.txunderflow.qe & reg2hw.intr_test.txunderflow.q);
 299: 
 300:   //////////////////////////////
 301:   // // Clock & reset control //
 302:   //////////////////////////////
 303:   //  clk_spi cannot use glitch-free clock mux as clock switching in glitch-free
 304:   //  requires two clocks to propagate clock selection and enable but SPI clock
 305:   //  doesn't exist until it transmits data through MOSI
 306:   logic sck_n;
 307:   logic rst_spi_n;
 308: 
 309:   prim_clock_inverter u_clk_spi (.clk_i(cio_sck_i), .clk_no(sck_n), .scanmode_i);
 310:   assign clk_spi_in  = (cpha ^ cpol) ? sck_n    : cio_sck_i   ;
 311:   assign clk_spi_out = (cpha ^ cpol) ? cio_sck_i    : sck_n   ;
 312: 
 313:   assign rst_spi_n = (scanmode_i) ? rst_ni : rst_ni & ~cio_csb_i;
 314: 
 315:   assign rst_txfifo_n = (scanmode_i) ? rst_ni : rst_ni & ~rst_txfifo_reg;
 316:   assign rst_rxfifo_n = (scanmode_i) ? rst_ni : rst_ni & ~rst_rxfifo_reg;
 317: 
 318: 
 319:   /////////////
 320:   // FW Mode //
 321:   /////////////
 322:   spi_fwmode u_fwmode (
 323:     .clk_in_i     (clk_spi_in),
 324:     .rst_in_ni    (rst_spi_n),
 325: 
 326:     .clk_out_i    (clk_spi_out),
 327:     .rst_out_ni   (rst_spi_n),
 328: 
 329:     .cpha_i        (cpha),
 330:     .cfg_rxorder_i (rxorder),
 331:     .cfg_txorder_i (txorder),
 332: 
 333:     .mode_i        (spi_mode),
 334: 
 335:     .rx_wvalid_o   (rxf_wvalid),
 336:     .rx_wready_i   (rxf_wready),
 337:     .rx_data_o     (rxf_wdata),
 338: 
 339:     .tx_rvalid_i   (txf_rvalid),
 340:     .tx_rready_o   (txf_rready),
 341:     .tx_data_i     (txf_rdata),
 342: 
 343:     .rx_overflow_o  (rxf_overflow),
 344:     .tx_underflow_o (txf_underflow),
 345: 
 346:     // SPI signal
 347:     .csb_i         (cio_csb_i),
 348:     .mosi          (cio_mosi_i),
 349:     .miso          (cio_miso_o),
 350:     .miso_oe       (cio_miso_en_o)
 351:   );
 352: 
 353:   // FIFO: Connecting FwMode to SRAM CTRLs
 354:   prim_fifo_async #(
 355:     .Width (FifoWidth),
 356:     .Depth (FifoDepth)
 357:   ) u_rx_fifo (
 358:     .clk_wr_i     (clk_spi_in),
 359:     .rst_wr_ni    (rst_rxfifo_n),
 360: 
 361:     .clk_rd_i     (clk_i),
 362:     .rst_rd_ni    (rst_rxfifo_n),
 363: 
 364:     .wvalid       (rxf_wvalid),
 365:     .wready       (rxf_wready),
 366:     .wdata        (rxf_wdata),
 367: 
 368:     .rvalid       (rxf_rvalid),
 369:     .rready       (rxf_rready),
 370:     .rdata        (rxf_rdata),
 371: 
 372:     .wdepth       (),
 373:     .rdepth       (as_rxfifo_depth)
 374:   );
 375: 
 376:   prim_fifo_async #(
 377:     .Width (FifoWidth),
 378:     .Depth (FifoDepth)
 379:   ) u_tx_fifo (
 380:     .clk_wr_i     (clk_i),
 381:     .rst_wr_ni    (rst_txfifo_n),
 382: 
 383:     .clk_rd_i     (clk_spi_out),
 384:     .rst_rd_ni    (rst_txfifo_n),
 385: 
 386:     .wvalid       (txf_wvalid),
 387:     .wready       (txf_wready),
 388:     .wdata        (txf_wdata),
 389: 
 390:     .rvalid       (txf_rvalid),
 391:     .rready       (txf_rready),
 392:     .rdata        (txf_rdata),
 393: 
 394:     .wdepth       (as_txfifo_depth),
 395:     .rdepth       ()
 396:   );
 397: 
 398:   // RX Fifo control (FIFO Read port --> SRAM request)
 399:   spi_fwm_rxf_ctrl #(
 400:     .FifoDw (FifoWidth),
 401:     .SramAw (SramAw),
 402:     .SramDw (SramDw)
 403:   ) u_rxf_ctrl (
 404:     .clk_i,
 405:     .rst_ni,
 406: 
 407:     .base_index_i  (sram_rxf_bindex),
 408:     .limit_index_i (sram_rxf_lindex),
 409:     .timer_v      (timer_v),
 410:     .rptr         (sram_rxf_rptr),  // Given by FW
 411:     .wptr         (sram_rxf_wptr),  // to Register interface
 412:     .depth        (sram_rxf_depth),
 413:     .full         (sram_rxf_full),
 414: 
 415:     .fifo_valid  (rxf_rvalid),
 416:     .fifo_ready  (rxf_rready),
 417:     .fifo_rdata  (rxf_rdata),
 418: 
 419:     .sram_req    (fwm_sram_req   [FwModeRxFifo]),
 420:     .sram_write  (fwm_sram_write [FwModeRxFifo]),
 421:     .sram_addr   (fwm_sram_addr  [FwModeRxFifo]),
 422:     .sram_wdata  (fwm_sram_wdata [FwModeRxFifo]),
 423:     .sram_gnt    (fwm_sram_gnt   [FwModeRxFifo]),
 424:     .sram_rvalid (fwm_sram_rvalid[FwModeRxFifo]),
 425:     .sram_rdata  (fwm_sram_rdata [FwModeRxFifo]),
 426:     .sram_error  (fwm_sram_error [FwModeRxFifo])
 427:   );
 428: 
 429:   // TX Fifo control (SRAM read request --> FIFO write)
 430:   spi_fwm_txf_ctrl #(
 431:     .FifoDw (FifoWidth),
 432:     .SramAw (SramAw),
 433:     .SramDw (SramDw)
 434:   ) u_txf_ctrl (
 435:     .clk_i,
 436:     .rst_ni,
 437: 
 438:     .base_index_i  (sram_txf_bindex),
 439:     .limit_index_i (sram_txf_lindex),
 440: 
 441:     .abort        (abort),
 442:     .rptr         (sram_txf_rptr),  // Given by FW
 443:     .wptr         (sram_txf_wptr),  // to Register interface
 444:     .depth        (sram_txf_depth),
 445: 
 446:     .fifo_valid  (txf_wvalid),
 447:     .fifo_ready  (txf_wready),
 448:     .fifo_wdata  (txf_wdata),
 449: 
 450:     .sram_req    (fwm_sram_req   [FwModeTxFifo]),
 451:     .sram_write  (fwm_sram_write [FwModeTxFifo]),
 452:     .sram_addr   (fwm_sram_addr  [FwModeTxFifo]),
 453:     .sram_wdata  (fwm_sram_wdata [FwModeTxFifo]),
 454:     .sram_gnt    (fwm_sram_gnt   [FwModeTxFifo]),
 455:     .sram_rvalid (fwm_sram_rvalid[FwModeTxFifo]),
 456:     .sram_rdata  (fwm_sram_rdata [FwModeTxFifo]),
 457:     .sram_error  (fwm_sram_error [FwModeTxFifo])
 458:   );
 459: 
 460:   // Arbiter for FIFOs : Connecting between SRAM Ctrls and SRAM interface
 461:   prim_sram_arbiter #(
 462:     .N       (2),  // RXF, TXF
 463:     .SramDw (SramDw),
 464:     .SramAw (SramAw)   // 2kB
 465:   ) u_fwmode_arb (
 466:     .clk_i,
 467:     .rst_ni,
 468: 
 469:     .req          (fwm_sram_req),
 470:     .req_addr     (fwm_sram_addr),
 471:     .req_write    (fwm_sram_write),
 472:     .req_wdata    (fwm_sram_wdata),
 473:     .gnt          (fwm_sram_gnt),
 474: 
 475:     .rsp_rvalid   (fwm_sram_rvalid),
 476:     .rsp_rdata    (fwm_sram_rdata),
 477:     .rsp_error    (fwm_sram_error),
 478: 
 479:     .sram_req     (mem_b_req),
 480:     .sram_addr    (mem_b_addr),
 481:     .sram_write   (mem_b_write),
 482:     .sram_wdata   (mem_b_wdata),
 483: 
 484:     .sram_rvalid  (mem_b_rvalid),
 485:     .sram_rdata   (mem_b_rdata),
 486:     .sram_rerror  (mem_b_rerror)
 487:   );
 488: 
 489:   tlul_adapter_sram #(
 490:     .SramAw      (SramAw),
 491:     .SramDw      (SramDw),
 492:     .Outstanding (1),
 493:     .ByteAccess  (0)
 494:   ) u_tlul2sram (
 495:     .clk_i,
 496:     .rst_ni,
 497: 
 498:     .tl_i (tl_sram_h2d [0]),
 499:     .tl_o (tl_sram_d2h [0]),
 500: 
 501:     .req_o    (mem_a_req),
 502:     .gnt_i    (mem_a_req),  //Always grant when request
 503:     .we_o     (mem_a_write),
 504:     .addr_o   (mem_a_addr),
 505:     .wdata_o  (mem_a_wdata),
 506:     .wmask_o  (),           // Not used
 507:     .rdata_i  (mem_a_rdata),
 508:     .rvalid_i (mem_a_rvalid),
 509:     .rerror_i (mem_a_rerror)
 510:   );
 511: 
 512:   // SRAM Wrapper
 513:   prim_ram_2p_adv #(
 514:     .Depth (512),
 515:     .Width (SramDw),    // 32 x 512 --> 2kB
 516:     .CfgW  (8),
 517: 
 518:     .EnableECC           (1), // No Protection
 519:     .EnableParity        (0),
 520:     .EnableInputPipeline (0),
 521:     .EnableOutputPipeline(0),
 522:     // this is a large memory, implement with SRAM
 523:     .MemT ("SRAM")
 524:   ) u_memory_2p (
 525:     .clk_i,
 526:     .rst_ni,
 527:     .a_req_i    (mem_a_req),
 528:     .a_write_i  (mem_a_write),
 529:     .a_addr_i   (mem_a_addr),
 530:     .a_wdata_i  (mem_a_wdata),
 531:     .a_rvalid_o (mem_a_rvalid),
 532:     .a_rdata_o  (mem_a_rdata),
 533:     .a_rerror_o (mem_a_rerror),
 534: 
 535:     .b_req_i    (mem_b_req),
 536:     .b_write_i  (mem_b_write),
 537:     .b_addr_i   (mem_b_addr),
 538:     .b_wdata_i  (mem_b_wdata),
 539:     .b_rvalid_o (mem_b_rvalid),
 540:     .b_rdata_o  (mem_b_rdata),
 541:     .b_rerror_o (mem_b_rerror),
 542: 
 543:     .cfg_i      ('0)
 544:   );
 545: 
 546:   // Register module
 547:   spi_device_reg_top u_reg (
 548:     .clk_i,
 549:     .rst_ni,
 550: 
 551:     .tl_i (tl_i),
 552:     .tl_o (tl_o),
 553: 
 554:     .tl_win_o (tl_sram_h2d),
 555:     .tl_win_i (tl_sram_d2h),
 556: 
 557:     .reg2hw,
 558:     .hw2reg,
 559: 
 560:     .devmode_i  (1'b1)
 561:   );
 562: 
 563:   // make sure scanmode_i is never X (including during reset)
 564:   `ASSERT_KNOWN(scanmodeKnown, scanmode_i, clk_i, 0)
 565:   `ASSERT_KNOWN(CioMisoEnOKnown, cio_miso_en_o, clk_i, !rst_ni)
 566: 
 567:   `ASSERT_KNOWN(IntrRxfOKnown,         intr_rxf_o,         clk_i, !rst_ni)
 568:   `ASSERT_KNOWN(IntrRxlvlOKnown,       intr_rxlvl_o,       clk_i, !rst_ni)
 569:   `ASSERT_KNOWN(IntrTxlvlOKnown,       intr_txlvl_o,       clk_i, !rst_ni)
 570:   `ASSERT_KNOWN(IntrRxerrOKnown,       intr_rxerr_o,       clk_i, !rst_ni)
 571:   `ASSERT_KNOWN(IntrRxoverflowOKnown,  intr_rxoverflow_o,  clk_i, !rst_ni)
 572:   `ASSERT_KNOWN(IntrTxunderflowOKnown, intr_txunderflow_o, clk_i, !rst_ni)
 573: 
 574: endmodule
 575: