@@ -416,6 +416,225 @@ module ibex_top #(
416
416
417
417
// Redundant lockstep core implementation
418
418
if (Lockstep) begin : gen_lockstep
419
+ // Note: certain synthesis tools like DC are very smart at optimizing away redundant logic.
420
+ // Hence, we have to insert an optimization barrier at the IOs of the lockstep Ibex.
421
+ // This is achieved by manually buffering each bit using prim_buf.
422
+ // Our Xilinx and DC synthesis flows make sure that these buffers cannot be optimized away
423
+ // using keep attributes (Vivado) and size_only constraints (DC).
424
+
425
+ localparam int NumBufferBits = $bits ({
426
+ hart_id_i,
427
+ boot_addr_i,
428
+ instr_req_o,
429
+ instr_gnt_i,
430
+ instr_rvalid_i,
431
+ instr_addr_o,
432
+ instr_rdata_i,
433
+ instr_err_i,
434
+ data_req_o,
435
+ data_gnt_i,
436
+ data_rvalid_i,
437
+ data_we_o,
438
+ data_be_o,
439
+ data_addr_o,
440
+ data_wdata_o,
441
+ data_rdata_i,
442
+ data_err_i,
443
+ dummy_instr_id,
444
+ rf_raddr_a,
445
+ rf_raddr_b,
446
+ rf_waddr_wb,
447
+ rf_we_wb,
448
+ rf_wdata_wb_ecc,
449
+ rf_rdata_a_ecc,
450
+ rf_rdata_b_ecc,
451
+ ic_tag_req,
452
+ ic_tag_write,
453
+ ic_tag_addr,
454
+ ic_tag_wdata,
455
+ ic_data_req,
456
+ ic_data_write,
457
+ ic_data_addr,
458
+ ic_data_wdata,
459
+ irq_software_i,
460
+ irq_timer_i,
461
+ irq_external_i,
462
+ irq_fast_i,
463
+ irq_nm_i,
464
+ irq_pending,
465
+ debug_req_i,
466
+ crash_dump_o,
467
+ core_busy_d
468
+ } );
469
+
470
+ logic [NumBufferBits- 1 : 0 ] buf_in, buf_out;
471
+
472
+ logic [31 : 0 ] hart_id_local;
473
+ logic [31 : 0 ] boot_addr_local;
474
+
475
+ logic instr_req_local;
476
+ logic instr_gnt_local;
477
+ logic instr_rvalid_local;
478
+ logic [31 : 0 ] instr_addr_local;
479
+ logic [31 : 0 ] instr_rdata_local;
480
+ logic instr_err_local;
481
+
482
+ logic data_req_local;
483
+ logic data_gnt_local;
484
+ logic data_rvalid_local;
485
+ logic data_we_local;
486
+ logic [3 : 0 ] data_be_local;
487
+ logic [31 : 0 ] data_addr_local;
488
+ logic [31 : 0 ] data_wdata_local;
489
+ logic [31 : 0 ] data_rdata_local;
490
+ logic data_err_local;
491
+
492
+ logic dummy_instr_id_local;
493
+ logic [4 : 0 ] rf_raddr_a_local;
494
+ logic [4 : 0 ] rf_raddr_b_local;
495
+ logic [4 : 0 ] rf_waddr_wb_local;
496
+ logic rf_we_wb_local;
497
+ logic [RegFileDataWidth- 1 : 0 ] rf_wdata_wb_ecc_local;
498
+ logic [RegFileDataWidth- 1 : 0 ] rf_rdata_a_ecc_local;
499
+ logic [RegFileDataWidth- 1 : 0 ] rf_rdata_b_ecc_local;
500
+
501
+ logic [IC_NUM_WAYS - 1 : 0 ] ic_tag_req_local;
502
+ logic ic_tag_write_local;
503
+ logic [IC_INDEX_W - 1 : 0 ] ic_tag_addr_local;
504
+ logic [TagSizeECC- 1 : 0 ] ic_tag_wdata_local;
505
+ logic [IC_NUM_WAYS - 1 : 0 ] ic_data_req_local;
506
+ logic ic_data_write_local;
507
+ logic [IC_INDEX_W - 1 : 0 ] ic_data_addr_local;
508
+ logic [LineSizeECC- 1 : 0 ] ic_data_wdata_local;
509
+
510
+ logic irq_software_local;
511
+ logic irq_timer_local;
512
+ logic irq_external_local;
513
+ logic [14 : 0 ] irq_fast_local;
514
+ logic irq_nm_local;
515
+ logic irq_pending_local;
516
+
517
+ logic debug_req_local;
518
+ crash_dump_t crash_dump_local;
519
+
520
+ logic core_busy_local;
521
+
522
+ assign buf_in = {
523
+ hart_id_i,
524
+ boot_addr_i,
525
+ instr_req_o,
526
+ instr_gnt_i,
527
+ instr_rvalid_i,
528
+ instr_addr_o,
529
+ instr_rdata_i,
530
+ instr_err_i,
531
+ data_req_o,
532
+ data_gnt_i,
533
+ data_rvalid_i,
534
+ data_we_o,
535
+ data_be_o,
536
+ data_addr_o,
537
+ data_wdata_o,
538
+ data_rdata_i,
539
+ data_err_i,
540
+ dummy_instr_id,
541
+ rf_raddr_a,
542
+ rf_raddr_b,
543
+ rf_waddr_wb,
544
+ rf_we_wb,
545
+ rf_wdata_wb_ecc,
546
+ rf_rdata_a_ecc,
547
+ rf_rdata_b_ecc,
548
+ ic_tag_req,
549
+ ic_tag_write,
550
+ ic_tag_addr,
551
+ ic_tag_wdata,
552
+ ic_data_req,
553
+ ic_data_write,
554
+ ic_data_addr,
555
+ ic_data_wdata,
556
+ irq_software_i,
557
+ irq_timer_i,
558
+ irq_external_i,
559
+ irq_fast_i,
560
+ irq_nm_i,
561
+ irq_pending,
562
+ debug_req_i,
563
+ crash_dump_o,
564
+ core_busy_d
565
+ } ;
566
+
567
+ assign {
568
+ hart_id_local,
569
+ boot_addr_local,
570
+ instr_req_local,
571
+ instr_gnt_local,
572
+ instr_rvalid_local,
573
+ instr_addr_local,
574
+ instr_rdata_local,
575
+ instr_err_local,
576
+ data_req_local,
577
+ data_gnt_local,
578
+ data_rvalid_local,
579
+ data_we_local,
580
+ data_be_local,
581
+ data_addr_local,
582
+ data_wdata_local,
583
+ data_rdata_local,
584
+ data_err_local,
585
+ dummy_instr_id_local,
586
+ rf_raddr_a_local,
587
+ rf_raddr_b_local,
588
+ rf_waddr_wb_local,
589
+ rf_we_wb_local,
590
+ rf_wdata_wb_ecc_local,
591
+ rf_rdata_a_ecc_local,
592
+ rf_rdata_b_ecc_local,
593
+ ic_tag_req_local,
594
+ ic_tag_write_local,
595
+ ic_tag_addr_local,
596
+ ic_tag_wdata_local,
597
+ ic_data_req_local,
598
+ ic_data_write_local,
599
+ ic_data_addr_local,
600
+ ic_data_wdata_local,
601
+ irq_software_local,
602
+ irq_timer_local,
603
+ irq_external_local,
604
+ irq_fast_local,
605
+ irq_nm_local,
606
+ irq_pending_local,
607
+ debug_req_local,
608
+ crash_dump_local,
609
+ core_busy_local
610
+ } = buf_out;
611
+
612
+ // Manually buffer all input signals.
613
+ for (genvar k = 0 ; k < NumBufferBits; k++ ) begin : gen_buffers
614
+ prim_buf u_prim_buf (
615
+ .in_i (buf_in[k]),
616
+ .out_o (buf_out[k])
617
+ );
618
+ end
619
+
620
+ logic [TagSizeECC- 1 : 0 ] ic_tag_rdata_local [IC_NUM_WAYS ];
621
+ logic [LineSizeECC- 1 : 0 ] ic_data_rdata_local [IC_NUM_WAYS ];
622
+ for (genvar k = 0 ; k < IC_NUM_WAYS ; k++ ) begin : gen_ways
623
+ for (genvar j = 0 ; j < TagSizeECC; j++ ) begin : gen_tag_bufs
624
+ prim_buf u_prim_buf (
625
+ .in_i (ic_tag_rdata[k][j]),
626
+ .out_o (ic_tag_rdata_local[k][j])
627
+ );
628
+ end
629
+ for (genvar j = 0 ; j < TagSizeECC; j++ ) begin : gen_data_bufs
630
+ prim_buf u_prim_buf (
631
+ .in_i (ic_data_rdata[k][j]),
632
+ .out_o (ic_data_rdata_local[k][j])
633
+ );
634
+ end
635
+ end
636
+
637
+ logic lockstep_alert_minor_local, lockstep_alert_major_local;
419
638
ibex_lockstep # (
420
639
.PMPEnable ( PMPEnable ),
421
640
.PMPGranularity ( PMPGranularity ),
@@ -445,60 +664,72 @@ module ibex_top #(
445
664
.clk_i (clk),
446
665
.rst_ni (rst_ni),
447
666
448
- .hart_id_i (hart_id_i ),
449
- .boot_addr_i (boot_addr_i ),
450
-
451
- .instr_req_i (instr_req_o ),
452
- .instr_gnt_i (instr_gnt_i ),
453
- .instr_rvalid_i (instr_rvalid_i ),
454
- .instr_addr_i (instr_addr_o ),
455
- .instr_rdata_i (instr_rdata_i ),
456
- .instr_err_i (instr_err_i ),
457
-
458
- .data_req_i (data_req_o ),
459
- .data_gnt_i (data_gnt_i ),
460
- .data_rvalid_i (data_rvalid_i ),
461
- .data_we_i (data_we_o ),
462
- .data_be_i (data_be_o ),
463
- .data_addr_i (data_addr_o ),
464
- .data_wdata_i (data_wdata_o ),
465
- .data_rdata_i (data_rdata_i ),
466
- .data_err_i (data_err_i ),
467
-
468
- .dummy_instr_id_i (dummy_instr_id ),
469
- .rf_raddr_a_i (rf_raddr_a ),
470
- .rf_raddr_b_i (rf_raddr_b ),
471
- .rf_waddr_wb_i (rf_waddr_wb ),
472
- .rf_we_wb_i (rf_we_wb ),
473
- .rf_wdata_wb_ecc_i (rf_wdata_wb_ecc ),
474
- .rf_rdata_a_ecc_i (rf_rdata_a_ecc ),
475
- .rf_rdata_b_ecc_i (rf_rdata_b_ecc ),
476
-
477
- .ic_tag_req_i (ic_tag_req ),
478
- .ic_tag_write_i (ic_tag_write ),
479
- .ic_tag_addr_i (ic_tag_addr ),
480
- .ic_tag_wdata_i (ic_tag_wdata ),
481
- .ic_tag_rdata_i (ic_tag_rdata ),
482
- .ic_data_req_i (ic_data_req ),
483
- .ic_data_write_i (ic_data_write ),
484
- .ic_data_addr_i (ic_data_addr ),
485
- .ic_data_wdata_i (ic_data_wdata ),
486
- .ic_data_rdata_i (ic_data_rdata ),
487
-
488
- .irq_software_i (irq_software_i ),
489
- .irq_timer_i (irq_timer_i ),
490
- .irq_external_i (irq_external_i ),
491
- .irq_fast_i (irq_fast_i ),
492
- .irq_nm_i (irq_nm_i ),
493
- .irq_pending_i (irq_pending ),
494
-
495
- .debug_req_i (debug_req_i ),
496
- .crash_dump_i (crash_dump_o ),
497
-
498
- .alert_minor_o (lockstep_alert_minor ),
499
- .alert_major_o (lockstep_alert_major ),
500
- .core_busy_i (core_busy_d )
667
+ .hart_id_i (hart_id_local ),
668
+ .boot_addr_i (boot_addr_local ),
669
+
670
+ .instr_req_i (instr_req_local ),
671
+ .instr_gnt_i (instr_gnt_local ),
672
+ .instr_rvalid_i (instr_rvalid_local ),
673
+ .instr_addr_i (instr_addr_local ),
674
+ .instr_rdata_i (instr_rdata_local ),
675
+ .instr_err_i (instr_err_local ),
676
+
677
+ .data_req_i (data_req_local ),
678
+ .data_gnt_i (data_gnt_local ),
679
+ .data_rvalid_i (data_rvalid_local ),
680
+ .data_we_i (data_we_local ),
681
+ .data_be_i (data_be_local ),
682
+ .data_addr_i (data_addr_local ),
683
+ .data_wdata_i (data_wdata_local ),
684
+ .data_rdata_i (data_rdata_local ),
685
+ .data_err_i (data_err_local ),
686
+
687
+ .dummy_instr_id_i (dummy_instr_id_local ),
688
+ .rf_raddr_a_i (rf_raddr_a_local ),
689
+ .rf_raddr_b_i (rf_raddr_b_local ),
690
+ .rf_waddr_wb_i (rf_waddr_wb_local ),
691
+ .rf_we_wb_i (rf_we_wb_local ),
692
+ .rf_wdata_wb_ecc_i (rf_wdata_wb_ecc_local ),
693
+ .rf_rdata_a_ecc_i (rf_rdata_a_ecc_local ),
694
+ .rf_rdata_b_ecc_i (rf_rdata_b_ecc_local ),
695
+
696
+ .ic_tag_req_i (ic_tag_req_local ),
697
+ .ic_tag_write_i (ic_tag_write_local ),
698
+ .ic_tag_addr_i (ic_tag_addr_local ),
699
+ .ic_tag_wdata_i (ic_tag_wdata_local ),
700
+ .ic_tag_rdata_i (ic_tag_rdata_local ),
701
+ .ic_data_req_i (ic_data_req_local ),
702
+ .ic_data_write_i (ic_data_write_local ),
703
+ .ic_data_addr_i (ic_data_addr_local ),
704
+ .ic_data_wdata_i (ic_data_wdata_local ),
705
+ .ic_data_rdata_i (ic_data_rdata_local ),
706
+
707
+ .irq_software_i (irq_software_local ),
708
+ .irq_timer_i (irq_timer_local ),
709
+ .irq_external_i (irq_external_local ),
710
+ .irq_fast_i (irq_fast_local ),
711
+ .irq_nm_i (irq_nm_local ),
712
+ .irq_pending_i (irq_pending_local ),
713
+
714
+ .debug_req_i (debug_req_local ),
715
+ .crash_dump_i (crash_dump_local ),
716
+
717
+ .alert_minor_o (lockstep_alert_minor_local ),
718
+ .alert_major_o (lockstep_alert_major_local ),
719
+ .core_busy_i (core_busy_local )
501
720
);
721
+
722
+ // Manually buffer the output signals.
723
+ prim_buf u_prim_buf_alert_minor (
724
+ .in_i (lockstep_alert_minor_local),
725
+ .out_o (lockstep_alert_minor)
726
+ );
727
+
728
+ prim_buf u_prim_buf_alert_major (
729
+ .in_i (lockstep_alert_major_local),
730
+ .out_o (lockstep_alert_major)
731
+ );
732
+
502
733
end else begin : gen_no_lockstep
503
734
assign lockstep_alert_major = 1'b0 ;
504
735
assign lockstep_alert_minor = 1'b0 ;
0 commit comments