diff options
Diffstat (limited to 'techlibs/xilinx/synth_xilinx.cc')
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 58dd928a0..524c54d3b 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -63,6 +63,9 @@ struct SynthXilinxPass : public Pass log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); log("\n"); + log(" -nocarry\n"); + log(" disable inference of carry chains\n"); + log("\n"); log(" -nobram\n"); log(" disable inference of block rams\n"); log("\n"); @@ -72,6 +75,9 @@ struct SynthXilinxPass : public Pass log(" -nosrl\n"); log(" disable inference of shift registers\n"); log("\n"); + log(" -nomux\n"); + log(" disable inference of wide multiplexers\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"); @@ -83,6 +89,9 @@ struct SynthXilinxPass : public Pass log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); + log(" -abc9\n"); + log(" use abc9 instead of abc\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); log("\n"); @@ -112,12 +121,12 @@ struct SynthXilinxPass : public Pass log(" memory_map\n"); log(" dffsr2dff\n"); log(" dff2dffe\n"); - log(" techmap -map +/xilinx/arith_map.v\n"); + log(" techmap -map +/xilinx/arith_map.v (without '-nocarry' only)\n"); log(" opt -fast\n"); log("\n"); log(" map_cells:\n"); + log(" pmux2shiftx (without '-nosrl' and '-nomux' only)\n"); log(" simplemap t:$dff t:$dffe (without '-nosrl' only)\n"); - log(" pmux2shiftx (without '-nosrl' only)\n"); log(" opt_expr -mux_undef (without '-nosrl' only)\n"); log(" shregmap -tech xilinx -minlen 3 (without '-nosrl' only)\n"); log(" techmap -map +/xilinx/cells_map.v\n"); @@ -129,10 +138,9 @@ struct SynthXilinxPass : public Pass log(" abc -luts 2:2,3,6:5,10,20 [-dff]\n"); log(" clean\n"); log(" shregmap -minlen 3 -init -params -enpol any_or_none (without '-nosrl' only)\n"); - log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); + log(" techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v\n"); log(" dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT \\\n"); log(" -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n"); - log(" clean\n"); log("\n"); log(" check:\n"); log(" hierarchy -check\n"); @@ -152,12 +160,15 @@ struct SynthXilinxPass : public Pass std::string edif_file; std::string blif_file; std::string run_from, run_to; + std::string abc = "abc"; bool flatten = false; bool retime = false; bool vpr = false; + bool nocarry = false; bool nobram = false; bool nodram = false; bool nosrl = false; + bool nomux = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -194,6 +205,10 @@ struct SynthXilinxPass : public Pass vpr = true; continue; } + if (args[argidx] == "-nocarry") { + nocarry = true; + continue; + } if (args[argidx] == "-nobram") { nobram = true; continue; @@ -204,6 +219,14 @@ struct SynthXilinxPass : public Pass } if (args[argidx] == "-nosrl") { nosrl = true; + continue; + } + if (args[argidx] == "-nomux") { + nomux = true; + continue; + } + if (args[argidx] == "-abc9") { + abc = "abc9"; continue; } break; @@ -269,10 +292,11 @@ struct SynthXilinxPass : public Pass Pass::call(design, "dffsr2dff"); Pass::call(design, "dff2dffe"); - if (vpr) { - Pass::call(design, "techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); - } else { - Pass::call(design, "techmap -map +/xilinx/arith_map.v"); + if (!nocarry) { + if (vpr) + Pass::call(design, "techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); + else + Pass::call(design, "techmap -map +/xilinx/arith_map.v"); } Pass::call(design, "opt -fast"); @@ -280,14 +304,17 @@ struct SynthXilinxPass : public Pass if (check_label(active, run_from, run_to, "map_cells")) { + // shregmap -tech xilinx can cope with $shiftx and $mux + // cells for identifying variable-length shift registers, + // so attempt to convert $pmux-es to the former + // Also: wide multiplexer inference benefits from this too + if (!nosrl || !nomux) + Pass::call(design, "pmux2shiftx"); + if (!nosrl) { // shregmap operates on bit-level flops, not word-level, // so break those down here Pass::call(design, "simplemap t:$dff t:$dffe"); - // 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 - Pass::call(design, "pmux2shiftx"); // pmux2shiftx can leave behind a $pmux with a single entry // -- need this to clean that up before shregmap Pass::call(design, "opt_expr -mux_undef"); @@ -295,7 +322,10 @@ struct SynthXilinxPass : public Pass Pass::call(design, "shregmap -tech xilinx -minlen 3"); } - Pass::call(design, "techmap -map +/xilinx/cells_map.v"); + std::string define; + if (nomux) + define += " -D NO_MUXFN"; + Pass::call(design, "techmap" + define + " -map +/xilinx/cells_map.v"); Pass::call(design, "clean"); } @@ -303,7 +333,10 @@ struct SynthXilinxPass : public Pass { Pass::call(design, "opt -full"); Pass::call(design, "techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v"); - Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); + if (abc == "abc9") + Pass::call(design, abc + " -lut +/xilinx/abc.lut -box +/xilinx/abc.box" + string(retime ? " -dff" : "")); + else + Pass::call(design, abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : "")); Pass::call(design, "clean"); // This shregmap call infers fixed length shift registers after abc // has performed any necessary retiming @@ -312,7 +345,6 @@ struct SynthXilinxPass : public Pass Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v"); Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT " "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT"); - Pass::call(design, "clean"); } if (check_label(active, run_from, run_to, "check")) |