Merge pull request #2529 from zachjs/unnamed-genblk
[yosys.git] / techlibs / xilinx / cells_sim.v
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 // See Xilinx UG953 and UG474 for a description of the cell types below.
21 // http://www.xilinx.com/support/documentation/user_guides/ug474_7Series_CLB.pdf
22 // http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_4/ug953-vivado-7series-libraries.pdf
23
24 module VCC(output P);
25 assign P = 1;
26 endmodule
27
28 module GND(output G);
29 assign G = 0;
30 endmodule
31
32 module IBUF(
33 output O,
34 (* iopad_external_pin *)
35 input I);
36 parameter IOSTANDARD = "default";
37 parameter IBUF_LOW_PWR = 0;
38 assign O = I;
39 specify
40 (I => O) = 0;
41 endspecify
42 endmodule
43
44 module IBUFG(
45 output O,
46 (* iopad_external_pin *)
47 input I);
48 parameter CAPACITANCE = "DONT_CARE";
49 parameter IBUF_DELAY_VALUE = "0";
50 parameter IBUF_LOW_PWR = "TRUE";
51 parameter IOSTANDARD = "DEFAULT";
52 assign O = I;
53 endmodule
54
55 module OBUF(
56 (* iopad_external_pin *)
57 output O,
58 input I);
59 parameter IOSTANDARD = "default";
60 parameter DRIVE = 12;
61 parameter SLEW = "SLOW";
62 assign O = I;
63 specify
64 (I => O) = 0;
65 endspecify
66 endmodule
67
68 module IOBUF (
69 (* iopad_external_pin *)
70 inout IO,
71 output O,
72 input I,
73 input T
74 );
75 parameter integer DRIVE = 12;
76 parameter IBUF_LOW_PWR = "TRUE";
77 parameter IOSTANDARD = "DEFAULT";
78 parameter SLEW = "SLOW";
79 assign IO = T ? 1'bz : I;
80 assign O = IO;
81 specify
82 (I => IO) = 0;
83 (IO => O) = 0;
84 endspecify
85 endmodule
86
87 module OBUFT (
88 (* iopad_external_pin *)
89 output O,
90 input I,
91 input T
92 );
93 parameter CAPACITANCE = "DONT_CARE";
94 parameter integer DRIVE = 12;
95 parameter IOSTANDARD = "DEFAULT";
96 parameter SLEW = "SLOW";
97 assign O = T ? 1'bz : I;
98 specify
99 (I => O) = 0;
100 endspecify
101 endmodule
102
103 module BUFG(
104 (* clkbuf_driver *)
105 output O,
106 input I);
107 assign O = I;
108 specify
109 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/CLK_BUFG_TOP_R.sdf#L11
110 (I => O) = 96;
111 endspecify
112 endmodule
113
114 module BUFGCTRL(
115 (* clkbuf_driver *)
116 output O,
117 input I0, input I1,
118 (* invertible_pin = "IS_S0_INVERTED" *)
119 input S0,
120 (* invertible_pin = "IS_S1_INVERTED" *)
121 input S1,
122 (* invertible_pin = "IS_CE0_INVERTED" *)
123 input CE0,
124 (* invertible_pin = "IS_CE1_INVERTED" *)
125 input CE1,
126 (* invertible_pin = "IS_IGNORE0_INVERTED" *)
127 input IGNORE0,
128 (* invertible_pin = "IS_IGNORE1_INVERTED" *)
129 input IGNORE1);
130
131 parameter [0:0] INIT_OUT = 1'b0;
132 parameter PRESELECT_I0 = "FALSE";
133 parameter PRESELECT_I1 = "FALSE";
134 parameter [0:0] IS_CE0_INVERTED = 1'b0;
135 parameter [0:0] IS_CE1_INVERTED = 1'b0;
136 parameter [0:0] IS_S0_INVERTED = 1'b0;
137 parameter [0:0] IS_S1_INVERTED = 1'b0;
138 parameter [0:0] IS_IGNORE0_INVERTED = 1'b0;
139 parameter [0:0] IS_IGNORE1_INVERTED = 1'b0;
140
141 wire I0_internal = ((CE0 ^ IS_CE0_INVERTED) ? I0 : INIT_OUT);
142 wire I1_internal = ((CE1 ^ IS_CE1_INVERTED) ? I1 : INIT_OUT);
143 wire S0_true = (S0 ^ IS_S0_INVERTED);
144 wire S1_true = (S1 ^ IS_S1_INVERTED);
145
146 assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
147
148 endmodule
149
150 module BUFHCE(
151 (* clkbuf_driver *)
152 output O,
153 input I,
154 (* invertible_pin = "IS_CE_INVERTED" *)
155 input CE);
156
157 parameter [0:0] INIT_OUT = 1'b0;
158 parameter CE_TYPE = "SYNC";
159 parameter [0:0] IS_CE_INVERTED = 1'b0;
160
161 assign O = ((CE ^ IS_CE_INVERTED) ? I : INIT_OUT);
162
163 endmodule
164
165 // module OBUFT(output O, input I, T);
166 // assign O = T ? 1'bz : I;
167 // endmodule
168
169 // module IOBUF(inout IO, output O, input I, T);
170 // assign O = IO, IO = T ? 1'bz : I;
171 // endmodule
172
173 module INV(
174 (* clkbuf_inv = "I" *)
175 output O,
176 input I
177 );
178 assign O = !I;
179 specify
180 (I => O) = 127;
181 endspecify
182 endmodule
183
184 (* abc9_lut=1 *)
185 module LUT1(output O, input I0);
186 parameter [1:0] INIT = 0;
187 assign O = I0 ? INIT[1] : INIT[0];
188 specify
189 (I0 => O) = 127;
190 endspecify
191 endmodule
192
193 (* abc9_lut=2 *)
194 module LUT2(output O, input I0, I1);
195 parameter [3:0] INIT = 0;
196 wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0];
197 assign O = I0 ? s1[1] : s1[0];
198 specify
199 (I0 => O) = 238;
200 (I1 => O) = 127;
201 endspecify
202 endmodule
203
204 (* abc9_lut=3 *)
205 module LUT3(output O, input I0, I1, I2);
206 parameter [7:0] INIT = 0;
207 wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0];
208 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
209 assign O = I0 ? s1[1] : s1[0];
210 specify
211 (I0 => O) = 407;
212 (I1 => O) = 238;
213 (I2 => O) = 127;
214 endspecify
215 endmodule
216
217 (* abc9_lut=3 *)
218 module LUT4(output O, input I0, I1, I2, I3);
219 parameter [15:0] INIT = 0;
220 wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0];
221 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
222 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
223 assign O = I0 ? s1[1] : s1[0];
224 specify
225 (I0 => O) = 472;
226 (I1 => O) = 407;
227 (I2 => O) = 238;
228 (I3 => O) = 127;
229 endspecify
230 endmodule
231
232 (* abc9_lut=3 *)
233 module LUT5(output O, input I0, I1, I2, I3, I4);
234 parameter [31:0] INIT = 0;
235 wire [15: 0] s4 = I4 ? INIT[31:16] : INIT[15: 0];
236 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
237 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
238 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
239 assign O = I0 ? s1[1] : s1[0];
240 specify
241 (I0 => O) = 631;
242 (I1 => O) = 472;
243 (I2 => O) = 407;
244 (I3 => O) = 238;
245 (I4 => O) = 127;
246 endspecify
247 endmodule
248
249 // This is a placeholder for ABC9 to extract the area/delay
250 // cost of 3-input LUTs and is not intended to be instantiated
251
252 (* abc9_lut=5 *)
253 module LUT6(output O, input I0, I1, I2, I3, I4, I5);
254 parameter [63:0] INIT = 0;
255 wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0];
256 wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0];
257 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
258 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
259 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
260 assign O = I0 ? s1[1] : s1[0];
261 specify
262 (I0 => O) = 642;
263 (I1 => O) = 631;
264 (I2 => O) = 472;
265 (I3 => O) = 407;
266 (I4 => O) = 238;
267 (I5 => O) = 127;
268 endspecify
269 endmodule
270
271 module LUT6_2(output O6, output O5, input I0, I1, I2, I3, I4, I5);
272 parameter [63:0] INIT = 0;
273 wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0];
274 wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0];
275 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
276 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
277 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
278 assign O6 = I0 ? s1[1] : s1[0];
279
280 wire [15: 0] s5_4 = I4 ? INIT[31:16] : INIT[15: 0];
281 wire [ 7: 0] s5_3 = I3 ? s5_4[15: 8] : s5_4[ 7: 0];
282 wire [ 3: 0] s5_2 = I2 ? s5_3[ 7: 4] : s5_3[ 3: 0];
283 wire [ 1: 0] s5_1 = I1 ? s5_2[ 3: 2] : s5_2[ 1: 0];
284 assign O5 = I0 ? s5_1[1] : s5_1[0];
285 endmodule
286
287 // This is a placeholder for ABC9 to extract the area/delay
288 // cost of 3-input LUTs and is not intended to be instantiated
289 (* abc9_lut=10 *)
290 module \$__ABC9_LUT7 (output O, input I0, I1, I2, I3, I4, I5, I6);
291 `ifndef __ICARUS__
292 specify
293 // https://github.com/SymbiFlow/prjxray-db/blob/1c85daf1b115da4d27ca83c6b89f53a94de39748/artix7/timings/slicel.sdf#L867
294 (I0 => O) = 642 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
295 (I1 => O) = 631 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
296 (I2 => O) = 472 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
297 (I3 => O) = 407 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
298 (I4 => O) = 238 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
299 (I5 => O) = 127 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
300 (I6 => O) = 0 + 296 /* to select F7BMUX */ + 174 /* CMUX */;
301 endspecify
302 `endif
303 endmodule
304
305 // This is a placeholder for ABC9 to extract the area/delay
306 // cost of 3-input LUTs and is not intended to be instantiated
307 (* abc9_lut=20 *)
308 module \$__ABC9_LUT8 (output O, input I0, I1, I2, I3, I4, I5, I6, I7);
309 `ifndef __ICARUS__
310 specify
311 // https://github.com/SymbiFlow/prjxray-db/blob/1c85daf1b115da4d27ca83c6b89f53a94de39748/artix7/timings/slicel.sdf#L716
312 (I0 => O) = 642 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
313 (I1 => O) = 631 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
314 (I2 => O) = 472 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
315 (I3 => O) = 407 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
316 (I4 => O) = 238 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
317 (I5 => O) = 127 + 223 /* to cross F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
318 (I6 => O) = 0 + 296 /* to select F7BMUX */ + 104 /* to cross F8MUX */ + 192 /* BMUX */;
319 (I7 => O) = 0 + 0 + 273 /* to select F8MUX */ + 192 /* BMUX */;
320 endspecify
321 `endif
322 endmodule
323
324 module MUXCY(output O, input CI, DI, S);
325 assign O = S ? CI : DI;
326 endmodule
327
328 module MUXF5(output O, input I0, I1, S);
329 assign O = S ? I1 : I0;
330 endmodule
331
332 module MUXF6(output O, input I0, I1, S);
333 assign O = S ? I1 : I0;
334 endmodule
335
336 (* abc9_box, lib_whitebox *)
337 module MUXF7(output O, input I0, I1, S);
338 assign O = S ? I1 : I0;
339 specify
340 // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L451-L453
341 (I0 => O) = 217;
342 (I1 => O) = 223;
343 (S => O) = 296;
344 endspecify
345 endmodule
346
347 (* abc9_box, lib_whitebox *)
348 module MUXF8(output O, input I0, I1, S);
349 assign O = S ? I1 : I0;
350 specify
351 // Max delays from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L462-L464
352 (I0 => O) = 104;
353 (I1 => O) = 94;
354 (S => O) = 273;
355 endspecify
356 endmodule
357
358 module MUXF9(output O, input I0, I1, S);
359 assign O = S ? I1 : I0;
360 endmodule
361
362 module XORCY(output O, input CI, LI);
363 assign O = CI ^ LI;
364 endmodule
365
366 (* abc9_box, lib_whitebox *)
367 module CARRY4(
368 (* abc9_carry *)
369 output [3:0] CO,
370 output [3:0] O,
371 (* abc9_carry *)
372 input CI,
373 input CYINIT,
374 input [3:0] DI, S
375 );
376 assign O = S ^ {CO[2:0], CI | CYINIT};
377 assign CO[0] = S[0] ? CI | CYINIT : DI[0];
378 assign CO[1] = S[1] ? CO[0] : DI[1];
379 assign CO[2] = S[2] ? CO[1] : DI[2];
380 assign CO[3] = S[3] ? CO[2] : DI[3];
381 specify
382 // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L11-L46
383 (CYINIT => O[0]) = 482;
384 (S[0] => O[0]) = 223;
385 (CI => O[0]) = 222;
386 (CYINIT => O[1]) = 598;
387 (DI[0] => O[1]) = 407;
388 (S[0] => O[1]) = 400;
389 (S[1] => O[1]) = 205;
390 (CI => O[1]) = 334;
391 (CYINIT => O[2]) = 584;
392 (DI[0] => O[2]) = 556;
393 (DI[1] => O[2]) = 537;
394 (S[0] => O[2]) = 523;
395 (S[1] => O[2]) = 558;
396 (S[2] => O[2]) = 226;
397 (CI => O[2]) = 239;
398 (CYINIT => O[3]) = 642;
399 (DI[0] => O[3]) = 615;
400 (DI[1] => O[3]) = 596;
401 (DI[2] => O[3]) = 438;
402 (S[0] => O[3]) = 582;
403 (S[1] => O[3]) = 618;
404 (S[2] => O[3]) = 330;
405 (S[3] => O[3]) = 227;
406 (CI => O[3]) = 313;
407 (CYINIT => CO[0]) = 536;
408 (DI[0] => CO[0]) = 379;
409 (S[0] => CO[0]) = 340;
410 (CI => CO[0]) = 271;
411 (CYINIT => CO[1]) = 494;
412 (DI[0] => CO[1]) = 465;
413 (DI[1] => CO[1]) = 445;
414 (S[0] => CO[1]) = 433;
415 (S[1] => CO[1]) = 469;
416 (CI => CO[1]) = 157;
417 (CYINIT => CO[2]) = 592;
418 (DI[0] => CO[2]) = 540;
419 (DI[1] => CO[2]) = 520;
420 (DI[2] => CO[2]) = 356;
421 (S[0] => CO[2]) = 512;
422 (S[1] => CO[2]) = 548;
423 (S[2] => CO[2]) = 292;
424 (CI => CO[2]) = 228;
425 (CYINIT => CO[3]) = 580;
426 (DI[0] => CO[3]) = 526;
427 (DI[1] => CO[3]) = 507;
428 (DI[2] => CO[3]) = 398;
429 (DI[3] => CO[3]) = 385;
430 (S[0] => CO[3]) = 508;
431 (S[1] => CO[3]) = 528;
432 (S[2] => CO[3]) = 378;
433 (S[3] => CO[3]) = 380;
434 (CI => CO[3]) = 114;
435 endspecify
436 endmodule
437
438 module CARRY8(
439 output [7:0] CO,
440 output [7:0] O,
441 input CI,
442 input CI_TOP,
443 input [7:0] DI, S
444 );
445 parameter CARRY_TYPE = "SINGLE_CY8";
446 wire CI4 = (CARRY_TYPE == "DUAL_CY4" ? CI_TOP : CO[3]);
447 assign O = S ^ {CO[6:4], CI4, CO[2:0], CI};
448 assign CO[0] = S[0] ? CI : DI[0];
449 assign CO[1] = S[1] ? CO[0] : DI[1];
450 assign CO[2] = S[2] ? CO[1] : DI[2];
451 assign CO[3] = S[3] ? CO[2] : DI[3];
452 assign CO[4] = S[4] ? CI4 : DI[4];
453 assign CO[5] = S[5] ? CO[4] : DI[5];
454 assign CO[6] = S[6] ? CO[5] : DI[6];
455 assign CO[7] = S[7] ? CO[6] : DI[7];
456 endmodule
457
458 module ORCY (output O, input CI, I);
459 assign O = CI | I;
460 endmodule
461
462 module MULT_AND (output LO, input I0, I1);
463 assign LO = I0 & I1;
464 endmodule
465
466 // Flip-flops and latches.
467
468 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
469
470 (* abc9_flop, lib_whitebox *)
471 module FDRE (
472 output reg Q,
473 (* clkbuf_sink *)
474 (* invertible_pin = "IS_C_INVERTED" *)
475 input C,
476 input CE,
477 (* invertible_pin = "IS_D_INVERTED" *)
478 input D,
479 (* invertible_pin = "IS_R_INVERTED" *)
480 input R
481 );
482 parameter [0:0] INIT = 1'b0;
483 parameter [0:0] IS_C_INVERTED = 1'b0;
484 parameter [0:0] IS_D_INVERTED = 1'b0;
485 parameter [0:0] IS_R_INVERTED = 1'b0;
486 initial Q <= INIT;
487 generate
488 case (|IS_C_INVERTED)
489 1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
490 1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
491 endcase
492 endgenerate
493 specify
494 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
495 $setup(D , posedge C &&& CE && !IS_C_INVERTED , /*-46*/ 0); // Negative times not currently supported
496 $setup(D , negedge C &&& CE && IS_C_INVERTED , /*-46*/ 0); // Negative times not currently supported
497 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
498 $setup(CE, posedge C &&& !IS_C_INVERTED, 109);
499 $setup(CE, negedge C &&& IS_C_INVERTED, 109);
500 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
501 $setup(R , posedge C &&& !IS_C_INVERTED, 404);
502 $setup(R , negedge C &&& IS_C_INVERTED, 404);
503 // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
504 if (!IS_C_INVERTED && R != IS_R_INVERTED) (posedge C => (Q : 1'b0)) = 303;
505 if ( IS_C_INVERTED && R != IS_R_INVERTED) (negedge C => (Q : 1'b0)) = 303;
506 if (!IS_C_INVERTED && R == IS_R_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
507 if ( IS_C_INVERTED && R == IS_R_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
508 endspecify
509 endmodule
510
511 (* abc9_flop, lib_whitebox *)
512 module FDRE_1 (
513 output reg Q,
514 (* clkbuf_sink *)
515 input C,
516 input CE,
517 input D,
518 input R
519 );
520 parameter [0:0] INIT = 1'b0;
521 initial Q <= INIT;
522 always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D;
523 specify
524 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
525 $setup(D , negedge C &&& CE, /*-46*/ 0); // Negative times not currently supported
526 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
527 $setup(CE, negedge C, 109);
528 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
529 $setup(R , negedge C, 404); // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
530 if (R) (negedge C => (Q : 1'b0)) = 303;
531 if (!R && CE) (negedge C => (Q : D)) = 303;
532 endspecify
533 endmodule
534
535 (* abc9_flop, lib_whitebox *)
536 module FDSE (
537 output reg Q,
538 (* clkbuf_sink *)
539 (* invertible_pin = "IS_C_INVERTED" *)
540 input C,
541 input CE,
542 (* invertible_pin = "IS_D_INVERTED" *)
543 input D,
544 (* invertible_pin = "IS_S_INVERTED" *)
545 input S
546 );
547 parameter [0:0] INIT = 1'b1;
548 parameter [0:0] IS_C_INVERTED = 1'b0;
549 parameter [0:0] IS_D_INVERTED = 1'b0;
550 parameter [0:0] IS_S_INVERTED = 1'b0;
551 initial Q <= INIT;
552 generate
553 case (|IS_C_INVERTED)
554 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
555 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
556 endcase
557 endgenerate
558 specify
559 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
560 $setup(D , posedge C &&& !IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
561 $setup(D , negedge C &&& IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
562 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
563 $setup(CE, posedge C &&& !IS_C_INVERTED, 109);
564 $setup(CE, negedge C &&& IS_C_INVERTED, 109);
565 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
566 $setup(S , posedge C &&& !IS_C_INVERTED, 404);
567 $setup(S , negedge C &&& IS_C_INVERTED, 404);
568 // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
569 if (!IS_C_INVERTED && S != IS_S_INVERTED) (posedge C => (Q : 1'b1)) = 303;
570 if ( IS_C_INVERTED && S != IS_S_INVERTED) (negedge C => (Q : 1'b1)) = 303;
571 if (!IS_C_INVERTED && S == IS_S_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
572 if ( IS_C_INVERTED && S == IS_S_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
573 endspecify
574 endmodule
575
576 (* abc9_flop, lib_whitebox *)
577 module FDSE_1 (
578 output reg Q,
579 (* clkbuf_sink *)
580 input C,
581 input CE,
582 input D,
583 input S
584 );
585 parameter [0:0] INIT = 1'b1;
586 initial Q <= INIT;
587 always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D;
588 specify
589 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
590 $setup(D , negedge C &&& CE, /*-46*/ 0); // Negative times not currently supported
591 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
592 $setup(CE, negedge C, 109);
593 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
594 $setup(S , negedge C, 404);
595 // https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L243
596 if (S) (negedge C => (Q : 1'b1)) = 303;
597 if (!S && CE) (negedge C => (Q : D)) = 303;
598 endspecify
599 endmodule
600
601 module FDRSE (
602 output reg Q,
603 (* clkbuf_sink *)
604 (* invertible_pin = "IS_C_INVERTED" *)
605 input C,
606 (* invertible_pin = "IS_CE_INVERTED" *)
607 input CE,
608 (* invertible_pin = "IS_D_INVERTED" *)
609 input D,
610 (* invertible_pin = "IS_R_INVERTED" *)
611 input R,
612 (* invertible_pin = "IS_S_INVERTED" *)
613 input S
614 );
615 parameter [0:0] INIT = 1'b0;
616 parameter [0:0] IS_C_INVERTED = 1'b0;
617 parameter [0:0] IS_CE_INVERTED = 1'b0;
618 parameter [0:0] IS_D_INVERTED = 1'b0;
619 parameter [0:0] IS_R_INVERTED = 1'b0;
620 parameter [0:0] IS_S_INVERTED = 1'b0;
621 initial Q <= INIT;
622 wire c = C ^ IS_C_INVERTED;
623 wire ce = CE ^ IS_CE_INVERTED;
624 wire d = D ^ IS_D_INVERTED;
625 wire r = R ^ IS_R_INVERTED;
626 wire s = S ^ IS_S_INVERTED;
627 always @(posedge c)
628 if (r)
629 Q <= 0;
630 else if (s)
631 Q <= 1;
632 else if (ce)
633 Q <= d;
634 endmodule
635
636 module FDRSE_1 (
637 output reg Q,
638 (* clkbuf_sink *)
639 (* invertible_pin = "IS_C_INVERTED" *)
640 input C,
641 (* invertible_pin = "IS_CE_INVERTED" *)
642 input CE,
643 (* invertible_pin = "IS_D_INVERTED" *)
644 input D,
645 (* invertible_pin = "IS_R_INVERTED" *)
646 input R,
647 (* invertible_pin = "IS_S_INVERTED" *)
648 input S
649 );
650 parameter [0:0] INIT = 1'b0;
651 parameter [0:0] IS_C_INVERTED = 1'b0;
652 parameter [0:0] IS_CE_INVERTED = 1'b0;
653 parameter [0:0] IS_D_INVERTED = 1'b0;
654 parameter [0:0] IS_R_INVERTED = 1'b0;
655 parameter [0:0] IS_S_INVERTED = 1'b0;
656 initial Q <= INIT;
657 wire c = C ^ IS_C_INVERTED;
658 wire ce = CE ^ IS_CE_INVERTED;
659 wire d = D ^ IS_D_INVERTED;
660 wire r = R ^ IS_R_INVERTED;
661 wire s = S ^ IS_S_INVERTED;
662 always @(negedge c)
663 if (r)
664 Q <= 0;
665 else if (s)
666 Q <= 1;
667 else if (ce)
668 Q <= d;
669 endmodule
670
671 (* abc9_box, lib_whitebox *)
672 module FDCE (
673 output reg Q,
674 (* clkbuf_sink *)
675 (* invertible_pin = "IS_C_INVERTED" *)
676 input C,
677 input CE,
678 (* invertible_pin = "IS_CLR_INVERTED" *)
679 input CLR,
680 (* invertible_pin = "IS_D_INVERTED" *)
681 input D
682 );
683 parameter [0:0] INIT = 1'b0;
684 parameter [0:0] IS_C_INVERTED = 1'b0;
685 parameter [0:0] IS_D_INVERTED = 1'b0;
686 parameter [0:0] IS_CLR_INVERTED = 1'b0;
687 initial Q <= INIT;
688 generate
689 case ({|IS_C_INVERTED, |IS_CLR_INVERTED})
690 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
691 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
692 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
693 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
694 endcase
695 endgenerate
696 specify
697 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
698 $setup(D , posedge C &&& !IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
699 $setup(D , negedge C &&& IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
700 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
701 $setup(CE , posedge C &&& !IS_C_INVERTED, 109);
702 $setup(CE , negedge C &&& IS_C_INVERTED, 109);
703 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
704 $setup(CLR, posedge C &&& !IS_C_INVERTED, 404);
705 $setup(CLR, negedge C &&& IS_C_INVERTED, 404);
706 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
707 `ifndef YOSYS
708 if (!IS_CLR_INVERTED) (posedge CLR => (Q : 1'b0)) = 764;
709 if ( IS_CLR_INVERTED) (negedge CLR => (Q : 1'b0)) = 764;
710 `else
711 if (IS_CLR_INVERTED != CLR) (CLR => Q) = 764; // Technically, this should be an edge sensitive path
712 // but for facilitating a bypass box, let's pretend it's
713 // a simple path
714 `endif
715 if (!IS_C_INVERTED && CLR == IS_CLR_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
716 if ( IS_C_INVERTED && CLR == IS_CLR_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
717 endspecify
718 endmodule
719
720 (* abc9_box, lib_whitebox *)
721 module FDCE_1 (
722 output reg Q,
723 (* clkbuf_sink *)
724 input C,
725 input CE,
726 input CLR,
727 input D
728 );
729 parameter [0:0] INIT = 1'b0;
730 initial Q <= INIT;
731 always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
732 specify
733 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
734 $setup(D , negedge C &&& CE, /*-46*/ 0); // Negative times not currently supported
735 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
736 $setup(CE , negedge C, 109);
737 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
738 $setup(CLR, negedge C, 404);
739 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
740 `ifndef YOSYS
741 (posedge CLR => (Q : 1'b0)) = 764;
742 `else
743 if (CLR) (CLR => Q) = 764; // Technically, this should be an edge sensitive path
744 // but for facilitating a bypass box, let's pretend it's
745 // a simple path
746 `endif
747 if (!CLR && CE) (negedge C => (Q : D)) = 303;
748 endspecify
749 endmodule
750
751 (* abc9_box, lib_whitebox *)
752 module FDPE (
753 output reg Q,
754 (* clkbuf_sink *)
755 (* invertible_pin = "IS_C_INVERTED" *)
756 input C,
757 input CE,
758 (* invertible_pin = "IS_D_INVERTED" *)
759 input D,
760 (* invertible_pin = "IS_PRE_INVERTED" *)
761 input PRE
762 );
763 parameter [0:0] INIT = 1'b1;
764 parameter [0:0] IS_C_INVERTED = 1'b0;
765 parameter [0:0] IS_D_INVERTED = 1'b0;
766 parameter [0:0] IS_PRE_INVERTED = 1'b0;
767 initial Q <= INIT;
768 generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED})
769 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
770 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
771 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
772 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
773 endcase
774 endgenerate
775 specify
776 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
777 $setup(D , posedge C &&& !IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
778 $setup(D , negedge C &&& IS_C_INVERTED && CE, /*-46*/ 0); // Negative times not currently supported
779 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
780 $setup(CE , posedge C &&& !IS_C_INVERTED, 109);
781 $setup(CE , negedge C &&& IS_C_INVERTED, 109);
782 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
783 $setup(PRE, posedge C &&& !IS_C_INVERTED, 404);
784 $setup(PRE, negedge C &&& IS_C_INVERTED, 404);
785 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
786 `ifndef YOSYS
787 if (!IS_PRE_INVERTED) (posedge PRE => (Q : 1'b1)) = 764;
788 if ( IS_PRE_INVERTED) (negedge PRE => (Q : 1'b1)) = 764;
789 `else
790 if (IS_PRE_INVERTED != PRE) (PRE => Q) = 764; // Technically, this should be an edge sensitive path
791 // but for facilitating a bypass box, let's pretend it's
792 // a simple path
793 `endif
794 if (!IS_C_INVERTED && PRE == IS_PRE_INVERTED && CE) (posedge C => (Q : D ^ IS_D_INVERTED)) = 303;
795 if ( IS_C_INVERTED && PRE == IS_PRE_INVERTED && CE) (negedge C => (Q : D ^ IS_D_INVERTED)) = 303;
796 endspecify
797 endmodule
798
799 (* abc9_box, lib_whitebox *)
800 module FDPE_1 (
801 output reg Q,
802 (* clkbuf_sink *)
803 input C,
804 input CE,
805 input D,
806 input PRE
807 );
808 parameter [0:0] INIT = 1'b1;
809 initial Q <= INIT;
810 always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
811 specify
812 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L249
813 $setup(D , negedge C &&& CE, /*-46*/ 0); // Negative times not currently supported
814 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
815 $setup(CE , negedge C, 109);
816 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L274
817 $setup(PRE, negedge C, 404);
818 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L270
819 `ifndef YOSYS
820 (posedge PRE => (Q : 1'b1)) = 764;
821 `else
822 if (PRE) (PRE => Q) = 764; // Technically, this should be an edge sensitive path
823 // but for facilitating a bypass box, let's pretend it's
824 // a simple path
825 `endif
826 if (!PRE && CE) (negedge C => (Q : D)) = 303;
827 endspecify
828 endmodule
829
830 module FDCPE (
831 output wire Q,
832 (* clkbuf_sink *)
833 (* invertible_pin = "IS_C_INVERTED" *)
834 input C,
835 input CE,
836 (* invertible_pin = "IS_CLR_INVERTED" *)
837 input CLR,
838 input D,
839 (* invertible_pin = "IS_PRE_INVERTED" *)
840 input PRE
841 );
842 parameter [0:0] INIT = 1'b0;
843 parameter [0:0] IS_C_INVERTED = 1'b0;
844 parameter [0:0] IS_CLR_INVERTED = 1'b0;
845 parameter [0:0] IS_PRE_INVERTED = 1'b0;
846 wire c = C ^ IS_C_INVERTED;
847 wire clr = CLR ^ IS_CLR_INVERTED;
848 wire pre = PRE ^ IS_PRE_INVERTED;
849 // Hacky model to avoid simulation-synthesis mismatches.
850 reg qc, qp, qs;
851 initial qc = INIT;
852 initial qp = INIT;
853 initial qs = 0;
854 always @(posedge c, posedge clr) begin
855 if (clr)
856 qc <= 0;
857 else if (CE)
858 qc <= D;
859 end
860 always @(posedge c, posedge pre) begin
861 if (pre)
862 qp <= 1;
863 else if (CE)
864 qp <= D;
865 end
866 always @* begin
867 if (clr)
868 qs <= 0;
869 else if (pre)
870 qs <= 1;
871 end
872 assign Q = qs ? qp : qc;
873 endmodule
874
875 module FDCPE_1 (
876 output wire Q,
877 (* clkbuf_sink *)
878 (* invertible_pin = "IS_C_INVERTED" *)
879 input C,
880 input CE,
881 (* invertible_pin = "IS_CLR_INVERTED" *)
882 input CLR,
883 input D,
884 (* invertible_pin = "IS_PRE_INVERTED" *)
885 input PRE
886 );
887 parameter [0:0] INIT = 1'b0;
888 parameter [0:0] IS_C_INVERTED = 1'b0;
889 parameter [0:0] IS_CLR_INVERTED = 1'b0;
890 parameter [0:0] IS_PRE_INVERTED = 1'b0;
891 wire c = C ^ IS_C_INVERTED;
892 wire clr = CLR ^ IS_CLR_INVERTED;
893 wire pre = PRE ^ IS_PRE_INVERTED;
894 // Hacky model to avoid simulation-synthesis mismatches.
895 reg qc, qp, qs;
896 initial qc = INIT;
897 initial qp = INIT;
898 initial qs = 0;
899 always @(negedge c, posedge clr) begin
900 if (clr)
901 qc <= 0;
902 else if (CE)
903 qc <= D;
904 end
905 always @(negedge c, posedge pre) begin
906 if (pre)
907 qp <= 1;
908 else if (CE)
909 qp <= D;
910 end
911 always @* begin
912 if (clr)
913 qs <= 0;
914 else if (pre)
915 qs <= 1;
916 end
917 assign Q = qs ? qp : qc;
918 endmodule
919
920 module LDCE (
921 output reg Q,
922 (* invertible_pin = "IS_CLR_INVERTED" *)
923 input CLR,
924 input D,
925 (* invertible_pin = "IS_G_INVERTED" *)
926 input G,
927 input GE
928 );
929 parameter [0:0] INIT = 1'b0;
930 parameter [0:0] IS_CLR_INVERTED = 1'b0;
931 parameter [0:0] IS_G_INVERTED = 1'b0;
932 parameter MSGON = "TRUE";
933 parameter XON = "TRUE";
934 initial Q = INIT;
935 wire clr = CLR ^ IS_CLR_INVERTED;
936 wire g = G ^ IS_G_INVERTED;
937 always @*
938 if (clr) Q <= 1'b0;
939 else if (GE && g) Q <= D;
940 endmodule
941
942 module LDPE (
943 output reg Q,
944 input D,
945 (* invertible_pin = "IS_G_INVERTED" *)
946 input G,
947 input GE,
948 (* invertible_pin = "IS_PRE_INVERTED" *)
949 input PRE
950 );
951 parameter [0:0] INIT = 1'b1;
952 parameter [0:0] IS_G_INVERTED = 1'b0;
953 parameter [0:0] IS_PRE_INVERTED = 1'b0;
954 parameter MSGON = "TRUE";
955 parameter XON = "TRUE";
956 initial Q = INIT;
957 wire g = G ^ IS_G_INVERTED;
958 wire pre = PRE ^ IS_PRE_INVERTED;
959 always @*
960 if (pre) Q <= 1'b1;
961 else if (GE && g) Q <= D;
962 endmodule
963
964 module LDCPE (
965 output reg Q,
966 (* invertible_pin = "IS_CLR_INVERTED" *)
967 input CLR,
968 (* invertible_pin = "IS_D_INVERTED" *)
969 input D,
970 (* invertible_pin = "IS_G_INVERTED" *)
971 input G,
972 (* invertible_pin = "IS_GE_INVERTED" *)
973 input GE,
974 (* invertible_pin = "IS_PRE_INVERTED" *)
975 input PRE
976 );
977 parameter [0:0] INIT = 1'b1;
978 parameter [0:0] IS_CLR_INVERTED = 1'b0;
979 parameter [0:0] IS_D_INVERTED = 1'b0;
980 parameter [0:0] IS_G_INVERTED = 1'b0;
981 parameter [0:0] IS_GE_INVERTED = 1'b0;
982 parameter [0:0] IS_PRE_INVERTED = 1'b0;
983 initial Q = INIT;
984 wire d = D ^ IS_D_INVERTED;
985 wire g = G ^ IS_G_INVERTED;
986 wire ge = GE ^ IS_GE_INVERTED;
987 wire clr = CLR ^ IS_CLR_INVERTED;
988 wire pre = PRE ^ IS_PRE_INVERTED;
989 always @*
990 if (clr) Q <= 1'b0;
991 else if (pre) Q <= 1'b1;
992 else if (ge && g) Q <= d;
993 endmodule
994
995 module AND2B1L (
996 output O,
997 input DI,
998 (* invertible_pin = "IS_SRI_INVERTED" *)
999 input SRI
1000 );
1001 parameter [0:0] IS_SRI_INVERTED = 1'b0;
1002 assign O = DI & ~(SRI ^ IS_SRI_INVERTED);
1003 endmodule
1004
1005 module OR2L (
1006 output O,
1007 input DI,
1008 (* invertible_pin = "IS_SRI_INVERTED" *)
1009 input SRI
1010 );
1011 parameter [0:0] IS_SRI_INVERTED = 1'b0;
1012 assign O = DI | (SRI ^ IS_SRI_INVERTED);
1013 endmodule
1014
1015 // LUTRAM.
1016
1017 // Single port.
1018
1019 module RAM16X1S (
1020 output O,
1021 input A0, A1, A2, A3,
1022 input D,
1023 (* clkbuf_sink *)
1024 (* invertible_pin = "IS_WCLK_INVERTED" *)
1025 input WCLK,
1026 input WE
1027 );
1028 parameter [15:0] INIT = 16'h0000;
1029 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1030 wire [3:0] a = {A3, A2, A1, A0};
1031 reg [15:0] mem = INIT;
1032 assign O = mem[a];
1033 wire clk = WCLK ^ IS_WCLK_INVERTED;
1034 always @(posedge clk) if (WE) mem[a] <= D;
1035 endmodule
1036
1037 module RAM16X1S_1 (
1038 output O,
1039 input A0, A1, A2, A3,
1040 input D,
1041 (* clkbuf_sink *)
1042 (* invertible_pin = "IS_WCLK_INVERTED" *)
1043 input WCLK,
1044 input WE
1045 );
1046 parameter [15:0] INIT = 16'h0000;
1047 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1048 wire [3:0] a = {A3, A2, A1, A0};
1049 reg [15:0] mem = INIT;
1050 assign O = mem[a];
1051 wire clk = WCLK ^ IS_WCLK_INVERTED;
1052 always @(negedge clk) if (WE) mem[a] <= D;
1053 endmodule
1054
1055 module RAM32X1S (
1056 output O,
1057 input A0, A1, A2, A3, A4,
1058 input D,
1059 (* clkbuf_sink *)
1060 (* invertible_pin = "IS_WCLK_INVERTED" *)
1061 input WCLK,
1062 input WE
1063 );
1064 parameter [31:0] INIT = 32'h00000000;
1065 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1066 wire [4:0] a = {A4, A3, A2, A1, A0};
1067 reg [31:0] mem = INIT;
1068 assign O = mem[a];
1069 wire clk = WCLK ^ IS_WCLK_INVERTED;
1070 always @(posedge clk) if (WE) mem[a] <= D;
1071 endmodule
1072
1073 module RAM32X1S_1 (
1074 output O,
1075 input A0, A1, A2, A3, A4,
1076 input D,
1077 (* clkbuf_sink *)
1078 (* invertible_pin = "IS_WCLK_INVERTED" *)
1079 input WCLK,
1080 input WE
1081 );
1082 parameter [31:0] INIT = 32'h00000000;
1083 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1084 wire [4:0] a = {A4, A3, A2, A1, A0};
1085 reg [31:0] mem = INIT;
1086 assign O = mem[a];
1087 wire clk = WCLK ^ IS_WCLK_INVERTED;
1088 always @(negedge clk) if (WE) mem[a] <= D;
1089 endmodule
1090
1091 module RAM64X1S (
1092 output O,
1093 input A0, A1, A2, A3, A4, A5,
1094 input D,
1095 (* clkbuf_sink *)
1096 (* invertible_pin = "IS_WCLK_INVERTED" *)
1097 input WCLK,
1098 input WE
1099 );
1100 parameter [63:0] INIT = 64'h0000000000000000;
1101 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1102 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1103 reg [63:0] mem = INIT;
1104 assign O = mem[a];
1105 wire clk = WCLK ^ IS_WCLK_INVERTED;
1106 always @(posedge clk) if (WE) mem[a] <= D;
1107 endmodule
1108
1109 module RAM64X1S_1 (
1110 output O,
1111 input A0, A1, A2, A3, A4, A5,
1112 input D,
1113 (* clkbuf_sink *)
1114 (* invertible_pin = "IS_WCLK_INVERTED" *)
1115 input WCLK,
1116 input WE
1117 );
1118 parameter [63:0] INIT = 64'h0000000000000000;
1119 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1120 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1121 reg [63:0] mem = INIT;
1122 assign O = mem[a];
1123 wire clk = WCLK ^ IS_WCLK_INVERTED;
1124 always @(negedge clk) if (WE) mem[a] <= D;
1125 endmodule
1126
1127 module RAM128X1S (
1128 output O,
1129 input A0, A1, A2, A3, A4, A5, A6,
1130 input D,
1131 (* clkbuf_sink *)
1132 (* invertible_pin = "IS_WCLK_INVERTED" *)
1133 input WCLK,
1134 input WE
1135 );
1136 parameter [127:0] INIT = 128'h00000000000000000000000000000000;
1137 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1138 wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0};
1139 reg [127:0] mem = INIT;
1140 assign O = mem[a];
1141 wire clk = WCLK ^ IS_WCLK_INVERTED;
1142 always @(posedge clk) if (WE) mem[a] <= D;
1143 endmodule
1144
1145 module RAM128X1S_1 (
1146 output O,
1147 input A0, A1, A2, A3, A4, A5, A6,
1148 input D,
1149 (* clkbuf_sink *)
1150 (* invertible_pin = "IS_WCLK_INVERTED" *)
1151 input WCLK,
1152 input WE
1153 );
1154 parameter [127:0] INIT = 128'h00000000000000000000000000000000;
1155 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1156 wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0};
1157 reg [127:0] mem = INIT;
1158 assign O = mem[a];
1159 wire clk = WCLK ^ IS_WCLK_INVERTED;
1160 always @(negedge clk) if (WE) mem[a] <= D;
1161 endmodule
1162
1163 module RAM256X1S (
1164 output O,
1165 input [7:0] A,
1166 input D,
1167 (* clkbuf_sink *)
1168 (* invertible_pin = "IS_WCLK_INVERTED" *)
1169 input WCLK,
1170 input WE
1171 );
1172 parameter [255:0] INIT = 256'h0;
1173 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1174 reg [255:0] mem = INIT;
1175 assign O = mem[A];
1176 wire clk = WCLK ^ IS_WCLK_INVERTED;
1177 always @(posedge clk) if (WE) mem[A] <= D;
1178 endmodule
1179
1180 module RAM512X1S (
1181 output O,
1182 input [8:0] A,
1183 input D,
1184 (* clkbuf_sink *)
1185 (* invertible_pin = "IS_WCLK_INVERTED" *)
1186 input WCLK,
1187 input WE
1188 );
1189 parameter [511:0] INIT = 512'h0;
1190 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1191 reg [511:0] mem = INIT;
1192 assign O = mem[A];
1193 wire clk = WCLK ^ IS_WCLK_INVERTED;
1194 always @(posedge clk) if (WE) mem[A] <= D;
1195 endmodule
1196
1197 // Single port, wide.
1198
1199 module RAM16X2S (
1200 output O0, O1,
1201 input A0, A1, A2, A3,
1202 input D0, D1,
1203 (* clkbuf_sink *)
1204 (* invertible_pin = "IS_WCLK_INVERTED" *)
1205 input WCLK,
1206 input WE
1207 );
1208 parameter [15:0] INIT_00 = 16'h0000;
1209 parameter [15:0] INIT_01 = 16'h0000;
1210 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1211 wire [3:0] a = {A3, A2, A1, A0};
1212 wire clk = WCLK ^ IS_WCLK_INVERTED;
1213 reg [15:0] mem0 = INIT_00;
1214 reg [15:0] mem1 = INIT_01;
1215 assign O0 = mem0[a];
1216 assign O1 = mem1[a];
1217 always @(posedge clk)
1218 if (WE) begin
1219 mem0[a] <= D0;
1220 mem1[a] <= D1;
1221 end
1222 endmodule
1223
1224 module RAM32X2S (
1225 output O0, O1,
1226 input A0, A1, A2, A3, A4,
1227 input D0, D1,
1228 (* clkbuf_sink *)
1229 (* invertible_pin = "IS_WCLK_INVERTED" *)
1230 input WCLK,
1231 input WE
1232 );
1233 parameter [31:0] INIT_00 = 32'h00000000;
1234 parameter [31:0] INIT_01 = 32'h00000000;
1235 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1236 wire [4:0] a = {A4, A3, A2, A1, A0};
1237 wire clk = WCLK ^ IS_WCLK_INVERTED;
1238 reg [31:0] mem0 = INIT_00;
1239 reg [31:0] mem1 = INIT_01;
1240 assign O0 = mem0[a];
1241 assign O1 = mem1[a];
1242 always @(posedge clk)
1243 if (WE) begin
1244 mem0[a] <= D0;
1245 mem1[a] <= D1;
1246 end
1247 endmodule
1248
1249 module RAM64X2S (
1250 output O0, O1,
1251 input A0, A1, A2, A3, A4, A5,
1252 input D0, D1,
1253 (* clkbuf_sink *)
1254 (* invertible_pin = "IS_WCLK_INVERTED" *)
1255 input WCLK,
1256 input WE
1257 );
1258 parameter [63:0] INIT_00 = 64'h0000000000000000;
1259 parameter [63:0] INIT_01 = 64'h0000000000000000;
1260 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1261 wire [5:0] a = {A5, A3, A2, A1, A0};
1262 wire clk = WCLK ^ IS_WCLK_INVERTED;
1263 reg [63:0] mem0 = INIT_00;
1264 reg [63:0] mem1 = INIT_01;
1265 assign O0 = mem0[a];
1266 assign O1 = mem1[a];
1267 always @(posedge clk)
1268 if (WE) begin
1269 mem0[a] <= D0;
1270 mem1[a] <= D1;
1271 end
1272 endmodule
1273
1274 module RAM16X4S (
1275 output O0, O1, O2, O3,
1276 input A0, A1, A2, A3,
1277 input D0, D1, D2, D3,
1278 (* clkbuf_sink *)
1279 (* invertible_pin = "IS_WCLK_INVERTED" *)
1280 input WCLK,
1281 input WE
1282 );
1283 parameter [15:0] INIT_00 = 16'h0000;
1284 parameter [15:0] INIT_01 = 16'h0000;
1285 parameter [15:0] INIT_02 = 16'h0000;
1286 parameter [15:0] INIT_03 = 16'h0000;
1287 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1288 wire [3:0] a = {A3, A2, A1, A0};
1289 wire clk = WCLK ^ IS_WCLK_INVERTED;
1290 reg [15:0] mem0 = INIT_00;
1291 reg [15:0] mem1 = INIT_01;
1292 reg [15:0] mem2 = INIT_02;
1293 reg [15:0] mem3 = INIT_03;
1294 assign O0 = mem0[a];
1295 assign O1 = mem1[a];
1296 assign O2 = mem2[a];
1297 assign O3 = mem3[a];
1298 always @(posedge clk)
1299 if (WE) begin
1300 mem0[a] <= D0;
1301 mem1[a] <= D1;
1302 mem2[a] <= D2;
1303 mem3[a] <= D3;
1304 end
1305 endmodule
1306
1307 module RAM32X4S (
1308 output O0, O1, O2, O3,
1309 input A0, A1, A2, A3, A4,
1310 input D0, D1, D2, D3,
1311 (* clkbuf_sink *)
1312 (* invertible_pin = "IS_WCLK_INVERTED" *)
1313 input WCLK,
1314 input WE
1315 );
1316 parameter [31:0] INIT_00 = 32'h00000000;
1317 parameter [31:0] INIT_01 = 32'h00000000;
1318 parameter [31:0] INIT_02 = 32'h00000000;
1319 parameter [31:0] INIT_03 = 32'h00000000;
1320 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1321 wire [4:0] a = {A4, A3, A2, A1, A0};
1322 wire clk = WCLK ^ IS_WCLK_INVERTED;
1323 reg [31:0] mem0 = INIT_00;
1324 reg [31:0] mem1 = INIT_01;
1325 reg [31:0] mem2 = INIT_02;
1326 reg [31:0] mem3 = INIT_03;
1327 assign O0 = mem0[a];
1328 assign O1 = mem1[a];
1329 assign O2 = mem2[a];
1330 assign O3 = mem3[a];
1331 always @(posedge clk)
1332 if (WE) begin
1333 mem0[a] <= D0;
1334 mem1[a] <= D1;
1335 mem2[a] <= D2;
1336 mem3[a] <= D3;
1337 end
1338 endmodule
1339
1340 module RAM16X8S (
1341 output [7:0] O,
1342 input A0, A1, A2, A3,
1343 input [7:0] D,
1344 (* clkbuf_sink *)
1345 (* invertible_pin = "IS_WCLK_INVERTED" *)
1346 input WCLK,
1347 input WE
1348 );
1349 parameter [15:0] INIT_00 = 16'h0000;
1350 parameter [15:0] INIT_01 = 16'h0000;
1351 parameter [15:0] INIT_02 = 16'h0000;
1352 parameter [15:0] INIT_03 = 16'h0000;
1353 parameter [15:0] INIT_04 = 16'h0000;
1354 parameter [15:0] INIT_05 = 16'h0000;
1355 parameter [15:0] INIT_06 = 16'h0000;
1356 parameter [15:0] INIT_07 = 16'h0000;
1357 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1358 wire [3:0] a = {A3, A2, A1, A0};
1359 wire clk = WCLK ^ IS_WCLK_INVERTED;
1360 reg [15:0] mem0 = INIT_00;
1361 reg [15:0] mem1 = INIT_01;
1362 reg [15:0] mem2 = INIT_02;
1363 reg [15:0] mem3 = INIT_03;
1364 reg [15:0] mem4 = INIT_04;
1365 reg [15:0] mem5 = INIT_05;
1366 reg [15:0] mem6 = INIT_06;
1367 reg [15:0] mem7 = INIT_07;
1368 assign O[0] = mem0[a];
1369 assign O[1] = mem1[a];
1370 assign O[2] = mem2[a];
1371 assign O[3] = mem3[a];
1372 assign O[4] = mem4[a];
1373 assign O[5] = mem5[a];
1374 assign O[6] = mem6[a];
1375 assign O[7] = mem7[a];
1376 always @(posedge clk)
1377 if (WE) begin
1378 mem0[a] <= D[0];
1379 mem1[a] <= D[1];
1380 mem2[a] <= D[2];
1381 mem3[a] <= D[3];
1382 mem4[a] <= D[4];
1383 mem5[a] <= D[5];
1384 mem6[a] <= D[6];
1385 mem7[a] <= D[7];
1386 end
1387 endmodule
1388
1389 module RAM32X8S (
1390 output [7:0] O,
1391 input A0, A1, A2, A3, A4,
1392 input [7:0] D,
1393 (* clkbuf_sink *)
1394 (* invertible_pin = "IS_WCLK_INVERTED" *)
1395 input WCLK,
1396 input WE
1397 );
1398 parameter [31:0] INIT_00 = 32'h00000000;
1399 parameter [31:0] INIT_01 = 32'h00000000;
1400 parameter [31:0] INIT_02 = 32'h00000000;
1401 parameter [31:0] INIT_03 = 32'h00000000;
1402 parameter [31:0] INIT_04 = 32'h00000000;
1403 parameter [31:0] INIT_05 = 32'h00000000;
1404 parameter [31:0] INIT_06 = 32'h00000000;
1405 parameter [31:0] INIT_07 = 32'h00000000;
1406 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1407 wire [4:0] a = {A4, A3, A2, A1, A0};
1408 wire clk = WCLK ^ IS_WCLK_INVERTED;
1409 reg [31:0] mem0 = INIT_00;
1410 reg [31:0] mem1 = INIT_01;
1411 reg [31:0] mem2 = INIT_02;
1412 reg [31:0] mem3 = INIT_03;
1413 reg [31:0] mem4 = INIT_04;
1414 reg [31:0] mem5 = INIT_05;
1415 reg [31:0] mem6 = INIT_06;
1416 reg [31:0] mem7 = INIT_07;
1417 assign O[0] = mem0[a];
1418 assign O[1] = mem1[a];
1419 assign O[2] = mem2[a];
1420 assign O[3] = mem3[a];
1421 assign O[4] = mem4[a];
1422 assign O[5] = mem5[a];
1423 assign O[6] = mem6[a];
1424 assign O[7] = mem7[a];
1425 always @(posedge clk)
1426 if (WE) begin
1427 mem0[a] <= D[0];
1428 mem1[a] <= D[1];
1429 mem2[a] <= D[2];
1430 mem3[a] <= D[3];
1431 mem4[a] <= D[4];
1432 mem5[a] <= D[5];
1433 mem6[a] <= D[6];
1434 mem7[a] <= D[7];
1435 end
1436 endmodule
1437
1438 // Dual port.
1439
1440 module RAM16X1D (
1441 output DPO, SPO,
1442 input D,
1443 (* clkbuf_sink *)
1444 (* invertible_pin = "IS_WCLK_INVERTED" *)
1445 input WCLK,
1446 input WE,
1447 input A0, A1, A2, A3,
1448 input DPRA0, DPRA1, DPRA2, DPRA3
1449 );
1450 parameter INIT = 16'h0;
1451 parameter IS_WCLK_INVERTED = 1'b0;
1452 wire [3:0] a = {A3, A2, A1, A0};
1453 wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0};
1454 reg [15:0] mem = INIT;
1455 assign SPO = mem[a];
1456 assign DPO = mem[dpra];
1457 wire clk = WCLK ^ IS_WCLK_INVERTED;
1458 always @(posedge clk) if (WE) mem[a] <= D;
1459 endmodule
1460
1461 module RAM16X1D_1 (
1462 output DPO, SPO,
1463 input D,
1464 (* clkbuf_sink *)
1465 (* invertible_pin = "IS_WCLK_INVERTED" *)
1466 input WCLK,
1467 input WE,
1468 input A0, A1, A2, A3,
1469 input DPRA0, DPRA1, DPRA2, DPRA3
1470 );
1471 parameter INIT = 16'h0;
1472 parameter IS_WCLK_INVERTED = 1'b0;
1473 wire [3:0] a = {A3, A2, A1, A0};
1474 wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0};
1475 reg [15:0] mem = INIT;
1476 assign SPO = mem[a];
1477 assign DPO = mem[dpra];
1478 wire clk = WCLK ^ IS_WCLK_INVERTED;
1479 always @(negedge clk) if (WE) mem[a] <= D;
1480 endmodule
1481
1482 (* abc9_box, lib_whitebox *)
1483 module RAM32X1D (
1484 output DPO, SPO,
1485 input D,
1486 (* clkbuf_sink *)
1487 (* invertible_pin = "IS_WCLK_INVERTED" *)
1488 input WCLK,
1489 input WE,
1490 input A0, A1, A2, A3, A4,
1491 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
1492 );
1493 parameter INIT = 32'h0;
1494 parameter IS_WCLK_INVERTED = 1'b0;
1495 wire [4:0] a = {A4, A3, A2, A1, A0};
1496 wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1497 reg [31:0] mem = INIT;
1498 assign SPO = mem[a];
1499 assign DPO = mem[dpra];
1500 wire clk = WCLK ^ IS_WCLK_INVERTED;
1501 always @(posedge clk) if (WE) mem[a] <= D;
1502 specify
1503 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1504 $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
1505 $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
1506 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1507 $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
1508 $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
1509 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
1510 $setup(A0, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
1511 $setup(A0, negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
1512 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
1513 $setup(A1, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
1514 $setup(A1, negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
1515 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
1516 $setup(A2, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
1517 $setup(A2, negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
1518 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
1519 $setup(A3, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
1520 $setup(A3, negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
1521 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
1522 $setup(A4, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
1523 $setup(A4, posedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
1524 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
1525 if (!IS_WCLK_INVERTED) (posedge WCLK => (SPO : D)) = 1153;
1526 if (!IS_WCLK_INVERTED) (posedge WCLK => (DPO : 1'bx)) = 1153;
1527 if ( IS_WCLK_INVERTED) (posedge WCLK => (SPO : D)) = 1153;
1528 if ( IS_WCLK_INVERTED) (negedge WCLK => (DPO : 1'bx)) = 1153;
1529 (A0 => SPO) = 642; (DPRA0 => DPO) = 642;
1530 (A1 => SPO) = 632; (DPRA1 => DPO) = 631;
1531 (A2 => SPO) = 472; (DPRA2 => DPO) = 472;
1532 (A3 => SPO) = 407; (DPRA3 => DPO) = 407;
1533 (A4 => SPO) = 238; (DPRA4 => DPO) = 238;
1534 endspecify
1535 endmodule
1536
1537 (* abc9_box, lib_whitebox *)
1538 module RAM32X1D_1 (
1539 output DPO, SPO,
1540 input D,
1541 (* clkbuf_sink *)
1542 (* invertible_pin = "IS_WCLK_INVERTED" *)
1543 input WCLK,
1544 input WE,
1545 input A0,
1546 input A1,
1547 input A2,
1548 input A3,
1549 input A4,
1550 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
1551 );
1552 parameter INIT = 32'h0;
1553 parameter IS_WCLK_INVERTED = 1'b0;
1554 wire [4:0] a = {A4, A3, A2, A1, A0};
1555 wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1556 reg [31:0] mem = INIT;
1557 assign SPO = mem[a];
1558 assign DPO = mem[dpra];
1559 wire clk = WCLK ^ IS_WCLK_INVERTED;
1560 always @(negedge clk) if (WE) mem[a] <= D;
1561 specify
1562 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1563 $setup(D , negedge WCLK &&& WE, 453);
1564 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1565 $setup(WE, negedge WCLK, 654);
1566 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800
1567 $setup(A0, negedge WCLK &&& WE, 245);
1568 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798
1569 $setup(A1, negedge WCLK &&& WE, 208);
1570 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796
1571 $setup(A2, negedge WCLK &&& WE, 147);
1572 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794
1573 $setup(A3, negedge WCLK &&& WE, 68);
1574 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792
1575 $setup(A4, negedge WCLK &&& WE, 66);
1576 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
1577 if (WE) (negedge WCLK => (SPO : D)) = 1153;
1578 if (WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
1579 (A0 => SPO) = 642; (DPRA0 => DPO) = 642;
1580 (A1 => SPO) = 632; (DPRA1 => DPO) = 631;
1581 (A2 => SPO) = 472; (DPRA2 => DPO) = 472;
1582 (A3 => SPO) = 407; (DPRA3 => DPO) = 407;
1583 (A4 => SPO) = 238; (DPRA4 => DPO) = 238;
1584 endspecify
1585 endmodule
1586
1587 (* abc9_box, lib_whitebox *)
1588 module RAM64X1D (
1589 output DPO, SPO,
1590 input D,
1591 (* clkbuf_sink *)
1592 (* invertible_pin = "IS_WCLK_INVERTED" *)
1593 input WCLK,
1594 input WE,
1595 input A0, A1, A2, A3, A4, A5,
1596 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
1597 );
1598 parameter INIT = 64'h0;
1599 parameter IS_WCLK_INVERTED = 1'b0;
1600 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1601 wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1602 reg [63:0] mem = INIT;
1603 assign SPO = mem[a];
1604 assign DPO = mem[dpra];
1605 wire clk = WCLK ^ IS_WCLK_INVERTED;
1606 always @(posedge clk) if (WE) mem[a] <= D;
1607 specify
1608 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1609 $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
1610 $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
1611 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1612 $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
1613 $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
1614 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
1615 $setup(A0, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
1616 $setup(A0, negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
1617 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
1618 $setup(A1, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
1619 $setup(A1, negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
1620 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
1621 $setup(A2, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
1622 $setup(A2, negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
1623 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
1624 $setup(A3, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
1625 $setup(A3, negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
1626 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
1627 $setup(A4, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
1628 $setup(A4, negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
1629 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
1630 $setup(A5, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
1631 $setup(A5, negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
1632 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
1633 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (SPO : D)) = 1153;
1634 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DPO : 1'bx)) = 1153;
1635 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (SPO : D)) = 1153;
1636 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
1637 (A0 => SPO) = 642; (DPRA0 => DPO) = 642;
1638 (A1 => SPO) = 632; (DPRA1 => DPO) = 631;
1639 (A2 => SPO) = 472; (DPRA2 => DPO) = 472;
1640 (A3 => SPO) = 407; (DPRA3 => DPO) = 407;
1641 (A4 => SPO) = 238; (DPRA4 => DPO) = 238;
1642 (A5 => SPO) = 127; (DPRA5 => DPO) = 127;
1643 endspecify
1644 endmodule
1645
1646 module RAM64X1D_1 (
1647 output DPO, SPO,
1648 input D,
1649 (* clkbuf_sink *)
1650 (* invertible_pin = "IS_WCLK_INVERTED" *)
1651 input WCLK,
1652 input WE,
1653 input A0, A1, A2, A3, A4, A5,
1654 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
1655 );
1656 parameter INIT = 64'h0;
1657 parameter IS_WCLK_INVERTED = 1'b0;
1658 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1659 wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1660 reg [63:0] mem = INIT;
1661 assign SPO = mem[a];
1662 assign DPO = mem[dpra];
1663 wire clk = WCLK ^ IS_WCLK_INVERTED;
1664 always @(negedge clk) if (WE) mem[a] <= D;
1665 specify
1666 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1667 $setup(D , negedge WCLK &&& WE, 453);
1668 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1669 $setup(WE, negedge WCLK, 654);
1670 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828
1671 $setup(A0, negedge WCLK &&& WE, 362);
1672 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826
1673 $setup(A1, negedge WCLK &&& WE, 245);
1674 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824
1675 $setup(A2, negedge WCLK &&& WE, 208);
1676 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822
1677 $setup(A3, negedge WCLK &&& WE, 147);
1678 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820
1679 $setup(A4, negedge WCLK &&& WE, 68);
1680 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818
1681 $setup(A5, negedge WCLK &&& WE, 66);
1682 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
1683 if (WE) (negedge WCLK => (SPO : D)) = 1153;
1684 if (WE) (negedge WCLK => (DPO : 1'bx)) = 1153;
1685 (A0 => SPO) = 642; (DPRA0 => DPO) = 642;
1686 (A1 => SPO) = 632; (DPRA1 => DPO) = 631;
1687 (A2 => SPO) = 472; (DPRA2 => DPO) = 472;
1688 (A3 => SPO) = 407; (DPRA3 => DPO) = 407;
1689 (A4 => SPO) = 238; (DPRA4 => DPO) = 238;
1690 (A5 => SPO) = 127; (DPRA5 => DPO) = 127;
1691 endspecify
1692 endmodule
1693
1694 (* abc9_box, lib_whitebox *)
1695 module RAM128X1D (
1696 output DPO, SPO,
1697 input D,
1698 (* clkbuf_sink *)
1699 (* invertible_pin = "IS_WCLK_INVERTED" *)
1700 input WCLK,
1701 input WE,
1702 input [6:0] A,
1703 input [6:0] DPRA
1704 );
1705 parameter INIT = 128'h0;
1706 parameter IS_WCLK_INVERTED = 1'b0;
1707 reg [127:0] mem = INIT;
1708 assign SPO = mem[A];
1709 assign DPO = mem[DPRA];
1710 wire clk = WCLK ^ IS_WCLK_INVERTED;
1711 always @(posedge clk) if (WE) mem[A] <= D;
1712 specify
1713 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1714 $setup(D , posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
1715 $setup(D , negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
1716 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1717 $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
1718 $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
1719 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830
1720 $setup(A[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 616);
1721 $setup(A[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 616);
1722 $setup(A[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
1723 $setup(A[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
1724 $setup(A[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
1725 $setup(A[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
1726 $setup(A[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
1727 $setup(A[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
1728 $setup(A[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
1729 $setup(A[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
1730 $setup(A[5], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
1731 $setup(A[5], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
1732 $setup(A[6], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
1733 $setup(A[6], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
1734 `ifndef __ICARUS__
1735 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981
1736 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (SPO : D)) = 1153 + 217 /* to cross F7AMUX */ + 175 /* AMUX */;
1737 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DPO : 1'bx)) = 1153 + 223 /* to cross F7BMUX */ + 174 /* CMUX */;
1738 (A[0] => SPO) = 642 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1739 (A[1] => SPO) = 631 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1740 (A[2] => SPO) = 472 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1741 (A[3] => SPO) = 407 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1742 (A[4] => SPO) = 238 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1743 (A[5] => SPO) = 127 + 193 /* to cross F7AMUX */ + 175 /* AMUX */;
1744 (A[6] => SPO) = 0 + 276 /* to select F7AMUX */ + 175 /* AMUX */;
1745 (DPRA[0] => DPO) = 642 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1746 (DPRA[1] => DPO) = 631 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1747 (DPRA[2] => DPO) = 472 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1748 (DPRA[3] => DPO) = 407 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1749 (DPRA[4] => DPO) = 238 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1750 (DPRA[5] => DPO) = 127 + 223 /* to cross MUXF7 */ + 174 /* CMUX */;
1751 (DPRA[6] => DPO) = 0 + 296 /* to select MUXF7 */ + 174 /* CMUX */;
1752 `endif
1753 endspecify
1754 endmodule
1755
1756 module RAM256X1D (
1757 output DPO, SPO,
1758 input D,
1759 (* clkbuf_sink *)
1760 (* invertible_pin = "IS_WCLK_INVERTED" *)
1761 input WCLK,
1762 input WE,
1763 input [7:0] A, DPRA
1764 );
1765 parameter INIT = 256'h0;
1766 parameter IS_WCLK_INVERTED = 1'b0;
1767 reg [255:0] mem = INIT;
1768 assign SPO = mem[A];
1769 assign DPO = mem[DPRA];
1770 wire clk = WCLK ^ IS_WCLK_INVERTED;
1771 always @(posedge clk) if (WE) mem[A] <= D;
1772 endmodule
1773
1774 // Multi port.
1775
1776 (* abc9_box, lib_whitebox *)
1777 module RAM32M (
1778 output [1:0] DOA,
1779 output [1:0] DOB,
1780 output [1:0] DOC,
1781 output [1:0] DOD,
1782 input [4:0] ADDRA, ADDRB, ADDRC,
1783 input [4:0] ADDRD,
1784 input [1:0] DIA,
1785 input [1:0] DIB,
1786 input [1:0] DIC,
1787 input [1:0] DID,
1788 (* clkbuf_sink *)
1789 (* invertible_pin = "IS_WCLK_INVERTED" *)
1790 input WCLK,
1791 input WE
1792 );
1793 parameter [63:0] INIT_A = 64'h0000000000000000;
1794 parameter [63:0] INIT_B = 64'h0000000000000000;
1795 parameter [63:0] INIT_C = 64'h0000000000000000;
1796 parameter [63:0] INIT_D = 64'h0000000000000000;
1797 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1798 reg [63:0] mem_a = INIT_A;
1799 reg [63:0] mem_b = INIT_B;
1800 reg [63:0] mem_c = INIT_C;
1801 reg [63:0] mem_d = INIT_D;
1802 assign DOA = mem_a[2*ADDRA+:2];
1803 assign DOB = mem_b[2*ADDRB+:2];
1804 assign DOC = mem_c[2*ADDRC+:2];
1805 assign DOD = mem_d[2*ADDRD+:2];
1806 wire clk = WCLK ^ IS_WCLK_INVERTED;
1807 always @(posedge clk)
1808 if (WE) begin
1809 mem_a[2*ADDRD+:2] <= DIA;
1810 mem_b[2*ADDRD+:2] <= DIB;
1811 mem_c[2*ADDRD+:2] <= DIC;
1812 mem_d[2*ADDRD+:2] <= DID;
1813 end
1814 specify
1815 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986
1816 $setup(ADDRD[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
1817 $setup(ADDRD[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
1818 $setup(ADDRD[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
1819 $setup(ADDRD[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
1820 $setup(ADDRD[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
1821 $setup(ADDRD[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
1822 $setup(ADDRD[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
1823 $setup(ADDRD[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
1824 $setup(ADDRD[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
1825 $setup(ADDRD[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
1826 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
1827 $setup(DIA[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 453);
1828 $setup(DIA[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 453);
1829 $setup(DIA[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 384);
1830 $setup(DIA[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 384);
1831 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
1832 $setup(DIB[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 461);
1833 $setup(DIB[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 461);
1834 $setup(DIB[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 354);
1835 $setup(DIB[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 354);
1836 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
1837 $setup(DIC[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 457);
1838 $setup(DIC[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 457);
1839 $setup(DIC[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 375);
1840 $setup(DIC[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 375);
1841 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
1842 $setup(DID[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 310);
1843 $setup(DID[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 310);
1844 $setup(DID[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 334);
1845 $setup(DID[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 334);
1846 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
1847 $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED, 654);
1848 $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED, 654);
1849 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
1850 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA[0] : DIA[0])) = 1153;
1851 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA[0] : DIA[0])) = 1153;
1852 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857
1853 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA[1] : DIA[1])) = 1188;
1854 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA[1] : DIA[1])) = 1188;
1855 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1856 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB[0] : DIB[0])) = 1161;
1857 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB[0] : DIB[0])) = 1161;
1858 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925
1859 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB[1] : DIB[1])) = 1187;
1860 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB[1] : DIB[1])) = 1187;
1861 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993
1862 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC[0] : DIC[0])) = 1158;
1863 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC[0] : DIC[0])) = 1158;
1864 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
1865 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC[1] : DIC[1])) = 1180;
1866 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC[1] : DIC[1])) = 1180;
1867 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
1868 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD[0] : DID[0])) = 1163;
1869 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD[0] : DID[0])) = 1163;
1870 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061
1871 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD[1] : DID[1])) = 1190;
1872 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD[1] : DID[1])) = 1190;
1873 (ADDRA[0] *> DOA) = 642; (ADDRB[0] *> DOB) = 642; (ADDRC[0] *> DOC) = 642; (ADDRD[0] *> DOD) = 642;
1874 (ADDRA[1] *> DOA) = 631; (ADDRB[1] *> DOB) = 631; (ADDRC[1] *> DOC) = 631; (ADDRD[1] *> DOD) = 631;
1875 (ADDRA[2] *> DOA) = 472; (ADDRB[2] *> DOB) = 472; (ADDRC[2] *> DOC) = 472; (ADDRD[2] *> DOD) = 472;
1876 (ADDRA[3] *> DOA) = 407; (ADDRB[3] *> DOB) = 407; (ADDRC[3] *> DOC) = 407; (ADDRD[3] *> DOD) = 407;
1877 (ADDRA[4] *> DOA) = 238; (ADDRB[4] *> DOB) = 238; (ADDRC[4] *> DOC) = 238; (ADDRD[4] *> DOD) = 238;
1878 endspecify
1879 endmodule
1880
1881 module RAM32M16 (
1882 output [1:0] DOA,
1883 output [1:0] DOB,
1884 output [1:0] DOC,
1885 output [1:0] DOD,
1886 output [1:0] DOE,
1887 output [1:0] DOF,
1888 output [1:0] DOG,
1889 output [1:0] DOH,
1890 input [4:0] ADDRA,
1891 input [4:0] ADDRB,
1892 input [4:0] ADDRC,
1893 input [4:0] ADDRD,
1894 input [4:0] ADDRE,
1895 input [4:0] ADDRF,
1896 input [4:0] ADDRG,
1897 input [4:0] ADDRH,
1898 input [1:0] DIA,
1899 input [1:0] DIB,
1900 input [1:0] DIC,
1901 input [1:0] DID,
1902 input [1:0] DIE,
1903 input [1:0] DIF,
1904 input [1:0] DIG,
1905 input [1:0] DIH,
1906 (* clkbuf_sink *)
1907 (* invertible_pin = "IS_WCLK_INVERTED" *)
1908 input WCLK,
1909 input WE
1910 );
1911 parameter [63:0] INIT_A = 64'h0000000000000000;
1912 parameter [63:0] INIT_B = 64'h0000000000000000;
1913 parameter [63:0] INIT_C = 64'h0000000000000000;
1914 parameter [63:0] INIT_D = 64'h0000000000000000;
1915 parameter [63:0] INIT_E = 64'h0000000000000000;
1916 parameter [63:0] INIT_F = 64'h0000000000000000;
1917 parameter [63:0] INIT_G = 64'h0000000000000000;
1918 parameter [63:0] INIT_H = 64'h0000000000000000;
1919 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1920 reg [63:0] mem_a = INIT_A;
1921 reg [63:0] mem_b = INIT_B;
1922 reg [63:0] mem_c = INIT_C;
1923 reg [63:0] mem_d = INIT_D;
1924 reg [63:0] mem_e = INIT_E;
1925 reg [63:0] mem_f = INIT_F;
1926 reg [63:0] mem_g = INIT_G;
1927 reg [63:0] mem_h = INIT_H;
1928 assign DOA = mem_a[2*ADDRA+:2];
1929 assign DOB = mem_b[2*ADDRB+:2];
1930 assign DOC = mem_c[2*ADDRC+:2];
1931 assign DOD = mem_d[2*ADDRD+:2];
1932 assign DOE = mem_e[2*ADDRE+:2];
1933 assign DOF = mem_f[2*ADDRF+:2];
1934 assign DOG = mem_g[2*ADDRG+:2];
1935 assign DOH = mem_h[2*ADDRH+:2];
1936 wire clk = WCLK ^ IS_WCLK_INVERTED;
1937 always @(posedge clk)
1938 if (WE) begin
1939 mem_a[2*ADDRH+:2] <= DIA;
1940 mem_b[2*ADDRH+:2] <= DIB;
1941 mem_c[2*ADDRH+:2] <= DIC;
1942 mem_d[2*ADDRH+:2] <= DID;
1943 mem_e[2*ADDRH+:2] <= DIE;
1944 mem_f[2*ADDRH+:2] <= DIF;
1945 mem_g[2*ADDRH+:2] <= DIG;
1946 mem_h[2*ADDRH+:2] <= DIH;
1947 end
1948 endmodule
1949
1950 (* abc9_box, lib_whitebox *)
1951 module RAM64M (
1952 output DOA,
1953 output DOB,
1954 output DOC,
1955 output DOD,
1956 input [5:0] ADDRA, ADDRB, ADDRC,
1957 input [5:0] ADDRD,
1958 input DIA,
1959 input DIB,
1960 input DIC,
1961 input DID,
1962 (* clkbuf_sink *)
1963 (* invertible_pin = "IS_WCLK_INVERTED" *)
1964 input WCLK,
1965 input WE
1966 );
1967 parameter [63:0] INIT_A = 64'h0000000000000000;
1968 parameter [63:0] INIT_B = 64'h0000000000000000;
1969 parameter [63:0] INIT_C = 64'h0000000000000000;
1970 parameter [63:0] INIT_D = 64'h0000000000000000;
1971 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1972 reg [63:0] mem_a = INIT_A;
1973 reg [63:0] mem_b = INIT_B;
1974 reg [63:0] mem_c = INIT_C;
1975 reg [63:0] mem_d = INIT_D;
1976 assign DOA = mem_a[ADDRA];
1977 assign DOB = mem_b[ADDRB];
1978 assign DOC = mem_c[ADDRC];
1979 assign DOD = mem_d[ADDRD];
1980 wire clk = WCLK ^ IS_WCLK_INVERTED;
1981 always @(posedge clk)
1982 if (WE) begin
1983 mem_a[ADDRD] <= DIA;
1984 mem_b[ADDRD] <= DIB;
1985 mem_c[ADDRD] <= DIC;
1986 mem_d[ADDRD] <= DID;
1987 end
1988 specify
1989 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830
1990 $setup(ADDRD[0], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 362);
1991 $setup(ADDRD[0], negedge WCLK &&& IS_WCLK_INVERTED && WE, 362);
1992 $setup(ADDRD[1], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 245);
1993 $setup(ADDRD[1], negedge WCLK &&& IS_WCLK_INVERTED && WE, 245);
1994 $setup(ADDRD[2], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 208);
1995 $setup(ADDRD[2], negedge WCLK &&& IS_WCLK_INVERTED && WE, 208);
1996 $setup(ADDRD[3], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 147);
1997 $setup(ADDRD[3], negedge WCLK &&& IS_WCLK_INVERTED && WE, 147);
1998 $setup(ADDRD[4], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 68);
1999 $setup(ADDRD[4], negedge WCLK &&& IS_WCLK_INVERTED && WE, 68);
2000 $setup(ADDRD[5], posedge WCLK &&& !IS_WCLK_INVERTED && WE, 66);
2001 $setup(ADDRD[5], negedge WCLK &&& IS_WCLK_INVERTED && WE, 66);
2002 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988
2003 $setup(DIA, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 384);
2004 $setup(DIA, negedge WCLK &&& IS_WCLK_INVERTED && WE, 384);
2005 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056
2006 $setup(DIB, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 354);
2007 $setup(DIB, negedge WCLK &&& IS_WCLK_INVERTED && WE, 354);
2008 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124
2009 $setup(DIC, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 375);
2010 $setup(DIC, negedge WCLK &&& IS_WCLK_INVERTED && WE, 375);
2011 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192
2012 $setup(DID, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 310);
2013 $setup(DID, negedge WCLK &&& IS_WCLK_INVERTED && WE, 310);
2014 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834
2015 $setup(WE, posedge WCLK &&& !IS_WCLK_INVERTED && WE, 654);
2016 $setup(WE, negedge WCLK &&& IS_WCLK_INVERTED && WE, 654);
2017 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889
2018 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOA : DIA)) = 1153;
2019 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOA : DIA)) = 1153;
2020 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
2021 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOB : DIB)) = 1161;
2022 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOB : DIB)) = 1161;
2023 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025
2024 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOC : DIC)) = 1158;
2025 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOC : DIC)) = 1158;
2026 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093
2027 if (!IS_WCLK_INVERTED && WE) (posedge WCLK => (DOD : DID)) = 1163;
2028 if ( IS_WCLK_INVERTED && WE) (negedge WCLK => (DOD : DID)) = 1163;
2029 (ADDRA[0] => DOA) = 642; (ADDRB[0] => DOB) = 642; (ADDRC[0] => DOC) = 642; (ADDRD[0] => DOD) = 642;
2030 (ADDRA[1] => DOA) = 631; (ADDRB[1] => DOB) = 631; (ADDRC[1] => DOC) = 631; (ADDRD[1] => DOD) = 631;
2031 (ADDRA[2] => DOA) = 472; (ADDRB[2] => DOB) = 472; (ADDRC[2] => DOC) = 472; (ADDRD[2] => DOD) = 472;
2032 (ADDRA[3] => DOA) = 407; (ADDRB[3] => DOB) = 407; (ADDRC[3] => DOC) = 407; (ADDRD[3] => DOD) = 407;
2033 (ADDRA[4] => DOA) = 238; (ADDRB[4] => DOB) = 238; (ADDRC[4] => DOC) = 238; (ADDRD[4] => DOD) = 238;
2034 endspecify
2035 endmodule
2036
2037 module RAM64M8 (
2038 output DOA,
2039 output DOB,
2040 output DOC,
2041 output DOD,
2042 output DOE,
2043 output DOF,
2044 output DOG,
2045 output DOH,
2046 input [5:0] ADDRA,
2047 input [5:0] ADDRB,
2048 input [5:0] ADDRC,
2049 input [5:0] ADDRD,
2050 input [5:0] ADDRE,
2051 input [5:0] ADDRF,
2052 input [5:0] ADDRG,
2053 input [5:0] ADDRH,
2054 input DIA,
2055 input DIB,
2056 input DIC,
2057 input DID,
2058 input DIE,
2059 input DIF,
2060 input DIG,
2061 input DIH,
2062 (* clkbuf_sink *)
2063 (* invertible_pin = "IS_WCLK_INVERTED" *)
2064 input WCLK,
2065 input WE
2066 );
2067 parameter [63:0] INIT_A = 64'h0000000000000000;
2068 parameter [63:0] INIT_B = 64'h0000000000000000;
2069 parameter [63:0] INIT_C = 64'h0000000000000000;
2070 parameter [63:0] INIT_D = 64'h0000000000000000;
2071 parameter [63:0] INIT_E = 64'h0000000000000000;
2072 parameter [63:0] INIT_F = 64'h0000000000000000;
2073 parameter [63:0] INIT_G = 64'h0000000000000000;
2074 parameter [63:0] INIT_H = 64'h0000000000000000;
2075 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
2076 reg [63:0] mem_a = INIT_A;
2077 reg [63:0] mem_b = INIT_B;
2078 reg [63:0] mem_c = INIT_C;
2079 reg [63:0] mem_d = INIT_D;
2080 reg [63:0] mem_e = INIT_E;
2081 reg [63:0] mem_f = INIT_F;
2082 reg [63:0] mem_g = INIT_G;
2083 reg [63:0] mem_h = INIT_H;
2084 assign DOA = mem_a[ADDRA];
2085 assign DOB = mem_b[ADDRB];
2086 assign DOC = mem_c[ADDRC];
2087 assign DOD = mem_d[ADDRD];
2088 assign DOE = mem_e[ADDRE];
2089 assign DOF = mem_f[ADDRF];
2090 assign DOG = mem_g[ADDRG];
2091 assign DOH = mem_h[ADDRH];
2092 wire clk = WCLK ^ IS_WCLK_INVERTED;
2093 always @(posedge clk)
2094 if (WE) begin
2095 mem_a[ADDRH] <= DIA;
2096 mem_b[ADDRH] <= DIB;
2097 mem_c[ADDRH] <= DIC;
2098 mem_d[ADDRH] <= DID;
2099 mem_e[ADDRH] <= DIE;
2100 mem_f[ADDRH] <= DIF;
2101 mem_g[ADDRH] <= DIG;
2102 mem_h[ADDRH] <= DIH;
2103 end
2104 endmodule
2105
2106 module RAM32X16DR8 (
2107 output DOA,
2108 output DOB,
2109 output DOC,
2110 output DOD,
2111 output DOE,
2112 output DOF,
2113 output DOG,
2114 output [1:0] DOH,
2115 input [5:0] ADDRA, ADDRB, ADDRC, ADDRD, ADDRE, ADDRF, ADDRG,
2116 input [4:0] ADDRH,
2117 input [1:0] DIA,
2118 input [1:0] DIB,
2119 input [1:0] DIC,
2120 input [1:0] DID,
2121 input [1:0] DIE,
2122 input [1:0] DIF,
2123 input [1:0] DIG,
2124 input [1:0] DIH,
2125 (* clkbuf_sink *)
2126 (* invertible_pin = "IS_WCLK_INVERTED" *)
2127 input WCLK,
2128 input WE
2129 );
2130 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
2131 reg [63:0] mem_a, mem_b, mem_c, mem_d, mem_e, mem_f, mem_g, mem_h;
2132 assign DOA = mem_a[ADDRA];
2133 assign DOB = mem_b[ADDRB];
2134 assign DOC = mem_c[ADDRC];
2135 assign DOD = mem_d[ADDRD];
2136 assign DOE = mem_e[ADDRE];
2137 assign DOF = mem_f[ADDRF];
2138 assign DOG = mem_g[ADDRG];
2139 assign DOH = mem_h[2*ADDRH+:2];
2140 wire clk = WCLK ^ IS_WCLK_INVERTED;
2141 always @(posedge clk)
2142 if (WE) begin
2143 mem_a[2*ADDRH+:2] <= DIA;
2144 mem_b[2*ADDRH+:2] <= DIB;
2145 mem_c[2*ADDRH+:2] <= DIC;
2146 mem_d[2*ADDRH+:2] <= DID;
2147 mem_e[2*ADDRH+:2] <= DIE;
2148 mem_f[2*ADDRH+:2] <= DIF;
2149 mem_g[2*ADDRH+:2] <= DIG;
2150 mem_h[2*ADDRH+:2] <= DIH;
2151 end
2152 endmodule
2153
2154 module RAM64X8SW (
2155 output [7:0] O,
2156 input [5:0] A,
2157 input D,
2158 (* clkbuf_sink *)
2159 (* invertible_pin = "IS_WCLK_INVERTED" *)
2160 input WCLK,
2161 input WE,
2162 input [2:0] WSEL
2163 );
2164 parameter [63:0] INIT_A = 64'h0000000000000000;
2165 parameter [63:0] INIT_B = 64'h0000000000000000;
2166 parameter [63:0] INIT_C = 64'h0000000000000000;
2167 parameter [63:0] INIT_D = 64'h0000000000000000;
2168 parameter [63:0] INIT_E = 64'h0000000000000000;
2169 parameter [63:0] INIT_F = 64'h0000000000000000;
2170 parameter [63:0] INIT_G = 64'h0000000000000000;
2171 parameter [63:0] INIT_H = 64'h0000000000000000;
2172 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
2173 reg [63:0] mem_a = INIT_A;
2174 reg [63:0] mem_b = INIT_B;
2175 reg [63:0] mem_c = INIT_C;
2176 reg [63:0] mem_d = INIT_D;
2177 reg [63:0] mem_e = INIT_E;
2178 reg [63:0] mem_f = INIT_F;
2179 reg [63:0] mem_g = INIT_G;
2180 reg [63:0] mem_h = INIT_H;
2181 assign O[7] = mem_a[A];
2182 assign O[6] = mem_b[A];
2183 assign O[5] = mem_c[A];
2184 assign O[4] = mem_d[A];
2185 assign O[3] = mem_e[A];
2186 assign O[2] = mem_f[A];
2187 assign O[1] = mem_g[A];
2188 assign O[0] = mem_h[A];
2189 wire clk = WCLK ^ IS_WCLK_INVERTED;
2190 always @(posedge clk)
2191 if (WE) begin
2192 case (WSEL)
2193 3'b111: mem_a[A] <= D;
2194 3'b110: mem_b[A] <= D;
2195 3'b101: mem_c[A] <= D;
2196 3'b100: mem_d[A] <= D;
2197 3'b011: mem_e[A] <= D;
2198 3'b010: mem_f[A] <= D;
2199 3'b001: mem_g[A] <= D;
2200 3'b000: mem_h[A] <= D;
2201 endcase
2202 end
2203 endmodule
2204
2205 // ROM.
2206
2207 module ROM16X1 (
2208 output O,
2209 input A0, A1, A2, A3
2210 );
2211 parameter [15:0] INIT = 16'h0;
2212 assign O = INIT[{A3, A2, A1, A0}];
2213 endmodule
2214
2215 module ROM32X1 (
2216 output O,
2217 input A0, A1, A2, A3, A4
2218 );
2219 parameter [31:0] INIT = 32'h0;
2220 assign O = INIT[{A4, A3, A2, A1, A0}];
2221 endmodule
2222
2223 module ROM64X1 (
2224 output O,
2225 input A0, A1, A2, A3, A4, A5
2226 );
2227 parameter [63:0] INIT = 64'h0;
2228 assign O = INIT[{A5, A4, A3, A2, A1, A0}];
2229 endmodule
2230
2231 module ROM128X1 (
2232 output O,
2233 input A0, A1, A2, A3, A4, A5, A6
2234 );
2235 parameter [127:0] INIT = 128'h0;
2236 assign O = INIT[{A6, A5, A4, A3, A2, A1, A0}];
2237 endmodule
2238
2239 module ROM256X1 (
2240 output O,
2241 input A0, A1, A2, A3, A4, A5, A6, A7
2242 );
2243 parameter [255:0] INIT = 256'h0;
2244 assign O = INIT[{A7, A6, A5, A4, A3, A2, A1, A0}];
2245 endmodule
2246
2247 // Shift registers.
2248
2249 (* abc9_box, lib_whitebox *)
2250 module SRL16 (
2251 output Q,
2252 input A0, A1, A2, A3,
2253 (* clkbuf_sink *)
2254 input CLK,
2255 input D
2256 );
2257 parameter [15:0] INIT = 16'h0000;
2258
2259 reg [15:0] r = INIT;
2260 assign Q = r[{A3,A2,A1,A0}];
2261 always @(posedge CLK) r <= { r[14:0], D };
2262
2263 specify
2264 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2265 (posedge CLK => (Q : 1'bx)) = 1472;
2266 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
2267 $setup(D , posedge CLK, 173);
2268 (A0 => Q) = 631;
2269 (A1 => Q) = 472;
2270 (A2 => Q) = 407;
2271 (A3 => Q) = 238;
2272 endspecify
2273 endmodule
2274
2275 (* abc9_box, lib_whitebox *)
2276 module SRL16E (
2277 output Q,
2278 input A0, A1, A2, A3, CE,
2279 (* clkbuf_sink *)
2280 (* invertible_pin = "IS_CLK_INVERTED" *)
2281 input CLK,
2282 input D
2283 );
2284 parameter [15:0] INIT = 16'h0000;
2285 parameter [0:0] IS_CLK_INVERTED = 1'b0;
2286
2287 reg [15:0] r = INIT;
2288 assign Q = r[{A3,A2,A1,A0}];
2289 generate
2290 if (IS_CLK_INVERTED) begin
2291 always @(negedge CLK) if (CE) r <= { r[14:0], D };
2292 end
2293 else
2294 always @(posedge CLK) if (CE) r <= { r[14:0], D };
2295 endgenerate
2296 specify
2297 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
2298 $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
2299 $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
2300 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2301 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : D)) = 1472;
2302 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : D)) = 1472;
2303 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2304 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : 1'bx)) = 1472;
2305 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : 1'bx)) = 1472;
2306 (A0 => Q) = 631;
2307 (A1 => Q) = 472;
2308 (A2 => Q) = 407;
2309 (A3 => Q) = 238;
2310 endspecify
2311 endmodule
2312
2313 (* abc9_box, lib_whitebox *)
2314 module SRLC16 (
2315 output Q,
2316 output Q15,
2317 input A0, A1, A2, A3,
2318 (* clkbuf_sink *)
2319 input CLK,
2320 input D
2321 );
2322 parameter [15:0] INIT = 16'h0000;
2323
2324 reg [15:0] r = INIT;
2325 assign Q15 = r[15];
2326 assign Q = r[{A3,A2,A1,A0}];
2327 always @(posedge CLK) r <= { r[14:0], D };
2328
2329 specify
2330 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
2331 $setup(D , posedge CLK, 173);
2332 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2333 (posedge CLK => (Q : 1'bx)) = 1472;
2334 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
2335 (posedge CLK => (Q15 : 1'bx)) = 1114;
2336 (A0 => Q) = 631;
2337 (A1 => Q) = 472;
2338 (A2 => Q) = 407;
2339 (A3 => Q) = 238;
2340 endspecify
2341 endmodule
2342
2343 (* abc9_box, lib_whitebox *)
2344 module SRLC16E (
2345 output Q,
2346 output Q15,
2347 input A0, A1, A2, A3, CE,
2348 (* clkbuf_sink *)
2349 (* invertible_pin = "IS_CLK_INVERTED" *)
2350 input CLK,
2351 input D
2352 );
2353 parameter [15:0] INIT = 16'h0000;
2354 parameter [0:0] IS_CLK_INVERTED = 1'b0;
2355
2356 reg [15:0] r = INIT;
2357 assign Q15 = r[15];
2358 assign Q = r[{A3,A2,A1,A0}];
2359 generate
2360 if (IS_CLK_INVERTED) begin
2361 always @(negedge CLK) if (CE) r <= { r[14:0], D };
2362 end
2363 else
2364 always @(posedge CLK) if (CE) r <= { r[14:0], D };
2365 endgenerate
2366 specify
2367 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
2368 $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
2369 $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
2370 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
2371 $setup(CE, posedge CLK &&& !IS_CLK_INVERTED, 109);
2372 $setup(CE, negedge CLK &&& IS_CLK_INVERTED, 109);
2373 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2374 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : D)) = 1472;
2375 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : D)) = 1472;
2376 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
2377 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q15 : 1'bx)) = 1114;
2378 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q15 : 1'bx)) = 1114;
2379 (A0 => Q) = 631;
2380 (A1 => Q) = 472;
2381 (A2 => Q) = 407;
2382 (A3 => Q) = 238;
2383 endspecify
2384 endmodule
2385
2386 (* abc9_box, lib_whitebox *)
2387 module SRLC32E (
2388 output Q,
2389 output Q31,
2390 input [4:0] A,
2391 input CE,
2392 (* clkbuf_sink *)
2393 (* invertible_pin = "IS_CLK_INVERTED" *)
2394 input CLK,
2395 input D
2396 );
2397 parameter [31:0] INIT = 32'h00000000;
2398 parameter [0:0] IS_CLK_INVERTED = 1'b0;
2399
2400 reg [31:0] r = INIT;
2401 assign Q31 = r[31];
2402 assign Q = r[A];
2403 generate
2404 if (IS_CLK_INVERTED) begin
2405 always @(negedge CLK) if (CE) r <= { r[30:0], D };
2406 end
2407 else
2408 always @(posedge CLK) if (CE) r <= { r[30:0], D };
2409 endgenerate
2410 specify
2411 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L912
2412 $setup(D , posedge CLK &&& !IS_CLK_INVERTED, 173);
2413 $setup(D , negedge CLK &&& IS_CLK_INVERTED, 173);
2414 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L248
2415 $setup(CE, posedge CLK &&& !IS_CLK_INVERTED, 109);
2416 $setup(CE, negedge CLK &&& IS_CLK_INVERTED, 109);
2417 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L905
2418 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q : 1'bx)) = 1472;
2419 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q : 1'bx)) = 1472;
2420 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904
2421 if (!IS_CLK_INVERTED && CE) (posedge CLK => (Q31 : 1'bx)) = 1114;
2422 if ( IS_CLK_INVERTED && CE) (negedge CLK => (Q31 : 1'bx)) = 1114;
2423 (A[0] => Q) = 642;
2424 (A[1] => Q) = 631;
2425 (A[2] => Q) = 472;
2426 (A[3] => Q) = 407;
2427 (A[4] => Q) = 238;
2428 endspecify
2429 endmodule
2430
2431 module CFGLUT5 (
2432 output CDO,
2433 output O5,
2434 output O6,
2435 input I4,
2436 input I3,
2437 input I2,
2438 input I1,
2439 input I0,
2440 input CDI,
2441 input CE,
2442 (* clkbuf_sink *)
2443 (* invertible_pin = "IS_CLK_INVERTED" *)
2444 input CLK
2445 );
2446 parameter [31:0] INIT = 32'h00000000;
2447 parameter [0:0] IS_CLK_INVERTED = 1'b0;
2448 wire clk = CLK ^ IS_CLK_INVERTED;
2449 reg [31:0] r = INIT;
2450 assign CDO = r[31];
2451 assign O5 = r[{1'b0, I3, I2, I1, I0}];
2452 assign O6 = r[{I4, I3, I2, I1, I0}];
2453 always @(posedge clk) if (CE) r <= {r[30:0], CDI};
2454 endmodule
2455
2456 // DSP
2457
2458 // Virtex 2, Virtex 2 Pro, Spartan 3.
2459
2460 // Asynchronous mode.
2461
2462 module MULT18X18 (
2463 input signed [17:0] A,
2464 input signed [17:0] B,
2465 output signed [35:0] P
2466 );
2467
2468 assign P = A * B;
2469
2470 endmodule
2471
2472 // Synchronous mode.
2473
2474 module MULT18X18S (
2475 input signed [17:0] A,
2476 input signed [17:0] B,
2477 output reg signed [35:0] P,
2478 (* clkbuf_sink *)
2479 input C,
2480 input CE,
2481 input R
2482 );
2483
2484 always @(posedge C)
2485 if (R)
2486 P <= 0;
2487 else if (CE)
2488 P <= A * B;
2489
2490 endmodule
2491
2492 // Spartan 3E, Spartan 3A.
2493
2494 module MULT18X18SIO (
2495 input signed [17:0] A,
2496 input signed [17:0] B,
2497 output signed [35:0] P,
2498 (* clkbuf_sink *)
2499 input CLK,
2500 input CEA,
2501 input CEB,
2502 input CEP,
2503 input RSTA,
2504 input RSTB,
2505 input RSTP,
2506 input signed [17:0] BCIN,
2507 output signed [17:0] BCOUT
2508 );
2509
2510 parameter integer AREG = 1;
2511 parameter integer BREG = 1;
2512 parameter B_INPUT = "DIRECT";
2513 parameter integer PREG = 1;
2514
2515 // The multiplier.
2516 wire signed [35:0] P_MULT;
2517 wire signed [17:0] A_MULT;
2518 wire signed [17:0] B_MULT;
2519 assign P_MULT = A_MULT * B_MULT;
2520
2521 // The cascade output.
2522 assign BCOUT = B_MULT;
2523
2524 // The B input multiplexer.
2525 wire signed [17:0] B_MUX;
2526 assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
2527
2528 // The registers.
2529 reg signed [17:0] A_REG;
2530 reg signed [17:0] B_REG;
2531 reg signed [35:0] P_REG;
2532
2533 initial begin
2534 A_REG = 0;
2535 B_REG = 0;
2536 P_REG = 0;
2537 end
2538
2539 always @(posedge CLK) begin
2540 if (RSTA)
2541 A_REG <= 0;
2542 else if (CEA)
2543 A_REG <= A;
2544
2545 if (RSTB)
2546 B_REG <= 0;
2547 else if (CEB)
2548 B_REG <= B_MUX;
2549
2550 if (RSTP)
2551 P_REG <= 0;
2552 else if (CEP)
2553 P_REG <= P_MULT;
2554 end
2555
2556 // The register enables.
2557 assign A_MULT = (AREG == 1) ? A_REG : A;
2558 assign B_MULT = (BREG == 1) ? B_REG : B_MUX;
2559 assign P = (PREG == 1) ? P_REG : P_MULT;
2560
2561 endmodule
2562
2563 // Spartan 3A DSP.
2564
2565 module DSP48A (
2566 input signed [17:0] A,
2567 input signed [17:0] B,
2568 input signed [47:0] C,
2569 input signed [17:0] D,
2570 input signed [47:0] PCIN,
2571 input CARRYIN,
2572 input [7:0] OPMODE,
2573 output signed [47:0] P,
2574 output signed [17:0] BCOUT,
2575 output signed [47:0] PCOUT,
2576 output CARRYOUT,
2577 (* clkbuf_sink *)
2578 input CLK,
2579 input CEA,
2580 input CEB,
2581 input CEC,
2582 input CED,
2583 input CEM,
2584 input CECARRYIN,
2585 input CEOPMODE,
2586 input CEP,
2587 input RSTA,
2588 input RSTB,
2589 input RSTC,
2590 input RSTD,
2591 input RSTM,
2592 input RSTCARRYIN,
2593 input RSTOPMODE,
2594 input RSTP
2595 );
2596
2597 parameter integer A0REG = 0;
2598 parameter integer A1REG = 1;
2599 parameter integer B0REG = 0;
2600 parameter integer B1REG = 1;
2601 parameter integer CREG = 1;
2602 parameter integer DREG = 1;
2603 parameter integer MREG = 1;
2604 parameter integer CARRYINREG = 1;
2605 parameter integer OPMODEREG = 1;
2606 parameter integer PREG = 1;
2607 parameter CARRYINSEL = "CARRYIN";
2608 parameter RSTTYPE = "SYNC";
2609
2610 // This is a strict subset of Spartan 6 -- reuse its model.
2611
2612 /* verilator lint_off PINMISSING */
2613 DSP48A1 #(
2614 .A0REG(A0REG),
2615 .A1REG(A1REG),
2616 .B0REG(B0REG),
2617 .B1REG(B1REG),
2618 .CREG(CREG),
2619 .DREG(DREG),
2620 .MREG(MREG),
2621 .CARRYINREG(CARRYINREG),
2622 .CARRYOUTREG(0),
2623 .OPMODEREG(OPMODEREG),
2624 .PREG(PREG),
2625 .CARRYINSEL(CARRYINSEL),
2626 .RSTTYPE(RSTTYPE)
2627 ) upgrade (
2628 .A(A),
2629 .B(B),
2630 .C(C),
2631 .D(D),
2632 .PCIN(PCIN),
2633 .CARRYIN(CARRYIN),
2634 .OPMODE(OPMODE),
2635 // M unconnected
2636 .P(P),
2637 .BCOUT(BCOUT),
2638 .PCOUT(PCOUT),
2639 .CARRYOUT(CARRYOUT),
2640 // CARRYOUTF unconnected
2641 .CLK(CLK),
2642 .CEA(CEA),
2643 .CEB(CEB),
2644 .CEC(CEC),
2645 .CED(CED),
2646 .CEM(CEM),
2647 .CECARRYIN(CECARRYIN),
2648 .CEOPMODE(CEOPMODE),
2649 .CEP(CEP),
2650 .RSTA(RSTA),
2651 .RSTB(RSTB),
2652 .RSTC(RSTC),
2653 .RSTD(RSTD),
2654 .RSTM(RSTM),
2655 .RSTCARRYIN(RSTCARRYIN),
2656 .RSTOPMODE(RSTOPMODE),
2657 .RSTP(RSTP)
2658 );
2659 /* verilator lint_on PINMISSING */
2660
2661 endmodule
2662
2663 // Spartan 6.
2664
2665 module DSP48A1 (
2666 input signed [17:0] A,
2667 input signed [17:0] B,
2668 input signed [47:0] C,
2669 input signed [17:0] D,
2670 input signed [47:0] PCIN,
2671 input CARRYIN,
2672 input [7:0] OPMODE,
2673 output signed [35:0] M,
2674 output signed [47:0] P,
2675 output signed [17:0] BCOUT,
2676 output signed [47:0] PCOUT,
2677 output CARRYOUT,
2678 output CARRYOUTF,
2679 (* clkbuf_sink *)
2680 input CLK,
2681 input CEA,
2682 input CEB,
2683 input CEC,
2684 input CED,
2685 input CEM,
2686 input CECARRYIN,
2687 input CEOPMODE,
2688 input CEP,
2689 input RSTA,
2690 input RSTB,
2691 input RSTC,
2692 input RSTD,
2693 input RSTM,
2694 input RSTCARRYIN,
2695 input RSTOPMODE,
2696 input RSTP
2697 );
2698
2699 parameter integer A0REG = 0;
2700 parameter integer A1REG = 1;
2701 parameter integer B0REG = 0;
2702 parameter integer B1REG = 1;
2703 parameter integer CREG = 1;
2704 parameter integer DREG = 1;
2705 parameter integer MREG = 1;
2706 parameter integer CARRYINREG = 1;
2707 parameter integer CARRYOUTREG = 1;
2708 parameter integer OPMODEREG = 1;
2709 parameter integer PREG = 1;
2710 parameter CARRYINSEL = "OPMODE5";
2711 parameter RSTTYPE = "SYNC";
2712
2713 wire signed [35:0] M_MULT;
2714 wire signed [47:0] P_IN;
2715 wire signed [17:0] A0_OUT;
2716 wire signed [17:0] B0_OUT;
2717 wire signed [17:0] A1_OUT;
2718 wire signed [17:0] B1_OUT;
2719 wire signed [17:0] B1_IN;
2720 wire signed [47:0] C_OUT;
2721 wire signed [17:0] D_OUT;
2722 wire signed [7:0] OPMODE_OUT;
2723 wire CARRYIN_OUT;
2724 wire CARRYOUT_IN;
2725 wire CARRYIN_IN;
2726 reg signed [47:0] XMUX;
2727 reg signed [47:0] ZMUX;
2728
2729 // The registers.
2730 reg signed [17:0] A0_REG;
2731 reg signed [17:0] A1_REG;
2732 reg signed [17:0] B0_REG;
2733 reg signed [17:0] B1_REG;
2734 reg signed [47:0] C_REG;
2735 reg signed [17:0] D_REG;
2736 reg signed [35:0] M_REG;
2737 reg signed [47:0] P_REG;
2738 reg [7:0] OPMODE_REG;
2739 reg CARRYIN_REG;
2740 reg CARRYOUT_REG;
2741
2742 initial begin
2743 A0_REG = 0;
2744 A1_REG = 0;
2745 B0_REG = 0;
2746 B1_REG = 0;
2747 C_REG = 0;
2748 D_REG = 0;
2749 M_REG = 0;
2750 P_REG = 0;
2751 OPMODE_REG = 0;
2752 CARRYIN_REG = 0;
2753 CARRYOUT_REG = 0;
2754 end
2755
2756 generate
2757
2758 if (RSTTYPE == "SYNC") begin
2759 always @(posedge CLK) begin
2760 if (RSTA) begin
2761 A0_REG <= 0;
2762 A1_REG <= 0;
2763 end else if (CEA) begin
2764 A0_REG <= A;
2765 A1_REG <= A0_OUT;
2766 end
2767 end
2768
2769 always @(posedge CLK) begin
2770 if (RSTB) begin
2771 B0_REG <= 0;
2772 B1_REG <= 0;
2773 end else if (CEB) begin
2774 B0_REG <= B;
2775 B1_REG <= B1_IN;
2776 end
2777 end
2778
2779 always @(posedge CLK) begin
2780 if (RSTC) begin
2781 C_REG <= 0;
2782 end else if (CEC) begin
2783 C_REG <= C;
2784 end
2785 end
2786
2787 always @(posedge CLK) begin
2788 if (RSTD) begin
2789 D_REG <= 0;
2790 end else if (CED) begin
2791 D_REG <= D;
2792 end
2793 end
2794
2795 always @(posedge CLK) begin
2796 if (RSTM) begin
2797 M_REG <= 0;
2798 end else if (CEM) begin
2799 M_REG <= M_MULT;
2800 end
2801 end
2802
2803 always @(posedge CLK) begin
2804 if (RSTP) begin
2805 P_REG <= 0;
2806 end else if (CEP) begin
2807 P_REG <= P_IN;
2808 end
2809 end
2810
2811 always @(posedge CLK) begin
2812 if (RSTOPMODE) begin
2813 OPMODE_REG <= 0;
2814 end else if (CEOPMODE) begin
2815 OPMODE_REG <= OPMODE;
2816 end
2817 end
2818
2819 always @(posedge CLK) begin
2820 if (RSTCARRYIN) begin
2821 CARRYIN_REG <= 0;
2822 CARRYOUT_REG <= 0;
2823 end else if (CECARRYIN) begin
2824 CARRYIN_REG <= CARRYIN_IN;
2825 CARRYOUT_REG <= CARRYOUT_IN;
2826 end
2827 end
2828 end else begin
2829 always @(posedge CLK, posedge RSTA) begin
2830 if (RSTA) begin
2831 A0_REG <= 0;
2832 A1_REG <= 0;
2833 end else if (CEA) begin
2834 A0_REG <= A;
2835 A1_REG <= A0_OUT;
2836 end
2837 end
2838
2839 always @(posedge CLK, posedge RSTB) begin
2840 if (RSTB) begin
2841 B0_REG <= 0;
2842 B1_REG <= 0;
2843 end else if (CEB) begin
2844 B0_REG <= B;
2845 B1_REG <= B1_IN;
2846 end
2847 end
2848
2849 always @(posedge CLK, posedge RSTC) begin
2850 if (RSTC) begin
2851 C_REG <= 0;
2852 end else if (CEC) begin
2853 C_REG <= C;
2854 end
2855 end
2856
2857 always @(posedge CLK, posedge RSTD) begin
2858 if (RSTD) begin
2859 D_REG <= 0;
2860 end else if (CED) begin
2861 D_REG <= D;
2862 end
2863 end
2864
2865 always @(posedge CLK, posedge RSTM) begin
2866 if (RSTM) begin
2867 M_REG <= 0;
2868 end else if (CEM) begin
2869 M_REG <= M_MULT;
2870 end
2871 end
2872
2873 always @(posedge CLK, posedge RSTP) begin
2874 if (RSTP) begin
2875 P_REG <= 0;
2876 end else if (CEP) begin
2877 P_REG <= P_IN;
2878 end
2879 end
2880
2881 always @(posedge CLK, posedge RSTOPMODE) begin
2882 if (RSTOPMODE) begin
2883 OPMODE_REG <= 0;
2884 end else if (CEOPMODE) begin
2885 OPMODE_REG <= OPMODE;
2886 end
2887 end
2888
2889 always @(posedge CLK, posedge RSTCARRYIN) begin
2890 if (RSTCARRYIN) begin
2891 CARRYIN_REG <= 0;
2892 CARRYOUT_REG <= 0;
2893 end else if (CECARRYIN) begin
2894 CARRYIN_REG <= CARRYIN_IN;
2895 CARRYOUT_REG <= CARRYOUT_IN;
2896 end
2897 end
2898 end
2899
2900 endgenerate
2901
2902 // The register enables.
2903 assign A0_OUT = (A0REG == 1) ? A0_REG : A;
2904 assign A1_OUT = (A1REG == 1) ? A1_REG : A0_OUT;
2905 assign B0_OUT = (B0REG == 1) ? B0_REG : B;
2906 assign B1_OUT = (B1REG == 1) ? B1_REG : B1_IN;
2907 assign C_OUT = (CREG == 1) ? C_REG : C;
2908 assign D_OUT = (DREG == 1) ? D_REG : D;
2909 assign M = (MREG == 1) ? M_REG : M_MULT;
2910 assign P = (PREG == 1) ? P_REG : P_IN;
2911 assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
2912 assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN_IN;
2913 assign CARRYOUT = (CARRYOUTREG == 1) ? CARRYOUT_REG : CARRYOUT_IN;
2914 assign CARRYOUTF = CARRYOUT;
2915
2916 // The pre-adder.
2917 wire signed [17:0] PREADDER;
2918 assign B1_IN = OPMODE_OUT[4] ? PREADDER : B0_OUT;
2919 assign PREADDER = OPMODE_OUT[6] ? D_OUT - B0_OUT : D_OUT + B0_OUT;
2920
2921 // The multiplier.
2922 assign M_MULT = A1_OUT * B1_OUT;
2923
2924 // The carry in selection.
2925 assign CARRYIN_IN = (CARRYINSEL == "OPMODE5") ? OPMODE_OUT[5] : CARRYIN;
2926
2927 // The post-adder inputs.
2928 always @* begin
2929 case (OPMODE_OUT[1:0])
2930 2'b00: XMUX <= 0;
2931 2'b01: XMUX <= M;
2932 2'b10: XMUX <= P;
2933 2'b11: XMUX <= {D_OUT[11:0], A1_OUT, B1_OUT};
2934 default: XMUX <= 48'hxxxxxxxxxxxx;
2935 endcase
2936 end
2937
2938 always @* begin
2939 case (OPMODE_OUT[3:2])
2940 2'b00: ZMUX <= 0;
2941 2'b01: ZMUX <= PCIN;
2942 2'b10: ZMUX <= P;
2943 2'b11: ZMUX <= C_OUT;
2944 default: ZMUX <= 48'hxxxxxxxxxxxx;
2945 endcase
2946 end
2947
2948 // The post-adder.
2949 wire signed [48:0] X_EXT;
2950 wire signed [48:0] Z_EXT;
2951 assign X_EXT = {1'b0, XMUX};
2952 assign Z_EXT = {1'b0, ZMUX};
2953 assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
2954
2955 // Cascade outputs.
2956 assign BCOUT = B1_OUT;
2957 assign PCOUT = P;
2958
2959 endmodule
2960
2961 module DSP48 (
2962 input signed [17:0] A,
2963 input signed [17:0] B,
2964 input signed [47:0] C,
2965 input signed [17:0] BCIN,
2966 input signed [47:0] PCIN,
2967 input CARRYIN,
2968 input [6:0] OPMODE,
2969 input SUBTRACT,
2970 input [1:0] CARRYINSEL,
2971 output signed [47:0] P,
2972 output signed [17:0] BCOUT,
2973 output signed [47:0] PCOUT,
2974 (* clkbuf_sink *)
2975 input CLK,
2976 input CEA,
2977 input CEB,
2978 input CEC,
2979 input CEM,
2980 input CECARRYIN,
2981 input CECINSUB,
2982 input CECTRL,
2983 input CEP,
2984 input RSTA,
2985 input RSTB,
2986 input RSTC,
2987 input RSTM,
2988 input RSTCARRYIN,
2989 input RSTCTRL,
2990 input RSTP
2991 );
2992
2993 parameter integer AREG = 1;
2994 parameter integer BREG = 1;
2995 parameter integer CREG = 1;
2996 parameter integer MREG = 1;
2997 parameter integer PREG = 1;
2998 parameter integer CARRYINREG = 1;
2999 parameter integer CARRYINSELREG = 1;
3000 parameter integer OPMODEREG = 1;
3001 parameter integer SUBTRACTREG = 1;
3002 parameter B_INPUT = "DIRECT";
3003 parameter LEGACY_MODE = "MULT18X18S";
3004
3005 wire signed [17:0] A_OUT;
3006 wire signed [17:0] B_OUT;
3007 wire signed [47:0] C_OUT;
3008 wire signed [35:0] M_MULT;
3009 wire signed [35:0] M_OUT;
3010 wire signed [47:0] P_IN;
3011 wire [6:0] OPMODE_OUT;
3012 wire [1:0] CARRYINSEL_OUT;
3013 wire CARRYIN_OUT;
3014 wire SUBTRACT_OUT;
3015 reg INT_CARRYIN_XY;
3016 reg INT_CARRYIN_Z;
3017 reg signed [47:0] XMUX;
3018 reg signed [47:0] YMUX;
3019 wire signed [47:0] XYMUX;
3020 reg signed [47:0] ZMUX;
3021 reg CIN;
3022
3023 // The B input multiplexer.
3024 wire signed [17:0] B_MUX;
3025 assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
3026
3027 // The cascade output.
3028 assign BCOUT = B_OUT;
3029 assign PCOUT = P;
3030
3031 // The registers.
3032 reg signed [17:0] A0_REG;
3033 reg signed [17:0] A1_REG;
3034 reg signed [17:0] B0_REG;
3035 reg signed [17:0] B1_REG;
3036 reg signed [47:0] C_REG;
3037 reg signed [35:0] M_REG;
3038 reg signed [47:0] P_REG;
3039 reg [6:0] OPMODE_REG;
3040 reg [1:0] CARRYINSEL_REG;
3041 reg SUBTRACT_REG;
3042 reg CARRYIN_REG;
3043 reg INT_CARRYIN_XY_REG;
3044
3045 initial begin
3046 A0_REG = 0;
3047 A1_REG = 0;
3048 B0_REG = 0;
3049 B1_REG = 0;
3050 C_REG = 0;
3051 M_REG = 0;
3052 P_REG = 0;
3053 OPMODE_REG = 0;
3054 CARRYINSEL_REG = 0;
3055 SUBTRACT_REG = 0;
3056 CARRYIN_REG = 0;
3057 INT_CARRYIN_XY_REG = 0;
3058 end
3059
3060 always @(posedge CLK) begin
3061 if (RSTA) begin
3062 A0_REG <= 0;
3063 A1_REG <= 0;
3064 end else if (CEA) begin
3065 A0_REG <= A;
3066 A1_REG <= A0_REG;
3067 end
3068 if (RSTB) begin
3069 B0_REG <= 0;
3070 B1_REG <= 0;
3071 end else if (CEB) begin
3072 B0_REG <= B_MUX;
3073 B1_REG <= B0_REG;
3074 end
3075 if (RSTC) begin
3076 C_REG <= 0;
3077 end else if (CEC) begin
3078 C_REG <= C;
3079 end
3080 if (RSTM) begin
3081 M_REG <= 0;
3082 end else if (CEM) begin
3083 M_REG <= M_MULT;
3084 end
3085 if (RSTP) begin
3086 P_REG <= 0;
3087 end else if (CEP) begin
3088 P_REG <= P_IN;
3089 end
3090 if (RSTCTRL) begin
3091 OPMODE_REG <= 0;
3092 CARRYINSEL_REG <= 0;
3093 SUBTRACT_REG <= 0;
3094 end else begin
3095 if (CECTRL) begin
3096 OPMODE_REG <= OPMODE;
3097 CARRYINSEL_REG <= CARRYINSEL;
3098 end
3099 if (CECINSUB)
3100 SUBTRACT_REG <= SUBTRACT;
3101 end
3102 if (RSTCARRYIN) begin
3103 CARRYIN_REG <= 0;
3104 INT_CARRYIN_XY_REG <= 0;
3105 end else begin
3106 if (CECINSUB)
3107 CARRYIN_REG <= CARRYIN;
3108 if (CECARRYIN)
3109 INT_CARRYIN_XY_REG <= INT_CARRYIN_XY;
3110 end
3111 end
3112
3113 // The register enables.
3114 assign A_OUT = (AREG == 2) ? A1_REG : (AREG == 1) ? A0_REG : A;
3115 assign B_OUT = (BREG == 2) ? B1_REG : (BREG == 1) ? B0_REG : B_MUX;
3116 assign C_OUT = (CREG == 1) ? C_REG : C;
3117 assign M_OUT = (MREG == 1) ? M_REG : M_MULT;
3118 assign P = (PREG == 1) ? P_REG : P_IN;
3119 assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
3120 assign SUBTRACT_OUT = (SUBTRACTREG == 1) ? SUBTRACT_REG : SUBTRACT;
3121 assign CARRYINSEL_OUT = (CARRYINSELREG == 1) ? CARRYINSEL_REG : CARRYINSEL;
3122 assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN;
3123
3124 // The multiplier.
3125 assign M_MULT = A_OUT * B_OUT;
3126
3127 // The post-adder inputs.
3128 always @* begin
3129 case (OPMODE_OUT[1:0])
3130 2'b00: XMUX <= 0;
3131 2'b10: XMUX <= P;
3132 2'b11: XMUX <= {{12{A_OUT[17]}}, A_OUT, B_OUT};
3133 default: XMUX <= 48'hxxxxxxxxxxxx;
3134 endcase
3135 case (OPMODE_OUT[1:0])
3136 2'b01: INT_CARRYIN_XY <= A_OUT[17] ~^ B_OUT[17];
3137 2'b11: INT_CARRYIN_XY <= ~A_OUT[17];
3138 // TODO: not tested in hardware.
3139 default: INT_CARRYIN_XY <= A_OUT[17] ~^ B_OUT[17];
3140 endcase
3141 end
3142
3143 always @* begin
3144 case (OPMODE_OUT[3:2])
3145 2'b00: YMUX <= 0;
3146 2'b11: YMUX <= C_OUT;
3147 default: YMUX <= 48'hxxxxxxxxxxxx;
3148 endcase
3149 end
3150
3151 assign XYMUX = (OPMODE_OUT[3:0] == 4'b0101) ? M_OUT : (XMUX + YMUX);
3152
3153 always @* begin
3154 case (OPMODE_OUT[6:4])
3155 3'b000: ZMUX <= 0;
3156 3'b001: ZMUX <= PCIN;
3157 3'b010: ZMUX <= P;
3158 3'b011: ZMUX <= C_OUT;
3159 3'b101: ZMUX <= {{17{PCIN[47]}}, PCIN[47:17]};
3160 3'b110: ZMUX <= {{17{P[47]}}, P[47:17]};
3161 default: ZMUX <= 48'hxxxxxxxxxxxx;
3162 endcase
3163 // TODO: check how all this works on actual hw.
3164 if (OPMODE_OUT[1:0] == 2'b10)
3165 INT_CARRYIN_Z <= ~P[47];
3166 else
3167 case (OPMODE_OUT[6:4])
3168 3'b001: INT_CARRYIN_Z <= ~PCIN[47];
3169 3'b010: INT_CARRYIN_Z <= ~P[47];
3170 3'b101: INT_CARRYIN_Z <= ~PCIN[47];
3171 3'b110: INT_CARRYIN_Z <= ~P[47];
3172 default: INT_CARRYIN_Z <= 1'bx;
3173 endcase
3174 end
3175
3176 always @* begin
3177 case (CARRYINSEL_OUT)
3178 2'b00: CIN <= CARRYIN_OUT;
3179 2'b01: CIN <= INT_CARRYIN_Z;
3180 2'b10: CIN <= INT_CARRYIN_XY;
3181 2'b11: CIN <= INT_CARRYIN_XY_REG;
3182 default: CIN <= 1'bx;
3183 endcase
3184 end
3185
3186 // The post-adder.
3187 assign P_IN = SUBTRACT_OUT ? (ZMUX - (XYMUX + CIN)) : (ZMUX + XYMUX + CIN);
3188
3189 endmodule
3190
3191 // TODO: DSP48E (Virtex 5).
3192
3193 // Virtex 6, Series 7.
3194
3195 `ifdef YOSYS
3196 (* abc9_box=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG)
3197 `ifdef ALLOW_WHITEBOX_DSP48E1
3198 // Do not make DSP48E1 a whitebox for ABC9 even if fully combinatorial, since it is a big complex block
3199 , lib_whitebox=!(PREG || AREG || ADREG || BREG || CREG || DREG || MREG || INMODEREG || OPMODEREG || ALUMODEREG || CARRYINREG || CARRYINSELREG)
3200 `endif
3201 *)
3202 `endif
3203 module DSP48E1 (
3204 output [29:0] ACOUT,
3205 output [17:0] BCOUT,
3206 output reg CARRYCASCOUT,
3207 output reg [3:0] CARRYOUT,
3208 output reg MULTSIGNOUT,
3209 output OVERFLOW,
3210 output reg signed [47:0] P,
3211 output reg PATTERNBDETECT,
3212 output reg PATTERNDETECT,
3213 output [47:0] PCOUT,
3214 output UNDERFLOW,
3215 input signed [29:0] A,
3216 input [29:0] ACIN,
3217 input [3:0] ALUMODE,
3218 input signed [17:0] B,
3219 input [17:0] BCIN,
3220 input [47:0] C,
3221 input CARRYCASCIN,
3222 input CARRYIN,
3223 input [2:0] CARRYINSEL,
3224 input CEA1,
3225 input CEA2,
3226 input CEAD,
3227 input CEALUMODE,
3228 input CEB1,
3229 input CEB2,
3230 input CEC,
3231 input CECARRYIN,
3232 input CECTRL,
3233 input CED,
3234 input CEINMODE,
3235 input CEM,
3236 input CEP,
3237 (* clkbuf_sink *) input CLK,
3238 input [24:0] D,
3239 input [4:0] INMODE,
3240 input MULTSIGNIN,
3241 input [6:0] OPMODE,
3242 input [47:0] PCIN,
3243 input RSTA,
3244 input RSTALLCARRYIN,
3245 input RSTALUMODE,
3246 input RSTB,
3247 input RSTC,
3248 input RSTCTRL,
3249 input RSTD,
3250 input RSTINMODE,
3251 input RSTM,
3252 input RSTP
3253 );
3254 parameter integer ACASCREG = 1;
3255 parameter integer ADREG = 1;
3256 parameter integer ALUMODEREG = 1;
3257 parameter integer AREG = 1;
3258 parameter AUTORESET_PATDET = "NO_RESET";
3259 parameter A_INPUT = "DIRECT";
3260 parameter integer BCASCREG = 1;
3261 parameter integer BREG = 1;
3262 parameter B_INPUT = "DIRECT";
3263 parameter integer CARRYINREG = 1;
3264 parameter integer CARRYINSELREG = 1;
3265 parameter integer CREG = 1;
3266 parameter integer DREG = 1;
3267 parameter integer INMODEREG = 1;
3268 parameter integer MREG = 1;
3269 parameter integer OPMODEREG = 1;
3270 parameter integer PREG = 1;
3271 parameter SEL_MASK = "MASK";
3272 parameter SEL_PATTERN = "PATTERN";
3273 parameter USE_DPORT = "FALSE";
3274 parameter USE_MULT = "MULTIPLY";
3275 parameter USE_PATTERN_DETECT = "NO_PATDET";
3276 parameter USE_SIMD = "ONE48";
3277 parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
3278 parameter [47:0] PATTERN = 48'h000000000000;
3279 parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
3280 parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
3281 parameter [0:0] IS_CLK_INVERTED = 1'b0;
3282 parameter [4:0] IS_INMODE_INVERTED = 5'b0;
3283 parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
3284
3285 `ifdef YOSYS
3286 function integer \A.required ;
3287 begin
3288 if (AREG != 0) \A.required = 254;
3289 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
3290 if (MREG != 0) \A.required = 1416;
3291 else if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3030 : 2739) ;
3292 end
3293 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
3294 // Worst-case from ADREG and MREG
3295 if (MREG != 0) \A.required = 2400;
3296 else if (ADREG != 0) \A.required = 1283;
3297 else if (PREG != 0) \A.required = 3723;
3298 else if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 4014 : 3723) ;
3299 end
3300 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
3301 if (PREG != 0) \A.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1730 : 1441) ;
3302 end
3303 end
3304 endfunction
3305 function integer \B.required ;
3306 begin
3307 if (BREG != 0) \B.required = 324;
3308 else if (MREG != 0) \B.required = 1285;
3309 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
3310 if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
3311 end
3312 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
3313 if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 2898 : 2608) ;
3314 end
3315 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
3316 if (PREG != 0) \B.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1718 : 1428) ;
3317 end
3318 end
3319 endfunction
3320 function integer \C.required ;
3321 begin
3322 if (CREG != 0) \C.required = 168;
3323 else if (PREG != 0) \C.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 1534 : 1244) ;
3324 end
3325 endfunction
3326 function integer \D.required ;
3327 begin
3328 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
3329 end
3330 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
3331 if (DREG != 0) \D.required = 248;
3332 else if (ADREG != 0) \D.required = 1195;
3333 else if (MREG != 0) \D.required = 2310;
3334 else if (PREG != 0) \D.required = (USE_PATTERN_DETECT != "NO_PATDET" ? 3925 : 3635) ;
3335 end
3336 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
3337 end
3338 end
3339 endfunction
3340 function integer \P.arrival ;
3341 begin
3342 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
3343 if (PREG != 0) \P.arrival = 329;
3344 // Worst-case from CREG and MREG
3345 else if (CREG != 0) \P.arrival = 1687;
3346 else if (MREG != 0) \P.arrival = 1671;
3347 // Worst-case from AREG and BREG
3348 else if (AREG != 0) \P.arrival = 2952;
3349 else if (BREG != 0) \P.arrival = 2813;
3350 end
3351 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
3352 if (PREG != 0) \P.arrival = 329;
3353 // Worst-case from CREG and MREG
3354 else if (CREG != 0) \P.arrival = 1687;
3355 else if (MREG != 0) \P.arrival = 1671;
3356 // Worst-case from AREG, ADREG, BREG, DREG
3357 else if (AREG != 0) \P.arrival = 3935;
3358 else if (DREG != 0) \P.arrival = 3908;
3359 else if (ADREG != 0) \P.arrival = 2958;
3360 else if (BREG != 0) \P.arrival = 2813;
3361 end
3362 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
3363 if (PREG != 0) \P.arrival = 329;
3364 // Worst-case from AREG, BREG, CREG
3365 else if (CREG != 0) \P.arrival = 1687;
3366 else if (AREG != 0) \P.arrival = 1632;
3367 else if (BREG != 0) \P.arrival = 1616;
3368 end
3369 end
3370 endfunction
3371 function integer \PCOUT.arrival ;
3372 begin
3373 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
3374 if (PREG != 0) \PCOUT.arrival = 435;
3375 // Worst-case from CREG and MREG
3376 else if (CREG != 0) \PCOUT.arrival = 1835;
3377 else if (MREG != 0) \PCOUT.arrival = 1819;
3378 // Worst-case from AREG and BREG
3379 else if (AREG != 0) \PCOUT.arrival = 3098;
3380 else if (BREG != 0) \PCOUT.arrival = 2960;
3381 end
3382 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
3383 if (PREG != 0) \PCOUT.arrival = 435;
3384 // Worst-case from CREG and MREG
3385 else if (CREG != 0) \PCOUT.arrival = 1835;
3386 else if (MREG != 0) \PCOUT.arrival = 1819;
3387 // Worst-case from AREG, ADREG, BREG, DREG
3388 else if (AREG != 0) \PCOUT.arrival = 4083;
3389 else if (DREG != 0) \PCOUT.arrival = 4056;
3390 else if (BREG != 0) \PCOUT.arrival = 2960;
3391 else if (ADREG != 0) \PCOUT.arrival = 2859;
3392 end
3393 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
3394 if (PREG != 0) \PCOUT.arrival = 435;
3395 // Worst-case from AREG, BREG, CREG
3396 else if (CREG != 0) \PCOUT.arrival = 1835;
3397 else if (AREG != 0) \PCOUT.arrival = 1780;
3398 else if (BREG != 0) \PCOUT.arrival = 1765;
3399 end
3400 end
3401 endfunction
3402 function integer \A.P.comb ;
3403 begin
3404 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.P.comb = 2823;
3405 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.P.comb = 3806;
3406 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.P.comb = 1523;
3407 end
3408 endfunction
3409 function integer \A.PCOUT.comb ;
3410 begin
3411 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \A.PCOUT.comb = 2970;
3412 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \A.PCOUT.comb = 3954;
3413 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \A.PCOUT.comb = 1671;
3414 end
3415 endfunction
3416 function integer \B.P.comb ;
3417 begin
3418 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.P.comb = 2690;
3419 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.P.comb = 2690;
3420 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.P.comb = 1509;
3421 end
3422 endfunction
3423 function integer \B.PCOUT.comb ;
3424 begin
3425 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \B.PCOUT.comb = 2838;
3426 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \B.PCOUT.comb = 2838;
3427 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \B.PCOUT.comb = 1658;
3428 end
3429 endfunction
3430 function integer \C.P.comb ;
3431 begin
3432 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.P.comb = 1325;
3433 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.P.comb = 1325;
3434 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.P.comb = 1325;
3435 end
3436 endfunction
3437 function integer \C.PCOUT.comb ;
3438 begin
3439 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
3440 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \C.PCOUT.comb = 1474;
3441 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") \C.PCOUT.comb = 1474;
3442 end
3443 endfunction
3444 function integer \D.P.comb ;
3445 begin
3446 if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.P.comb = 3717;
3447 end
3448 endfunction
3449 function integer \D.PCOUT.comb ;
3450 begin
3451 if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") \D.PCOUT.comb = 3700;
3452 end
3453 endfunction
3454
3455 generate
3456 if (PREG == 0 && MREG == 0 && AREG == 0 && ADREG == 0)
3457 specify
3458 (A *> P) = \A.P.comb ();
3459 (A *> PCOUT) = \A.PCOUT.comb ();
3460 endspecify
3461 else
3462 specify
3463 $setup(A, posedge CLK &&& !IS_CLK_INVERTED, \A.required () );
3464 $setup(A, negedge CLK &&& IS_CLK_INVERTED, \A.required () );
3465 endspecify
3466
3467 if (PREG == 0 && MREG == 0 && BREG == 0)
3468 specify
3469 (B *> P) = \B.P.comb ();
3470 (B *> PCOUT) = \B.PCOUT.comb ();
3471 endspecify
3472 else
3473 specify
3474 $setup(B, posedge CLK &&& !IS_CLK_INVERTED, \B.required () );
3475 $setup(B, negedge CLK &&& IS_CLK_INVERTED, \B.required () );
3476 endspecify
3477
3478 if (PREG == 0 && CREG == 0)
3479 specify
3480 (C *> P) = \C.P.comb ();
3481 (C *> PCOUT) = \C.PCOUT.comb ();
3482 endspecify
3483 else
3484 specify
3485 $setup(C, posedge CLK &&& !IS_CLK_INVERTED, \C.required () );
3486 $setup(C, negedge CLK &&& IS_CLK_INVERTED, \C.required () );
3487 endspecify
3488
3489 if (PREG == 0 && MREG == 0 && ADREG == 0 && DREG == 0)
3490 specify
3491 (D *> P) = \D.P.comb ();
3492 (D *> PCOUT) = \D.PCOUT.comb ();
3493 endspecify
3494 else
3495 specify
3496 $setup(D, posedge CLK &&& !IS_CLK_INVERTED, \D.required () );
3497 $setup(D, negedge CLK &&& IS_CLK_INVERTED, \D.required () );
3498 endspecify
3499
3500 if (PREG == 0)
3501 specify
3502 (PCIN *> P) = 1107;
3503 (PCIN *> PCOUT) = 1255;
3504 endspecify
3505 else
3506 specify
3507 $setup(PCIN, posedge CLK &&& !IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025);
3508 $setup(PCIN, negedge CLK &&& IS_CLK_INVERTED, USE_PATTERN_DETECT != "NO_PATDET" ? 1315 : 1025);
3509 endspecify
3510
3511 if (PREG || AREG || ADREG || BREG || CREG || DREG || MREG)
3512 specify
3513 if (!IS_CLK_INVERTED && CEP) (posedge CLK => (P : 48'bx)) = \P.arrival () ;
3514 if ( IS_CLK_INVERTED && CEP) (negedge CLK => (P : 48'bx)) = \P.arrival () ;
3515 if (!IS_CLK_INVERTED && CEP) (posedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ;
3516 if ( IS_CLK_INVERTED && CEP) (negedge CLK => (PCOUT : 48'bx)) = \PCOUT.arrival () ;
3517 endspecify
3518 endgenerate
3519 `endif
3520
3521 initial begin
3522 `ifndef YOSYS
3523 if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
3524 if (SEL_MASK != "MASK") $fatal(1, "Unsupported SEL_MASK value");
3525 if (SEL_PATTERN != "PATTERN") $fatal(1, "Unsupported SEL_PATTERN value");
3526 if (USE_SIMD != "ONE48" && USE_SIMD != "TWO24" && USE_SIMD != "FOUR12") $fatal(1, "Unsupported USE_SIMD value");
3527 if (IS_ALUMODE_INVERTED != 4'b0) $fatal(1, "Unsupported IS_ALUMODE_INVERTED value");
3528 if (IS_CARRYIN_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CARRYIN_INVERTED value");
3529 if (IS_CLK_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CLK_INVERTED value");
3530 if (IS_INMODE_INVERTED != 5'b0) $fatal(1, "Unsupported IS_INMODE_INVERTED value");
3531 if (IS_OPMODE_INVERTED != 7'b0) $fatal(1, "Unsupported IS_OPMODE_INVERTED value");
3532 `endif
3533 end
3534
3535 wire signed [29:0] A_muxed;
3536 wire signed [17:0] B_muxed;
3537
3538 generate
3539 if (A_INPUT == "CASCADE") assign A_muxed = ACIN;
3540 else assign A_muxed = A;
3541
3542 if (B_INPUT == "CASCADE") assign B_muxed = BCIN;
3543 else assign B_muxed = B;
3544 endgenerate
3545
3546 reg signed [29:0] Ar1, Ar2;
3547 reg signed [24:0] Dr;
3548 reg signed [17:0] Br1, Br2;
3549 reg signed [47:0] Cr;
3550 reg [4:0] INMODEr;
3551 reg [6:0] OPMODEr;
3552 reg [3:0] ALUMODEr;
3553 reg [2:0] CARRYINSELr;
3554
3555 generate
3556 // Configurable A register
3557 if (AREG == 2) begin
3558 initial Ar1 = 30'b0;
3559 initial Ar2 = 30'b0;
3560 always @(posedge CLK)
3561 if (RSTA) begin
3562 Ar1 <= 30'b0;
3563 Ar2 <= 30'b0;
3564 end else begin
3565 if (CEA1) Ar1 <= A_muxed;
3566 if (CEA2) Ar2 <= Ar1;
3567 end
3568 end else if (AREG == 1) begin
3569 //initial Ar1 = 30'b0;
3570 initial Ar2 = 30'b0;
3571 always @(posedge CLK)
3572 if (RSTA) begin
3573 Ar1 <= 30'b0;
3574 Ar2 <= 30'b0;
3575 end else begin
3576 if (CEA1) Ar1 <= A_muxed;
3577 if (CEA2) Ar2 <= A_muxed;
3578 end
3579 end else begin
3580 always @* Ar1 <= A_muxed;
3581 always @* Ar2 <= A_muxed;
3582 end
3583
3584 // Configurable B register
3585 if (BREG == 2) begin
3586 initial Br1 = 25'b0;
3587 initial Br2 = 25'b0;
3588 always @(posedge CLK)
3589 if (RSTB) begin
3590 Br1 <= 18'b0;
3591 Br2 <= 18'b0;
3592 end else begin
3593 if (CEB1) Br1 <= B_muxed;
3594 if (CEB2) Br2 <= Br1;
3595 end
3596 end else if (BREG == 1) begin
3597 //initial Br1 = 18'b0;
3598 initial Br2 = 18'b0;
3599 always @(posedge CLK)
3600 if (RSTB) begin
3601 Br1 <= 18'b0;
3602 Br2 <= 18'b0;
3603 end else begin
3604 if (CEB1) Br1 <= B_muxed;
3605 if (CEB2) Br2 <= B_muxed;
3606 end
3607 end else begin
3608 always @* Br1 <= B_muxed;
3609 always @* Br2 <= B_muxed;
3610 end
3611
3612 // C and D registers
3613 if (CREG == 1) initial Cr = 48'b0;
3614 if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end
3615 else always @* Cr <= C;
3616
3617 if (CREG == 1) initial Dr = 25'b0;
3618 if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
3619 else always @* Dr <= D;
3620
3621 // Control registers
3622 if (INMODEREG == 1) initial INMODEr = 5'b0;
3623 if (INMODEREG == 1) begin always @(posedge CLK) if (RSTINMODE) INMODEr <= 5'b0; else if (CEINMODE) INMODEr <= INMODE; end
3624 else always @* INMODEr <= INMODE;
3625 if (OPMODEREG == 1) initial OPMODEr = 7'b0;
3626 if (OPMODEREG == 1) begin always @(posedge CLK) if (RSTCTRL) OPMODEr <= 7'b0; else if (CECTRL) OPMODEr <= OPMODE; end
3627 else always @* OPMODEr <= OPMODE;
3628 if (ALUMODEREG == 1) initial ALUMODEr = 4'b0;
3629 if (ALUMODEREG == 1) begin always @(posedge CLK) if (RSTALUMODE) ALUMODEr <= 4'b0; else if (CEALUMODE) ALUMODEr <= ALUMODE; end
3630 else always @* ALUMODEr <= ALUMODE;
3631 if (CARRYINSELREG == 1) initial CARRYINSELr = 3'b0;
3632 if (CARRYINSELREG == 1) begin always @(posedge CLK) if (RSTCTRL) CARRYINSELr <= 3'b0; else if (CECTRL) CARRYINSELr <= CARRYINSEL; end
3633 else always @* CARRYINSELr <= CARRYINSEL;
3634 endgenerate
3635
3636 // A and B cascade
3637 generate
3638 if (ACASCREG == 1 && AREG == 2) assign ACOUT = Ar1;
3639 else assign ACOUT = Ar2;
3640 if (BCASCREG == 1 && BREG == 2) assign BCOUT = Br1;
3641 else assign BCOUT = Br2;
3642 endgenerate
3643
3644 // A/D input selection and pre-adder
3645 wire signed [24:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2;
3646 wire signed [24:0] Ar12_gated = INMODEr[1] ? 25'b0 : Ar12_muxed;
3647 wire signed [24:0] Dr_gated = INMODEr[2] ? Dr : 25'b0;
3648 wire signed [24:0] AD_result = INMODEr[3] ? (Dr_gated - Ar12_gated) : (Dr_gated + Ar12_gated);
3649 reg signed [24:0] ADr;
3650
3651 generate
3652 if (ADREG == 1) initial ADr = 25'b0;
3653 if (ADREG == 1) begin always @(posedge CLK) if (RSTD) ADr <= 25'b0; else if (CEAD) ADr <= AD_result; end
3654 else always @* ADr <= AD_result;
3655 endgenerate
3656
3657 // 25x18 multiplier
3658 wire signed [24:0] A_MULT;
3659 wire signed [17:0] B_MULT = INMODEr[4] ? Br1 : Br2;
3660 generate
3661 if (USE_DPORT == "TRUE") assign A_MULT = ADr;
3662 else assign A_MULT = Ar12_gated;
3663 endgenerate
3664
3665 wire signed [42:0] M = A_MULT * B_MULT;
3666 wire signed [42:0] Mx = (CARRYINSEL == 3'b010) ? 43'bx : M;
3667 reg signed [42:0] Mr = 43'b0;
3668
3669 // Multiplier result register
3670 generate
3671 if (MREG == 1) begin always @(posedge CLK) if (RSTM) Mr <= 43'b0; else if (CEM) Mr <= Mx; end
3672 else always @* Mr <= Mx;
3673 endgenerate
3674
3675 wire signed [42:0] Mrx = (CARRYINSELr == 3'b010) ? 43'bx : Mr;
3676
3677 // X, Y and Z ALU inputs
3678 reg signed [47:0] X, Y, Z;
3679
3680 always @* begin
3681 // X multiplexer
3682 case (OPMODEr[1:0])
3683 2'b00: X = 48'b0;
3684 2'b01: begin X = $signed(Mrx);
3685 `ifndef YOSYS
3686 if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
3687 `endif
3688 end
3689 2'b10:
3690 if (PREG == 1)
3691 X = P;
3692 else begin
3693 X = 48'bx;
3694 `ifndef YOSYS
3695 $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10");
3696 `endif
3697 end
3698 2'b11: X = $signed({Ar2, Br2});
3699 default: X = 48'bx;
3700 endcase
3701
3702 // Y multiplexer
3703 case (OPMODEr[3:2])
3704 2'b00: Y = 48'b0;
3705 2'b01: begin Y = 48'b0; // FIXME: more accurate partial product modelling?
3706 `ifndef YOSYS
3707 if (OPMODEr[1:0] != 2'b01) $fatal(1, "OPMODEr[1:0] must be 2'b01 when OPMODEr[3:2] is 2'b01");
3708 `endif
3709 end
3710 2'b10: Y = {48{1'b1}};
3711 2'b11: Y = Cr;
3712 default: Y = 48'bx;
3713 endcase
3714
3715 // Z multiplexer
3716 case (OPMODEr[6:4])
3717 3'b000: Z = 48'b0;
3718 3'b001: Z = PCIN;
3719 3'b010:
3720 if (PREG == 1)
3721 Z = P;
3722 else begin
3723 Z = 48'bx;
3724 `ifndef YOSYS
3725 $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b010");
3726 `endif
3727 end
3728 3'b011: Z = Cr;
3729 3'b100:
3730 if (PREG == 1 && OPMODEr[3:0] === 4'b1000)
3731 Z = P;
3732 else begin
3733 Z = 48'bx;
3734 `ifndef YOSYS
3735 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
3736 if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100");
3737 `endif
3738 end
3739 3'b101: Z = $signed(PCIN[47:17]);
3740 3'b110:
3741 if (PREG == 1)
3742 Z = $signed(P[47:17]);
3743 else begin
3744 Z = 48'bx;
3745 `ifndef YOSYS
3746 $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b110");
3747 `endif
3748 end
3749 default: Z = 48'bx;
3750 endcase
3751 end
3752
3753 // Carry in
3754 wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
3755 reg CARRYINr, A24_xnor_B17;
3756 generate
3757 if (CARRYINREG == 1) initial CARRYINr = 1'b0;
3758 if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
3759 else always @* CARRYINr = CARRYIN;
3760
3761 if (MREG == 1) initial A24_xnor_B17 = 1'b0;
3762 if (MREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) A24_xnor_B17 <= 1'b0; else if (CEM) A24_xnor_B17 <= A24_xnor_B17d; end
3763 else always @* A24_xnor_B17 = A24_xnor_B17d;
3764 endgenerate
3765
3766 reg cin_muxed;
3767
3768 always @(*) begin
3769 case (CARRYINSELr)
3770 3'b000: cin_muxed = CARRYINr;
3771 3'b001: cin_muxed = ~PCIN[47];
3772 3'b010: cin_muxed = CARRYCASCIN;
3773 3'b011: cin_muxed = PCIN[47];
3774 3'b100:
3775 if (PREG == 1)
3776 cin_muxed = CARRYCASCOUT;
3777 else begin
3778 cin_muxed = 1'bx;
3779 `ifndef YOSYS
3780 $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b100");
3781 `endif
3782 end
3783 3'b101:
3784 if (PREG == 1)
3785 cin_muxed = ~P[47];
3786 else begin
3787 cin_muxed = 1'bx;
3788 `ifndef YOSYS
3789 $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b101");
3790 `endif
3791 end
3792 3'b110: cin_muxed = A24_xnor_B17;
3793 3'b111:
3794 if (PREG == 1)
3795 cin_muxed = P[47];
3796 else begin
3797 cin_muxed = 1'bx;
3798 `ifndef YOSYS
3799 $fatal(1, "PREG must be 1 when CARRYINSEL is 3'b111");
3800 `endif
3801 end
3802 default: cin_muxed = 1'bx;
3803 endcase
3804 end
3805
3806 wire alu_cin = (ALUMODEr[3] || ALUMODEr[2]) ? 1'b0 : cin_muxed;
3807
3808 // ALU core
3809 wire [47:0] Z_muxinv = ALUMODEr[0] ? ~Z : Z;
3810 wire [47:0] xor_xyz = X ^ Y ^ Z_muxinv;
3811 wire [47:0] maj_xyz = (X & Y) | (X & Z_muxinv) | (Y & Z_muxinv);
3812
3813 wire [47:0] xor_xyz_muxed = ALUMODEr[3] ? maj_xyz : xor_xyz;
3814 wire [47:0] maj_xyz_gated = ALUMODEr[2] ? 48'b0 : maj_xyz;
3815
3816 wire [48:0] maj_xyz_simd_gated;
3817 wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
3818 wire [47:0] alu_sum;
3819 assign int_carry_in[0] = 1'b0;
3820 wire [3:0] carryout_reset;
3821
3822 generate
3823 if (USE_SIMD == "FOUR12") begin
3824 assign maj_xyz_simd_gated = {
3825 maj_xyz_gated[47:36],
3826 1'b0, maj_xyz_gated[34:24],
3827 1'b0, maj_xyz_gated[22:12],
3828 1'b0, maj_xyz_gated[10:0],
3829 alu_cin
3830 };
3831 assign int_carry_in[3:1] = 3'b000;
3832 assign ext_carry_out = {
3833 int_carry_out[3],
3834 maj_xyz_gated[35] ^ int_carry_out[2],
3835 maj_xyz_gated[23] ^ int_carry_out[1],
3836 maj_xyz_gated[11] ^ int_carry_out[0]
3837 };
3838 assign carryout_reset = 4'b0000;
3839 end else if (USE_SIMD == "TWO24") begin
3840 assign maj_xyz_simd_gated = {
3841 maj_xyz_gated[47:24],
3842 1'b0, maj_xyz_gated[22:0],
3843 alu_cin
3844 };
3845 assign int_carry_in[3:1] = {int_carry_out[2], 1'b0, int_carry_out[0]};
3846 assign ext_carry_out = {
3847 int_carry_out[3],
3848 1'bx,
3849 maj_xyz_gated[23] ^ int_carry_out[1],
3850 1'bx
3851 };
3852 assign carryout_reset = 4'b0x0x;
3853 end else begin
3854 assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
3855 assign int_carry_in[3:1] = int_carry_out[2:0];
3856 assign ext_carry_out = {
3857 int_carry_out[3],
3858 3'bxxx
3859 };
3860 assign carryout_reset = 4'b0xxx;
3861 end
3862
3863 genvar i;
3864 for (i = 0; i < 4; i = i + 1)
3865 assign {int_carry_out[i], alu_sum[i*12 +: 12]} = {1'b0, maj_xyz_simd_gated[i*12 +: ((i == 3) ? 13 : 12)]}
3866 + xor_xyz_muxed[i*12 +: 12] + int_carry_in[i];
3867 endgenerate
3868
3869 wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
3870 wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
3871 ((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
3872 wire CARRYCASCOUTd = ext_carry_out[3];
3873 wire MULTSIGNOUTd = Mrx[42];
3874
3875 generate
3876 if (PREG == 1) begin
3877 initial P = 48'b0;
3878 initial CARRYOUT = carryout_reset;
3879 initial CARRYCASCOUT = 1'b0;
3880 initial MULTSIGNOUT = 1'b0;
3881 always @(posedge CLK)
3882 if (RSTP) begin
3883 P <= 48'b0;
3884 CARRYOUT <= carryout_reset;
3885 CARRYCASCOUT <= 1'b0;
3886 MULTSIGNOUT <= 1'b0;
3887 end else if (CEP) begin
3888 P <= Pd;
3889 CARRYOUT <= CARRYOUTd;
3890 CARRYCASCOUT <= CARRYCASCOUTd;
3891 MULTSIGNOUT <= MULTSIGNOUTd;
3892 end
3893 end else begin
3894 always @* begin
3895 P = Pd;
3896 CARRYOUT = CARRYOUTd;
3897 CARRYCASCOUT = CARRYCASCOUTd;
3898 MULTSIGNOUT = MULTSIGNOUTd;
3899 end
3900 end
3901 endgenerate
3902
3903 assign PCOUT = P;
3904
3905 generate
3906 wire PATTERNDETECTd, PATTERNBDETECTd;
3907
3908 if (USE_PATTERN_DETECT == "PATDET") begin
3909 // TODO: Support SEL_PATTERN != "PATTERN" and SEL_MASK != "MASK
3910 assign PATTERNDETECTd = &(~(Pd ^ PATTERN) | MASK);
3911 assign PATTERNBDETECTd = &((Pd ^ PATTERN) | MASK);
3912 end else begin
3913 assign PATTERNDETECTd = 1'b1;
3914 assign PATTERNBDETECTd = 1'b1;
3915 end
3916
3917 if (PREG == 1) begin
3918 reg PATTERNDETECTPAST, PATTERNBDETECTPAST;
3919 initial PATTERNDETECT = 1'b0;
3920 initial PATTERNBDETECT = 1'b0;
3921 initial PATTERNDETECTPAST = 1'b0;
3922 initial PATTERNBDETECTPAST = 1'b0;
3923 always @(posedge CLK)
3924 if (RSTP) begin
3925 PATTERNDETECT <= 1'b0;
3926 PATTERNBDETECT <= 1'b0;
3927 PATTERNDETECTPAST <= 1'b0;
3928 PATTERNBDETECTPAST <= 1'b0;
3929 end else if (CEP) begin
3930 PATTERNDETECT <= PATTERNDETECTd;
3931 PATTERNBDETECT <= PATTERNBDETECTd;
3932 PATTERNDETECTPAST <= PATTERNDETECT;
3933 PATTERNBDETECTPAST <= PATTERNBDETECT;
3934 end
3935 assign OVERFLOW = &{PATTERNDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
3936 assign UNDERFLOW = &{PATTERNBDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
3937 end else begin
3938 always @* begin
3939 PATTERNDETECT = PATTERNDETECTd;
3940 PATTERNBDETECT = PATTERNBDETECTd;
3941 end
3942 assign OVERFLOW = 1'bx, UNDERFLOW = 1'bx;
3943 end
3944 endgenerate
3945
3946 endmodule
3947
3948 // TODO: DSP48E2 (Ultrascale).
3949
3950 // Block RAM
3951
3952 module RAMB18E1 (
3953 (* clkbuf_sink *)
3954 (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
3955 input CLKARDCLK,
3956 (* clkbuf_sink *)
3957 (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
3958 input CLKBWRCLK,
3959 (* invertible_pin = "IS_ENARDEN_INVERTED" *)
3960 input ENARDEN,
3961 (* invertible_pin = "IS_ENBWREN_INVERTED" *)
3962 input ENBWREN,
3963 input REGCEAREGCE,
3964 input REGCEB,
3965 (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
3966 input RSTRAMARSTRAM,
3967 (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
3968 input RSTRAMB,
3969 (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
3970 input RSTREGARSTREG,
3971 (* invertible_pin = "IS_RSTREGB_INVERTED" *)
3972 input RSTREGB,
3973 input [13:0] ADDRARDADDR,
3974 input [13:0] ADDRBWRADDR,
3975 input [15:0] DIADI,
3976 input [15:0] DIBDI,
3977 input [1:0] DIPADIP,
3978 input [1:0] DIPBDIP,
3979 input [1:0] WEA,
3980 input [3:0] WEBWE,
3981 output [15:0] DOADO,
3982 output [15:0] DOBDO,
3983 output [1:0] DOPADOP,
3984 output [1:0] DOPBDOP
3985 );
3986 parameter integer DOA_REG = 0;
3987 parameter integer DOB_REG = 0;
3988 parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3989 parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3990 parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3991 parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3992 parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3993 parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3994 parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3995 parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3996 parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3997 parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3998 parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
3999 parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4000 parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4001 parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4002 parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4003 parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4004 parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4005 parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4006 parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4007 parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4008 parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4009 parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4010 parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4011 parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4012 parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4013 parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4014 parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4015 parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4016 parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4017 parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4018 parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4019 parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4020 parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4021 parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4022 parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4023 parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4024 parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4025 parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4026 parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4027 parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4028 parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4029 parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4030 parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4031 parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4032 parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4033 parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4034 parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4035 parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4036 parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4037 parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4038 parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4039 parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4040 parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4041 parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4042 parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4043 parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4044 parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4045 parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4046 parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4047 parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4048 parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4049 parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4050 parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4051 parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4052 parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4053 parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4054 parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4055 parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4056 parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4057 parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4058 parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4059 parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4060 parameter INIT_A = 18'h0;
4061 parameter INIT_B = 18'h0;
4062 parameter INIT_FILE = "NONE";
4063 parameter RAM_MODE = "TDP";
4064 parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
4065 parameter integer READ_WIDTH_A = 0;
4066 parameter integer READ_WIDTH_B = 0;
4067 parameter RSTREG_PRIORITY_A = "RSTREG";
4068 parameter RSTREG_PRIORITY_B = "RSTREG";
4069 parameter SIM_COLLISION_CHECK = "ALL";
4070 parameter SIM_DEVICE = "VIRTEX6";
4071 parameter SRVAL_A = 18'h0;
4072 parameter SRVAL_B = 18'h0;
4073 parameter WRITE_MODE_A = "WRITE_FIRST";
4074 parameter WRITE_MODE_B = "WRITE_FIRST";
4075 parameter integer WRITE_WIDTH_A = 0;
4076 parameter integer WRITE_WIDTH_B = 0;
4077 parameter IS_CLKARDCLK_INVERTED = 1'b0;
4078 parameter IS_CLKBWRCLK_INVERTED = 1'b0;
4079 parameter IS_ENARDEN_INVERTED = 1'b0;
4080 parameter IS_ENBWREN_INVERTED = 1'b0;
4081 parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
4082 parameter IS_RSTRAMB_INVERTED = 1'b0;
4083 parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
4084 parameter IS_RSTREGB_INVERTED = 1'b0;
4085
4086 specify
4087 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
4088 $setup(ADDRARDADDR, posedge CLKARDCLK, 566);
4089 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
4090 $setup(ADDRBWRADDR, posedge CLKBWRCLK, 566);
4091 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
4092 $setup(WEA, posedge CLKARDCLK, 532);
4093 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
4094 $setup(WEBWE, posedge CLKBWRCLK, 532);
4095 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L29
4096 $setup(REGCEAREGCE, posedge CLKARDCLK, 360);
4097 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L31
4098 $setup(RSTREGARSTREG, posedge CLKARDCLK, 342);
4099 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L49
4100 $setup(REGCEB, posedge CLKBWRCLK, 360);
4101 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L59
4102 $setup(RSTREGB, posedge CLKBWRCLK, 342);
4103 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
4104 $setup(DIADI, posedge CLKARDCLK, 737);
4105 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
4106 $setup(DIBDI, posedge CLKBWRCLK, 737);
4107 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
4108 $setup(DIPADIP, posedge CLKARDCLK, 737);
4109 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
4110 $setup(DIPBDIP, posedge CLKBWRCLK, 737);
4111 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
4112 if (&DOA_REG) (posedge CLKARDCLK => (DOADO : 16'bx)) = 2454;
4113 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
4114 if (&DOA_REG) (posedge CLKARDCLK => (DOPADOP : 2'bx)) = 2454;
4115 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L153
4116 if (|DOA_REG) (posedge CLKARDCLK => (DOADO : 16'bx)) = 882;
4117 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L154
4118 if (|DOA_REG) (posedge CLKARDCLK => (DOPADOP : 2'bx)) = 882;
4119 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
4120 if (&DOB_REG) (posedge CLKBWRCLK => (DOBDO : 16'bx)) = 2454;
4121 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
4122 if (&DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 2'bx)) = 2454;
4123 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L173
4124 if (|DOB_REG) (posedge CLKBWRCLK => (DOBDO : 16'bx)) = 882;
4125 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L174
4126 if (|DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 2'bx)) = 882;
4127 endspecify
4128 endmodule
4129
4130 module RAMB36E1 (
4131 output CASCADEOUTA,
4132 output CASCADEOUTB,
4133 output [31:0] DOADO,
4134 output [31:0] DOBDO,
4135 output [3:0] DOPADOP,
4136 output [3:0] DOPBDOP,
4137 output [7:0] ECCPARITY,
4138 output [8:0] RDADDRECC,
4139 output SBITERR,
4140 output DBITERR,
4141 (* invertible_pin = "IS_ENARDEN_INVERTED" *)
4142 input ENARDEN,
4143 (* clkbuf_sink *)
4144 (* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
4145 input CLKARDCLK,
4146 (* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
4147 input RSTRAMARSTRAM,
4148 (* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
4149 input RSTREGARSTREG,
4150 input CASCADEINA,
4151 input REGCEAREGCE,
4152 (* invertible_pin = "IS_ENBWREN_INVERTED" *)
4153 input ENBWREN,
4154 (* clkbuf_sink *)
4155 (* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
4156 input CLKBWRCLK,
4157 (* invertible_pin = "IS_RSTRAMB_INVERTED" *)
4158 input RSTRAMB,
4159 (* invertible_pin = "IS_RSTREGB_INVERTED" *)
4160 input RSTREGB,
4161 input CASCADEINB,
4162 input REGCEB,
4163 input INJECTDBITERR,
4164 input INJECTSBITERR,
4165 input [15:0] ADDRARDADDR,
4166 input [15:0] ADDRBWRADDR,
4167 input [31:0] DIADI,
4168 input [31:0] DIBDI,
4169 input [3:0] DIPADIP,
4170 input [3:0] DIPBDIP,
4171 input [3:0] WEA,
4172 input [7:0] WEBWE
4173 );
4174 parameter integer DOA_REG = 0;
4175 parameter integer DOB_REG = 0;
4176 parameter EN_ECC_READ = "FALSE";
4177 parameter EN_ECC_WRITE = "FALSE";
4178 parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4179 parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4180 parameter INITP_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4181 parameter INITP_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4182 parameter INITP_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4183 parameter INITP_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4184 parameter INITP_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4185 parameter INITP_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4186 parameter INITP_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4187 parameter INITP_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4188 parameter INITP_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4189 parameter INITP_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4190 parameter INITP_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4191 parameter INITP_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4192 parameter INITP_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4193 parameter INITP_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4194 parameter INIT_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4195 parameter INIT_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4196 parameter INIT_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4197 parameter INIT_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4198 parameter INIT_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4199 parameter INIT_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4200 parameter INIT_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4201 parameter INIT_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4202 parameter INIT_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4203 parameter INIT_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4204 parameter INIT_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4205 parameter INIT_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4206 parameter INIT_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4207 parameter INIT_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4208 parameter INIT_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4209 parameter INIT_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4210 parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4211 parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4212 parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4213 parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4214 parameter INIT_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4215 parameter INIT_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4216 parameter INIT_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4217 parameter INIT_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4218 parameter INIT_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4219 parameter INIT_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4220 parameter INIT_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4221 parameter INIT_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4222 parameter INIT_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4223 parameter INIT_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4224 parameter INIT_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4225 parameter INIT_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4226 parameter INIT_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4227 parameter INIT_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4228 parameter INIT_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4229 parameter INIT_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4230 parameter INIT_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4231 parameter INIT_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4232 parameter INIT_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4233 parameter INIT_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4234 parameter INIT_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4235 parameter INIT_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4236 parameter INIT_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4237 parameter INIT_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4238 parameter INIT_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4239 parameter INIT_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4240 parameter INIT_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4241 parameter INIT_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4242 parameter INIT_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4243 parameter INIT_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4244 parameter INIT_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4245 parameter INIT_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4246 parameter INIT_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4247 parameter INIT_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4248 parameter INIT_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4249 parameter INIT_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4250 parameter INIT_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4251 parameter INIT_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4252 parameter INIT_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4253 parameter INIT_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4254 parameter INIT_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4255 parameter INIT_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4256 parameter INIT_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4257 parameter INIT_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4258 parameter INIT_40 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4259 parameter INIT_41 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4260 parameter INIT_42 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4261 parameter INIT_43 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4262 parameter INIT_44 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4263 parameter INIT_45 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4264 parameter INIT_46 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4265 parameter INIT_47 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4266 parameter INIT_48 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4267 parameter INIT_49 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4268 parameter INIT_4A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4269 parameter INIT_4B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4270 parameter INIT_4C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4271 parameter INIT_4D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4272 parameter INIT_4E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4273 parameter INIT_4F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4274 parameter INIT_50 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4275 parameter INIT_51 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4276 parameter INIT_52 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4277 parameter INIT_53 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4278 parameter INIT_54 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4279 parameter INIT_55 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4280 parameter INIT_56 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4281 parameter INIT_57 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4282 parameter INIT_58 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4283 parameter INIT_59 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4284 parameter INIT_5A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4285 parameter INIT_5B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4286 parameter INIT_5C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4287 parameter INIT_5D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4288 parameter INIT_5E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4289 parameter INIT_5F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4290 parameter INIT_60 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4291 parameter INIT_61 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4292 parameter INIT_62 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4293 parameter INIT_63 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4294 parameter INIT_64 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4295 parameter INIT_65 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4296 parameter INIT_66 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4297 parameter INIT_67 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4298 parameter INIT_68 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4299 parameter INIT_69 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4300 parameter INIT_6A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4301 parameter INIT_6B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4302 parameter INIT_6C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4303 parameter INIT_6D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4304 parameter INIT_6E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4305 parameter INIT_6F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4306 parameter INIT_70 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4307 parameter INIT_71 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4308 parameter INIT_72 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4309 parameter INIT_73 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4310 parameter INIT_74 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4311 parameter INIT_75 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4312 parameter INIT_76 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4313 parameter INIT_77 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4314 parameter INIT_78 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4315 parameter INIT_79 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4316 parameter INIT_7A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4317 parameter INIT_7B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4318 parameter INIT_7C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4319 parameter INIT_7D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4320 parameter INIT_7E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4321 parameter INIT_7F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
4322 parameter INIT_A = 36'h0;
4323 parameter INIT_B = 36'h0;
4324 parameter INIT_FILE = "NONE";
4325 parameter RAM_EXTENSION_A = "NONE";
4326 parameter RAM_EXTENSION_B = "NONE";
4327 parameter RAM_MODE = "TDP";
4328 parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE";
4329 parameter integer READ_WIDTH_A = 0;
4330 parameter integer READ_WIDTH_B = 0;
4331 parameter RSTREG_PRIORITY_A = "RSTREG";
4332 parameter RSTREG_PRIORITY_B = "RSTREG";
4333 parameter SIM_COLLISION_CHECK = "ALL";
4334 parameter SIM_DEVICE = "VIRTEX6";
4335 parameter SRVAL_A = 36'h0;
4336 parameter SRVAL_B = 36'h0;
4337 parameter WRITE_MODE_A = "WRITE_FIRST";
4338 parameter WRITE_MODE_B = "WRITE_FIRST";
4339 parameter integer WRITE_WIDTH_A = 0;
4340 parameter integer WRITE_WIDTH_B = 0;
4341 parameter IS_CLKARDCLK_INVERTED = 1'b0;
4342 parameter IS_CLKBWRCLK_INVERTED = 1'b0;
4343 parameter IS_ENARDEN_INVERTED = 1'b0;
4344 parameter IS_ENBWREN_INVERTED = 1'b0;
4345 parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0;
4346 parameter IS_RSTRAMB_INVERTED = 1'b0;
4347 parameter IS_RSTREGARSTREG_INVERTED = 1'b0;
4348 parameter IS_RSTREGB_INVERTED = 1'b0;
4349
4350 specify
4351 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L13
4352 $setup(ADDRARDADDR, posedge CLKARDCLK, 566);
4353 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L17
4354 $setup(ADDRBWRADDR, posedge CLKBWRCLK, 566);
4355 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L19
4356 $setup(WEA, posedge CLKARDCLK, 532);
4357 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L21
4358 $setup(WEBWE, posedge CLKBWRCLK, 532);
4359 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L29
4360 $setup(REGCEAREGCE, posedge CLKARDCLK, 360);
4361 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L31
4362 $setup(RSTREGARSTREG, posedge CLKARDCLK, 342);
4363 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L49
4364 $setup(REGCEB, posedge CLKBWRCLK, 360);
4365 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L59
4366 $setup(RSTREGB, posedge CLKBWRCLK, 342);
4367 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L123
4368 $setup(DIADI, posedge CLKARDCLK, 737);
4369 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L133
4370 $setup(DIBDI, posedge CLKBWRCLK, 737);
4371 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L125
4372 $setup(DIPADIP, posedge CLKARDCLK, 737);
4373 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L135
4374 $setup(DIPBDIP, posedge CLKBWRCLK, 737);
4375 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L143
4376 if (&DOA_REG) (posedge CLKARDCLK => (DOADO : 32'bx)) = 2454;
4377 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L144
4378 if (&DOA_REG) (posedge CLKARDCLK => (DOPADOP : 4'bx)) = 2454;
4379 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L153
4380 if (|DOA_REG) (posedge CLKARDCLK => (DOADO : 32'bx)) = 882;
4381 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L154
4382 if (|DOA_REG) (posedge CLKARDCLK => (DOPADOP : 4'bx)) = 882;
4383 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L163
4384 if (&DOB_REG) (posedge CLKBWRCLK => (DOBDO : 32'bx)) = 2454;
4385 // https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/BRAM_L.sdf#L164
4386 if (&DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 4'bx)) = 2454;
4387 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L173
4388 if (|DOB_REG) (posedge CLKBWRCLK => (DOBDO : 32'bx)) = 882;
4389 // https://github.com/SymbiFlow/prjxray-db/blob/4bc6385ab300b1819848371f508185f57b649a0e/artix7/timings/BRAM_L.sdf#L174
4390 if (|DOB_REG) (posedge CLKBWRCLK => (DOPBDOP : 4'bx)) = 882;
4391 endspecify
4392 endmodule