2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 * 2019 Eddie Hung <eddie@fpgeh.com>
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 // The following techmapping rules are intended to be run (with -max_iter 1)
22 // before invoking the `abc9` pass in order to transform the design into
23 // a format that it understands.
25 // For example, (complex) flip-flops are expected to be described as an
26 // combinatorial box (containing all control logic such as clock enable
27 // or synchronous resets) followed by a basic D-Q flop.
28 // Yosys will automatically analyse the simulation model (described in
29 // cells_sim.v) and detach any $_DFF_P_ or $_DFF_N_ cells present in
30 // order to extract the combinatorial control logic left behind.
31 // Specifically, a simulation model similar to the one below:
33 // ++===================================++
36 // D -->>-----< > +------+ ||
37 // R -->>-----< Comb. > |$_DFF_| ||
38 // CE -->>-----< logic >-----| [NP]_|---+---->>-- Q
39 // || +--< > +------+ | ||
42 // || +----------------------------+ ||
44 // ++===================================++
46 // is transformed into:
48 // ++==================++
52 // D -->>-----< > || +------+
53 // R -->>-----< Comb. > || |$__ABC|
54 // CE -->>-----< logic >--->>-- $nextQ --| _FF_ |--+-->> Q
55 // $abc9_currQ +-->>-----< > || +------+ |
58 // | ++==================++ |
60 // +----------------------------------------------+
62 // The purpose of the following FD* rules are to wrap the flop with:
63 // (a) a special $__ABC9_FF_ in front of the FD*'s output, indicating to abc9
64 // the connectivity of its basic D-Q flop
65 // (b) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock
66 // domain (used when partitioning the module so that `abc9' only
67 // performs sequential synthesis (with reachability analysis) correctly on
68 // one domain at a time)
69 // (c) a special _TECHMAP_REPLACE_.$abc9_control that captures the control
70 // domain (which, combined with this cell type, encodes to `abc9' which
71 // flops may be merged together)
72 // (d) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback
73 // into the (combinatorial) FD* cell to facilitate clock-enable behaviour
74 module FDRE (output reg Q, input C, CE, D, R);
75 parameter [0:0] INIT = 1'b0;
76 parameter [0:0] IS_C_INVERTED = 1'b0;
77 parameter [0:0] IS_D_INVERTED = 1'b0;
78 parameter [0:0] IS_R_INVERTED = 1'b0;
82 .IS_C_INVERTED(IS_C_INVERTED),
83 .IS_D_INVERTED(IS_D_INVERTED),
84 .IS_R_INVERTED(IS_R_INVERTED)
86 .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R)
88 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q));
91 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
92 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, R, IS_R_INVERTED};
93 wire _TECHMAP_REPLACE_.$abc9_currQ = Q;
95 module FDRE_1 (output reg Q, input C, CE, D, R);
96 parameter [0:0] INIT = 1'b0;
100 ) _TECHMAP_REPLACE_ (
101 .D(D), .Q($nextQ), .C(C), .CE(CE), .R(R)
103 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q));
106 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
107 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, R, 1'b0 /* IS_R_INVERTED */};
108 wire _TECHMAP_REPLACE_.$abc9_currQ = Q;
111 module FDCE (output reg Q, input C, CE, D, CLR);
112 parameter [0:0] INIT = 1'b0;
113 parameter [0:0] IS_C_INVERTED = 1'b0;
114 parameter [0:0] IS_D_INVERTED = 1'b0;
115 parameter [0:0] IS_CLR_INVERTED = 1'b0;
116 wire $nextQ, $abc9_currQ;
119 .IS_C_INVERTED(IS_C_INVERTED),
120 .IS_D_INVERTED(IS_D_INVERTED),
121 .IS_CLR_INVERTED(IS_CLR_INVERTED)
122 ) _TECHMAP_REPLACE_ (
123 .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR)
124 // ^^^ Note that async
125 // control is not directly
126 // supported by abc9 but its
127 // behaviour is captured by
128 // $__ABC9_ASYNC below
130 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ));
131 // Since this is an async flop, async behaviour is also dealt with
132 // using the $_ABC9_ASYNC box by abc9_map.v
133 \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(Q));
136 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
137 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, CLR, IS_CLR_INVERTED};
138 wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
140 module FDCE_1 (output reg Q, input C, CE, D, CLR);
141 parameter [0:0] INIT = 1'b0;
142 wire $nextQ, $abc9_currQ;
145 ) _TECHMAP_REPLACE_ (
146 .D(D), .Q($nextQ), .C(C), .CE(CE), .CLR(CLR)
147 // ^^^ Note that async
148 // control is not directly
149 // supported by abc9 but its
150 // behaviour is captured by
151 // $__ABC9_ASYNC below
153 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ));
154 \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(CLR), .Y(Q));
157 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
158 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, CLR, 1'b0 /* IS_CLR_INVERTED */};
159 wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
162 module FDPE (output reg Q, input C, CE, D, PRE);
163 parameter [0:0] INIT = 1'b0;
164 parameter [0:0] IS_C_INVERTED = 1'b0;
165 parameter [0:0] IS_D_INVERTED = 1'b0;
166 parameter [0:0] IS_PRE_INVERTED = 1'b0;
167 wire $nextQ, $abc9_currQ;
170 .IS_C_INVERTED(IS_C_INVERTED),
171 .IS_D_INVERTED(IS_D_INVERTED),
172 .IS_PRE_INVERTED(IS_PRE_INVERTED),
173 ) _TECHMAP_REPLACE_ (
174 .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE)
175 // ^^^ Note that async
176 // control is not directly
177 // supported by abc9 but its
178 // behaviour is captured by
179 // $__ABC9_ASYNC below
181 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ));
182 \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(Q));
185 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
186 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, PRE, IS_PRE_INVERTED};
187 wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
189 module FDPE_1 (output reg Q, input C, CE, D, PRE);
190 parameter [0:0] INIT = 1'b0;
191 wire $nextQ, $abc9_currQ;
194 ) _TECHMAP_REPLACE_ (
195 .D(D), .Q($nextQ), .C(C), .CE(CE), .PRE(PRE)
196 // ^^^ Note that async
197 // control is not directly
198 // supported by abc9 but its
199 // behaviour is captured by
200 // $__ABC9_ASYNC below
202 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q($abc9_currQ));
203 \$__ABC9_ASYNC abc_async (.A($abc9_currQ), .S(PRE), .Y(Q));
206 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
207 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, PRE, 1'b0 /* IS_PRE_INVERTED */};
208 wire _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
211 module FDSE (output reg Q, input C, CE, D, S);
212 parameter [0:0] INIT = 1'b1;
213 parameter [0:0] IS_C_INVERTED = 1'b0;
214 parameter [0:0] IS_D_INVERTED = 1'b0;
215 parameter [0:0] IS_S_INVERTED = 1'b0;
219 .IS_C_INVERTED(IS_C_INVERTED),
220 .IS_D_INVERTED(IS_D_INVERTED),
221 .IS_S_INVERTED(IS_S_INVERTED)
222 ) _TECHMAP_REPLACE_ (
223 .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S)
225 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q));
228 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
229 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, IS_D_INVERTED, S, IS_S_INVERTED};
230 wire _TECHMAP_REPLACE_.$abc9_currQ = Q;
232 module FDSE_1 (output reg Q, input C, CE, D, S);
233 parameter [0:0] INIT = 1'b1;
237 ) _TECHMAP_REPLACE_ (
238 .D(D), .Q($nextQ), .C(C), .CE(CE), .S(S)
240 \$__ABC9_FF_ abc_dff (.D($nextQ), .Q(Q));
243 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
244 wire [3:0] _TECHMAP_REPLACE_.$abc9_control = {CE, 1'b0 /* IS_D_INVERTED */, S, 1'b0 /* IS_S_INVERTED */};
245 wire _TECHMAP_REPLACE_.$abc9_currQ = Q;
250 (* techmap_autopurge *) input D,
251 (* techmap_autopurge *) input WCLK,
252 (* techmap_autopurge *) input WE,
253 (* techmap_autopurge *) input A0, A1, A2, A3, A4,
254 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
256 parameter INIT = 32'h0;
257 parameter IS_WCLK_INVERTED = 1'b0;
260 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
261 ) _TECHMAP_REPLACE_ (
262 .DPO(\$DPO ), .SPO(\$SPO ),
263 .D(D), .WCLK(WCLK), .WE(WE),
264 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
265 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
267 \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
268 \$__ABC9_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
273 (* techmap_autopurge *) input D,
274 (* techmap_autopurge *) input WCLK,
275 (* techmap_autopurge *) input WE,
276 (* techmap_autopurge *) input A0, A1, A2, A3, A4, A5,
277 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
279 parameter INIT = 64'h0;
280 parameter IS_WCLK_INVERTED = 1'b0;
283 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
284 ) _TECHMAP_REPLACE_ (
285 .DPO(\$DPO ), .SPO(\$SPO ),
286 .D(D), .WCLK(WCLK), .WE(WE),
287 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
288 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
290 \$__ABC9_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
291 \$__ABC9_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
296 (* techmap_autopurge *) input D,
297 (* techmap_autopurge *) input WCLK,
298 (* techmap_autopurge *) input WE,
299 (* techmap_autopurge *) input [6:0] A, DPRA
301 parameter INIT = 128'h0;
302 parameter IS_WCLK_INVERTED = 1'b0;
305 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
306 ) _TECHMAP_REPLACE_ (
307 .DPO(\$DPO ), .SPO(\$SPO ),
308 .D(D), .WCLK(WCLK), .WE(WE),
312 \$__ABC9_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
313 \$__ABC9_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
318 (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
320 parameter [15:0] INIT = 16'h0000;
321 parameter [0:0] IS_CLK_INVERTED = 1'b0;
324 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
325 ) _TECHMAP_REPLACE_ (
327 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
329 \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q));
335 (* techmap_autopurge *) input [4:0] A,
336 (* techmap_autopurge *) input CE, CLK, D
338 parameter [31:0] INIT = 32'h00000000;
339 parameter [0:0] IS_CLK_INVERTED = 1'b0;
342 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
343 ) _TECHMAP_REPLACE_ (
345 .A(A), .CE(CE), .CLK(CLK), .D(D)
347 \$__ABC9_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
351 (* techmap_autopurge *) output [29:0] ACOUT,
352 (* techmap_autopurge *) output [17:0] BCOUT,
353 (* techmap_autopurge *) output reg CARRYCASCOUT,
354 (* techmap_autopurge *) output reg [3:0] CARRYOUT,
355 (* techmap_autopurge *) output reg MULTSIGNOUT,
356 (* techmap_autopurge *) output OVERFLOW,
357 (* techmap_autopurge *) output reg signed [47:0] P,
358 (* techmap_autopurge *) output PATTERNBDETECT,
359 (* techmap_autopurge *) output PATTERNDETECT,
360 (* techmap_autopurge *) output [47:0] PCOUT,
361 (* techmap_autopurge *) output UNDERFLOW,
362 (* techmap_autopurge *) input signed [29:0] A,
363 (* techmap_autopurge *) input [29:0] ACIN,
364 (* techmap_autopurge *) input [3:0] ALUMODE,
365 (* techmap_autopurge *) input signed [17:0] B,
366 (* techmap_autopurge *) input [17:0] BCIN,
367 (* techmap_autopurge *) input [47:0] C,
368 (* techmap_autopurge *) input CARRYCASCIN,
369 (* techmap_autopurge *) input CARRYIN,
370 (* techmap_autopurge *) input [2:0] CARRYINSEL,
371 (* techmap_autopurge *) input CEA1,
372 (* techmap_autopurge *) input CEA2,
373 (* techmap_autopurge *) input CEAD,
374 (* techmap_autopurge *) input CEALUMODE,
375 (* techmap_autopurge *) input CEB1,
376 (* techmap_autopurge *) input CEB2,
377 (* techmap_autopurge *) input CEC,
378 (* techmap_autopurge *) input CECARRYIN,
379 (* techmap_autopurge *) input CECTRL,
380 (* techmap_autopurge *) input CED,
381 (* techmap_autopurge *) input CEINMODE,
382 (* techmap_autopurge *) input CEM,
383 (* techmap_autopurge *) input CEP,
384 (* techmap_autopurge *) input CLK,
385 (* techmap_autopurge *) input [24:0] D,
386 (* techmap_autopurge *) input [4:0] INMODE,
387 (* techmap_autopurge *) input MULTSIGNIN,
388 (* techmap_autopurge *) input [6:0] OPMODE,
389 (* techmap_autopurge *) input [47:0] PCIN,
390 (* techmap_autopurge *) input RSTA,
391 (* techmap_autopurge *) input RSTALLCARRYIN,
392 (* techmap_autopurge *) input RSTALUMODE,
393 (* techmap_autopurge *) input RSTB,
394 (* techmap_autopurge *) input RSTC,
395 (* techmap_autopurge *) input RSTCTRL,
396 (* techmap_autopurge *) input RSTD,
397 (* techmap_autopurge *) input RSTINMODE,
398 (* techmap_autopurge *) input RSTM,
399 (* techmap_autopurge *) input RSTP
401 parameter integer ACASCREG = 1;
402 parameter integer ADREG = 1;
403 parameter integer ALUMODEREG = 1;
404 parameter integer AREG = 1;
405 parameter AUTORESET_PATDET = "NO_RESET";
406 parameter A_INPUT = "DIRECT";
407 parameter integer BCASCREG = 1;
408 parameter integer BREG = 1;
409 parameter B_INPUT = "DIRECT";
410 parameter integer CARRYINREG = 1;
411 parameter integer CARRYINSELREG = 1;
412 parameter integer CREG = 1;
413 parameter integer DREG = 1;
414 parameter integer INMODEREG = 1;
415 parameter integer MREG = 1;
416 parameter integer OPMODEREG = 1;
417 parameter integer PREG = 1;
418 parameter SEL_MASK = "MASK";
419 parameter SEL_PATTERN = "PATTERN";
420 parameter USE_DPORT = "FALSE";
421 parameter USE_MULT = "MULTIPLY";
422 parameter USE_PATTERN_DETECT = "NO_PATDET";
423 parameter USE_SIMD = "ONE48";
424 parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
425 parameter [47:0] PATTERN = 48'h000000000000;
426 parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
427 parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
428 parameter [0:0] IS_CLK_INVERTED = 1'b0;
429 parameter [4:0] IS_INMODE_INVERTED = 5'b0;
430 parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
432 parameter _TECHMAP_CELLTYPE_ = "";
433 localparam techmap_guard = (_TECHMAP_CELLTYPE_ != "");
435 `define DSP48E1_INST(__CELL__) """
439 .ALUMODEREG(ALUMODEREG),
441 .AUTORESET_PATDET(AUTORESET_PATDET),
446 .CARRYINREG(CARRYINREG),
447 .CARRYINSELREG(CARRYINSELREG),
450 .INMODEREG(INMODEREG),
452 .OPMODEREG(OPMODEREG),
455 .SEL_PATTERN(SEL_PATTERN),
456 .USE_DPORT(USE_DPORT),
458 .USE_PATTERN_DETECT(USE_PATTERN_DETECT),
462 .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
463 .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
464 .IS_CLK_INVERTED(IS_CLK_INVERTED),
465 .IS_INMODE_INVERTED(IS_INMODE_INVERTED),
466 .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
467 ) _TECHMAP_REPLACE_ (
470 .CARRYCASCOUT(CARRYCASCOUT),
472 .MULTSIGNOUT(MULTSIGNOUT),
475 .PATTERNBDETECT(PATTERNBDETECT),
476 .PATTERNDETECT(PATTERNDETECT),
478 .UNDERFLOW(UNDERFLOW),
485 .CARRYCASCIN(CARRYCASCIN),
487 .CARRYINSEL(CARRYINSEL),
491 .CEALUMODE(CEALUMODE),
495 .CECARRYIN(CECARRYIN),
504 .MULTSIGNIN(MULTSIGNIN),
508 .RSTALLCARRYIN(RSTALLCARRYIN),
509 .RSTALUMODE(RSTALUMODE),
514 .RSTINMODE(RSTINMODE),
525 wire pA, pB, pC, pD, pAD, pM, pP;
527 wire [47:0] oPCOUT, mPCOUT;
530 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
531 // Disconnect the A-input if MREG is enabled, since
532 // combinatorial path is broken
533 if (AREG == 0 && MREG == 0 && PREG == 0)
534 assign iA = A, pA = 1'bx;
536 \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
537 if (BREG == 0 && MREG == 0 && PREG == 0)
538 assign iB = B, pB = 1'bx;
540 \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
541 if (CREG == 0 && PREG == 0)
542 assign iC = C, pC = 1'bx;
544 \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
547 else if (techmap_guard)
548 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
550 if (ADREG == 1 && techmap_guard)
551 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
555 \$__ABC9_REG rM (.Q(pM));
561 \$__ABC9_REG rP (.Q(pP));
564 if (MREG == 0 && PREG == 0)
565 assign mP = oP, mPCOUT = oPCOUT;
567 assign mP = 1'bx, mPCOUT = 1'bx;
568 \$__ABC9_DSP48E1_MULT_P_MUX muxP (
569 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
571 \$__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
572 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
575 `DSP48E1_INST(\$__ABC9_DSP48E1_MULT )
577 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
578 // Disconnect the A-input if MREG is enabled, since
579 // combinatorial path is broken
580 if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
581 assign iA = A, pA = 1'bx;
583 \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
584 if (BREG == 0 && MREG == 0 && PREG == 0)
585 assign iB = B, pB = 1'bx;
587 \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
588 if (CREG == 0 && PREG == 0)
589 assign iC = C, pC = 1'bx;
591 \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
592 if (DREG == 0 && ADREG == 0)
593 assign iD = D, pD = 1'bx;
595 \$__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
599 \$__ABC9_REG rM (.Q(pM));
602 \$__ABC9_REG rAD (.Q(pAD));
609 assign pAD = 1'bx, pM = 1'bx;
610 \$__ABC9_REG rP (.Q(pP));
613 if (MREG == 0 && PREG == 0)
614 assign mP = oP, mPCOUT = oPCOUT;
616 assign mP = 1'bx, mPCOUT = 1'bx;
617 \$__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
618 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
620 \$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
621 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
624 `DSP48E1_INST(\$__ABC9_DSP48E1_MULT_DPORT )
626 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
627 // Disconnect the A-input if MREG is enabled, since
628 // combinatorial path is broken
629 if (AREG == 0 && PREG == 0)
630 assign iA = A, pA = 1'bx;
632 \$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
633 if (BREG == 0 && PREG == 0)
634 assign iB = B, pB = 1'bx;
636 \$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
637 if (CREG == 0 && PREG == 0)
638 assign iC = C, pC = 1'bx;
640 \$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
641 if (DREG == 1 && techmap_guard)
642 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
644 if (ADREG == 1 && techmap_guard)
645 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
647 if (MREG == 1 && techmap_guard)
648 $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
651 \$__ABC9_REG rP (.Q(pP));
655 if (MREG == 0 && PREG == 0)
656 assign mP = oP, mPCOUT = oPCOUT;
658 assign mP = 1'bx, mPCOUT = 1'bx;
659 \$__ABC9_DSP48E1_P_MUX muxP (
660 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
662 \$__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
663 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
666 `DSP48E1_INST(\$__ABC9_DSP48E1 )
669 $error("Invalid DSP48E1 configuration");