FDCE ports to be alphabetical
[yosys.git] / techlibs / xilinx / cells_sim.v
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 */
19
20 // See Xilinx UG953 and UG474 for a description of the cell types below.
21 // http://www.xilinx.com/support/documentation/user_guides/ug474_7Series_CLB.pdf
22 // http://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_4/ug953-vivado-7series-libraries.pdf
23
24 module VCC(output P);
25 assign P = 1;
26 endmodule
27
28 module GND(output G);
29 assign G = 0;
30 endmodule
31
32 module IBUF(
33 output O,
34 (* iopad_external_pin *)
35 input I);
36 parameter IOSTANDARD = "default";
37 parameter IBUF_LOW_PWR = 0;
38 assign O = I;
39 endmodule
40
41 module IBUFG(
42 output O,
43 (* iopad_external_pin *)
44 input I);
45 parameter CAPACITANCE = "DONT_CARE";
46 parameter IBUF_DELAY_VALUE = "0";
47 parameter IBUF_LOW_PWR = "TRUE";
48 parameter IOSTANDARD = "DEFAULT";
49 assign O = I;
50 endmodule
51
52 module OBUF(
53 (* iopad_external_pin *)
54 output O,
55 input I);
56 parameter IOSTANDARD = "default";
57 parameter DRIVE = 12;
58 parameter SLEW = "SLOW";
59 assign O = I;
60 endmodule
61
62 module IOBUF (
63 (* iopad_external_pin *)
64 inout IO,
65 output O,
66 input I,
67 input T
68 );
69 parameter integer DRIVE = 12;
70 parameter IBUF_LOW_PWR = "TRUE";
71 parameter IOSTANDARD = "DEFAULT";
72 parameter SLEW = "SLOW";
73 assign IO = T ? 1'bz : I;
74 assign O = IO;
75 endmodule
76
77 module OBUFT (
78 (* iopad_external_pin *)
79 output O,
80 input I,
81 input T
82 );
83 parameter CAPACITANCE = "DONT_CARE";
84 parameter integer DRIVE = 12;
85 parameter IOSTANDARD = "DEFAULT";
86 parameter SLEW = "SLOW";
87 assign O = T ? 1'bz : I;
88 endmodule
89
90 module BUFG(
91 (* clkbuf_driver *)
92 output O,
93 input I);
94
95 assign O = I;
96 endmodule
97
98 module BUFGCTRL(
99 (* clkbuf_driver *)
100 output O,
101 input I0, input I1,
102 (* invertible_pin = "IS_S0_INVERTED" *)
103 input S0,
104 (* invertible_pin = "IS_S1_INVERTED" *)
105 input S1,
106 (* invertible_pin = "IS_CE0_INVERTED" *)
107 input CE0,
108 (* invertible_pin = "IS_CE1_INVERTED" *)
109 input CE1,
110 (* invertible_pin = "IS_IGNORE0_INVERTED" *)
111 input IGNORE0,
112 (* invertible_pin = "IS_IGNORE1_INVERTED" *)
113 input IGNORE1);
114
115 parameter [0:0] INIT_OUT = 1'b0;
116 parameter PRESELECT_I0 = "FALSE";
117 parameter PRESELECT_I1 = "FALSE";
118 parameter [0:0] IS_CE0_INVERTED = 1'b0;
119 parameter [0:0] IS_CE1_INVERTED = 1'b0;
120 parameter [0:0] IS_S0_INVERTED = 1'b0;
121 parameter [0:0] IS_S1_INVERTED = 1'b0;
122 parameter [0:0] IS_IGNORE0_INVERTED = 1'b0;
123 parameter [0:0] IS_IGNORE1_INVERTED = 1'b0;
124
125 wire I0_internal = ((CE0 ^ IS_CE0_INVERTED) ? I0 : INIT_OUT);
126 wire I1_internal = ((CE1 ^ IS_CE1_INVERTED) ? I1 : INIT_OUT);
127 wire S0_true = (S0 ^ IS_S0_INVERTED);
128 wire S1_true = (S1 ^ IS_S1_INVERTED);
129
130 assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
131
132 endmodule
133
134 module BUFHCE(
135 (* clkbuf_driver *)
136 output O,
137 input I,
138 (* invertible_pin = "IS_CE_INVERTED" *)
139 input CE);
140
141 parameter [0:0] INIT_OUT = 1'b0;
142 parameter CE_TYPE = "SYNC";
143 parameter [0:0] IS_CE_INVERTED = 1'b0;
144
145 assign O = ((CE ^ IS_CE_INVERTED) ? I : INIT_OUT);
146
147 endmodule
148
149 // module OBUFT(output O, input I, T);
150 // assign O = T ? 1'bz : I;
151 // endmodule
152
153 // module IOBUF(inout IO, output O, input I, T);
154 // assign O = IO, IO = T ? 1'bz : I;
155 // endmodule
156
157 module INV(
158 (* clkbuf_inv = "I" *)
159 output O,
160 input I
161 );
162 assign O = !I;
163 endmodule
164
165 module LUT1(output O, input I0);
166 parameter [1:0] INIT = 0;
167 assign O = I0 ? INIT[1] : INIT[0];
168 endmodule
169
170 module LUT2(output O, input I0, I1);
171 parameter [3:0] INIT = 0;
172 wire [ 1: 0] s1 = I1 ? INIT[ 3: 2] : INIT[ 1: 0];
173 assign O = I0 ? s1[1] : s1[0];
174 endmodule
175
176 module LUT3(output O, input I0, I1, I2);
177 parameter [7:0] INIT = 0;
178 wire [ 3: 0] s2 = I2 ? INIT[ 7: 4] : INIT[ 3: 0];
179 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
180 assign O = I0 ? s1[1] : s1[0];
181 endmodule
182
183 module LUT4(output O, input I0, I1, I2, I3);
184 parameter [15:0] INIT = 0;
185 wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0];
186 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
187 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
188 assign O = I0 ? s1[1] : s1[0];
189 endmodule
190
191 module LUT5(output O, input I0, I1, I2, I3, I4);
192 parameter [31:0] INIT = 0;
193 wire [15: 0] s4 = I4 ? INIT[31:16] : INIT[15: 0];
194 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
195 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
196 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
197 assign O = I0 ? s1[1] : s1[0];
198 endmodule
199
200 module LUT6(output O, input I0, I1, I2, I3, I4, I5);
201 parameter [63:0] INIT = 0;
202 wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0];
203 wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0];
204 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
205 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
206 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
207 assign O = I0 ? s1[1] : s1[0];
208 endmodule
209
210 module LUT6_2(output O6, output O5, input I0, I1, I2, I3, I4, I5);
211 parameter [63:0] INIT = 0;
212 wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0];
213 wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0];
214 wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0];
215 wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0];
216 wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0];
217 assign O6 = I0 ? s1[1] : s1[0];
218
219 wire [15: 0] s5_4 = I4 ? INIT[31:16] : INIT[15: 0];
220 wire [ 7: 0] s5_3 = I3 ? s5_4[15: 8] : s5_4[ 7: 0];
221 wire [ 3: 0] s5_2 = I2 ? s5_3[ 7: 4] : s5_3[ 3: 0];
222 wire [ 1: 0] s5_1 = I1 ? s5_2[ 3: 2] : s5_2[ 1: 0];
223 assign O5 = I0 ? s5_1[1] : s5_1[0];
224 endmodule
225
226 module MUXCY(output O, input CI, DI, S);
227 assign O = S ? CI : DI;
228 endmodule
229
230 module MUXF5(output O, input I0, I1, S);
231 assign O = S ? I1 : I0;
232 endmodule
233
234 module MUXF6(output O, input I0, I1, S);
235 assign O = S ? I1 : I0;
236 endmodule
237
238 (* abc9_box_id = 1, lib_whitebox *)
239 module MUXF7(output O, input I0, I1, S);
240 assign O = S ? I1 : I0;
241 endmodule
242
243 (* abc9_box_id = 2, lib_whitebox *)
244 module MUXF8(output O, input I0, I1, S);
245 assign O = S ? I1 : I0;
246 endmodule
247
248 module MUXF9(output O, input I0, I1, S);
249 assign O = S ? I1 : I0;
250 endmodule
251
252 module XORCY(output O, input CI, LI);
253 assign O = CI ^ LI;
254 endmodule
255
256 (* abc9_box_id = 4, lib_whitebox *)
257 module CARRY4(
258 (* abc9_carry *)
259 output [3:0] CO,
260 output [3:0] O,
261 (* abc9_carry *)
262 input CI,
263 input CYINIT,
264 input [3:0] DI, S
265 );
266 assign O = S ^ {CO[2:0], CI | CYINIT};
267 assign CO[0] = S[0] ? CI | CYINIT : DI[0];
268 assign CO[1] = S[1] ? CO[0] : DI[1];
269 assign CO[2] = S[2] ? CO[1] : DI[2];
270 assign CO[3] = S[3] ? CO[2] : DI[3];
271 endmodule
272
273 module CARRY8(
274 output [7:0] CO,
275 output [7:0] O,
276 input CI,
277 input CI_TOP,
278 input [7:0] DI, S
279 );
280 parameter CARRY_TYPE = "SINGLE_CY8";
281 wire CI4 = (CARRY_TYPE == "DUAL_CY4" ? CI_TOP : CO[3]);
282 assign O = S ^ {CO[6:4], CI4, CO[2:0], CI};
283 assign CO[0] = S[0] ? CI : DI[0];
284 assign CO[1] = S[1] ? CO[0] : DI[1];
285 assign CO[2] = S[2] ? CO[1] : DI[2];
286 assign CO[3] = S[3] ? CO[2] : DI[3];
287 assign CO[4] = S[4] ? CI4 : DI[4];
288 assign CO[5] = S[5] ? CO[4] : DI[5];
289 assign CO[6] = S[6] ? CO[5] : DI[6];
290 assign CO[7] = S[7] ? CO[6] : DI[7];
291 endmodule
292
293 `ifdef _EXPLICIT_CARRY
294
295 module CARRY0(output CO_CHAIN, CO_FABRIC, O, input CI, CI_INIT, DI, S);
296 parameter CYINIT_FABRIC = 0;
297 wire CI_COMBINE;
298 if(CYINIT_FABRIC) begin
299 assign CI_COMBINE = CI_INIT;
300 end else begin
301 assign CI_COMBINE = CI;
302 end
303 assign CO_CHAIN = S ? CI_COMBINE : DI;
304 assign CO_FABRIC = S ? CI_COMBINE : DI;
305 assign O = S ^ CI_COMBINE;
306 endmodule
307
308 module CARRY(output CO_CHAIN, CO_FABRIC, O, input CI, DI, S);
309 assign CO_CHAIN = S ? CI : DI;
310 assign CO_FABRIC = S ? CI : DI;
311 assign O = S ^ CI;
312 endmodule
313
314 `endif
315
316 module ORCY (output O, input CI, I);
317 assign O = CI | I;
318 endmodule
319
320 module MULT_AND (output LO, input I0, I1);
321 assign LO = I0 & I1;
322 endmodule
323
324 // Flip-flops and latches.
325
326 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
327
328 (* abc9_box_id=1100, lib_whitebox, abc9_flop *)
329 module FDRE (
330 (* abc9_arrival=303 *)
331 output reg Q,
332 (* clkbuf_sink *)
333 (* invertible_pin = "IS_C_INVERTED" *)
334 input C,
335 input CE,
336 (* invertible_pin = "IS_D_INVERTED" *)
337 input D,
338 (* invertible_pin = "IS_R_INVERTED" *)
339 input R
340 );
341 parameter [0:0] INIT = 1'b0;
342 parameter [0:0] IS_C_INVERTED = 1'b0;
343 parameter [0:0] IS_D_INVERTED = 1'b0;
344 parameter [0:0] IS_R_INVERTED = 1'b0;
345 initial Q <= INIT;
346 generate case (|IS_C_INVERTED)
347 1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
348 1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
349 endcase endgenerate
350 endmodule
351
352 (* abc9_box_id=1101, lib_whitebox, abc9_flop *)
353 module FDRE_1 (
354 (* abc9_arrival=303 *)
355 output reg Q,
356 (* clkbuf_sink *)
357 input C,
358 input CE, D, R
359 );
360 parameter [0:0] INIT = 1'b0;
361 initial Q <= INIT;
362 always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D;
363 endmodule
364
365 module FDRSE (
366 output reg Q,
367 (* clkbuf_sink *)
368 (* invertible_pin = "IS_C_INVERTED" *)
369 input C,
370 (* invertible_pin = "IS_CE_INVERTED" *)
371 input CE,
372 (* invertible_pin = "IS_D_INVERTED" *)
373 input D,
374 (* invertible_pin = "IS_R_INVERTED" *)
375 input R,
376 (* invertible_pin = "IS_S_INVERTED" *)
377 input S
378 );
379 parameter [0:0] INIT = 1'b0;
380 parameter [0:0] IS_C_INVERTED = 1'b0;
381 parameter [0:0] IS_CE_INVERTED = 1'b0;
382 parameter [0:0] IS_D_INVERTED = 1'b0;
383 parameter [0:0] IS_R_INVERTED = 1'b0;
384 parameter [0:0] IS_S_INVERTED = 1'b0;
385 initial Q <= INIT;
386 wire c = C ^ IS_C_INVERTED;
387 wire ce = CE ^ IS_CE_INVERTED;
388 wire d = D ^ IS_D_INVERTED;
389 wire r = R ^ IS_R_INVERTED;
390 wire s = S ^ IS_S_INVERTED;
391 always @(posedge c)
392 if (r)
393 Q <= 0;
394 else if (s)
395 Q <= 1;
396 else if (ce)
397 Q <= d;
398 endmodule
399
400 (* abc9_box_id=1102, lib_whitebox, abc9_flop *)
401 module FDCE (
402 (* abc9_arrival=303 *)
403 output reg Q,
404 (* clkbuf_sink *)
405 (* invertible_pin = "IS_C_INVERTED" *)
406 input C,
407 input CE,
408 (* invertible_pin = "IS_CLR_INVERTED" *)
409 input CLR,
410 (* invertible_pin = "IS_D_INVERTED" *)
411 input D
412 );
413 parameter [0:0] INIT = 1'b0;
414 parameter [0:0] IS_C_INVERTED = 1'b0;
415 parameter [0:0] IS_D_INVERTED = 1'b0;
416 parameter [0:0] IS_CLR_INVERTED = 1'b0;
417 initial Q <= INIT;
418 generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED})
419 2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
420 2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
421 2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
422 2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED;
423 endcase endgenerate
424 endmodule
425
426 (* abc9_box_id=1103, lib_whitebox, abc9_flop *)
427 module FDCE_1 (
428 (* abc9_arrival=303 *)
429 output reg Q,
430 (* clkbuf_sink *)
431 input C,
432 input CE, D, CLR
433 );
434 parameter [0:0] INIT = 1'b0;
435 initial Q <= INIT;
436 always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
437 endmodule
438
439 module FDCPE (
440 output wire Q,
441 (* clkbuf_sink *)
442 (* invertible_pin = "IS_C_INVERTED" *)
443 input C,
444 input CE,
445 (* invertible_pin = "IS_CLR_INVERTED" *)
446 input CLR,
447 input D,
448 (* invertible_pin = "IS_PRE_INVERTED" *)
449 input PRE
450 );
451 parameter [0:0] INIT = 1'b0;
452 parameter [0:0] IS_C_INVERTED = 1'b0;
453 parameter [0:0] IS_CLR_INVERTED = 1'b0;
454 parameter [0:0] IS_PRE_INVERTED = 1'b0;
455 wire c = C ^ IS_C_INVERTED;
456 wire clr = CLR ^ IS_CLR_INVERTED;
457 wire pre = PRE ^ IS_PRE_INVERTED;
458 // Hacky model to avoid simulation-synthesis mismatches.
459 reg qc, qp, qs;
460 initial qc = INIT;
461 initial qp = INIT;
462 initial qs = 0;
463 always @(posedge c, posedge clr) begin
464 if (clr)
465 qc <= 0;
466 else if (CE)
467 qc <= D;
468 end
469 always @(posedge c, posedge pre) begin
470 if (pre)
471 qp <= 1;
472 else if (CE)
473 qp <= D;
474 end
475 always @* begin
476 if (clr)
477 qs <= 0;
478 else if (pre)
479 qs <= 1;
480 end
481 assign Q = qs ? qp : qc;
482 endmodule
483
484 (* abc9_box_id=1104, lib_whitebox, abc9_flop *)
485 module FDPE (
486 (* abc9_arrival=303 *)
487 output reg Q,
488 (* clkbuf_sink *)
489 (* invertible_pin = "IS_C_INVERTED" *)
490 input C,
491 input CE,
492 (* invertible_pin = "IS_D_INVERTED" *)
493 input D,
494 (* invertible_pin = "IS_PRE_INVERTED" *)
495 input PRE
496 );
497 parameter [0:0] INIT = 1'b1;
498 parameter [0:0] IS_C_INVERTED = 1'b0;
499 parameter [0:0] IS_D_INVERTED = 1'b0;
500 parameter [0:0] IS_PRE_INVERTED = 1'b0;
501 initial Q <= INIT;
502 generate case ({|IS_C_INVERTED, |IS_PRE_INVERTED})
503 2'b00: always @(posedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
504 2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
505 2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
506 2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
507 endcase endgenerate
508 endmodule
509
510 (* abc9_box_id=1105, lib_whitebox, abc9_flop *)
511 module FDPE_1 (
512 (* abc9_arrival=303 *)
513 output reg Q,
514 (* clkbuf_sink *)
515 input C,
516 input CE, D, PRE
517 );
518 parameter [0:0] INIT = 1'b1;
519 initial Q <= INIT;
520 always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
521 endmodule
522
523 (* abc9_box_id=1106, lib_whitebox, abc9_flop *)
524 module FDSE (
525 (* abc9_arrival=303 *)
526 output reg Q,
527 (* clkbuf_sink *)
528 (* invertible_pin = "IS_C_INVERTED" *)
529 input C,
530 input CE,
531 (* invertible_pin = "IS_D_INVERTED" *)
532 input D,
533 (* invertible_pin = "IS_S_INVERTED" *)
534 input S
535 );
536 parameter [0:0] INIT = 1'b1;
537 parameter [0:0] IS_C_INVERTED = 1'b0;
538 parameter [0:0] IS_D_INVERTED = 1'b0;
539 parameter [0:0] IS_S_INVERTED = 1'b0;
540 initial Q <= INIT;
541 generate case (|IS_C_INVERTED)
542 1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
543 1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED;
544 endcase endgenerate
545 endmodule
546
547 (* abc9_box_id=1107, lib_whitebox, abc9_flop *)
548 module FDSE_1 (
549 (* abc9_arrival=303 *)
550 output reg Q,
551 (* clkbuf_sink *)
552 input C,
553 input CE, D, S
554 );
555 parameter [0:0] INIT = 1'b1;
556 initial Q <= INIT;
557 always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D;
558 endmodule
559
560 module LDCE (
561 output reg Q,
562 (* invertible_pin = "IS_CLR_INVERTED" *)
563 input CLR,
564 input D,
565 (* invertible_pin = "IS_G_INVERTED" *)
566 input G,
567 input GE
568 );
569 parameter [0:0] INIT = 1'b0;
570 parameter [0:0] IS_CLR_INVERTED = 1'b0;
571 parameter [0:0] IS_G_INVERTED = 1'b0;
572 parameter MSGON = "TRUE";
573 parameter XON = "TRUE";
574 initial Q = INIT;
575 wire clr = CLR ^ IS_CLR_INVERTED;
576 wire g = G ^ IS_G_INVERTED;
577 always @*
578 if (clr) Q <= 1'b0;
579 else if (GE && g) Q <= D;
580 endmodule
581
582 module LDPE (
583 output reg Q,
584 input D,
585 (* invertible_pin = "IS_G_INVERTED" *)
586 input G,
587 input GE,
588 (* invertible_pin = "IS_PRE_INVERTED" *)
589 input PRE
590 );
591 parameter [0:0] INIT = 1'b1;
592 parameter [0:0] IS_G_INVERTED = 1'b0;
593 parameter [0:0] IS_PRE_INVERTED = 1'b0;
594 parameter MSGON = "TRUE";
595 parameter XON = "TRUE";
596 initial Q = INIT;
597 wire g = G ^ IS_G_INVERTED;
598 wire pre = PRE ^ IS_PRE_INVERTED;
599 always @*
600 if (pre) Q <= 1'b1;
601 else if (GE && g) Q <= D;
602 endmodule
603
604 module LDCPE (
605 output reg Q,
606 (* invertible_pin = "IS_CLR_INVERTED" *)
607 input CLR,
608 (* invertible_pin = "IS_D_INVERTED" *)
609 input D,
610 (* invertible_pin = "IS_G_INVERTED" *)
611 input G,
612 (* invertible_pin = "IS_GE_INVERTED" *)
613 input GE,
614 (* invertible_pin = "IS_PRE_INVERTED" *)
615 input PRE
616 );
617 parameter [0:0] INIT = 1'b1;
618 parameter [0:0] IS_CLR_INVERTED = 1'b0;
619 parameter [0:0] IS_D_INVERTED = 1'b0;
620 parameter [0:0] IS_G_INVERTED = 1'b0;
621 parameter [0:0] IS_GE_INVERTED = 1'b0;
622 parameter [0:0] IS_PRE_INVERTED = 1'b0;
623 initial Q = INIT;
624 wire d = D ^ IS_D_INVERTED;
625 wire g = G ^ IS_G_INVERTED;
626 wire ge = GE ^ IS_GE_INVERTED;
627 wire clr = CLR ^ IS_CLR_INVERTED;
628 wire pre = PRE ^ IS_PRE_INVERTED;
629 always @*
630 if (clr) Q <= 1'b0;
631 else if (pre) Q <= 1'b1;
632 else if (ge && g) Q <= d;
633 endmodule
634
635 module AND2B1L (
636 output O,
637 input DI,
638 (* invertible_pin = "IS_SRI_INVERTED" *)
639 input SRI
640 );
641 parameter [0:0] IS_SRI_INVERTED = 1'b0;
642 assign O = DI & ~(SRI ^ IS_SRI_INVERTED);
643 endmodule
644
645 module OR2L (
646 output O,
647 input DI,
648 (* invertible_pin = "IS_SRI_INVERTED" *)
649 input SRI
650 );
651 parameter [0:0] IS_SRI_INVERTED = 1'b0;
652 assign O = DI | (SRI ^ IS_SRI_INVERTED);
653 endmodule
654
655 // LUTRAM.
656
657 // Single port.
658
659 module RAM16X1S (
660 output O,
661 input A0, A1, A2, A3,
662 input D,
663 (* clkbuf_sink *)
664 (* invertible_pin = "IS_WCLK_INVERTED" *)
665 input WCLK,
666 input WE
667 );
668 parameter [15:0] INIT = 16'h0000;
669 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
670 wire [3:0] a = {A3, A2, A1, A0};
671 reg [15:0] mem = INIT;
672 assign O = mem[a];
673 wire clk = WCLK ^ IS_WCLK_INVERTED;
674 always @(posedge clk) if (WE) mem[a] <= D;
675 endmodule
676
677 module RAM16X1S_1 (
678 output O,
679 input A0, A1, A2, A3,
680 input D,
681 (* clkbuf_sink *)
682 (* invertible_pin = "IS_WCLK_INVERTED" *)
683 input WCLK,
684 input WE
685 );
686 parameter [15:0] INIT = 16'h0000;
687 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
688 wire [3:0] a = {A3, A2, A1, A0};
689 reg [15:0] mem = INIT;
690 assign O = mem[a];
691 wire clk = WCLK ^ IS_WCLK_INVERTED;
692 always @(negedge clk) if (WE) mem[a] <= D;
693 endmodule
694
695 module RAM32X1S (
696 output O,
697 input A0, A1, A2, A3, A4,
698 input D,
699 (* clkbuf_sink *)
700 (* invertible_pin = "IS_WCLK_INVERTED" *)
701 input WCLK,
702 input WE
703 );
704 parameter [31:0] INIT = 32'h00000000;
705 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
706 wire [4:0] a = {A4, A3, A2, A1, A0};
707 reg [31:0] mem = INIT;
708 assign O = mem[a];
709 wire clk = WCLK ^ IS_WCLK_INVERTED;
710 always @(posedge clk) if (WE) mem[a] <= D;
711 endmodule
712
713 module RAM32X1S_1 (
714 output O,
715 input A0, A1, A2, A3, A4,
716 input D,
717 (* clkbuf_sink *)
718 (* invertible_pin = "IS_WCLK_INVERTED" *)
719 input WCLK,
720 input WE
721 );
722 parameter [31:0] INIT = 32'h00000000;
723 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
724 wire [4:0] a = {A4, A3, A2, A1, A0};
725 reg [31:0] mem = INIT;
726 assign O = mem[a];
727 wire clk = WCLK ^ IS_WCLK_INVERTED;
728 always @(negedge clk) if (WE) mem[a] <= D;
729 endmodule
730
731 module RAM64X1S (
732 output O,
733 input A0, A1, A2, A3, A4, A5,
734 input D,
735 (* clkbuf_sink *)
736 (* invertible_pin = "IS_WCLK_INVERTED" *)
737 input WCLK,
738 input WE
739 );
740 parameter [63:0] INIT = 64'h0000000000000000;
741 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
742 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
743 reg [63:0] mem = INIT;
744 assign O = mem[a];
745 wire clk = WCLK ^ IS_WCLK_INVERTED;
746 always @(posedge clk) if (WE) mem[a] <= D;
747 endmodule
748
749 module RAM64X1S_1 (
750 output O,
751 input A0, A1, A2, A3, A4, A5,
752 input D,
753 (* clkbuf_sink *)
754 (* invertible_pin = "IS_WCLK_INVERTED" *)
755 input WCLK,
756 input WE
757 );
758 parameter [63:0] INIT = 64'h0000000000000000;
759 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
760 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
761 reg [63:0] mem = INIT;
762 assign O = mem[a];
763 wire clk = WCLK ^ IS_WCLK_INVERTED;
764 always @(negedge clk) if (WE) mem[a] <= D;
765 endmodule
766
767 module RAM128X1S (
768 output O,
769 input A0, A1, A2, A3, A4, A5, A6,
770 input D,
771 (* clkbuf_sink *)
772 (* invertible_pin = "IS_WCLK_INVERTED" *)
773 input WCLK,
774 input WE
775 );
776 parameter [127:0] INIT = 128'h00000000000000000000000000000000;
777 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
778 wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0};
779 reg [127:0] mem = INIT;
780 assign O = mem[a];
781 wire clk = WCLK ^ IS_WCLK_INVERTED;
782 always @(posedge clk) if (WE) mem[a] <= D;
783 endmodule
784
785 module RAM128X1S_1 (
786 output O,
787 input A0, A1, A2, A3, A4, A5, A6,
788 input D,
789 (* clkbuf_sink *)
790 (* invertible_pin = "IS_WCLK_INVERTED" *)
791 input WCLK,
792 input WE
793 );
794 parameter [127:0] INIT = 128'h00000000000000000000000000000000;
795 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
796 wire [6:0] a = {A6, A5, A4, A3, A2, A1, A0};
797 reg [127:0] mem = INIT;
798 assign O = mem[a];
799 wire clk = WCLK ^ IS_WCLK_INVERTED;
800 always @(negedge clk) if (WE) mem[a] <= D;
801 endmodule
802
803 module RAM256X1S (
804 output O,
805 input [7:0] A,
806 input D,
807 (* clkbuf_sink *)
808 (* invertible_pin = "IS_WCLK_INVERTED" *)
809 input WCLK,
810 input WE
811 );
812 parameter [255:0] INIT = 256'h0;
813 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
814 reg [255:0] mem = INIT;
815 assign O = mem[A];
816 wire clk = WCLK ^ IS_WCLK_INVERTED;
817 always @(posedge clk) if (WE) mem[A] <= D;
818 endmodule
819
820 module RAM512X1S (
821 output O,
822 input [8:0] A,
823 input D,
824 (* clkbuf_sink *)
825 (* invertible_pin = "IS_WCLK_INVERTED" *)
826 input WCLK,
827 input WE
828 );
829 parameter [511:0] INIT = 512'h0;
830 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
831 reg [511:0] mem = INIT;
832 assign O = mem[A];
833 wire clk = WCLK ^ IS_WCLK_INVERTED;
834 always @(posedge clk) if (WE) mem[A] <= D;
835 endmodule
836
837 // Single port, wide.
838
839 module RAM16X2S (
840 output O0, O1,
841 input A0, A1, A2, A3,
842 input D0, D1,
843 (* clkbuf_sink *)
844 (* invertible_pin = "IS_WCLK_INVERTED" *)
845 input WCLK,
846 input WE
847 );
848 parameter [15:0] INIT_00 = 16'h0000;
849 parameter [15:0] INIT_01 = 16'h0000;
850 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
851 wire [3:0] a = {A3, A2, A1, A0};
852 wire clk = WCLK ^ IS_WCLK_INVERTED;
853 reg [15:0] mem0 = INIT_00;
854 reg [15:0] mem1 = INIT_01;
855 assign O0 = mem0[a];
856 assign O1 = mem1[a];
857 always @(posedge clk)
858 if (WE) begin
859 mem0[a] <= D0;
860 mem1[a] <= D1;
861 end
862 endmodule
863
864 module RAM32X2S (
865 output O0, O1,
866 input A0, A1, A2, A3, A4,
867 input D0, D1,
868 (* clkbuf_sink *)
869 (* invertible_pin = "IS_WCLK_INVERTED" *)
870 input WCLK,
871 input WE
872 );
873 parameter [31:0] INIT_00 = 32'h00000000;
874 parameter [31:0] INIT_01 = 32'h00000000;
875 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
876 wire [4:0] a = {A4, A3, A2, A1, A0};
877 wire clk = WCLK ^ IS_WCLK_INVERTED;
878 reg [31:0] mem0 = INIT_00;
879 reg [31:0] mem1 = INIT_01;
880 assign O0 = mem0[a];
881 assign O1 = mem1[a];
882 always @(posedge clk)
883 if (WE) begin
884 mem0[a] <= D0;
885 mem1[a] <= D1;
886 end
887 endmodule
888
889 module RAM64X2S (
890 output O0, O1,
891 input A0, A1, A2, A3, A4, A5,
892 input D0, D1,
893 (* clkbuf_sink *)
894 (* invertible_pin = "IS_WCLK_INVERTED" *)
895 input WCLK,
896 input WE
897 );
898 parameter [63:0] INIT_00 = 64'h0000000000000000;
899 parameter [63:0] INIT_01 = 64'h0000000000000000;
900 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
901 wire [5:0] a = {A5, A3, A2, A1, A0};
902 wire clk = WCLK ^ IS_WCLK_INVERTED;
903 reg [63:0] mem0 = INIT_00;
904 reg [63:0] mem1 = INIT_01;
905 assign O0 = mem0[a];
906 assign O1 = mem1[a];
907 always @(posedge clk)
908 if (WE) begin
909 mem0[a] <= D0;
910 mem1[a] <= D1;
911 end
912 endmodule
913
914 module RAM16X4S (
915 output O0, O1, O2, O3,
916 input A0, A1, A2, A3,
917 input D0, D1, D2, D3,
918 (* clkbuf_sink *)
919 (* invertible_pin = "IS_WCLK_INVERTED" *)
920 input WCLK,
921 input WE
922 );
923 parameter [15:0] INIT_00 = 16'h0000;
924 parameter [15:0] INIT_01 = 16'h0000;
925 parameter [15:0] INIT_02 = 16'h0000;
926 parameter [15:0] INIT_03 = 16'h0000;
927 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
928 wire [3:0] a = {A3, A2, A1, A0};
929 wire clk = WCLK ^ IS_WCLK_INVERTED;
930 reg [15:0] mem0 = INIT_00;
931 reg [15:0] mem1 = INIT_01;
932 reg [15:0] mem2 = INIT_02;
933 reg [15:0] mem3 = INIT_03;
934 assign O0 = mem0[a];
935 assign O1 = mem1[a];
936 assign O2 = mem2[a];
937 assign O3 = mem3[a];
938 always @(posedge clk)
939 if (WE) begin
940 mem0[a] <= D0;
941 mem1[a] <= D1;
942 mem2[a] <= D2;
943 mem3[a] <= D3;
944 end
945 endmodule
946
947 module RAM32X4S (
948 output O0, O1, O2, O3,
949 input A0, A1, A2, A3, A4,
950 input D0, D1, D2, D3,
951 (* clkbuf_sink *)
952 (* invertible_pin = "IS_WCLK_INVERTED" *)
953 input WCLK,
954 input WE
955 );
956 parameter [31:0] INIT_00 = 32'h00000000;
957 parameter [31:0] INIT_01 = 32'h00000000;
958 parameter [31:0] INIT_02 = 32'h00000000;
959 parameter [31:0] INIT_03 = 32'h00000000;
960 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
961 wire [4:0] a = {A4, A3, A2, A1, A0};
962 wire clk = WCLK ^ IS_WCLK_INVERTED;
963 reg [31:0] mem0 = INIT_00;
964 reg [31:0] mem1 = INIT_01;
965 reg [31:0] mem2 = INIT_02;
966 reg [31:0] mem3 = INIT_03;
967 assign O0 = mem0[a];
968 assign O1 = mem1[a];
969 assign O2 = mem2[a];
970 assign O3 = mem3[a];
971 always @(posedge clk)
972 if (WE) begin
973 mem0[a] <= D0;
974 mem1[a] <= D1;
975 mem2[a] <= D2;
976 mem3[a] <= D3;
977 end
978 endmodule
979
980 module RAM16X8S (
981 output [7:0] O,
982 input A0, A1, A2, A3,
983 input [7:0] D,
984 (* clkbuf_sink *)
985 (* invertible_pin = "IS_WCLK_INVERTED" *)
986 input WCLK,
987 input WE
988 );
989 parameter [15:0] INIT_00 = 16'h0000;
990 parameter [15:0] INIT_01 = 16'h0000;
991 parameter [15:0] INIT_02 = 16'h0000;
992 parameter [15:0] INIT_03 = 16'h0000;
993 parameter [15:0] INIT_04 = 16'h0000;
994 parameter [15:0] INIT_05 = 16'h0000;
995 parameter [15:0] INIT_06 = 16'h0000;
996 parameter [15:0] INIT_07 = 16'h0000;
997 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
998 wire [3:0] a = {A3, A2, A1, A0};
999 wire clk = WCLK ^ IS_WCLK_INVERTED;
1000 reg [15:0] mem0 = INIT_00;
1001 reg [15:0] mem1 = INIT_01;
1002 reg [15:0] mem2 = INIT_02;
1003 reg [15:0] mem3 = INIT_03;
1004 reg [15:0] mem4 = INIT_04;
1005 reg [15:0] mem5 = INIT_05;
1006 reg [15:0] mem6 = INIT_06;
1007 reg [15:0] mem7 = INIT_07;
1008 assign O[0] = mem0[a];
1009 assign O[1] = mem1[a];
1010 assign O[2] = mem2[a];
1011 assign O[3] = mem3[a];
1012 assign O[4] = mem4[a];
1013 assign O[5] = mem5[a];
1014 assign O[6] = mem6[a];
1015 assign O[7] = mem7[a];
1016 always @(posedge clk)
1017 if (WE) begin
1018 mem0[a] <= D[0];
1019 mem1[a] <= D[1];
1020 mem2[a] <= D[2];
1021 mem3[a] <= D[3];
1022 mem4[a] <= D[4];
1023 mem5[a] <= D[5];
1024 mem6[a] <= D[6];
1025 mem7[a] <= D[7];
1026 end
1027 endmodule
1028
1029 module RAM32X8S (
1030 output [7:0] O,
1031 input A0, A1, A2, A3, A4,
1032 input [7:0] D,
1033 (* clkbuf_sink *)
1034 (* invertible_pin = "IS_WCLK_INVERTED" *)
1035 input WCLK,
1036 input WE
1037 );
1038 parameter [31:0] INIT_00 = 32'h00000000;
1039 parameter [31:0] INIT_01 = 32'h00000000;
1040 parameter [31:0] INIT_02 = 32'h00000000;
1041 parameter [31:0] INIT_03 = 32'h00000000;
1042 parameter [31:0] INIT_04 = 32'h00000000;
1043 parameter [31:0] INIT_05 = 32'h00000000;
1044 parameter [31:0] INIT_06 = 32'h00000000;
1045 parameter [31:0] INIT_07 = 32'h00000000;
1046 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1047 wire [4:0] a = {A4, A3, A2, A1, A0};
1048 wire clk = WCLK ^ IS_WCLK_INVERTED;
1049 reg [31:0] mem0 = INIT_00;
1050 reg [31:0] mem1 = INIT_01;
1051 reg [31:0] mem2 = INIT_02;
1052 reg [31:0] mem3 = INIT_03;
1053 reg [31:0] mem4 = INIT_04;
1054 reg [31:0] mem5 = INIT_05;
1055 reg [31:0] mem6 = INIT_06;
1056 reg [31:0] mem7 = INIT_07;
1057 assign O[0] = mem0[a];
1058 assign O[1] = mem1[a];
1059 assign O[2] = mem2[a];
1060 assign O[3] = mem3[a];
1061 assign O[4] = mem4[a];
1062 assign O[5] = mem5[a];
1063 assign O[6] = mem6[a];
1064 assign O[7] = mem7[a];
1065 always @(posedge clk)
1066 if (WE) begin
1067 mem0[a] <= D[0];
1068 mem1[a] <= D[1];
1069 mem2[a] <= D[2];
1070 mem3[a] <= D[3];
1071 mem4[a] <= D[4];
1072 mem5[a] <= D[5];
1073 mem6[a] <= D[6];
1074 mem7[a] <= D[7];
1075 end
1076 endmodule
1077
1078 // Dual port.
1079
1080 module RAM16X1D (
1081 output DPO, SPO,
1082 input D,
1083 (* clkbuf_sink *)
1084 (* invertible_pin = "IS_WCLK_INVERTED" *)
1085 input WCLK,
1086 input WE,
1087 input A0, A1, A2, A3,
1088 input DPRA0, DPRA1, DPRA2, DPRA3
1089 );
1090 parameter INIT = 16'h0;
1091 parameter IS_WCLK_INVERTED = 1'b0;
1092 wire [3:0] a = {A3, A2, A1, A0};
1093 wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0};
1094 reg [15:0] mem = INIT;
1095 assign SPO = mem[a];
1096 assign DPO = mem[dpra];
1097 wire clk = WCLK ^ IS_WCLK_INVERTED;
1098 always @(posedge clk) if (WE) mem[a] <= D;
1099 endmodule
1100
1101 module RAM16X1D_1 (
1102 output DPO, SPO,
1103 input D,
1104 (* clkbuf_sink *)
1105 (* invertible_pin = "IS_WCLK_INVERTED" *)
1106 input WCLK,
1107 input WE,
1108 input A0, A1, A2, A3,
1109 input DPRA0, DPRA1, DPRA2, DPRA3
1110 );
1111 parameter INIT = 16'h0;
1112 parameter IS_WCLK_INVERTED = 1'b0;
1113 wire [3:0] a = {A3, A2, A1, A0};
1114 wire [3:0] dpra = {DPRA3, DPRA2, DPRA1, DPRA0};
1115 reg [15:0] mem = INIT;
1116 assign SPO = mem[a];
1117 assign DPO = mem[dpra];
1118 wire clk = WCLK ^ IS_WCLK_INVERTED;
1119 always @(negedge clk) if (WE) mem[a] <= D;
1120 endmodule
1121
1122 module RAM32X1D (
1123 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1124 (* abc9_arrival=1153 *)
1125 output DPO, SPO,
1126 input D,
1127 (* clkbuf_sink *)
1128 (* invertible_pin = "IS_WCLK_INVERTED" *)
1129 input WCLK,
1130 input WE,
1131 input A0, A1, A2, A3, A4,
1132 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
1133 );
1134 parameter INIT = 32'h0;
1135 parameter IS_WCLK_INVERTED = 1'b0;
1136 wire [4:0] a = {A4, A3, A2, A1, A0};
1137 wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1138 reg [31:0] mem = INIT;
1139 assign SPO = mem[a];
1140 assign DPO = mem[dpra];
1141 wire clk = WCLK ^ IS_WCLK_INVERTED;
1142 always @(posedge clk) if (WE) mem[a] <= D;
1143 endmodule
1144
1145 module RAM32X1D_1 (
1146 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1147 (* abc9_arrival=1153 *)
1148 output DPO, SPO,
1149 input D,
1150 (* clkbuf_sink *)
1151 (* invertible_pin = "IS_WCLK_INVERTED" *)
1152 input WCLK,
1153 input WE,
1154 input A0, A1, A2, A3, A4,
1155 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
1156 );
1157 parameter INIT = 32'h0;
1158 parameter IS_WCLK_INVERTED = 1'b0;
1159 wire [4:0] a = {A4, A3, A2, A1, A0};
1160 wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1161 reg [31:0] mem = INIT;
1162 assign SPO = mem[a];
1163 assign DPO = mem[dpra];
1164 wire clk = WCLK ^ IS_WCLK_INVERTED;
1165 always @(negedge clk) if (WE) mem[a] <= D;
1166 endmodule
1167
1168 module RAM64X1D (
1169 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1170 (* abc9_arrival=1153 *)
1171 output DPO, SPO,
1172 input D,
1173 (* clkbuf_sink *)
1174 (* invertible_pin = "IS_WCLK_INVERTED" *)
1175 input WCLK,
1176 input WE,
1177 input A0, A1, A2, A3, A4, A5,
1178 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
1179 );
1180 parameter INIT = 64'h0;
1181 parameter IS_WCLK_INVERTED = 1'b0;
1182 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1183 wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1184 reg [63:0] mem = INIT;
1185 assign SPO = mem[a];
1186 assign DPO = mem[dpra];
1187 wire clk = WCLK ^ IS_WCLK_INVERTED;
1188 always @(posedge clk) if (WE) mem[a] <= D;
1189 endmodule
1190
1191 module RAM64X1D_1 (
1192 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1193 (* abc9_arrival=1153 *)
1194 output DPO, SPO,
1195 input D,
1196 (* clkbuf_sink *)
1197 (* invertible_pin = "IS_WCLK_INVERTED" *)
1198 input WCLK,
1199 input WE,
1200 input A0, A1, A2, A3, A4, A5,
1201 input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
1202 );
1203 parameter INIT = 64'h0;
1204 parameter IS_WCLK_INVERTED = 1'b0;
1205 wire [5:0] a = {A5, A4, A3, A2, A1, A0};
1206 wire [5:0] dpra = {DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
1207 reg [63:0] mem = INIT;
1208 assign SPO = mem[a];
1209 assign DPO = mem[dpra];
1210 wire clk = WCLK ^ IS_WCLK_INVERTED;
1211 always @(negedge clk) if (WE) mem[a] <= D;
1212 endmodule
1213
1214 module RAM128X1D (
1215 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1216 (* abc9_arrival=1153 *)
1217 output DPO, SPO,
1218 input D,
1219 (* clkbuf_sink *)
1220 (* invertible_pin = "IS_WCLK_INVERTED" *)
1221 input WCLK,
1222 input WE,
1223 input [6:0] A, DPRA
1224 );
1225 parameter INIT = 128'h0;
1226 parameter IS_WCLK_INVERTED = 1'b0;
1227 reg [127:0] mem = INIT;
1228 assign SPO = mem[A];
1229 assign DPO = mem[DPRA];
1230 wire clk = WCLK ^ IS_WCLK_INVERTED;
1231 always @(posedge clk) if (WE) mem[A] <= D;
1232 endmodule
1233
1234 module RAM256X1D (
1235 output DPO, SPO,
1236 input D,
1237 (* clkbuf_sink *)
1238 (* invertible_pin = "IS_WCLK_INVERTED" *)
1239 input WCLK,
1240 input WE,
1241 input [7:0] A, DPRA
1242 );
1243 parameter INIT = 256'h0;
1244 parameter IS_WCLK_INVERTED = 1'b0;
1245 reg [255:0] mem = INIT;
1246 assign SPO = mem[A];
1247 assign DPO = mem[DPRA];
1248 wire clk = WCLK ^ IS_WCLK_INVERTED;
1249 always @(posedge clk) if (WE) mem[A] <= D;
1250 endmodule
1251
1252 // Multi port.
1253
1254 module RAM32M (
1255 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1256 (* abc9_arrival=1153 *)
1257 output [1:0] DOA, DOB, DOC, DOD,
1258 input [4:0] ADDRA, ADDRB, ADDRC, ADDRD,
1259 input [1:0] DIA, DIB, DIC, DID,
1260 (* clkbuf_sink *)
1261 (* invertible_pin = "IS_WCLK_INVERTED" *)
1262 input WCLK,
1263 input WE
1264 );
1265 parameter [63:0] INIT_A = 64'h0000000000000000;
1266 parameter [63:0] INIT_B = 64'h0000000000000000;
1267 parameter [63:0] INIT_C = 64'h0000000000000000;
1268 parameter [63:0] INIT_D = 64'h0000000000000000;
1269 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1270 reg [63:0] mem_a = INIT_A;
1271 reg [63:0] mem_b = INIT_B;
1272 reg [63:0] mem_c = INIT_C;
1273 reg [63:0] mem_d = INIT_D;
1274 assign DOA = mem_a[2*ADDRA+:2];
1275 assign DOB = mem_b[2*ADDRB+:2];
1276 assign DOC = mem_c[2*ADDRC+:2];
1277 assign DOD = mem_d[2*ADDRD+:2];
1278 wire clk = WCLK ^ IS_WCLK_INVERTED;
1279 always @(posedge clk)
1280 if (WE) begin
1281 mem_a[2*ADDRD+:2] <= DIA;
1282 mem_b[2*ADDRD+:2] <= DIB;
1283 mem_c[2*ADDRD+:2] <= DIC;
1284 mem_d[2*ADDRD+:2] <= DID;
1285 end
1286 endmodule
1287
1288 module RAM32M16 (
1289 output [1:0] DOA,
1290 output [1:0] DOB,
1291 output [1:0] DOC,
1292 output [1:0] DOD,
1293 output [1:0] DOE,
1294 output [1:0] DOF,
1295 output [1:0] DOG,
1296 output [1:0] DOH,
1297 input [4:0] ADDRA,
1298 input [4:0] ADDRB,
1299 input [4:0] ADDRC,
1300 input [4:0] ADDRD,
1301 input [4:0] ADDRE,
1302 input [4:0] ADDRF,
1303 input [4:0] ADDRG,
1304 input [4:0] ADDRH,
1305 input [1:0] DIA,
1306 input [1:0] DIB,
1307 input [1:0] DIC,
1308 input [1:0] DID,
1309 input [1:0] DIE,
1310 input [1:0] DIF,
1311 input [1:0] DIG,
1312 input [1:0] DIH,
1313 (* clkbuf_sink *)
1314 (* invertible_pin = "IS_WCLK_INVERTED" *)
1315 input WCLK,
1316 input WE
1317 );
1318 parameter [63:0] INIT_A = 64'h0000000000000000;
1319 parameter [63:0] INIT_B = 64'h0000000000000000;
1320 parameter [63:0] INIT_C = 64'h0000000000000000;
1321 parameter [63:0] INIT_D = 64'h0000000000000000;
1322 parameter [63:0] INIT_E = 64'h0000000000000000;
1323 parameter [63:0] INIT_F = 64'h0000000000000000;
1324 parameter [63:0] INIT_G = 64'h0000000000000000;
1325 parameter [63:0] INIT_H = 64'h0000000000000000;
1326 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1327 reg [63:0] mem_a = INIT_A;
1328 reg [63:0] mem_b = INIT_B;
1329 reg [63:0] mem_c = INIT_C;
1330 reg [63:0] mem_d = INIT_D;
1331 reg [63:0] mem_e = INIT_E;
1332 reg [63:0] mem_f = INIT_F;
1333 reg [63:0] mem_g = INIT_G;
1334 reg [63:0] mem_h = INIT_H;
1335 assign DOA = mem_a[2*ADDRA+:2];
1336 assign DOB = mem_b[2*ADDRB+:2];
1337 assign DOC = mem_c[2*ADDRC+:2];
1338 assign DOD = mem_d[2*ADDRD+:2];
1339 assign DOE = mem_e[2*ADDRE+:2];
1340 assign DOF = mem_f[2*ADDRF+:2];
1341 assign DOG = mem_g[2*ADDRG+:2];
1342 assign DOH = mem_h[2*ADDRH+:2];
1343 wire clk = WCLK ^ IS_WCLK_INVERTED;
1344 always @(posedge clk)
1345 if (WE) begin
1346 mem_a[2*ADDRH+:2] <= DIA;
1347 mem_b[2*ADDRH+:2] <= DIB;
1348 mem_c[2*ADDRH+:2] <= DIC;
1349 mem_d[2*ADDRH+:2] <= DID;
1350 mem_e[2*ADDRH+:2] <= DIE;
1351 mem_f[2*ADDRH+:2] <= DIF;
1352 mem_g[2*ADDRH+:2] <= DIG;
1353 mem_h[2*ADDRH+:2] <= DIH;
1354 end
1355 endmodule
1356
1357 module RAM64M (
1358 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
1359 (* abc9_arrival=1153 *)
1360 output DOA, DOB, DOC, DOD,
1361 input [5:0] ADDRA, ADDRB, ADDRC, ADDRD,
1362 input DIA, DIB, DIC, DID,
1363 (* clkbuf_sink *)
1364 (* invertible_pin = "IS_WCLK_INVERTED" *)
1365 input WCLK,
1366 input WE
1367 );
1368 parameter [63:0] INIT_A = 64'h0000000000000000;
1369 parameter [63:0] INIT_B = 64'h0000000000000000;
1370 parameter [63:0] INIT_C = 64'h0000000000000000;
1371 parameter [63:0] INIT_D = 64'h0000000000000000;
1372 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1373 reg [63:0] mem_a = INIT_A;
1374 reg [63:0] mem_b = INIT_B;
1375 reg [63:0] mem_c = INIT_C;
1376 reg [63:0] mem_d = INIT_D;
1377 assign DOA = mem_a[ADDRA];
1378 assign DOB = mem_b[ADDRB];
1379 assign DOC = mem_c[ADDRC];
1380 assign DOD = mem_d[ADDRD];
1381 wire clk = WCLK ^ IS_WCLK_INVERTED;
1382 always @(posedge clk)
1383 if (WE) begin
1384 mem_a[ADDRD] <= DIA;
1385 mem_b[ADDRD] <= DIB;
1386 mem_c[ADDRD] <= DIC;
1387 mem_d[ADDRD] <= DID;
1388 end
1389 endmodule
1390
1391 module RAM64M8 (
1392 output DOA,
1393 output DOB,
1394 output DOC,
1395 output DOD,
1396 output DOE,
1397 output DOF,
1398 output DOG,
1399 output DOH,
1400 input [5:0] ADDRA,
1401 input [5:0] ADDRB,
1402 input [5:0] ADDRC,
1403 input [5:0] ADDRD,
1404 input [5:0] ADDRE,
1405 input [5:0] ADDRF,
1406 input [5:0] ADDRG,
1407 input [5:0] ADDRH,
1408 input DIA,
1409 input DIB,
1410 input DIC,
1411 input DID,
1412 input DIE,
1413 input DIF,
1414 input DIG,
1415 input DIH,
1416 (* clkbuf_sink *)
1417 (* invertible_pin = "IS_WCLK_INVERTED" *)
1418 input WCLK,
1419 input WE
1420 );
1421 parameter [63:0] INIT_A = 64'h0000000000000000;
1422 parameter [63:0] INIT_B = 64'h0000000000000000;
1423 parameter [63:0] INIT_C = 64'h0000000000000000;
1424 parameter [63:0] INIT_D = 64'h0000000000000000;
1425 parameter [63:0] INIT_E = 64'h0000000000000000;
1426 parameter [63:0] INIT_F = 64'h0000000000000000;
1427 parameter [63:0] INIT_G = 64'h0000000000000000;
1428 parameter [63:0] INIT_H = 64'h0000000000000000;
1429 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
1430 reg [63:0] mem_a = INIT_A;
1431 reg [63:0] mem_b = INIT_B;
1432 reg [63:0] mem_c = INIT_C;
1433 reg [63:0] mem_d = INIT_D;
1434 reg [63:0] mem_e = INIT_E;
1435 reg [63:0] mem_f = INIT_F;
1436 reg [63:0] mem_g = INIT_G;
1437 reg [63:0] mem_h = INIT_H;
1438 assign DOA = mem_a[ADDRA];
1439 assign DOB = mem_b[ADDRB];
1440 assign DOC = mem_c[ADDRC];
1441 assign DOD = mem_d[ADDRD];
1442 assign DOE = mem_e[ADDRE];
1443 assign DOF = mem_f[ADDRF];
1444 assign DOG = mem_g[ADDRG];
1445 assign DOH = mem_h[ADDRH];
1446 wire clk = WCLK ^ IS_WCLK_INVERTED;
1447 always @(posedge clk)
1448 if (WE) begin
1449 mem_a[ADDRH] <= DIA;
1450 mem_b[ADDRH] <= DIB;
1451 mem_c[ADDRH] <= DIC;
1452 mem_d[ADDRH] <= DID;
1453 mem_e[ADDRH] <= DIE;
1454 mem_f[ADDRH] <= DIF;
1455 mem_g[ADDRH] <= DIG;
1456 mem_h[ADDRH] <= DIH;
1457 end
1458 endmodule
1459
1460 // ROM.
1461
1462 module ROM16X1 (
1463 output O,
1464 input A0, A1, A2, A3
1465 );
1466 parameter [15:0] INIT = 16'h0;
1467 assign O = INIT[{A3, A2, A1, A0}];
1468 endmodule
1469
1470 module ROM32X1 (
1471 output O,
1472 input A0, A1, A2, A3, A4
1473 );
1474 parameter [31:0] INIT = 32'h0;
1475 assign O = INIT[{A4, A3, A2, A1, A0}];
1476 endmodule
1477
1478 module ROM64X1 (
1479 output O,
1480 input A0, A1, A2, A3, A4, A5
1481 );
1482 parameter [63:0] INIT = 64'h0;
1483 assign O = INIT[{A5, A4, A3, A2, A1, A0}];
1484 endmodule
1485
1486 module ROM128X1 (
1487 output O,
1488 input A0, A1, A2, A3, A4, A5, A6
1489 );
1490 parameter [127:0] INIT = 128'h0;
1491 assign O = INIT[{A6, A5, A4, A3, A2, A1, A0}];
1492 endmodule
1493
1494 module ROM256X1 (
1495 output O,
1496 input A0, A1, A2, A3, A4, A5, A6, A7
1497 );
1498 parameter [255:0] INIT = 256'h0;
1499 assign O = INIT[{A7, A6, A5, A4, A3, A2, A1, A0}];
1500 endmodule
1501
1502 // Shift registers.
1503
1504 module SRL16 (
1505 output Q,
1506 input A0, A1, A2, A3,
1507 (* clkbuf_sink *)
1508 input CLK,
1509 input D
1510 );
1511 parameter [15:0] INIT = 16'h0000;
1512
1513 reg [15:0] r = INIT;
1514 assign Q = r[{A3,A2,A1,A0}];
1515 always @(posedge CLK) r <= { r[14:0], D };
1516 endmodule
1517
1518 module SRL16E (
1519 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
1520 (* abc9_arrival=1472 *)
1521 output Q,
1522 input A0, A1, A2, A3, CE,
1523 (* clkbuf_sink *)
1524 (* invertible_pin = "IS_CLK_INVERTED" *)
1525 input CLK,
1526 input D
1527 );
1528 parameter [15:0] INIT = 16'h0000;
1529 parameter [0:0] IS_CLK_INVERTED = 1'b0;
1530
1531 reg [15:0] r = INIT;
1532 assign Q = r[{A3,A2,A1,A0}];
1533 generate
1534 if (IS_CLK_INVERTED) begin
1535 always @(negedge CLK) if (CE) r <= { r[14:0], D };
1536 end
1537 else
1538 always @(posedge CLK) if (CE) r <= { r[14:0], D };
1539 endgenerate
1540 endmodule
1541
1542 module SRLC16 (
1543 output Q,
1544 output Q15,
1545 input A0, A1, A2, A3,
1546 (* clkbuf_sink *)
1547 input CLK,
1548 input D
1549 );
1550 parameter [15:0] INIT = 16'h0000;
1551
1552 reg [15:0] r = INIT;
1553 assign Q15 = r[15];
1554 assign Q = r[{A3,A2,A1,A0}];
1555 always @(posedge CLK) r <= { r[14:0], D };
1556 endmodule
1557
1558 module SRLC16E (
1559 output Q,
1560 output Q15,
1561 input A0, A1, A2, A3, CE,
1562 (* clkbuf_sink *)
1563 (* invertible_pin = "IS_CLK_INVERTED" *)
1564 input CLK,
1565 input D
1566 );
1567 parameter [15:0] INIT = 16'h0000;
1568 parameter [0:0] IS_CLK_INVERTED = 1'b0;
1569
1570 reg [15:0] r = INIT;
1571 assign Q15 = r[15];
1572 assign Q = r[{A3,A2,A1,A0}];
1573 generate
1574 if (IS_CLK_INVERTED) begin
1575 always @(negedge CLK) if (CE) r <= { r[14:0], D };
1576 end
1577 else
1578 always @(posedge CLK) if (CE) r <= { r[14:0], D };
1579 endgenerate
1580 endmodule
1581
1582 module SRLC32E (
1583 // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
1584 (* abc9_arrival=1472 *)
1585 output Q,
1586 (* abc9_arrival=1114 *)
1587 output Q31,
1588 input [4:0] A,
1589 input CE,
1590 (* clkbuf_sink *)
1591 (* invertible_pin = "IS_CLK_INVERTED" *)
1592 input CLK,
1593 input D
1594 );
1595 parameter [31:0] INIT = 32'h00000000;
1596 parameter [0:0] IS_CLK_INVERTED = 1'b0;
1597
1598 reg [31:0] r = INIT;
1599 assign Q31 = r[31];
1600 assign Q = r[A];
1601 generate
1602 if (IS_CLK_INVERTED) begin
1603 always @(negedge CLK) if (CE) r <= { r[30:0], D };
1604 end
1605 else
1606 always @(posedge CLK) if (CE) r <= { r[30:0], D };
1607 endgenerate
1608 endmodule
1609
1610 module CFGLUT5 (
1611 output CDO,
1612 output O5,
1613 output O6,
1614 input I4,
1615 input I3,
1616 input I2,
1617 input I1,
1618 input I0,
1619 input CDI,
1620 input CE,
1621 (* clkbuf_sink *)
1622 (* invertible_pin = "IS_CLK_INVERTED" *)
1623 input CLK
1624 );
1625 parameter [31:0] INIT = 32'h00000000;
1626 parameter [0:0] IS_CLK_INVERTED = 1'b0;
1627 wire clk = CLK ^ IS_CLK_INVERTED;
1628 reg [31:0] r = INIT;
1629 assign CDO = r[31];
1630 assign O5 = r[{1'b0, I3, I2, I1, I0}];
1631 assign O6 = r[{I4, I3, I2, I1, I0}];
1632 always @(posedge clk) if (CE) r <= {r[30:0], CDI};
1633 endmodule
1634
1635 // DSP
1636
1637 // Virtex 2, Virtex 2 Pro, Spartan 3.
1638
1639 // Asynchronous mode.
1640
1641 module MULT18X18 (
1642 input signed [17:0] A,
1643 input signed [17:0] B,
1644 output signed [35:0] P
1645 );
1646
1647 assign P = A * B;
1648
1649 endmodule
1650
1651 // Synchronous mode.
1652
1653 module MULT18X18S (
1654 input signed [17:0] A,
1655 input signed [17:0] B,
1656 output reg signed [35:0] P,
1657 (* clkbuf_sink *)
1658 input C,
1659 input CE,
1660 input R
1661 );
1662
1663 always @(posedge C)
1664 if (R)
1665 P <= 0;
1666 else if (CE)
1667 P <= A * B;
1668
1669 endmodule
1670
1671 // Spartan 3E, Spartan 3A.
1672
1673 module MULT18X18SIO (
1674 input signed [17:0] A,
1675 input signed [17:0] B,
1676 output signed [35:0] P,
1677 (* clkbuf_sink *)
1678 input CLK,
1679 input CEA,
1680 input CEB,
1681 input CEP,
1682 input RSTA,
1683 input RSTB,
1684 input RSTP,
1685 input signed [17:0] BCIN,
1686 output signed [17:0] BCOUT
1687 );
1688
1689 parameter integer AREG = 1;
1690 parameter integer BREG = 1;
1691 parameter B_INPUT = "DIRECT";
1692 parameter integer PREG = 1;
1693
1694 // The multiplier.
1695 wire signed [35:0] P_MULT;
1696 assign P_MULT = A_MULT * B_MULT;
1697
1698 // The cascade output.
1699 assign BCOUT = B_MULT;
1700
1701 // The B input multiplexer.
1702 wire signed [17:0] B_MUX;
1703 assign B_MUX = (B_INPUT == "DIRECT") ? B : BCIN;
1704
1705 // The registers.
1706 reg signed [17:0] A_REG;
1707 reg signed [17:0] B_REG;
1708 reg signed [35:0] P_REG;
1709
1710 initial begin
1711 A_REG = 0;
1712 B_REG = 0;
1713 P_REG = 0;
1714 end
1715
1716 always @(posedge CLK) begin
1717 if (RSTA)
1718 A_REG <= 0;
1719 else if (CEA)
1720 A_REG <= A;
1721
1722 if (RSTB)
1723 B_REG <= 0;
1724 else if (CEB)
1725 B_REG <= B_MUX;
1726
1727 if (RSTP)
1728 P_REG <= 0;
1729 else if (CEP)
1730 P_REG <= P_MULT;
1731 end
1732
1733 // The register enables.
1734 wire signed [17:0] A_MULT;
1735 wire signed [17:0] B_MULT;
1736 assign A_MULT = (AREG == 1) ? A_REG : A;
1737 assign B_MULT = (BREG == 1) ? B_REG : B_MUX;
1738 assign P = (PREG == 1) ? P_REG : P_MULT;
1739
1740 endmodule
1741
1742 // Spartan 3A DSP.
1743
1744 module DSP48A (
1745 input signed [17:0] A,
1746 input signed [17:0] B,
1747 input signed [47:0] C,
1748 input signed [17:0] D,
1749 input signed [47:0] PCIN,
1750 input CARRYIN,
1751 input [7:0] OPMODE,
1752 output signed [47:0] P,
1753 output signed [17:0] BCOUT,
1754 output signed [47:0] PCOUT,
1755 output CARRYOUT,
1756 (* clkbuf_sink *)
1757 input CLK,
1758 input CEA,
1759 input CEB,
1760 input CEC,
1761 input CED,
1762 input CEM,
1763 input CECARRYIN,
1764 input CEOPMODE,
1765 input CEP,
1766 input RSTA,
1767 input RSTB,
1768 input RSTC,
1769 input RSTD,
1770 input RSTM,
1771 input RSTCARRYIN,
1772 input RSTOPMODE,
1773 input RSTP
1774 );
1775
1776 parameter integer A0REG = 0;
1777 parameter integer A1REG = 1;
1778 parameter integer B0REG = 0;
1779 parameter integer B1REG = 1;
1780 parameter integer CREG = 1;
1781 parameter integer DREG = 1;
1782 parameter integer MREG = 1;
1783 parameter integer CARRYINREG = 1;
1784 parameter integer OPMODEREG = 1;
1785 parameter integer PREG = 1;
1786 parameter CARRYINSEL = "CARRYIN";
1787 parameter RSTTYPE = "SYNC";
1788
1789 // This is a strict subset of Spartan 6 -- reuse its model.
1790
1791 DSP48A1 #(
1792 .A0REG(A0REG),
1793 .A1REG(A1REG),
1794 .B0REG(B0REG),
1795 .B1REG(B1REG),
1796 .CREG(CREG),
1797 .DREG(DREG),
1798 .MREG(MREG),
1799 .CARRYINREG(CARRYINREG),
1800 .CARRYOUTREG(0),
1801 .OPMODEREG(OPMODEREG),
1802 .PREG(PREG),
1803 .CARRYINSEL(CARRYINSEL),
1804 .RSTTYPE(RSTTYPE)
1805 ) upgrade (
1806 .A(A),
1807 .B(B),
1808 .C(C),
1809 .D(D),
1810 .PCIN(PCIN),
1811 .CARRYIN(CARRYIN),
1812 .OPMODE(OPMODE),
1813 // M unconnected
1814 .P(P),
1815 .BCOUT(BCOUT),
1816 .PCOUT(PCOUT),
1817 .CARRYOUT(CARRYOUT),
1818 // CARRYOUTF unconnected
1819 .CLK(CLK),
1820 .CEA(CEA),
1821 .CEB(CEB),
1822 .CEC(CEC),
1823 .CED(CED),
1824 .CEM(CEM),
1825 .CECARRYIN(CECARRYIN),
1826 .CEOPMODE(CEOPMODE),
1827 .CEP(CEP),
1828 .RSTA(RSTA),
1829 .RSTB(RSTB),
1830 .RSTC(RSTC),
1831 .RSTD(RSTD),
1832 .RSTM(RSTM),
1833 .RSTCARRYIN(RSTCARRYIN),
1834 .RSTOPMODE(RSTOPMODE),
1835 .RSTP(RSTP)
1836 );
1837
1838 endmodule
1839
1840 // Spartan 6.
1841
1842 module DSP48A1 (
1843 input signed [17:0] A,
1844 input signed [17:0] B,
1845 input signed [47:0] C,
1846 input signed [17:0] D,
1847 input signed [47:0] PCIN,
1848 input CARRYIN,
1849 input [7:0] OPMODE,
1850 output signed [35:0] M,
1851 output signed [47:0] P,
1852 output signed [17:0] BCOUT,
1853 output signed [47:0] PCOUT,
1854 output CARRYOUT,
1855 output CARRYOUTF,
1856 (* clkbuf_sink *)
1857 input CLK,
1858 input CEA,
1859 input CEB,
1860 input CEC,
1861 input CED,
1862 input CEM,
1863 input CECARRYIN,
1864 input CEOPMODE,
1865 input CEP,
1866 input RSTA,
1867 input RSTB,
1868 input RSTC,
1869 input RSTD,
1870 input RSTM,
1871 input RSTCARRYIN,
1872 input RSTOPMODE,
1873 input RSTP
1874 );
1875
1876 parameter integer A0REG = 0;
1877 parameter integer A1REG = 1;
1878 parameter integer B0REG = 0;
1879 parameter integer B1REG = 1;
1880 parameter integer CREG = 1;
1881 parameter integer DREG = 1;
1882 parameter integer MREG = 1;
1883 parameter integer CARRYINREG = 1;
1884 parameter integer CARRYOUTREG = 1;
1885 parameter integer OPMODEREG = 1;
1886 parameter integer PREG = 1;
1887 parameter CARRYINSEL = "OPMODE5";
1888 parameter RSTTYPE = "SYNC";
1889
1890 wire signed [35:0] M_MULT;
1891 wire signed [47:0] P_IN;
1892 wire signed [17:0] A0_OUT;
1893 wire signed [17:0] B0_OUT;
1894 wire signed [17:0] A1_OUT;
1895 wire signed [17:0] B1_OUT;
1896 wire signed [17:0] B1_IN;
1897 wire signed [47:0] C_OUT;
1898 wire signed [17:0] D_OUT;
1899 wire signed [7:0] OPMODE_OUT;
1900 wire CARRYIN_OUT;
1901 wire CARRYOUT_IN;
1902 wire CARRYIN_IN;
1903 reg signed [47:0] XMUX;
1904 reg signed [47:0] ZMUX;
1905
1906 // The registers.
1907 reg signed [17:0] A0_REG;
1908 reg signed [17:0] A1_REG;
1909 reg signed [17:0] B0_REG;
1910 reg signed [17:0] B1_REG;
1911 reg signed [47:0] C_REG;
1912 reg signed [17:0] D_REG;
1913 reg signed [35:0] M_REG;
1914 reg signed [47:0] P_REG;
1915 reg [7:0] OPMODE_REG;
1916 reg CARRYIN_REG;
1917 reg CARRYOUT_REG;
1918
1919 initial begin
1920 A0_REG = 0;
1921 A1_REG = 0;
1922 B0_REG = 0;
1923 B1_REG = 0;
1924 C_REG = 0;
1925 D_REG = 0;
1926 M_REG = 0;
1927 P_REG = 0;
1928 OPMODE_REG = 0;
1929 CARRYIN_REG = 0;
1930 CARRYOUT_REG = 0;
1931 end
1932
1933 generate
1934
1935 if (RSTTYPE == "SYNC") begin
1936 always @(posedge CLK) begin
1937 if (RSTA) begin
1938 A0_REG <= 0;
1939 A1_REG <= 0;
1940 end else if (CEA) begin
1941 A0_REG <= A;
1942 A1_REG <= A0_OUT;
1943 end
1944 end
1945
1946 always @(posedge CLK) begin
1947 if (RSTB) begin
1948 B0_REG <= 0;
1949 B1_REG <= 0;
1950 end else if (CEB) begin
1951 B0_REG <= B;
1952 B1_REG <= B1_IN;
1953 end
1954 end
1955
1956 always @(posedge CLK) begin
1957 if (RSTC) begin
1958 C_REG <= 0;
1959 end else if (CEC) begin
1960 C_REG <= C;
1961 end
1962 end
1963
1964 always @(posedge CLK) begin
1965 if (RSTD) begin
1966 D_REG <= 0;
1967 end else if (CED) begin
1968 D_REG <= D;
1969 end
1970 end
1971
1972 always @(posedge CLK) begin
1973 if (RSTM) begin
1974 M_REG <= 0;
1975 end else if (CEM) begin
1976 M_REG <= M_MULT;
1977 end
1978 end
1979
1980 always @(posedge CLK) begin
1981 if (RSTP) begin
1982 P_REG <= 0;
1983 end else if (CEP) begin
1984 P_REG <= P_IN;
1985 end
1986 end
1987
1988 always @(posedge CLK) begin
1989 if (RSTOPMODE) begin
1990 OPMODE_REG <= 0;
1991 end else if (CEOPMODE) begin
1992 OPMODE_REG <= OPMODE;
1993 end
1994 end
1995
1996 always @(posedge CLK) begin
1997 if (RSTCARRYIN) begin
1998 CARRYIN_REG <= 0;
1999 CARRYOUT_REG <= 0;
2000 end else if (CECARRYIN) begin
2001 CARRYIN_REG <= CARRYIN_IN;
2002 CARRYOUT_REG <= CARRYOUT_IN;
2003 end
2004 end
2005 end else begin
2006 always @(posedge CLK, posedge RSTA) begin
2007 if (RSTA) begin
2008 A0_REG <= 0;
2009 A1_REG <= 0;
2010 end else if (CEA) begin
2011 A0_REG <= A;
2012 A1_REG <= A0_OUT;
2013 end
2014 end
2015
2016 always @(posedge CLK, posedge RSTB) begin
2017 if (RSTB) begin
2018 B0_REG <= 0;
2019 B1_REG <= 0;
2020 end else if (CEB) begin
2021 B0_REG <= B;
2022 B1_REG <= B1_IN;
2023 end
2024 end
2025
2026 always @(posedge CLK, posedge RSTC) begin
2027 if (RSTC) begin
2028 C_REG <= 0;
2029 end else if (CEC) begin
2030 C_REG <= C;
2031 end
2032 end
2033
2034 always @(posedge CLK, posedge RSTD) begin
2035 if (RSTD) begin
2036 D_REG <= 0;
2037 end else if (CED) begin
2038 D_REG <= D;
2039 end
2040 end
2041
2042 always @(posedge CLK, posedge RSTM) begin
2043 if (RSTM) begin
2044 M_REG <= 0;
2045 end else if (CEM) begin
2046 M_REG <= M_MULT;
2047 end
2048 end
2049
2050 always @(posedge CLK, posedge RSTP) begin
2051 if (RSTP) begin
2052 P_REG <= 0;
2053 end else if (CEP) begin
2054 P_REG <= P_IN;
2055 end
2056 end
2057
2058 always @(posedge CLK, posedge RSTOPMODE) begin
2059 if (RSTOPMODE) begin
2060 OPMODE_REG <= 0;
2061 end else if (CEOPMODE) begin
2062 OPMODE_REG <= OPMODE;
2063 end
2064 end
2065
2066 always @(posedge CLK, posedge RSTCARRYIN) begin
2067 if (RSTCARRYIN) begin
2068 CARRYIN_REG <= 0;
2069 CARRYOUT_REG <= 0;
2070 end else if (CECARRYIN) begin
2071 CARRYIN_REG <= CARRYIN_IN;
2072 CARRYOUT_REG <= CARRYOUT_IN;
2073 end
2074 end
2075 end
2076
2077 endgenerate
2078
2079 // The register enables.
2080 assign A0_OUT = (A0REG == 1) ? A0_REG : A;
2081 assign A1_OUT = (A1REG == 1) ? A1_REG : A0_OUT;
2082 assign B0_OUT = (B0REG == 1) ? B0_REG : B;
2083 assign B1_OUT = (B1REG == 1) ? B1_REG : B1_IN;
2084 assign C_OUT = (CREG == 1) ? C_REG : C;
2085 assign D_OUT = (DREG == 1) ? D_REG : D;
2086 assign M = (MREG == 1) ? M_REG : M_MULT;
2087 assign P = (PREG == 1) ? P_REG : P_IN;
2088 assign OPMODE_OUT = (OPMODEREG == 1) ? OPMODE_REG : OPMODE;
2089 assign CARRYIN_OUT = (CARRYINREG == 1) ? CARRYIN_REG : CARRYIN_IN;
2090 assign CARRYOUT = (CARRYOUTREG == 1) ? CARRYOUT_REG : CARRYOUT_IN;
2091 assign CARRYOUTF = CARRYOUT;
2092
2093 // The pre-adder.
2094 wire signed [17:0] PREADDER;
2095 assign B1_IN = OPMODE_OUT[4] ? PREADDER : B0_OUT;
2096 assign PREADDER = OPMODE_OUT[6] ? D_OUT - B0_OUT : D_OUT + B0_OUT;
2097
2098 // The multiplier.
2099 assign M_MULT = A1_OUT * B1_OUT;
2100
2101 // The carry in selection.
2102 assign CARRYIN_IN = (CARRYINSEL == "OPMODE5") ? OPMODE_OUT[5] : CARRYIN;
2103
2104 // The post-adder inputs.
2105 always @* begin
2106 case (OPMODE_OUT[1:0])
2107 2'b00: XMUX <= 0;
2108 2'b01: XMUX <= M;
2109 2'b10: XMUX <= P;
2110 2'b11: XMUX <= {D_OUT[11:0], A1_OUT, B1_OUT};
2111 default: XMUX <= 48'hxxxxxxxxxxxx;
2112 endcase
2113 end
2114
2115 always @* begin
2116 case (OPMODE_OUT[3:2])
2117 2'b00: ZMUX <= 0;
2118 2'b01: ZMUX <= PCIN;
2119 2'b10: ZMUX <= P;
2120 2'b11: ZMUX <= C_OUT;
2121 default: ZMUX <= 48'hxxxxxxxxxxxx;
2122 endcase
2123 end
2124
2125 // The post-adder.
2126 wire signed [48:0] X_EXT;
2127 wire signed [48:0] Z_EXT;
2128 assign X_EXT = {1'b0, XMUX};
2129 assign Z_EXT = {1'b0, ZMUX};
2130 assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
2131
2132 // Cascade outputs.
2133 assign BCOUT = B1_OUT;
2134 assign PCOUT = P;
2135
2136 endmodule
2137
2138 // TODO: DSP48 (Virtex 4).
2139
2140 // TODO: DSP48E (Virtex 5).
2141
2142 // Virtex 6, Series 7.
2143
2144 module DSP48E1 (
2145 output [29:0] ACOUT,
2146 output [17:0] BCOUT,
2147 output reg CARRYCASCOUT,
2148 output reg [3:0] CARRYOUT,
2149 output reg MULTSIGNOUT,
2150 output OVERFLOW,
2151 output reg signed [47:0] P,
2152 output reg PATTERNBDETECT,
2153 output reg PATTERNDETECT,
2154 output [47:0] PCOUT,
2155 output UNDERFLOW,
2156 input signed [29:0] A,
2157 input [29:0] ACIN,
2158 input [3:0] ALUMODE,
2159 input signed [17:0] B,
2160 input [17:0] BCIN,
2161 input [47:0] C,
2162 input CARRYCASCIN,
2163 input CARRYIN,
2164 input [2:0] CARRYINSEL,
2165 input CEA1,
2166 input CEA2,
2167 input CEAD,
2168 input CEALUMODE,
2169 input CEB1,
2170 input CEB2,
2171 input CEC,
2172 input CECARRYIN,
2173 input CECTRL,
2174 input CED,
2175 input CEINMODE,
2176 input CEM,
2177 input CEP,
2178 (* clkbuf_sink *) input CLK,
2179 input [24:0] D,
2180 input [4:0] INMODE,
2181 input MULTSIGNIN,
2182 input [6:0] OPMODE,
2183 input [47:0] PCIN,
2184 input RSTA,
2185 input RSTALLCARRYIN,
2186 input RSTALUMODE,
2187 input RSTB,
2188 input RSTC,
2189 input RSTCTRL,
2190 input RSTD,
2191 input RSTINMODE,
2192 input RSTM,
2193 input RSTP
2194 );
2195 parameter integer ACASCREG = 1;
2196 parameter integer ADREG = 1;
2197 parameter integer ALUMODEREG = 1;
2198 parameter integer AREG = 1;
2199 parameter AUTORESET_PATDET = "NO_RESET";
2200 parameter A_INPUT = "DIRECT";
2201 parameter integer BCASCREG = 1;
2202 parameter integer BREG = 1;
2203 parameter B_INPUT = "DIRECT";
2204 parameter integer CARRYINREG = 1;
2205 parameter integer CARRYINSELREG = 1;
2206 parameter integer CREG = 1;
2207 parameter integer DREG = 1;
2208 parameter integer INMODEREG = 1;
2209 parameter integer MREG = 1;
2210 parameter integer OPMODEREG = 1;
2211 parameter integer PREG = 1;
2212 parameter SEL_MASK = "MASK";
2213 parameter SEL_PATTERN = "PATTERN";
2214 parameter USE_DPORT = "FALSE";
2215 parameter USE_MULT = "MULTIPLY";
2216 parameter USE_PATTERN_DETECT = "NO_PATDET";
2217 parameter USE_SIMD = "ONE48";
2218 parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
2219 parameter [47:0] PATTERN = 48'h000000000000;
2220 parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
2221 parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
2222 parameter [0:0] IS_CLK_INVERTED = 1'b0;
2223 parameter [4:0] IS_INMODE_INVERTED = 5'b0;
2224 parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
2225
2226 initial begin
2227 `ifdef __ICARUS__
2228 if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
2229 if (SEL_MASK != "MASK") $fatal(1, "Unsupported SEL_MASK value");
2230 if (SEL_PATTERN != "PATTERN") $fatal(1, "Unsupported SEL_PATTERN value");
2231 if (USE_SIMD != "ONE48" && USE_SIMD != "TWO24" && USE_SIMD != "FOUR12") $fatal(1, "Unsupported USE_SIMD value");
2232 if (IS_ALUMODE_INVERTED != 4'b0) $fatal(1, "Unsupported IS_ALUMODE_INVERTED value");
2233 if (IS_CARRYIN_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CARRYIN_INVERTED value");
2234 if (IS_CLK_INVERTED != 1'b0) $fatal(1, "Unsupported IS_CLK_INVERTED value");
2235 if (IS_INMODE_INVERTED != 5'b0) $fatal(1, "Unsupported IS_INMODE_INVERTED value");
2236 if (IS_OPMODE_INVERTED != 7'b0) $fatal(1, "Unsupported IS_OPMODE_INVERTED value");
2237 `endif
2238 end
2239
2240 wire signed [29:0] A_muxed;
2241 wire signed [17:0] B_muxed;
2242
2243 generate
2244 if (A_INPUT == "CASCADE") assign A_muxed = ACIN;
2245 else assign A_muxed = A;
2246
2247 if (B_INPUT == "CASCADE") assign B_muxed = BCIN;
2248 else assign B_muxed = B;
2249 endgenerate
2250
2251 reg signed [29:0] Ar1, Ar2;
2252 reg signed [24:0] Dr;
2253 reg signed [17:0] Br1, Br2;
2254 reg signed [47:0] Cr;
2255 reg [4:0] INMODEr = 5'b0;
2256 reg [6:0] OPMODEr = 7'b0;
2257 reg [3:0] ALUMODEr = 4'b0;
2258 reg [2:0] CARRYINSELr = 3'b0;
2259
2260 generate
2261 // Configurable A register
2262 if (AREG == 2) begin
2263 initial Ar1 = 30'b0;
2264 initial Ar2 = 30'b0;
2265 always @(posedge CLK)
2266 if (RSTA) begin
2267 Ar1 <= 30'b0;
2268 Ar2 <= 30'b0;
2269 end else begin
2270 if (CEA1) Ar1 <= A_muxed;
2271 if (CEA2) Ar2 <= Ar1;
2272 end
2273 end else if (AREG == 1) begin
2274 //initial Ar1 = 30'b0;
2275 initial Ar2 = 30'b0;
2276 always @(posedge CLK)
2277 if (RSTA) begin
2278 Ar1 <= 30'b0;
2279 Ar2 <= 30'b0;
2280 end else begin
2281 if (CEA1) Ar1 <= A_muxed;
2282 if (CEA2) Ar2 <= A_muxed;
2283 end
2284 end else begin
2285 always @* Ar1 <= A_muxed;
2286 always @* Ar2 <= A_muxed;
2287 end
2288
2289 // Configurable B register
2290 if (BREG == 2) begin
2291 initial Br1 = 25'b0;
2292 initial Br2 = 25'b0;
2293 always @(posedge CLK)
2294 if (RSTB) begin
2295 Br1 <= 18'b0;
2296 Br2 <= 18'b0;
2297 end else begin
2298 if (CEB1) Br1 <= B_muxed;
2299 if (CEB2) Br2 <= Br1;
2300 end
2301 end else if (BREG == 1) begin
2302 //initial Br1 = 25'b0;
2303 initial Br2 = 25'b0;
2304 always @(posedge CLK)
2305 if (RSTB) begin
2306 Br1 <= 18'b0;
2307 Br2 <= 18'b0;
2308 end else begin
2309 if (CEB1) Br1 <= B_muxed;
2310 if (CEB2) Br2 <= B_muxed;
2311 end
2312 end else begin
2313 always @* Br1 <= B_muxed;
2314 always @* Br2 <= B_muxed;
2315 end
2316
2317 // C and D registers
2318 if (CREG == 1) initial Cr = 48'b0;
2319 if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end
2320 else always @* Cr <= C;
2321
2322 if (CREG == 1) initial Dr = 25'b0;
2323 if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
2324 else always @* Dr <= D;
2325
2326 // Control registers
2327 if (INMODEREG == 1) initial INMODEr = 5'b0;
2328 if (INMODEREG == 1) begin always @(posedge CLK) if (RSTINMODE) INMODEr <= 5'b0; else if (CEINMODE) INMODEr <= INMODE; end
2329 else always @* INMODEr <= INMODE;
2330 if (OPMODEREG == 1) initial OPMODEr = 7'b0;
2331 if (OPMODEREG == 1) begin always @(posedge CLK) if (RSTCTRL) OPMODEr <= 7'b0; else if (CECTRL) OPMODEr <= OPMODE; end
2332 else always @* OPMODEr <= OPMODE;
2333 if (ALUMODEREG == 1) initial ALUMODEr = 4'b0;
2334 if (ALUMODEREG == 1) begin always @(posedge CLK) if (RSTALUMODE) ALUMODEr <= 4'b0; else if (CEALUMODE) ALUMODEr <= ALUMODE; end
2335 else always @* ALUMODEr <= ALUMODE;
2336 if (CARRYINSELREG == 1) initial CARRYINSELr = 3'b0;
2337 if (CARRYINSELREG == 1) begin always @(posedge CLK) if (RSTCTRL) CARRYINSELr <= 3'b0; else if (CECTRL) CARRYINSELr <= CARRYINSEL; end
2338 else always @* CARRYINSELr <= CARRYINSEL;
2339 endgenerate
2340
2341 // A and B cascade
2342 generate
2343 if (ACASCREG == 1 && AREG == 2) assign ACOUT = Ar1;
2344 else assign ACOUT = Ar2;
2345 if (BCASCREG == 1 && BREG == 2) assign BCOUT = Br1;
2346 else assign BCOUT = Br2;
2347 endgenerate
2348
2349 // A/D input selection and pre-adder
2350 wire signed [29:0] Ar12_muxed = INMODEr[0] ? Ar1 : Ar2;
2351 wire signed [24:0] Ar12_gated = INMODEr[1] ? 25'b0 : Ar12_muxed;
2352 wire signed [24:0] Dr_gated = INMODEr[2] ? Dr : 25'b0;
2353 wire signed [24:0] AD_result = INMODEr[3] ? (Dr_gated - Ar12_gated) : (Dr_gated + Ar12_gated);
2354 reg signed [24:0] ADr;
2355
2356 generate
2357 if (ADREG == 1) initial ADr = 25'b0;
2358 if (ADREG == 1) begin always @(posedge CLK) if (RSTD) ADr <= 25'b0; else if (CEAD) ADr <= AD_result; end
2359 else always @* ADr <= AD_result;
2360 endgenerate
2361
2362 // 25x18 multiplier
2363 wire signed [24:0] A_MULT;
2364 wire signed [17:0] B_MULT = INMODEr[4] ? Br1 : Br2;
2365 generate
2366 if (USE_DPORT == "TRUE") assign A_MULT = ADr;
2367 else assign A_MULT = Ar12_gated;
2368 endgenerate
2369
2370 wire signed [42:0] M = A_MULT * B_MULT;
2371 wire signed [42:0] Mx = (CARRYINSEL == 3'b010) ? 43'bx : M;
2372 reg signed [42:0] Mr = 43'b0;
2373
2374 // Multiplier result register
2375 generate
2376 if (MREG == 1) begin always @(posedge CLK) if (RSTM) Mr <= 43'b0; else if (CEM) Mr <= Mx; end
2377 else always @* Mr <= Mx;
2378 endgenerate
2379
2380 wire signed [42:0] Mrx = (CARRYINSELr == 3'b010) ? 43'bx : Mr;
2381
2382 // X, Y and Z ALU inputs
2383 reg signed [47:0] X, Y, Z;
2384
2385 always @* begin
2386 // X multiplexer
2387 case (OPMODEr[1:0])
2388 2'b00: X = 48'b0;
2389 2'b01: begin X = $signed(Mrx);
2390 `ifdef __ICARUS__
2391 if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
2392 `endif
2393 end
2394 2'b10: begin X = P;
2395 `ifdef __ICARUS__
2396 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[1:0] is 2'b10");
2397 `endif
2398 end
2399 2'b11: X = $signed({Ar2, Br2});
2400 default: X = 48'bx;
2401 endcase
2402
2403 // Y multiplexer
2404 case (OPMODEr[3:2])
2405 2'b00: Y = 48'b0;
2406 2'b01: begin Y = 48'b0; // FIXME: more accurate partial product modelling?
2407 `ifdef __ICARUS__
2408 if (OPMODEr[1:0] != 2'b01) $fatal(1, "OPMODEr[1:0] must be 2'b01 when OPMODEr[3:2] is 2'b01");
2409 `endif
2410 end
2411 2'b10: Y = {48{1'b1}};
2412 2'b11: Y = Cr;
2413 default: Y = 48'bx;
2414 endcase
2415
2416 // Z multiplexer
2417 case (OPMODEr[6:4])
2418 3'b000: Z = 48'b0;
2419 3'b001: Z = PCIN;
2420 3'b010: begin Z = P;
2421 `ifdef __ICARUS__
2422 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
2423 `endif
2424 end
2425 3'b011: Z = Cr;
2426 3'b100: begin Z = P;
2427 `ifdef __ICARUS__
2428 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
2429 if (OPMODEr[3:0] != 4'b1000) $fatal(1, "OPMODEr[3:0] must be 4'b1000 when OPMODEr[6:4] i0s 3'b100");
2430 `endif
2431 end
2432 3'b101: Z = $signed(PCIN[47:17]);
2433 3'b110: Z = $signed(P[47:17]);
2434 default: Z = 48'bx;
2435 endcase
2436 end
2437
2438 // Carry in
2439 wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
2440 reg CARRYINr = 1'b0, A24_xnor_B17 = 1'b0;
2441 generate
2442 if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
2443 else always @* CARRYINr = CARRYIN;
2444
2445 if (MREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) A24_xnor_B17 <= 1'b0; else if (CEM) A24_xnor_B17 <= A24_xnor_B17d; end
2446 else always @* A24_xnor_B17 = A24_xnor_B17d;
2447 endgenerate
2448
2449 reg cin_muxed;
2450
2451 always @(*) begin
2452 case (CARRYINSELr)
2453 3'b000: cin_muxed = CARRYINr;
2454 3'b001: cin_muxed = ~PCIN[47];
2455 3'b010: cin_muxed = CARRYCASCIN;
2456 3'b011: cin_muxed = PCIN[47];
2457 3'b100: cin_muxed = CARRYCASCOUT;
2458 3'b101: cin_muxed = ~P[47];
2459 3'b110: cin_muxed = A24_xnor_B17;
2460 3'b111: cin_muxed = P[47];
2461 default: cin_muxed = 1'bx;
2462 endcase
2463 end
2464
2465 wire alu_cin = (ALUMODEr[3] || ALUMODEr[2]) ? 1'b0 : cin_muxed;
2466
2467 // ALU core
2468 wire [47:0] Z_muxinv = ALUMODEr[0] ? ~Z : Z;
2469 wire [47:0] xor_xyz = X ^ Y ^ Z_muxinv;
2470 wire [47:0] maj_xyz = (X & Y) | (X & Z_muxinv) | (Y & Z_muxinv);
2471
2472 wire [47:0] xor_xyz_muxed = ALUMODEr[3] ? maj_xyz : xor_xyz;
2473 wire [47:0] maj_xyz_gated = ALUMODEr[2] ? 48'b0 : maj_xyz;
2474
2475 wire [48:0] maj_xyz_simd_gated;
2476 wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
2477 wire [47:0] alu_sum;
2478 assign int_carry_in[0] = 1'b0;
2479 wire [3:0] carryout_reset;
2480
2481 generate
2482 if (USE_SIMD == "FOUR12") begin
2483 assign maj_xyz_simd_gated = {
2484 maj_xyz_gated[47:36],
2485 1'b0, maj_xyz_gated[34:24],
2486 1'b0, maj_xyz_gated[22:12],
2487 1'b0, maj_xyz_gated[10:0],
2488 alu_cin
2489 };
2490 assign int_carry_in[3:1] = 3'b000;
2491 assign ext_carry_out = {
2492 int_carry_out[3],
2493 maj_xyz_gated[35] ^ int_carry_out[2],
2494 maj_xyz_gated[23] ^ int_carry_out[1],
2495 maj_xyz_gated[11] ^ int_carry_out[0]
2496 };
2497 assign carryout_reset = 4'b0000;
2498 end else if (USE_SIMD == "TWO24") begin
2499 assign maj_xyz_simd_gated = {
2500 maj_xyz_gated[47:24],
2501 1'b0, maj_xyz_gated[22:0],
2502 alu_cin
2503 };
2504 assign int_carry_in[3:1] = {int_carry_out[2], 1'b0, int_carry_out[0]};
2505 assign ext_carry_out = {
2506 int_carry_out[3],
2507 1'bx,
2508 maj_xyz_gated[23] ^ int_carry_out[1],
2509 1'bx
2510 };
2511 assign carryout_reset = 4'b0x0x;
2512 end else begin
2513 assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
2514 assign int_carry_in[3:1] = int_carry_out[2:0];
2515 assign ext_carry_out = {
2516 int_carry_out[3],
2517 3'bxxx
2518 };
2519 assign carryout_reset = 4'b0xxx;
2520 end
2521
2522 genvar i;
2523 for (i = 0; i < 4; i = i + 1)
2524 assign {int_carry_out[i], alu_sum[i*12 +: 12]} = {1'b0, maj_xyz_simd_gated[i*12 +: ((i == 3) ? 13 : 12)]}
2525 + xor_xyz_muxed[i*12 +: 12] + int_carry_in[i];
2526 endgenerate
2527
2528 wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
2529 wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
2530 ((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
2531 wire CARRYCASCOUTd = ext_carry_out[3];
2532 wire MULTSIGNOUTd = Mrx[42];
2533
2534 generate
2535 if (PREG == 1) begin
2536 initial P = 48'b0;
2537 initial CARRYOUT = carryout_reset;
2538 initial CARRYCASCOUT = 1'b0;
2539 initial MULTSIGNOUT = 1'b0;
2540 always @(posedge CLK)
2541 if (RSTP) begin
2542 P <= 48'b0;
2543 CARRYOUT <= carryout_reset;
2544 CARRYCASCOUT <= 1'b0;
2545 MULTSIGNOUT <= 1'b0;
2546 end else if (CEP) begin
2547 P <= Pd;
2548 CARRYOUT <= CARRYOUTd;
2549 CARRYCASCOUT <= CARRYCASCOUTd;
2550 MULTSIGNOUT <= MULTSIGNOUTd;
2551 end
2552 end else begin
2553 always @* begin
2554 P = Pd;
2555 CARRYOUT = CARRYOUTd;
2556 CARRYCASCOUT = CARRYCASCOUTd;
2557 MULTSIGNOUT = MULTSIGNOUTd;
2558 end
2559 end
2560 endgenerate
2561
2562 assign PCOUT = P;
2563
2564 generate
2565 wire PATTERNDETECTd, PATTERNBDETECTd;
2566
2567 if (USE_PATTERN_DETECT == "PATDET") begin
2568 // TODO: Support SEL_PATTERN != "PATTERN" and SEL_MASK != "MASK
2569 assign PATTERNDETECTd = &(~(Pd ^ PATTERN) | MASK);
2570 assign PATTERNBDETECTd = &((Pd ^ PATTERN) | MASK);
2571 end else begin
2572 assign PATTERNDETECTd = 1'b1;
2573 assign PATTERNBDETECTd = 1'b1;
2574 end
2575
2576 if (PREG == 1) begin
2577 reg PATTERNDETECTPAST, PATTERNBDETECTPAST;
2578 initial PATTERNDETECT = 1'b0;
2579 initial PATTERNBDETECT = 1'b0;
2580 initial PATTERNDETECTPAST = 1'b0;
2581 initial PATTERNBDETECTPAST = 1'b0;
2582 always @(posedge CLK)
2583 if (RSTP) begin
2584 PATTERNDETECT <= 1'b0;
2585 PATTERNBDETECT <= 1'b0;
2586 PATTERNDETECTPAST <= 1'b0;
2587 PATTERNBDETECTPAST <= 1'b0;
2588 end else if (CEP) begin
2589 PATTERNDETECT <= PATTERNDETECTd;
2590 PATTERNBDETECT <= PATTERNBDETECTd;
2591 PATTERNDETECTPAST <= PATTERNDETECT;
2592 PATTERNBDETECTPAST <= PATTERNBDETECT;
2593 end
2594 assign OVERFLOW = &{PATTERNDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
2595 assign UNDERFLOW = &{PATTERNBDETECTPAST, ~PATTERNBDETECT, ~PATTERNDETECT};
2596 end else begin
2597 always @* begin
2598 PATTERNDETECT = PATTERNDETECTd;
2599 PATTERNBDETECT = PATTERNBDETECTd;
2600 end
2601 assign OVERFLOW = 1'bx, UNDERFLOW = 1'bx;
2602 end
2603 endgenerate
2604
2605 endmodule
2606
2607 // TODO: DSP48E2 (Ultrascale).