log(" -nosrl\n");
log(" disable inference of shift registers\n");
log("\n");
- log(" do not use XORCY/MUXCY cells in output netlist\n");
+ log(" -nocarry\n");
- log(" -nomux\n");
- log(" do not use MUXF[78] muxes to implement LUTs larger than LUT6s\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");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
- log("\n");
- log(" begin:\n");
- log(" read_verilog -lib +/xilinx/cells_sim.v\n");
- log(" read_verilog -lib +/xilinx/cells_xtra.v\n");
- log(" read_verilog -lib +/xilinx/brams_bb.v\n");
- log(" hierarchy -check -top <top>\n");
- log("\n");
- log(" flatten: (only if -flatten)\n");
- log(" proc\n");
- log(" flatten\n");
- log("\n");
- log(" coarse:\n");
- log(" synth -run coarse\n");
- log("\n");
- log(" bram: (only executed when '-nobram' is not given)\n");
- log(" memory_bram -rules +/xilinx/brams.txt\n");
- log(" techmap -map +/xilinx/brams_map.v\n");
- log("\n");
- log(" dram: (only executed when '-nodram' is not given)\n");
- log(" memory_bram -rules +/xilinx/drams.txt\n");
- log(" techmap -map +/xilinx/drams_map.v\n");
- log("\n");
- log(" fine:\n");
- log(" opt -fast\n");
- log(" memory_map\n");
- log(" dffsr2dff\n");
- log(" dff2dffe\n");
- log(" techmap -map +/xilinx/arith_map.v\n");
- log(" opt -fast\n");
- log("\n");
- log(" map_cells:\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");
- log(" clean\n");
- log("\n");
- log(" map_luts:\n");
- log(" opt -full\n");
- log(" techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v\n");
- 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(" 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");
- log(" stat\n");
- log(" check -noinit\n");
- log("\n");
- log(" edif: (only if -edif)\n");
- log(" write_edif <file-name>\n");
- log("\n");
- log(" blif: (only if -blif)\n");
- log(" write_blif <file-name>\n");
+ help_script();
log("\n");
}
- 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
+ {
+ top_opt = "-auto-top";
+ edif_file.clear();
+ blif_file.clear();
+ flatten = false;
+ retime = false;
+ vpr = false;
+ nobram = false;
+ nodram = false;
+ nosrl = false;
++ nocarry = false;
++ nowidelut = false;
+ arch = "xc7";
+ }
+
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- std::string top_opt = "-auto-top";
- std::string edif_file;
- std::string blif_file;
std::string run_from, run_to;
- bool flatten = false;
- bool retime = false;
- bool nocarry = false;
- bool nomux = false;
- bool vpr = false;
- bool nobram = false;
- bool nodram = false;
- bool nosrl = false;
+ clear_flags();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
}
}
- if (check_label(active, run_from, run_to, "fine"))
- {
- Pass::call(design, "opt -fast");
- Pass::call(design, "memory_map");
- Pass::call(design, "dffsr2dff");
- Pass::call(design, "dff2dffe");
- 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");
- }
+ if (check_label("dram", "(skip if '-nodram')")) {
+ if (!nodram || help_mode) {
+ run("memory_bram -rules +/xilinx/drams.txt");
+ run("techmap -map +/xilinx/drams_map.v");
}
- Pass::call(design, "opt -fast");
}
- if (check_label(active, run_from, run_to, "map_cells"))
- {
- if (!nosrl) {
+ if (check_label("fine")) {
+ // 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 (!nosrl || help_mode) {
// 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");
+ run("simplemap t:$dff t:$dffe", "(skip if '-nosrl')");
// shregmap with '-tech xilinx' infers variable length shift regs
- Pass::call(design, "shregmap -tech xilinx -minlen 3");
+ run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
}
- if (!vpr || help_mode)
- Pass::call(design, "techmap -map +/xilinx/cells_map.v");
- Pass::call(design, "clean");
++ if (help_mode)
++ run("techmap -map +/techmap.v -map +/xilinx/arith_map.v", "(skip if '-nocarry')");
++ else if (!vpr)
+ run("techmap -map +/techmap.v -map +/xilinx/arith_map.v");
+ else
- run("techmap -map +/techmap.v +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
++ run("techmap -map +/techmap.v -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
+
+ run("opt -fast");
}
- if (check_label(active, run_from, run_to, "map_luts"))
- {
- Pass::call(design, "opt -full");
- Pass::call(design, "techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v");
- if (nomux)
- Pass::call(design, "abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
+ if (check_label("map_cells")) {
+ run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
+ run("clean");
+ }
+
+ 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
- Pass::call(design, "abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
- Pass::call(design, "clean");
+ run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
+ run("clean");
// This shregmap call infers fixed length shift registers after abc
// has performed any necessary retiming
- if (!nosrl)
- Pass::call(design, "shregmap -minlen 3 -init -params -enpol any_or_none");
- 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 "
+ if (!nosrl || help_mode)
+ run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')");
+ run("techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
+ run("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");
+ run("clean");
}
- if (check_label(active, run_from, run_to, "check"))
- {
- Pass::call(design, "hierarchy -check");
- Pass::call(design, "stat");
- Pass::call(design, "check -noinit");
+ if (check_label("check")) {
+ run("hierarchy -check");
+ run("stat -tech xilinx");
+ run("check -noinit");
}
- if (check_label(active, run_from, run_to, "edif"))
- {
- if (!edif_file.empty())
- Pass::call(design, stringf("write_edif -pvector bra %s", edif_file.c_str()));
- }
- if (check_label(active, run_from, run_to, "blif"))
- {
- if (!blif_file.empty())
- Pass::call(design, stringf("write_blif %s", edif_file.c_str()));
+ if (check_label("edif")) {
+ if (!edif_file.empty() || help_mode)
+ run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
}
- log_pop();
+ if (check_label("blif")) {
+ if (!blif_file.empty() || help_mode)
+ run(stringf("write_blif %s", edif_file.c_str()));
+ }
}
} SynthXilinxPass;