2 `define SB_DFF_REG reg Q = 0
3 // `define SB_DFF_REG reg Q
5 `define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif
6 `define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif
7 `define ABC_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc_arrival=TIME *) `endif
9 // SiliconBlue IO Cells
13 input LATCH_INPUT_VALUE,
23 parameter [5:0] PIN_TYPE = 6'b000000;
24 parameter [0:0] PULLUP = 1'b0;
25 parameter [0:0] NEG_TRIGGER = 1'b0;
26 parameter IO_STANDARD = "SB_LVCMOS";
29 reg dout, din_0, din_1;
31 reg dout_q_0, dout_q_1;
34 // IO tile generates a constant 1'b1 internally if global_cen is not connected
35 wire clken_pulled = CLOCK_ENABLE || CLOCK_ENABLE === 1'bz;
39 generate if (!NEG_TRIGGER) begin
40 always @(posedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
41 always @(posedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
42 always @(negedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
43 always @(posedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
44 always @(posedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
45 always @(negedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
46 always @(posedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
48 always @(negedge INPUT_CLK) clken_pulled_ri <= clken_pulled;
49 always @(negedge INPUT_CLK) if (clken_pulled) din_q_0 <= PACKAGE_PIN;
50 always @(posedge INPUT_CLK) if (clken_pulled_ri) din_q_1 <= PACKAGE_PIN;
51 always @(negedge OUTPUT_CLK) clken_pulled_ro <= clken_pulled;
52 always @(negedge OUTPUT_CLK) if (clken_pulled) dout_q_0 <= D_OUT_0;
53 always @(posedge OUTPUT_CLK) if (clken_pulled_ro) dout_q_1 <= D_OUT_1;
54 always @(negedge OUTPUT_CLK) if (clken_pulled) outena_q <= OUTPUT_ENABLE;
58 if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
59 din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
63 // work around simulation glitches on dout in DDR mode
66 always @* outclk_delayed_1 <= OUTPUT_CLK;
67 always @* outclk_delayed_2 <= outclk_delayed_1;
71 dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
73 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
76 assign D_IN_0 = din_0, D_IN_1 = din_1;
79 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
80 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
81 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
88 output GLOBAL_BUFFER_OUTPUT,
89 input LATCH_INPUT_VALUE,
99 parameter [5:0] PIN_TYPE = 6'b000000;
100 parameter [0:0] PULLUP = 1'b0;
101 parameter [0:0] NEG_TRIGGER = 1'b0;
102 parameter IO_STANDARD = "SB_LVCMOS";
104 assign GLOBAL_BUFFER_OUTPUT = PACKAGE_PIN;
109 .NEG_TRIGGER(NEG_TRIGGER),
110 .IO_STANDARD(IO_STANDARD)
112 .PACKAGE_PIN(PACKAGE_PIN),
113 .LATCH_INPUT_VALUE(LATCH_INPUT_VALUE),
114 .CLOCK_ENABLE(CLOCK_ENABLE),
115 .INPUT_CLK(INPUT_CLK),
116 .OUTPUT_CLK(OUTPUT_CLK),
117 .OUTPUT_ENABLE(OUTPUT_ENABLE),
126 input USER_SIGNAL_TO_GLOBAL_BUFFER,
127 output GLOBAL_BUFFER_OUTPUT
129 assign GLOBAL_BUFFER_OUTPUT = USER_SIGNAL_TO_GLOBAL_BUFFER;
132 // SiliconBlue Logic Cells
135 module SB_LUT4 (output O, input I0, I1, I2, I3);
136 parameter [15:0] LUT_INIT = 0;
137 wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
138 wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0];
139 wire [1:0] s1 = I1 ? s2[ 3:2] : s2[1:0];
140 assign O = I0 ? s1[1] : s1[0];
144 module SB_CARRY (output CO, input I0, I1, CI);
145 assign CO = (I0 && I1) || ((I0 || I1) && CI);
148 (* abc_box_id = 1, lib_whitebox *)
149 module \$__ICE40_CARRY_WRAPPER (
176 // Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
177 // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
178 // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
180 // Positive Edge SiliconBlue FF Cells
226 always @(posedge C, posedge R)
254 always @(posedge C, posedge S)
284 always @(posedge C, posedge R)
314 always @(posedge C, posedge S)
321 // Negative Edge SiliconBlue FF Cells
367 always @(negedge C, posedge R)
395 always @(negedge C, posedge S)
425 always @(negedge C, posedge R)
455 always @(negedge C, posedge S)
462 // SiliconBlue RAM Cells
465 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
466 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
467 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
469 input RCLK, RCLKE, RE,
471 input WCLK, WCLKE, WE,
473 input [15:0] MASK, WDATA
479 parameter WRITE_MODE = 0;
480 parameter READ_MODE = 0;
482 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
483 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
484 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
485 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
486 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
487 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
488 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
489 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
490 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
491 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
492 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
493 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
494 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
495 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
496 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
497 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
499 parameter INIT_FILE = "";
510 0: assign WMASK_I = MASK;
512 1: assign WMASK_I = WADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
513 WADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
515 2: assign WMASK_I = WADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
516 WADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
517 WADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
518 WADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
520 3: assign WMASK_I = WADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
521 WADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
522 WADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
523 WADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
524 WADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
525 WADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
526 WADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
527 WADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
531 0: assign RMASK_I = 16'b 0000_0000_0000_0000;
533 1: assign RMASK_I = RADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
534 RADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
536 2: assign RMASK_I = RADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
537 RADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
538 RADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
539 RADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
541 3: assign RMASK_I = RADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
542 RADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
543 RADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
544 RADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
545 RADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
546 RADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
547 RADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
548 RADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
552 0: assign WDATA_I = WDATA;
554 1: assign WDATA_I = {WDATA[14], WDATA[14], WDATA[12], WDATA[12],
555 WDATA[10], WDATA[10], WDATA[ 8], WDATA[ 8],
556 WDATA[ 6], WDATA[ 6], WDATA[ 4], WDATA[ 4],
557 WDATA[ 2], WDATA[ 2], WDATA[ 0], WDATA[ 0]};
559 2: assign WDATA_I = {WDATA[13], WDATA[13], WDATA[13], WDATA[13],
560 WDATA[ 9], WDATA[ 9], WDATA[ 9], WDATA[ 9],
561 WDATA[ 5], WDATA[ 5], WDATA[ 5], WDATA[ 5],
562 WDATA[ 1], WDATA[ 1], WDATA[ 1], WDATA[ 1]};
564 3: assign WDATA_I = {WDATA[11], WDATA[11], WDATA[11], WDATA[11],
565 WDATA[11], WDATA[11], WDATA[11], WDATA[11],
566 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3],
567 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3]};
571 0: assign RDATA = RDATA_I;
572 1: assign RDATA = {1'b0, |RDATA_I[15:14], 1'b0, |RDATA_I[13:12], 1'b0, |RDATA_I[11:10], 1'b0, |RDATA_I[ 9: 8],
573 1'b0, |RDATA_I[ 7: 6], 1'b0, |RDATA_I[ 5: 4], 1'b0, |RDATA_I[ 3: 2], 1'b0, |RDATA_I[ 1: 0]};
574 2: assign RDATA = {2'b0, |RDATA_I[15:12], 3'b0, |RDATA_I[11: 8], 3'b0, |RDATA_I[ 7: 4], 3'b0, |RDATA_I[ 3: 0], 1'b0};
575 3: assign RDATA = {4'b0, |RDATA_I[15: 8], 7'b0, |RDATA_I[ 7: 0], 3'b0};
580 reg [15:0] memory [0:255];
584 $readmemh(INIT_FILE, memory);
586 for (i=0; i<16; i=i+1) begin
587 memory[ 0*16 + i] = INIT_0[16*i +: 16];
588 memory[ 1*16 + i] = INIT_1[16*i +: 16];
589 memory[ 2*16 + i] = INIT_2[16*i +: 16];
590 memory[ 3*16 + i] = INIT_3[16*i +: 16];
591 memory[ 4*16 + i] = INIT_4[16*i +: 16];
592 memory[ 5*16 + i] = INIT_5[16*i +: 16];
593 memory[ 6*16 + i] = INIT_6[16*i +: 16];
594 memory[ 7*16 + i] = INIT_7[16*i +: 16];
595 memory[ 8*16 + i] = INIT_8[16*i +: 16];
596 memory[ 9*16 + i] = INIT_9[16*i +: 16];
597 memory[10*16 + i] = INIT_A[16*i +: 16];
598 memory[11*16 + i] = INIT_B[16*i +: 16];
599 memory[12*16 + i] = INIT_C[16*i +: 16];
600 memory[13*16 + i] = INIT_D[16*i +: 16];
601 memory[14*16 + i] = INIT_E[16*i +: 16];
602 memory[15*16 + i] = INIT_F[16*i +: 16];
606 always @(posedge WCLK) begin
607 if (WE && WCLKE) begin
608 if (!WMASK_I[ 0]) memory[WADDR[7:0]][ 0] <= WDATA_I[ 0];
609 if (!WMASK_I[ 1]) memory[WADDR[7:0]][ 1] <= WDATA_I[ 1];
610 if (!WMASK_I[ 2]) memory[WADDR[7:0]][ 2] <= WDATA_I[ 2];
611 if (!WMASK_I[ 3]) memory[WADDR[7:0]][ 3] <= WDATA_I[ 3];
612 if (!WMASK_I[ 4]) memory[WADDR[7:0]][ 4] <= WDATA_I[ 4];
613 if (!WMASK_I[ 5]) memory[WADDR[7:0]][ 5] <= WDATA_I[ 5];
614 if (!WMASK_I[ 6]) memory[WADDR[7:0]][ 6] <= WDATA_I[ 6];
615 if (!WMASK_I[ 7]) memory[WADDR[7:0]][ 7] <= WDATA_I[ 7];
616 if (!WMASK_I[ 8]) memory[WADDR[7:0]][ 8] <= WDATA_I[ 8];
617 if (!WMASK_I[ 9]) memory[WADDR[7:0]][ 9] <= WDATA_I[ 9];
618 if (!WMASK_I[10]) memory[WADDR[7:0]][10] <= WDATA_I[10];
619 if (!WMASK_I[11]) memory[WADDR[7:0]][11] <= WDATA_I[11];
620 if (!WMASK_I[12]) memory[WADDR[7:0]][12] <= WDATA_I[12];
621 if (!WMASK_I[13]) memory[WADDR[7:0]][13] <= WDATA_I[13];
622 if (!WMASK_I[14]) memory[WADDR[7:0]][14] <= WDATA_I[14];
623 if (!WMASK_I[15]) memory[WADDR[7:0]][15] <= WDATA_I[15];
627 always @(posedge RCLK) begin
628 if (RE && RCLKE) begin
629 RDATA_I <= memory[RADDR[7:0]] & ~RMASK_I;
635 module SB_RAM40_4KNR (
636 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
637 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
638 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
640 input RCLKN, RCLKE, RE,
642 input WCLK, WCLKE, WE,
644 input [15:0] MASK, WDATA
646 parameter WRITE_MODE = 0;
647 parameter READ_MODE = 0;
649 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
650 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
651 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
652 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
653 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
654 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
655 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
656 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
657 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
658 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
659 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
660 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
661 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
662 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
663 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
664 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
666 parameter INIT_FILE = "";
669 .WRITE_MODE(WRITE_MODE),
670 .READ_MODE (READ_MODE ),
687 .INIT_FILE (INIT_FILE )
703 module SB_RAM40_4KNW (
704 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
705 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
706 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
708 input RCLK, RCLKE, RE,
710 input WCLKN, WCLKE, WE,
712 input [15:0] MASK, WDATA
714 parameter WRITE_MODE = 0;
715 parameter READ_MODE = 0;
717 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
718 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
719 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
720 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
721 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
722 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
723 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
724 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
725 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
726 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
727 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
728 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
729 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
730 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
731 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
732 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
734 parameter INIT_FILE = "";
737 .WRITE_MODE(WRITE_MODE),
738 .READ_MODE (READ_MODE ),
755 .INIT_FILE (INIT_FILE )
771 module SB_RAM40_4KNRNW (
772 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
773 `ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
774 `ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
776 input RCLKN, RCLKE, RE,
778 input WCLKN, WCLKE, WE,
780 input [15:0] MASK, WDATA
782 parameter WRITE_MODE = 0;
783 parameter READ_MODE = 0;
785 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
786 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
787 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
788 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
789 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
790 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
791 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
792 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
793 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
794 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
795 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
796 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
797 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
798 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
799 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
800 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
802 parameter INIT_FILE = "";
805 .WRITE_MODE(WRITE_MODE),
806 .READ_MODE (READ_MODE ),
823 .INIT_FILE (INIT_FILE )
839 // Packed IceStorm Logic Cells
842 input I0, I1, I2, I3, CIN, CLK, CEN, SR,
850 parameter [15:0] LUT_INIT = 0;
852 parameter [0:0] NEG_CLK = 0;
853 parameter [0:0] CARRY_ENABLE = 0;
854 parameter [0:0] DFF_ENABLE = 0;
855 parameter [0:0] SET_NORESET = 0;
856 parameter [0:0] ASYNC_SR = 0;
858 parameter [0:0] CIN_CONST = 0;
859 parameter [0:0] CIN_SET = 0;
861 wire mux_cin = CIN_CONST ? CIN_SET : CIN;
863 assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
865 wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
866 wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
867 wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
868 wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
873 assign polarized_clk = CLK ^ NEG_CLK;
876 always @(posedge polarized_clk)
878 o_reg <= SR ? SET_NORESET : lut_o;
881 always @(posedge polarized_clk, posedge SR)
883 o_reg <= SET_NORESET;
887 assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
890 // SiliconBlue PLL Cells
893 module SB_PLL40_CORE (
898 input [7:0] DYNAMICDELAY,
902 input LATCHINPUTVALUE,
907 parameter FEEDBACK_PATH = "SIMPLE";
908 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
909 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
910 parameter SHIFTREG_DIV_MODE = 1'b0;
911 parameter FDA_FEEDBACK = 4'b0000;
912 parameter FDA_RELATIVE = 4'b0000;
913 parameter PLLOUT_SELECT = "GENCLK";
914 parameter DIVR = 4'b0000;
915 parameter DIVF = 7'b0000000;
916 parameter DIVQ = 3'b000;
917 parameter FILTER_RANGE = 3'b000;
918 parameter ENABLE_ICEGATE = 1'b0;
919 parameter TEST_MODE = 1'b0;
920 parameter EXTERNAL_DIVIDE_FACTOR = 1;
924 module SB_PLL40_PAD (
929 input [7:0] DYNAMICDELAY,
933 input LATCHINPUTVALUE,
938 parameter FEEDBACK_PATH = "SIMPLE";
939 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
940 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
941 parameter SHIFTREG_DIV_MODE = 1'b0;
942 parameter FDA_FEEDBACK = 4'b0000;
943 parameter FDA_RELATIVE = 4'b0000;
944 parameter PLLOUT_SELECT = "GENCLK";
945 parameter DIVR = 4'b0000;
946 parameter DIVF = 7'b0000000;
947 parameter DIVQ = 3'b000;
948 parameter FILTER_RANGE = 3'b000;
949 parameter ENABLE_ICEGATE = 1'b0;
950 parameter TEST_MODE = 1'b0;
951 parameter EXTERNAL_DIVIDE_FACTOR = 1;
955 module SB_PLL40_2_PAD (
958 output PLLOUTGLOBALA,
960 output PLLOUTGLOBALB,
962 input [7:0] DYNAMICDELAY,
966 input LATCHINPUTVALUE,
971 parameter FEEDBACK_PATH = "SIMPLE";
972 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
973 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
974 parameter SHIFTREG_DIV_MODE = 1'b0;
975 parameter FDA_FEEDBACK = 4'b0000;
976 parameter FDA_RELATIVE = 4'b0000;
977 parameter PLLOUT_SELECT_PORTB = "GENCLK";
978 parameter DIVR = 4'b0000;
979 parameter DIVF = 7'b0000000;
980 parameter DIVQ = 3'b000;
981 parameter FILTER_RANGE = 3'b000;
982 parameter ENABLE_ICEGATE_PORTA = 1'b0;
983 parameter ENABLE_ICEGATE_PORTB = 1'b0;
984 parameter TEST_MODE = 1'b0;
985 parameter EXTERNAL_DIVIDE_FACTOR = 1;
989 module SB_PLL40_2F_CORE (
992 output PLLOUTGLOBALA,
994 output PLLOUTGLOBALB,
996 input [7:0] DYNAMICDELAY,
1000 input LATCHINPUTVALUE,
1005 parameter FEEDBACK_PATH = "SIMPLE";
1006 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
1007 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
1008 parameter SHIFTREG_DIV_MODE = 1'b0;
1009 parameter FDA_FEEDBACK = 4'b0000;
1010 parameter FDA_RELATIVE = 4'b0000;
1011 parameter PLLOUT_SELECT_PORTA = "GENCLK";
1012 parameter PLLOUT_SELECT_PORTB = "GENCLK";
1013 parameter DIVR = 4'b0000;
1014 parameter DIVF = 7'b0000000;
1015 parameter DIVQ = 3'b000;
1016 parameter FILTER_RANGE = 3'b000;
1017 parameter ENABLE_ICEGATE_PORTA = 1'b0;
1018 parameter ENABLE_ICEGATE_PORTB = 1'b0;
1019 parameter TEST_MODE = 1'b0;
1020 parameter EXTERNAL_DIVIDE_FACTOR = 1;
1024 module SB_PLL40_2F_PAD (
1027 output PLLOUTGLOBALA,
1029 output PLLOUTGLOBALB,
1031 input [7:0] DYNAMICDELAY,
1035 input LATCHINPUTVALUE,
1040 parameter FEEDBACK_PATH = "SIMPLE";
1041 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
1042 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
1043 parameter SHIFTREG_DIV_MODE = 2'b00;
1044 parameter FDA_FEEDBACK = 4'b0000;
1045 parameter FDA_RELATIVE = 4'b0000;
1046 parameter PLLOUT_SELECT_PORTA = "GENCLK";
1047 parameter PLLOUT_SELECT_PORTB = "GENCLK";
1048 parameter DIVR = 4'b0000;
1049 parameter DIVF = 7'b0000000;
1050 parameter DIVQ = 3'b000;
1051 parameter FILTER_RANGE = 3'b000;
1052 parameter ENABLE_ICEGATE_PORTA = 1'b0;
1053 parameter ENABLE_ICEGATE_PORTB = 1'b0;
1054 parameter TEST_MODE = 1'b0;
1055 parameter EXTERNAL_DIVIDE_FACTOR = 1;
1058 // SiliconBlue Device Configuration Cells
1060 (* blackbox, keep *)
1061 module SB_WARMBOOT (
1068 module SB_SPRAM256KA (
1069 input [13:0] ADDRESS,
1070 input [15:0] DATAIN,
1071 input [3:0] MASKWREN,
1072 input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
1073 output reg [15:0] DATAOUT
1077 reg [15:0] mem [0:16383];
1078 wire off = SLEEP || !POWEROFF;
1081 always @(negedge POWEROFF) begin
1082 for (i = 0; i <= 16383; i = i+1)
1086 always @(posedge CLOCK, posedge off) begin
1090 if (CHIPSELECT && !STANDBY && !WREN) begin
1091 DATAOUT <= mem[ADDRESS];
1093 if (CHIPSELECT && !STANDBY && WREN) begin
1094 if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
1095 if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
1096 if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
1097 if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
1122 parameter TRIM_EN = "0b0";
1123 parameter CLKHF_DIV = "0b00";
1145 parameter CURRENT_MODE = "0b0";
1146 parameter RGB0_CURRENT = "0b000000";
1147 parameter RGB1_CURRENT = "0b000000";
1148 parameter RGB2_CURRENT = "0b000000";
1152 module SB_LED_DRV_CUR(
1169 parameter CURRENT_MODE = "0b0";
1170 parameter RGB0_CURRENT = "0b000000";
1171 parameter RGB1_CURRENT = "0b000000";
1172 parameter RGB2_CURRENT = "0b000000";
1209 output SCLO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1214 parameter I2C_SLAVE_INIT_ADDR = "0b1111100001";
1215 parameter BUS_ADDR74 = "0b0001";
1258 output SCKO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1269 parameter BUS_ADDR74 = "0b0000";
1299 module SB_FILTER_50NS(
1307 input LATCH_INPUT_VALUE,
1311 input OUTPUT_ENABLE,
1319 parameter [5:0] PIN_TYPE = 6'b000000;
1320 parameter [0:0] PULLUP = 1'b0;
1321 parameter [0:0] WEAK_PULLUP = 1'b0;
1322 parameter [0:0] NEG_TRIGGER = 1'b0;
1323 parameter IO_STANDARD = "SB_LVCMOS";
1326 reg dout, din_0, din_1;
1327 reg din_q_0, din_q_1;
1328 reg dout_q_0, dout_q_1;
1331 generate if (!NEG_TRIGGER) begin
1332 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1333 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1334 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1335 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1336 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1338 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1339 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1340 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1341 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1342 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1346 if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
1347 din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
1351 // work around simulation glitches on dout in DDR mode
1352 reg outclk_delayed_1;
1353 reg outclk_delayed_2;
1354 always @* outclk_delayed_1 <= OUTPUT_CLK;
1355 always @* outclk_delayed_2 <= outclk_delayed_1;
1359 dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
1361 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1364 assign D_IN_0 = din_0, D_IN_1 = din_1;
1367 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
1368 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
1369 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
1376 input LATCHINPUTVALUE,
1386 parameter [5:0] PIN_TYPE = 6'b000000;
1387 parameter [0:0] NEG_TRIGGER = 1'b0;
1390 reg dout, din_0, din_1;
1391 reg din_q_0, din_q_1;
1392 reg dout_q_0, dout_q_1;
1395 generate if (!NEG_TRIGGER) begin
1396 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1397 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1398 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1399 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1400 always @(posedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1402 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1403 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1404 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1405 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1406 always @(negedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1410 if (!PIN_TYPE[1] || !LATCHINPUTVALUE)
1411 din_0 = PIN_TYPE[0] ? PACKAGEPIN : din_q_0;
1415 // work around simulation glitches on dout in DDR mode
1416 reg outclk_delayed_1;
1417 reg outclk_delayed_2;
1418 always @* outclk_delayed_1 <= OUTPUTCLK;
1419 always @* outclk_delayed_2 <= outclk_delayed_1;
1423 dout = PIN_TYPE[2] ? !dout_q_0 : DOUT0;
1425 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1428 assign DIN0 = din_0, DIN1 = din_1;
1431 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGEPIN = dout ? 1'bz : 1'b0;
1432 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGEPIN = OUTPUTENABLE ? (dout ? 1'bz : 1'b0) : 1'bz;
1433 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGEPIN = outena_q ? (dout ? 1'bz : 1'b0) : 1'bz;
1440 input [15:0] C, A, B, D,
1441 input AHOLD, BHOLD, CHOLD, DHOLD,
1442 input IRSTTOP, IRSTBOT,
1443 input ORSTTOP, ORSTBOT,
1444 input OLOADTOP, OLOADBOT,
1445 input ADDSUBTOP, ADDSUBBOT,
1446 input OHOLDTOP, OHOLDBOT,
1447 input CI, ACCUMCI, SIGNEXTIN,
1448 `ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L587
1450 output CO, ACCUMCO, SIGNEXTOUT
1452 parameter [0:0] NEG_TRIGGER = 0;
1453 parameter [0:0] C_REG = 0;
1454 parameter [0:0] A_REG = 0;
1455 parameter [0:0] B_REG = 0;
1456 parameter [0:0] D_REG = 0;
1457 parameter [0:0] TOP_8x8_MULT_REG = 0;
1458 parameter [0:0] BOT_8x8_MULT_REG = 0;
1459 parameter [0:0] PIPELINE_16x16_MULT_REG1 = 0;
1460 parameter [0:0] PIPELINE_16x16_MULT_REG2 = 0;
1461 parameter [1:0] TOPOUTPUT_SELECT = 0;
1462 parameter [1:0] TOPADDSUB_LOWERINPUT = 0;
1463 parameter [0:0] TOPADDSUB_UPPERINPUT = 0;
1464 parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
1465 parameter [1:0] BOTOUTPUT_SELECT = 0;
1466 parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
1467 parameter [0:0] BOTADDSUB_UPPERINPUT = 0;
1468 parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
1469 parameter [0:0] MODE_8x8 = 0;
1470 parameter [0:0] A_SIGNED = 0;
1471 parameter [0:0] B_SIGNED = 0;
1473 wire clock = CLK ^ NEG_TRIGGER;
1475 // internal wires, compare Figure on page 133 of ICE Technology Library 3.0 and Fig 2 on page 2 of Lattice TN1295-DSP
1476 // http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf
1477 // https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/AD/DSPFunctionUsageGuideforICE40Devices.ashx
1478 wire [15:0] iA, iB, iC, iD;
1479 wire [15:0] iF, iJ, iK, iG;
1481 wire [15:0] iW, iX, iP, iQ;
1482 wire [15:0] iY, iZ, iR, iS;
1487 always @(posedge clock, posedge IRSTTOP) begin
1491 end else if (CE) begin
1492 if (!CHOLD) rC <= C;
1493 if (!AHOLD) rA <= A;
1496 assign iC = C_REG ? rC : C;
1497 assign iA = A_REG ? rA : A;
1501 always @(posedge clock, posedge IRSTBOT) begin
1505 end else if (CE) begin
1506 if (!BHOLD) rB <= B;
1507 if (!DHOLD) rD <= D;
1510 assign iB = B_REG ? rB : B;
1511 assign iD = D_REG ? rD : D;
1514 wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
1515 wire [15:0] Ah, Al, Bh, Bl;
1516 assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
1517 assign Al = {A_SIGNED && MODE_8x8 ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
1518 assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
1519 assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
1520 assign p_Ah_Bh = Ah * Bh; // F
1521 assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J
1522 assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K
1523 assign p_Al_Bl = Al * Bl; // G
1527 always @(posedge clock, posedge IRSTTOP) begin
1531 end else if (CE) begin
1533 if (!MODE_8x8) rJ <= p_Al_Bh;
1536 assign iF = TOP_8x8_MULT_REG ? rF : p_Ah_Bh;
1537 assign iJ = PIPELINE_16x16_MULT_REG1 ? rJ : p_Al_Bh;
1541 always @(posedge clock, posedge IRSTBOT) begin
1545 end else if (CE) begin
1546 if (!MODE_8x8) rK <= p_Ah_Bl;
1550 assign iK = PIPELINE_16x16_MULT_REG1 ? rK : p_Ah_Bl;
1551 assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
1554 wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK};
1555 wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ};
1556 assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16);
1560 always @(posedge clock, posedge IRSTBOT) begin
1563 end else if (CE) begin
1564 if (!MODE_8x8) rH <= iL;
1567 assign iH = PIPELINE_16x16_MULT_REG2 ? rH : iL;
1572 assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
1573 assign iX = (TOPADDSUB_LOWERINPUT == 0) ? iA : (TOPADDSUB_LOWERINPUT == 1) ? iF : (TOPADDSUB_LOWERINPUT == 2) ? iH[31:16] : {16{iZ[15]}};
1574 assign {ACCUMCO, XW} = iX + (iW ^ {16{ADDSUBTOP}}) + HCI;
1575 assign CO = ACCUMCO ^ ADDSUBTOP;
1576 assign iP = OLOADTOP ? iC : XW ^ {16{ADDSUBTOP}};
1577 always @(posedge clock, posedge ORSTTOP) begin
1580 end else if (CE) begin
1581 if (!OHOLDTOP) rQ <= iP;
1585 assign Oh = (TOPOUTPUT_SELECT == 0) ? iP : (TOPOUTPUT_SELECT == 1) ? iQ : (TOPOUTPUT_SELECT == 2) ? iF : iH[31:16];
1586 assign HCI = (TOPADDSUB_CARRYSELECT == 0) ? 1'b0 : (TOPADDSUB_CARRYSELECT == 1) ? 1'b1 : (TOPADDSUB_CARRYSELECT == 2) ? LCO : LCO ^ ADDSUBBOT;
1587 assign SIGNEXTOUT = iX[15];
1592 assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
1593 assign iZ = (BOTADDSUB_LOWERINPUT == 0) ? iB : (BOTADDSUB_LOWERINPUT == 1) ? iG : (BOTADDSUB_LOWERINPUT == 2) ? iH[15:0] : {16{SIGNEXTIN}};
1594 assign {LCO, YZ} = iZ + (iY ^ {16{ADDSUBBOT}}) + LCI;
1595 assign iR = OLOADBOT ? iD : YZ ^ {16{ADDSUBBOT}};
1596 always @(posedge clock, posedge ORSTBOT) begin
1599 end else if (CE) begin
1600 if (!OHOLDBOT) rS <= iR;
1604 assign Ol = (BOTOUTPUT_SELECT == 0) ? iR : (BOTOUTPUT_SELECT == 1) ? iS : (BOTOUTPUT_SELECT == 2) ? iG : iH[15:0];
1605 assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
1606 assign O = {Oh, Ol};