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 // ============================================================================
25 (* techmap_autopurge *) input D,
26 (* techmap_autopurge *) input WCLK,
27 (* techmap_autopurge *) input WE,
28 (* techmap_autopurge *) input A0, A1, A2, A3, A4,
29 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
31 parameter INIT = 32'h0;
32 parameter IS_WCLK_INVERTED = 1'b0;
35 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
37 .DPO(\$DPO ), .SPO(\$SPO ),
38 .D(D), .WCLK(WCLK), .WE(WE),
39 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
40 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
42 \$__ABC_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
43 \$__ABC_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
48 (* techmap_autopurge *) input D,
49 (* techmap_autopurge *) input WCLK,
50 (* techmap_autopurge *) input WE,
51 (* techmap_autopurge *) input A0, A1, A2, A3, A4, A5,
52 (* techmap_autopurge *) input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
54 parameter INIT = 64'h0;
55 parameter IS_WCLK_INVERTED = 1'b0;
58 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
60 .DPO(\$DPO ), .SPO(\$SPO ),
61 .D(D), .WCLK(WCLK), .WE(WE),
62 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
63 .DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
65 \$__ABC_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
66 \$__ABC_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
71 (* techmap_autopurge *) input D,
72 (* techmap_autopurge *) input WCLK,
73 (* techmap_autopurge *) input WE,
74 (* techmap_autopurge *) input [6:0] A, DPRA
76 parameter INIT = 128'h0;
77 parameter IS_WCLK_INVERTED = 1'b0;
80 .INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
82 .DPO(\$DPO ), .SPO(\$SPO ),
83 .D(D), .WCLK(WCLK), .WE(WE),
87 \$__ABC_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
88 \$__ABC_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
93 (* techmap_autopurge *) input A0, A1, A2, A3, CE, CLK, D
95 parameter [15:0] INIT = 16'h0000;
96 parameter [0:0] IS_CLK_INVERTED = 1'b0;
99 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
100 ) _TECHMAP_REPLACE_ (
102 .A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
104 \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q));
110 (* techmap_autopurge *) input [4:0] A,
111 (* techmap_autopurge *) input CE, CLK, D
113 parameter [31:0] INIT = 32'h00000000;
114 parameter [0:0] IS_CLK_INVERTED = 1'b0;
117 .INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
118 ) _TECHMAP_REPLACE_ (
120 .A(A), .CE(CE), .CLK(CLK), .D(D)
122 \$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
128 output reg CARRYCASCOUT,
129 output reg [3:0] CARRYOUT,
130 output reg MULTSIGNOUT,
132 output reg signed [47:0] P,
133 output PATTERNBDETECT,
134 output PATTERNDETECT,
137 (* techmap_autopurge *) input signed [29:0] A,
138 (* techmap_autopurge *) input [29:0] ACIN,
139 (* techmap_autopurge *) input [3:0] ALUMODE,
140 (* techmap_autopurge *) input signed [17:0] B,
141 (* techmap_autopurge *) input [17:0] BCIN,
142 (* techmap_autopurge *) input [47:0] C,
143 (* techmap_autopurge *) input CARRYCASCIN,
144 (* techmap_autopurge *) input CARRYIN,
145 (* techmap_autopurge *) input [2:0] CARRYINSEL,
146 (* techmap_autopurge *) input CEA1,
147 (* techmap_autopurge *) input CEA2,
148 (* techmap_autopurge *) input CEAD,
149 (* techmap_autopurge *) input CEALUMODE,
150 (* techmap_autopurge *) input CEB1,
151 (* techmap_autopurge *) input CEB2,
152 (* techmap_autopurge *) input CEC,
153 (* techmap_autopurge *) input CECARRYIN,
154 (* techmap_autopurge *) input CECTRL,
155 (* techmap_autopurge *) input CED,
156 (* techmap_autopurge *) input CEINMODE,
157 (* techmap_autopurge *) input CEM,
158 (* techmap_autopurge *) input CEP,
159 (* techmap_autopurge *) input CLK,
160 (* techmap_autopurge *) input [24:0] D,
161 (* techmap_autopurge *) input [4:0] INMODE,
162 (* techmap_autopurge *) input MULTSIGNIN,
163 (* techmap_autopurge *) input [6:0] OPMODE,
164 (* techmap_autopurge *) input [47:0] PCIN,
165 (* techmap_autopurge *) input RSTA,
166 (* techmap_autopurge *) input RSTALLCARRYIN,
167 (* techmap_autopurge *) input RSTALUMODE,
168 (* techmap_autopurge *) input RSTB,
169 (* techmap_autopurge *) input RSTC,
170 (* techmap_autopurge *) input RSTCTRL,
171 (* techmap_autopurge *) input RSTD,
172 (* techmap_autopurge *) input RSTINMODE,
173 (* techmap_autopurge *) input RSTM,
174 (* techmap_autopurge *) input RSTP
176 parameter integer ACASCREG = 1;
177 parameter integer ADREG = 1;
178 parameter integer ALUMODEREG = 1;
179 parameter integer AREG = 1;
180 parameter AUTORESET_PATDET = "NO_RESET";
181 parameter A_INPUT = "DIRECT";
182 parameter integer BCASCREG = 1;
183 parameter integer BREG = 1;
184 parameter B_INPUT = "DIRECT";
185 parameter integer CARRYINREG = 1;
186 parameter integer CARRYINSELREG = 1;
187 parameter integer CREG = 1;
188 parameter integer DREG = 1;
189 parameter integer INMODEREG = 1;
190 parameter integer MREG = 1;
191 parameter integer OPMODEREG = 1;
192 parameter integer PREG = 1;
193 parameter SEL_MASK = "MASK";
194 parameter SEL_PATTERN = "PATTERN";
195 parameter USE_DPORT = "FALSE";
196 parameter USE_MULT = "MULTIPLY";
197 parameter USE_PATTERN_DETECT = "NO_PATDET";
198 parameter USE_SIMD = "ONE48";
199 parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
200 parameter [47:0] PATTERN = 48'h000000000000;
201 parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
202 parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
203 parameter [0:0] IS_CLK_INVERTED = 1'b0;
204 parameter [4:0] IS_INMODE_INVERTED = 5'b0;
205 parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
207 parameter _TECHMAP_CELLTYPE_ = "";
208 localparam techmap_guard = (_TECHMAP_CELLTYPE_ != "");
210 `define DSP48E1_INST(__CELL__) """
214 .ALUMODEREG(ALUMODEREG),
216 .AUTORESET_PATDET(AUTORESET_PATDET),
221 .CARRYINREG(CARRYINREG),
222 .CARRYINSELREG(CARRYINSELREG),
225 .INMODEREG(INMODEREG),
227 .OPMODEREG(OPMODEREG),
230 .SEL_PATTERN(SEL_PATTERN),
231 .USE_DPORT(USE_DPORT),
233 .USE_PATTERN_DETECT(USE_PATTERN_DETECT),
237 .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
238 .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
239 .IS_CLK_INVERTED(IS_CLK_INVERTED),
240 .IS_INMODE_INVERTED(IS_INMODE_INVERTED),
241 .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
242 ) _TECHMAP_REPLACE_ (
245 .CARRYCASCOUT(CARRYCASCOUT),
247 .MULTSIGNOUT(MULTSIGNOUT),
250 .PATTERNBDETECT(PATTERNBDETECT),
251 .PATTERNDETECT(PATTERNDETECT),
253 .UNDERFLOW(UNDERFLOW),
260 .CARRYCASCIN(CARRYCASCIN),
262 .CARRYINSEL(CARRYINSEL),
266 .CEALUMODE(CEALUMODE),
270 .CECARRYIN(CECARRYIN),
279 .MULTSIGNIN(MULTSIGNIN),
283 .RSTALLCARRYIN(RSTALLCARRYIN),
284 .RSTALUMODE(RSTALUMODE),
289 .RSTINMODE(RSTINMODE),
296 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
302 wire pA, pB, pC, pD, pAD, pM, pP;
303 wire [47:0] oP, oPCOUT;
305 // Disconnect the A-input if MREG is enabled, since
306 // combinatorial path is broken
307 if (AREG == 0 && MREG == 0 && PREG == 0)
308 assign iA = A, pA = 1'bx;
310 \$__ABC_DSP48E1_REG rA (.I(A), .O(iA), .Q(pA));
311 if (BREG == 0 && MREG == 0 && PREG == 0)
312 assign iB = B, pB = 1'bx;
314 \$__ABC_DSP48E1_REG rB (.I(B), .O(iB), .Q(pB));
315 if (CREG == 0 && PREG == 0)
316 assign iC = C, pC = 1'bx;
318 \$__ABC_DSP48E1_REG rC (.I(C), .O(iC), .Q(pC));
321 else if (techmap_guard)
322 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
324 if (ADREG == 1 && techmap_guard)
325 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
330 \$__ABC_DSP48E1_REG rM (.Q(pM));
335 \$__ABC_DSP48E1_REG rP (.Q(pP));
339 \$__ABC_DSP48E1_MULT_P_MUX muxP (
340 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oP), .Pq(pP), .O(P)
342 \$__ABC_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
343 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oPCOUT), .Pq(pP), .O(PCOUT)
346 `DSP48E1_INST(\$__ABC_DSP48E1_MULT )
348 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
354 wire pA, pB, pC, pD, pAD, pM, pP;
355 wire [47:0] oP, oPCOUT;
357 // Disconnect the A-input if MREG is enabled, since
358 // combinatorial path is broken
359 if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
360 assign iA = A, pA = 1'bx;
362 \$__ABC_DSP48E1_REG rA (.I(A), .O(iA), .Q(pA));
363 if (BREG == 0 && MREG == 0 && PREG == 0)
364 assign iB = B, pB = 1'bx;
366 \$__ABC_DSP48E1_REG rB (.I(B), .O(iB), .Q(pB));
367 if (CREG == 0 && PREG == 0)
368 assign iC = C, pC = 1'bx;
370 \$__ABC_DSP48E1_REG rC (.I(C), .O(iC), .Q(pC));
371 if (DREG == 0 && ADREG == 0)
372 assign iD = D, pD = 1'bx;
374 \$__ABC_DSP48E1_REG rD (.I(D), .O(iD), .Q(pD));
377 \$__ABC_DSP48E1_REG rM (.Q(pM));
381 \$__ABC_DSP48E1_REG rAD (.Q(pAD));
387 \$__ABC_DSP48E1_REG rP (.Q(pP));
389 \$__ABC_DSP48E1_MULT_DPORT_P_MUX muxP (
390 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oP), .Pq(pP), .O(P)
392 \$__ABC_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
393 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oPCOUT), .Pq(pP), .O(PCOUT)
396 `DSP48E1_INST(\$__ABC_DSP48E1_MULT_DPORT )
398 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
404 wire pA, pB, pC, pD, pAD, pM, pP;
405 wire [47:0] oP, oPCOUT;
407 // Disconnect the A-input if MREG is enabled, since
408 // combinatorial path is broken
409 if (AREG == 0 && PREG == 0)
410 assign iA = A, pA = 1'bx;
412 \$__ABC_DSP48E1_REG rA (.I(A), .O(iA), .Q(pA));
413 if (BREG == 0 && PREG == 0)
414 assign iB = B, pB = 1'bx;
416 \$__ABC_DSP48E1_REG rB (.I(B), .O(iB), .Q(pB));
417 if (CREG == 0 && PREG == 0)
418 assign iC = C, pC = 1'bx;
420 \$__ABC_DSP48E1_REG rC (.I(C), .O(iC), .Q(pC));
421 if (MREG == 1 && techmap_guard)
422 $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
424 if (DREG == 1 && techmap_guard)
425 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
427 if (ADREG == 1 && techmap_guard)
428 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
431 \$__ABC_DSP48E1_REG rP (.Q(pP));
435 \$__ABC_DSP48E1_P_MUX muxP (
436 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oP), .Pq(pP), .O(P)
438 \$__ABC_DSP48E1_PCOUT_MUX muxPCOUT (
439 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .Mq(pM), .P(oPCOUT), .Pq(pP), .O(PCOUT)
442 `DSP48E1_INST(\$__ABC_DSP48E1 )
445 $error("Invalid DSP48E1 configuration");