1/*
2 *  yosys -- Yosys Open SYnthesis Suite
3 *
4 *  Copyright (C) 2012  Claire Xenia Wolf <claire@yosyshq.com>
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
24module VCC(output P);
25  assign P = 1;
26endmodule
27
28module GND(output G);
29  assign G = 0;
30endmodule
31
32module 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
42endmodule
43
44module 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;
53endmodule
54
55module 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
66endmodule
67
68module 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
85endmodule
86
87module 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
101endmodule
102
103module 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
112endmodule
113
114module 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
131parameter [0:0] INIT_OUT = 1'b0;
132parameter PRESELECT_I0 = "FALSE";
133parameter PRESELECT_I1 = "FALSE";
134parameter [0:0] IS_CE0_INVERTED = 1'b0;
135parameter [0:0] IS_CE1_INVERTED = 1'b0;
136parameter [0:0] IS_S0_INVERTED = 1'b0;
137parameter [0:0] IS_S1_INVERTED = 1'b0;
138parameter [0:0] IS_IGNORE0_INVERTED = 1'b0;
139parameter [0:0] IS_IGNORE1_INVERTED = 1'b0;
140
141wire I0_internal = ((CE0 ^ IS_CE0_INVERTED) ? I0 : INIT_OUT);
142wire I1_internal = ((CE1 ^ IS_CE1_INVERTED) ? I1 : INIT_OUT);
143wire S0_true = (S0 ^ IS_S0_INVERTED);
144wire S1_true = (S1 ^ IS_S1_INVERTED);
145
146assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
147
148endmodule
149
150module BUFHCE(
151    (* clkbuf_driver *)
152    output O,
153    input I,
154    (* invertible_pin = "IS_CE_INVERTED" *)
155    input CE);
156
157parameter [0:0] INIT_OUT = 1'b0;
158parameter CE_TYPE = "SYNC";
159parameter [0:0] IS_CE_INVERTED = 1'b0;
160
161assign O = ((CE ^ IS_CE_INVERTED) ? I : INIT_OUT);
162
163endmodule
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
173module INV(
174    (* clkbuf_inv = "I" *)
175    output O,
176    input I
177);
178  assign O = !I;
179  specify
180    (I => O) = 127;
181  endspecify
182endmodule
183
184(* abc9_lut=1 *)
185module 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
191endmodule
192
193(* abc9_lut=2 *)
194module 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
202endmodule
203
204(* abc9_lut=3 *)
205module 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
215endmodule
216
217(* abc9_lut=3 *)
218module 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
230endmodule
231
232(* abc9_lut=3 *)
233module 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
247endmodule
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 *)
253module 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
269endmodule
270
271module 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];
285endmodule
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 *)
290module \$__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
303endmodule
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 *)
308module \$__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
322endmodule
323
324module MUXCY(output O, input CI, DI, S);
325  assign O = S ? CI : DI;
326endmodule
327
328module MUXF5(output O, input I0, I1, S);
329  assign O = S ? I1 : I0;
330endmodule
331
332module MUXF6(output O, input I0, I1, S);
333  assign O = S ? I1 : I0;
334endmodule
335
336(* abc9_box, lib_whitebox *)
337module 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
345endmodule
346
347(* abc9_box, lib_whitebox *)
348module 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
356endmodule
357
358module MUXF9(output O, input I0, I1, S);
359  assign O = S ? I1 : I0;
360endmodule
361
362module XORCY(output O, input CI, LI);
363  assign O = CI ^ LI;
364endmodule
365
366(* abc9_box, lib_whitebox *)
367module 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
436endmodule
437
438module 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];
456endmodule
457
458module ORCY (output O, input CI, I);
459  assign O = CI | I;
460endmodule
461
462module MULT_AND (output LO, input I0, I1);
463  assign LO = I0 & I1;
464endmodule
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 *)
471module 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
509endmodule
510
511(* abc9_flop, lib_whitebox *)
512module 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
533endmodule
534
535(* abc9_flop, lib_whitebox *)
536module 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
574endmodule
575
576(* abc9_flop, lib_whitebox *)
577module 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
599endmodule
600
601module 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;
634endmodule
635
636module 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;
669endmodule
670
671(* abc9_box, lib_whitebox *)
672module 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
718endmodule
719
720(* abc9_box, lib_whitebox *)
721module 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
749endmodule
750
751(* abc9_box, lib_whitebox *)
752module 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
797endmodule
798
799(* abc9_box, lib_whitebox *)
800module 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
828endmodule
829
830module 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;
873endmodule
874
875module 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;
918endmodule
919
920module 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;
940endmodule
941
942module 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;
962endmodule
963
964module 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;
993endmodule
994
995module 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);
1003endmodule
1004
1005module 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);
1013endmodule
1014
1015// LUTRAM.
1016
1017// Single port.
1018
1019module 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;
1035endmodule
1036
1037module 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;
1053endmodule
1054
1055module 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;
1071endmodule
1072
1073module 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;
1089endmodule
1090
1091module 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;
1107endmodule
1108
1109module 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;
1125endmodule
1126
1127module 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;
1143endmodule
1144
1145module 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;
1161endmodule
1162
1163module 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;
1178endmodule
1179
1180module 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;
1195endmodule
1196
1197// Single port, wide.
1198
1199module 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
1222endmodule
1223
1224module 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
1247endmodule
1248
1249module 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
1272endmodule
1273
1274module 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
1305endmodule
1306
1307module 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
1338endmodule
1339
1340module 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
1387endmodule
1388
1389module 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
1436endmodule
1437
1438// Dual port.
1439
1440module 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;
1459endmodule
1460
1461module 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;
1480endmodule
1481
1482(* abc9_box, lib_whitebox *)
1483module 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
1535endmodule
1536
1537(* abc9_box, lib_whitebox *)
1538module 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
1585endmodule
1586
1587(* abc9_box, lib_whitebox *)
1588module 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
1644endmodule
1645
1646module 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
1692endmodule
1693
1694(* abc9_box, lib_whitebox *)
1695module 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
1754endmodule
1755
1756module 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;
1772endmodule
1773
1774// Multi port.
1775
1776(* abc9_box, lib_whitebox *)
1777module 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
1879endmodule
1880
1881module 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
1948endmodule
1949
1950(* abc9_box, lib_whitebox *)
1951module 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
2035endmodule
2036
2037module 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
2104endmodule
2105
2106module 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
2152endmodule
2153
2154module 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
2203endmodule
2204
2205// ROM.
2206
2207module 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}];
2213endmodule
2214
2215module 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}];
2221endmodule
2222
2223module 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}];
2229endmodule
2230
2231module 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}];
2237endmodule
2238
2239module 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}];
2245endmodule
2246
2247// Shift registers.
2248
2249(* abc9_box, lib_whitebox *)
2250module 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
2273endmodule
2274
2275(* abc9_box, lib_whitebox *)
2276module 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
2311endmodule
2312
2313(* abc9_box, lib_whitebox *)
2314module 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
2341endmodule
2342
2343(* abc9_box, lib_whitebox *)
2344module 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
2384endmodule
2385
2386(* abc9_box, lib_whitebox *)
2387module 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
2429endmodule
2430
2431module 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};
2454endmodule
2455
2456// DSP
2457
2458// Virtex 2, Virtex 2 Pro, Spartan 3.
2459
2460// Asynchronous mode.
2461
2462module MULT18X18 (
2463    input signed [17:0] A,
2464    input signed [17:0] B,
2465    output signed [35:0] P
2466);
2467
2468assign P = A * B;
2469
2470endmodule
2471
2472// Synchronous mode.
2473
2474module 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
2484always @(posedge C)
2485	if (R)
2486		P <= 0;
2487	else if (CE)
2488		P <= A * B;
2489
2490endmodule
2491
2492// Spartan 3E, Spartan 3A.
2493
2494module 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
2510parameter integer AREG = 1;
2511parameter integer BREG = 1;
2512parameter B_INPUT = "DIRECT";
2513parameter integer PREG = 1;
2514
2515// The multiplier.
2516wire signed [35:0] P_MULT;
2517wire signed [17:0] A_MULT;
2518wire signed [17:0] B_MULT;
2519assign P_MULT = A_MULT * B_MULT;
2520
2521// The cascade output.
2522assign BCOUT = B_MULT;
2523
2524// The B input multiplexer.
2525wire signed [17:0] B_MUX;
2526assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
2527
2528// The registers.
2529reg signed [17:0] A_REG;
2530reg signed [17:0] B_REG;
2531reg signed [35:0] P_REG;
2532
2533initial begin
2534	A_REG = 0;
2535	B_REG = 0;
2536	P_REG = 0;
2537end
2538
2539always @(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;
2554end
2555
2556// The register enables.
2557assign A_MULT = (AREG == 1) ? A_REG : A;
2558assign B_MULT = (BREG == 1) ? B_REG : B_MUX;
2559assign P = (PREG == 1) ? P_REG : P_MULT;
2560
2561endmodule
2562
2563// Spartan 3A DSP.
2564
2565module 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
2597parameter integer A0REG = 0;
2598parameter integer A1REG = 1;
2599parameter integer B0REG = 0;
2600parameter integer B1REG = 1;
2601parameter integer CREG = 1;
2602parameter integer DREG = 1;
2603parameter integer MREG = 1;
2604parameter integer CARRYINREG = 1;
2605parameter integer OPMODEREG = 1;
2606parameter integer PREG = 1;
2607parameter CARRYINSEL = "CARRYIN";
2608parameter RSTTYPE = "SYNC";
2609
2610// This is a strict subset of Spartan 6 -- reuse its model.
2611
2612/* verilator lint_off PINMISSING */
2613DSP48A1 #(
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
2661endmodule
2662
2663// Spartan 6.
2664
2665module 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
2699parameter integer A0REG = 0;
2700parameter integer A1REG = 1;
2701parameter integer B0REG = 0;
2702parameter integer B1REG = 1;
2703parameter integer CREG = 1;
2704parameter integer DREG = 1;
2705parameter integer MREG = 1;
2706parameter integer CARRYINREG = 1;
2707parameter integer CARRYOUTREG = 1;
2708parameter integer OPMODEREG = 1;
2709parameter integer PREG = 1;
2710parameter CARRYINSEL = "OPMODE5";
2711parameter RSTTYPE = "SYNC";
2712
2713wire signed [35:0] M_MULT;
2714wire signed [47:0] P_IN;
2715wire signed [17:0] A0_OUT;
2716wire signed [17:0] B0_OUT;
2717wire signed [17:0] A1_OUT;
2718wire signed [17:0] B1_OUT;
2719wire signed [17:0] B1_IN;
2720wire signed [47:0] C_OUT;
2721wire signed [17:0] D_OUT;
2722wire signed [7:0] OPMODE_OUT;
2723wire CARRYIN_OUT;
2724wire CARRYOUT_IN;
2725wire CARRYIN_IN;
2726reg signed [47:0] XMUX;
2727reg signed [47:0] ZMUX;
2728
2729// The registers.
2730reg signed [17:0] A0_REG;
2731reg signed [17:0] A1_REG;
2732reg signed [17:0] B0_REG;
2733reg signed [17:0] B1_REG;
2734reg signed [47:0] C_REG;
2735reg signed [17:0] D_REG;
2736reg signed [35:0] M_REG;
2737reg signed [47:0] P_REG;
2738reg [7:0] OPMODE_REG;
2739reg CARRYIN_REG;
2740reg CARRYOUT_REG;
2741
2742initial 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;
2754end
2755
2756generate
2757
2758if (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
2828end 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
2898end
2899
2900endgenerate
2901
2902// The register enables.
2903assign A0_OUT = (A0REG == 1) ? A0_REG : A;
2904assign A1_OUT = (A1REG == 1) ? A1_REG : A0_OUT;
2905assign B0_OUT = (B0REG == 1) ? B0_REG : B;
2906assign B1_OUT = (B1REG == 1) ? B1_REG : B1_IN;
2907assign C_OUT = (CREG == 1) ? C_REG : C;
2908assign D_OUT = (DREG == 1) ? D_REG : D;
2909assign M = (MREG == 1) ? M_REG : M_MULT;
2910assign P = (PREG == 1) ? P_REG : P_IN;
2911assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
2912assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN_IN;
2913assign CARRYOUT = (CARRYOUTREG == 1) ? CARRYOUT_REG : CARRYOUT_IN;
2914assign CARRYOUTF = CARRYOUT;
2915
2916// The pre-adder.
2917wire signed [17:0] PREADDER;
2918assign B1_IN = OPMODE_OUT[4] ? PREADDER : B0_OUT;
2919assign PREADDER = OPMODE_OUT[6] ? D_OUT - B0_OUT : D_OUT + B0_OUT;
2920
2921// The multiplier.
2922assign M_MULT = A1_OUT * B1_OUT;
2923
2924// The carry in selection.
2925assign CARRYIN_IN = (CARRYINSEL == "OPMODE5") ? OPMODE_OUT[5] : CARRYIN;
2926
2927// The post-adder inputs.
2928always @* 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
2936end
2937
2938always @* 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
2946end
2947
2948// The post-adder.
2949wire signed [48:0] X_EXT;
2950wire signed [48:0] Z_EXT;
2951assign X_EXT = {1'b0, XMUX};
2952assign Z_EXT = {1'b0, ZMUX};
2953assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
2954
2955// Cascade outputs.
2956assign BCOUT = B1_OUT;
2957assign PCOUT = P;
2958
2959endmodule
2960
2961module 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
2993parameter integer AREG = 1;
2994parameter integer BREG = 1;
2995parameter integer CREG = 1;
2996parameter integer MREG = 1;
2997parameter integer PREG = 1;
2998parameter integer CARRYINREG = 1;
2999parameter integer CARRYINSELREG = 1;
3000parameter integer OPMODEREG = 1;
3001parameter integer SUBTRACTREG = 1;
3002parameter B_INPUT = "DIRECT";
3003parameter LEGACY_MODE = "MULT18X18S";
3004
3005wire signed [17:0] A_OUT;
3006wire signed [17:0] B_OUT;
3007wire signed [47:0] C_OUT;
3008wire signed [35:0] M_MULT;
3009wire signed [35:0] M_OUT;
3010wire signed [47:0] P_IN;
3011wire [6:0] OPMODE_OUT;
3012wire [1:0] CARRYINSEL_OUT;
3013wire CARRYIN_OUT;
3014wire SUBTRACT_OUT;
3015reg INT_CARRYIN_XY;
3016reg INT_CARRYIN_Z;
3017reg signed [47:0] XMUX;
3018reg signed [47:0] YMUX;
3019wire signed [47:0] XYMUX;
3020reg signed [47:0] ZMUX;
3021reg CIN;
3022
3023// The B input multiplexer.
3024wire signed [17:0] B_MUX;
3025assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
3026
3027// The cascade output.
3028assign BCOUT = B_OUT;
3029assign PCOUT = P;
3030
3031// The registers.
3032reg signed [17:0] A0_REG;
3033reg signed [17:0] A1_REG;
3034reg signed [17:0] B0_REG;
3035reg signed [17:0] B1_REG;
3036reg signed [47:0] C_REG;
3037reg signed [35:0] M_REG;
3038reg signed [47:0] P_REG;
3039reg [6:0] OPMODE_REG;
3040reg [1:0] CARRYINSEL_REG;
3041reg SUBTRACT_REG;
3042reg CARRYIN_REG;
3043reg INT_CARRYIN_XY_REG;
3044
3045initial 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;
3058end
3059
3060always @(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
3111end
3112
3113// The register enables.
3114assign A_OUT = (AREG == 2) ? A1_REG : (AREG == 1) ? A0_REG : A;
3115assign B_OUT = (BREG == 2) ? B1_REG : (BREG == 1) ? B0_REG : B_MUX;
3116assign C_OUT = (CREG == 1) ? C_REG : C;
3117assign M_OUT = (MREG == 1) ? M_REG : M_MULT;
3118assign P = (PREG == 1) ? P_REG : P_IN;
3119assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
3120assign SUBTRACT_OUT = (SUBTRACTREG == 1) ? SUBTRACT_REG : SUBTRACT;
3121assign CARRYINSEL_OUT = (CARRYINSELREG == 1) ? CARRYINSEL_REG : CARRYINSEL;
3122assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN;
3123
3124// The multiplier.
3125assign M_MULT = A_OUT * B_OUT;
3126
3127// The post-adder inputs.
3128always @* 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
3141end
3142
3143always @* 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
3149end
3150
3151assign XYMUX = (OPMODE_OUT[3:0] == 4'b0101) ? M_OUT : (XMUX + YMUX);
3152
3153always @* 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
3174end
3175
3176always @* 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
3184end
3185
3186// The post-adder.
3187assign P_IN = SUBTRACT_OUT ? (ZMUX - (XYMUX + CIN)) : (ZMUX + XYMUX + CIN);
3188
3189endmodule
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
3203module 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
3946endmodule
3947
3948// TODO: DSP48E2 (Ultrascale).
3949
3950// Block RAM
3951
3952module 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
4128endmodule
4129
4130module 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
4392endmodule
4393