aboutsummaryrefslogtreecommitdiffstats
path: root/passes/cmds
diff options
context:
space:
mode:
Diffstat (limited to 'passes/cmds')
-rw-r--r--passes/cmds/Makefile.inc2
-rw-r--r--passes/cmds/add.cc99
-rw-r--r--passes/cmds/exec.cc203
-rw-r--r--passes/cmds/logger.cc183
-rw-r--r--passes/cmds/select.cc376
-rw-r--r--passes/cmds/show.cc19
6 files changed, 683 insertions, 199 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc
index 07a5d3ddc..60f20fa6d 100644
--- a/passes/cmds/Makefile.inc
+++ b/passes/cmds/Makefile.inc
@@ -1,4 +1,5 @@
+OBJS += passes/cmds/exec.o
OBJS += passes/cmds/add.o
OBJS += passes/cmds/delete.o
OBJS += passes/cmds/design.o
@@ -33,3 +34,4 @@ OBJS += passes/cmds/blackbox.o
OBJS += passes/cmds/ltp.o
OBJS += passes/cmds/bugpoint.o
OBJS += passes/cmds/scratchpad.o
+OBJS += passes/cmds/logger.o
diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc
index dd05ac81f..c49b8bf5d 100644
--- a/passes/cmds/add.cc
+++ b/passes/cmds/add.cc
@@ -22,26 +22,61 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
+static bool is_formal_celltype(const std::string &celltype)
+{
+ if(celltype == "assert" || celltype == "assume" || celltype == "live" || celltype == "fair" || celltype == "cover")
+ return true;
+ else
+ return false;
+}
+
+static void add_formal(RTLIL::Module *module, const std::string &celltype, const std::string &name, const std::string &enable_name)
+{
+ std::string escaped_name = RTLIL::escape_id(name);
+ std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : "";
+ RTLIL::Wire *wire = module->wire(escaped_name);
+ log_assert(is_formal_celltype(celltype));
+
+ if (wire == nullptr) {
+ log_error("Could not find wire with name \"%s\".\n", name.c_str());
+ }
+ else {
+ RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype);
+ formal_cell->setPort(ID(A), wire);
+ if(enable_name == "") {
+ formal_cell->setPort(ID(EN), State::S1);
+ log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str());
+ }
+ else {
+ RTLIL::Wire *enable_wire = module->wire(escaped_enable_name);
+ if(enable_wire == nullptr)
+ log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str());
+
+ formal_cell->setPort(ID(EN), enable_wire);
+ log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str());
+ }
+ }
+}
+
static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global)
{
- RTLIL::Wire *wire = NULL;
+ RTLIL::Wire *wire = nullptr;
name = RTLIL::escape_id(name);
if (module->count_id(name) != 0)
{
- if (module->wires_.count(name) > 0)
- wire = module->wires_.at(name);
+ wire = module->wire(name);
- if (wire != NULL && wire->width != width)
- wire = NULL;
+ if (wire != nullptr && wire->width != width)
+ wire = nullptr;
- if (wire != NULL && wire->port_input != flag_input)
- wire = NULL;
+ if (wire != nullptr && wire->port_input != flag_input)
+ wire = nullptr;
- if (wire != NULL && wire->port_output != flag_output)
- wire = NULL;
+ if (wire != nullptr && wire->port_output != flag_output)
+ wire = nullptr;
- if (wire == NULL)
+ if (wire == nullptr)
log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());
log("Module %s already has such an object.\n", module->name.c_str());
@@ -53,7 +88,6 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
wire->port_output = flag_output;
if (flag_input || flag_output) {
- wire->port_id = module->wires_.size();
module->fixup_ports();
}
@@ -63,21 +97,20 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n
if (!flag_global)
return;
- for (auto &it : module->cells_)
+ for (auto cell : module->cells())
{
- if (design->modules_.count(it.second->type) == 0)
+ RTLIL::Module *mod = design->module(cell->type);
+ if (mod == nullptr)
continue;
-
- RTLIL::Module *mod = design->modules_.at(it.second->type);
if (!design->selected_whole_module(mod->name))
continue;
if (mod->get_blackbox_attribute())
continue;
- if (it.second->hasPort(name))
+ if (cell->hasPort(name))
continue;
- it.second->setPort(name, wire);
- log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str());
+ cell->setPort(name, wire);
+ log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), cell->name.c_str(), cell->type.c_str());
}
}
@@ -106,6 +139,12 @@ struct AddPass : public Pass {
log("selected modules.\n");
log("\n");
log("\n");
+ log(" add {-assert|-assume|-live|-fair|-cover} <name1> [-if <name2>]\n");
+ log("\n");
+ log("Add an $assert, $assume, etc. cell connected to a wire named name1, with its\n");
+ log("enable signal optionally connected to a wire named name2 (default: 1'b1).\n");
+ log("\n");
+ log("\n");
log(" add -mod <name[s]>\n");
log("\n");
log("Add module[s] with the specified name[s].\n");
@@ -115,6 +154,7 @@ struct AddPass : public Pass {
{
std::string command;
std::string arg_name;
+ std::string enable_name = "";
bool arg_flag_input = false;
bool arg_flag_output = false;
bool arg_flag_global = false;
@@ -144,6 +184,17 @@ struct AddPass : public Pass {
argidx++;
break;
}
+ if (arg.length() > 0 && arg[0] == '-' && is_formal_celltype(arg.substr(1))) {
+ if (argidx + 1 >= args.size())
+ break;
+ command = arg.substr(1);
+ arg_name = args[++argidx];
+ if (argidx + 2 < args.size() && args[argidx + 1] == "-if") {
+ enable_name = args[argidx + 2];
+ argidx += 2;
+ }
+ continue;
+ }
break;
}
@@ -155,17 +206,23 @@ struct AddPass : public Pass {
extra_args(args, argidx, design);
- for (auto &mod : design->modules_)
+ bool selected_anything = false;
+ for (auto module : design->modules())
{
- RTLIL::Module *module = mod.second;
+ log_assert(module != nullptr);
if (!design->selected_whole_module(module->name))
continue;
if (module->get_bool_attribute("\\blackbox"))
continue;
- if (command == "wire")
+ selected_anything = true;
+ if (is_formal_celltype(command))
+ add_formal(module, command, arg_name, enable_name);
+ else if (command == "wire")
add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global);
}
+ if (!selected_anything)
+ log_warning("No modules selected, or only blackboxes. Nothing was added.\n");
}
} AddPass;
diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc
new file mode 100644
index 000000000..399cb0ebb
--- /dev/null
+++ b/passes/cmds/exec.cc
@@ -0,0 +1,203 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 - 2020 Claire Wolf <claire@symbioticeda.com>
+ *
+ * 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.
+ *
+ * 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/log.h"
+#include <cstdio>
+
+#if defined(_WIN32)
+# define WIFEXITED(x) 1
+# define WIFSIGNALED(x) 0
+# define WIFSTOPPED(x) 0
+# define WEXITSTATUS(x) ((x) & 0xff)
+# define WTERMSIG(x) SIGTERM
+#else
+# include <sys/wait.h>
+#endif
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct ExecPass : public Pass {
+ ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" exec [options] -- [command]\n");
+ log("\n");
+ log("Execute a command in the operating system shell. All supplied arguments are\n");
+ log("concatenated and passed as a command to popen(3). Whitespace is not guaranteed\n");
+ log("to be preserved, even if quoted. stdin and stderr are not connected, while stdout is\n");
+ log("logged unless the \"-q\" option is specified.\n");
+ log("\n");
+ log("\n");
+ log(" -q\n");
+ log(" Suppress stdout and stderr from subprocess\n");
+ log("\n");
+ log(" -expect-return <int>\n");
+ log(" Generate an error if popen() does not return specified value.\n");
+ log(" May only be specified once; the final specified value is controlling\n");
+ log(" if specified multiple times.\n");
+ log("\n");
+ log(" -expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex does not match any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log(" -not-expect-stdout <regex>\n");
+ log(" Generate an error if the specified regex matches any line\n");
+ log(" in subprocess's stdout. May be specified multiple times.\n");
+ log("\n");
+ log("\n");
+ log(" Example: exec -q -expect-return 0 -- echo \"bananapie\" | grep \"nana\"\n");
+ log("\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ std::string cmd = "";
+ char buf[1024] = {};
+ std::string linebuf = "";
+ bool flag_cmd = false;
+ bool flag_quiet = false;
+ bool flag_expect_return = false;
+ int expect_return_value = 0;
+ bool flag_expect_stdout = false;
+ struct expect_stdout_elem {
+ bool matched;
+ bool polarity; //true: this regex must match at least one line
+ //false: this regex must not match any line
+ std::string str;
+ YS_REGEX_TYPE re;
+
+ expect_stdout_elem() : matched(false), polarity(true), str(), re(){};
+ };
+ std::vector<expect_stdout_elem> expect_stdout;
+
+ if(args.size() == 0)
+ log_cmd_error("No command provided.\n");
+
+ for(size_t argidx = 1; argidx < args.size(); ++argidx) {
+ if (flag_cmd) {
+ cmd += args[argidx] + (argidx != (args.size() - 1)? " " : "");
+ } else {
+ if (args[argidx] == "--")
+ flag_cmd = true;
+ else if (args[argidx] == "-q")
+ flag_quiet = true;
+ else if (args[argidx] == "-expect-return") {
+ flag_expect_return = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected return value specified.\n");
+
+ expect_return_value = atoi(args[argidx].c_str());
+ } else if (args[argidx] == "-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+ } else if (args[argidx] == "-not-expect-stdout") {
+ flag_expect_stdout = true;
+ ++argidx;
+ if (argidx >= args.size())
+ log_cmd_error("No expected regular expression specified.\n");
+
+ try{
+ expect_stdout_elem x;
+ x.str = args[argidx];
+ x.re = YS_REGEX_COMPILE(args[argidx]);
+ x.polarity = false;
+ expect_stdout.push_back(x);
+ } catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", args[argidx].c_str());
+ }
+
+ } else
+ log_cmd_error("Unknown option \"%s\" or \"--\" doesn\'t precede command.", args[argidx].c_str());
+ }
+ }
+
+ log_header(design, "Executing command \"%s\".\n", cmd.c_str());
+ log_push();
+
+ fflush(stdout);
+ bool keep_reading = true;
+ int status = 0;
+ int retval = 0;
+
+#ifndef EMSCRIPTEN
+ FILE *f = popen(cmd.c_str(), "r");
+ if (f == nullptr)
+ log_cmd_error("errno %d after popen() returned NULL.\n", errno);
+ while (keep_reading) {
+ keep_reading = (fgets(buf, sizeof(buf), f) != nullptr);
+ linebuf += buf;
+ memset(buf, 0, sizeof(buf));
+
+ auto pos = linebuf.find('\n');
+ while (pos != std::string::npos) {
+ std::string line = linebuf.substr(0, pos);
+ linebuf.erase(0, pos + 1);
+ if (!flag_quiet)
+ log("%s\n", line.c_str());
+
+ if (flag_expect_stdout)
+ for(auto &x : expect_stdout)
+ if (YS_REGEX_NS::regex_search(line, x.re))
+ x.matched = true;
+
+ pos = linebuf.find('\n');
+ }
+ }
+ status = pclose(f);
+#endif
+
+ if(WIFEXITED(status)) {
+ retval = WEXITSTATUS(status);
+ }
+ else if(WIFSIGNALED(status)) {
+ retval = WTERMSIG(status);
+ }
+ else if(WIFSTOPPED(status)) {
+ retval = WSTOPSIG(status);
+ }
+
+ if (flag_expect_return && retval != expect_return_value)
+ log_cmd_error("Return value %d did not match expected return value %d.\n", retval, expect_return_value);
+
+ if (flag_expect_stdout)
+ for (auto &x : expect_stdout)
+ if (x.polarity ^ x.matched)
+ log_cmd_error("Command stdout did%s have a line matching given regex \"%s\".\n", (x.polarity? " not" : ""), x.str.c_str());
+
+ log_pop();
+ }
+} ExecPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/logger.cc b/passes/cmds/logger.cc
new file mode 100644
index 000000000..9a27952d4
--- /dev/null
+++ b/passes/cmds/logger.cc
@@ -0,0 +1,183 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2020 Miodrag Milanovic <clifford@clifford.at>
+ *
+ * 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.
+ *
+ * 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/log.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct LoggerPass : public Pass {
+ LoggerPass() : Pass("logger", "set logger properties") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" logger [options]\n");
+ log("\n");
+ log("This command sets global logger properties, also available using command line\n");
+ log("options.\n");
+ log("\n");
+ log(" -[no]time\n");
+ log(" enable/disable display of timestamp in log output.\n");
+ log("\n");
+ log(" -[no]stderr\n");
+ log(" enable/disable logging errors to stderr.\n");
+ log("\n");
+ log(" -warn regex\n");
+ log(" print a warning for all log messages matching the regex.\n");
+ log("\n");
+ log(" -nowarn regex\n");
+ log(" if a warning message matches the regex, it is printed as regular\n");
+ log(" message instead.\n");
+ log("\n");
+ log(" -werror regex\n");
+ log(" if a warning message matches the regex, it is printed as error\n");
+ log(" message instead and the tool terminates with a nonzero return code.\n");
+ log("\n");
+ log(" -[no]debug\n");
+ log(" globally enable/disable debug log messages.\n");
+ log("\n");
+ log(" -experimental <feature>\n");
+ log(" do not print warnings for the specified experimental feature\n");
+ log("\n");
+ log(" -expect <type> <regex> <expected_count>\n");
+ log(" expect log,warning or error to appear. In case of error return code is 0.\n");
+ log("\n");
+ log(" -expect-no-warnings\n");
+ log(" gives error in case there is at least one warning that is not expected.\n");
+ log("\n");
+ }
+
+ void execute(std::vector<std::string> args, RTLIL::Design * design) YS_OVERRIDE
+ {
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+
+ if (args[argidx] == "-time") {
+ log_time = true;
+ log("Enabled timestamp in logs.\n");
+ continue;
+ }
+ if (args[argidx] == "-notime") {
+ log_time = false;
+ log("Disabled timestamp in logs.\n");
+ continue;
+ }
+ if (args[argidx] == "-stderr") {
+ log_error_stderr = true;
+ log("Enabled loggint errors to stderr.\n");
+ continue;
+ }
+ if (args[argidx] == "-nostderr") {
+ log_error_stderr = false;
+ log("Disabled loggint errors to stderr.\n");
+ continue;
+ }
+ if (args[argidx] == "-warn" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to warn list.\n", pattern.c_str());
+ log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-nowarn" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to nowarn list.\n", pattern.c_str());
+ log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-werror" && argidx+1 < args.size()) {
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ try {
+ log("Added regex '%s' for warnings to werror list.\n", pattern.c_str());
+ log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-debug") {
+ log_force_debug = 1;
+ log("Enabled debug log messages.\n");
+ continue;
+ }
+ if (args[argidx] == "-nodebug") {
+ log_force_debug = 0;
+ log("Disabled debug log messages.\n");
+ continue;
+ }
+ if (args[argidx] == "-experimental" && argidx+1 < args.size()) {
+ std::string value = args[++argidx];
+ log("Added '%s' experimental ignore list.\n", value.c_str());
+ log_experimentals_ignored.insert(value);
+ continue;
+ }
+ if (args[argidx] == "-expect" && argidx+3 < args.size()) {
+ std::string type = args[++argidx];
+ if (type!="error" && type!="warning" && type!="log")
+ log_cmd_error("Expect command require type to be 'log', 'warning' or 'error' !\n");
+ if (type=="error" && log_expect_error.size()>0)
+ log_cmd_error("Only single error message can be expected !\n");
+ std::string pattern = args[++argidx];
+ if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2);
+ int count = atoi(args[++argidx].c_str());
+ if (count<=0)
+ log_cmd_error("Number of expected messages must be higher then 0 !\n");
+ if (type=="error" && count!=1)
+ log_cmd_error("Expected error message occurrences must be 1 !\n");
+ log("Added regex '%s' for warnings to expected %s list.\n", pattern.c_str(), type.c_str());
+ try {
+ if (type=="error")
+ log_expect_error.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ else if (type=="warning")
+ log_expect_warning.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ else
+ log_expect_log.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count)));
+ }
+ catch (const YS_REGEX_NS::regex_error& e) {
+ log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str());
+ }
+ continue;
+ }
+ if (args[argidx] == "-expect-no-warnings") {
+ log_expect_no_warnings = true;
+ continue;
+ }
+ break;
+ }
+ extra_args(args, argidx, design, false);
+ }
+} LoggerPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc
index 0f1f05ccb..b64b077e4 100644
--- a/passes/cmds/select.cc
+++ b/passes/cmds/select.cc
@@ -58,7 +58,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char
{
RTLIL::SigSpec sig_value;
- if (!RTLIL::SigSpec::parse(sig_value, NULL, pattern))
+ if (!RTLIL::SigSpec::parse(sig_value, nullptr, pattern))
return false;
RTLIL::Const pattern_value = sig_value.as_const();
@@ -152,27 +152,26 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs)
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
continue;
- if (!lhs.selected_module(mod_it.first)) {
- new_sel.selected_modules.insert(mod_it.first);
+ if (!lhs.selected_module(mod->name)) {
+ new_sel.selected_modules.insert(mod->name);
continue;
}
- RTLIL::Module *mod = mod_it.second;
- for (auto &it : mod->wires_)
- if (!lhs.selected_member(mod_it.first, it.first))
- new_sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (!lhs.selected_member(mod->name, wire->name))
+ new_sel.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
- if (!lhs.selected_member(mod_it.first, it.first))
- new_sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (!lhs.selected_member(mod_it.first, it.first))
+ if (!lhs.selected_member(mod->name, it.first))
new_sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (!lhs.selected_member(mod->name, cell->name))
+ new_sel.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
- if (!lhs.selected_member(mod_it.first, it.first))
+ if (!lhs.selected_member(mod->name, it.first))
new_sel.selected_members[mod->name].insert(it.first);
}
@@ -223,15 +222,15 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c
static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
{
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
{
- for (auto &cell_it : mod_it.second->cells_)
+ for (auto cell : mod->cells())
{
- if (design->modules_.count(cell_it.second->type) == 0)
+ if (design->module(cell->type) == nullptr)
continue;
- lhs.selected_modules.insert(cell_it.second->type);
+ lhs.selected_modules.insert(cell->type);
}
}
}
@@ -240,21 +239,21 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs)
static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs)
{
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
- if (lhs.selected_module(mod_it.first))
- for (auto &cell_it : mod_it.second->cells_)
- if (lhs.selected_member(mod_it.first, cell_it.first) && design->modules_.count(cell_it.second->type))
- new_sel.selected_modules.insert(cell_it.second->type);
+ for (auto mod : design->modules())
+ if (lhs.selected_module(mod->name))
+ for (auto cell : mod->cells())
+ if (lhs.selected_member(mod->name, cell->name) && (design->module(cell->type) != nullptr))
+ new_sel.selected_modules.insert(cell->type);
lhs = new_sel;
}
static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs)
{
RTLIL::Selection new_sel(false);
- for (auto &mod_it : design->modules_)
- for (auto &cell_it : mod_it.second->cells_)
- if (design->modules_.count(cell_it.second->type) && lhs.selected_whole_module(cell_it.second->type))
- new_sel.selected_members[mod_it.first].insert(cell_it.first);
+ for (auto mod : design->modules())
+ for (auto cell : mod->cells())
+ if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type))
+ new_sel.selected_members[mod->name].insert(cell->name);
lhs = new_sel;
}
@@ -268,23 +267,23 @@ static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs)
static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs)
{
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name))
continue;
- if (!lhs.selected_module(mod_it.first))
+ if (!lhs.selected_module(mod->name))
continue;
- SigMap sigmap(mod_it.second);
+ SigMap sigmap(mod);
SigPool selected_bits;
- for (auto &it : mod_it.second->wires_)
- if (lhs.selected_member(mod_it.first, it.first))
- selected_bits.add(sigmap(it.second));
+ for (auto wire : mod->wires())
+ if (lhs.selected_member(mod->name, wire->name))
+ selected_bits.add(sigmap(wire));
- for (auto &it : mod_it.second->wires_)
- if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second)))
- lhs.selected_members[mod_it.first].insert(it.first);
+ for (auto wire : mod->wires())
+ if (!lhs.selected_member(mod->name, wire->name) && selected_bits.check_any(sigmap(wire)))
+ lhs.selected_members[mod->name].insert(wire->name);
}
}
@@ -323,8 +322,8 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R
if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0)
return;
lhs.full_selection = false;
- for (auto &it : design->modules_)
- lhs.selected_modules.insert(it.first);
+ for (auto mod : design->modules())
+ lhs.selected_modules.insert(mod->name);
}
for (auto &it : rhs.selected_modules) {
@@ -334,19 +333,19 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R
for (auto &it : rhs.selected_members)
{
- if (design->modules_.count(it.first) == 0)
+ if (design->module(it.first) == nullptr)
continue;
- RTLIL::Module *mod = design->modules_[it.first];
+ RTLIL::Module *mod = design->module(it.first);
if (lhs.selected_modules.count(mod->name) > 0)
{
- for (auto &it : mod->wires_)
- lhs.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ lhs.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
lhs.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- lhs.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ lhs.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
lhs.selected_members[mod->name].insert(it.first);
lhs.selected_modules.erase(mod->name);
@@ -367,8 +366,8 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co
if (lhs.full_selection) {
lhs.full_selection = false;
- for (auto &it : design->modules_)
- lhs.selected_modules.insert(it.first);
+ for (auto mod : design->modules())
+ lhs.selected_modules.insert(mod->name);
}
std::vector<RTLIL::IdString> del_list;
@@ -431,18 +430,17 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
{
int sel_objects = 0;
bool is_input, is_output;
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first))
+ if (lhs.selected_whole_module(mod->name) || !lhs.selected_module(mod->name))
continue;
- RTLIL::Module *mod = mod_it.second;
std::set<RTLIL::Wire*> selected_wires;
auto selected_members = lhs.selected_members[mod->name];
- for (auto &it : mod->wires_)
- if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0)
- selected_wires.insert(it.second);
+ for (auto wire : mod->wires())
+ if (lhs.selected_member(mod->name, wire->name) && limits.count(wire->name) == 0)
+ selected_wires.insert(wire);
for (auto &conn : mod->connections())
{
@@ -450,7 +448,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
std::vector<RTLIL::SigBit> conn_rhs = conn.second.to_sigbit_vector();
for (size_t i = 0; i < conn_lhs.size(); i++) {
- if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL)
+ if (conn_lhs[i].wire == nullptr || conn_rhs[i].wire == nullptr)
continue;
if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0)
lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--;
@@ -459,15 +457,15 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
}
}
- for (auto &cell : mod->cells_)
- for (auto &conn : cell.second->connections())
+ for (auto cell : mod->cells())
+ for (auto &conn : cell->connections())
{
char last_mode = '-';
- if (eval_only && !yosys_celltypes.cell_evaluable(cell.second->type))
+ if (eval_only && !yosys_celltypes.cell_evaluable(cell->type))
goto exclude_match;
for (auto &rule : rules) {
last_mode = rule.mode;
- if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0)
+ if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0)
continue;
if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0)
continue;
@@ -479,14 +477,14 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v
if (last_mode == '+')
goto exclude_match;
include_match:
- is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first);
- is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first);
+ is_input = mode == 'x' || ct.cell_input(cell->type, conn.first);
+ is_output = mode == 'x' || ct.cell_output(cell->type, conn.first);
for (auto &chunk : conn.second.chunks())
- if (chunk.wire != NULL) {
- if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell.first) == 0)
+ if (chunk.wire != nullptr) {
+ if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name) == 0)
if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input))
- lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--;
- if (max_objects != 0 && selected_members.count(cell.first) > 0 && limits.count(cell.first) == 0 && selected_members.count(chunk.wire->name) == 0)
+ lhs.selected_members[mod->name].insert(cell->name), sel_objects++, max_objects--;
+ if (max_objects != 0 && selected_members.count(cell->name) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name) == 0)
if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output))
lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--;
}
@@ -627,9 +625,13 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se
}
}
-static void select_stmt(RTLIL::Design *design, std::string arg)
+static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_empty_warning = false)
{
std::string arg_mod, arg_memb;
+ std::unordered_map<std::string, bool> arg_mod_found;
+ std::unordered_map<std::string, bool> arg_memb_found;
+ auto isalpha = [](const char &x) { return ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')); };
+ bool prefixed = GetSize(arg) >= 2 && isalpha(arg[0]) && arg[1] == ':';
if (arg.size() == 0)
return;
@@ -760,19 +762,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (!design->selected_active_module.empty()) {
arg_mod = design->selected_active_module;
arg_memb = arg;
+ if (!prefixed) arg_memb_found[arg_memb] = false;
} else
- if (GetSize(arg) >= 2 && arg[0] >= 'a' && arg[0] <= 'z' && arg[1] == ':') {
+ if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') {
arg_mod = "*", arg_memb = arg;
} else {
size_t pos = arg.find('/');
if (pos == std::string::npos) {
- if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0)
- arg_mod = arg;
- else
- arg_mod = "*", arg_memb = arg;
+ arg_mod = arg;
+ if (!prefixed) arg_mod_found[arg_mod] = false;
} else {
arg_mod = arg.substr(0, pos);
+ if (!prefixed) arg_mod_found[arg_mod] = false;
arg_memb = arg.substr(pos+1);
+ bool arg_memb_prefixed = GetSize(arg_memb) >= 2 && isalpha(arg_memb[0]) && arg_memb[1] == ':';
+ if (!arg_memb_prefixed) arg_memb_found[arg_memb] = false;
}
}
@@ -785,56 +789,61 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
}
sel.full_selection = false;
- for (auto &mod_it : design->modules_)
+ for (auto mod : design->modules())
{
if (arg_mod.compare(0, 2, "A:") == 0) {
- if (!match_attr(mod_it.second->attributes, arg_mod.substr(2)))
+ if (!match_attr(mod->attributes, arg_mod.substr(2)))
+ continue;
+ } else
+ if (arg_mod.compare(0, 2, "N:") == 0) {
+ if (!match_ids(mod->name, arg_mod.substr(2)))
continue;
} else
- if (!match_ids(mod_it.first, arg_mod))
+ if (!match_ids(mod->name, arg_mod))
continue;
+ else
+ arg_mod_found[arg_mod] = true;
if (arg_memb == "") {
- sel.selected_modules.insert(mod_it.first);
+ sel.selected_modules.insert(mod->name);
continue;
}
- RTLIL::Module *mod = mod_it.second;
if (arg_memb.compare(0, 2, "w:") == 0) {
- for (auto &it : mod->wires_)
- if (match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "i:") == 0) {
- for (auto &it : mod->wires_)
- if (it.second->port_input && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->port_input && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "o:") == 0) {
- for (auto &it : mod->wires_)
- if (it.second->port_output && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->port_output && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "x:") == 0) {
- for (auto &it : mod->wires_)
- if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
} else
if (arg_memb.compare(0, 2, "s:") == 0) {
size_t delim = arg_memb.substr(2).find(':');
if (delim == std::string::npos) {
int width = atoi(arg_memb.substr(2).c_str());
- for (auto &it : mod->wires_)
- if (it.second->width == width)
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (wire->width == width)
+ sel.selected_members[mod->name].insert(wire->name);
} else {
std::string min_str = arg_memb.substr(2, delim);
std::string max_str = arg_memb.substr(2+delim+1);
int min_width = min_str.empty() ? 0 : atoi(min_str.c_str());
int max_width = max_str.empty() ? -1 : atoi(max_str.c_str());
- for (auto &it : mod->wires_)
- if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (min_width <= wire->width && (wire->width <= max_width || max_width == -1))
+ sel.selected_members[mod->name].insert(wire->name);
}
} else
if (arg_memb.compare(0, 2, "m:") == 0) {
@@ -842,15 +851,15 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
if (match_ids(it.first, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
} else
- if (arg_memb.compare(0, 2, "c:") ==0) {
- for (auto &it : mod->cells_)
- if (match_ids(it.first, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ if (arg_memb.compare(0, 2, "c:") == 0) {
+ for (auto cell : mod->cells())
+ if (match_ids(cell->name, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else
if (arg_memb.compare(0, 2, "t:") == 0) {
- for (auto &it : mod->cells_)
- if (match_ids(it.second->type, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_ids(cell->type, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else
if (arg_memb.compare(0, 2, "p:") == 0) {
for (auto &it : mod->processes)
@@ -858,62 +867,82 @@ static void select_stmt(RTLIL::Design *design, std::string arg)
sel.selected_members[mod->name].insert(it.first);
} else
if (arg_memb.compare(0, 2, "a:") == 0) {
- for (auto &it : mod->wires_)
- if (match_attr(it.second->attributes, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_attr(wire->attributes, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(wire->name);
for (auto &it : mod->memories)
if (match_attr(it.second->attributes, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (match_attr(it.second->attributes, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_attr(cell->attributes, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
for (auto &it : mod->processes)
if (match_attr(it.second->attributes, arg_memb.substr(2)))
sel.selected_members[mod->name].insert(it.first);
} else
if (arg_memb.compare(0, 2, "r:") == 0) {
- for (auto &it : mod->cells_)
- if (match_attr(it.second->parameters, arg_memb.substr(2)))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto cell : mod->cells())
+ if (match_attr(cell->parameters, arg_memb.substr(2)))
+ sel.selected_members[mod->name].insert(cell->name);
} else {
+ std::string orig_arg_memb = arg_memb;
if (arg_memb.compare(0, 2, "n:") == 0)
arg_memb = arg_memb.substr(2);
- for (auto &it : mod->wires_)
- if (match_ids(it.first, arg_memb))
- sel.selected_members[mod->name].insert(it.first);
+ for (auto wire : mod->wires())
+ if (match_ids(wire->name, arg_memb)) {
+ sel.selected_members[mod->name].insert(wire->name);
+ arg_memb_found[orig_arg_memb] = true;
+ }
for (auto &it : mod->memories)
- if (match_ids(it.first, arg_memb))
- sel.selected_members[mod->name].insert(it.first);
- for (auto &it : mod->cells_)
- if (match_ids(it.first, arg_memb))
+ if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
+ arg_memb_found[orig_arg_memb] = true;
+ }
+ for (auto cell : mod->cells())
+ if (match_ids(cell->name, arg_memb)) {
+ sel.selected_members[mod->name].insert(cell->name);
+ arg_memb_found[orig_arg_memb] = true;
+ }
for (auto &it : mod->processes)
- if (match_ids(it.first, arg_memb))
+ if (match_ids(it.first, arg_memb)) {
sel.selected_members[mod->name].insert(it.first);
+ arg_memb_found[orig_arg_memb] = true;
+ }
}
}
select_filter_active_mod(design, work_stack.back());
+
+ for (auto &it : arg_mod_found) {
+ if (it.second == false && !disable_empty_warning) {
+ log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str());
+ }
+ }
+ for (auto &it : arg_memb_found) {
+ if (it.second == false && !disable_empty_warning) {
+ log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str());
+ }
+ }
}
static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel)
{
std::string desc = "Selection contains:\n";
- for (auto mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
- desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first));
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name));
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first));
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name));
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
+ desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first));
}
}
return desc;
@@ -928,7 +957,7 @@ void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, si
work_stack.clear();
for (; argidx < args_size; argidx++) {
if (args[argidx].compare(0, 1, "-") == 0) {
- if (pass != NULL)
+ if (pass != nullptr)
pass->cmd_error(args, argidx, "Unexpected option in selection arguments.");
else
log_cmd_error("Unexpected option in selection arguments.");
@@ -1077,6 +1106,10 @@ struct SelectPass : public Pass {
log(" all modules with an attribute matching the given pattern\n");
log(" in addition to = also <, <=, >=, and > are supported\n");
log("\n");
+ log(" N:<pattern>\n");
+ log(" all modules with a name matching the given pattern\n");
+ log(" (i.e. 'N:' is optional as it is the default matching rule)\n");
+ log("\n");
log("An <obj_pattern> can be an object name, wildcard expression, or one of\n");
log("the following:\n");
log("\n");
@@ -1267,7 +1300,7 @@ struct SelectPass : public Pass {
}
if (arg == "-module" && argidx+1 < args.size()) {
RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]);
- if (design->modules_.count(mod_name) == 0)
+ if (design->module(mod_name) == nullptr)
log_cmd_error("No such module: %s\n", id2cstr(mod_name));
design->selected_active_module = mod_name.str();
got_module = true;
@@ -1279,7 +1312,8 @@ struct SelectPass : public Pass {
}
if (arg.size() > 0 && arg[0] == '-')
log_cmd_error("Unknown option %s.\n", arg.c_str());
- select_stmt(design, arg);
+ bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1);
+ select_stmt(design, arg, disable_empty_warning);
sel_str += " " + arg;
}
@@ -1353,41 +1387,41 @@ struct SelectPass : public Pass {
if (list_mode || count_mode || !write_file.empty())
{
- #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; }
+ #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != nullptr) fprintf(f, __VA_ARGS__); total_count++; }
int total_count = 0;
- FILE *f = NULL;
+ FILE *f = nullptr;
if (!write_file.empty()) {
f = fopen(write_file.c_str(), "w");
yosys_output_files.insert(write_file);
- if (f == NULL)
+ if (f == nullptr)
log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno));
}
RTLIL::Selection *sel = &design->selection_stack.back();
if (work_stack.size() > 0)
sel = &work_stack.back();
sel->optimize(design);
- for (auto mod_it : design->modules_)
+ for (auto mod : design->modules())
{
- if (sel->selected_whole_module(mod_it.first) && list_mode)
- log("%s\n", id2cstr(mod_it.first));
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
- LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first))
+ if (sel->selected_whole_module(mod->name) && list_mode)
+ log("%s\n", id2cstr(mod->name));
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name))
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first))
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name))
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
+ LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first))
}
}
if (count_mode)
log("%d objects.\n", total_count);
- if (f != NULL)
+ if (f != nullptr)
fclose(f);
#undef LOG_OBJECT
return;
@@ -1448,19 +1482,19 @@ struct SelectPass : public Pass {
log_cmd_error("No selection to check.\n");
RTLIL::Selection *sel = &work_stack.back();
sel->optimize(design);
- for (auto mod_it : design->modules_)
- if (sel->selected_module(mod_it.first)) {
- for (auto &it : mod_it.second->wires_)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto mod : design->modules())
+ if (sel->selected_module(mod->name)) {
+ for (auto wire : mod->wires())
+ if (sel->selected_member(mod->name, wire->name))
total_count++;
- for (auto &it : mod_it.second->memories)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto &it : mod->memories)
+ if (sel->selected_member(mod->name, it.first))
total_count++;
- for (auto &it : mod_it.second->cells_)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto cell : mod->cells())
+ if (sel->selected_member(mod->name, cell->name))
total_count++;
- for (auto &it : mod_it.second->processes)
- if (sel->selected_member(mod_it.first, it.first))
+ for (auto &it : mod->processes)
+ if (sel->selected_member(mod->name, it.first))
total_count++;
}
if (assert_count >= 0 && assert_count != total_count)
@@ -1581,15 +1615,13 @@ struct CdPass : public Pass {
std::string modname = RTLIL::escape_id(args[1]);
- if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) {
- RTLIL::Module *module = NULL;
- if (design->modules_.count(design->selected_active_module) > 0)
- module = design->modules_.at(design->selected_active_module);
- if (module != NULL && module->cells_.count(modname) > 0)
- modname = module->cells_.at(modname)->type.str();
+ if (design->module(modname) == nullptr && !design->selected_active_module.empty()) {
+ RTLIL::Module *module = design->module(design->selected_active_module);
+ if (module != nullptr && module->cell(modname) != nullptr)
+ modname = module->cell(modname)->type.str();
}
- if (design->modules_.count(modname) > 0) {
+ if (design->module(modname) != nullptr) {
design->selected_active_module = modname;
design->selection_stack.back() = RTLIL::Selection();
select_filter_active_mod(design, design->selection_stack.back());
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index eeef24bde..e0d428811 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -668,6 +668,10 @@ struct ShowPass : public Pass {
log(" -notitle\n");
log(" do not add the module name as graph title to the dot file\n");
log("\n");
+ log(" -nobg\n");
+ log(" don't run viewer in the background, IE wait for the viewer tool to\n");
+ log(" exit before returning\n");
+ log("\n");
log("When no <format> is specified, 'dot' is used. When no <format> and <viewer> is\n");
log("specified, 'xdot' is used to display the schematic (POSIX systems only).\n");
log("\n");
@@ -706,6 +710,7 @@ struct ShowPass : public Pass {
bool flag_abbreviate = true;
bool flag_notitle = false;
bool custom_prefix = false;
+ std::string background = "&";
RTLIL::IdString colorattr;
size_t argidx;
@@ -787,6 +792,10 @@ struct ShowPass : public Pass {
flag_notitle = true;
continue;
}
+ if (arg == "-nobg") {
+ background= "";
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -859,21 +868,19 @@ struct ShowPass : public Pass {
// system()/cmd.exe does not understand single quotes nor
// background tasks on Windows. So we have to pause yosys
// until the viewer exits.
- #define VIEW_CMD "%s \"%s\""
+ std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str());
#else
- #define VIEW_CMD "%s '%s' &"
+ std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str());
#endif
- std::string cmd = stringf(VIEW_CMD, viewer_exe.c_str(), out_file.c_str());
- #undef VIEW_CMD
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)
log_cmd_error("Shell command failed!\n");
} else
if (format.empty()) {
#ifdef __APPLE__
- std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' &", getuid(), dot_file.c_str(), dot_file.c_str());
+ std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str());
#else
- std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str());
+ std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str());
#endif
log("Exec: %s\n", cmd.c_str());
if (run_command(cmd) != 0)