Merge pull request #1617 from YosysHQ/eddie/abc9_dsp_refactor

Refactor abc9's DSP48E1 handling
This commit is contained in:
Eddie Hung 2020-01-06 15:00:16 -08:00 committed by GitHub
commit 66698cb6fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 508 additions and 1654 deletions

View File

@ -128,7 +128,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper' # is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally # will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC.. # delete your work on ABC..
ABCREV = 623b5e8 ABCREV = f6dc4a5
ABCPULL = 1 ABCPULL = 1
ABCURL ?= https://github.com/berkeley-abc/abc ABCURL ?= https://github.com/berkeley-abc/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1

View File

@ -282,244 +282,119 @@ module DSP48E1 (
parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [4:0] IS_INMODE_INVERTED = 5'b0;
parameter [6:0] IS_OPMODE_INVERTED = 7'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
parameter _TECHMAP_CELLTYPE_ = ""; wire [47:0] $P, $PCOUT;
localparam techmap_guard = (_TECHMAP_CELLTYPE_ != "");
`define DSP48E1_INST(__CELL__) """ DSP48E1 #(
__CELL__ #( .ACASCREG(ACASCREG),
.ACASCREG(ACASCREG), .ADREG(ADREG),
.ADREG(ADREG), .ALUMODEREG(ALUMODEREG),
.ALUMODEREG(ALUMODEREG), .AREG(AREG),
.AREG(AREG), .AUTORESET_PATDET(AUTORESET_PATDET),
.AUTORESET_PATDET(AUTORESET_PATDET), .A_INPUT(A_INPUT),
.A_INPUT(A_INPUT), .BCASCREG(BCASCREG),
.BCASCREG(BCASCREG), .BREG(BREG),
.BREG(BREG), .B_INPUT(B_INPUT),
.B_INPUT(B_INPUT), .CARRYINREG(CARRYINREG),
.CARRYINREG(CARRYINREG), .CARRYINSELREG(CARRYINSELREG),
.CARRYINSELREG(CARRYINSELREG), .CREG(CREG),
.CREG(CREG), .DREG(DREG),
.DREG(DREG), .INMODEREG(INMODEREG),
.INMODEREG(INMODEREG), .MREG(MREG),
.MREG(MREG), .OPMODEREG(OPMODEREG),
.OPMODEREG(OPMODEREG), .PREG(PREG),
.PREG(PREG), .SEL_MASK(SEL_MASK),
.SEL_MASK(SEL_MASK), .SEL_PATTERN(SEL_PATTERN),
.SEL_PATTERN(SEL_PATTERN), .USE_DPORT(USE_DPORT),
.USE_DPORT(USE_DPORT), .USE_MULT(USE_MULT),
.USE_MULT(USE_MULT), .USE_PATTERN_DETECT(USE_PATTERN_DETECT),
.USE_PATTERN_DETECT(USE_PATTERN_DETECT), .USE_SIMD(USE_SIMD),
.USE_SIMD(USE_SIMD), .MASK(MASK),
.MASK(MASK), .PATTERN(PATTERN),
.PATTERN(PATTERN), .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED), .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED), .IS_CLK_INVERTED(IS_CLK_INVERTED),
.IS_CLK_INVERTED(IS_CLK_INVERTED), .IS_INMODE_INVERTED(IS_INMODE_INVERTED),
.IS_INMODE_INVERTED(IS_INMODE_INVERTED), .IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
.IS_OPMODE_INVERTED(IS_OPMODE_INVERTED) ) _TECHMAP_REPLACE_ (
) _TECHMAP_REPLACE_ ( .ACOUT(ACOUT),
.ACOUT(ACOUT), .BCOUT(BCOUT),
.BCOUT(BCOUT), .CARRYCASCOUT(CARRYCASCOUT),
.CARRYCASCOUT(CARRYCASCOUT), .CARRYOUT(CARRYOUT),
.CARRYOUT(CARRYOUT), .MULTSIGNOUT(MULTSIGNOUT),
.MULTSIGNOUT(MULTSIGNOUT), .OVERFLOW(OVERFLOW),
.OVERFLOW(OVERFLOW), .P($P),
.P(oP), .PATTERNBDETECT(PATTERNBDETECT),
.PATTERNBDETECT(PATTERNBDETECT), .PATTERNDETECT(PATTERNDETECT),
.PATTERNDETECT(PATTERNDETECT), .PCOUT($PCOUT),
.PCOUT(oPCOUT), .UNDERFLOW(UNDERFLOW),
.UNDERFLOW(UNDERFLOW), .A(A),
.A(iA), .ACIN(ACIN),
.ACIN(ACIN), .ALUMODE(ALUMODE),
.ALUMODE(ALUMODE), .B(B),
.B(iB), .BCIN(BCIN),
.BCIN(BCIN), .C(C),
.C(iC), .CARRYCASCIN(CARRYCASCIN),
.CARRYCASCIN(CARRYCASCIN), .CARRYIN(CARRYIN),
.CARRYIN(CARRYIN), .CARRYINSEL(CARRYINSEL),
.CARRYINSEL(CARRYINSEL), .CEA1(CEA1),
.CEA1(CEA1), .CEA2(CEA2),
.CEA2(CEA2), .CEAD(CEAD),
.CEAD(CEAD), .CEALUMODE(CEALUMODE),
.CEALUMODE(CEALUMODE), .CEB1(CEB1),
.CEB1(CEB1), .CEB2(CEB2),
.CEB2(CEB2), .CEC(CEC),
.CEC(CEC), .CECARRYIN(CECARRYIN),
.CECARRYIN(CECARRYIN), .CECTRL(CECTRL),
.CECTRL(CECTRL), .CED(CED),
.CED(CED), .CEINMODE(CEINMODE),
.CEINMODE(CEINMODE), .CEM(CEM),
.CEM(CEM), .CEP(CEP),
.CEP(CEP), .CLK(CLK),
.CLK(CLK), .D(D),
.D(iD), .INMODE(INMODE),
.INMODE(INMODE), .MULTSIGNIN(MULTSIGNIN),
.MULTSIGNIN(MULTSIGNIN), .OPMODE(OPMODE),
.OPMODE(OPMODE), .PCIN(PCIN),
.PCIN(PCIN), .RSTA(RSTA),
.RSTA(RSTA), .RSTALLCARRYIN(RSTALLCARRYIN),
.RSTALLCARRYIN(RSTALLCARRYIN), .RSTALUMODE(RSTALUMODE),
.RSTALUMODE(RSTALUMODE), .RSTB(RSTB),
.RSTB(RSTB), .RSTC(RSTC),
.RSTC(RSTC), .RSTCTRL(RSTCTRL),
.RSTCTRL(RSTCTRL), .RSTD(RSTD),
.RSTD(RSTD), .RSTINMODE(RSTINMODE),
.RSTINMODE(RSTINMODE), .RSTM(RSTM),
.RSTM(RSTM), .RSTP(RSTP)
.RSTP(RSTP) );
);
"""
wire [29:0] iA;
wire [17:0] iB;
wire [47:0] iC;
wire [24:0] iD;
wire pA, pB, pC, pD, pAD, pM, pP;
wire [47:0] oP, mP;
wire [47:0] oPCOUT, mPCOUT;
generate generate
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin wire [29:0] $A;
// Disconnect the A-input if MREG is enabled, since wire [17:0] $B;
// combinatorial path is broken wire [47:0] $C;
if (AREG == 0 && MREG == 0 && PREG == 0) wire [24:0] $D;
assign iA = A, pA = 1'bx;
else
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && MREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 0)
assign iD = D;
else if (techmap_guard)
$error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
assign pD = 1'bx;
if (ADREG == 1 && techmap_guard)
$error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
assign pAD = 1'bx;
if (PREG == 0) begin
if (MREG == 1)
\$__ABC9_REG rM (.Q(pM));
else
assign pM = 1'bx;
assign pP = 1'bx;
end else begin
assign pM = 1'bx;
\$__ABC9_REG rP (.Q(pP));
end
if (MREG == 0 && PREG == 0)
assign mP = oP, mPCOUT = oPCOUT;
else
assign mP = 1'bx, mPCOUT = 1'bx;
\$__ABC9_DSP48E1_MULT_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
\$__ABC9_DSP48E1_MULT_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
`DSP48E1_INST(\$__ABC9_DSP48E1_MULT )
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
// Disconnect the A-input if MREG is enabled, since
// combinatorial path is broken
if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
assign iA = A, pA = 1'bx;
else
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && MREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 0 && ADREG == 0)
assign iD = D, pD = 1'bx;
else
\$__ABC9_REG #(.WIDTH(25)) rD (.I(D), .O(iD), .Q(pD));
if (PREG == 0) begin if (PREG == 0) begin
if (MREG == 1) begin if (MREG == 0 && AREG == 0) assign $A = A;
assign pAD = 1'bx; else assign $A = 30'bx;
\$__ABC9_REG rM (.Q(pM)); if (MREG == 0 && BREG == 0) assign $B = B;
end else begin else assign $B = 18'bx;
if (ADREG == 1) if (MREG == 0 && DREG == 0) assign $D = D;
\$__ABC9_REG rAD (.Q(pAD)); else assign $D = 25'bx;
else
assign pAD = 1'bx; if (CREG == 0) assign $C = C;
assign pM = 1'bx; else assign $C = 48'bx;
end end
assign pP = 1'bx; else begin
end else begin assign $A = 30'bx, $B = 18'bx, $C = 48'bx, $D = 25'bx;
assign pAD = 1'bx, pM = 1'bx;
\$__ABC9_REG rP (.Q(pP));
end end
if (MREG == 0 && PREG == 0) if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE")
assign mP = oP, mPCOUT = oPCOUT; $__ABC9_DSP48E1_MULT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE")
$__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE")
$__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
else else
assign mP = 1'bx, mPCOUT = 1'bx; $error("Invalid DSP48E1 configuration");
\$__ABC9_DSP48E1_MULT_DPORT_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
`DSP48E1_INST(\$__ABC9_DSP48E1_MULT_DPORT )
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
// Disconnect the A-input if MREG is enabled, since
// combinatorial path is broken
if (AREG == 0 && PREG == 0)
assign iA = A, pA = 1'bx;
else
\$__ABC9_REG #(.WIDTH(30)) rA (.I(A), .O(iA), .Q(pA));
if (BREG == 0 && PREG == 0)
assign iB = B, pB = 1'bx;
else
\$__ABC9_REG #(.WIDTH(18)) rB (.I(B), .O(iB), .Q(pB));
if (CREG == 0 && PREG == 0)
assign iC = C, pC = 1'bx;
else
\$__ABC9_REG #(.WIDTH(48)) rC (.I(C), .O(iC), .Q(pC));
if (DREG == 1 && techmap_guard)
$error("Invalid DSP48E1 configuration: DREG enabled but USE_DPORT == \"FALSE\"");
assign pD = 1'bx;
if (ADREG == 1 && techmap_guard)
$error("Invalid DSP48E1 configuration: ADREG enabled but USE_DPORT == \"FALSE\"");
assign pAD = 1'bx;
if (MREG == 1 && techmap_guard)
$error("Invalid DSP48E1 configuration: MREG enabled but USE_MULT == \"NONE\"");
assign pM = 1'bx;
if (PREG == 1)
\$__ABC9_REG rP (.Q(pP));
else
assign pP = 1'bx;
if (MREG == 0 && PREG == 0)
assign mP = oP, mPCOUT = oPCOUT;
else
assign mP = 1'bx, mPCOUT = 1'bx;
\$__ABC9_DSP48E1_P_MUX muxP (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
);
\$__ABC9_DSP48E1_PCOUT_MUX muxPCOUT (
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oPCOUT), .Mq(pM), .P(mPCOUT), .Pq(pP), .O(PCOUT)
);
`DSP48E1_INST(\$__ABC9_DSP48E1 )
end
else
$error("Invalid DSP48E1 configuration");
endgenerate endgenerate
`undef DSP48E1_INST
endmodule endmodule

View File

@ -44,147 +44,22 @@ endmodule
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); module \$__ABC9_LUT7 (input A, input [6:0] S, output Y);
endmodule endmodule
// Boxes used to represent the comb behaviour of various modes
// Modules used to model the comb/seq behaviour of DSP48E1 // of DSP48E1
// With abc9_map.v responsible for splicing the below modules
// between the combinatorial DSP48E1 box (e.g. disconnecting
// A when AREG, MREG or PREG is enabled and splicing in the
// "$__ABC9_DSP48E1_REG" blackbox as "REG" in the diagram below)
// this acts to first disables the combinatorial path (as there
// is no connectivity through REG), and secondly, since this is
// blackbox a new PI will be introduced with an arrival time of
// zero.
// Note: Since these "$__ABC9_DSP48E1_REG" modules are of a
// sequential nature, they are not passed as a box to ABC and
// (desirably) represented as PO/PIs.
//
// At the DSP output, we place a blackbox mux ("M" in the diagram
// below) to capture the fact that the critical-path could come
// from any one of its inputs.
// In contrast to "REG", the "$__ABC9_DSP48E1_*_MUX" modules are
// combinatorial blackboxes that do get passed to ABC.
// The propagation delay through this box (specified in the box
// file) captures the arrival time of the register (i.e.
// propagation from AREG to P after clock edge), or zero delay
// for the combinatorial path from the DSP.
//
// Doing so should means that ABC is able to analyse the
// worst-case delay through to P, regardless of if it was
// through any combinatorial paths (e.g. B, below) or an
// internal register (A2REG).
// However, the true value of being as complete as this is
// questionable since if AREG=1 and BREG=0 (as below)
// then the worse-case path would very likely be through B
// and very unlikely to be through AREG.Q...?
//
// In graphical form:
//
// +-----+
// +------>> REG >>----+
// | +-----+ |
// | |
// | +---------+ | __
// A >>-+X X-| | +--| \
// | DSP48E1 |P | M |--->> P
// | AREG=1 |-------|__/
// B >>------| |
// +---------+
//
`define ABC9_DSP48E1_MUX(__NAME__) """
module __NAME__ (input Aq, ADq, Bq, Cq, Dq, input [47:0] I, input Mq, input [47:0] P, input Pq, output [47:0] O);
endmodule
"""
(* abc9_box_id=2100 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_P_MUX )
(* abc9_box_id=2101 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_PCOUT_MUX )
(* abc9_box_id=2102 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_P_MUX )
(* abc9_box_id=2103 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX )
(* abc9_box_id=2104 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_P_MUX )
(* abc9_box_id=2105 *) `ABC9_DSP48E1_MUX(\$__ABC9_DSP48E1_PCOUT_MUX )
`define ABC9_DSP48E1(__NAME__) """ `define ABC9_DSP48E1(__NAME__) """
module __NAME__ ( module __NAME__ (
output [29:0] ACOUT, input [29:0] $A,
output [17:0] BCOUT, input [17:0] $B,
output reg CARRYCASCOUT, input [47:0] $C,
output reg [3:0] CARRYOUT, input [24:0] $D,
output reg MULTSIGNOUT, input [47:0] $P,
output OVERFLOW, input [47:0] $PCIN,
output reg signed [47:0] P, input [47:0] $PCOUT,
output PATTERNBDETECT, output [47:0] P,
output PATTERNDETECT, output [47:0] PCOUT);
output [47:0] PCOUT,
output UNDERFLOW,
input signed [29:0] A,
input [29:0] ACIN,
input [3:0] ALUMODE,
input signed [17:0] B,
input [17:0] BCIN,
input [47:0] C,
input CARRYCASCIN,
input CARRYIN,
input [2:0] CARRYINSEL,
input CEA1,
input CEA2,
input CEAD,
input CEALUMODE,
input CEB1,
input CEB2,
input CEC,
input CECARRYIN,
input CECTRL,
input CED,
input CEINMODE,
input CEM,
input CEP,
input CLK,
input [24:0] D,
input [4:0] INMODE,
input MULTSIGNIN,
input [6:0] OPMODE,
input [47:0] PCIN,
input RSTA,
input RSTALLCARRYIN,
input RSTALUMODE,
input RSTB,
input RSTC,
input RSTCTRL,
input RSTD,
input RSTINMODE,
input RSTM,
input RSTP
);
parameter integer ACASCREG = 1;
parameter integer ADREG = 1;
parameter integer ALUMODEREG = 1;
parameter integer AREG = 1;
parameter AUTORESET_PATDET = "NO_RESET";
parameter A_INPUT = "DIRECT";
parameter integer BCASCREG = 1;
parameter integer BREG = 1;
parameter B_INPUT = "DIRECT";
parameter integer CARRYINREG = 1;
parameter integer CARRYINSELREG = 1;
parameter integer CREG = 1;
parameter integer DREG = 1;
parameter integer INMODEREG = 1;
parameter integer MREG = 1;
parameter integer OPMODEREG = 1;
parameter integer PREG = 1;
parameter SEL_MASK = "MASK";
parameter SEL_PATTERN = "PATTERN";
parameter USE_DPORT = "FALSE";
parameter USE_MULT = "MULTIPLY";
parameter USE_PATTERN_DETECT = "NO_PATDET";
parameter USE_SIMD = "ONE48";
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
parameter [47:0] PATTERN = 48'h000000000000;
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
endmodule endmodule
""" """
(* abc9_box_id=3000 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT ) (* abc9_box_id=3000 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT)
(* abc9_box_id=3001 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1_MULT_DPORT ) (* abc9_box_id=3001 *) `ABC9_DSP48E1($__ABC9_DSP48E1_MULT_DPORT)
(* abc9_box_id=3002 *) `ABC9_DSP48E1(\$__ABC9_DSP48E1 ) (* abc9_box_id=3002 *) `ABC9_DSP48E1($__ABC9_DSP48E1)
`undef ABC9_DSP48E1

View File

@ -20,192 +20,24 @@
// ============================================================================ // ============================================================================
module \$__ABC9_LUT6 (input A, input [5:0] S, output Y); module $__ABC9_LUT6(input A, input [5:0] S, output Y);
assign Y = A; assign Y = A;
endmodule endmodule
module \$__ABC9_LUT7 (input A, input [6:0] S, output Y); module $__ABC9_LUT7(input A, input [6:0] S, output Y);
assign Y = A; assign Y = A;
endmodule endmodule
module \$__ABC9_REG (input [WIDTH-1:0] I, output [WIDTH-1:0] O, output Q);
parameter WIDTH = 1;
assign O = I;
endmodule
(* techmap_celltype = "$__ABC9_DSP48E1_MULT_P_MUX $__ABC9_DSP48E1_MULT_PCOUT_MUX $__ABC9_DSP48E1_MULT_DPORT_P_MUX $__ABC9_DSP48E1_MULT_DPORT_PCOUT_MUX $__ABC9_DSP48E1_P_MUX $__ABC9_DSP48E1_PCOUT_MUX" *)
module \$__ABC9_DSP48E1_MUX (
input Aq, Bq, Cq, Dq, ADq,
input [47:0] I,
input Mq,
input [47:0] P,
input Pq,
output [47:0] O
);
assign O = I;
endmodule
(* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *) (* techmap_celltype = "$__ABC9_DSP48E1_MULT $__ABC9_DSP48E1_MULT_DPORT $__ABC9_DSP48E1" *)
module \$__ABC9_DSP48E1 ( module $ABC9_DSP48E1(
(* techmap_autopurge *) output [29:0] ACOUT, input [29:0] $A,
(* techmap_autopurge *) output [17:0] BCOUT, input [17:0] $B,
(* techmap_autopurge *) output reg CARRYCASCOUT, input [47:0] $C,
(* techmap_autopurge *) output reg [3:0] CARRYOUT, input [24:0] $D,
(* techmap_autopurge *) output reg MULTSIGNOUT, input [47:0] $P,
(* techmap_autopurge *) output OVERFLOW, input [47:0] $PCIN,
(* techmap_autopurge *) output reg signed [47:0] P, input [47:0] $PCOUT,
(* techmap_autopurge *) output PATTERNBDETECT, output [47:0] P,
(* techmap_autopurge *) output PATTERNDETECT, output [47:0] PCOUT
(* techmap_autopurge *) output [47:0] PCOUT,
(* techmap_autopurge *) output UNDERFLOW,
(* techmap_autopurge *) input signed [29:0] A,
(* techmap_autopurge *) input [29:0] ACIN,
(* techmap_autopurge *) input [3:0] ALUMODE,
(* techmap_autopurge *) input signed [17:0] B,
(* techmap_autopurge *) input [17:0] BCIN,
(* techmap_autopurge *) input [47:0] C,
(* techmap_autopurge *) input CARRYCASCIN,
(* techmap_autopurge *) input CARRYIN,
(* techmap_autopurge *) input [2:0] CARRYINSEL,
(* techmap_autopurge *) input CEA1,
(* techmap_autopurge *) input CEA2,
(* techmap_autopurge *) input CEAD,
(* techmap_autopurge *) input CEALUMODE,
(* techmap_autopurge *) input CEB1,
(* techmap_autopurge *) input CEB2,
(* techmap_autopurge *) input CEC,
(* techmap_autopurge *) input CECARRYIN,
(* techmap_autopurge *) input CECTRL,
(* techmap_autopurge *) input CED,
(* techmap_autopurge *) input CEINMODE,
(* techmap_autopurge *) input CEM,
(* techmap_autopurge *) input CEP,
(* techmap_autopurge *) input CLK,
(* techmap_autopurge *) input [24:0] D,
(* techmap_autopurge *) input [4:0] INMODE,
(* techmap_autopurge *) input MULTSIGNIN,
(* techmap_autopurge *) input [6:0] OPMODE,
(* techmap_autopurge *) input [47:0] PCIN,
(* techmap_autopurge *) input RSTA,
(* techmap_autopurge *) input RSTALLCARRYIN,
(* techmap_autopurge *) input RSTALUMODE,
(* techmap_autopurge *) input RSTB,
(* techmap_autopurge *) input RSTC,
(* techmap_autopurge *) input RSTCTRL,
(* techmap_autopurge *) input RSTD,
(* techmap_autopurge *) input RSTINMODE,
(* techmap_autopurge *) input RSTM,
(* techmap_autopurge *) input RSTP
); );
parameter integer ACASCREG = 1; assign P = $P, PCOUT = $PCOUT;
parameter integer ADREG = 1;
parameter integer ALUMODEREG = 1;
parameter integer AREG = 1;
parameter AUTORESET_PATDET = "NO_RESET";
parameter A_INPUT = "DIRECT";
parameter integer BCASCREG = 1;
parameter integer BREG = 1;
parameter B_INPUT = "DIRECT";
parameter integer CARRYINREG = 1;
parameter integer CARRYINSELREG = 1;
parameter integer CREG = 1;
parameter integer DREG = 1;
parameter integer INMODEREG = 1;
parameter integer MREG = 1;
parameter integer OPMODEREG = 1;
parameter integer PREG = 1;
parameter SEL_MASK = "MASK";
parameter SEL_PATTERN = "PATTERN";
parameter USE_DPORT = "FALSE";
parameter USE_MULT = "MULTIPLY";
parameter USE_PATTERN_DETECT = "NO_PATDET";
parameter USE_SIMD = "ONE48";
parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
parameter [47:0] PATTERN = 48'h000000000000;
parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
parameter [4:0] IS_INMODE_INVERTED = 5'b0;
parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
DSP48E1 #(
.ACASCREG(ACASCREG),
.ADREG(ADREG),
.ALUMODEREG(ALUMODEREG),
.AREG(AREG),
.AUTORESET_PATDET(AUTORESET_PATDET),
.A_INPUT(A_INPUT),
.BCASCREG(BCASCREG),
.BREG(BREG),
.B_INPUT(B_INPUT),
.CARRYINREG(CARRYINREG),
.CARRYINSELREG(CARRYINSELREG),
.CREG(CREG),
.DREG(DREG),
.INMODEREG(INMODEREG),
.MREG(MREG),
.OPMODEREG(OPMODEREG),
.PREG(PREG),
.SEL_MASK(SEL_MASK),
.SEL_PATTERN(SEL_PATTERN),
.USE_DPORT(USE_DPORT),
.USE_MULT(USE_MULT),
.USE_PATTERN_DETECT(USE_PATTERN_DETECT),
.USE_SIMD(USE_SIMD),
.MASK(MASK),
.PATTERN(PATTERN),
.IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
.IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
.IS_CLK_INVERTED(IS_CLK_INVERTED),
.IS_INMODE_INVERTED(IS_INMODE_INVERTED),
.IS_OPMODE_INVERTED(IS_OPMODE_INVERTED)
) _TECHMAP_REPLACE_ (
.ACOUT(ACOUT),
.BCOUT(BCOUT),
.CARRYCASCOUT(CARRYCASCOUT),
.CARRYOUT(CARRYOUT),
.MULTSIGNOUT(MULTSIGNOUT),
.OVERFLOW(OVERFLOW),
.P(P),
.PATTERNBDETECT(PATTERNBDETECT),
.PATTERNDETECT(PATTERNDETECT),
.PCOUT(PCOUT),
.UNDERFLOW(UNDERFLOW),
.A(A),
.ACIN(ACIN),
.ALUMODE(ALUMODE),
.B(B),
.BCIN(BCIN),
.C(C),
.CARRYCASCIN(CARRYCASCIN),
.CARRYIN(CARRYIN),
.CARRYINSEL(CARRYINSEL),
.CEA1(CEA1),
.CEA2(CEA2),
.CEAD(CEAD),
.CEALUMODE(CEALUMODE),
.CEB1(CEB1),
.CEB2(CEB2),
.CEC(CEC),
.CECARRYIN(CECARRYIN),
.CECTRL(CECTRL),
.CED(CED),
.CEINMODE(CEINMODE),
.CEM(CEM),
.CEP(CEP),
.CLK(CLK),
.D(D),
.INMODE(INMODE),
.MULTSIGNIN(MULTSIGNIN),
.OPMODE(OPMODE),
.PCIN(PCIN),
.RSTA(RSTA),
.RSTALLCARRYIN(RSTALLCARRYIN),
.RSTALUMODE(RSTALUMODE),
.RSTB(RSTB),
.RSTC(RSTC),
.RSTCTRL(RSTCTRL),
.RSTD(RSTD),
.RSTINMODE(RSTINMODE),
.RSTM(RSTM),
.RSTP(RSTP)
);
endmodule endmodule

File diff suppressed because it is too large Load Diff

View File

@ -2160,9 +2160,15 @@ module DSP48E1 (
output reg [3:0] CARRYOUT, output reg [3:0] CARRYOUT,
output reg MULTSIGNOUT, output reg MULTSIGNOUT,
output OVERFLOW, output OVERFLOW,
`ifdef YOSYS
(* abc9_arrival = \DSP48E1.P_arrival () *)
`endif
output reg signed [47:0] P, output reg signed [47:0] P,
output reg PATTERNBDETECT, output reg PATTERNBDETECT,
output reg PATTERNDETECT, output reg PATTERNDETECT,
`ifdef YOSYS
(* abc9_arrival = \DSP48E1.PCOUT_arrival () *)
`endif
output [47:0] PCOUT, output [47:0] PCOUT,
output UNDERFLOW, output UNDERFLOW,
input signed [29:0] A, input signed [29:0] A,
@ -2235,6 +2241,77 @@ module DSP48E1 (
parameter [4:0] IS_INMODE_INVERTED = 5'b0; parameter [4:0] IS_INMODE_INVERTED = 5'b0;
parameter [6:0] IS_OPMODE_INVERTED = 7'b0; parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
`ifdef YOSYS
function integer \DSP48E1.P_arrival ;
begin
\DSP48E1.P_arrival = 0;
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
if (PREG != 0) \DSP48E1.P_arrival = 329;
// Worst-case from CREG and MREG
else if (CREG != 0) \DSP48E1.P_arrival = 1687;
else if (MREG != 0) \DSP48E1.P_arrival = 1671;
// Worst-case from AREG and BREG
else if (AREG != 0) \DSP48E1.P_arrival = 2952;
else if (BREG != 0) \DSP48E1.P_arrival = 2813;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
if (PREG != 0) \DSP48E1.P_arrival = 329;
// Worst-case from CREG and MREG
else if (CREG != 0) \DSP48E1.P_arrival = 1687;
else if (MREG != 0) \DSP48E1.P_arrival = 1671;
// Worst-case from AREG, ADREG, BREG, DREG
else if (AREG != 0) \DSP48E1.P_arrival = 3935;
else if (DREG != 0) \DSP48E1.P_arrival = 3908;
else if (ADREG != 0) \DSP48E1.P_arrival = 2958;
else if (BREG != 0) \DSP48E1.P_arrival = 2813;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
if (PREG != 0) \DSP48E1.P_arrival = 329;
// Worst-case from AREG, BREG, CREG
else if (CREG != 0) \DSP48E1.P_arrival = 1687;
else if (AREG != 0) \DSP48E1.P_arrival = 1632;
else if (BREG != 0) \DSP48E1.P_arrival = 1616;
end
//else
// $error("Invalid DSP48E1 configuration");
end
endfunction
function integer \DSP48E1.PCOUT_arrival ;
begin
\DSP48E1.PCOUT_arrival = 0;
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
if (PREG != 0) \DSP48E1.PCOUT_arrival = 435;
// Worst-case from CREG and MREG
else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835;
else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819;
// Worst-case from AREG and BREG
else if (AREG != 0) \DSP48E1.PCOUT_arrival = 3098;
else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960;
end
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE") begin
if (PREG != 0) \DSP48E1.PCOUT_arrival = 435;
// Worst-case from CREG and MREG
else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835;
else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819;
// Worst-case from AREG, ADREG, BREG, DREG
else if (AREG != 0) \DSP48E1.PCOUT_arrival = 4083;
else if (DREG != 0) \DSP48E1.PCOUT_arrival = 4056;
else if (BREG != 0) \DSP48E1.PCOUT_arrival = 2960;
else if (ADREG != 0) \DSP48E1.PCOUT_arrival = 2859;
end
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE") begin
if (PREG != 0) \DSP48E1.PCOUT_arrival = 435;
// Worst-case from AREG, BREG, CREG
else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835;
else if (AREG != 0) \DSP48E1.PCOUT_arrival = 1780;
else if (BREG != 0) \DSP48E1.PCOUT_arrival = 1765;
end
//else
// $error("Invalid DSP48E1 configuration");
end
endfunction
`endif
initial begin initial begin
`ifndef YOSYS `ifndef YOSYS
if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value"); if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");