mirror of https://github.com/YosysHQ/yosys.git
xilinx: Support multiplier mapping for all families.
This supports several older families that are not yet supported for actual logic synthesis — the intention is to add them soon.
This commit is contained in:
parent
a3a7bb9bf7
commit
7b350cacd4
|
@ -42,7 +42,13 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
|
|||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3s_mult_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc3sda_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc4v_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc5v_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_dsp_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_dsp_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_map.v))
|
||||
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc9_unmap.v))
|
||||
|
|
|
@ -343,14 +343,51 @@ struct SynthXilinxPass : public ScriptPass
|
|||
if (!nodsp || help_mode) {
|
||||
run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
|
||||
// NB: Xilinx multipliers are signed only
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/dsp_map.v -D DSP_A_MAXWIDTH=25 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 -D DSP_B_MAXWIDTH=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
if (help_mode)
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/{family}_dsp_map.v {options}");
|
||||
else if (family == "xc2v" || family == "xc3s" || family == "xc3se" || family == "xc3sa")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3s_mult_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc3sda")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc3sda_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc6s")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc6s_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc4v")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc4v_dsp_map.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL18X18");
|
||||
else if (family == "xc5v")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc5v_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
else if (family == "xc6v" || family == "xc7")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xc7_dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
else if (family == "xcu" || family == "xcup")
|
||||
run("techmap -map +/mul2dsp.v -map +/xilinx/xcu_dsp_map.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL27X18");
|
||||
run("select a:mul2dsp");
|
||||
run("setattr -unset mul2dsp");
|
||||
run("opt_expr -fine");
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
MULT18X18 _TECHMAP_REPLACE_ (
|
||||
.A(A),
|
||||
.B(B),
|
||||
.P(Y)
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48A #(
|
||||
// Disable all registers
|
||||
.A0REG(0),
|
||||
.A1REG(0),
|
||||
.B0REG(0),
|
||||
.B1REG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSEL("OPMODE5"),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(18'b0),
|
||||
.P(P_48),
|
||||
|
||||
.OPMODE(8'b0000010)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48 #(
|
||||
// Disable all registers
|
||||
.AREG(0),
|
||||
.BREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.SUBTRACTREG(0),
|
||||
.LEGACY_MODE("MULT18X18")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.P(P_48),
|
||||
|
||||
.SUBTRACT(1'b0),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(2'b00),
|
||||
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
|
@ -0,0 +1,45 @@
|
|||
module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.MULTCARRYINREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULT"),
|
||||
.USE_SIMD("ONE48")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{5{A[24]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.P(P_48),
|
||||
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48A1 #(
|
||||
// Disable all registers
|
||||
.A0REG(0),
|
||||
.A1REG(0),
|
||||
.B0REG(0),
|
||||
.B1REG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSEL("OPMODE5"),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A(A),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(18'b0),
|
||||
.P(P_48),
|
||||
|
||||
.OPMODE(8'b0000010)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
module \$__MUL27X18 (input [26:0] A, input [17:0] B, output [44:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E2 #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.ADREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.INMODEREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULTIPLY"),
|
||||
.USE_SIMD("ONE48"),
|
||||
.AMULTSEL("A"),
|
||||
.BMULTSEL("B")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{3{A[26]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(27'b0),
|
||||
.P(P_48),
|
||||
|
||||
.INMODE(5'b00000),
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(9'b00000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue