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),
300 wire pA, pB, pC, pD, pAD, pM, pP;
302 wire [47:0] oPCOUT, mPCOUT;
305 if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
306 // Disconnect the A-input if MREG is enabled, since
307 // combinatorial path is broken
308 if (AREG == 0 && MREG == 0 && PREG == 0)
309 assign iA = A, pA = 1'bx;
311 \$__ABC_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
312 if (BREG == 0 && MREG == 0 && PREG == 0)
313 assign iB = B, pB = 1'bx;
315 \$__ABC_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
316 if (CREG == 0 && PREG == 0)
317 assign iC = C, pC = 1'bx;
319 \$__ABC_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
322 else if (techmap_guard)
323 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
325 if (ADREG == 1 && techmap_guard)
326 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
330 \$__ABC_REG rM (.Q(pM));
336 \$__ABC_REG rP (.Q(pP));
339 if (MREG == 0 && PREG == 0)
340 assign mP = oP, mPCOUT = oPCOUT;
342 assign mP = 1'bx, mPCOUT = 1'bx;
343 \$__ABC_DSP48E1_MULT_P_MUX muxP (
344 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
346 \$__ABC_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
347 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
350 `DSP48E1_INST(\$__ABC_DSP48E1_MULT )
352 else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
353 // Disconnect the A-input if MREG is enabled, since
354 // combinatorial path is broken
355 if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
356 assign iA = A, pA = 1'bx;
358 \$__ABC_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
359 if (BREG == 0 && MREG == 0 && PREG == 0)
360 assign iB = B, pB = 1'bx;
362 \$__ABC_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
363 if (CREG == 0 && PREG == 0)
364 assign iC = C, pC = 1'bx;
366 \$__ABC_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
367 if (DREG == 0 && ADREG == 0)
368 assign iD = D, pD = 1'bx;
370 \$__ABC_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
374 \$__ABC_REG rM (.Q(pM));
377 \$__ABC_REG rAD (.Q(pAD));
384 assign pAD = 1'bx, pM = 1'bx;
385 \$__ABC_REG rP (.Q(pP));
388 if (MREG == 0 && PREG == 0)
389 assign mP = oP, mPCOUT = oPCOUT;
391 assign mP = 1'bx, mPCOUT = 1'bx;
392 \$__ABC_DSP48E1_MULT_DPORT_P_MUX muxP (
393 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
395 \$__ABC_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
396 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
399 `DSP48E1_INST(\$__ABC_DSP48E1_MULT_DPORT )
401 else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
402 // Disconnect the A-input if MREG is enabled, since
403 // combinatorial path is broken
404 if (AREG == 0 && PREG == 0)
405 assign iA = A, pA = 1'bx;
407 \$__ABC_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
408 if (BREG == 0 && PREG == 0)
409 assign iB = B, pB = 1'bx;
411 \$__ABC_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
412 if (CREG == 0 && PREG == 0)
413 assign iC = C, pC = 1'bx;
415 \$__ABC_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
416 if (DREG == 1 && techmap_guard)
417 $error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
419 if (ADREG == 1 && techmap_guard)
420 $error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
422 if (MREG == 1 && techmap_guard)
423 $error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
426 \$__ABC_REG rP (.Q(pP));
430 if (MREG == 0 && PREG == 0)
431 assign mP = oP, mPCOUT = oPCOUT;
433 assign mP = 1'bx, mPCOUT = 1'bx;
434 \$__ABC_DSP48E1_P_MUX muxP (
435 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
437 \$__ABC_DSP48E1_PCOUT_MUX muxPCOUT (
438 .Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
441 `DSP48E1_INST(\$__ABC_DSP48E1 )
444 $error("Invalid DSP48E1 configuration");