Grrr
[yosys.git] / techlibs / xilinx / synth_xilinx.cc
index c4c27d816562f621ca4456a8350a4a9ea9ffd7b7..dfe4c647b7ae381b735232260b8bbfe3ef802fe5 100644 (file)
@@ -42,6 +42,10 @@ struct SynthXilinxPass : public ScriptPass
                log("    -top <module>\n");
                log("        use the specified module as top module\n");
                log("\n");
+               log("    -arch {xcup|xcu|xc7|xc6s}\n");
+               log("        run synthesis for the specified Xilinx architecture\n");
+               log("        default: xc7\n");
+               log("\n");
                log("    -edif <file>\n");
                log("        write the design to the specified edif file. writing of an output file\n");
                log("        is omitted if this parameter is not specified.\n");
@@ -63,6 +67,12 @@ struct SynthXilinxPass : public ScriptPass
                log("    -nosrl\n");
                log("        disable inference of shift registers\n");
                log("\n");
+               log("    -nocarry\n");
+               log("        do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
+               log("\n");
+               log("    -nowidelut\n");
+               log("        do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
+               log("\n");
                log("    -run <from_label>:<to_label>\n");
                log("        only run the commands between the labels (see below). an empty\n");
                log("        from label is synonymous to 'begin', and empty to label is\n");
@@ -80,8 +90,8 @@ struct SynthXilinxPass : public ScriptPass
                log("\n");
        }
 
-       std::string top_opt, edif_file, blif_file;
-       bool flatten, retime, vpr, nobram, nodram, nosrl;
+       std::string top_opt, edif_file, blif_file, arch;
+       bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut;
 
        void clear_flags() YS_OVERRIDE
        {
@@ -94,6 +104,9 @@ struct SynthXilinxPass : public ScriptPass
                nobram = false;
                nodram = false;
                nosrl = false;
+               nocarry = false;
+               nowidelut = false;
+               arch = "xc7";
        }
 
        void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -108,6 +121,10 @@ struct SynthXilinxPass : public ScriptPass
                                top_opt = "-top " + args[++argidx];
                                continue;
                        }
+                       if (args[argidx] == "-arch" && argidx+1 < args.size()) {
+                               arch = args[++argidx];
+                               continue;
+                       }
                        if (args[argidx] == "-edif" && argidx+1 < args.size()) {
                                edif_file = args[++argidx];
                                continue;
@@ -132,6 +149,14 @@ struct SynthXilinxPass : public ScriptPass
                                retime = true;
                                continue;
                        }
+                       if (args[argidx] == "-nocarry") {
+                               nocarry = true;
+                               continue;
+                       }
+                       if (args[argidx] == "-nowidelut") {
+                               nowidelut = true;
+                               continue;
+                       }
                        if (args[argidx] == "-vpr") {
                                vpr = true;
                                continue;
@@ -152,6 +177,9 @@ struct SynthXilinxPass : public ScriptPass
                }
                extra_args(args, argidx, design);
 
+               if (arch != "xcup" && arch != "xcu" && arch != "xc7" && arch != "xc6s")
+                       log_cmd_error("Invalid Xilinx -arch setting: %s\n", arch.c_str());
+
                if (!design->full_selection())
                        log_cmd_error("This command only operates on fully selected designs!\n");
 
@@ -205,47 +233,48 @@ struct SynthXilinxPass : public ScriptPass
                }
 
                if (check_label("fine")) {
-                       run("opt -fast");
+                       // shregmap -tech xilinx can cope with $shiftx and $mux
+                       //   cells for identifiying variable-length shift registers,
+                       //   so attempt to convert $pmux-es to the former
+                       if (!nosrl || help_mode)
+                               run("pmux2shiftx", "(skip if '-nosrl')");
+
+                       run("opt -fast -full");
                        run("memory_map");
                        run("dffsr2dff");
                        run("dff2dffe");
+                       run("opt -full");
 
-                       if (!vpr || help_mode)
-                               run("techmap -map +/xilinx/arith_map.v");
-                       else
-                               run("techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
-
-                       run("hierarchy -check");
-                       run("opt -fast");
-               }
-
-               if (check_label("map_cells"))
-               {
                        if (!nosrl || help_mode) {
                                // shregmap operates on bit-level flops, not word-level,
                                //   so break those down here
                                run("simplemap t:$dff t:$dffe", "(skip if '-nosrl')");
-                               // shregmap -tech xilinx can cope with $shiftx and $mux
-                               //   cells for identifiying variable-length shift registers,
-                               //   so attempt to convert $pmux-es to the former
-                               run("pmux2shiftx", "(skip if '-nosrl')");
-                               // pmux2shiftx can leave behind a $pmux with a single entry
-                               //   -- need this to clean that up before shregmap
-                               run("opt_expr -mux_undef", "(skip if '-nosrl')");
                                // shregmap with '-tech xilinx' infers variable length shift regs
                                run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
                        }
 
-                       run("techmap -map +/xilinx/cells_map.v");
+                       if (help_mode)
+                               run("techmap -map +/techmap.v [-map +/xilinx/arith_map.v]", "(skip if '-nocarry')");
+                       else if (!nocarry) {
+                               if (!vpr)
+                                       run("techmap -map +/techmap.v -map +/xilinx/arith_map.v");
+                               else
+                                       run("techmap -map +/techmap.v -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
+                       }
+
+                       run("opt -fast");
+               }
+
+               if (check_label("map_cells")) {
+                       run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
                        run("clean");
                }
 
-               if (check_label("map_luts"))
-               {
-                       run("opt -full");
-                       run("techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v");
+               if (check_label("map_luts")) {
                        if (help_mode)
-                               run("abc -luts 2:2,3,6:5,10,20 [-dff]");
+                               run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(skip if 'nowidelut', only for '-retime')");
+                       else if (nowidelut)
+                               run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
                        else
                                run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
                        run("clean");
@@ -259,21 +288,18 @@ struct SynthXilinxPass : public ScriptPass
                        run("clean");
                }
 
-               if (check_label("check"))
-               {
+               if (check_label("check")) {
                        run("hierarchy -check");
-                       run("stat");
+                       run("stat -tech xilinx");
                        run("check -noinit");
                }
 
-               if (check_label("edif"))
-               {
+               if (check_label("edif")) {
                        if (!edif_file.empty() || help_mode)
                                run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
                }
 
-               if (check_label("blif"))
-               {
+               if (check_label("blif")) {
                        if (!blif_file.empty() || help_mode)
                                run(stringf("write_blif %s", edif_file.c_str()));
                }