xc7: Map combinational DSP48E1s
authorDavid Shah <dave@ds0.me>
Mon, 8 Jul 2019 18:15:25 +0000 (19:15 +0100)
committerDavid Shah <dave@ds0.me>
Mon, 8 Jul 2019 18:15:25 +0000 (19:15 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/ecp5/dsp_map.v
techlibs/xilinx/Makefile.inc
techlibs/xilinx/dsp_map.v [new file with mode: 0644]
techlibs/xilinx/synth_xilinx.cc

index 22e30574cb4398d7386fc59dbb10208fd3707c1b..5f7755afbda15ad013a9a1d94979b920eeaeaaac 100644 (file)
@@ -1,5 +1,5 @@
 module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] OUT);
-       MULT18X18D mult_i(
+       MULT18X18D _TECHMAP_REPLACE_ (
                .A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .A4(A[4]), .A5(A[5]), .A6(A[6]), .A7(A[7]), .A8(A[8]), .A9(A[9]), .A10(A[10]), .A11(A[11]), .A12(A[12]), .A13(A[13]), .A14(A[14]), .A15(A[15]), .A16(A[16]), .A17(A[17]),
                .B0(B[0]), .B1(B[1]), .B2(B[2]), .B3(B[3]), .B4(B[4]), .B5(B[5]), .B6(B[6]), .B7(B[7]), .B8(B[8]), .B9(B[9]), .B10(B[10]), .B11(B[11]), .B12(B[12]), .B13(B[13]), .B14(B[14]), .B15(B[15]), .B16(B[16]), .B17(B[17]),
                .C17(1'b0), .C16(1'b0), .C15(1'b0), .C14(1'b0), .C13(1'b0), .C12(1'b0), .C11(1'b0), .C10(1'b0), .C9(1'b0), .C8(1'b0), .C7(1'b0), .C6(1'b0), .C5(1'b0), .C4(1'b0), .C3(1'b0), .C2(1'b0), .C1(1'b0), .C0(1'b0),
@@ -7,4 +7,4 @@ module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] OUT);
 
                .P0(OUT[0]), .P1(OUT[1]), .P2(OUT[2]), .P3(OUT[3]), .P4(OUT[4]), .P5(OUT[5]), .P6(OUT[6]), .P7(OUT[7]), .P8(OUT[8]), .P9(OUT[9]), .P10(OUT[10]), .P11(OUT[11]), .P12(OUT[12]), .P13(OUT[13]), .P14(OUT[14]), .P15(OUT[15]), .P16(OUT[16]), .P17(OUT[17]), .P18(OUT[18]), .P19(OUT[19]), .P20(OUT[20]), .P21(OUT[21]), .P22(OUT[22]), .P23(OUT[23]), .P24(OUT[24]), .P25(OUT[25]), .P26(OUT[26]), .P27(OUT[27]), .P28(OUT[28]), .P29(OUT[29]), .P30(OUT[30]), .P31(OUT[31]), .P32(OUT[32]), .P33(OUT[33]), .P34(OUT[34]), .P35(OUT[35])
        );
-endmodule
\ No newline at end of file
+endmodule
index 17c5df37d8c925deb06e2f0559fd5f08df8bda6d..c41015e948c26f65b5911a0bac7d8855d0986abf 100644 (file)
@@ -31,6 +31,7 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/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/abc_xc7.box))
 $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
diff --git a/techlibs/xilinx/dsp_map.v b/techlibs/xilinx/dsp_map.v
new file mode 100644 (file)
index 0000000..4faa204
--- /dev/null
@@ -0,0 +1,40 @@
+module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] OUT);
+       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)
+       ) _TECHMAP_REPLACE_ (
+               //Data path
+               .A({5'b0, A}),
+               .B(B),
+               .C(48'b0),
+               .D(24'b0),
+               .P(P_48),
+
+               .INMODE(4'b0000),
+               .ALUMODE(4'b0000),
+               .OPMODE(7'b000101),
+               .CARRYINSEL(3'b000),
+
+               .ACIN(30'b0),
+               .BCIN(18'b0),
+               .PCIN(48'b0),
+               .CARRYIN(1'b0)
+       );
+       assign OUT = P_48;
+endmodule
index 0a30848aa6c06444d9799fee8960f0915a482b73..db0cbb64491df8c9a565949a6e4606eb906dcb95 100644 (file)
@@ -77,6 +77,9 @@ struct SynthXilinxPass : public ScriptPass
                log("    -nowidelut\n");
                log("        do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
                log("\n");
+               log("    -nodsp\n");
+               log("        do not use DSP48E1s to implement multipliers and associated logic\n");
+               log("\n");
                log("    -widemux <int>\n");
                log("        enable inference of hard multiplexer resources (MuxFx) for muxes at or\n");
                log("        above this number of inputs (minimum value 5).\n");
@@ -103,7 +106,7 @@ struct SynthXilinxPass : public ScriptPass
        }
 
        std::string top_opt, edif_file, blif_file, family;
-       bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
+       bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, nodsp, abc9;
        int widemux;
 
        void clear_flags() YS_OVERRIDE
@@ -121,6 +124,7 @@ struct SynthXilinxPass : public ScriptPass
                nosrl = false;
                nocarry = false;
                nowidelut = false;
+               nodsp = false;
                abc9 = false;
                widemux = 0;
        }
@@ -201,6 +205,10 @@ struct SynthXilinxPass : public ScriptPass
                                abc9 = true;
                                continue;
                        }
+                       if (args[argidx] == "-nodsp") {
+                               nodsp = true;
+                               continue;
+                       }
                        break;
                }
                extra_args(args, argidx, design);
@@ -239,10 +247,31 @@ struct SynthXilinxPass : public ScriptPass
                }
 
                if (check_label("coarse")) {
-                       if (help_mode)
-                               run("synth -run coarse [-flatten]", "(with '-flatten')");
-                       else
-                               run("synth -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')");
+                       run("proc");
+                       if (flatten || help_mode)
+                               run("flatten", "(with '-flatten')");
+                       run("opt_expr");
+                       run("opt_clean");
+                       run("check");
+                       run("opt");
+                       run("wreduce");
+                       run("peepopt");
+                       run("opt_clean");
+                       run("share");
+                       run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+                       run("opt_expr");
+                       run("opt_clean");
+                       if (!nodsp || help_mode) {
+                               run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 -D DSP_NAME=$__MUL25X18");
+                               run("clean");
+                               run("techmap -map +/xilinx/dsp_map.v");
+                       }
+                       run("alumacc");
+                       run("opt");
+                       run("fsm");
+                       run("opt -fast");
+                       run("memory -nomap");
+                       run("opt_clean");
 
                        if (widemux > 0 || help_mode)
                                run("muxpack", "    ('-widemux' only)");