Line Coverage for Module :
spi_passthrough
| Line No. | Total | Covered | Percent |
TOTAL | | 200 | 189 | 94.50 |
CONT_ASSIGN | 271 | 1 | 1 | 100.00 |
CONT_ASSIGN | 276 | 1 | 1 | 100.00 |
CONT_ASSIGN | 326 | 1 | 1 | 100.00 |
CONT_ASSIGN | 333 | 1 | 1 | 100.00 |
ALWAYS | 336 | 4 | 4 | 100.00 |
ALWAYS | 345 | 4 | 4 | 100.00 |
ALWAYS | 349 | 3 | 3 | 100.00 |
CONT_ASSIGN | 355 | 1 | 1 | 100.00 |
ALWAYS | 360 | 4 | 4 | 100.00 |
CONT_ASSIGN | 372 | 1 | 1 | 100.00 |
CONT_ASSIGN | 373 | 1 | 1 | 100.00 |
ALWAYS | 376 | 4 | 4 | 100.00 |
ALWAYS | 400 | 8 | 8 | 100.00 |
ALWAYS | 414 | 4 | 4 | 100.00 |
ALWAYS | 425 | 4 | 4 | 100.00 |
CONT_ASSIGN | 439 | 0 | 0 | |
ALWAYS | 449 | 4 | 4 | 100.00 |
CONT_ASSIGN | 463 | 1 | 1 | 100.00 |
ALWAYS | 466 | 3 | 3 | 100.00 |
CONT_ASSIGN | 475 | 1 | 1 | 100.00 |
ALWAYS | 478 | 3 | 3 | 100.00 |
ALWAYS | 486 | 6 | 6 | 100.00 |
CONT_ASSIGN | 497 | 1 | 1 | 100.00 |
ALWAYS | 506 | 3 | 3 | 100.00 |
ALWAYS | 520 | 4 | 4 | 100.00 |
ALWAYS | 528 | 3 | 3 | 100.00 |
ALWAYS | 533 | 6 | 6 | 100.00 |
ALWAYS | 539 | 3 | 3 | 100.00 |
CONT_ASSIGN | 543 | 1 | 1 | 100.00 |
CONT_ASSIGN | 546 | 1 | 1 | 100.00 |
ALWAYS | 561 | 5 | 5 | 100.00 |
CONT_ASSIGN | 570 | 1 | 1 | 100.00 |
CONT_ASSIGN | 572 | 1 | 1 | 100.00 |
CONT_ASSIGN | 575 | 1 | 1 | 100.00 |
CONT_ASSIGN | 576 | 1 | 1 | 100.00 |
ALWAYS | 582 | 6 | 6 | 100.00 |
CONT_ASSIGN | 589 | 1 | 1 | 100.00 |
ALWAYS | 596 | 6 | 4 | 66.67 |
CONT_ASSIGN | 604 | 1 | 1 | 100.00 |
CONT_ASSIGN | 609 | 1 | 1 | 100.00 |
ALWAYS | 613 | 3 | 3 | 100.00 |
CONT_ASSIGN | 616 | 1 | 1 | 100.00 |
ALWAYS | 685 | 13 | 13 | 100.00 |
ALWAYS | 713 | 3 | 3 | 100.00 |
CONT_ASSIGN | 728 | 1 | 1 | 100.00 |
CONT_ASSIGN | 734 | 1 | 1 | 100.00 |
CONT_ASSIGN | 737 | 1 | 1 | 100.00 |
ALWAYS | 745 | 3 | 3 | 100.00 |
ALWAYS | 753 | 68 | 59 | 86.76 |
270 logic is_active;
271 1/1 assign is_active = (spi_mode_i == PassThrough);
Tests: T1 T2 T3
272
273 logic [7:0] opcode, opcode_d;
274
275 logic unused_opcode_7;
276 1/1 assign unused_opcode_7 = opcode[7];
Tests: T1 T2 T3
277
278 // If the filter becomes 1 on the 8th beat, it lowers SCK enable signal to CG
279 // cell then, at the 8th posedge of SCK, csb_deassert becomes 1.
280 // ____ ____ ____
281 // SCK ____/ 7 \____/ 8 \____/
282 // ___
283 // filter _______/XXXXXX/ \______________
284 // ______________
285 // sck_gate_en \__________________
286 // ______________
287 // csb_deassert __________________/
288 logic filter;
289
290 // If 1, SCK propagates to the downstream SPI Flash device.
291 logic sck_gate_en;
292
293 // CSb to the downstream device control If 1, CSb is de-asserted. This signal
294 // is glitch sensitive. This value is changed at SCK posedge. This does not
295 // drive CSb output directly. CSb to downstream is OR-ed with this and CSb
296 // from host system.
297 //
298 // `cdb_deassert` should be latched at the posedge of SCK. `filter` signal is
299 // computed in between the 7th posedge of SCK and the 8th posedge. As the
300 // command bit does not arrive until the 7th negedge of SCK, the filter signal
301 // is not valid in the first half of the period. By latching the filter signal
302 // at the posedge of the SCK, csb_deassert always shows correct value if the
303 // command needs to be filtered or not.
304 //
305 // However, the CSb output to the downstream flash device is better to be in
306 // the out clock domain. It helps the design constraints to be simpler. So,
307 // the `csb_deassert` is again latched at the outclk (which is the negedge of
308 // SCK).
309 logic csb_deassert;
310 logic csb_deassert_outclk;
311
312 // == BEGIN: Counters ======================================================
313 // bitcnt to count up to dummy
314 localparam int unsigned MetaMaxBeat = 8+32+8; // Cmd + Addr + Dummy
315 localparam int unsigned MetaBitCntW = $clog2(MetaMaxBeat);
316 logic [MetaBitCntW-1:0] bitcnt;
317
318 // Address or anything host driving after opcode counter
319 logic [AddrCntW-1:0] addrcnt_outclk;
320
321 // Dummy counter
322 logic [DummyCntW-1:0] dummycnt, dummycnt_d;
323 // -- END: Counters ------------------------------------------------------
324
325 // event
326 1/1 assign event_cmd_filtered_o = filter;
Tests: T1 T2 T3
327
328 //////////////
329 // Datapath //
330 //////////////
331
332 // Opcode Latch
333 1/1 assign opcode_d = {opcode[6:0], host_s_i[0]};
Tests: T1 T2 T3
334
335 always_ff @(posedge clk_i or negedge rst_ni) begin
336 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
337 1/1 opcode <= 8'h 00;
Tests: T1 T2 T3
338 1/1 end else if (bitcnt < MetaBitCntW'(8)) begin
Tests: T13 T14 T15
339 1/1 opcode <= opcode_d;
Tests: T13 T14 T15
340 end
MISSING_ELSE
341 end
342
343 // Command Filter: CSb control
344 always_ff @(posedge clk_i or negedge rst_ni) begin
345 2/2 if (!rst_ni) csb_deassert <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
346 2/2 else if (filter) csb_deassert <= 1'b 1;
Tests: T13 T14 T15 | T15 T16 T17
MISSING_ELSE
347 end
348 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
349 2/2 if (!rst_out_ni) csb_deassert_outclk <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
350 1/1 else csb_deassert_outclk <= csb_deassert;
Tests: T13 T14 T15
351 end
352
353 // Look at the waveform above to see why sck_gate_en is inversion of fliter OR
354 // csb_deassert
355 1/1 assign sck_gate_en = ~(filter | csb_deassert);
Tests: T1 T2 T3
356
357 // Bitcnt counter
358 /// Bitcnt increases until it hit the max value then wait reset.
359 always_ff @(posedge clk_i or negedge rst_ni) begin
360 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
361 1/1 bitcnt <= '0;
Tests: T1 T2 T3
362 1/1 end else if (bitcnt != '1) begin
Tests: T13 T14 T15
363 1/1 bitcnt <= bitcnt + MetaBitCntW'(1);
Tests: T13 T14 T15
364 end
MISSING_ELSE
365 end
366
367 // Latch only two bits at 7th cmd opcode
368 logic cmd_7th; // 7th beat of transaction
369 logic cmd_8th; // in 8th beat of transaction
370 logic [1:0] cmd_filter;
371
372 1/1 assign cmd_7th = (bitcnt == MetaBitCntW'(6));
Tests: T1 T2 T3
373 1/1 assign cmd_8th = (bitcnt == MetaBitCntW'(7));
Tests: T1 T2 T3
374
375 always_ff @(posedge clk_i or negedge rst_ni) begin
376 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
377 1/1 cmd_filter <= 2'b 00;
Tests: T1 T2 T3
378 1/1 end else if (cmd_7th) begin
Tests: T13 T14 T15
379 // In this 7th beat, cmd_filter latches 2 bits from cfg_cmd_filter_i
380 // This reduces the last filter datapath from muxing 256 to just mux2
381 //
382 // If below syntax does not work, it can be replaced with
383 // for (int unsigned i = 0 ; i < 128 ; i++) begin
384 // it (i == opcode[6:0]) cmd_filter <= cfg_cmd_filter_i[2*i+:2];
385 // end
386 1/1 cmd_filter <= cfg_cmd_filter_i[{opcode_d[6:0],1'b0}+:2];
Tests: T13 T14 T15
387 end
MISSING_ELSE
388 end
389
390 // Command Info Latch
391 cmd_info_t cmd_info, cmd_info_d;
392 cmd_info_t [1:0] cmd_info_7th, cmd_info_7th_d;
393
394 logic [AddrCntW-1:0] addr_size_d;
395
396 logic cmd_info_latch;
397
398 // Search opcode @ 7th opcode
399 always_comb begin
400 1/1 cmd_info_7th_d = {CmdInfoInput, CmdInfoInput};
Tests: T1 T2 T3
401 1/1 if (cmd_7th) begin
Tests: T1 T2 T3
402 1/1 for(int unsigned i = 0 ; i < NumTotalCmdInfo ; i++) begin
Tests: T13 T14 T15
403 1/1 if (cmd_info_i[i].valid) begin
Tests: T13 T14 T15
404 1/1 if (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b1}) begin
Tests: T13 T14 T15
405 1/1 cmd_info_7th_d[1] = cmd_info_i[i];
Tests: T13 T14 T15
406 1/1 end else if (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b0}) begin
Tests: T13 T14 T15
407 1/1 cmd_info_7th_d[0] = cmd_info_i[i];
Tests: T14 T15 T17
408 end
MISSING_ELSE
409 end // cmd_info_i[i].valid
MISSING_ELSE
410 end
411 end
MISSING_ELSE
412 end
413 always_ff @(posedge clk_i or negedge rst_ni) begin
414 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
415 1/1 cmd_info_7th <= '0;
Tests: T1 T2 T3
416 1/1 end else if (cmd_7th) begin
Tests: T13 T14 T15
417 // Search two candidate among NumCmdInfo. If only one matched, other
418 // cmd_info is Always Input command.
419 1/1 cmd_info_7th <= cmd_info_7th_d;
Tests: T13 T14 T15
420 //cmd_info_7th <= {PassThroughCmdInfo[{opcode_d[6:0],1'b1}],
421 // PassThroughCmdInfo[{opcode_d[6:0],1'b0}]};
422 end
MISSING_ELSE
423 end
424 always_ff @(posedge clk_i or negedge rst_ni) begin
425 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
426 1/1 cmd_info <= '0;
Tests: T1 T2 T3
427 1/1 end else if (cmd_info_latch) begin
Tests: T13 T14 T15
428 // Latch only two cmd_info when the 7th bit arrives. Then select among two
429 // at the 8th beat for cmd_info_d to reduce timing.
430 1/1 cmd_info <= cmd_info_d;
Tests: T15 T16 T17
431 end
MISSING_ELSE
432 end
433
434 // Some of the fields of cmd_info are used in the big FSM below. The opcode field and the addr_*
435 // fields are ignored because we pick them from cmd_info_d instead (in a different FSM state). We
436 // rely on the synthesis tool not to generate the unneeded flops but must explicitly waive lint
437 // warnings about unused fields.
438 logic unused_cmd_info_fields;
439 unreachable assign unused_cmd_info_fields = &{
440 1'b0,
441 cmd_info.valid, // valid bit is checked before latching into cmd_info
442 cmd_info.opcode,
443 cmd_info.opcode,
444 cmd_info.upload,
445 cmd_info.busy
446 };
447
448 always_comb begin
449 1/1 cmd_info_d = '0;
Tests: T1 T2 T3
450
451 1/1 if (cmd_8th) begin
Tests: T1 T2 T3
452 // Latch only two cmd_info when the 7th bit arrives. Then select among two
453 // at the 8th beat for cmd_info_d to reduce timing.
454 1/1 cmd_info_d = cmd_info_7th[host_s_i[0]];
Tests: T13 T14 T15
455
456 1/1 cmd_info_d.opcode = opcode_d;
Tests: T13 T14 T15
457
458 // dummy_size is set inside State Machine
459 end
MISSING_ELSE
460 end
461
462 addr_mode_e addr_mode;
463 1/1 assign addr_mode = get_addr_mode(cmd_info.addr_mode, cfg_addr_4b_en_i);
Tests: T1 T2 T3
464
465 always_comb begin
466 1/1 addr_size_d = AddrCntW'(23);
Tests: T1 T2 T3
467 1/1 if (addr_mode == Addr4B) begin
Tests: T1 T2 T3
468 1/1 addr_size_d = AddrCntW'(31);
Tests: T15 T16 T17
469 end
MISSING_ELSE
470 end
471
472 // Address swap
473 logic addr_set_d, addr_set_q;
474 logic addr_phase, addr_phase_outclk;
475 1/1 assign addr_phase = (st == StAddress);
Tests: T1 T2 T3
476
477 always_ff @(posedge clk_i or negedge rst_ni) begin
478 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
479 1/1 addr_set_q <= '0;
Tests: T1 T2 T3
480 end else begin
481 1/1 addr_set_q <= addr_set_d;
Tests: T13 T14 T15
482 end
483 end
484
485 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
486 1/1 if (!rst_out_ni) begin
Tests: T1 T2 T3
487 1/1 addrcnt_outclk <= '0;
Tests: T1 T2 T3
488 1/1 end else if (addr_set_q) begin
Tests: T13 T14 T15
489 1/1 addrcnt_outclk <= addr_size_d;
Tests: T15 T16 T17
490 1/1 end else if (addrcnt_outclk != '0) begin
Tests: T13 T14 T15
491 1/1 addrcnt_outclk <= addrcnt_outclk - AddrCntW'(1);
Tests: T15 T16 T17
492 end
MISSING_ELSE
493 end
494
495 // Based on AddrCnt, the logic swap.
496 logic addr_swap;
497 1/1 assign addr_swap = cfg_addr_mask_i[addrcnt_outclk]
Tests: T1 T2 T3
498 ? cfg_addr_value_i[addrcnt_outclk]
499 : host_s_i[0];
500
501 // Address swap should happen in outclk domain.
502 // The state machine operates in inclk domain.
503 // The state generates mux selection signal.
504 // The signal latched in outclk domain then activates the mux.
505 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
506 2/2 if (!rst_out_ni) addr_phase_outclk <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
507 1/1 else addr_phase_outclk <= addr_phase;
Tests: T13 T14 T15
508 end
509
510 // Payload (4 bytes) swap
511 logic [4:0] payloadcnt, payloadcnt_outclk;
512 logic payload_replace, payload_replace_outclk;
513 logic payload_replace_set, payload_replace_clr;
514
515 // payload counter
516 //
517 // Reset to 'd31. decrease by 1 in every inclk. Stop at 0 then
518 // payload_replace is cleared.
519 always_ff @(posedge clk_i or negedge rst_ni) begin
520 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
521 1/1 payloadcnt <= 5'h 1F;
Tests: T1 T2 T3
522 1/1 end else if ((payloadcnt != '0) && payload_replace) begin
Tests: T13 T14 T15
523 1/1 payloadcnt <= payloadcnt - 1'b 1;
Tests: T17 T24 T58
524 end
MISSING_ELSE
525 end
526
527 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
528 2/2 if (!rst_out_ni) payloadcnt_outclk <= 5'h 1F;
Tests: T1 T2 T3 | T1 T2 T3
529 1/1 else payloadcnt_outclk <= payloadcnt;
Tests: T13 T14 T15
530 end
531
532 always_ff @(posedge clk_i or negedge rst_ni) begin
533 2/2 if (!rst_ni) payload_replace <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
534 2/2 else if (payload_replace_set) payload_replace <= 1'b 1;
Tests: T13 T14 T15 | T17 T22 T24
535 2/2 else if (payload_replace_clr) payload_replace <= 1'b 0;
Tests: T13 T14 T15 | T17 T24 T59
MISSING_ELSE
536 end
537
538 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
539 2/2 if (!rst_out_ni) payload_replace_outclk <= 1'b 0;
Tests: T1 T2 T3 | T1 T2 T3
540 1/1 else payload_replace_outclk <= payload_replace;
Tests: T13 T14 T15
541 end
542
543 1/1 assign payload_replace_clr = (payloadcnt == '0);
Tests: T1 T2 T3
544 // FSM drives payload_replace_set : assert when st moves to StDriving
545 logic payload_swap;
546 1/1 assign payload_swap = cfg_payload_mask_i[payloadcnt_outclk]
Tests: T1 T2 T3
547 ? cfg_payload_data_i[payloadcnt_outclk]
548 : host_s_i[0] ;
549
550 // SPI swap (merging Addr & Payload)
551 logic swap_en, swap_data, addr_swap_en, payload_swap_en;
552
553 // Latch cmd_info config signals in output clock.
554 // cmd_info structure is latched in input clock. But addr_swap_en and
555 // payload_swap_en affects the output path (from host to the downstream flash
556 // device). as the output delay is bigger than the half of SCK, these paths
557 // violates timing regardless of the path delay. By latching the configs
558 // into output clock (inverted SCK), it alleviates the timing budget.
559 logic cmd_info_addr_swap_en_outclk, cmd_info_payload_swap_en_outclk;
560 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
561 1/1 if (!rst_out_ni) begin
Tests: T1 T2 T3
562 1/1 cmd_info_addr_swap_en_outclk <= 1'b 0;
Tests: T1 T2 T3
563 1/1 cmd_info_payload_swap_en_outclk <= 1'b 0;
Tests: T1 T2 T3
564 end else begin
565 1/1 cmd_info_addr_swap_en_outclk <= cmd_info.addr_swap_en;
Tests: T13 T14 T15
566 1/1 cmd_info_payload_swap_en_outclk <= cmd_info.payload_swap_en;
Tests: T13 T14 T15
567 end
568 end
569
570 1/1 assign addr_swap_en = addr_phase_outclk
Tests: T1 T2 T3
571 & cmd_info_addr_swap_en_outclk;
572 1/1 assign payload_swap_en = payload_replace_outclk
Tests: T1 T2 T3
573 & cmd_info_payload_swap_en_outclk;
574
575 1/1 assign swap_en = addr_swap_en | payload_swap_en ;
Tests: T1 T2 T3
576 1/1 assign swap_data = (addr_swap_en) ? addr_swap : payload_swap ;
Tests: T1 T2 T3
577
578 // Dummy Counter
579 logic dummy_set;
580 logic dummycnt_zero;
581 always_ff @(posedge clk_i or negedge rst_ni) begin
582 2/2 if (!rst_ni) dummycnt <= '0;
Tests: T1 T2 T3 | T1 T2 T3
583 1/1 else if (dummy_set) begin
Tests: T13 T14 T15
584 1/1 dummycnt <= dummycnt_d;
Tests: T15 T16 T17
585 1/1 end else if (st == StHighZ) begin
Tests: T13 T14 T15
586 1/1 dummycnt <= dummycnt - 1'b 1;
Tests: T15 T16 T17
587 end
MISSING_ELSE
588 end
589 1/1 assign dummycnt_zero = (dummycnt == '0);
Tests: T1 T2 T3
590
591 // MByte counter
592 logic mbyte_set;
593 logic mbytecnt_zero;
594 logic [1:0] mbyte_cnt;
595 always_ff @(posedge clk_i or negedge rst_ni) begin
596 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
597 1/1 mbyte_cnt <= '0;
Tests: T1 T2 T3
598 1/1 end else if (mbyte_set) begin
Tests: T13 T14 T15
599 0/1 ==> mbyte_cnt <= 2'h 3;
600 1/1 end else if (st == StMByte) begin
Tests: T13 T14 T15
601 0/1 ==> mbyte_cnt <= mbyte_cnt - 1'b 1;
602 end
MISSING_ELSE
603 end
604 1/1 assign mbytecnt_zero = (mbyte_cnt == '0);
Tests: T1 T2 T3
605
606 // = BEGIN: Passthrough Mux (!important) ====================================
607
608 // As swap_en is in outclk domain, addr_swap can be directly used.
609 1/1 assign passthrough_o.s = (swap_en) ? {host_s_i[3:1], swap_data} : host_s_i ;
Tests: T1 T2 T3
610
611 logic [3:0] passthrough_s_en;
612 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
613 2/2 if (!rst_out_ni) passthrough_s_en <= 4'h 1; // S[0] active by default
Tests: T1 T2 T3 | T1 T2 T3
614 1/1 else passthrough_s_en <= device_s_en_inclk;
Tests: T13 T14 T15
615 end
616 1/1 assign passthrough_o.s_en = passthrough_s_en;
Tests: T1 T2 T3
617
618 // 2-stage pipeline for high-throughput read commands
619 logic [3:0] half_cycle_sampled_sd;
620 logic [3:0] read_pipeline_stg1_d, read_pipeline_stg1_q;
621 logic [3:0] read_pipeline_stg2_d, read_pipeline_stg2_q;
622 logic [3:0] host_s_en_muxed;
623 logic [3:0] read_pipeline_oe_stg1_d, read_pipeline_oe_stg1_q;
624 logic [3:0] read_pipeline_oe_stg2_d, read_pipeline_oe_stg2_q;
625
626 // Sample on the ordinary capture edge, in case half-cycle sampling is
627 // selected. This flop samples data that is to be prepared for a later
628 // launch edge, in a sort of store-and-forward setup.
629 prim_flop #(
630 .Width ($bits(passthrough_i.s)),
631 .ResetValue ('0)
632 ) u_read_half_cycle (
633 .clk_i (clk_i),
634 .rst_ni,
635 .d_i (passthrough_i.s),
636 .q_o (half_cycle_sampled_sd)
637 );
638
639 // This flop begins the 2-stage pipeline on clk_out_i, the launch clock for
640 // data output. The input data is either the combinatorial input from the
641 // pad connected to the downstream SPI flash, or it is the output of the
642 // u_read_half_cycle flop above, which sampled the data on the capture edge
643 // that occurred a half cycle earlier.
644 prim_flop #(
645 .Width ($bits(read_pipeline_stg1_d)),
646 .ResetValue ('0)
647 ) u_read_pipe_stg1 (
648 .clk_i (clk_out_i),
649 .rst_ni (rst_out_ni),
650 .d_i (read_pipeline_stg1_d),
651 .q_o (read_pipeline_stg1_q)
652 );
653
654 prim_flop #(
655 .Width ($bits(read_pipeline_stg2_d)),
656 .ResetValue ('0)
657 ) u_read_pipe_stg2 (
658 .clk_i (clk_out_i),
659 .rst_ni (rst_out_ni),
660 .d_i (read_pipeline_stg2_d),
661 .q_o (read_pipeline_stg2_q)
662 );
663
664 prim_flop #(
665 .Width ($bits(read_pipeline_oe_stg1_d)),
666 .ResetValue ('0)
667 ) u_read_pipe_oe_stg1 (
668 .clk_i (clk_out_i),
669 .rst_ni (rst_out_ni),
670 .d_i (read_pipeline_oe_stg1_d),
671 .q_o (read_pipeline_oe_stg1_q)
672 );
673
674 prim_flop #(
675 .Width ($bits(read_pipeline_oe_stg2_d)),
676 .ResetValue ('0)
677 ) u_read_pipe_oe_stg2 (
678 .clk_i (clk_out_i),
679 .rst_ni (rst_out_ni),
680 .d_i (read_pipeline_oe_stg2_d),
681 .q_o (read_pipeline_oe_stg2_q)
682 );
683
684 always_comb begin
685 1/1 host_s_o = passthrough_i.s;
Tests: T1 T2 T3
686 1/1 read_pipeline_stg2_d = read_pipeline_stg1_q;
Tests: T1 T2 T3
687 1/1 read_pipeline_stg1_d = half_cycle_sampled_sd;
Tests: T1 T2 T3
688
689 1/1 host_s_en_muxed = host_s_en_inclk;
Tests: T1 T2 T3
690 1/1 read_pipeline_oe_stg2_d = read_pipeline_oe_stg1_q;
Tests: T1 T2 T3
691 1/1 read_pipeline_oe_stg1_d = host_s_en_inclk;
Tests: T1 T2 T3
692
693 1/1 unique case (cmd_info.read_pipeline_mode)
Tests: T1 T2 T3
694 RdPipeTwoStageFullCycle: begin
695 1/1 host_s_o = read_pipeline_stg2_q;
Tests: T16 T21 T57
696 1/1 read_pipeline_stg1_d = passthrough_i.s;
Tests: T16 T21 T57
697 1/1 host_s_en_muxed = read_pipeline_oe_stg2_q;
Tests: T16 T21 T57
698 end
699 RdPipeTwoStageHalfCycle: begin
700 1/1 host_s_o = read_pipeline_stg2_q;
Tests: T17 T24 T57
701 1/1 read_pipeline_stg1_d = half_cycle_sampled_sd;
Tests: T17 T24 T57
702 1/1 host_s_en_muxed = read_pipeline_oe_stg2_q;
Tests: T17 T24 T57
703 end
704 default: begin
705 host_s_o = passthrough_i.s;
706 read_pipeline_stg1_d = half_cycle_sampled_sd;
707 host_s_en_muxed = host_s_en_inclk;
708 end
709 endcase
710 end
711
712 always_ff @(posedge clk_out_i or negedge rst_out_ni) begin
713 2/2 if (!rst_out_ni) host_s_en_o <= '0; // input mode
Tests: T1 T2 T3 | T1 T2 T3
714 1/1 else host_s_en_o <= host_s_en_muxed;
Tests: T13 T14 T15
715 end
716
717 logic pt_gated_sck;
718 prim_clock_gating #(
719 .NoFpgaGate (1'b 0),
720 .FpgaBufGlobal (1'b 1) // Going outside of chip
721 ) u_pt_sck_cg (
722 .clk_i (host_sck_i ),
723 .en_i (sck_gate_en ),
724 .test_en_i (1'b 0 ), // No FF connected to this gated SCK
725 .clk_o (pt_gated_sck)
726 );
727
728 1/1 assign passthrough_o.sck = pt_gated_sck;
Tests: T1 T2 T3
729 assign passthrough_o.sck_en = 1'b 1;
730
731 // CSb propagation: csb_deassert signal should be an output of FF or latch to
732 // make CSb glitch-free.
733 assign passthrough_o.csb_en = 1'b 1;
734 1/1 assign passthrough_o.csb = host_csb_i | csb_deassert_outclk ;
Tests: T1 T2 T3
735
736 // passthrough_en
737 1/1 assign passthrough_o.passthrough_en = is_active && !passthrough_block_i;
Tests: T1 T2 T3
738
739 // - END: Passthrough Mux (!important) ------------------------------------
740
741 ///////////////////
742 // State Machine //
743 ///////////////////
744 always_ff @(posedge clk_i or negedge rst_ni) begin
745 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
746 1/1 st <= StIdle;
Tests: T1 T2 T3
747 end else begin
748 1/1 st <= st_d;
Tests: T13 T14 T15
749 end
750 end
751
752 always_comb begin
753 1/1 st_d = st;
Tests: T1 T2 T3
754
755 // filter
756 1/1 filter = 1'b 0;
Tests: T1 T2 T3
757
758 // Command Cfg Latch
759 1/1 cmd_info_latch = 1'b 0;
Tests: T1 T2 T3
760
761 // addr_set
762 1/1 addr_set_d = 1'b 0;
Tests: T1 T2 T3
763
764 // Payload swap control
765 1/1 payload_replace_set = 1'b 0;
Tests: T1 T2 T3
766
767 // mbyte counter udpate
768 1/1 mbyte_set = 1'b 0;
Tests: T1 T2 T3
769
770 // Dummy
771 1/1 dummy_set = 1'b 0;
Tests: T1 T2 T3
772 1/1 dummycnt_d = '0;
Tests: T1 T2 T3
773
774 // Output enable
775 1/1 host_s_en_inclk = 4'h 0;
Tests: T1 T2 T3
776 1/1 device_s_en_inclk = 4'h 1; // S[0] MOSI active
Tests: T1 T2 T3
777
778 1/1 unique case (st)
Tests: T1 T2 T3
779 StIdle: begin
780 1/1 if (!is_active) begin
Tests: T1 T2 T3
781 1/1 st_d = StIdle;
Tests: T1 T2 T3
782 1/1 end else if (cmd_8th && cmd_filter[host_s_i[0]]) begin
Tests: T15 T16 T17
783 1/1 st_d = StFilter;
Tests: T15 T16 T17
784 1/1 filter = 1'b 1;
Tests: T15 T16 T17
785
786 // Send notification event to SW
787 1/1 end else if (cmd_8th && cmd_info_d.valid) begin
Tests: T15 T16 T17
788 1/1 cmd_info_latch = 1'b 1;
Tests: T15 T16 T17
789
790 // Divert to multiple states.
791 //
792 // The following states are mainly for controlling the output enable
793 // signals. StAddress state, however, controls the SPI lines for
794 // address swap in case of Read Commands.
795 //
796 // Order: addr_mode , dummy_en, |payload_en
797 // Note that no direct transition to MByte state.
798 1/1 if (cmd_info_d.addr_mode != AddrDisabled) begin
Tests: T15 T16 T17
799 1/1 st_d = StAddress;
Tests: T15 T16 T17
800
801 1/1 addr_set_d = 1'b 1;
Tests: T15 T16 T17
802 1/1 end else if (cmd_info_d.dummy_en) begin
Tests: T15 T16 T17
803 1/1 st_d = StHighZ;
Tests: T23 T60 T61
804
805 1/1 dummy_set = 1'b 1;
Tests: T23 T60 T61
806 1/1 dummycnt_d = cmd_info_d.dummy_size;
Tests: T23 T60 T61
807 1/1 end else if (cmd_info_d.payload_en != 0) begin
Tests: T15 T16 T17
808 // Any input/output payload
809 1/1 if (cmd_info_d.payload_dir == PayloadOut) begin
Tests: T15 T16 T17
810 1/1 st_d = StWait;
Tests: T15 T16 T23
811 end else begin
812 1/1 st_d = StDriving;
Tests: T17 T22 T62
813
814 1/1 payload_replace_set = 1'b 1;
Tests: T17 T22 T62
815 end
816 end
MISSING_ELSE
817 end // cmd_8th && cmd_info_d.valid
818 1/1 else if (cmd_8th) begin
Tests: T15 T16 T17
819 // cmd_info_d.valid is 0. Skip current transaction
820 1/1 st_d = StFilter;
Tests: T15 T17 T21
821 1/1 filter = 1'b 1;
Tests: T15 T17 T21
822 end
MISSING_ELSE
823 end
824
825 StMByte: begin
826 0/1 ==> if (mbytecnt_zero) begin
827 0/1 ==> st_d = StHighZ;
828
829 0/1 ==> dummy_set = 1'b 1;
830 0/1 ==> dummycnt_d = cmd_info_d.dummy_size;
831 end else begin
832 0/1 ==> st_d = StMByte;
833 end
834 end
835
836 StFilter: begin
837 // Command is filtered. Wait until reset(CSb) comes.
838 1/1 st_d = StFilter;
Tests: T15 T16 T17
839 1/1 host_s_en_inclk = 4'h 0; // explicit
Tests: T15 T16 T17
840 1/1 device_s_en_inclk = 4'h 0;
Tests: T15 T16 T17
841 end
842
843 StWait: begin
844 // Device Returns Data to host
845 1/1 st_d = StWait;
Tests: T15 T16 T17
846
847 // output enable for host
848 1/1 host_s_en_inclk = cmd_info.payload_en;
Tests: T15 T16 T17
849 1/1 device_s_en_inclk = 4'h 0;
Tests: T15 T16 T17
850 end
851
852 StDriving: begin
853 // Host sends Data to device
854 1/1 st_d = StDriving;
Tests: T17 T22 T24
855
856 // Output enable for device
857 1/1 host_s_en_inclk = 4'h 0; // explicit
Tests: T17 T22 T24
858 1/1 device_s_en_inclk = cmd_info.payload_en;
Tests: T17 T22 T24
859 end
860
861 StHighZ: begin
862 1/1 host_s_en_inclk = 4'h 0; // explicit
Tests: T15 T16 T17
863 1/1 device_s_en_inclk = 4'h 0; // float
Tests: T15 T16 T17
864 1/1 if (dummycnt_zero && (cmd_info.payload_dir == PayloadOut)) begin
Tests: T15 T16 T17
865 // Assume payload_en not 0
866 1/1 st_d = StWait;
Tests: T15 T16 T17
867 1/1 end else if (dummycnt_zero && (cmd_info.payload_dir == PayloadIn)) begin
Tests: T15 T16 T17
868 0/1 ==> st_d = StDriving;
869
870 0/1 ==> payload_replace_set = 1'b 1;
871 end
MISSING_ELSE
872 end
873
874 StAddress: begin
875 // based on state, addr_phase is set. So just check if counter reaches 0
876 1/1 if (addrcnt_outclk == '0) begin
Tests: T15 T16 T17
877 1/1 if (cmd_info.mbyte_en) begin
Tests: T15 T16 T17
878 0/1 ==> st_d = StMByte;
879
880 0/1 ==> mbyte_set = 1'b 1;
881 1/1 end else if (cmd_info.dummy_en) begin
Tests: T15 T16 T17
882 1/1 st_d = StHighZ;
Tests: T15 T16 T17
883
884 1/1 dummy_set = 1'b 1;
Tests: T15 T16 T17
885 1/1 dummycnt_d = cmd_info.dummy_size;
Tests: T15 T16 T17
886 1/1 end else if (cmd_info.payload_en != 0
Tests: T15 T17 T21
887 && (cmd_info.payload_dir == PayloadOut)) begin
888 1/1 st_d = StWait;
Tests: T17 T21 T63
889 1/1 end else if (cmd_info.payload_en != 0
Tests: T15 T17 T24
890 && (cmd_info.payload_dir == PayloadIn)) begin
891 1/1 st_d = StDriving;
Tests: T24 T61 T52
892
893 1/1 payload_replace_set = 1'b 1;
Tests: T24 T61 T52
894 end else begin
895 // Addr completed command. goto wait state
896 1/1 st_d = StWait;
Tests: T15 T17 T56
897 end
898 end
MISSING_ELSE
899 end
900
901 default: begin
902 st_d = StIdle;
Cond Coverage for Module :
spi_passthrough
| Total | Covered | Percent |
Conditions | 97 | 86 | 88.66 |
Logical | 97 | 86 | 88.66 |
Non-Logical | 0 | 0 | |
Event | 0 | 0 | |
LINE 271
EXPRESSION (spi_mode_i == PassThrough)
-------------1-------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T15,T16,T17 |
LINE 355
SUB-EXPRESSION (filter | csb_deassert)
---1-- ------2-----
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T15,T16,T17 |
1 | 0 | Covered | T15,T16,T17 |
LINE 362
EXPRESSION (bitcnt != '1)
-------1------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T13,T14,T15 |
LINE 372
EXPRESSION (bitcnt == 6'(6))
--------1--------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T13,T14,T15 |
LINE 373
EXPRESSION (bitcnt == 6'(7))
--------1--------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T13,T14,T15 |
LINE 404
EXPRESSION (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b1})
-----------------------1-----------------------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T13,T14,T15 |
LINE 406
EXPRESSION (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b0})
-----------------------1-----------------------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T14,T15,T17 |
LINE 467
EXPRESSION (addr_mode == Addr4B)
----------1----------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T15,T16,T17 |
LINE 475
EXPRESSION (st == StAddress)
--------1--------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T15,T16,T17 |
LINE 490
EXPRESSION (addrcnt_outclk != '0)
-----------1----------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T15,T16,T17 |
LINE 497
EXPRESSION (cfg_addr_mask_i[addrcnt_outclk] ? cfg_addr_value_i[addrcnt_outclk] : host_s_i[0])
---------------1---------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T14,T15,T16 |
LINE 522
EXPRESSION ((payloadcnt != '0) && payload_replace)
---------1-------- -------2-------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T17,T24,T59 |
1 | 0 | Covered | T13,T14,T15 |
1 | 1 | Covered | T17,T24,T58 |
LINE 522
SUB-EXPRESSION (payloadcnt != '0)
---------1--------
-1- | Status | Tests |
0 | Covered | T17,T24,T59 |
1 | Covered | T13,T14,T15 |
LINE 543
EXPRESSION (payloadcnt == '0)
---------1--------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T17,T24,T59 |
LINE 546
EXPRESSION (cfg_payload_mask_i[payloadcnt_outclk] ? cfg_payload_data_i[payloadcnt_outclk] : host_s_i[0])
------------------1------------------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T15,T17,T21 |
LINE 570
EXPRESSION (addr_phase_outclk & cmd_info_addr_swap_en_outclk)
--------1-------- --------------2-------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T16,T23,T64 |
1 | 0 | Covered | T15,T17,T21 |
1 | 1 | Covered | T16,T23,T64 |
LINE 572
EXPRESSION (payload_replace_outclk & cmd_info_payload_swap_en_outclk)
-----------1---------- ---------------2---------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T61,T51,T52 |
1 | 0 | Covered | T17,T22,T24 |
1 | 1 | Covered | T61,T51,T52 |
LINE 575
EXPRESSION (addr_swap_en | payload_swap_en)
------1----- -------2-------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T1,T2,T3 |
0 | 1 | Covered | T61,T51,T52 |
1 | 0 | Covered | T16,T23,T64 |
LINE 576
EXPRESSION (addr_swap_en ? addr_swap : payload_swap)
------1-----
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T16,T23,T64 |
LINE 585
EXPRESSION (st == StHighZ)
-------1-------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Covered | T15,T16,T17 |
LINE 589
EXPRESSION (dummycnt == '0)
--------1-------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 600
EXPRESSION (st == StMByte)
-------1-------
-1- | Status | Tests |
0 | Covered | T13,T14,T15 |
1 | Not Covered | |
LINE 604
EXPRESSION (mbyte_cnt == '0)
--------1--------
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T1,T2,T3 |
LINE 609
EXPRESSION (swap_en ? ({host_s_i[3:1], swap_data}) : host_s_i)
---1---
-1- | Status | Tests |
0 | Covered | T1,T2,T3 |
1 | Covered | T16,T23,T64 |
LINE 734
EXPRESSION (host_csb_i | csb_deassert_outclk)
-----1---- ---------2---------
-1- | -2- | Status | Tests |
0 | 0 | Covered | T2,T8,T13 |
0 | 1 | Covered | T15,T16,T17 |
1 | 0 | Covered | T1,T2,T3 |
LINE 737
EXPRESSION (is_active && ((!passthrough_block_i)))
----1---- ------------2-----------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T1,T2,T3 |
1 | 0 | Covered | T24,T56,T65 |
1 | 1 | Covered | T15,T16,T17 |
LINE 782
EXPRESSION (cmd_8th && cmd_filter[host_s_i[0]])
---1--- -----------2-----------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Covered | T15,T16,T17 |
1 | 1 | Covered | T15,T16,T17 |
LINE 787
EXPRESSION (cmd_8th && cmd_info_d.valid)
---1--- --------2-------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Covered | T15,T17,T21 |
1 | 1 | Covered | T15,T16,T17 |
LINE 798
EXPRESSION (cmd_info_d.addr_mode != AddrDisabled)
-------------------1------------------
-1- | Status | Tests |
0 | Covered | T15,T16,T17 |
1 | Covered | T15,T16,T17 |
LINE 807
EXPRESSION (cmd_info_d.payload_en != 4'b0)
---------------1---------------
-1- | Status | Tests |
0 | Covered | T24,T66,T67 |
1 | Covered | T15,T16,T17 |
LINE 809
EXPRESSION (cmd_info_d.payload_dir == PayloadOut)
-------------------1------------------
-1- | Status | Tests |
0 | Covered | T17,T22,T62 |
1 | Covered | T15,T16,T23 |
LINE 864
EXPRESSION (dummycnt_zero && (cmd_info.payload_dir == PayloadOut))
------1------ ------------------2-----------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T15,T16,T17 |
1 | 0 | Not Covered | |
1 | 1 | Covered | T15,T16,T17 |
LINE 864
SUB-EXPRESSION (cmd_info.payload_dir == PayloadOut)
------------------1-----------------
-1- | Status | Tests |
0 | Not Covered | |
1 | Covered | T15,T16,T17 |
LINE 867
EXPRESSION (dummycnt_zero && (cmd_info.payload_dir == PayloadIn))
------1------ -----------------2-----------------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Not Covered | |
LINE 867
SUB-EXPRESSION (cmd_info.payload_dir == PayloadIn)
-----------------1-----------------
-1- | Status | Tests |
0 | Covered | T15,T16,T17 |
1 | Not Covered | |
LINE 876
EXPRESSION (addrcnt_outclk == '0)
-----------1----------
-1- | Status | Tests |
0 | Covered | T15,T16,T17 |
1 | Covered | T15,T16,T17 |
LINE 886
EXPRESSION ((cmd_info.payload_en != 4'b0) && (cmd_info.payload_dir == PayloadOut))
--------------1-------------- ------------------2-----------------
-1- | -2- | Status | Tests |
0 | 1 | Covered | T15,T17,T56 |
1 | 0 | Covered | T24,T61,T52 |
1 | 1 | Covered | T17,T21,T63 |
LINE 886
SUB-EXPRESSION (cmd_info.payload_en != 4'b0)
--------------1--------------
-1- | Status | Tests |
0 | Covered | T15,T17,T56 |
1 | Covered | T17,T21,T24 |
LINE 886
SUB-EXPRESSION (cmd_info.payload_dir == PayloadOut)
------------------1-----------------
-1- | Status | Tests |
0 | Covered | T24,T61,T52 |
1 | Covered | T15,T17,T21 |
LINE 889
EXPRESSION ((cmd_info.payload_en != 4'b0) && (cmd_info.payload_dir == PayloadIn))
--------------1-------------- -----------------2-----------------
-1- | -2- | Status | Tests |
0 | 1 | Not Covered | |
1 | 0 | Not Covered | |
1 | 1 | Covered | T24,T61,T52 |
LINE 889
SUB-EXPRESSION (cmd_info.payload_en != 4'b0)
--------------1--------------
-1- | Status | Tests |
0 | Covered | T15,T17,T56 |
1 | Covered | T24,T61,T52 |
LINE 889
SUB-EXPRESSION (cmd_info.payload_dir == PayloadIn)
-----------------1-----------------
-1- | Status | Tests |
0 | Covered | T15,T17,T56 |
1 | Covered | T24,T61,T52 |
FSM Coverage for Module :
spi_passthrough
Summary for FSM :: st
| Total | Covered | Percent | |
States |
7 |
6 |
85.71 |
(Not included in score) |
Transitions |
12 |
9 |
75.00 |
|
Sequences |
0 |
0 |
|
|
State, Transition and Sequence Details for FSM :: st
states | Line No. | Covered | Tests |
StAddress |
799 |
Covered |
T15,T16,T17 |
StDriving |
812 |
Covered |
T17,T22,T24 |
StFilter |
783 |
Covered |
T15,T16,T17 |
StHighZ |
803 |
Covered |
T15,T16,T17 |
StIdle |
781 |
Covered |
T1,T2,T3 |
StMByte |
832 |
Not Covered |
|
StWait |
810 |
Covered |
T15,T16,T17 |
transitions | Line No. | Covered | Tests |
StAddress->StDriving |
891 |
Covered |
T24,T61,T52 |
StAddress->StHighZ |
882 |
Covered |
T15,T16,T17 |
StAddress->StMByte |
878 |
Not Covered |
|
StAddress->StWait |
888 |
Covered |
T15,T17,T21 |
StHighZ->StDriving |
868 |
Not Covered |
|
StHighZ->StWait |
866 |
Covered |
T15,T16,T17 |
StIdle->StAddress |
799 |
Covered |
T15,T16,T17 |
StIdle->StDriving |
812 |
Covered |
T17,T22,T62 |
StIdle->StFilter |
783 |
Covered |
T15,T16,T17 |
StIdle->StHighZ |
803 |
Covered |
T23,T60,T61 |
StIdle->StWait |
810 |
Covered |
T15,T16,T23 |
StMByte->StHighZ |
827 |
Not Covered |
|
Branch Coverage for Module :
spi_passthrough
| Line No. | Total | Covered | Percent |
Branches |
|
96 |
89 |
92.71 |
TERNARY |
497 |
2 |
2 |
100.00 |
TERNARY |
546 |
2 |
2 |
100.00 |
TERNARY |
576 |
2 |
2 |
100.00 |
TERNARY |
609 |
2 |
2 |
100.00 |
IF |
336 |
3 |
3 |
100.00 |
IF |
345 |
3 |
3 |
100.00 |
IF |
349 |
2 |
2 |
100.00 |
IF |
360 |
3 |
3 |
100.00 |
IF |
376 |
3 |
3 |
100.00 |
IF |
401 |
2 |
2 |
100.00 |
IF |
414 |
3 |
3 |
100.00 |
IF |
425 |
3 |
3 |
100.00 |
IF |
451 |
2 |
2 |
100.00 |
IF |
467 |
2 |
2 |
100.00 |
IF |
478 |
2 |
2 |
100.00 |
IF |
486 |
4 |
4 |
100.00 |
IF |
506 |
2 |
2 |
100.00 |
IF |
520 |
3 |
3 |
100.00 |
IF |
528 |
2 |
2 |
100.00 |
IF |
533 |
4 |
4 |
100.00 |
IF |
539 |
2 |
2 |
100.00 |
IF |
561 |
2 |
2 |
100.00 |
IF |
582 |
4 |
4 |
100.00 |
IF |
596 |
4 |
2 |
50.00 |
IF |
613 |
2 |
2 |
100.00 |
CASE |
693 |
3 |
3 |
100.00 |
IF |
713 |
2 |
2 |
100.00 |
IF |
745 |
2 |
2 |
100.00 |
CASE |
778 |
24 |
19 |
79.17 |
497 assign addr_swap = cfg_addr_mask_i[addrcnt_outclk]
498 ? cfg_addr_value_i[addrcnt_outclk]
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T14,T15,T16 |
0 |
Covered |
T1,T2,T3 |
546 assign payload_swap = cfg_payload_mask_i[payloadcnt_outclk]
547 ? cfg_payload_data_i[payloadcnt_outclk]
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T15,T17,T21 |
0 |
Covered |
T1,T2,T3 |
576 assign swap_data = (addr_swap_en) ? addr_swap : payload_swap ;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T16,T23,T64 |
0 |
Covered |
T1,T2,T3 |
609 assign passthrough_o.s = (swap_en) ? {host_s_i[3:1], swap_data} : host_s_i ;
-1-
==>
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T16,T23,T64 |
0 |
Covered |
T1,T2,T3 |
336 if (!rst_ni) begin
-1-
337 opcode <= 8'h 00;
==>
338 end else if (bitcnt < MetaBitCntW'(8)) begin
-2-
339 opcode <= opcode_d;
==>
340 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T13,T14,T15 |
0 |
0 |
Covered |
T13,T14,T15 |
345 if (!rst_ni) csb_deassert <= 1'b 0;
-1-
==>
346 else if (filter) csb_deassert <= 1'b 1;
-2-
==>
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T15,T16,T17 |
0 |
0 |
Covered |
T13,T14,T15 |
349 if (!rst_out_ni) csb_deassert_outclk <= 1'b 0;
-1-
==>
350 else csb_deassert_outclk <= csb_deassert;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
360 if (!rst_ni) begin
-1-
361 bitcnt <= '0;
==>
362 end else if (bitcnt != '1) begin
-2-
363 bitcnt <= bitcnt + MetaBitCntW'(1);
==>
364 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T13,T14,T15 |
0 |
0 |
Covered |
T13,T14,T15 |
376 if (!rst_ni) begin
-1-
377 cmd_filter <= 2'b 00;
==>
378 end else if (cmd_7th) begin
-2-
379 // In this 7th beat, cmd_filter latches 2 bits from cfg_cmd_filter_i
380 // This reduces the last filter datapath from muxing 256 to just mux2
381 //
382 // If below syntax does not work, it can be replaced with
383 // for (int unsigned i = 0 ; i < 128 ; i++) begin
384 // it (i == opcode[6:0]) cmd_filter <= cfg_cmd_filter_i[2*i+:2];
385 // end
386 cmd_filter <= cfg_cmd_filter_i[{opcode_d[6:0],1'b0}+:2];
==>
387 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T13,T14,T15 |
0 |
0 |
Covered |
T13,T14,T15 |
401 if (cmd_7th) begin
-1-
402 for(int unsigned i = 0 ; i < NumTotalCmdInfo ; i++) begin
==>
403 if (cmd_info_i[i].valid) begin
404 if (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b1}) begin
405 cmd_info_7th_d[1] = cmd_info_i[i];
406 end else if (cmd_info_i[i].opcode == {opcode_d[6:0], 1'b0}) begin
407 cmd_info_7th_d[0] = cmd_info_i[i];
408 end
409 end // cmd_info_i[i].valid
410 end
411 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T13,T14,T15 |
0 |
Covered |
T1,T2,T3 |
414 if (!rst_ni) begin
-1-
415 cmd_info_7th <= '0;
==>
416 end else if (cmd_7th) begin
-2-
417 // Search two candidate among NumCmdInfo. If only one matched, other
418 // cmd_info is Always Input command.
419 cmd_info_7th <= cmd_info_7th_d;
==>
420 //cmd_info_7th <= {PassThroughCmdInfo[{opcode_d[6:0],1'b1}],
421 // PassThroughCmdInfo[{opcode_d[6:0],1'b0}]};
422 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T13,T14,T15 |
0 |
0 |
Covered |
T13,T14,T15 |
425 if (!rst_ni) begin
-1-
426 cmd_info <= '0;
==>
427 end else if (cmd_info_latch) begin
-2-
428 // Latch only two cmd_info when the 7th bit arrives. Then select among two
429 // at the 8th beat for cmd_info_d to reduce timing.
430 cmd_info <= cmd_info_d;
==>
431 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T15,T16,T17 |
0 |
0 |
Covered |
T13,T14,T15 |
451 if (cmd_8th) begin
-1-
452 // Latch only two cmd_info when the 7th bit arrives. Then select among two
453 // at the 8th beat for cmd_info_d to reduce timing.
454 cmd_info_d = cmd_info_7th[host_s_i[0]];
==>
455
456 cmd_info_d.opcode = opcode_d;
457
458 // dummy_size is set inside State Machine
459 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T13,T14,T15 |
0 |
Covered |
T1,T2,T3 |
467 if (addr_mode == Addr4B) begin
-1-
468 addr_size_d = AddrCntW'(31);
==>
469 end
MISSING_ELSE
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T15,T16,T17 |
0 |
Covered |
T1,T2,T3 |
478 if (!rst_ni) begin
-1-
479 addr_set_q <= '0;
==>
480 end else begin
481 addr_set_q <= addr_set_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
486 if (!rst_out_ni) begin
-1-
487 addrcnt_outclk <= '0;
==>
488 end else if (addr_set_q) begin
-2-
489 addrcnt_outclk <= addr_size_d;
==>
490 end else if (addrcnt_outclk != '0) begin
-3-
491 addrcnt_outclk <= addrcnt_outclk - AddrCntW'(1);
==>
492 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T15,T16,T17 |
0 |
0 |
1 |
Covered |
T15,T16,T17 |
0 |
0 |
0 |
Covered |
T13,T14,T15 |
506 if (!rst_out_ni) addr_phase_outclk <= 1'b 0;
-1-
==>
507 else addr_phase_outclk <= addr_phase;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
520 if (!rst_ni) begin
-1-
521 payloadcnt <= 5'h 1F;
==>
522 end else if ((payloadcnt != '0) && payload_replace) begin
-2-
523 payloadcnt <= payloadcnt - 1'b 1;
==>
524 end
MISSING_ELSE
==>
Branches:
-1- | -2- | Status | Tests |
1 |
- |
Covered |
T1,T2,T3 |
0 |
1 |
Covered |
T17,T24,T58 |
0 |
0 |
Covered |
T13,T14,T15 |
528 if (!rst_out_ni) payloadcnt_outclk <= 5'h 1F;
-1-
==>
529 else payloadcnt_outclk <= payloadcnt;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
533 if (!rst_ni) payload_replace <= 1'b 0;
-1-
==>
534 else if (payload_replace_set) payload_replace <= 1'b 1;
-2-
==>
535 else if (payload_replace_clr) payload_replace <= 1'b 0;
-3-
==>
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T17,T22,T24 |
0 |
0 |
1 |
Covered |
T17,T24,T59 |
0 |
0 |
0 |
Covered |
T13,T14,T15 |
539 if (!rst_out_ni) payload_replace_outclk <= 1'b 0;
-1-
==>
540 else payload_replace_outclk <= payload_replace;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
561 if (!rst_out_ni) begin
-1-
562 cmd_info_addr_swap_en_outclk <= 1'b 0;
==>
563 cmd_info_payload_swap_en_outclk <= 1'b 0;
564 end else begin
565 cmd_info_addr_swap_en_outclk <= cmd_info.addr_swap_en;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
582 if (!rst_ni) dummycnt <= '0;
-1-
==>
583 else if (dummy_set) begin
-2-
584 dummycnt <= dummycnt_d;
==>
585 end else if (st == StHighZ) begin
-3-
586 dummycnt <= dummycnt - 1'b 1;
==>
587 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Covered |
T15,T16,T17 |
0 |
0 |
1 |
Covered |
T15,T16,T17 |
0 |
0 |
0 |
Covered |
T13,T14,T15 |
596 if (!rst_ni) begin
-1-
597 mbyte_cnt <= '0;
==>
598 end else if (mbyte_set) begin
-2-
599 mbyte_cnt <= 2'h 3;
==>
600 end else if (st == StMByte) begin
-3-
601 mbyte_cnt <= mbyte_cnt - 1'b 1;
==>
602 end
MISSING_ELSE
==>
Branches:
-1- | -2- | -3- | Status | Tests |
1 |
- |
- |
Covered |
T1,T2,T3 |
0 |
1 |
- |
Not Covered |
|
0 |
0 |
1 |
Not Covered |
|
0 |
0 |
0 |
Covered |
T13,T14,T15 |
613 if (!rst_out_ni) passthrough_s_en <= 4'h 1; // S[0] active by default
-1-
==>
614 else passthrough_s_en <= device_s_en_inclk;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
693 unique case (cmd_info.read_pipeline_mode)
-1-
694 RdPipeTwoStageFullCycle: begin
695 host_s_o = read_pipeline_stg2_q;
==>
696 read_pipeline_stg1_d = passthrough_i.s;
697 host_s_en_muxed = read_pipeline_oe_stg2_q;
698 end
699 RdPipeTwoStageHalfCycle: begin
700 host_s_o = read_pipeline_stg2_q;
==>
701 read_pipeline_stg1_d = half_cycle_sampled_sd;
702 host_s_en_muxed = read_pipeline_oe_stg2_q;
703 end
704 default: begin
705 host_s_o = passthrough_i.s;
==>
Branches:
-1- | Status | Tests |
RdPipeTwoStageFullCycle |
Covered |
T16,T21,T57 |
RdPipeTwoStageHalfCycle |
Covered |
T17,T24,T57 |
default |
Covered |
T1,T2,T3 |
713 if (!rst_out_ni) host_s_en_o <= '0; // input mode
-1-
==>
714 else host_s_en_o <= host_s_en_muxed;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
745 if (!rst_ni) begin
-1-
746 st <= StIdle;
==>
747 end else begin
748 st <= st_d;
==>
Branches:
-1- | Status | Tests |
1 |
Covered |
T1,T2,T3 |
0 |
Covered |
T13,T14,T15 |
778 unique case (st)
-1-
779 StIdle: begin
780 if (!is_active) begin
-2-
781 st_d = StIdle;
==>
782 end else if (cmd_8th && cmd_filter[host_s_i[0]]) begin
-3-
783 st_d = StFilter;
==>
784 filter = 1'b 1;
785
786 // Send notification event to SW
787 end else if (cmd_8th && cmd_info_d.valid) begin
-4-
788 cmd_info_latch = 1'b 1;
789
790 // Divert to multiple states.
791 //
792 // The following states are mainly for controlling the output enable
793 // signals. StAddress state, however, controls the SPI lines for
794 // address swap in case of Read Commands.
795 //
796 // Order: addr_mode , dummy_en, |payload_en
797 // Note that no direct transition to MByte state.
798 if (cmd_info_d.addr_mode != AddrDisabled) begin
-5-
799 st_d = StAddress;
==>
800
801 addr_set_d = 1'b 1;
802 end else if (cmd_info_d.dummy_en) begin
-6-
803 st_d = StHighZ;
==>
804
805 dummy_set = 1'b 1;
806 dummycnt_d = cmd_info_d.dummy_size;
807 end else if (cmd_info_d.payload_en != 0) begin
-7-
808 // Any input/output payload
809 if (cmd_info_d.payload_dir == PayloadOut) begin
-8-
810 st_d = StWait;
==>
811 end else begin
812 st_d = StDriving;
==>
813
814 payload_replace_set = 1'b 1;
815 end
816 end
MISSING_ELSE
==>
817 end // cmd_8th && cmd_info_d.valid
818 else if (cmd_8th) begin
-9-
819 // cmd_info_d.valid is 0. Skip current transaction
820 st_d = StFilter;
==>
821 filter = 1'b 1;
822 end
MISSING_ELSE
==>
823 end
824
825 StMByte: begin
826 if (mbytecnt_zero) begin
-10-
827 st_d = StHighZ;
==>
828
829 dummy_set = 1'b 1;
830 dummycnt_d = cmd_info_d.dummy_size;
831 end else begin
832 st_d = StMByte;
==>
833 end
834 end
835
836 StFilter: begin
837 // Command is filtered. Wait until reset(CSb) comes.
838 st_d = StFilter;
==>
839 host_s_en_inclk = 4'h 0; // explicit
840 device_s_en_inclk = 4'h 0;
841 end
842
843 StWait: begin
844 // Device Returns Data to host
845 st_d = StWait;
==>
846
847 // output enable for host
848 host_s_en_inclk = cmd_info.payload_en;
849 device_s_en_inclk = 4'h 0;
850 end
851
852 StDriving: begin
853 // Host sends Data to device
854 st_d = StDriving;
==>
855
856 // Output enable for device
857 host_s_en_inclk = 4'h 0; // explicit
858 device_s_en_inclk = cmd_info.payload_en;
859 end
860
861 StHighZ: begin
862 host_s_en_inclk = 4'h 0; // explicit
863 device_s_en_inclk = 4'h 0; // float
864 if (dummycnt_zero && (cmd_info.payload_dir == PayloadOut)) begin
-11-
865 // Assume payload_en not 0
866 st_d = StWait;
==>
867 end else if (dummycnt_zero && (cmd_info.payload_dir == PayloadIn)) begin
-12-
868 st_d = StDriving;
==>
869
870 payload_replace_set = 1'b 1;
871 end
MISSING_ELSE
==>
872 end
873
874 StAddress: begin
875 // based on state, addr_phase is set. So just check if counter reaches 0
876 if (addrcnt_outclk == '0) begin
-13-
877 if (cmd_info.mbyte_en) begin
-14-
878 st_d = StMByte;
==>
879
880 mbyte_set = 1'b 1;
881 end else if (cmd_info.dummy_en) begin
-15-
882 st_d = StHighZ;
==>
883
884 dummy_set = 1'b 1;
885 dummycnt_d = cmd_info.dummy_size;
886 end else if (cmd_info.payload_en != 0
-16-
887 && (cmd_info.payload_dir == PayloadOut)) begin
888 st_d = StWait;
==>
889 end else if (cmd_info.payload_en != 0
-17-
890 && (cmd_info.payload_dir == PayloadIn)) begin
891 st_d = StDriving;
==>
892
893 payload_replace_set = 1'b 1;
894 end else begin
895 // Addr completed command. goto wait state
896 st_d = StWait;
==>
897 end
898 end
MISSING_ELSE
==>
899 end
900
901 default: begin
902 st_d = StIdle;
==>
Branches:
-1- | -2- | -3- | -4- | -5- | -6- | -7- | -8- | -9- | -10- | -11- | -12- | -13- | -14- | -15- | -16- | -17- | Status | Tests |
StIdle |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T1,T2,T3 |
StIdle |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StIdle |
0 |
0 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StIdle |
0 |
0 |
1 |
0 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T23,T60,T61 |
StIdle |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T23 |
StIdle |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T17,T22,T62 |
StIdle |
0 |
0 |
1 |
0 |
0 |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T24,T66,T67 |
StIdle |
0 |
0 |
0 |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T17,T21 |
StIdle |
0 |
0 |
0 |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StMByte |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
StMByte |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
StFilter |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StWait |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StDriving |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Covered |
T17,T22,T24 |
StHighZ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
- |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StHighZ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
1 |
- |
- |
- |
- |
- |
Not Covered |
|
StHighZ |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
0 |
- |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
1 |
- |
- |
- |
Not Covered |
|
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
1 |
- |
- |
Covered |
T15,T16,T17 |
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
0 |
1 |
- |
Covered |
T17,T21,T63 |
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
0 |
0 |
1 |
Covered |
T24,T61,T52 |
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
1 |
0 |
0 |
0 |
0 |
Covered |
T15,T17,T56 |
StAddress |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
0 |
- |
- |
- |
- |
Covered |
T15,T16,T17 |
default |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
Not Covered |
|
Assert Coverage for Module :
spi_passthrough
Assertion Details
PassThroughStKnown_A
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
140189703 |
110429241 |
0 |
0 |
T13 |
1362 |
1362 |
0 |
0 |
T14 |
12966 |
12966 |
0 |
0 |
T15 |
56310 |
55596 |
0 |
0 |
T16 |
29086 |
29086 |
0 |
0 |
T17 |
45084 |
44664 |
0 |
0 |
T19 |
16479 |
16479 |
0 |
0 |
T21 |
33897 |
33664 |
0 |
0 |
T22 |
38186 |
37584 |
0 |
0 |
T23 |
24346 |
24204 |
0 |
0 |
T24 |
0 |
41932 |
0 |
0 |
T27 |
360 |
0 |
0 |
0 |
PayloadSwapConstraint_M
Name | Attempts | Real Successes | Failures | Incomplete |
Total |
140189703 |
1996464 |
0 |
0 |
T51 |
561048 |
2048 |
0 |
0 |
T52 |
304380 |
37832 |
0 |
0 |
T53 |
139403 |
0 |
0 |
0 |
T54 |
614678 |
0 |
0 |
0 |
T61 |
15023 |
2080 |
0 |
0 |
T68 |
0 |
40976 |
0 |
0 |
T69 |
0 |
32 |
0 |
0 |
T70 |
0 |
18432 |
0 |
0 |
T71 |
0 |
12528 |
0 |
0 |
T72 |
0 |
21048 |
0 |
0 |
T73 |
0 |
14448 |
0 |
0 |
T74 |
0 |
2072 |
0 |
0 |
T75 |
37116 |
0 |
0 |
0 |
T76 |
87858 |
0 |
0 |
0 |
T77 |
32 |
0 |
0 |
0 |
T78 |
32832 |
0 |
0 |
0 |
T79 |
75200 |
0 |
0 |
0 |