aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--techlibs/xilinx/Makefile.inc8
-rw-r--r--techlibs/xilinx/synth_xilinx.cc53
-rw-r--r--techlibs/xilinx/xc3s_mult_map.v14
-rw-r--r--techlibs/xilinx/xc3sda_dsp_map.v34
-rw-r--r--techlibs/xilinx/xc4v_dsp_map.v38
-rw-r--r--techlibs/xilinx/xc5v_dsp_map.v45
-rw-r--r--techlibs/xilinx/xc6s_dsp_map.v35
-rw-r--r--techlibs/xilinx/xc7_dsp_map.v (renamed from techlibs/xilinx/dsp_map.v)0
-rw-r--r--techlibs/xilinx/xcu_dsp_map.v51
9 files changed, 269 insertions, 9 deletions
diff --git a/techlibs/xilinx/Makefile.inc b/techlibs/xilinx/Makefile.inc
index 1e59f0a1b..3354605ef 100644
--- a/techlibs/xilinx/Makefile.inc
+++ b/techlibs/xilinx/Makefile.inc
@@ -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))
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 6f8254b59..6566da832 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -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");
diff --git a/techlibs/xilinx/xc3s_mult_map.v b/techlibs/xilinx/xc3s_mult_map.v
new file mode 100644
index 000000000..67cd4ac60
--- /dev/null
+++ b/techlibs/xilinx/xc3s_mult_map.v
@@ -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
+
diff --git a/techlibs/xilinx/xc3sda_dsp_map.v b/techlibs/xilinx/xc3sda_dsp_map.v
new file mode 100644
index 000000000..87348a173
--- /dev/null
+++ b/techlibs/xilinx/xc3sda_dsp_map.v
@@ -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
+
diff --git a/techlibs/xilinx/xc4v_dsp_map.v b/techlibs/xilinx/xc4v_dsp_map.v
new file mode 100644
index 000000000..69c42f343
--- /dev/null
+++ b/techlibs/xilinx/xc4v_dsp_map.v
@@ -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
diff --git a/techlibs/xilinx/xc5v_dsp_map.v b/techlibs/xilinx/xc5v_dsp_map.v
new file mode 100644
index 000000000..fc7ba46cc
--- /dev/null
+++ b/techlibs/xilinx/xc5v_dsp_map.v
@@ -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
+
diff --git a/techlibs/xilinx/xc6s_dsp_map.v b/techlibs/xilinx/xc6s_dsp_map.v
new file mode 100644
index 000000000..e8705723b
--- /dev/null
+++ b/techlibs/xilinx/xc6s_dsp_map.v
@@ -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
+
+
diff --git a/techlibs/xilinx/dsp_map.v b/techlibs/xilinx/xc7_dsp_map.v
index a4256eb92..a4256eb92 100644
--- a/techlibs/xilinx/dsp_map.v
+++ b/techlibs/xilinx/xc7_dsp_map.v
diff --git a/techlibs/xilinx/xcu_dsp_map.v b/techlibs/xilinx/xcu_dsp_map.v
new file mode 100644
index 000000000..fa95a5776
--- /dev/null
+++ b/techlibs/xilinx/xcu_dsp_map.v
@@ -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
+