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
178 // Positive Edge SiliconBlue FF Cells
216 always @(posedge C, posedge R)
240 always @(posedge C, posedge S)
266 always @(posedge C, posedge R)
292 always @(posedge C, posedge S)
299 // Negative Edge SiliconBlue FF Cells
337 always @(negedge C, posedge R)
361 always @(negedge C, posedge S)
387 always @(negedge C, posedge R)
413 always @(negedge C, posedge S)
420 // SiliconBlue RAM Cells
423 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
425 input RCLK, RCLKE, RE,
427 input WCLK, WCLKE, WE,
429 input [15:0] MASK, WDATA
435 parameter WRITE_MODE = 0;
436 parameter READ_MODE = 0;
438 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
439 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
440 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
441 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
442 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
443 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
444 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
445 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
446 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
447 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
448 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
449 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
450 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
451 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
452 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
453 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
455 parameter INIT_FILE = "";
466 0: assign WMASK_I = MASK;
468 1: assign WMASK_I = WADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
469 WADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
471 2: assign WMASK_I = WADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
472 WADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
473 WADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
474 WADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
476 3: assign WMASK_I = WADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
477 WADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
478 WADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
479 WADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
480 WADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
481 WADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
482 WADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
483 WADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
487 0: assign RMASK_I = 16'b 0000_0000_0000_0000;
489 1: assign RMASK_I = RADDR[ 8] == 0 ? 16'b 1010_1010_1010_1010 :
490 RADDR[ 8] == 1 ? 16'b 0101_0101_0101_0101 : 16'bx;
492 2: assign RMASK_I = RADDR[ 9:8] == 0 ? 16'b 1110_1110_1110_1110 :
493 RADDR[ 9:8] == 1 ? 16'b 1101_1101_1101_1101 :
494 RADDR[ 9:8] == 2 ? 16'b 1011_1011_1011_1011 :
495 RADDR[ 9:8] == 3 ? 16'b 0111_0111_0111_0111 : 16'bx;
497 3: assign RMASK_I = RADDR[10:8] == 0 ? 16'b 1111_1110_1111_1110 :
498 RADDR[10:8] == 1 ? 16'b 1111_1101_1111_1101 :
499 RADDR[10:8] == 2 ? 16'b 1111_1011_1111_1011 :
500 RADDR[10:8] == 3 ? 16'b 1111_0111_1111_0111 :
501 RADDR[10:8] == 4 ? 16'b 1110_1111_1110_1111 :
502 RADDR[10:8] == 5 ? 16'b 1101_1111_1101_1111 :
503 RADDR[10:8] == 6 ? 16'b 1011_1111_1011_1111 :
504 RADDR[10:8] == 7 ? 16'b 0111_1111_0111_1111 : 16'bx;
508 0: assign WDATA_I = WDATA;
510 1: assign WDATA_I = {WDATA[14], WDATA[14], WDATA[12], WDATA[12],
511 WDATA[10], WDATA[10], WDATA[ 8], WDATA[ 8],
512 WDATA[ 6], WDATA[ 6], WDATA[ 4], WDATA[ 4],
513 WDATA[ 2], WDATA[ 2], WDATA[ 0], WDATA[ 0]};
515 2: assign WDATA_I = {WDATA[13], WDATA[13], WDATA[13], WDATA[13],
516 WDATA[ 9], WDATA[ 9], WDATA[ 9], WDATA[ 9],
517 WDATA[ 5], WDATA[ 5], WDATA[ 5], WDATA[ 5],
518 WDATA[ 1], WDATA[ 1], WDATA[ 1], WDATA[ 1]};
520 3: assign WDATA_I = {WDATA[11], WDATA[11], WDATA[11], WDATA[11],
521 WDATA[11], WDATA[11], WDATA[11], WDATA[11],
522 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3],
523 WDATA[ 3], WDATA[ 3], WDATA[ 3], WDATA[ 3]};
527 0: assign RDATA = RDATA_I;
528 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],
529 1'b0, |RDATA_I[ 7: 6], 1'b0, |RDATA_I[ 5: 4], 1'b0, |RDATA_I[ 3: 2], 1'b0, |RDATA_I[ 1: 0]};
530 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};
531 3: assign RDATA = {4'b0, |RDATA_I[15: 8], 7'b0, |RDATA_I[ 7: 0], 3'b0};
536 reg [15:0] memory [0:255];
540 $readmemh(INIT_FILE, memory);
542 for (i=0; i<16; i=i+1) begin
543 memory[ 0*16 + i] = INIT_0[16*i +: 16];
544 memory[ 1*16 + i] = INIT_1[16*i +: 16];
545 memory[ 2*16 + i] = INIT_2[16*i +: 16];
546 memory[ 3*16 + i] = INIT_3[16*i +: 16];
547 memory[ 4*16 + i] = INIT_4[16*i +: 16];
548 memory[ 5*16 + i] = INIT_5[16*i +: 16];
549 memory[ 6*16 + i] = INIT_6[16*i +: 16];
550 memory[ 7*16 + i] = INIT_7[16*i +: 16];
551 memory[ 8*16 + i] = INIT_8[16*i +: 16];
552 memory[ 9*16 + i] = INIT_9[16*i +: 16];
553 memory[10*16 + i] = INIT_A[16*i +: 16];
554 memory[11*16 + i] = INIT_B[16*i +: 16];
555 memory[12*16 + i] = INIT_C[16*i +: 16];
556 memory[13*16 + i] = INIT_D[16*i +: 16];
557 memory[14*16 + i] = INIT_E[16*i +: 16];
558 memory[15*16 + i] = INIT_F[16*i +: 16];
562 always @(posedge WCLK) begin
563 if (WE && WCLKE) begin
564 if (!WMASK_I[ 0]) memory[WADDR[7:0]][ 0] <= WDATA_I[ 0];
565 if (!WMASK_I[ 1]) memory[WADDR[7:0]][ 1] <= WDATA_I[ 1];
566 if (!WMASK_I[ 2]) memory[WADDR[7:0]][ 2] <= WDATA_I[ 2];
567 if (!WMASK_I[ 3]) memory[WADDR[7:0]][ 3] <= WDATA_I[ 3];
568 if (!WMASK_I[ 4]) memory[WADDR[7:0]][ 4] <= WDATA_I[ 4];
569 if (!WMASK_I[ 5]) memory[WADDR[7:0]][ 5] <= WDATA_I[ 5];
570 if (!WMASK_I[ 6]) memory[WADDR[7:0]][ 6] <= WDATA_I[ 6];
571 if (!WMASK_I[ 7]) memory[WADDR[7:0]][ 7] <= WDATA_I[ 7];
572 if (!WMASK_I[ 8]) memory[WADDR[7:0]][ 8] <= WDATA_I[ 8];
573 if (!WMASK_I[ 9]) memory[WADDR[7:0]][ 9] <= WDATA_I[ 9];
574 if (!WMASK_I[10]) memory[WADDR[7:0]][10] <= WDATA_I[10];
575 if (!WMASK_I[11]) memory[WADDR[7:0]][11] <= WDATA_I[11];
576 if (!WMASK_I[12]) memory[WADDR[7:0]][12] <= WDATA_I[12];
577 if (!WMASK_I[13]) memory[WADDR[7:0]][13] <= WDATA_I[13];
578 if (!WMASK_I[14]) memory[WADDR[7:0]][14] <= WDATA_I[14];
579 if (!WMASK_I[15]) memory[WADDR[7:0]][15] <= WDATA_I[15];
583 always @(posedge RCLK) begin
584 if (RE && RCLKE) begin
585 RDATA_I <= memory[RADDR[7:0]] & ~RMASK_I;
591 module SB_RAM40_4KNR (
592 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
594 input RCLKN, RCLKE, RE,
596 input WCLK, WCLKE, WE,
598 input [15:0] MASK, WDATA
600 parameter WRITE_MODE = 0;
601 parameter READ_MODE = 0;
603 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
604 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
605 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
606 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
607 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
608 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
609 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
610 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
611 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
612 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
613 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
614 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
615 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
616 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
617 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
618 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
620 parameter INIT_FILE = "";
623 .WRITE_MODE(WRITE_MODE),
624 .READ_MODE (READ_MODE ),
641 .INIT_FILE (INIT_FILE )
657 module SB_RAM40_4KNW (
658 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
660 input RCLK, RCLKE, RE,
662 input WCLKN, WCLKE, WE,
664 input [15:0] MASK, WDATA
666 parameter WRITE_MODE = 0;
667 parameter READ_MODE = 0;
669 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
670 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
671 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
672 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
673 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
674 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
675 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
676 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
677 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
678 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
679 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
680 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
681 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
682 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
683 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
684 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
686 parameter INIT_FILE = "";
689 .WRITE_MODE(WRITE_MODE),
690 .READ_MODE (READ_MODE ),
707 .INIT_FILE (INIT_FILE )
723 module SB_RAM40_4KNRNW (
724 `ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
726 input RCLKN, RCLKE, RE,
728 input WCLKN, WCLKE, WE,
730 input [15:0] MASK, WDATA
732 parameter WRITE_MODE = 0;
733 parameter READ_MODE = 0;
735 parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
736 parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
737 parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
738 parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
739 parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
740 parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
741 parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
742 parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
743 parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
744 parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
745 parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
746 parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
747 parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
748 parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
749 parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
750 parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
752 parameter INIT_FILE = "";
755 .WRITE_MODE(WRITE_MODE),
756 .READ_MODE (READ_MODE ),
773 .INIT_FILE (INIT_FILE )
789 // Packed IceStorm Logic Cells
792 input I0, I1, I2, I3, CIN, CLK, CEN, SR,
798 parameter [15:0] LUT_INIT = 0;
800 parameter [0:0] NEG_CLK = 0;
801 parameter [0:0] CARRY_ENABLE = 0;
802 parameter [0:0] DFF_ENABLE = 0;
803 parameter [0:0] SET_NORESET = 0;
804 parameter [0:0] ASYNC_SR = 0;
806 parameter [0:0] CIN_CONST = 0;
807 parameter [0:0] CIN_SET = 0;
809 wire mux_cin = CIN_CONST ? CIN_SET : CIN;
811 assign COUT = CARRY_ENABLE ? (I1 && I2) || ((I1 || I2) && mux_cin) : 1'bx;
813 wire [7:0] lut_s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
814 wire [3:0] lut_s2 = I2 ? lut_s3[ 7:4] : lut_s3[3:0];
815 wire [1:0] lut_s1 = I1 ? lut_s2[ 3:2] : lut_s2[1:0];
816 wire lut_o = I0 ? lut_s1[ 1] : lut_s1[ 0];
821 assign polarized_clk = CLK ^ NEG_CLK;
824 always @(posedge polarized_clk)
826 o_reg <= SR ? SET_NORESET : lut_o;
829 always @(posedge polarized_clk, posedge SR)
831 o_reg <= SET_NORESET;
835 assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;
838 // SiliconBlue PLL Cells
841 module SB_PLL40_CORE (
846 input [7:0] DYNAMICDELAY,
850 input LATCHINPUTVALUE,
855 parameter FEEDBACK_PATH = "SIMPLE";
856 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
857 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
858 parameter SHIFTREG_DIV_MODE = 1'b0;
859 parameter FDA_FEEDBACK = 4'b0000;
860 parameter FDA_RELATIVE = 4'b0000;
861 parameter PLLOUT_SELECT = "GENCLK";
862 parameter DIVR = 4'b0000;
863 parameter DIVF = 7'b0000000;
864 parameter DIVQ = 3'b000;
865 parameter FILTER_RANGE = 3'b000;
866 parameter ENABLE_ICEGATE = 1'b0;
867 parameter TEST_MODE = 1'b0;
868 parameter EXTERNAL_DIVIDE_FACTOR = 1;
872 module SB_PLL40_PAD (
877 input [7:0] DYNAMICDELAY,
881 input LATCHINPUTVALUE,
886 parameter FEEDBACK_PATH = "SIMPLE";
887 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
888 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
889 parameter SHIFTREG_DIV_MODE = 1'b0;
890 parameter FDA_FEEDBACK = 4'b0000;
891 parameter FDA_RELATIVE = 4'b0000;
892 parameter PLLOUT_SELECT = "GENCLK";
893 parameter DIVR = 4'b0000;
894 parameter DIVF = 7'b0000000;
895 parameter DIVQ = 3'b000;
896 parameter FILTER_RANGE = 3'b000;
897 parameter ENABLE_ICEGATE = 1'b0;
898 parameter TEST_MODE = 1'b0;
899 parameter EXTERNAL_DIVIDE_FACTOR = 1;
903 module SB_PLL40_2_PAD (
906 output PLLOUTGLOBALA,
908 output PLLOUTGLOBALB,
910 input [7:0] DYNAMICDELAY,
914 input LATCHINPUTVALUE,
919 parameter FEEDBACK_PATH = "SIMPLE";
920 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
921 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
922 parameter SHIFTREG_DIV_MODE = 1'b0;
923 parameter FDA_FEEDBACK = 4'b0000;
924 parameter FDA_RELATIVE = 4'b0000;
925 parameter PLLOUT_SELECT_PORTB = "GENCLK";
926 parameter DIVR = 4'b0000;
927 parameter DIVF = 7'b0000000;
928 parameter DIVQ = 3'b000;
929 parameter FILTER_RANGE = 3'b000;
930 parameter ENABLE_ICEGATE_PORTA = 1'b0;
931 parameter ENABLE_ICEGATE_PORTB = 1'b0;
932 parameter TEST_MODE = 1'b0;
933 parameter EXTERNAL_DIVIDE_FACTOR = 1;
937 module SB_PLL40_2F_CORE (
940 output PLLOUTGLOBALA,
942 output PLLOUTGLOBALB,
944 input [7:0] DYNAMICDELAY,
948 input LATCHINPUTVALUE,
953 parameter FEEDBACK_PATH = "SIMPLE";
954 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
955 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
956 parameter SHIFTREG_DIV_MODE = 1'b0;
957 parameter FDA_FEEDBACK = 4'b0000;
958 parameter FDA_RELATIVE = 4'b0000;
959 parameter PLLOUT_SELECT_PORTA = "GENCLK";
960 parameter PLLOUT_SELECT_PORTB = "GENCLK";
961 parameter DIVR = 4'b0000;
962 parameter DIVF = 7'b0000000;
963 parameter DIVQ = 3'b000;
964 parameter FILTER_RANGE = 3'b000;
965 parameter ENABLE_ICEGATE_PORTA = 1'b0;
966 parameter ENABLE_ICEGATE_PORTB = 1'b0;
967 parameter TEST_MODE = 1'b0;
968 parameter EXTERNAL_DIVIDE_FACTOR = 1;
972 module SB_PLL40_2F_PAD (
975 output PLLOUTGLOBALA,
977 output PLLOUTGLOBALB,
979 input [7:0] DYNAMICDELAY,
983 input LATCHINPUTVALUE,
988 parameter FEEDBACK_PATH = "SIMPLE";
989 parameter DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED";
990 parameter DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED";
991 parameter SHIFTREG_DIV_MODE = 2'b00;
992 parameter FDA_FEEDBACK = 4'b0000;
993 parameter FDA_RELATIVE = 4'b0000;
994 parameter PLLOUT_SELECT_PORTA = "GENCLK";
995 parameter PLLOUT_SELECT_PORTB = "GENCLK";
996 parameter DIVR = 4'b0000;
997 parameter DIVF = 7'b0000000;
998 parameter DIVQ = 3'b000;
999 parameter FILTER_RANGE = 3'b000;
1000 parameter ENABLE_ICEGATE_PORTA = 1'b0;
1001 parameter ENABLE_ICEGATE_PORTB = 1'b0;
1002 parameter TEST_MODE = 1'b0;
1003 parameter EXTERNAL_DIVIDE_FACTOR = 1;
1006 // SiliconBlue Device Configuration Cells
1008 (* blackbox, keep *)
1009 module SB_WARMBOOT (
1016 module SB_SPRAM256KA (
1017 input [13:0] ADDRESS,
1018 input [15:0] DATAIN,
1019 input [3:0] MASKWREN,
1020 input WREN, CHIPSELECT, CLOCK, STANDBY, SLEEP, POWEROFF,
1021 output reg [15:0] DATAOUT
1025 reg [15:0] mem [0:16383];
1026 wire off = SLEEP || !POWEROFF;
1029 always @(negedge POWEROFF) begin
1030 for (i = 0; i <= 16383; i = i+1)
1034 always @(posedge CLOCK, posedge off) begin
1038 if (CHIPSELECT && !STANDBY && !WREN) begin
1039 DATAOUT <= mem[ADDRESS];
1041 if (CHIPSELECT && !STANDBY && WREN) begin
1042 if (MASKWREN[0]) mem[ADDRESS][ 3: 0] = DATAIN[ 3: 0];
1043 if (MASKWREN[1]) mem[ADDRESS][ 7: 4] = DATAIN[ 7: 4];
1044 if (MASKWREN[2]) mem[ADDRESS][11: 8] = DATAIN[11: 8];
1045 if (MASKWREN[3]) mem[ADDRESS][15:12] = DATAIN[15:12];
1070 parameter TRIM_EN = "0b0";
1071 parameter CLKHF_DIV = "0b00";
1093 parameter CURRENT_MODE = "0b0";
1094 parameter RGB0_CURRENT = "0b000000";
1095 parameter RGB1_CURRENT = "0b000000";
1096 parameter RGB2_CURRENT = "0b000000";
1100 module SB_LED_DRV_CUR(
1117 parameter CURRENT_MODE = "0b0";
1118 parameter RGB0_CURRENT = "0b000000";
1119 parameter RGB1_CURRENT = "0b000000";
1120 parameter RGB2_CURRENT = "0b000000";
1157 output SCLO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1162 parameter I2C_SLAVE_INIT_ADDR = "0b1111100001";
1163 parameter BUS_ADDR74 = "0b0001";
1206 output SCKO, //inout in the SB verilog library, but output in the VHDL and PDF libs and seemingly in the HW itself
1217 parameter BUS_ADDR74 = "0b0000";
1247 module SB_FILTER_50NS(
1255 input LATCH_INPUT_VALUE,
1259 input OUTPUT_ENABLE,
1267 parameter [5:0] PIN_TYPE = 6'b000000;
1268 parameter [0:0] PULLUP = 1'b0;
1269 parameter [0:0] WEAK_PULLUP = 1'b0;
1270 parameter [0:0] NEG_TRIGGER = 1'b0;
1271 parameter IO_STANDARD = "SB_LVCMOS";
1274 reg dout, din_0, din_1;
1275 reg din_q_0, din_q_1;
1276 reg dout_q_0, dout_q_1;
1279 generate if (!NEG_TRIGGER) begin
1280 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1281 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1282 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1283 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1284 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1286 always @(negedge INPUT_CLK) if (CLOCK_ENABLE) din_q_0 <= PACKAGE_PIN;
1287 always @(posedge INPUT_CLK) if (CLOCK_ENABLE) din_q_1 <= PACKAGE_PIN;
1288 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_0 <= D_OUT_0;
1289 always @(posedge OUTPUT_CLK) if (CLOCK_ENABLE) dout_q_1 <= D_OUT_1;
1290 always @(negedge OUTPUT_CLK) if (CLOCK_ENABLE) outena_q <= OUTPUT_ENABLE;
1294 if (!PIN_TYPE[1] || !LATCH_INPUT_VALUE)
1295 din_0 = PIN_TYPE[0] ? PACKAGE_PIN : din_q_0;
1299 // work around simulation glitches on dout in DDR mode
1300 reg outclk_delayed_1;
1301 reg outclk_delayed_2;
1302 always @* outclk_delayed_1 <= OUTPUT_CLK;
1303 always @* outclk_delayed_2 <= outclk_delayed_1;
1307 dout = PIN_TYPE[2] ? !dout_q_0 : D_OUT_0;
1309 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1312 assign D_IN_0 = din_0, D_IN_1 = din_1;
1315 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGE_PIN = dout;
1316 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGE_PIN = OUTPUT_ENABLE ? dout : 1'bz;
1317 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGE_PIN = outena_q ? dout : 1'bz;
1324 input LATCHINPUTVALUE,
1334 parameter [5:0] PIN_TYPE = 6'b000000;
1335 parameter [0:0] NEG_TRIGGER = 1'b0;
1338 reg dout, din_0, din_1;
1339 reg din_q_0, din_q_1;
1340 reg dout_q_0, dout_q_1;
1343 generate if (!NEG_TRIGGER) begin
1344 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1345 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1346 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1347 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1348 always @(posedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1350 always @(negedge INPUTCLK) if (CLOCKENABLE) din_q_0 <= PACKAGEPIN;
1351 always @(posedge INPUTCLK) if (CLOCKENABLE) din_q_1 <= PACKAGEPIN;
1352 always @(negedge OUTPUTCLK) if (CLOCKENABLE) dout_q_0 <= DOUT0;
1353 always @(posedge OUTPUTCLK) if (CLOCKENABLE) dout_q_1 <= DOUT1;
1354 always @(negedge OUTPUTCLK) if (CLOCKENABLE) outena_q <= OUTPUTENABLE;
1358 if (!PIN_TYPE[1] || !LATCHINPUTVALUE)
1359 din_0 = PIN_TYPE[0] ? PACKAGEPIN : din_q_0;
1363 // work around simulation glitches on dout in DDR mode
1364 reg outclk_delayed_1;
1365 reg outclk_delayed_2;
1366 always @* outclk_delayed_1 <= OUTPUTCLK;
1367 always @* outclk_delayed_2 <= outclk_delayed_1;
1371 dout = PIN_TYPE[2] ? !dout_q_0 : DOUT0;
1373 dout = (outclk_delayed_2 ^ NEG_TRIGGER) || PIN_TYPE[2] ? dout_q_0 : dout_q_1;
1376 assign DIN0 = din_0, DIN1 = din_1;
1379 if (PIN_TYPE[5:4] == 2'b01) assign PACKAGEPIN = dout ? 1'bz : 1'b0;
1380 if (PIN_TYPE[5:4] == 2'b10) assign PACKAGEPIN = OUTPUTENABLE ? (dout ? 1'bz : 1'b0) : 1'bz;
1381 if (PIN_TYPE[5:4] == 2'b11) assign PACKAGEPIN = outena_q ? (dout ? 1'bz : 1'b0) : 1'bz;
1388 input [15:0] C, A, B, D,
1389 input AHOLD, BHOLD, CHOLD, DHOLD,
1390 input IRSTTOP, IRSTBOT,
1391 input ORSTTOP, ORSTBOT,
1392 input OLOADTOP, OLOADBOT,
1393 input ADDSUBTOP, ADDSUBBOT,
1394 input OHOLDTOP, OHOLDBOT,
1395 input CI, ACCUMCI, SIGNEXTIN,
1397 output CO, ACCUMCO, SIGNEXTOUT
1399 parameter [0:0] NEG_TRIGGER = 0;
1400 parameter [0:0] C_REG = 0;
1401 parameter [0:0] A_REG = 0;
1402 parameter [0:0] B_REG = 0;
1403 parameter [0:0] D_REG = 0;
1404 parameter [0:0] TOP_8x8_MULT_REG = 0;
1405 parameter [0:0] BOT_8x8_MULT_REG = 0;
1406 parameter [0:0] PIPELINE_16x16_MULT_REG1 = 0;
1407 parameter [0:0] PIPELINE_16x16_MULT_REG2 = 0;
1408 parameter [1:0] TOPOUTPUT_SELECT = 0;
1409 parameter [1:0] TOPADDSUB_LOWERINPUT = 0;
1410 parameter [0:0] TOPADDSUB_UPPERINPUT = 0;
1411 parameter [1:0] TOPADDSUB_CARRYSELECT = 0;
1412 parameter [1:0] BOTOUTPUT_SELECT = 0;
1413 parameter [1:0] BOTADDSUB_LOWERINPUT = 0;
1414 parameter [0:0] BOTADDSUB_UPPERINPUT = 0;
1415 parameter [1:0] BOTADDSUB_CARRYSELECT = 0;
1416 parameter [0:0] MODE_8x8 = 0;
1417 parameter [0:0] A_SIGNED = 0;
1418 parameter [0:0] B_SIGNED = 0;
1420 wire clock = CLK ^ NEG_TRIGGER;
1422 // internal wires, compare Figure on page 133 of ICE Technology Library 3.0 and Fig 2 on page 2 of Lattice TN1295-DSP
1423 // http://www.latticesemi.com/~/media/LatticeSemi/Documents/TechnicalBriefs/SBTICETechnologyLibrary201608.pdf
1424 // https://www.latticesemi.com/-/media/LatticeSemi/Documents/ApplicationNotes/AD/DSPFunctionUsageGuideforICE40Devices.ashx
1425 wire [15:0] iA, iB, iC, iD;
1426 wire [15:0] iF, iJ, iK, iG;
1428 wire [15:0] iW, iX, iP, iQ;
1429 wire [15:0] iY, iZ, iR, iS;
1434 always @(posedge clock, posedge IRSTTOP) begin
1438 end else if (CE) begin
1439 if (!CHOLD) rC <= C;
1440 if (!AHOLD) rA <= A;
1443 assign iC = C_REG ? rC : C;
1444 assign iA = A_REG ? rA : A;
1448 always @(posedge clock, posedge IRSTBOT) begin
1452 end else if (CE) begin
1453 if (!BHOLD) rB <= B;
1454 if (!DHOLD) rD <= D;
1457 assign iB = B_REG ? rB : B;
1458 assign iD = D_REG ? rD : D;
1461 wire [15:0] p_Ah_Bh, p_Al_Bh, p_Ah_Bl, p_Al_Bl;
1462 wire [15:0] Ah, Al, Bh, Bl;
1463 assign Ah = {A_SIGNED ? {8{iA[15]}} : 8'b0, iA[15: 8]};
1464 assign Al = {A_SIGNED && MODE_8x8 ? {8{iA[ 7]}} : 8'b0, iA[ 7: 0]};
1465 assign Bh = {B_SIGNED ? {8{iB[15]}} : 8'b0, iB[15: 8]};
1466 assign Bl = {B_SIGNED && MODE_8x8 ? {8{iB[ 7]}} : 8'b0, iB[ 7: 0]};
1467 assign p_Ah_Bh = Ah * Bh; // F
1468 assign p_Al_Bh = {8'b0, Al[7:0]} * Bh; // J
1469 assign p_Ah_Bl = Ah * {8'b0, Bl[7:0]}; // K
1470 assign p_Al_Bl = Al * Bl; // G
1474 always @(posedge clock, posedge IRSTTOP) begin
1478 end else if (CE) begin
1480 if (!MODE_8x8) rJ <= p_Al_Bh;
1483 assign iF = TOP_8x8_MULT_REG ? rF : p_Ah_Bh;
1484 assign iJ = PIPELINE_16x16_MULT_REG1 ? rJ : p_Al_Bh;
1488 always @(posedge clock, posedge IRSTBOT) begin
1492 end else if (CE) begin
1493 if (!MODE_8x8) rK <= p_Ah_Bl;
1497 assign iK = PIPELINE_16x16_MULT_REG1 ? rK : p_Ah_Bl;
1498 assign iG = BOT_8x8_MULT_REG ? rG : p_Al_Bl;
1501 wire [23:0] iK_e = {A_SIGNED ? {8{iK[15]}} : 8'b0, iK};
1502 wire [23:0] iJ_e = {B_SIGNED ? {8{iJ[15]}} : 8'b0, iJ};
1503 assign iL = iG + (iK_e << 8) + (iJ_e << 8) + (iF << 16);
1507 always @(posedge clock, posedge IRSTBOT) begin
1510 end else if (CE) begin
1511 if (!MODE_8x8) rH <= iL;
1514 assign iH = PIPELINE_16x16_MULT_REG2 ? rH : iL;
1519 assign iW = TOPADDSUB_UPPERINPUT ? iC : iQ;
1520 assign iX = (TOPADDSUB_LOWERINPUT == 0) ? iA : (TOPADDSUB_LOWERINPUT == 1) ? iF : (TOPADDSUB_LOWERINPUT == 2) ? iH[31:16] : {16{iZ[15]}};
1521 assign {ACCUMCO, XW} = iX + (iW ^ {16{ADDSUBTOP}}) + HCI;
1522 assign CO = ACCUMCO ^ ADDSUBTOP;
1523 assign iP = OLOADTOP ? iC : XW ^ {16{ADDSUBTOP}};
1524 always @(posedge clock, posedge ORSTTOP) begin
1527 end else if (CE) begin
1528 if (!OHOLDTOP) rQ <= iP;
1532 assign Oh = (TOPOUTPUT_SELECT == 0) ? iP : (TOPOUTPUT_SELECT == 1) ? iQ : (TOPOUTPUT_SELECT == 2) ? iF : iH[31:16];
1533 assign HCI = (TOPADDSUB_CARRYSELECT == 0) ? 1'b0 : (TOPADDSUB_CARRYSELECT == 1) ? 1'b1 : (TOPADDSUB_CARRYSELECT == 2) ? LCO : LCO ^ ADDSUBBOT;
1534 assign SIGNEXTOUT = iX[15];
1539 assign iY = BOTADDSUB_UPPERINPUT ? iD : iS;
1540 assign iZ = (BOTADDSUB_LOWERINPUT == 0) ? iB : (BOTADDSUB_LOWERINPUT == 1) ? iG : (BOTADDSUB_LOWERINPUT == 2) ? iH[15:0] : {16{SIGNEXTIN}};
1541 assign {LCO, YZ} = iZ + (iY ^ {16{ADDSUBBOT}}) + LCI;
1542 assign iR = OLOADBOT ? iD : YZ ^ {16{ADDSUBBOT}};
1543 always @(posedge clock, posedge ORSTBOT) begin
1546 end else if (CE) begin
1547 if (!OHOLDBOT) rS <= iR;
1551 assign Ol = (BOTOUTPUT_SELECT == 0) ? iR : (BOTOUTPUT_SELECT == 1) ? iS : (BOTOUTPUT_SELECT == 2) ? iG : iH[15:0];
1552 assign LCI = (BOTADDSUB_CARRYSELECT == 0) ? 1'b0 : (BOTADDSUB_CARRYSELECT == 1) ? 1'b1 : (BOTADDSUB_CARRYSELECT == 2) ? ACCUMCI : CI;
1553 assign O = {Oh, Ol};