yosys/techlibs/common/synth.cc

321 lines
9.2 KiB
C++
Raw Permalink Normal View History

2014-09-14 09:09:06 -05:00
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
2015-07-02 04:14:30 -05:00
*
2014-09-14 09:09:06 -05:00
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
2015-07-02 04:14:30 -05:00
*
2014-09-14 09:09:06 -05:00
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include "kernel/register.h"
#include "kernel/rtlil.h"
2014-09-14 09:09:06 -05:00
2014-09-27 09:17:53 -05:00
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthPass : public ScriptPass {
SynthPass() : ScriptPass("synth", "generic synthesis script") {}
2014-09-14 09:09:06 -05:00
2020-06-18 18:34:52 -05:00
void help() override
2014-09-14 09:09:06 -05:00
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" synth [options]\n");
log("\n");
log("This command runs the default synthesis script. This command does not operate\n");
log("on partly selected designs.\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module (default='top')\n");
log("\n");
log(" -auto-top\n");
log(" automatically determine the top of the design hierarchy\n");
log("\n");
log(" -flatten\n");
log(" flatten the design before synthesis. this will pass '-auto-top' to\n");
log(" 'hierarchy' if no top module is specified.\n");
log("\n");
2015-01-30 15:46:53 -06:00
log(" -encfile <file>\n");
log(" passed to 'fsm_recode' via 'fsm'\n");
log("\n");
2019-01-02 02:25:03 -06:00
log(" -lut <k>\n");
log(" perform synthesis for a k-LUT architecture.\n");
log("\n");
2015-07-02 08:25:38 -05:00
log(" -nofsm\n");
log(" do not run FSM optimization\n");
log("\n");
log(" -noabc\n");
log(" do not run abc (as if yosys was compiled without ABC support)\n");
log("\n");
log(" -booth\n");
2024-02-07 17:03:15 -06:00
log(" run the booth pass to map $mul to Booth encoded multipliers\n");
log("\n");
2015-06-15 10:07:40 -05:00
log(" -noalumacc\n");
log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n");
log(" their direct form ($add, $sub, etc.).\n");
log("\n");
log(" -nordff\n");
log(" passed to 'memory'. prohibits merging of FFs into memory read ports\n");
log("\n");
log(" -noshare\n");
log(" do not run SAT-based resource sharing\n");
log("\n");
2014-09-14 09:09:06 -05:00
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(" synonymous to the end of the command list.\n");
log("\n");
2019-02-20 13:08:49 -06:00
log(" -abc9\n");
2019-06-14 12:32:46 -05:00
log(" use new ABC9 flow (EXPERIMENTAL)\n");
2019-02-20 13:08:49 -06:00
log("\n");
2020-02-28 08:29:57 -06:00
log(" -flowmap\n");
log(" use FlowMap LUT techmapping instead of ABC\n");
log("\n");
log(" -no-rw-check\n");
log(" marks all recognized read ports as \"return don't-care value on\n");
log(" read/write collision\" (same result as setting the no_rw_check\n");
log(" attribute on all memories).\n");
log("\n");
log(" -extra-map filename\n");
log(" source extra rules from the given file to complement the default\n");
log(" mapping library in the `techmap` step. this option can be\n");
log(" repeated.\n");
2014-09-14 09:09:06 -05:00
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
2014-09-14 09:09:06 -05:00
log("\n");
}
2019-02-20 13:08:49 -06:00
string top_module, fsm_opts, memory_opts, abc;
bool autotop, flatten, noalumacc, nofsm, noabc, noshare, flowmap, booth;
2019-01-02 02:25:03 -06:00
int lut;
std::vector<std::string> techmap_maps;
2020-06-18 18:34:52 -05:00
void clear_flags() override
{
top_module.clear();
fsm_opts.clear();
memory_opts.clear();
autotop = false;
flatten = false;
2019-01-02 02:25:03 -06:00
lut = 0;
noalumacc = false;
nofsm = false;
noabc = false;
noshare = false;
2020-02-28 08:29:57 -06:00
flowmap = false;
booth = false;
2019-02-20 13:08:49 -06:00
abc = "abc";
techmap_maps.clear();
}
2020-06-18 18:34:52 -05:00
void execute(std::vector<std::string> args, RTLIL::Design *design) override
2014-09-14 09:09:06 -05:00
{
string run_from, run_to;
clear_flags();
2014-09-14 09:09:06 -05:00
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-top" && argidx + 1 < args.size()) {
2014-09-14 09:09:06 -05:00
top_module = args[++argidx];
continue;
}
if (args[argidx] == "-encfile" && argidx + 1 < args.size()) {
2015-01-30 15:46:53 -06:00
fsm_opts = " -encfile " + args[++argidx];
continue;
}
if (args[argidx] == "-run" && argidx + 1 < args.size()) {
size_t pos = args[argidx + 1].find(':');
2014-09-14 09:09:06 -05:00
if (pos == std::string::npos) {
run_from = args[++argidx];
run_to = args[argidx];
} else {
run_from = args[++argidx].substr(0, pos);
run_to = args[argidx].substr(pos + 1);
2014-09-14 09:09:06 -05:00
}
continue;
}
if (args[argidx] == "-auto-top") {
autotop = true;
continue;
}
if (args[argidx] == "-flatten") {
flatten = true;
continue;
}
if (args[argidx] == "-lut" && argidx + 1 < args.size()) {
2019-01-02 02:25:03 -06:00
lut = atoi(args[++argidx].c_str());
continue;
}
2015-07-02 08:25:38 -05:00
if (args[argidx] == "-nofsm") {
nofsm = true;
continue;
}
if (args[argidx] == "-noabc") {
noabc = true;
continue;
}
2015-06-15 10:07:40 -05:00
if (args[argidx] == "-noalumacc") {
noalumacc = true;
continue;
}
if (args[argidx] == "-booth") {
booth = true;
continue;
}
2015-06-15 10:07:40 -05:00
if (args[argidx] == "-nordff") {
memory_opts += " -nordff";
continue;
}
if (args[argidx] == "-noshare") {
noshare = true;
continue;
}
2019-02-20 13:08:49 -06:00
if (args[argidx] == "-abc9") {
abc = "abc9";
continue;
}
2020-02-28 08:29:57 -06:00
if (args[argidx] == "-flowmap") {
flowmap = true;
continue;
}
if (args[argidx] == "-no-rw-check") {
memory_opts += " -no-rw-check";
continue;
}
if (args[argidx] == "-extra-map" && argidx + 1 < args.size()) {
techmap_maps.push_back(args[++argidx]);
continue;
}
2014-09-14 09:09:06 -05:00
break;
}
extra_args(args, argidx, design);
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
2014-09-14 09:09:06 -05:00
2019-06-14 12:32:46 -05:00
if (abc == "abc9" && !lut)
2019-08-20 22:37:52 -05:00
log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)\n");
2020-02-28 08:29:57 -06:00
if (flowmap && !lut)
log_cmd_error("FlowMap is only supported for FPGA synthesis (using '-lut' option)\n");
2019-06-14 12:32:46 -05:00
2016-04-21 16:28:37 -05:00
log_header(design, "Executing SYNTH pass.\n");
2014-09-14 09:09:06 -05:00
log_push();
run_script(design, run_from, run_to);
log_pop();
}
2020-06-18 18:34:52 -05:00
void script() override
{
if (check_label("begin")) {
if (help_mode) {
run("hierarchy -check [-top <top> | -auto-top]");
} else {
if (top_module.empty()) {
if (flatten || autotop)
run("hierarchy -check -auto-top");
else
run("hierarchy -check");
} else
run(stringf("hierarchy -check -top %s", top_module.c_str()));
}
2014-09-14 09:09:06 -05:00
}
if (check_label("coarse")) {
run("proc");
2024-02-07 17:03:02 -06:00
if (flatten || help_mode)
run("flatten", " (if -flatten)");
run("opt_expr");
run("opt_clean");
run("check");
2020-07-20 16:19:51 -05:00
run("opt -nodffe -nosdff");
2024-02-07 17:03:02 -06:00
if (!nofsm || help_mode)
2020-07-20 16:19:51 -05:00
run("fsm" + fsm_opts, " (unless -nofsm)");
run("opt");
2019-07-09 12:14:23 -05:00
run("wreduce");
run("peepopt");
run("opt_clean");
2019-01-02 02:25:03 -06:00
if (help_mode)
run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v", " (if -lut)");
else if (lut)
run(stringf("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=%d", lut));
2024-02-07 17:03:02 -06:00
if (booth || help_mode)
run("booth", " (if -booth)");
2015-06-15 10:07:40 -05:00
if (!noalumacc)
run("alumacc", " (unless -noalumacc)");
if (!noshare)
run("share", " (unless -noshare)");
run("opt");
run("memory -nomap" + memory_opts);
run("opt_clean");
2014-09-14 09:09:06 -05:00
}
if (check_label("fine")) {
run("opt -fast -full");
run("memory_map");
run("opt -full");
if (help_mode) {
run("techmap", " (unless -extra-map)");
run("techmap -map +/techmap.v -map <inject>", " (if -extra-map)");
} else {
std::string techmap_opts;
if (!techmap_maps.empty())
techmap_opts += " -map +/techmap.v";
for (auto fn : techmap_maps)
techmap_opts += stringf(" -map %s", fn.c_str());
run("techmap" + techmap_opts);
}
if (help_mode) {
2019-01-02 02:25:03 -06:00
run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
run("clean; opt_lut", " (if -noabc and -lut)");
2020-02-28 08:29:57 -06:00
run("flowmap -maxlut K", " (if -flowmap and -lut)");
} else if (noabc && lut) {
2019-01-02 02:25:03 -06:00
run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
run("clean; opt_lut");
} else if (flowmap) {
2020-02-28 08:29:57 -06:00
run(stringf("flowmap -maxlut %d", lut));
}
run("opt -fast");
2024-02-07 17:03:02 -06:00
if ((!noabc && !flowmap) || help_mode) {
#ifdef YOSYS_ENABLE_ABC
if (help_mode) {
2019-02-20 13:08:49 -06:00
run(abc + " -fast", " (unless -noabc, unless -lut)");
run(abc + " -fast -lut k", "(unless -noabc, if -lut)");
} else {
2019-01-02 02:25:03 -06:00
if (lut)
2019-02-20 13:08:49 -06:00
run(stringf("%s -fast -lut %d", abc.c_str(), lut));
2019-01-02 02:25:03 -06:00
else
2019-02-20 13:08:49 -06:00
run(abc + " -fast");
2019-01-02 02:25:03 -06:00
}
run("opt -fast", " (unless -noabc)");
#endif
}
2014-10-30 21:46:27 -05:00
}
if (check_label("check")) {
run("hierarchy -check");
run("stat");
run("check");
2014-09-14 09:09:06 -05:00
}
}
} SynthPass;
2015-07-02 04:14:30 -05:00
2014-09-27 09:17:53 -05:00
PRIVATE_NAMESPACE_END