mirror of https://github.com/YosysHQ/yosys.git
Rework abc9's DSP48E1 model
This commit is contained in:
parent
9e5ff30d05
commit
db04161eca
|
@ -282,11 +282,9 @@ 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),
|
||||||
|
@ -324,17 +322,17 @@ __CELL__ #(
|
||||||
.CARRYOUT(CARRYOUT),
|
.CARRYOUT(CARRYOUT),
|
||||||
.MULTSIGNOUT(MULTSIGNOUT),
|
.MULTSIGNOUT(MULTSIGNOUT),
|
||||||
.OVERFLOW(OVERFLOW),
|
.OVERFLOW(OVERFLOW),
|
||||||
.P(oP),
|
.P($P),
|
||||||
.PATTERNBDETECT(PATTERNBDETECT),
|
.PATTERNBDETECT(PATTERNBDETECT),
|
||||||
.PATTERNDETECT(PATTERNDETECT),
|
.PATTERNDETECT(PATTERNDETECT),
|
||||||
.PCOUT(oPCOUT),
|
.PCOUT($PCOUT),
|
||||||
.UNDERFLOW(UNDERFLOW),
|
.UNDERFLOW(UNDERFLOW),
|
||||||
.A(iA),
|
.A(A),
|
||||||
.ACIN(ACIN),
|
.ACIN(ACIN),
|
||||||
.ALUMODE(ALUMODE),
|
.ALUMODE(ALUMODE),
|
||||||
.B(iB),
|
.B(B),
|
||||||
.BCIN(BCIN),
|
.BCIN(BCIN),
|
||||||
.C(iC),
|
.C(C),
|
||||||
.CARRYCASCIN(CARRYCASCIN),
|
.CARRYCASCIN(CARRYCASCIN),
|
||||||
.CARRYIN(CARRYIN),
|
.CARRYIN(CARRYIN),
|
||||||
.CARRYINSEL(CARRYINSEL),
|
.CARRYINSEL(CARRYINSEL),
|
||||||
|
@ -352,7 +350,7 @@ __CELL__ #(
|
||||||
.CEM(CEM),
|
.CEM(CEM),
|
||||||
.CEP(CEP),
|
.CEP(CEP),
|
||||||
.CLK(CLK),
|
.CLK(CLK),
|
||||||
.D(iD),
|
.D(D),
|
||||||
.INMODE(INMODE),
|
.INMODE(INMODE),
|
||||||
.MULTSIGNIN(MULTSIGNIN),
|
.MULTSIGNIN(MULTSIGNIN),
|
||||||
.OPMODE(OPMODE),
|
.OPMODE(OPMODE),
|
||||||
|
@ -368,158 +366,29 @@ __CELL__ #(
|
||||||
.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)
|
if (PREG != 0)
|
||||||
assign mP = oP, mPCOUT = oPCOUT;
|
assign P = $P, PCOUT = $PCOUT;
|
||||||
else
|
else begin
|
||||||
assign mP = 1'bx, mPCOUT = 1'bx;
|
if (AREG == 0) assign $A = A;
|
||||||
\$__ABC9_DSP48E1_MULT_P_MUX muxP (
|
if (BREG == 0) assign $B = B;
|
||||||
.Aq(pA), .Bq(pB), .Cq(pC), .Dq(pD), .ADq(pAD), .I(oP), .Mq(pM), .P(mP), .Pq(pP), .O(P)
|
if (CREG == 0) assign $C = C;
|
||||||
);
|
if (DREG == 0) assign $D = D;
|
||||||
\$__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 )
|
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE")
|
||||||
end
|
$__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") begin
|
else if (USE_MULT == "MULTIPLY" && USE_DPORT == "TRUE")
|
||||||
// Disconnect the A-input if MREG is enabled, since
|
$__ABC9_DSP48E1_MULT_DPORT dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
|
||||||
// combinatorial path is broken
|
else if (USE_MULT == "NONE" && USE_DPORT == "FALSE")
|
||||||
if (AREG == 0 && ADREG == 0 && MREG == 0 && PREG == 0)
|
$__ABC9_DSP48E1 dsp_comb(.$A($A), .$B($B), .$C($C), .$D($D), .$P($P), .$PCIN(PCIN), .$PCOUT($PCOUT), .P(P), .PCOUT(PCOUT));
|
||||||
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 (MREG == 1) begin
|
|
||||||
assign pAD = 1'bx;
|
|
||||||
\$__ABC9_REG rM (.Q(pM));
|
|
||||||
end else begin
|
|
||||||
if (ADREG == 1)
|
|
||||||
\$__ABC9_REG rAD (.Q(pAD));
|
|
||||||
else
|
|
||||||
assign pAD = 1'bx;
|
|
||||||
assign pM = 1'bx;
|
|
||||||
end
|
|
||||||
assign pP = 1'bx;
|
|
||||||
end else begin
|
|
||||||
assign pAD = 1'bx, 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_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
|
else
|
||||||
$error("Invalid DSP48E1 configuration");
|
$error("Invalid DSP48E1 configuration");
|
||||||
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
`undef DSP48E1_INST
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
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)
|
|
||||||
);
|
);
|
||||||
|
assign P = $P, PCOUT = $PCOUT;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||||
|
`ifndef __ICARUS__
|
||||||
|
(* abc9_arrival = \DSP48E1.P_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *)
|
||||||
|
`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,
|
||||||
|
`ifndef __ICARUS__
|
||||||
|
(* abc9_arrival = \DSP48E1.PCOUT_arrival (USE_MULT, USE_DPORT, AREG, ADREG, BREG, CREG, DREG, MREG, PREG) *)
|
||||||
|
`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,79 @@ 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;
|
||||||
|
|
||||||
|
function \DSP48E1.P_arrival ;
|
||||||
|
input USE_MULT, USE_DPORT;
|
||||||
|
input AREG, ADREG, BREG, CREG, DREG, MREG, PREG;
|
||||||
|
begin
|
||||||
|
\DSP48E1.P_arrival = 0;
|
||||||
|
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
|
||||||
|
if (PREG != 0) \DSP48E1.P_arrival = 329;
|
||||||
|
// Worse-case from CREG and MREG
|
||||||
|
else if (CREG != 0) \DSP48E1.P_arrival = 1687;
|
||||||
|
else if (MREG != 0) \DSP48E1.P_arrival = 1671;
|
||||||
|
// Worse-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;
|
||||||
|
// Worse-case from CREG and MREG
|
||||||
|
else if (CREG != 0) \DSP48E1.P_arrival = 1687;
|
||||||
|
else if (MREG != 0) \DSP48E1.P_arrival = 1671;
|
||||||
|
// Worse-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;
|
||||||
|
// Worse-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 \DSP48E1.PCOUT_arrival ;
|
||||||
|
input USE_MULT, USE_DPORT;
|
||||||
|
input AREG, ADREG, BREG, CREG, DREG, MREG, PREG;
|
||||||
|
begin
|
||||||
|
\DSP48E1.PCOUT_arrival = 0;
|
||||||
|
if (USE_MULT == "MULTIPLY" && USE_DPORT == "FALSE") begin
|
||||||
|
if (PREG != 0) \DSP48E1.PCOUT_arrival = 435;
|
||||||
|
// Worse-case from CREG and MREG
|
||||||
|
else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835;
|
||||||
|
else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819;
|
||||||
|
// Worse-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;
|
||||||
|
// Worse-case from CREG and MREG
|
||||||
|
else if (CREG != 0) \DSP48E1.PCOUT_arrival = 1835;
|
||||||
|
else if (MREG != 0) \DSP48E1.PCOUT_arrival = 1819;
|
||||||
|
// Worse-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;
|
||||||
|
// Worse-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
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
`ifdef __ICARUS__
|
`ifdef __ICARUS__
|
||||||
if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
|
if (AUTORESET_PATDET != "NO_RESET") $fatal(1, "Unsupported AUTORESET_PATDET value");
|
||||||
|
|
Loading…
Reference in New Issue