1 (* abc9_lut=1, lib_whitebox *)
2 module LUT4(input A, B, C, D, output Z);
3 parameter INIT = "0x0000";
4 `include "parse_init.vh"
5 localparam initp = parse_init(INIT);
6 wire [7:0] s3 = D ? initp[15:8] : initp[7:0];
7 wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0];
8 wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0];
9 assign Z = A ? s1[1] : s1[0];
11 // Per-input delay differences are considered 'interconnect'
22 // This is a placeholder for ABC9 to extract the area/delay
23 // cost of 5-input LUTs and is not intended to be instantiated
25 module \$__ABC9_LUT5 (input SEL, D, C, B, A, output Z);
36 module WIDEFN9(input A0, B0, C0, D0, A1, B1, C1, D1, SEL, output Z);
37 parameter INIT0 = "0x0000";
38 parameter INIT1 = "0x0000";
40 LUT4 #(.INIT(INIT0)) lut4_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(z0));
41 LUT4 #(.INIT(INIT1)) lut4_1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(z1));
42 assign Z = SEL ? z1 : z0;
45 (* abc9_box, lib_whitebox *)
46 module INV(input A, output Z);
54 // Bidirectional IO buffer
55 module BB(input T, I, output O,
56 (* iopad_external_pin *) inout B);
57 assign B = T ? 1'bz : O;
63 (* iopad_external_pin *) input I,
70 (* iopad_external_pin *) output O);
74 // Output buffer with tristate
75 module OBZ(input I, T,
76 (* iopad_external_pin *) output O);
77 assign O = T ? 1'bz : I;
90 // (all have active high clock, enable and set/reset - use INV to invert)
93 (* abc9_box, lib_whitebox *)
94 module FD1P3BX(input D, CK, SP, PD, output reg Q);
95 parameter GSR = "DISABLED";
97 always @(posedge CK or posedge PD)
103 $setup(D, posedge CK, 0);
104 $setup(SP, posedge CK, 212);
105 $setup(PD, posedge CK, 224);
107 if (PD) (posedge CLK => (Q : 1)) = 0;
109 if (PD) (PD => Q) = 0; // Technically, this should be an edge sensitive path
110 // but for facilitating a bypass box, let's pretend it's
113 if (!PD && SP) (posedge CK => (Q : D)) = 336;
118 (* abc9_box, lib_whitebox *)
119 module FD1P3DX(input D, CK, SP, CD, output reg Q);
120 parameter GSR = "DISABLED";
122 always @(posedge CK or posedge CD)
128 $setup(D, posedge CK, 0);
129 $setup(SP, posedge CK, 212);
130 $setup(CD, posedge CK, 224);
132 if (CD) (posedge CLK => (Q : 0)) = 0;
134 if (CD) (CD => Q) = 0; // Technically, this should be an edge sensitive path
135 // but for facilitating a bypass box, let's pretend it's
138 if (!CD && SP) (posedge CK => (Q : D)) = 336;
143 (* abc9_flop, lib_whitebox *)
144 module FD1P3IX(input D, CK, SP, CD, output reg Q);
145 parameter GSR = "DISABLED";
153 $setup(D, posedge CK, 0);
154 $setup(SP, posedge CK, 212);
155 $setup(CD, posedge CK, 224);
156 if (!CD && SP) (posedge CK => (Q : D)) = 336;
161 (* abc9_flop, lib_whitebox *)
162 module FD1P3JX(input D, CK, SP, PD, output reg Q);
163 parameter GSR = "DISABLED";
171 $setup(D, posedge CK, 0);
172 $setup(SP, posedge CK, 212);
173 $setup(PD, posedge CK, 224);
174 if (!PD && SP) (posedge CK => (Q : D)) = 336;
178 // LUT4 with LUT3 tap for CCU2 use only
180 module LUT4_3(input A, B, C, D, output Z, Z3);
181 parameter INIT = "0x0000";
182 `include "parse_init.vh"
183 localparam initp = parse_init(INIT);
184 wire [7:0] s3 = D ? initp[15:8] : initp[7:0];
185 wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0];
186 wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0];
187 assign Z = A ? s1[1] : s1[0];
189 wire [3:0] s2_3 = C ? initp[ 7:4] : initp[3:0];
190 wire [1:0] s1_3 = B ? s2_3[ 3:2] : s2_3[1:0];
191 assign Z3 = A ? s1_3[1] : s1_3[0];
195 // Carry primitive (incoporating two LUTs)
196 (* abc9_box, lib_whitebox *)
198 (* abc9_carry *) input CIN,
199 input A1, B1, C1, D1, A0, B0, C0, D0,
201 (* abc9_carry *) output COUT);
202 parameter INJECT = "YES";
203 parameter INIT0 = "0x0000";
204 parameter INIT1 = "0x1111";
206 localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0;
208 wire LUT3_0, LUT4_0, LUT3_1, LUT4_1, carry_0;
209 LUT4_3 #(.INIT(INIT0)) lut0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0), .Z3(LUT3_0));
210 LUT4_3 #(.INIT(INIT1)) lut1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1), .Z3(LUT3_1));
212 assign S0 = LUT4_0 ^ (CIN & ~inject_p);
213 assign carry_0 = LUT4_0 ? CIN : (LUT3_0 & ~inject_p);
214 assign S1 = LUT4_1 ^ (carry_0 & ~inject_p);
215 assign COUT = LUT4_1 ? carry_0 : (LUT3_1 & ~inject_p);
246 module OXIDE_FF(input CLK, LSR, CE, DI, M, output reg Q);
247 parameter GSR = "ENABLED";
248 parameter [127:0] CEMUX = "1";
249 parameter CLKMUX = "CLK";
250 parameter LSRMUX = "LSR";
251 parameter REGDDR = "DISABLED";
252 parameter SRMODE = "LSR_OVER_CE";
253 parameter REGSET = "RESET";
254 parameter [127:0] LSRMODE = "LSR";
259 "1": assign muxce = 1'b1;
260 "0": assign muxce = 1'b0;
261 "INV": assign muxce = ~CE;
262 default: assign muxce = CE;
266 wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
267 wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
270 if (LSRMODE == "PRLD")
273 assign srval = (REGSET == "SET") ? 1'b1 : 1'b0;
279 if (REGDDR == "ENABLED") begin
280 if (SRMODE == "ASYNC") begin
281 always @(posedge muxclk, negedge muxclk, posedge muxlsr)
287 always @(posedge muxclk, negedge muxclk)
294 if (SRMODE == "ASYNC") begin
295 always @(posedge muxclk, posedge muxlsr)
301 always @(posedge muxclk)
311 // Packed combinational logic (for post-pnr sim)
313 input A, B, C, D, // LUT inputs
314 input SEL, // mux select input
315 input F1, // output from LUT 1 for mux
316 input FCI, // carry input
317 input WAD0, WAD1, WAD2, WAD3, // LUTRAM write address inputs
318 input WD, // LUTRAM write data input
319 input WCK, WRE, // LUTRAM write clock and enable
320 output F, // LUT/carry output
321 output OFX // mux output
323 parameter MODE = "LOGIC"; // LOGIC, CCU2, DPRAM
324 parameter [15:0] INIT = 16'h0000;
325 parameter INJECT = "YES";
327 localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0;
329 reg [15:0] lut = INIT;
331 wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
332 wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0];
333 wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0];
334 wire Z = A ? s1[1] : s1[0];
336 wire [3:0] s2_3 = C ? INIT[ 7:4] : INIT[3:0];
337 wire [1:0] s1_3 = B ? s2_3[ 3:2] : s2_3[1:0];
338 wire Z3 = A ? s1_3[1] : s1_3[0];
341 if (MODE == "DPRAM") begin
342 always @(posedge WCK)
344 lut[{WAD3, WAD2, WAD1, WAD0}] <= WD;
346 if (MODE == "CCU2") begin
347 assign F = Z ^ (FCI & ~inject_p);
348 assign FCO = Z ? FCI : (Z3 & ~inject_p);
354 assign OFX = SEL ? F1 : F;
360 input [3:0] RAD, DI, WAD,
364 parameter INITVAL = "0x0000000000000000";
365 `include "parse_init.vh"
366 localparam [63:0] parsed_init = parse_init_64(INITVAL);
371 for (i = 0; i < 15; i++)
372 mem[i] = parsed_init[i * 4 +: 4];
375 always @(posedge WCK)
378 assign DO = mem[RAD];