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