diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/Makefile.inc | 1 | ||||
-rw-r--r-- | passes/cmds/add.cc | 4 | ||||
-rw-r--r-- | passes/cmds/design.cc | 67 | ||||
-rw-r--r-- | passes/cmds/exec.cc | 205 | ||||
-rw-r--r-- | passes/cmds/logger.cc | 38 | ||||
-rw-r--r-- | passes/cmds/select.cc | 376 | ||||
-rw-r--r-- | passes/fsm/fsm_extract.cc | 6 | ||||
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 132 | ||||
-rw-r--r-- | passes/opt/opt_expr.cc | 70 | ||||
-rw-r--r-- | passes/opt/opt_merge.cc | 234 | ||||
-rw-r--r-- | passes/sat/eval.cc | 90 | ||||
-rw-r--r-- | passes/sat/expose.cc | 151 | ||||
-rw-r--r-- | passes/sat/freduce.cc | 28 | ||||
-rw-r--r-- | passes/sat/miter.cc | 116 | ||||
-rw-r--r-- | passes/techmap/iopadmap.cc | 24 | ||||
-rw-r--r-- | passes/techmap/techmap.cc | 2 |
16 files changed, 874 insertions, 670 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 20b38bf8e..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 diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 7b76f3d4a..c49b8bf5d 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -206,6 +206,7 @@ struct AddPass : public Pass { extra_args(args, argidx, design); + bool selected_anything = false; for (auto module : design->modules()) { log_assert(module != nullptr); @@ -214,11 +215,14 @@ struct AddPass : public Pass { if (module->get_bool_attribute("\\blackbox")) continue; + 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/design.cc b/passes/cmds/design.cc index 172addcc1..7ea0be9ee 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -18,6 +18,7 @@ */ #include "kernel/yosys.h" +#include "frontends/verilog/preproc.h" #include "frontends/ast/ast.h" YOSYS_NAMESPACE_BEGIN @@ -194,13 +195,13 @@ struct DesignPass : public Pass { argidx = args.size(); } - for (auto &it : copy_from_design->modules_) { - if (sel.selected_whole_module(it.first)) { - copy_src_modules.push_back(it.second); + for (auto mod : copy_from_design->modules()) { + if (sel.selected_whole_module(mod->name)) { + copy_src_modules.push_back(mod); continue; } - if (sel.selected_module(it.first)) - log_cmd_error("Module %s is only partly selected.\n", RTLIL::id2cstr(it.first)); + if (sel.selected_module(mod->name)) + log_cmd_error("Module %s is only partly selected.\n", log_id(mod->name)); } if (import_mode) { @@ -230,8 +231,8 @@ struct DesignPass : public Pass { pool<Module*> queue; dict<IdString, IdString> done; - if (copy_to_design->modules_.count(prefix)) - delete copy_to_design->modules_.at(prefix); + if (copy_to_design->module(prefix) != nullptr) + copy_to_design->remove(copy_to_design->module(prefix)); if (GetSize(copy_src_modules) != 1) log_cmd_error("No top module found in source design.\n"); @@ -240,12 +241,13 @@ struct DesignPass : public Pass { { log("Importing %s as %s.\n", log_id(mod), log_id(prefix)); - copy_to_design->modules_[prefix] = mod->clone(); - copy_to_design->modules_[prefix]->name = prefix; - copy_to_design->modules_[prefix]->design = copy_to_design; - copy_to_design->modules_[prefix]->attributes.erase("\\top"); + RTLIL::Module *t = mod->clone(); + t->name = prefix; + t->design = copy_to_design; + t->attributes.erase("\\top"); + copy_to_design->add(t); - queue.insert(copy_to_design->modules_[prefix]); + queue.insert(t); done[mod->name] = prefix; } @@ -268,15 +270,16 @@ struct DesignPass : public Pass { log("Importing %s as %s.\n", log_id(fmod), log_id(trg_name)); - if (copy_to_design->modules_.count(trg_name)) - delete copy_to_design->modules_.at(trg_name); + if (copy_to_design->module(trg_name) != nullptr) + copy_to_design->remove(copy_to_design->module(trg_name)); - copy_to_design->modules_[trg_name] = fmod->clone(); - copy_to_design->modules_[trg_name]->name = trg_name; - copy_to_design->modules_[trg_name]->design = copy_to_design; - copy_to_design->modules_[trg_name]->attributes.erase("\\top"); + RTLIL::Module *t = fmod->clone(); + t->name = trg_name; + t->design = copy_to_design; + t->attributes.erase("\\top"); + copy_to_design->add(t); - queue.insert(copy_to_design->modules_[trg_name]); + queue.insert(t); done[cell->type] = trg_name; } @@ -294,12 +297,13 @@ struct DesignPass : public Pass { { std::string trg_name = as_name.empty() ? mod->name.str() : RTLIL::escape_id(as_name); - if (copy_to_design->modules_.count(trg_name)) - delete copy_to_design->modules_.at(trg_name); + if (copy_to_design->module(trg_name) != nullptr) + copy_to_design->remove(copy_to_design->module(trg_name)); - copy_to_design->modules_[trg_name] = mod->clone(); - copy_to_design->modules_[trg_name]->name = trg_name; - copy_to_design->modules_[trg_name]->design = copy_to_design; + RTLIL::Module *t = mod->clone(); + t->name = trg_name; + t->design = copy_to_design; + copy_to_design->add(t); } } @@ -307,8 +311,8 @@ struct DesignPass : public Pass { { RTLIL::Design *design_copy = new RTLIL::Design; - for (auto &it : design->modules_) - design_copy->add(it.second->clone()); + for (auto mod : design->modules()) + design_copy->add(mod->clone()); design_copy->selection_stack = design->selection_stack; design_copy->selection_vars = design->selection_vars; @@ -325,9 +329,8 @@ struct DesignPass : public Pass { if (reset_mode || !load_name.empty() || push_mode || pop_mode) { - for (auto &it : design->modules_) - delete it.second; - design->modules_.clear(); + for (auto mod : design->modules()) + design->remove(mod); design->selection_stack.clear(); design->selection_vars.clear(); @@ -346,15 +349,15 @@ struct DesignPass : public Pass { delete node; design->verilog_globals.clear(); - design->verilog_defines.clear(); + design->verilog_defines->clear(); } if (!load_name.empty() || pop_mode) { RTLIL::Design *saved_design = pop_mode ? pushed_designs.back() : saved_designs.at(load_name); - for (auto &it : saved_design->modules_) - design->add(it.second->clone()); + for (auto mod : saved_design->modules()) + design->add(mod->clone()); design->selection_stack = saved_design->selection_stack; design->selection_vars = saved_design->selection_vars; diff --git a/passes/cmds/exec.cc b/passes/cmds/exec.cc new file mode 100644 index 000000000..7eeefe705 --- /dev/null +++ b/passes/cmds/exec.cc @@ -0,0 +1,205 @@ +/* + * 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) +# include <csignal> +# define WIFEXITED(x) 1 +# define WIFSIGNALED(x) 0 +# define WIFSTOPPED(x) 0 +# define WEXITSTATUS(x) ((x) & 0xff) +# define WTERMSIG(x) SIGTERM +# define WSTOPSIG(x) 0 +#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 index bd1038a7e..9a27952d4 100644 --- a/passes/cmds/logger.cc +++ b/passes/cmds/logger.cc @@ -96,12 +96,9 @@ struct LoggerPass : public Pass { 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(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -111,12 +108,9 @@ struct LoggerPass : public Pass { 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(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -126,12 +120,9 @@ struct LoggerPass : public Pass { 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(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep)); + log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; @@ -168,22 +159,13 @@ struct LoggerPass : public Pass { 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(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + 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(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + log_expect_warning.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); else - log_expect_log.push_back(std::make_pair(std::regex(pattern, - std::regex_constants::nosubs | - std::regex_constants::optimize | - std::regex_constants::egrep), LogExpectedItem(pattern, count))); + log_expect_log.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); } - catch (const std::regex_error& e) { + catch (const YS_REGEX_NS::regex_error& e) { log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); } continue; 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/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index a85c3bec0..0f7b4d106 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -422,11 +422,7 @@ struct FsmExtractPass : public Pass { log_header(design, "Executing FSM_EXTRACT pass (extracting FSM from design).\n"); extra_args(args, 1, design); - CellTypes ct; - ct.setup_internals(); - ct.setup_internals_mem(); - ct.setup_stdcells(); - ct.setup_stdcells_mem(); + CellTypes ct(design); for (auto &mod_it : design->modules_) { diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index fa4a8ea29..3f4fe502d 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -42,11 +42,10 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, { std::set<RTLIL::IdString> found_celltypes; - for (auto i1 : design->modules_) - for (auto i2 : i1.second->cells_) + for (auto mod : design->modules()) + for (auto cell : mod->cells()) { - RTLIL::Cell *cell = i2.second; - if (design->has(cell->type)) + if (design->module(cell->type) != nullptr) continue; if (cell->type.begins_with("$__")) continue; @@ -62,15 +61,15 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, std::map<RTLIL::IdString, int> portwidths; log("Generate module for cell type %s:\n", celltype.c_str()); - for (auto i1 : design->modules_) - for (auto i2 : i1.second->cells_) - if (i2.second->type == celltype) { - for (auto &conn : i2.second->connections()) { + for (auto mod : design->modules()) + for (auto cell : mod->cells()) + if (cell->type == celltype) { + for (auto &conn : cell->connections()) { if (conn.first[0] != '$') portnames.insert(conn.first); portwidths[conn.first] = max(portwidths[conn.first], conn.second.size()); } - for (auto ¶ : i2.second->parameters) + for (auto ¶ : cell->parameters) parameters.insert(para.first); } @@ -168,26 +167,24 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // If any of the ports are actually interface ports, we will always need to // reprocess the module: if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) { - for (auto &wire : module->wires_) { - if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) + for (auto wire : module->wires()) { + if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface")) has_interface_ports = true; } } // Always keep track of all derived interfaces available in the current module in 'interfaces_in_module': dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module; - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; if(cell->get_bool_attribute("\\is_interface")) { - RTLIL::Module *intf_module = design->modules_[cell->type]; + RTLIL::Module *intf_module = design->module(cell->type); interfaces_in_module[cell->name] = intf_module; } } - for (auto &cell_it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = cell_it.second; bool has_interfaces_not_found = false; std::vector<RTLIL::IdString> connections_to_remove; @@ -208,11 +205,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule; dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule; - if (design->modules_.count(cell->type) == 0) + if (design->module(cell->type) == nullptr) { - if (design->modules_.count("$abstract" + cell->type.str())) + if (design->module("$abstract" + cell->type.str()) != nullptr) { - cell->type = design->modules_.at("$abstract" + cell->type.str())->derive(design, cell->parameters); + cell->type = design->module("$abstract" + cell->type.str())->derive(design, cell->parameters); cell->parameters.clear(); did_something = true; continue; @@ -246,7 +243,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check continue; loaded_module: - if (design->modules_.count(cell->type) == 0) + if (design->module(cell->type) == nullptr) log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str()); did_something = true; } else { @@ -256,7 +253,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to // some lists, so that the ports for sub-modules can be replaced further down: for (auto &conn : cell->connections()) { - if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list + if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list //const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type"); //for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness) //} @@ -285,11 +282,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check if (nexactmatch != 0) // Choose the one with the plain name if it exists interface_name2 = interface_name; RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2); - for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists. - std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first); - std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first); + for (auto mod_wire : mod_replace_ports->wires()) { // Go over all wires in interface, and add replacements to lists. + std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire->name); + std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire); connections_to_add_name.push_back(RTLIL::IdString(signal_name1)); - if(module->wires_.count(signal_name2) == 0) { + if(module->wire(signal_name2) == nullptr) { log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name)); } else { @@ -344,9 +341,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check } } - RTLIL::Module *mod = design->modules_[cell->type]; + RTLIL::Module *mod = design->module(cell->type); - if (design->modules_.at(cell->type)->get_blackbox_attribute()) { + if (design->module(cell->type)->get_blackbox_attribute()) { if (flag_simcheck) log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); @@ -389,7 +386,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // an interface instance: if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) { cell->set_bool_attribute("\\is_interface"); - RTLIL::Module *derived_module = design->modules_[cell->type]; + RTLIL::Module *derived_module = design->module(cell->type); interfaces_in_module[cell->name] = derived_module; did_something = true; } @@ -414,25 +411,25 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::Cell *cell = it.first; int idx = it.second.first, num = it.second.second; - if (design->modules_.count(cell->type) == 0) + if (design->module(cell->type) == nullptr) log_error("Array cell `%s.%s' of unknown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); - RTLIL::Module *mod = design->modules_[cell->type]; + RTLIL::Module *mod = design->module(cell->type); for (auto &conn : cell->connections_) { int conn_size = conn.second.size(); RTLIL::IdString portname = conn.first; if (portname.begins_with("$")) { int port_id = atoi(portname.substr(1).c_str()); - for (auto &wire_it : mod->wires_) - if (wire_it.second->port_id == port_id) { - portname = wire_it.first; + for (auto wire : mod->wires()) + if (wire->port_id == port_id) { + portname = wire->name; break; } } - if (mod->wires_.count(portname) == 0) + if (mod->wire(portname) == nullptr) log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first)); - int port_size = mod->wires_.at(portname)->width; + int port_size = mod->wire(portname)->width; if (conn_size == port_size || conn_size == 0) continue; if (conn_size != port_size*num) @@ -470,21 +467,21 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) hierarchy_worker(design, used, top, 0); std::vector<RTLIL::Module*> del_modules; - for (auto &it : design->modules_) - if (used.count(it.second) == 0) - del_modules.push_back(it.second); + for (auto mod : design->modules()) + if (used.count(mod) == 0) + del_modules.push_back(mod); else { // Now all interface ports must have been exploded, and it is hence // safe to delete all of the remaining dummy interface ports: pool<RTLIL::Wire*> del_wires; - for(auto &wire : it.second->wires_) { - if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) { - del_wires.insert(wire.second); + for(auto wire : mod->wires()) { + if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface")) { + del_wires.insert(wire); } } if (del_wires.size() > 0) { - it.second->remove(del_wires); - it.second->fixup_ports(); + mod->remove(del_wires); + mod->fixup_ports(); } } @@ -493,9 +490,8 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib) if (!purge_lib && mod->get_blackbox_attribute()) continue; log("Removing unused module `%s'.\n", mod->name.c_str()); - design->modules_.erase(mod->name); + design->remove(mod); del_counter++; - delete mod; } log("Removed %d unused modules.\n", del_counter); @@ -817,9 +813,9 @@ struct HierarchyPass : public Pass { log_push(); if (top_mod == nullptr) - for (auto &mod_it : design->modules_) - if (mod_it.second->get_bool_attribute("\\top")) - top_mod = mod_it.second; + for (auto mod : design->modules()) + if (mod->get_bool_attribute("\\top")) + top_mod = mod; if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) { IdString top_name = top_mod->name.substr(strlen("$abstract")); @@ -862,11 +858,11 @@ struct HierarchyPass : public Pass { log_error("Design has no top module.\n"); if (top_mod != NULL) { - for (auto &mod_it : design->modules_) - if (mod_it.second == top_mod) - mod_it.second->attributes["\\initial_top"] = RTLIL::Const(1); + for (auto mod : design->modules()) + if (mod == top_mod) + mod->attributes["\\initial_top"] = RTLIL::Const(1); else - mod_it.second->attributes.erase("\\initial_top"); + mod->attributes.erase("\\initial_top"); } bool did_something = true; @@ -900,9 +896,9 @@ struct HierarchyPass : public Pass { // Delete modules marked as 'to_delete': std::vector<RTLIL::Module *> modules_to_delete; - for(auto &mod_it : design->modules_) { - if (mod_it.second->get_bool_attribute("\\to_delete")) { - modules_to_delete.push_back(mod_it.second); + for(auto mod : design->modules()) { + if (mod->get_bool_attribute("\\to_delete")) { + modules_to_delete.push_back(mod); } } for(size_t i=0; i<modules_to_delete.size(); i++) { @@ -917,12 +913,12 @@ struct HierarchyPass : public Pass { } if (top_mod != NULL) { - for (auto &mod_it : design->modules_) { - if (mod_it.second == top_mod) - mod_it.second->attributes["\\top"] = RTLIL::Const(1); + for (auto mod : design->modules()) { + if (mod == top_mod) + mod->attributes["\\top"] = RTLIL::Const(1); else - mod_it.second->attributes.erase("\\top"); - mod_it.second->attributes.erase("\\initial_top"); + mod->attributes.erase("\\top"); + mod->attributes.erase("\\initial_top"); } } @@ -941,22 +937,20 @@ struct HierarchyPass : public Pass { std::map<std::pair<RTLIL::Module*,int>, RTLIL::IdString> pos_map; std::vector<std::pair<RTLIL::Module*,RTLIL::Cell*>> pos_work; - for (auto &mod_it : design->modules_) - for (auto &cell_it : mod_it.second->cells_) { - RTLIL::Cell *cell = cell_it.second; - if (design->modules_.count(cell->type) == 0) + for (auto mod : design->modules()) + for (auto cell : mod->cells()) { + if (design->module(cell->type) == nullptr) continue; for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { - pos_mods.insert(design->modules_.at(cell->type)); - pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod_it.second, cell)); + pos_mods.insert(design->module(cell->type)); + pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod, cell)); break; } } for (auto module : pos_mods) - for (auto &wire_it : module->wires_) { - RTLIL::Wire *wire = wire_it.second; + for (auto wire : module->wires()) { if (wire->port_id > 0) pos_map[std::pair<RTLIL::Module*,int>(module, wire->port_id)] = wire->name; } @@ -970,7 +964,7 @@ struct HierarchyPass : public Pass { for (auto &conn : cell->connections()) if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') { int id = atoi(conn.first.c_str()+1); - std::pair<RTLIL::Module*,int> key(design->modules_.at(cell->type), id); + std::pair<RTLIL::Module*,int> key(design->module(cell->type), id); if (pos_map.count(key) == 0) { log(" Failed to map positional argument %d of cell %s.%s (%s).\n", id, RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type)); diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 1a586711c..1a9de7f40 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -687,10 +687,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons int i; for (i = 0; i < GetSize(sig_y); i++) { - if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) - module->connect(sig_y[i], sig_a[i]); - else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) - module->connect(sig_y[i], sig_b[i]); + RTLIL::SigBit b = sig_b.at(i, State::Sx); + RTLIL::SigBit a = sig_a.at(i, State::Sx); + if (b == State::S0 && a != State::Sx) + module->connect(sig_y[i], a); + else if (sub && b == State::S1 && a == State::S1) + module->connect(sig_y[i], State::S0); + else if (!sub && a == State::S0 && b != State::Sx) + module->connect(sig_y[i], b); else break; } @@ -704,7 +708,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type == "$alu") + if (cell->type == ID($alu)) { RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B)); @@ -714,9 +718,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons RTLIL::SigSpec sig_y = cell->getPort(ID::Y); RTLIL::SigSpec sig_co = cell->getPort(ID(CO)); - if (sig_ci.wire || sig_bi.wire) - goto next_cell; - bool sub = (sig_ci == State::S1 && sig_bi == State::S1); // If not a subtraction, yet there is a carry or B is inverted @@ -726,14 +727,21 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons int i; for (i = 0; i < GetSize(sig_y); i++) { - if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) { - module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]); + RTLIL::SigBit b = sig_b.at(i, State::Sx); + RTLIL::SigBit a = sig_a.at(i, State::Sx); + if (b == State::S0 && a != State::Sx) { module->connect(sig_y[i], sig_a[i]); + module->connect(sig_x[i], sub ? module->Not(NEW_ID, a).as_bit() : a); module->connect(sig_co[i], sub ? State::S1 : State::S0); } - else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) { - module->connect(sig_x[i], sig_b[i]); - module->connect(sig_y[i], sig_b[i]); + else if (sub && b == State::S1 && a == State::S1) { + module->connect(sig_y[i], State::S0); + module->connect(sig_x[i], module->Not(NEW_ID, a)); + module->connect(sig_co[i], State::S0); + } + else if (!sub && a == State::S0 && b != State::Sx) { + module->connect(sig_y[i], b); + module->connect(sig_x[i], b); module->connect(sig_co[i], State::S0); } else @@ -1066,12 +1074,26 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons bool identity_wrt_b = false; bool arith_inverse = false; - if (cell->type.in(ID($add), ID($sub), ID($or), ID($xor))) + if (cell->type.in(ID($add), ID($sub), ID($alu), ID($or), ID($xor))) { RTLIL::SigSpec a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec b = assign_map(cell->getPort(ID::B)); - if (cell->type != ID($sub) && a.is_fully_const() && a.as_bool() == false) + bool sub = cell->type == ID($sub); + + if (cell->type == ID($alu)) { + RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI))); + RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI))); + + sub = (sig_ci == State::S1 && sig_bi == State::S1); + + // If not a subtraction, yet there is a carry or B is inverted + // then no optimisation is possible as carry will not be constant + if (!sub && (sig_ci != State::S0 || sig_bi != State::S0)) + goto next_cell; + } + + if (!sub && a.is_fully_const() && a.as_bool() == false) identity_wrt_b = true; if (b.is_fully_const() && b.as_bool() == false) @@ -1109,17 +1131,27 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (identity_wrt_a || identity_wrt_b) { if (identity_wrt_a) - cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); + cover_list("opt.opt_expr.identwrt.a", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); if (identity_wrt_b) - cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); + cover_list("opt.opt_expr.identwrt.b", "$add", "$sub", "$alu", "$or", "$xor", "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", "$mul", "$div", cell->type.str()); log_debug("Replacing %s cell `%s' in module `%s' with identity for port %c.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B'); + if (cell->type == ID($alu)) { + int y_width = GetSize(cell->getPort(ID(Y))); + module->connect(cell->getPort(ID(X)), RTLIL::Const(State::S0, y_width)); + module->connect(cell->getPort(ID(CO)), RTLIL::Const(State::S0, y_width)); + cell->unsetPort(ID(BI)); + cell->unsetPort(ID(CI)); + cell->unsetPort(ID(X)); + cell->unsetPort(ID(CO)); + } + if (!identity_wrt_a) { cell->setPort(ID::A, cell->getPort(ID::B)); - cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH)); - cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED)); + cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH))); + cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED))); } cell->type = arith_inverse ? ID($neg) : ID($pos); diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 8823a9061..4aa78ff39 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -26,7 +26,6 @@ #include <stdio.h> #include <set> -#define USE_CELL_HASH_CACHE USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -41,9 +40,7 @@ struct OptMergeWorker CellTypes ct; int total_count; -#ifdef USE_CELL_HASH_CACHE - dict<const RTLIL::Cell*, std::string> cell_hash_cache; -#endif + SHA1 checksum; static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn) { @@ -68,7 +65,6 @@ struct OptMergeWorker } } -#ifdef USE_CELL_HASH_CACHE std::string int_to_hash_string(unsigned int v) { if (v == 0) @@ -83,14 +79,9 @@ struct OptMergeWorker std::string hash_cell_parameters_and_connections(const RTLIL::Cell *cell) { - if (cell_hash_cache.count(cell) > 0) - return cell_hash_cache[cell]; - + vector<string> hash_conn_strings; std::string hash_string = cell->type.str() + "\n"; - for (auto &it : cell->parameters) - hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n"; - const dict<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections(); dict<RTLIL::IdString, RTLIL::SigSpec> alt_conn; @@ -124,13 +115,22 @@ struct OptMergeWorker conn = &alt_conn; } - vector<string> hash_conn_strings; - for (auto &it : *conn) { - if (cell->output(it.first)) - continue; - RTLIL::SigSpec sig = it.second; - assign_map.apply(sig); + RTLIL::SigSpec sig; + if (cell->output(it.first)) { + if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || + cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || + cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + // For the 'Q' output of state elements, + // use its (* init *) attribute value + for (const auto &b : dff_init_map(it.second)) + sig.append(b.wire ? State::Sx : b); + } + else + continue; + } + else + sig = assign_map(it.second); string s = "C " + it.first.str() + "="; for (auto &chunk : sig.chunks()) { if (chunk.wire) @@ -143,50 +143,59 @@ struct OptMergeWorker hash_conn_strings.push_back(s + "\n"); } + for (auto &it : cell->parameters) + hash_conn_strings.push_back("P " + it.first.str() + "=" + it.second.as_string() + "\n"); + std::sort(hash_conn_strings.begin(), hash_conn_strings.end()); for (auto it : hash_conn_strings) hash_string += it; - cell_hash_cache[cell] = sha1(hash_string); - return cell_hash_cache[cell]; + checksum.update(hash_string); + return checksum.final(); } -#endif - bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2, bool <) + bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) { -#ifdef USE_CELL_HASH_CACHE - std::string hash1 = hash_cell_parameters_and_connections(cell1); - std::string hash2 = hash_cell_parameters_and_connections(cell2); - - if (hash1 != hash2) { - lt = hash1 < hash2; - return true; - } -#endif - - if (cell1->parameters != cell2->parameters) { - std::map<RTLIL::IdString, RTLIL::Const> p1(cell1->parameters.begin(), cell1->parameters.end()); - std::map<RTLIL::IdString, RTLIL::Const> p2(cell2->parameters.begin(), cell2->parameters.end()); - lt = p1 < p2; - return true; - } - - dict<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections(); - dict<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections(); - - for (auto &it : conn1) { - if (cell1->output(it.first)) - it.second = RTLIL::SigSpec(); - else - assign_map.apply(it.second); - } - - for (auto &it : conn2) { - if (cell2->output(it.first)) - it.second = RTLIL::SigSpec(); - else - assign_map.apply(it.second); + log_assert(cell1 != cell2); + if (cell1->type != cell2->type) return false; + + if (cell1->parameters != cell2->parameters) + return false; + + if (cell1->connections_.size() != cell2->connections_.size()) + return false; + for (const auto &it : cell1->connections_) + if (!cell2->connections_.count(it.first)) + return false; + + decltype(Cell::connections_) conn1, conn2; + conn1.reserve(cell1->connections_.size()); + conn2.reserve(cell1->connections_.size()); + + for (const auto &it : cell1->connections_) { + if (cell1->output(it.first)) { + if (it.first == ID(Q) && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || + cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || + cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + // For the 'Q' output of state elements, + // use the (* init *) attribute value + auto &sig1 = conn1[it.first]; + for (const auto &b : dff_init_map(it.second)) + sig1.append(b.wire ? State::Sx : b); + auto &sig2 = conn2[it.first]; + for (const auto &b : dff_init_map(cell2->getPort(it.first))) + sig2.append(b.wire ? State::Sx : b); + } + else { + conn1[it.first] = RTLIL::SigSpec(); + conn2[it.first] = RTLIL::SigSpec(); + } + } + else { + conn1[it.first] = assign_map(it.second); + conn2[it.first] = assign_map(cell2->getPort(it.first)); + } } if (cell1->type == ID($and) || cell1->type == ID($or) || cell1->type == ID($xor) || cell1->type == ID($xnor) || cell1->type == ID($add) || cell1->type == ID($mul) || @@ -215,54 +224,9 @@ struct OptMergeWorker sort_pmux_conn(conn2); } - if (conn1 != conn2) { - std::map<RTLIL::IdString, RTLIL::SigSpec> c1(conn1.begin(), conn1.end()); - std::map<RTLIL::IdString, RTLIL::SigSpec> c2(conn2.begin(), conn2.end()); - lt = c1 < c2; - return true; - } - - if (conn1.count(ID(Q)) != 0 && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") || - cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") || - cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) { - std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort(ID(Q))).to_sigbit_vector(); - std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort(ID(Q))).to_sigbit_vector(); - for (size_t i = 0; i < q1.size(); i++) - if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) { - lt = q1.at(i) < q2.at(i); - return true; - } - } - - return false; + return conn1 == conn2; } - bool compare_cells(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) - { - if (cell1->type != cell2->type) - return cell1->type < cell2->type; - - if ((!mode_share_all && !ct.cell_known(cell1->type)) || !cell1->known()) - return cell1 < cell2; - - if (cell1->has_keep_attr() || cell2->has_keep_attr()) - return cell1 < cell2; - - bool lt; - if (compare_cell_parameters_and_connections(cell1, cell2, lt)) - return lt; - - return false; - } - - struct CompareCells { - OptMergeWorker *that; - CompareCells(OptMergeWorker *that) : that(that) {} - bool operator()(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) const { - return that->compare_cells(cell1, cell2); - } - }; - OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all) : design(design), module(module), assign_map(module), mode_share_all(mode_share_all) { @@ -299,9 +263,6 @@ struct OptMergeWorker bool did_something = true; while (did_something) { -#ifdef USE_CELL_HASH_CACHE - cell_hash_cache.clear(); -#endif std::vector<RTLIL::Cell*> cells; cells.reserve(module->cells_.size()); for (auto &it : module->cells_) { @@ -312,42 +273,51 @@ struct OptMergeWorker } did_something = false; - std::map<RTLIL::Cell*, RTLIL::Cell*, CompareCells> sharemap(CompareCells(this)); + dict<std::string, RTLIL::Cell*> sharemap; for (auto cell : cells) { - if (sharemap.count(cell) > 0) { - did_something = true; - log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str()); - for (auto &it : cell->connections()) { - if (cell->output(it.first)) { - RTLIL::SigSpec other_sig = sharemap[cell]->getPort(it.first); - log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), - log_signal(it.second), log_signal(other_sig)); - module->connect(RTLIL::SigSig(it.second, other_sig)); - assign_map.add(it.second, other_sig); - - if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || - cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || - cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { - for (auto c : it.second.chunks()) { - auto jt = c.wire->attributes.find(ID(init)); - if (jt == c.wire->attributes.end()) - continue; - for (int i = c.offset; i < c.offset + c.width; i++) - jt->second[i] = State::Sx; + if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) + continue; + + auto hash = hash_cell_parameters_and_connections(cell); + auto r = sharemap.insert(std::make_pair(hash, cell)); + if (!r.second) { + if (compare_cell_parameters_and_connections(cell, r.first->second)) { + if (cell->has_keep_attr()) { + if (r.first->second->has_keep_attr()) + continue; + std::swap(r.first->second, cell); + } + + + did_something = true; + log_debug(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), r.first->second->name.c_str()); + for (auto &it : cell->connections()) { + if (cell->output(it.first)) { + RTLIL::SigSpec other_sig = r.first->second->getPort(it.first); + log_debug(" Redirecting output %s: %s = %s\n", it.first.c_str(), + log_signal(it.second), log_signal(other_sig)); + module->connect(RTLIL::SigSig(it.second, other_sig)); + assign_map.add(it.second, other_sig); + + if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") || + cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") || + cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) { + for (auto c : it.second.chunks()) { + auto jt = c.wire->attributes.find(ID(init)); + if (jt == c.wire->attributes.end()) + continue; + for (int i = c.offset; i < c.offset + c.width; i++) + jt->second[i] = State::Sx; + } + dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second))); } - dff_init_map.add(it.second, Const(State::Sx, GetSize(it.second))); } } + log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); + module->remove(cell); + total_count++; } - log_debug(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str()); -#ifdef USE_CELL_HASH_CACHE - cell_hash_cache.erase(cell); -#endif - module->remove(cell); - total_count++; - } else { - sharemap[cell] = cell; } } } diff --git a/passes/sat/eval.cc b/passes/sat/eval.cc index e0bb439f4..148480d55 100644 --- a/passes/sat/eval.cc +++ b/passes/sat/eval.cc @@ -88,25 +88,24 @@ struct BruteForceEquivChecker mod1(mod1), mod2(mod2), counter(0), errors(0), ignore_x_mod1(ignore_x_mod1) { log("Checking for equivalence (brute-force): %s vs %s\n", mod1->name.c_str(), mod2->name.c_str()); - for (auto &w : mod1->wires_) + for (auto w : mod1->wires()) { - RTLIL::Wire *wire1 = w.second; - if (wire1->port_id == 0) + if (w->port_id == 0) continue; - if (mod2->wires_.count(wire1->name) == 0) - log_cmd_error("Port %s in module 1 has no counterpart in module 2!\n", wire1->name.c_str()); + if (mod2->wire(w->name) == nullptr) + log_cmd_error("Port %s in module 1 has no counterpart in module 2!\n", w->name.c_str()); - RTLIL::Wire *wire2 = mod2->wires_.at(wire1->name); - if (wire1->width != wire2->width || wire1->port_input != wire2->port_input || wire1->port_output != wire2->port_output) - log_cmd_error("Port %s in module 1 does not match its counterpart in module 2!\n", wire1->name.c_str()); + RTLIL::Wire *w2 = mod2->wire(w->name); + if (w->width != w2->width || w->port_input != w2->port_input || w->port_output != w2->port_output) + log_cmd_error("Port %s in module 1 does not match its counterpart in module 2!\n", w->name.c_str()); - if (wire1->port_input) { - mod1_inputs.append(wire1); - mod2_inputs.append(wire2); + if (w->port_input) { + mod1_inputs.append(w); + mod2_inputs.append(w2); } else { - mod1_outputs.append(wire1); - mod2_outputs.append(wire2); + mod1_outputs.append(w); + mod2_outputs.append(w2); } } @@ -148,17 +147,17 @@ struct VlogHammerReporter SatGen satgen(ez.get(), &sigmap); satgen.model_undef = model_undef; - for (auto &c : module->cells_) - if (!satgen.importCell(c.second)) - log_error("Failed to import cell %s (type %s) to SAT database.\n", RTLIL::id2cstr(c.first), RTLIL::id2cstr(c.second->type)); + for (auto c : module->cells()) + if (!satgen.importCell(c)) + log_error("Failed to import cell %s (type %s) to SAT database.\n", log_id(c->name), log_id(c->type)); ez->assume(satgen.signals_eq(recorded_set_vars, recorded_set_vals)); - std::vector<int> y_vec = satgen.importDefSigSpec(module->wires_.at("\\y")); + std::vector<int> y_vec = satgen.importDefSigSpec(module->wire("\\y")); std::vector<bool> y_values; if (model_undef) { - std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wires_.at("\\y")); + std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wire("\\y")); y_vec.insert(y_vec.end(), y_undef_vec.begin(), y_undef_vec.end()); } @@ -253,7 +252,7 @@ struct VlogHammerReporter std::vector<RTLIL::State> bits(patterns[idx].bits.begin(), patterns[idx].bits.begin() + total_input_width); for (int i = 0; i < int(inputs.size()); i++) { - RTLIL::Wire *wire = module->wires_.at(inputs[i]); + RTLIL::Wire *wire = module->wire(inputs[i]); for (int j = input_widths[i]-1; j >= 0; j--) { ce.set(RTLIL::SigSpec(wire, j), bits.back()); recorded_set_vars.append(RTLIL::SigSpec(wire, j)); @@ -263,21 +262,21 @@ struct VlogHammerReporter if (module == modules.front()) { RTLIL::SigSpec sig(wire); if (!ce.eval(sig)) - log_error("Can't read back value for port %s!\n", RTLIL::id2cstr(inputs[i])); + log_error("Can't read back value for port %s!\n", log_id(inputs[i])); input_pattern_list += stringf(" %s", sig.as_const().as_string().c_str()); - log("++PAT++ %d %s %s #\n", idx, RTLIL::id2cstr(inputs[i]), sig.as_const().as_string().c_str()); + log("++PAT++ %d %s %s #\n", idx, log_id(inputs[i]), sig.as_const().as_string().c_str()); } } - if (module->wires_.count("\\y") == 0) - log_error("No output wire (y) found in module %s!\n", RTLIL::id2cstr(module->name)); + if (module->wire("\\y") == nullptr) + log_error("No output wire (y) found in module %s!\n", log_id(module->name)); - RTLIL::SigSpec sig(module->wires_.at("\\y")); + RTLIL::SigSpec sig(module->wire("\\y")); RTLIL::SigSpec undef; while (!ce.eval(sig, undef)) { - // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", RTLIL::id2cstr(module->name), log_signal(sig), log_signal(undef)); - log_warning("Setting signal %s in module %s to undef.\n", log_signal(undef), RTLIL::id2cstr(module->name)); + // log_error("Evaluation of y in module %s failed: sig=%s, undef=%s\n", log_id(module->name), log_signal(sig), log_signal(undef)); + log_warning("Setting signal %s in module %s to undef.\n", log_signal(undef), log_id(module->name)); ce.set(undef, RTLIL::Const(RTLIL::State::Sx, undef.size())); } @@ -289,7 +288,7 @@ struct VlogHammerReporter sat_check(module, recorded_set_vars, recorded_set_vals, sig, true); } else if (rtl_sig.size() > 0) { if (rtl_sig.size() != sig.size()) - log_error("Output (y) has a different width in module %s compared to rtl!\n", RTLIL::id2cstr(module->name)); + log_error("Output (y) has a different width in module %s compared to rtl!\n", log_id(module->name)); for (int i = 0; i < GetSize(sig); i++) if (rtl_sig[i] == RTLIL::State::Sx) sig[i] = RTLIL::State::Sx; @@ -307,10 +306,10 @@ struct VlogHammerReporter { for (auto name : split(module_list, ",")) { RTLIL::IdString esc_name = RTLIL::escape_id(module_prefix + name); - if (design->modules_.count(esc_name) == 0) + if (design->module(esc_name) == nullptr) log_error("Can't find module %s in current design!\n", name.c_str()); log("Using module %s (%s).\n", esc_name.c_str(), name.c_str()); - modules.push_back(design->modules_.at(esc_name)); + modules.push_back(design->module(esc_name)); module_names.push_back(name); } @@ -319,11 +318,11 @@ struct VlogHammerReporter int width = -1; RTLIL::IdString esc_name = RTLIL::escape_id(name); for (auto mod : modules) { - if (mod->wires_.count(esc_name) == 0) - log_error("Can't find input %s in module %s!\n", name.c_str(), RTLIL::id2cstr(mod->name)); - RTLIL::Wire *port = mod->wires_.at(esc_name); + if (mod->wire(esc_name) == nullptr) + log_error("Can't find input %s in module %s!\n", name.c_str(), log_id(mod->name)); + RTLIL::Wire *port = mod->wire(esc_name); if (!port->port_input || port->port_output) - log_error("Wire %s in module %s is not an input!\n", name.c_str(), RTLIL::id2cstr(mod->name)); + log_error("Wire %s in module %s is not an input!\n", name.c_str(), log_id(mod->name)); if (width >= 0 && width != port->width) log_error("Port %s has different sizes in the different modules!\n", name.c_str()); width = port->width; @@ -415,11 +414,11 @@ struct EvalPass : public Pass { /* this should only be used for regression testing of ConstEval -- see vloghammer */ std::string mod1_name = RTLIL::escape_id(args[++argidx]); std::string mod2_name = RTLIL::escape_id(args[++argidx]); - if (design->modules_.count(mod1_name) == 0) + if (design->module(mod1_name) == nullptr) log_error("Can't find module `%s'!\n", mod1_name.c_str()); - if (design->modules_.count(mod2_name) == 0) + if (design->module(mod2_name) == nullptr) log_error("Can't find module `%s'!\n", mod2_name.c_str()); - BruteForceEquivChecker checker(design->modules_.at(mod1_name), design->modules_.at(mod2_name), args[argidx-2] == "-brute_force_equiv_checker_x"); + BruteForceEquivChecker checker(design->module(mod1_name), design->module(mod2_name), args[argidx-2] == "-brute_force_equiv_checker_x"); if (checker.errors > 0) log_cmd_error("Modules are not equivalent!\n"); log("Verified %s = %s (using brute-force check on %d cases).\n", @@ -441,13 +440,12 @@ struct EvalPass : public Pass { extra_args(args, argidx, design); RTLIL::Module *module = NULL; - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) { - if (module) - log_cmd_error("Only one module must be selected for the EVAL pass! (selected: %s and %s)\n", - RTLIL::id2cstr(module->name), RTLIL::id2cstr(mod_it.first)); - module = mod_it.second; - } + for (auto mod : design->selected_modules()) { + if (module) + log_cmd_error("Only one module must be selected for the EVAL pass! (selected: %s and %s)\n", + log_id(module->name), log_id(mod->name)); + module = mod; + } if (module == NULL) log_cmd_error("Can't perform EVAL on an empty selection!\n"); @@ -468,9 +466,9 @@ struct EvalPass : public Pass { } if (shows.size() == 0) { - for (auto &it : module->wires_) - if (it.second->port_output) - shows.push_back(it.second->name.str()); + for (auto w : module->wires()) + if (w->port_output) + shows.push_back(w->name.str()); } if (tables.empty()) diff --git a/passes/sat/expose.cc b/passes/sat/expose.cc index 29dfc7b19..8fb47f357 100644 --- a/passes/sat/expose.cc +++ b/passes/sat/expose.cc @@ -53,7 +53,7 @@ bool consider_cell(RTLIL::Design *design, std::set<RTLIL::IdString> &dff_cells, { if (cell->name[0] == '$' || dff_cells.count(cell->name)) return false; - if (cell->type[0] == '\\' && !design->modules_.count(cell->type)) + if (cell->type[0] == '\\' && (design->module(cell->type) == nullptr)) return false; return true; } @@ -85,27 +85,24 @@ void find_dff_wires(std::set<RTLIL::IdString> &dff_wires, RTLIL::Module *module) SigMap sigmap(module); SigPool dffsignals; - for (auto &it : module->cells_) { - if (ct.cell_known(it.second->type) && it.second->hasPort("\\Q")) - dffsignals.add(sigmap(it.second->getPort("\\Q"))); + for (auto cell : module->cells()) { + if (ct.cell_known(cell->type) && cell->hasPort("\\Q")) + dffsignals.add(sigmap(cell->getPort("\\Q"))); } - for (auto &it : module->wires_) { - if (dffsignals.check_any(it.second)) - dff_wires.insert(it.first); + for (auto w : module->wires()) { + if (dffsignals.check_any(w)) + dff_wires.insert(w->name); } } -void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Design *design, RTLIL::Module *module) +void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Module *module) { std::map<RTLIL::SigBit, dff_map_bit_info_t> bit_info; SigMap sigmap(module); - for (auto &it : module->cells_) + for (auto cell : module->selected_cells()) { - if (!design->selected(module, it.second)) - continue; - dff_map_bit_info_t info; info.bit_d = RTLIL::State::Sm; info.bit_clk = RTLIL::State::Sm; @@ -113,7 +110,7 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::De info.clk_polarity = false; info.arst_polarity = false; info.arst_value = RTLIL::State::Sm; - info.cell = it.second; + info.cell = cell; if (info.cell->type == "$dff") { info.bit_clk = sigmap(info.cell->getPort("\\CLK")).as_bit(); @@ -164,12 +161,12 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::De } std::map<RTLIL::IdString, dff_map_info_t> empty_dq_map; - for (auto &it : module->wires_) + for (auto w : module->wires()) { - if (!consider_wire(it.second, empty_dq_map)) + if (!consider_wire(w, empty_dq_map)) continue; - std::vector<RTLIL::SigBit> bits_q = sigmap(it.second).to_sigbit_vector(); + std::vector<RTLIL::SigBit> bits_q = sigmap(w).to_sigbit_vector(); std::vector<RTLIL::SigBit> bits_d; std::vector<RTLIL::State> arst_value; std::set<RTLIL::Cell*> cells; @@ -207,7 +204,7 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::De info.arst_value = arst_value; for (auto it : cells) info.cells.push_back(it->name); - map[it.first] = info; + map[w->name] = info; } } @@ -314,26 +311,23 @@ struct ExposePass : public Pass { RTLIL::Module *first_module = NULL; std::set<RTLIL::IdString> shared_dff_wires; - for (auto &mod_it : design->modules_) + for (auto mod : design->selected_modules()) { - if (!design->selected(mod_it.second)) - continue; - - create_dff_dq_map(dff_dq_maps[mod_it.second], design, mod_it.second); + create_dff_dq_map(dff_dq_maps[mod], mod); if (!flag_shared) continue; if (first_module == NULL) { - for (auto &it : dff_dq_maps[mod_it.second]) + for (auto &it : dff_dq_maps[mod]) shared_dff_wires.insert(it.first); - first_module = mod_it.second; + first_module = mod; } else { std::set<RTLIL::IdString> new_shared_dff_wires; for (auto &it : shared_dff_wires) { - if (!dff_dq_maps[mod_it.second].count(it)) + if (!dff_dq_maps[mod].count(it)) continue; - if (!compare_wires(first_module->wires_.at(it), mod_it.second->wires_.at(it))) + if (!compare_wires(first_module->wire(it), mod->wire(it))) continue; new_shared_dff_wires.insert(it); } @@ -364,28 +358,23 @@ struct ExposePass : public Pass { { RTLIL::Module *first_module = NULL; - for (auto &mod_it : design->modules_) + for (auto module : design->selected_modules()) { - RTLIL::Module *module = mod_it.second; - - if (!design->selected(module)) - continue; - std::set<RTLIL::IdString> dff_wires; if (flag_dff) find_dff_wires(dff_wires, module); if (first_module == NULL) { - for (auto &it : module->wires_) - if (design->selected(module, it.second) && consider_wire(it.second, dff_dq_maps[module])) - if (!flag_dff || dff_wires.count(it.first)) - shared_wires.insert(it.first); + for (auto w : module->wires()) + if (design->selected(module, w) && consider_wire(w, dff_dq_maps[module])) + if (!flag_dff || dff_wires.count(w->name)) + shared_wires.insert(w->name); if (flag_evert) - for (auto &it : module->cells_) - if (design->selected(module, it.second) && consider_cell(design, dff_cells[module], it.second)) - shared_cells.insert(it.first); + for (auto cell : module->cells()) + if (design->selected(module, cell) && consider_cell(design, dff_cells[module], cell)) + shared_cells.insert(cell->name); first_module = module; } @@ -397,16 +386,16 @@ struct ExposePass : public Pass { { RTLIL::Wire *wire; - if (module->wires_.count(it) == 0) + if (module->wire(it) == nullptr) goto delete_shared_wire; - wire = module->wires_.at(it); + wire = module->wire(it); if (!design->selected(module, wire)) goto delete_shared_wire; if (!consider_wire(wire, dff_dq_maps[module])) goto delete_shared_wire; - if (!compare_wires(first_module->wires_.at(it), wire)) + if (!compare_wires(first_module->wire(it), wire)) goto delete_shared_wire; if (flag_dff && !dff_wires.count(it)) goto delete_shared_wire; @@ -421,16 +410,16 @@ struct ExposePass : public Pass { { RTLIL::Cell *cell; - if (module->cells_.count(it) == 0) + if (module->cell(it) == nullptr) goto delete_shared_cell; - cell = module->cells_.at(it); + cell = module->cell(it); if (!design->selected(module, cell)) goto delete_shared_cell; if (!consider_cell(design, dff_cells[module], cell)) goto delete_shared_cell; - if (!compare_cells(first_module->cells_.at(it), cell)) + if (!compare_cells(first_module->cell(it), cell)) goto delete_shared_cell; if (0) @@ -446,13 +435,8 @@ struct ExposePass : public Pass { } } - for (auto &mod_it : design->modules_) + for (auto module : design->selected_modules()) { - RTLIL::Module *module = mod_it.second; - - if (!design->selected(module)) - continue; - std::set<RTLIL::IdString> dff_wires; if (flag_dff && !flag_shared) find_dff_wires(dff_wires, module); @@ -461,49 +445,49 @@ struct ExposePass : public Pass { SigMap out_to_in_map; - for (auto &it : module->wires_) + for (auto w : module->wires()) { if (flag_shared) { - if (shared_wires.count(it.first) == 0) + if (shared_wires.count(w->name) == 0) continue; } else { - if (!design->selected(module, it.second) || !consider_wire(it.second, dff_dq_maps[module])) + if (!design->selected(module, w) || !consider_wire(w, dff_dq_maps[module])) continue; - if (flag_dff && !dff_wires.count(it.first)) + if (flag_dff && !dff_wires.count(w->name)) continue; } if (flag_input) { - if (!it.second->port_input) { - it.second->port_input = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it.second->name)); - RTLIL::Wire *w = module->addWire(NEW_ID, GetSize(it.second)); - out_to_in_map.add(it.second, w); + if (!w->port_input) { + w->port_input = true; + log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); + RTLIL::Wire *in_wire = module->addWire(NEW_ID, GetSize(w)); + out_to_in_map.add(w, in_wire); } } else { - if (!it.second->port_output) { - it.second->port_output = true; - log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it.second->name)); + if (!w->port_output) { + w->port_output = true; + log("New module port: %s/%s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(w->name)); } if (flag_cut) { - RTLIL::Wire *in_wire = add_new_wire(module, it.second->name.str() + sep + "i", it.second->width); + RTLIL::Wire *in_wire = add_new_wire(module, w->name.str() + sep + "i", w->width); in_wire->port_input = true; - out_to_in_map.add(sigmap(it.second), in_wire); + out_to_in_map.add(sigmap(w), in_wire); } } } if (flag_input) { - for (auto &it : module->cells_) { - if (!ct.cell_known(it.second->type)) + for (auto cell : module->cells()) { + if (!ct.cell_known(cell->type)) continue; - for (auto &conn : it.second->connections_) - if (ct.cell_output(it.second->type, conn.first)) + for (auto &conn : cell->connections_) + if (ct.cell_output(cell->type, conn.first)) conn.second = out_to_in_map(sigmap(conn.second)); } @@ -513,11 +497,11 @@ struct ExposePass : public Pass { if (flag_cut) { - for (auto &it : module->cells_) { - if (!ct.cell_known(it.second->type)) + for (auto cell : module->cells()) { + if (!ct.cell_known(cell->type)) continue; - for (auto &conn : it.second->connections_) - if (ct.cell_input(it.second->type, conn.first)) + for (auto &conn : cell->connections_) + if (ct.cell_input(cell->type, conn.first)) conn.second = out_to_in_map(sigmap(conn.second)); } @@ -529,10 +513,10 @@ struct ExposePass : public Pass { for (auto &dq : dff_dq_maps[module]) { - if (!module->wires_.count(dq.first)) + if (module->wire(dq.first) == nullptr) continue; - RTLIL::Wire *wire = module->wires_.at(dq.first); + RTLIL::Wire *wire = module->wire(dq.first); std::set<RTLIL::SigBit> wire_bits_set = sigmap(wire).to_sigbit_set(); std::vector<RTLIL::SigBit> wire_bits_vec = sigmap(wire).to_sigbit_vector(); @@ -541,7 +525,7 @@ struct ExposePass : public Pass { RTLIL::Wire *wire_dummy_q = add_new_wire(module, NEW_ID, 0); for (auto &cell_name : info.cells) { - RTLIL::Cell *cell = module->cells_.at(cell_name); + RTLIL::Cell *cell = module->cell(cell_name); std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->getPort("\\Q")).to_sigbit_vector(); for (auto &bit : cell_q_bits) if (wire_bits_set.count(bit)) @@ -609,25 +593,22 @@ struct ExposePass : public Pass { { std::vector<RTLIL::Cell*> delete_cells; - for (auto &it : module->cells_) + for (auto cell : module->cells()) { if (flag_shared) { - if (shared_cells.count(it.first) == 0) + if (shared_cells.count(cell->name) == 0) continue; } else { - if (!design->selected(module, it.second) || !consider_cell(design, dff_cells[module], it.second)) + if (!design->selected(module, cell) || !consider_cell(design, dff_cells[module], cell)) continue; } - RTLIL::Cell *cell = it.second; - - if (design->modules_.count(cell->type)) + if (design->module(cell->type) != nullptr) { - RTLIL::Module *mod = design->modules_.at(cell->type); + RTLIL::Module *mod = design->module(cell->type); - for (auto &it : mod->wires_) + for (auto p : mod->wires()) { - RTLIL::Wire *p = it.second; if (!p->port_input && !p->port_output) continue; diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index f29631639..54016e528 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -614,29 +614,29 @@ struct FreduceWorker int bits_full_total = 0; std::vector<std::set<RTLIL::SigBit>> batches; - for (auto &it : module->wires_) - if (it.second->port_input) { - batches.push_back(sigmap(it.second).to_sigbit_set()); - bits_full_total += it.second->width; + for (auto w : module->wires()) + if (w->port_input) { + batches.push_back(sigmap(w).to_sigbit_set()); + bits_full_total += w->width; } - for (auto &it : module->cells_) { - if (ct.cell_known(it.second->type)) { + for (auto cell : module->cells()) { + if (ct.cell_known(cell->type)) { std::set<RTLIL::SigBit> inputs, outputs; - for (auto &port : it.second->connections()) { + for (auto &port : cell->connections()) { std::vector<RTLIL::SigBit> bits = sigmap(port.second).to_sigbit_vector(); - if (ct.cell_output(it.second->type, port.first)) + if (ct.cell_output(cell->type, port.first)) outputs.insert(bits.begin(), bits.end()); else inputs.insert(bits.begin(), bits.end()); } - std::pair<RTLIL::Cell*, std::set<RTLIL::SigBit>> drv(it.second, inputs); + std::pair<RTLIL::Cell*, std::set<RTLIL::SigBit>> drv(cell, inputs); for (auto &bit : outputs) drivers[bit] = drv; batches.push_back(outputs); bits_full_total += outputs.size(); } - if (inv_mode && it.second->type == "$_NOT_") - inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(it.second->getPort("\\A")), sigmap(it.second->getPort("\\Y")))); + if (inv_mode && cell->type == "$_NOT_") + inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(cell->getPort("\\A")), sigmap(cell->getPort("\\Y")))); } int bits_count = 0; @@ -828,10 +828,8 @@ struct FreducePass : public Pass { extra_args(args, argidx, design); int bitcount = 0; - for (auto &mod_it : design->modules_) { - RTLIL::Module *module = mod_it.second; - if (design->selected(module)) - bitcount += FreduceWorker(design, module).run(); + for (auto module : design->selected_modules()) { + bitcount += FreduceWorker(design, module).run(); } log("Rewired a total of %d signal bits.\n", bitcount); diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index 49ef40061..742433935 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -66,50 +66,48 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: RTLIL::IdString gate_name = RTLIL::escape_id(args[argidx++]); RTLIL::IdString miter_name = RTLIL::escape_id(args[argidx++]); - if (design->modules_.count(gold_name) == 0) + if (design->module(gold_name) == nullptr) log_cmd_error("Can't find gold module %s!\n", gold_name.c_str()); - if (design->modules_.count(gate_name) == 0) + if (design->module(gate_name) == nullptr) log_cmd_error("Can't find gate module %s!\n", gate_name.c_str()); - if (design->modules_.count(miter_name) != 0) + if (design->module(miter_name) != nullptr) log_cmd_error("There is already a module %s!\n", miter_name.c_str()); - RTLIL::Module *gold_module = design->modules_.at(gold_name); - RTLIL::Module *gate_module = design->modules_.at(gate_name); + RTLIL::Module *gold_module = design->module(gold_name); + RTLIL::Module *gate_module = design->module(gate_name); - for (auto &it : gold_module->wires_) { - RTLIL::Wire *w1 = it.second, *w2; - if (w1->port_id == 0) + for (auto gold_wire : gold_module->wires()) { + if (gold_wire->port_id == 0) continue; - if (gate_module->wires_.count(it.second->name) == 0) + RTLIL::Wire *gate_wire = gate_module->wire(gold_wire->name); + if (gate_wire == nullptr) goto match_gold_port_error; - w2 = gate_module->wires_.at(it.second->name); - if (w1->port_input != w2->port_input) + if (gold_wire->port_input != gate_wire->port_input) goto match_gold_port_error; - if (w1->port_output != w2->port_output) + if (gold_wire->port_output != gate_wire->port_output) goto match_gold_port_error; - if (w1->width != w2->width) + if (gold_wire->width != gate_wire->width) goto match_gold_port_error; continue; match_gold_port_error: - log_cmd_error("No matching port in gate module was found for %s!\n", it.second->name.c_str()); + log_cmd_error("No matching port in gate module was found for %s!\n", gold_wire->name.c_str()); } - for (auto &it : gate_module->wires_) { - RTLIL::Wire *w1 = it.second, *w2; - if (w1->port_id == 0) + for (auto gate_wire : gate_module->wires()) { + if (gate_wire->port_id == 0) continue; - if (gold_module->wires_.count(it.second->name) == 0) + RTLIL::Wire *gold_wire = gold_module->wire(gate_wire->name); + if (gold_wire == nullptr) goto match_gate_port_error; - w2 = gold_module->wires_.at(it.second->name); - if (w1->port_input != w2->port_input) + if (gate_wire->port_input != gold_wire->port_input) goto match_gate_port_error; - if (w1->port_output != w2->port_output) + if (gate_wire->port_output != gold_wire->port_output) goto match_gate_port_error; - if (w1->width != w2->width) + if (gate_wire->width != gold_wire->width) goto match_gate_port_error; continue; match_gate_port_error: - log_cmd_error("No matching port in gold module was found for %s!\n", it.second->name.c_str()); + log_cmd_error("No matching port in gold module was found for %s!\n", gate_wire->name.c_str()); } log("Creating miter cell \"%s\" with gold cell \"%s\" and gate cell \"%s\".\n", RTLIL::id2cstr(miter_name), RTLIL::id2cstr(gold_name), RTLIL::id2cstr(gate_name)); @@ -123,73 +121,71 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: RTLIL::SigSpec all_conditions; - for (auto &it : gold_module->wires_) + for (auto gold_wire : gold_module->wires()) { - RTLIL::Wire *w1 = it.second; - - if (w1->port_input) + if (gold_wire->port_input) { - RTLIL::Wire *w2 = miter_module->addWire("\\in_" + RTLIL::unescape_id(w1->name), w1->width); - w2->port_input = true; + RTLIL::Wire *w = miter_module->addWire("\\in_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + w->port_input = true; - gold_cell->setPort(w1->name, w2); - gate_cell->setPort(w1->name, w2); + gold_cell->setPort(gold_wire->name, w); + gate_cell->setPort(gold_wire->name, w); } - if (w1->port_output) + if (gold_wire->port_output) { - RTLIL::Wire *w2_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(w1->name), w1->width); - w2_gold->port_output = flag_make_outputs; + RTLIL::Wire *w_gold = miter_module->addWire("\\gold_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + w_gold->port_output = flag_make_outputs; - RTLIL::Wire *w2_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(w1->name), w1->width); - w2_gate->port_output = flag_make_outputs; + RTLIL::Wire *w_gate = miter_module->addWire("\\gate_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + w_gate->port_output = flag_make_outputs; - gold_cell->setPort(w1->name, w2_gold); - gate_cell->setPort(w1->name, w2_gate); + gold_cell->setPort(gold_wire->name, w_gold); + gate_cell->setPort(gold_wire->name, w_gate); RTLIL::SigSpec this_condition; if (flag_ignore_gold_x) { - RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w2_gold->width); - for (int i = 0; i < w2_gold->width; i++) { + RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w_gold->width); + for (int i = 0; i < w_gold->width; i++) { RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx"); eqx_cell->parameters["\\A_WIDTH"] = 1; eqx_cell->parameters["\\B_WIDTH"] = 1; eqx_cell->parameters["\\Y_WIDTH"] = 1; eqx_cell->parameters["\\A_SIGNED"] = 0; eqx_cell->parameters["\\B_SIGNED"] = 0; - eqx_cell->setPort("\\A", RTLIL::SigSpec(w2_gold, i)); + eqx_cell->setPort("\\A", RTLIL::SigSpec(w_gold, i)); eqx_cell->setPort("\\B", RTLIL::State::Sx); eqx_cell->setPort("\\Y", gold_x.extract(i, 1)); } - RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w2_gold->width); - RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w2_gate->width); + RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w_gold->width); + RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w_gate->width); RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or"); - or_gold_cell->parameters["\\A_WIDTH"] = w2_gold->width; - or_gold_cell->parameters["\\B_WIDTH"] = w2_gold->width; - or_gold_cell->parameters["\\Y_WIDTH"] = w2_gold->width; + or_gold_cell->parameters["\\A_WIDTH"] = w_gold->width; + or_gold_cell->parameters["\\B_WIDTH"] = w_gold->width; + or_gold_cell->parameters["\\Y_WIDTH"] = w_gold->width; or_gold_cell->parameters["\\A_SIGNED"] = 0; or_gold_cell->parameters["\\B_SIGNED"] = 0; - or_gold_cell->setPort("\\A", w2_gold); + or_gold_cell->setPort("\\A", w_gold); or_gold_cell->setPort("\\B", gold_x); or_gold_cell->setPort("\\Y", gold_masked); RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or"); - or_gate_cell->parameters["\\A_WIDTH"] = w2_gate->width; - or_gate_cell->parameters["\\B_WIDTH"] = w2_gate->width; - or_gate_cell->parameters["\\Y_WIDTH"] = w2_gate->width; + or_gate_cell->parameters["\\A_WIDTH"] = w_gate->width; + or_gate_cell->parameters["\\B_WIDTH"] = w_gate->width; + or_gate_cell->parameters["\\Y_WIDTH"] = w_gate->width; or_gate_cell->parameters["\\A_SIGNED"] = 0; or_gate_cell->parameters["\\B_SIGNED"] = 0; - or_gate_cell->setPort("\\A", w2_gate); + or_gate_cell->setPort("\\A", w_gate); or_gate_cell->setPort("\\B", gold_x); or_gate_cell->setPort("\\Y", gate_masked); RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); - eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; - eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; + eq_cell->parameters["\\A_WIDTH"] = w_gold->width; + eq_cell->parameters["\\B_WIDTH"] = w_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; @@ -201,20 +197,20 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: else { RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx"); - eq_cell->parameters["\\A_WIDTH"] = w2_gold->width; - eq_cell->parameters["\\B_WIDTH"] = w2_gate->width; + eq_cell->parameters["\\A_WIDTH"] = w_gold->width; + eq_cell->parameters["\\B_WIDTH"] = w_gate->width; eq_cell->parameters["\\Y_WIDTH"] = 1; eq_cell->parameters["\\A_SIGNED"] = 0; eq_cell->parameters["\\B_SIGNED"] = 0; - eq_cell->setPort("\\A", w2_gold); - eq_cell->setPort("\\B", w2_gate); + eq_cell->setPort("\\A", w_gold); + eq_cell->setPort("\\B", w_gate); eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID)); this_condition = eq_cell->getPort("\\Y"); } if (flag_make_outcmp) { - RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(w1->name)); + RTLIL::Wire *w_cmp = miter_module->addWire("\\cmp_" + RTLIL::unescape_id(gold_wire->name)); w_cmp->port_output = true; miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } @@ -285,9 +281,9 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL IdString module_name = RTLIL::escape_id(args[argidx++]); IdString miter_name = argidx < args.size() ? RTLIL::escape_id(args[argidx++]) : ""; - if (design->modules_.count(module_name) == 0) + if (design->module(module_name) == nullptr) log_cmd_error("Can't find module %s!\n", module_name.c_str()); - if (!miter_name.empty() && design->modules_.count(miter_name) != 0) + if (!miter_name.empty() && design->module(miter_name) != nullptr) log_cmd_error("There is already a module %s!\n", miter_name.c_str()); Module *module = design->module(module_name); diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index f63012d1a..8b1862237 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -308,7 +308,9 @@ struct IopadmapPass : public Pass { { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, tinoutpad_celltype.c_str()); - Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(tinoutpad_celltype)); + Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + RTLIL::escape_id(tinoutpad_celltype)); cell->setPort(RTLIL::escape_id(tinoutpad_portname_oe), en_sig); cell->attributes[ID::keep] = RTLIL::Const(1); @@ -328,7 +330,9 @@ struct IopadmapPass : public Pass { } else { log("Mapping port %s.%s[%d] using %s.\n", log_id(module), log_id(wire), i, toutpad_celltype.c_str()); - Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(toutpad_celltype)); + Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s[%d]", log_id(module), log_id(wire), i)), + RTLIL::escape_id(toutpad_celltype)); cell->setPort(RTLIL::escape_id(toutpad_portname_oe), en_sig); cell->setPort(RTLIL::escape_id(toutpad_portname_i), data_sig); @@ -406,7 +410,9 @@ struct IopadmapPass : public Pass { SigBit wire_bit(wire, i); - RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); + RTLIL::Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), wire_bit); if (!portname_pad.empty()) @@ -420,12 +426,16 @@ struct IopadmapPass : public Pass { } else { - RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); + RTLIL::Cell *cell = module->addCell( + module->uniquify(stringf("$iopadmap$%s.%s", log_id(module->name), log_id(wire->name))), + RTLIL::escape_id(celltype)); cell->setPort(RTLIL::escape_id(portname_int), RTLIL::SigSpec(wire)); if (!portname_pad.empty()) { RTLIL::Wire *new_wire = NULL; - new_wire = module->addWire(NEW_ID, wire); + new_wire = module->addWire( + module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + wire); module->swap_names(new_wire, wire); wire->attributes.clear(); cell->setPort(RTLIL::escape_id(portname_pad), RTLIL::SigSpec(new_wire)); @@ -446,7 +456,9 @@ struct IopadmapPass : public Pass { for (auto &it : rewrite_bits) { RTLIL::Wire *wire = it.first; - RTLIL::Wire *new_wire = module->addWire(NEW_ID, wire); + RTLIL::Wire *new_wire = module->addWire( + module->uniquify(stringf("$iopadmap$%s", log_id(wire))), + wire); module->swap_names(new_wire, wire); wire->attributes.clear(); for (int i = 0; i < wire->width; i++) diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc index 0c57733d4..10001baaa 100644 --- a/passes/techmap/techmap.cc +++ b/passes/techmap/techmap.cc @@ -177,10 +177,10 @@ struct TechmapWorker std::string orig_cell_name; pool<string> extra_src_attrs = cell->get_strpool_attribute(ID(src)); + orig_cell_name = cell->name.str(); if (!flatten_mode) { for (auto &it : tpl->cells_) if (it.first == ID(_TECHMAP_REPLACE_)) { - orig_cell_name = cell->name.str(); module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str()); break; } |