$(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))
+++ /dev/null
-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;
- DSP48E1 #(
- // 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"),
- .USE_DPORT("FALSE")
- ) _TECHMAP_REPLACE_ (
- //Data path
- .A({{5{A[24]}}, A}),
- .B(B),
- .C(48'b0),
- .D(25'b0),
- .P(P_48),
-
- .INMODE(5'b00000),
- .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
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");
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+
+
--- /dev/null
+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;
+ DSP48E1 #(
+ // 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"),
+ .USE_DPORT("FALSE")
+ ) _TECHMAP_REPLACE_ (
+ //Data path
+ .A({{5{A[24]}}, A}),
+ .B(B),
+ .C(48'b0),
+ .D(25'b0),
+ .P(P_48),
+
+ .INMODE(5'b00000),
+ .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
--- /dev/null
+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
+