diff options
Diffstat (limited to 'techlibs/xilinx/synth_xilinx.cc')
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index 83c2edc86..2f3dfb012 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -79,6 +79,11 @@ struct SynthXilinxPass : public ScriptPass log(" -nowidelut\n"); log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\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"); + log(" default: 0 (no inference)\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"); @@ -101,6 +106,7 @@ struct SynthXilinxPass : public ScriptPass std::string top_opt, edif_file, blif_file, arch; bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9; + int widemux; void clear_flags() YS_OVERRIDE { @@ -118,6 +124,7 @@ struct SynthXilinxPass : public ScriptPass nocarry = false; nowidelut = false; abc9 = false; + widemux = 0; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -188,6 +195,10 @@ struct SynthXilinxPass : public ScriptPass nosrl = true; continue; } + if (args[argidx] == "-widemux" && argidx+1 < args.size()) { + widemux = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-abc9") { abc9 = true; continue; @@ -199,6 +210,9 @@ struct SynthXilinxPass : public ScriptPass if (arch != "xcup" && arch != "xcu" && arch != "xc7" && arch != "xc6s") log_cmd_error("Invalid Xilinx -arch setting: %s\n", arch.c_str()); + if (widemux != 0 && widemux < 5) + log_cmd_error("-widemux value must be 0 or >= 5.\n"); + if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); @@ -214,9 +228,9 @@ struct SynthXilinxPass : public ScriptPass { if (check_label("begin")) { if (vpr) - run("read_verilog -lib -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); + run("read_verilog -lib -icells -D _ABC -D_EXPLICIT_CARRY +/xilinx/cells_sim.v"); else - run("read_verilog -lib -D _ABC +/xilinx/cells_sim.v"); + run("read_verilog -lib -icells -D _ABC +/xilinx/cells_sim.v"); run("read_verilog -lib +/xilinx/cells_xtra.v"); @@ -226,26 +240,21 @@ struct SynthXilinxPass : public ScriptPass run(stringf("hierarchy -check %s", top_opt.c_str())); } - if (check_label("flatten", "(with '-flatten' only)")) { - if (flatten || help_mode) { - run("proc"); - run("flatten"); - } - } - if (check_label("coarse")) { - run("synth -run coarse"); + if (help_mode) + run("synth -run coarse [-flatten]", "(with '-flatten')"); + else + run("synth -run coarse" + std::string(flatten ? "" : " -flatten"), "(with '-flatten')"); + + if (widemux > 0 || help_mode) + run("muxpack", " ('-widemux' only)"); // 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 - if (!nosrl || help_mode) - run("pmux2shiftx", "(skip if '-nosrl')"); - - // Run a number of peephole optimisations, including one - // that optimises $mul cells driving $shiftx's B input - // and that aids wide mux analysis - run("peepopt"); + // Also: wide multiplexer inference benefits from this too + if (!(nosrl && widemux == 0) || help_mode) + run("pmux2shiftx", "(skip if '-nosrl' and '-widemux' < 5)"); } if (check_label("bram", "(skip if '-nobram')")) { @@ -267,32 +276,65 @@ struct SynthXilinxPass : public ScriptPass run("memory_map"); run("dffsr2dff"); run("dff2dffe"); + if (help_mode) { + run("simplemap t:$mux", " ('-widemux' only)"); + run("muxcover <internal options>, ('-widemux' only)"); + } + else if (widemux > 0) { + run("simplemap t:$mux"); + std::string muxcover_args = " -nodecode"; + switch (widemux) { + // NB: Cost of mux2 is 100; mux8 should cost between 3 and 4 + // of those so that 4:1 muxes and below are implemented + // out of mux2s + case 5: muxcover_args += " -mux8=350 -mux16=400"; break; + case 6: muxcover_args += " -mux8=450 -mux16=500"; break; + case 7: muxcover_args += " -mux8=550 -mux16=600"; break; + case 8: muxcover_args += " -mux8=650 -mux16=700"; break; + case 9: muxcover_args += " -mux16=750"; break; + case 10: muxcover_args += " -mux16=850"; break; + case 11: muxcover_args += " -mux16=950"; break; + case 12: muxcover_args += " -mux16=1050"; break; + case 13: muxcover_args += " -mux16=1150"; break; + case 14: muxcover_args += " -mux16=1250"; break; + case 15: muxcover_args += " -mux16=1350"; break; + default: muxcover_args += " -mux16=1450"; break; + } + run("muxcover " + muxcover_args); + } run("opt -full"); 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')"); + run("simplemap t:$dff t:$dffe", " (skip if '-nosrl')"); // shregmap with '-tech xilinx' infers variable length shift regs run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')"); } - std::string techmap_files = " -map +/techmap.v"; + std::string techmap_args = " -map +/techmap.v"; + if (help_mode) + techmap_args += " [-map +/xilinx/mux_map.v]"; + else if (widemux > 0) + techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/xilinx/mux_map.v", widemux); if (help_mode) - techmap_files += " [-map +/xilinx/arith_map.v]"; + techmap_args += " [-map +/xilinx/arith_map.v]"; else if (!nocarry) { - techmap_files += " -map +/xilinx/arith_map.v"; + techmap_args += " -map +/xilinx/arith_map.v"; if (vpr) - techmap_files += " -D _EXPLICIT_CARRY"; + techmap_args += " -D _EXPLICIT_CARRY"; else if (abc9) - techmap_files += " -D _CLB_CARRY"; + techmap_args += " -D _CLB_CARRY"; } - run("techmap " + techmap_files); + run("techmap " + techmap_args); run("opt -fast"); } if (check_label("map_cells")) { - run("techmap -map +/techmap.v -map +/xilinx/cells_map.v"); + std::string techmap_args = "-map +/techmap.v -D _ABC -map +/xilinx/cells_map.v"; + if (widemux > 0) + techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux); + run("techmap " + techmap_args); run("clean"); } |