yosys/techlibs/common/synth.cc

291 lines
7.5 KiB
C++
Raw Normal View History

2014-09-14 09:09:06 -05:00
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
2014-09-27 09:17:53 -05:00
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthPass : public ScriptPass
2014-09-14 09:09:06 -05:00
{
SynthPass() : ScriptPass("synth", "generic synthesis script") { }
2014-09-14 09:09:06 -05:00
void help() YS_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");
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");
2019-07-08 21:14:54 -05:00
log(" -keepdc\n");
log(" do not optimize explicit don't-care values on $mux cells.\n");
log("\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;
2019-07-08 21:14:54 -05:00
bool autotop, flatten, noalumacc, nofsm, noabc, noshare, keepdc;
2019-01-02 02:25:03 -06:00
int lut;
void clear_flags() YS_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;
2019-02-20 13:08:49 -06:00
abc = "abc";
2019-07-08 21:14:54 -05:00
keepdc = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_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()) {
top_module = args[++argidx];
continue;
}
2015-01-30 15:46:53 -06:00
if (args[argidx] == "-encfile" && argidx+1 < args.size()) {
fsm_opts = " -encfile " + args[++argidx];
continue;
}
2014-09-14 09:09:06 -05:00
if (args[argidx] == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
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);
}
continue;
}
if (args[argidx] == "-auto-top") {
autotop = true;
continue;
}
if (args[argidx] == "-flatten") {
flatten = true;
continue;
}
2019-01-02 02:25:03 -06:00
if (args[argidx] == "-lut") {
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] == "-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;
}
2019-07-08 21:14:54 -05:00
if (args[argidx] == "-keepdc") {
keepdc = true;
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)
log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)");
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();
}
void script() YS_OVERRIDE
{
if (check_label("begin"))
2014-09-14 09:09:06 -05:00
{
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"))
2014-09-14 09:09:06 -05:00
{
run("proc");
if (help_mode || flatten)
run("flatten", " (if -flatten)");
run("opt_expr");
run("opt_clean");
run("check");
run("opt");
2019-07-08 21:14:54 -05:00
if (help_mode)
run("wreduce [-keepdc]");
else
run("wreduce" + std::string(keepdc ? " -keepdc" : ""));
run("peepopt");
run("opt_clean");
2019-01-02 02:25:03 -06:00
if (help_mode)
run("techmap -map +/cmp2lut.v", " (if -lut)");
else
run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut));
2015-06-15 10:07:40 -05:00
if (!noalumacc)
run("alumacc", " (unless -noalumacc)");
if (!noshare)
run("share", " (unless -noshare)");
run("opt");
2015-07-02 08:25:38 -05:00
if (!nofsm)
run("fsm" + fsm_opts, " (unless -nofsm)");
run("opt -fast");
run("memory -nomap" + memory_opts);
run("opt_clean");
2014-09-14 09:09:06 -05:00
}
if (check_label("fine"))
2014-09-14 09:09:06 -05:00
{
run("opt -fast -full");
run("memory_map");
run("opt -full");
run("techmap");
2019-01-02 02:25:03 -06:00
if (help_mode)
{
run("techmap -map +/gate2lut.v", "(if -noabc and -lut)");
run("clean; opt_lut", " (if -noabc and -lut)");
}
else if (noabc && lut)
{
run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut));
run("clean; opt_lut");
}
run("opt -fast");
if (!noabc) {
#ifdef YOSYS_ENABLE_ABC
2019-01-02 02:25:03 -06:00
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)");
2019-01-02 02:25:03 -06:00
}
else
{
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"))
2014-10-30 21:46:27 -05:00
{
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