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 // ++==================++
53 // R -->>-----< Comb. > || +----------+
54 // CE -->>-----< logic >--->>-- $Q --|$__ABC_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) an optional $__ABC9_ASYNC_ cell in front of $__ABC_FF_'s output to
66 // capture asynchronous behaviour
67 // (c) a special _TECHMAP_REPLACE_.$abc9_clock wire to capture its clock
68 // domain and polarity (used when partitioning the module so that `abc9' only
69 // performs sequential synthesis (with reachability analysis) correctly on
70 // one domain at a time) and also used to infer the optional delay target
71 // from the (* abc9_clock_period = %d *) attribute attached to any wire
73 // (d) a special _TECHMAP_REPLACE_.$abc9_init wire to encode the flop's initial
75 // (e) a special _TECHMAP_REPLACE_.$abc9_currQ wire that will be used for feedback
76 // into the (combinatorial) FD* cell to facilitate clock-enable behaviour
78 // In order to perform sequential synthesis, `abc9' also requires that
79 // the initial value of all flops be zero.
81 module FDRE (output Q, input C, CE, D, R);
82 parameter [0:0] INIT = 1'b0;
83 parameter [0:0] IS_C_INVERTED = 1'b0;
84 parameter [0:0] IS_D_INVERTED = 1'b0;
85 parameter [0:0] IS_R_INVERTED = 1'b0;
88 generate if (INIT == 1'b1) begin
92 .IS_C_INVERTED(IS_C_INVERTED),
93 .IS_D_INVERTED(IS_D_INVERTED),
94 .IS_S_INVERTED(IS_R_INVERTED)
96 .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
103 .IS_C_INVERTED(IS_C_INVERTED),
104 .IS_D_INVERTED(IS_D_INVERTED),
105 .IS_R_INVERTED(IS_R_INVERTED)
106 ) _TECHMAP_REPLACE_ (
107 .D(D), .Q($Q), .C(C), .CE(CE), .R(R)
111 $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
114 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
115 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
116 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
121 .IS_C_INVERTED(IS_C_INVERTED),
122 .IS_D_INVERTED(IS_D_INVERTED),
123 .IS_R_INVERTED(IS_R_INVERTED)
124 ) _TECHMAP_REPLACE_ (
125 .D(D), .Q(Q), .C(C), .CE(CE), .R(R)
129 module FDRE_1 (output Q, input C, CE, D, R);
130 parameter [0:0] INIT = 1'b0;
133 generate if (INIT == 1'b1) begin
137 ) _TECHMAP_REPLACE_ (
138 .D(~D), .Q($Q), .C(C), .CE(CE), .S(R)
145 ) _TECHMAP_REPLACE_ (
146 .D(D), .Q($Q), .C(C), .CE(CE), .R(R)
150 $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
153 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
154 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
155 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
160 ) _TECHMAP_REPLACE_ (
161 .D(D), .Q(Q), .C(C), .CE(CE), .R(R)
166 module FDCE (output Q, input C, CE, D, CLR);
167 parameter [0:0] INIT = 1'b0;
168 parameter [0:0] IS_C_INVERTED = 1'b0;
169 parameter [0:0] IS_D_INVERTED = 1'b0;
170 parameter [0:0] IS_CLR_INVERTED = 1'b0;
172 wire QQ, $Q, $abc9_currQ;
173 generate if (INIT == 1'b1) begin
177 .IS_C_INVERTED(IS_C_INVERTED),
178 .IS_D_INVERTED(IS_D_INVERTED),
179 .IS_PRE_INVERTED(IS_CLR_INVERTED)
180 ) _TECHMAP_REPLACE_ (
181 .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
182 // ^^^ Note that async
183 // control is not directly
184 // supported by abc9 but its
185 // behaviour is captured by
186 // $__ABC9_ASYNC1 below
188 // Since this is an async flop, async behaviour is dealt with here
189 $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
195 .IS_C_INVERTED(IS_C_INVERTED),
196 .IS_D_INVERTED(IS_D_INVERTED),
197 .IS_CLR_INVERTED(IS_CLR_INVERTED)
198 ) _TECHMAP_REPLACE_ (
199 .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
200 // ^^^ Note that async
201 // control is not directly
202 // supported by abc9 but its
203 // behaviour is captured by
204 // $__ABC9_ASYNC0 below
206 // Since this is an async flop, async behaviour is dealt with here
207 $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
209 $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
212 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
213 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
214 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
219 .IS_C_INVERTED(IS_C_INVERTED),
220 .IS_D_INVERTED(IS_D_INVERTED),
221 .IS_CLR_INVERTED(IS_CLR_INVERTED)
222 ) _TECHMAP_REPLACE_ (
223 .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR)
227 module FDCE_1 (output Q, input C, CE, D, CLR);
228 parameter [0:0] INIT = 1'b0;
230 wire QQ, $Q, $abc9_currQ;
231 generate if (INIT == 1'b1) begin
235 ) _TECHMAP_REPLACE_ (
236 .D(~D), .Q($Q), .C(C), .CE(CE), .PRE(CLR)
237 // ^^^ Note that async
238 // control is not directly
239 // supported by abc9 but its
240 // behaviour is captured by
241 // $__ABC9_ASYNC1 below
243 $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ));
249 ) _TECHMAP_REPLACE_ (
250 .D(D), .Q($Q), .C(C), .CE(CE), .CLR(CLR)
251 // ^^^ Note that async
252 // control is not directly
253 // supported by abc9 but its
254 // behaviour is captured by
255 // $__ABC9_ASYNC0 below
257 $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(CLR), .Y(QQ));
259 $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
262 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
263 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
264 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
269 ) _TECHMAP_REPLACE_ (
270 .D(D), .Q(Q), .C(C), .CE(CE), .CLR(CLR)
275 module FDPE (output Q, input C, CE, D, PRE);
276 parameter [0:0] INIT = 1'b1;
277 parameter [0:0] IS_C_INVERTED = 1'b0;
278 parameter [0:0] IS_D_INVERTED = 1'b0;
279 parameter [0:0] IS_PRE_INVERTED = 1'b0;
281 wire QQ, $Q, $abc9_currQ;
282 generate if (INIT == 1'b1) begin
286 .IS_C_INVERTED(IS_C_INVERTED),
287 .IS_D_INVERTED(IS_D_INVERTED),
288 .IS_CLR_INVERTED(IS_PRE_INVERTED),
289 ) _TECHMAP_REPLACE_ (
290 .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
291 // ^^^ Note that async
292 // control is not directly
293 // supported by abc9 but its
294 // behaviour is captured by
295 // $__ABC9_ASYNC0 below
297 $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
303 .IS_C_INVERTED(IS_C_INVERTED),
304 .IS_D_INVERTED(IS_D_INVERTED),
305 .IS_PRE_INVERTED(IS_PRE_INVERTED),
306 ) _TECHMAP_REPLACE_ (
307 .D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
308 // ^^^ Note that async
309 // control is not directly
310 // supported by abc9 but its
311 // behaviour is captured by
312 // $__ABC9_ASYNC1 below
314 $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
316 $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
319 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
320 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
321 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
326 .IS_C_INVERTED(IS_C_INVERTED),
327 .IS_D_INVERTED(IS_D_INVERTED),
328 .IS_PRE_INVERTED(IS_PRE_INVERTED),
329 ) _TECHMAP_REPLACE_ (
330 .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE)
334 module FDPE_1 (output Q, input C, CE, D, PRE);
335 parameter [0:0] INIT = 1'b1;
337 wire QQ, $Q, $abc9_currQ;
338 generate if (INIT == 1'b1) begin
342 ) _TECHMAP_REPLACE_ (
343 .D(~D), .Q($Q), .C(C), .CE(CE), .CLR(PRE)
344 // ^^^ Note that async
345 // control is not directly
346 // supported by abc9 but its
347 // behaviour is captured by
348 // $__ABC9_ASYNC0 below
350 $__ABC9_ASYNC0 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ));
356 ) _TECHMAP_REPLACE_ (
357 .D(D), .Q($Q), .C(C), .CE(CE), .PRE(PRE)
358 // ^^^ Note that async
359 // control is not directly
360 // supported by abc9 but its
361 // behaviour is captured by
362 // $__ABC9_ASYNC1 below
364 $__ABC9_ASYNC1 abc_async (.A($abc9_currQ), .S(PRE), .Y(QQ));
366 $__ABC9_FF_ abc_dff (.D($Q), .Q($abc9_currQ));
369 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
370 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
371 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = $abc9_currQ;
376 ) _TECHMAP_REPLACE_ (
377 .D(D), .Q(Q), .C(C), .CE(CE), .PRE(PRE)
382 module FDSE (output Q, input C, CE, D, S);
383 parameter [0:0] INIT = 1'b1;
384 parameter [0:0] IS_C_INVERTED = 1'b0;
385 parameter [0:0] IS_D_INVERTED = 1'b0;
386 parameter [0:0] IS_S_INVERTED = 1'b0;
389 generate if (INIT == 1'b1) begin
393 .IS_C_INVERTED(IS_C_INVERTED),
394 .IS_D_INVERTED(IS_D_INVERTED),
395 .IS_R_INVERTED(IS_S_INVERTED)
396 ) _TECHMAP_REPLACE_ (
397 .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
404 .IS_C_INVERTED(IS_C_INVERTED),
405 .IS_D_INVERTED(IS_D_INVERTED),
406 .IS_S_INVERTED(IS_S_INVERTED)
407 ) _TECHMAP_REPLACE_ (
408 .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
411 $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
414 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, IS_C_INVERTED};
415 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
416 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
421 .IS_C_INVERTED(IS_C_INVERTED),
422 .IS_D_INVERTED(IS_D_INVERTED),
423 .IS_S_INVERTED(IS_S_INVERTED)
424 ) _TECHMAP_REPLACE_ (
425 .D(D), .Q(Q), .C(C), .CE(CE), .S(S)
429 module FDSE_1 (output Q, input C, CE, D, S);
430 parameter [0:0] INIT = 1'b1;
433 generate if (INIT == 1'b1) begin
437 ) _TECHMAP_REPLACE_ (
438 .D(~D), .Q($Q), .C(C), .CE(CE), .R(S)
445 ) _TECHMAP_REPLACE_ (
446 .D(D), .Q($Q), .C(C), .CE(CE), .S(S)
449 $__ABC9_FF_ abc_dff (.D($Q), .Q(QQ));
452 wire [1:0] _TECHMAP_REPLACE_.$abc9_clock = {C, 1'b1 /* IS_C_INVERTED */};
453 wire [0:0] _TECHMAP_REPLACE_.$abc9_init = 1'b0;
454 wire [0:0] _TECHMAP_REPLACE_.$abc9_currQ = QQ;
459 ) _TECHMAP_REPLACE_ (
460 .D(D), .Q(Q), .C(C), .CE(CE), .S(S)
467 (* techmap_autopurge *) input D,
468 (* techmap_autopurge *) input WCLK,
469 (* techmap_autopurge *) input WE,
470 (* techmap_autopurge *) input A0, A1, A2, A3, A4,
471 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
473 parameter INIT = 32'h0;
474 parameter IS_WCLK_INVERTED = 1'b0;
477 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
478 ) _TECHMAP_REPLACE_ (
479 .DPO($DPO), .SPO($SPO),
480 .D(D), .WCLK(WCLK), .WE(WE),
481 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
482 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
484 $__ABC9_LUT6 spo (.A($SPO), .S({1'b1, A4, A3, A2, A1, A0}), .Y(SPO));
485 $__ABC9_LUT6 dpo (.A($DPO), .S({1'b1, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
490 (* techmap_autopurge *) input D,
491 (* techmap_autopurge *) input WCLK,
492 (* techmap_autopurge *) input WE,
493 (* techmap_autopurge *) input A0, A1, A2, A3, A4, A5,
494 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
496 parameter INIT = 64'h0;
497 parameter IS_WCLK_INVERTED = 1'b0;
500 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
501 ) _TECHMAP_REPLACE_ (
502 .DPO($DPO), .SPO($SPO),
503 .D(D), .WCLK(WCLK), .WE(WE),
504 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
505 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
507 $__ABC9_LUT6 spo (.A($SPO), .S({A5, A4, A3, A2, A1, A0}), .Y(SPO));
508 $__ABC9_LUT6 dpo (.A($DPO), .S({DPRA5, DPRA4, DPRA3, DPRA2, DPRA1, DPRA0}), .Y(DPO));
513 (* techmap_autopurge *) input D,
514 (* techmap_autopurge *) input WCLK,
515 (* techmap_autopurge *) input WE,
516 (* techmap_autopurge *) input [6:0] A, DPRA
518 parameter INIT = 128'h0;
519 parameter IS_WCLK_INVERTED = 1'b0;
522 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
523 ) _TECHMAP_REPLACE_ (
524 .DPO($DPO), .SPO($SPO),
525 .D(D), .WCLK(WCLK), .WE(WE),
529 $__ABC9_LUT7 spo (.A($SPO), .S(A), .Y(SPO));
530 $__ABC9_LUT7 dpo (.A($DPO), .S(DPRA), .Y(DPO));
538 (* techmap_autopurge *) input [4:0] ADDRA,
539 (* techmap_autopurge *) input [4:0] ADDRB,
540 (* techmap_autopurge *) input [4:0] ADDRC,
541 (* techmap_autopurge *) input [4:0] ADDRD,
542 (* techmap_autopurge *) input [1:0] DIA,
543 (* techmap_autopurge *) input [1:0] DIB,
544 (* techmap_autopurge *) input [1:0] DIC,
545 (* techmap_autopurge *) input [1:0] DID,
546 (* techmap_autopurge *) input WCLK,
547 (* techmap_autopurge *) input WE
549 parameter [63:0] INIT_A = 64'h0000000000000000;
550 parameter [63:0] INIT_B = 64'h0000000000000000;
551 parameter [63:0] INIT_C = 64'h0000000000000000;
552 parameter [63:0] INIT_D = 64'h0000000000000000;
553 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
554 wire [1:0] $DOA, $DOB, $DOC, $DOD;
556 .INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
557 .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
558 ) _TECHMAP_REPLACE_ (
559 .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
560 .WCLK(WCLK), .WE(WE),
561 .ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
562 .DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
564 $__ABC9_LUT6 doa0 (.A($DOA[0]), .S({1'b1, ADDRA}), .Y(DOA[0]));
565 $__ABC9_LUT6 doa1 (.A($DOA[1]), .S({1'b1, ADDRA}), .Y(DOA[1]));
566 $__ABC9_LUT6 dob0 (.A($DOB[0]), .S({1'b1, ADDRB}), .Y(DOB[0]));
567 $__ABC9_LUT6 dob1 (.A($DOB[1]), .S({1'b1, ADDRB}), .Y(DOB[1]));
568 $__ABC9_LUT6 doc0 (.A($DOC[0]), .S({1'b1, ADDRC}), .Y(DOC[0]));
569 $__ABC9_LUT6 doc1 (.A($DOC[1]), .S({1'b1, ADDRC}), .Y(DOC[1]));
570 $__ABC9_LUT6 dod0 (.A($DOD[0]), .S({1'b1, ADDRD}), .Y(DOD[0]));
571 $__ABC9_LUT6 dod1 (.A($DOD[1]), .S({1'b1, ADDRD}), .Y(DOD[1]));
579 (* techmap_autopurge *) input [5:0] ADDRA,
580 (* techmap_autopurge *) input [5:0] ADDRB,
581 (* techmap_autopurge *) input [5:0] ADDRC,
582 (* techmap_autopurge *) input [5:0] ADDRD,
583 (* techmap_autopurge *) input DIA,
584 (* techmap_autopurge *) input DIB,
585 (* techmap_autopurge *) input DIC,
586 (* techmap_autopurge *) input DID,
587 (* techmap_autopurge *) input WCLK,
588 (* techmap_autopurge *) input WE
590 parameter [63:0] INIT_A = 64'h0000000000000000;
591 parameter [63:0] INIT_B = 64'h0000000000000000;
592 parameter [63:0] INIT_C = 64'h0000000000000000;
593 parameter [63:0] INIT_D = 64'h0000000000000000;
594 parameter [0:0] IS_WCLK_INVERTED = 1'b0;
595 wire $DOA, $DOB, $DOC, $DOD;
597 .INIT_A(INIT_A), .INIT_B(INIT_B), .INIT_C(INIT_C), .INIT_D(INIT_D),
598 .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
599 ) _TECHMAP_REPLACE_ (
600 .DOA($DOA), .DOB($DOB), .DOC($DOC), .DOD($DOD),
601 .WCLK(WCLK), .WE(WE),
602 .ADDRA(ADDRA), .ADDRB(ADDRB), .ADDRC(ADDRC), .ADDRD(ADDRD),
603 .DIA(DIA), .DIB(DIB), .DIC(DIC), .DID(DID)
605 $__ABC9_LUT6 doa (.A($DOA), .S(ADDRA), .Y(DOA));
606 $__ABC9_LUT6 dob (.A($DOB), .S(ADDRB), .Y(DOB));
607 $__ABC9_LUT6 doc (.A($DOC), .S(ADDRC), .Y(DOC));
608 $__ABC9_LUT6 dod (.A($DOD), .S(ADDRD), .Y(DOD));
613 (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
615 parameter [15:0] INIT = 16'h0000;
616 parameter [0:0] IS_CLK_INVERTED = 1'b0;
619 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
620 ) _TECHMAP_REPLACE_ (
622 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
624 $__ABC9_LUT6 q (.A($Q), .S({1'b1, A3, A2, A1, A0, 1'b1}), .Y(Q));
630 (* techmap_autopurge *) input [4:0] A,
631 (* techmap_autopurge *) input CE, CLK, D
633 parameter [31:0] INIT = 32'h00000000;
634 parameter [0:0] IS_CLK_INVERTED = 1'b0;
637 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
638 ) _TECHMAP_REPLACE_ (
640 .A(A), .CE(CE), .CLK(CLK), .D(D)
642 $__ABC9_LUT6 q (.A($Q), .S({1'b1, A}), .Y(Q));
646 (* techmap_autopurge *) output [29:0] ACOUT,
647 (* techmap_autopurge *) output [17:0] BCOUT,
648 (* techmap_autopurge *) output reg CARRYCASCOUT,
649 (* techmap_autopurge *) output reg [3:0] CARRYOUT,
650 (* techmap_autopurge *) output reg MULTSIGNOUT,
651 (* techmap_autopurge *) output OVERFLOW,
652 (* techmap_autopurge *) output reg signed [47:0] P,
653 (* techmap_autopurge *) output PATTERNBDETECT,
654 (* techmap_autopurge *) output PATTERNDETECT,
655 (* techmap_autopurge *) output [47:0] PCOUT,
656 (* techmap_autopurge *) output UNDERFLOW,
657 (* techmap_autopurge *) input signed [29:0] A,
658 (* techmap_autopurge *) input [29:0] ACIN,
659 (* techmap_autopurge *) input [3:0] ALUMODE,
660 (* techmap_autopurge *) input signed [17:0] B,
661 (* techmap_autopurge *) input [17:0] BCIN,
662 (* techmap_autopurge *) input [47:0] C,
663 (* techmap_autopurge *) input CARRYCASCIN,
664 (* techmap_autopurge *) input CARRYIN,
665 (* techmap_autopurge *) input [2:0] CARRYINSEL,
666 (* techmap_autopurge *) input CEA1,
667 (* techmap_autopurge *) input CEA2,
668 (* techmap_autopurge *) input CEAD,
669 (* techmap_autopurge *) input CEALUMODE,
670 (* techmap_autopurge *) input CEB1,
671 (* techmap_autopurge *) input CEB2,
672 (* techmap_autopurge *) input CEC,
673 (* techmap_autopurge *) input CECARRYIN,
674 (* techmap_autopurge *) input CECTRL,
675 (* techmap_autopurge *) input CED,
676 (* techmap_autopurge *) input CEINMODE,
677 (* techmap_autopurge *) input CEM,
678 (* techmap_autopurge *) input CEP,
679 (* techmap_autopurge *) input CLK,
680 (* techmap_autopurge *) input [24:0] D,
681 (* techmap_autopurge *) input [4:0] INMODE,
682 (* techmap_autopurge *) input MULTSIGNIN,
683 (* techmap_autopurge *) input [6:0] OPMODE,
684 (* techmap_autopurge *) input [47:0] PCIN,
685 (* techmap_autopurge *) input RSTA,
686 (* techmap_autopurge *) input RSTALLCARRYIN,
687 (* techmap_autopurge *) input RSTALUMODE,
688 (* techmap_autopurge *) input RSTB,
689 (* techmap_autopurge *) input RSTC,
690 (* techmap_autopurge *) input RSTCTRL,
691 (* techmap_autopurge *) input RSTD,
692 (* techmap_autopurge *) input RSTINMODE,
693 (* techmap_autopurge *) input RSTM,
694 (* techmap_autopurge *) input RSTP
696 parameter integer ACASCREG = 1;
697 parameter integer ADREG = 1;
698 parameter integer ALUMODEREG = 1;
699 parameter integer AREG = 1;
700 parameter AUTORESET_PATDET = "NO_RESET";
701 parameter A_INPUT = "DIRECT";
702 parameter integer BCASCREG = 1;
703 parameter integer BREG = 1;
704 parameter B_INPUT = "DIRECT";
705 parameter integer CARRYINREG = 1;
706 parameter integer CARRYINSELREG = 1;
707 parameter integer CREG = 1;
708 parameter integer DREG = 1;
709 parameter integer INMODEREG = 1;
710 parameter integer MREG = 1;
711 parameter integer OPMODEREG = 1;
712 parameter integer PREG = 1;
713 parameter SEL_MASK = "MASK";
714 parameter SEL_PATTERN = "PATTERN";
715 parameter USE_DPORT = "FALSE";
716 parameter USE_MULT = "MULTIPLY";
717 parameter USE_PATTERN_DETECT = "NO_PATDET";
718 parameter USE_SIMD = "ONE48";
719 parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
720 parameter [47:0] PATTERN = 48'h000000000000;
721 parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
722 parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
723 parameter [0:0] IS_CLK_INVERTED = 1'b0;
724 parameter [4:0] IS_INMODE_INVERTED = 5'b0;
725 parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
727 parameter _TECHMAP_CELLTYPE_ = "";
728 localparam techmap_guard = (_TECHMAP_CELLTYPE_ != "");
730 `define DSP48E1_INST(__CELL__) """
734 .ALUMODEREG(ALUMODEREG),
736 .AUTORESET_PATDET(AUTORESET_PATDET),
741 .CARRYINREG(CARRYINREG),
742 .CARRYINSELREG(CARRYINSELREG),
745 .INMODEREG(INMODEREG),
747 .OPMODEREG(OPMODEREG),
750 .SEL_PATTERN(SEL_PATTERN),
751 .USE_DPORT(USE_DPORT),
753 .USE_PATTERN_DETECT(USE_PATTERN_DETECT),
757 .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
758 .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
759 .IS_CLK_INVERTED(IS_CLK_INVERTED),
760 .IS_INMODE_INVERTED(IS_INMODE_INVERTED),
761 .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
762 ) _TECHMAP_REPLACE_ (
765 .CARRYCASCOUT(CARRYCASCOUT),
767 .MULTSIGNOUT(MULTSIGNOUT),
770 .PATTERNBDETECT(PATTERNBDETECT),
771 .PATTERNDETECT(PATTERNDETECT),
773 .UNDERFLOW(UNDERFLOW),
780 .CARRYCASCIN(CARRYCASCIN),
782 .CARRYINSEL(CARRYINSEL),
786 .CEALUMODE(CEALUMODE),
790 .CECARRYIN(CECARRYIN),
799 .MULTSIGNIN(MULTSIGNIN),
803 .RSTALLCARRYIN(RSTALLCARRYIN),
804 .RSTALUMODE(RSTALUMODE),
809 .RSTINMODE(RSTINMODE),
820 wire pA, pB, pC, pD, pAD, pM, pP;
822 wire [47:0] oPCOUT, mPCOUT;
825 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
826 // Disconnect the A-input if MREG is enabled, since
827 // combinatorial path is broken
828 if (AREG == 0 && MREG == 0 && PREG == 0)
829 assign iA = A, pA = 1'bx;
831 $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
832 if (BREG == 0 && MREG == 0 && PREG == 0)
833 assign iB = B, pB = 1'bx;
835 $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
836 if (CREG == 0 && PREG == 0)
837 assign iC = C, pC = 1'bx;
839 $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
842 else if (techmap_guard)
843 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
845 if (ADREG == 1 && techmap_guard)
846 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
850 $__ABC9_REG rM (.Q(pM));
856 $__ABC9_REG rP (.Q(pP));
859 if (MREG == 0 && PREG == 0)
860 assign mP = oP, mPCOUT = oPCOUT;
862 assign mP = 1'bx, mPCOUT = 1'bx;
863 $__ABC9_DSP48E1_MULT_P_MUX muxP (
864 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
866 $__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
867 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
870 `DSP48E1_INST($__ABC9_DSP48E1_MULT )
872 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
873 // Disconnect the A-input if MREG is enabled, since
874 // combinatorial path is broken
875 if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
876 assign iA = A, pA = 1'bx;
878 $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
879 if (BREG == 0 && MREG == 0 && PREG == 0)
880 assign iB = B, pB = 1'bx;
882 $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
883 if (CREG == 0 && PREG == 0)
884 assign iC = C, pC = 1'bx;
886 $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
887 if (DREG == 0 && ADREG == 0)
888 assign iD = D, pD = 1'bx;
890 $__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
894 $__ABC9_REG rM (.Q(pM));
897 $__ABC9_REG rAD (.Q(pAD));
904 assign pAD = 1'bx, pM = 1'bx;
905 $__ABC9_REG rP (.Q(pP));
908 if (MREG == 0 && PREG == 0)
909 assign mP = oP, mPCOUT = oPCOUT;
911 assign mP = 1'bx, mPCOUT = 1'bx;
912 $__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
913 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
915 $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
916 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
919 `DSP48E1_INST($__ABC9_DSP48E1_MULT_DPORT )
921 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
922 // Disconnect the A-input if MREG is enabled, since
923 // combinatorial path is broken
924 if (AREG == 0 && PREG == 0)
925 assign iA = A, pA = 1'bx;
927 $__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
928 if (BREG == 0 && PREG == 0)
929 assign iB = B, pB = 1'bx;
931 $__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
932 if (CREG == 0 && PREG == 0)
933 assign iC = C, pC = 1'bx;
935 $__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
936 if (DREG == 1 && techmap_guard)
937 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
939 if (ADREG == 1 && techmap_guard)
940 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
942 if (MREG == 1 && techmap_guard)
943 $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
946 $__ABC9_REG rP (.Q(pP));
950 if (MREG == 0 && PREG == 0)
951 assign mP = oP, mPCOUT = oPCOUT;
953 assign mP = 1'bx, mPCOUT = 1'bx;
954 $__ABC9_DSP48E1_P_MUX muxP (
955 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
957 $__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
958 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
961 `DSP48E1_INST($__ABC9_DSP48E1 )
964 $error("Invalid DSP48E1 configuration");