aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-03-31 11:16:34 +0200
committerClifford Wolf <clifford@clifford.at>2016-03-31 11:16:34 +0200
commit25533190818b0fe207be9a4626a9a273a08ae219 (patch)
tree67922d2eb15bb54b19fc30a6462d7d140dda528f
parent6cafd08ac1090f405168187632fab4308129c599 (diff)
downloadyosys-25533190818b0fe207be9a4626a9a273a08ae219.tar.gz
yosys-25533190818b0fe207be9a4626a9a273a08ae219.tar.bz2
yosys-25533190818b0fe207be9a4626a9a273a08ae219.zip
Added ScriptPass helper class for script-like passes
-rw-r--r--kernel/register.cc59
-rw-r--r--kernel/register.h17
-rw-r--r--kernel/yosys.cc6
-rw-r--r--techlibs/common/synth.cc153
-rw-r--r--techlibs/ice40/synth_ice40.cc205
5 files changed, 222 insertions, 218 deletions
diff --git a/kernel/register.cc b/kernel/register.cc
index 49a67324d..ebe3055ac 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -80,6 +80,7 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
state.begin_ns = PerformanceTimer::query();
state.parent_pass = current_pass;
current_pass = this;
+ clear_flags();
return state;
}
@@ -99,6 +100,10 @@ void Pass::help()
log("\n");
}
+void Pass::clear_flags()
+{
+}
+
void Pass::cmd_log_args(const std::vector<std::string> &args)
{
if (args.size() <= 1)
@@ -282,6 +287,60 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec
design->selected_active_module = backup_selected_active_module;
}
+bool ScriptPass::check_label(std::string label, std::string info)
+{
+ if (active_design == nullptr) {
+ log("\n");
+ if (info.empty())
+ log(" %s:\n", label.c_str());
+ else
+ log(" %s: %s\n", label.c_str(), info.c_str());
+ return true;
+ } else {
+ if (!active_run_from.empty() && active_run_from == active_run_to) {
+ block_active = (label == active_run_from);
+ } else {
+ if (label == active_run_from)
+ block_active = true;
+ if (label == active_run_to)
+ block_active = false;
+ }
+ return block_active;
+ }
+}
+
+void ScriptPass::run(std::string command, std::string info)
+{
+ if (active_design == nullptr) {
+ if (info.empty())
+ log(" %s\n", command.c_str());
+ else
+ log(" %s %s\n", command.c_str(), info.c_str());
+ } else
+ Pass::call(active_design, command);
+}
+
+void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
+{
+ help_mode = false;
+ active_design = design;
+ block_active = run_from.empty();
+ active_run_from = run_from;
+ active_run_to = run_to;
+ script();
+}
+
+void ScriptPass::help_script()
+{
+ clear_flags();
+ help_mode = true;
+ active_design = nullptr;
+ block_active = true;
+ active_run_from.clear();
+ active_run_to.clear();
+ script();
+}
+
Frontend::Frontend(std::string name, std::string short_help) :
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
diff --git a/kernel/register.h b/kernel/register.h
index 0ef07b760..8024c56a0 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -31,6 +31,7 @@ struct Pass
virtual ~Pass();
virtual void help();
+ virtual void clear_flags();
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
int call_counter;
@@ -63,6 +64,22 @@ struct Pass
static void done_register();
};
+struct ScriptPass : Pass
+{
+ bool block_active, help_mode;
+ RTLIL::Design *active_design;
+ std::string active_run_from, active_run_to;
+
+ ScriptPass(std::string name, std::string short_help = "** document me **") : Pass(name, short_help) { }
+
+ virtual void script() = 0;
+
+ bool check_label(std::string label, std::string info = std::string());
+ void run(std::string command, std::string info = std::string());
+ void run_script(RTLIL::Design *design, std::string run_from = std::string(), std::string run_to = std::string());
+ void help_script();
+};
+
struct Frontend : Pass
{
// for reading of here documents
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 501d94224..8da57fd4e 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -1100,8 +1100,8 @@ struct HistoryPass : public Pass {
} HistoryPass;
#endif
-struct ScriptPass : public Pass {
- ScriptPass() : Pass("script", "execute commands from script file") { }
+struct ScriptCmdPass : public Pass {
+ ScriptCmdPass() : Pass("script", "execute commands from script file") { }
virtual void help() {
log("\n");
log(" script <filename> [<from_label>:<to_label>]\n");
@@ -1127,7 +1127,7 @@ struct ScriptPass : public Pass {
else
extra_args(args, 2, design, false);
}
-} ScriptPass;
+} ScriptCmdPass;
YOSYS_NAMESPACE_END
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index c837e1378..8eb1aeba4 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -25,22 +25,11 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
+struct SynthPass : public ScriptPass
{
- if (!run_from.empty() && run_from == run_to) {
- active = (label == run_from);
- } else {
- if (label == run_from)
- active = true;
- if (label == run_to)
- active = false;
- }
- return active;
-}
+ SynthPass() : ScriptPass("synth", "generic synthesis script") { }
-struct SynthPass : public Pass {
- SynthPass() : Pass("synth", "generic synthesis script") { }
- virtual void help()
+ virtual void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -75,49 +64,28 @@ struct SynthPass : public Pass {
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
+ help_script();
log("\n");
- log(" begin:\n");
- log(" hierarchy -check [-top <top>]\n");
- log("\n");
- log(" coarse:\n");
- log(" proc\n");
- log(" opt_expr\n");
- log(" opt_clean\n");
- log(" check\n");
- log(" opt\n");
- log(" wreduce\n");
- log(" alumacc\n");
- log(" share\n");
- log(" opt\n");
- log(" fsm\n");
- log(" opt -fast\n");
- log(" memory -nomap\n");
- log(" opt_clean\n");
- log("\n");
- log(" fine:\n");
- log(" opt -fast -full\n");
- log(" memory_map\n");
- log(" opt -full\n");
- log(" techmap\n");
- log(" opt -fast\n");
- #ifdef YOSYS_ENABLE_ABC
- log(" abc -fast\n");
- log(" opt -fast\n");
- #endif
- log("\n");
- log(" check:\n");
- log(" hierarchy -check\n");
- log(" stat\n");
- log(" check\n");
- log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+
+ std::string top_module, fsm_opts, memory_opts;
+ bool noalumacc, nofsm, noabc;
+
+ virtual void clear_flags() YS_OVERRIDE
+ {
+ top_module.clear();
+ fsm_opts.clear();
+ memory_opts.clear();
+
+ noalumacc = false;
+ nofsm = false;
+ noabc = false;
+ }
+
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- std::string top_module, fsm_opts, memory_opts;
- std::string run_from, run_to;
- bool noalumacc = false;
- bool nofsm = false;
- bool noabc = false;
+ string run_from, run_to;
+ clear_flags();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -164,62 +132,69 @@ struct SynthPass : public Pass {
if (!design->full_selection())
log_cmd_error("This comannd only operates on fully selected designs!\n");
- bool active = run_from.empty();
-
log_header("Executing SYNTH pass.\n");
log_push();
- if (check_label(active, run_from, run_to, "begin"))
+ run_script(design, run_from, run_to);
+
+ log_pop();
+ }
+
+ virtual void script() YS_OVERRIDE
+ {
+ if (check_label("begin"))
{
- if (top_module.empty())
- Pass::call(design, stringf("hierarchy -check"));
- else
- Pass::call(design, stringf("hierarchy -check -top %s", top_module.c_str()));
+ if (help_mode) {
+ run("hierarchy -check [-top <top>]");
+ } else {
+ if (top_module.empty())
+ run(stringf("hierarchy -check"));
+ else
+ run(stringf("hierarchy -check -top %s", top_module.c_str()));
+ }
}
- if (check_label(active, run_from, run_to, "coarse"))
+ if (check_label("coarse"))
{
- Pass::call(design, "proc");
- Pass::call(design, "opt_expr");
- Pass::call(design, "opt_clean");
- Pass::call(design, "check");
- Pass::call(design, "opt");
- Pass::call(design, "wreduce");
+ run("proc");
+ run("opt_expr");
+ run("opt_clean");
+ run("check");
+ run("opt");
+ run("wreduce");
if (!noalumacc)
- Pass::call(design, "alumacc");
- Pass::call(design, "share");
- Pass::call(design, "opt");
+ run("alumacc");
+ run("share");
+ run("opt");
if (!nofsm)
- Pass::call(design, "fsm" + fsm_opts);
- Pass::call(design, "opt -fast");
- Pass::call(design, "memory -nomap" + memory_opts);
- Pass::call(design, "opt_clean");
+ run("fsm" + fsm_opts);
+ run("opt -fast");
+ run("memory -nomap" + memory_opts);
+ run("opt_clean");
}
- if (check_label(active, run_from, run_to, "fine"))
+ if (check_label("fine"))
{
- Pass::call(design, "opt -fast -full");
- Pass::call(design, "memory_map");
- Pass::call(design, "opt -full");
- Pass::call(design, "techmap");
- Pass::call(design, "opt -fast");
+ run("opt -fast -full");
+ run("memory_map");
+ run("opt -full");
+ run("techmap");
+ run("opt -fast");
if (!noabc) {
#ifdef YOSYS_ENABLE_ABC
- Pass::call(design, "abc -fast");
- Pass::call(design, "opt -fast");
+ run("abc -fast");
+ run("opt -fast");
#endif
}
}
- if (check_label(active, run_from, run_to, "check"))
+ if (check_label("check"))
{
- Pass::call(design, "hierarchy -check");
- Pass::call(design, "stat");
- Pass::call(design, "check");
+ run("hierarchy -check");
+ run("stat");
+ run("check");
}
-
- log_pop();
}
} SynthPass;
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index f24d31a8c..2ed7642ae 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -25,18 +25,11 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
+struct SynthIce40Pass : public ScriptPass
{
- if (label == run_from)
- active = true;
- if (label == run_to)
- active = false;
- return active;
-}
+ SynthIce40Pass() : ScriptPass("synth_ice40", "synthesis for iCE40 FPGAs") { }
-struct SynthIce40Pass : public Pass {
- SynthIce40Pass() : Pass("synth_ice40", "synthesis for iCE40 FPGAs") { }
- virtual void help()
+ virtual void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -77,73 +70,30 @@ struct SynthIce40Pass : public Pass {
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
+ help_script();
log("\n");
- log(" begin:\n");
- log(" read_verilog -lib +/ice40/cells_sim.v\n");
- log(" hierarchy -check -top <top>\n");
- log("\n");
- log(" flatten: (unless -noflatten)\n");
- log(" proc\n");
- log(" flatten\n");
- log(" tribuf -logic\n");
- log("\n");
- log(" coarse:\n");
- log(" synth -run coarse\n");
- log("\n");
- log(" bram: (skip if -nobram)\n");
- log(" memory_bram -rules +/ice40/brams.txt\n");
- log(" techmap -map +/ice40/brams_map.v\n");
- log("\n");
- log(" fine:\n");
- log(" opt -fast -mux_undef -undriven -fine\n");
- log(" memory_map\n");
- log(" opt -undriven -fine\n");
- log(" techmap -map +/techmap.v [-map +/ice40/arith_map.v]\n");
- log(" abc -dff (only if -retime)\n");
- log(" ice40_opt\n");
- log("\n");
- log(" map_ffs:\n");
- log(" dffsr2dff\n");
- log(" dff2dffe -direct-match $_DFF_*\n");
- log(" techmap -map +/ice40/cells_map.v\n");
- log(" opt_expr -mux_undef\n");
- log(" simplemap\n");
- log(" ice40_ffinit\n");
- log(" ice40_ffssr\n");
- log(" ice40_opt -full\n");
- log("\n");
- log(" map_luts:\n");
- log(" abc (only if -abc2)\n");
- log(" ice40_opt (only if -abc2)\n");
- log(" abc -lut 4\n");
- log(" clean\n");
- log("\n");
- log(" map_cells:\n");
- log(" techmap -map +/ice40/cells_map.v\n");
- log(" clean\n");
- log("\n");
- log(" check:\n");
- log(" hierarchy -check\n");
- log(" stat\n");
- log(" check -noinit\n");
- log("\n");
- log(" blif:\n");
- log(" write_blif -gates -attr -param <file-name>\n");
- log("\n");
- log(" edif:\n");
- log(" write_edif <file-name>\n");
- log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+
+ string top_opt = "-auto-top";
+ string blif_file, edif_file;
+ bool nocarry, nobram, flatten, retime, abc2;
+
+ virtual void clear_flags() YS_OVERRIDE
+ {
+ top_opt = "-auto-top";
+ blif_file = "";
+ edif_file = "";
+ nocarry = false;
+ nobram = false;
+ flatten = true;
+ retime = false;
+ abc2 = false;
+ }
+
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- std::string top_opt = "-auto-top";
std::string run_from, run_to;
- std::string blif_file, edif_file;
- bool nocarry = false;
- bool nobram = false;
- bool flatten = true;
- bool retime = false;
- bool abc2 = false;
+ clear_flags();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -199,97 +149,100 @@ struct SynthIce40Pass : public Pass {
if (!design->full_selection())
log_cmd_error("This comannd only operates on fully selected designs!\n");
- bool active = run_from.empty();
-
log_header("Executing SYNTH_ICE40 pass.\n");
log_push();
- if (check_label(active, run_from, run_to, "begin"))
+ run_script(design, run_from, run_to);
+
+ log_pop();
+ }
+
+ virtual void script() YS_OVERRIDE
+ {
+ if (check_label("begin"))
{
- Pass::call(design, "read_verilog -lib +/ice40/cells_sim.v");
- Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str()));
+ run("read_verilog -lib +/ice40/cells_sim.v");
+ run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
- if (flatten && check_label(active, run_from, run_to, "flatten"))
+ if (flatten && check_label("flatten", "(unless -noflatten)"))
{
- Pass::call(design, "proc");
- Pass::call(design, "flatten");
- Pass::call(design, "tribuf -logic");
+ run("proc");
+ run("flatten");
+ run("tribuf -logic");
}
- if (check_label(active, run_from, run_to, "coarse"))
+ if (check_label("coarse"))
{
- Pass::call(design, "synth -run coarse");
+ run("synth -run coarse");
}
- if (!nobram && check_label(active, run_from, run_to, "bram"))
+ if (!nobram && check_label("bram", "(skip if -nobram)"))
{
- Pass::call(design, "memory_bram -rules +/ice40/brams.txt");
- Pass::call(design, "techmap -map +/ice40/brams_map.v");
+ run("memory_bram -rules +/ice40/brams.txt");
+ run("techmap -map +/ice40/brams_map.v");
}
- if (check_label(active, run_from, run_to, "fine"))
+ if (check_label("fine"))
{
- Pass::call(design, "opt -fast -mux_undef -undriven -fine");
- Pass::call(design, "memory_map");
- Pass::call(design, "opt -undriven -fine");
+ run("opt -fast -mux_undef -undriven -fine");
+ run("memory_map");
+ run("opt -undriven -fine");
if (nocarry)
- Pass::call(design, "techmap");
+ run("techmap");
else
- Pass::call(design, "techmap -map +/techmap.v -map +/ice40/arith_map.v");
- if (retime)
- Pass::call(design, "abc -dff");
- Pass::call(design, "ice40_opt");
+ run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
+ if (retime || help_mode)
+ run("abc -dff", "(only if -retime)");
+ run("ice40_opt");
}
- if (check_label(active, run_from, run_to, "map_ffs"))
+ if (check_label("map_ffs"))
{
- Pass::call(design, "dffsr2dff");
- Pass::call(design, "dff2dffe -direct-match $_DFF_*");
- Pass::call(design, "techmap -map +/ice40/cells_map.v");
- Pass::call(design, "opt_expr -mux_undef");
- Pass::call(design, "simplemap");
- Pass::call(design, "ice40_ffinit");
- Pass::call(design, "ice40_ffssr");
- Pass::call(design, "ice40_opt -full");
+ run("dffsr2dff");
+ run("dff2dffe -direct-match $_DFF_*");
+ run("techmap -map +/ice40/cells_map.v");
+ run("opt_expr -mux_undef");
+ run("simplemap");
+ run("ice40_ffinit");
+ run("ice40_ffssr");
+ run("ice40_opt -full");
}
- if (check_label(active, run_from, run_to, "map_luts"))
+ if (check_label("map_luts"))
{
- if (abc2) {
- Pass::call(design, "abc");
- Pass::call(design, "ice40_opt");
+ if (abc2 || help_mode) {
+ run("abc", " (only if -abc2)");
+ run("ice40_opt", "(only if -abc2)");
}
- Pass::call(design, "abc -lut 4");
- Pass::call(design, "clean");
+ run("abc -lut 4");
+ run("clean");
}
- if (check_label(active, run_from, run_to, "map_cells"))
+ if (check_label("map_cells"))
{
- Pass::call(design, "techmap -map +/ice40/cells_map.v");
- Pass::call(design, "clean");
+ run("techmap -map +/ice40/cells_map.v");
+ run("clean");
}
- if (check_label(active, run_from, run_to, "check"))
+ if (check_label("check"))
{
- Pass::call(design, "hierarchy -check");
- Pass::call(design, "stat");
- Pass::call(design, "check -noinit");
+ run("hierarchy -check");
+ run("stat");
+ run("check -noinit");
}
- if (check_label(active, run_from, run_to, "blif"))
+ if (check_label("blif"))
{
- if (!blif_file.empty())
- Pass::call(design, stringf("write_blif -gates -attr -param %s", blif_file.c_str()));
+ if (!blif_file.empty() || help_mode)
+ run(stringf("write_blif -gates -attr -param %s", help_mode ? "<file-name>" : blif_file.c_str()));
}
- if (check_label(active, run_from, run_to, "edif"))
+ if (check_label("edif"))
{
- if (!edif_file.empty())
- Pass::call(design, stringf("write_edif %s", edif_file.c_str()));
+ if (!edif_file.empty() || help_mode)
+ run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
-
- log_pop();
}
} SynthIce40Pass;