summaryrefslogtreecommitdiff
path: root/techlibs/common/prep.cc
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/common/prep.cc')
-rw-r--r--techlibs/common/prep.cc170
1 files changed, 110 insertions, 60 deletions
diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc
index 8bae920d..fac6c4ba 100644
--- a/techlibs/common/prep.cc
+++ b/techlibs/common/prep.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 PrepPass : 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;
-}
+ PrepPass() : ScriptPass("prep", "generic synthesis script") { }
-struct PrepPass : public Pass {
- PrepPass() : Pass("prep", "generic synthesis script") { }
- virtual void help()
+ virtual void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -53,6 +42,24 @@ struct PrepPass : public Pass {
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");
+ log(" -ifx\n");
+ log(" passed to 'proc'. uses verilog simulation behavior for verilog if/case\n");
+ log(" undef handling. this also prevents 'wreduce' from being run.\n");
+ log("\n");
+ log(" -memx\n");
+ log(" simulate verilog simulation behavior for out-of-bounds memory accesses\n");
+ log(" using the 'memory_memx' pass. This option implies -nordff.\n");
+ log("\n");
+ log(" -nomem\n");
+ log(" do not run any of the memory_* passes\n");
+ log("\n");
log(" -nordff\n");
log(" passed to 'memory_dff'. prohibits merging of FFs into memory read ports\n");
log("\n");
@@ -63,31 +70,28 @@ struct PrepPass : 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(" prep:\n");
- log(" proc\n");
- log(" opt_const\n");
- log(" opt_clean\n");
- log(" check\n");
- log(" opt -keepdc\n");
- log(" wreduce\n");
- log(" memory_dff [-nordff]\n");
- log(" opt_clean\n");
- log(" memory_collect\n");
- log(" opt -keepdc -fast\n");
- log("\n");
- log(" check:\n");
- log(" stat\n");
- log(" check\n");
- log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+
+ string top_module, fsm_opts, memory_opts;
+ bool autotop, flatten, ifxmode, memxmode, nomemmode;
+
+ virtual void clear_flags() YS_OVERRIDE
+ {
+ top_module.clear();
+ memory_opts.clear();
+
+ autotop = false;
+ flatten = false;
+ ifxmode = false;
+ memxmode = false;
+ nomemmode = false;
+ }
+
+ virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
- std::string top_module, memory_opts;
- std::string run_from, run_to;
+ string run_from, run_to;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
@@ -107,6 +111,27 @@ struct PrepPass : public Pass {
}
continue;
}
+ if (args[argidx] == "-auto-top") {
+ autotop = true;
+ continue;
+ }
+ if (args[argidx] == "-flatten") {
+ flatten = true;
+ continue;
+ }
+ if (args[argidx] == "-ifx") {
+ ifxmode = true;
+ continue;
+ }
+ if (args[argidx] == "-memx") {
+ memxmode = true;
+ memory_opts += " -nordff";
+ continue;
+ }
+ if (args[argidx] == "-nomem") {
+ nomemmode = true;
+ continue;
+ }
if (args[argidx] == "-nordff") {
memory_opts += " -nordff";
continue;
@@ -118,40 +143,65 @@ struct PrepPass : 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 PREP pass.\n");
+ log_header(design, "Executing PREP 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> | -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()));
+ }
}
- if (check_label(active, run_from, run_to, "coarse"))
+ if (check_label("coarse"))
{
- Pass::call(design, "proc");
- Pass::call(design, "opt_const");
- Pass::call(design, "opt_clean");
- Pass::call(design, "check");
- Pass::call(design, "opt -keepdc");
- Pass::call(design, "wreduce");
- Pass::call(design, "memory_dff" + memory_opts);
- Pass::call(design, "opt_clean");
- Pass::call(design, "memory_collect");
- Pass::call(design, "opt -keepdc -fast");
+ if (help_mode)
+ run("proc [-ifx]");
+ else
+ run(ifxmode ? "proc -ifx" : "proc");
+ if (help_mode || flatten)
+ run("flatten", "(if -flatten)");
+ run("opt_expr -keepdc");
+ run("opt_clean");
+ run("check");
+ run("opt -keepdc");
+ if (!ifxmode) {
+ if (help_mode)
+ run("wreduce [-memx]");
+ else
+ run(memxmode ? "wreduce -memx" : "wreduce");
+ }
+ if (!nomemmode) {
+ run("memory_dff" + (help_mode ? " [-nordff]" : memory_opts));
+ if (help_mode || memxmode)
+ run("memory_memx", "(if -memx)");
+ run("opt_clean");
+ run("memory_collect");
+ }
+ run("opt -keepdc -fast");
}
- if (check_label(active, run_from, run_to, "check"))
+ if (check_label("check"))
{
- Pass::call(design, "stat");
- Pass::call(design, "check");
+ run("stat");
+ run("check");
}
-
- log_pop();
}
} PrepPass;