diff options
Diffstat (limited to 'passes/cmds')
-rw-r--r-- | passes/cmds/Makefile.inc | 2 | ||||
-rw-r--r-- | passes/cmds/add.cc | 101 | ||||
-rw-r--r-- | passes/cmds/blackbox.cc | 2 | ||||
-rw-r--r-- | passes/cmds/bugpoint.cc | 32 | ||||
-rw-r--r-- | passes/cmds/check.cc | 51 | ||||
-rw-r--r-- | passes/cmds/chformal.cc | 82 | ||||
-rw-r--r-- | passes/cmds/connect.cc | 26 | ||||
-rw-r--r-- | passes/cmds/connwrappers.cc | 22 | ||||
-rw-r--r-- | passes/cmds/copy.cc | 4 | ||||
-rw-r--r-- | passes/cmds/delete.cc | 43 | ||||
-rw-r--r-- | passes/cmds/design.cc | 84 | ||||
-rw-r--r-- | passes/cmds/exec.cc | 205 | ||||
-rw-r--r-- | passes/cmds/logger.cc | 183 | ||||
-rw-r--r-- | passes/cmds/qwp.cc | 2 | ||||
-rw-r--r-- | passes/cmds/select.cc | 376 | ||||
-rw-r--r-- | passes/cmds/setattr.cc | 40 | ||||
-rw-r--r-- | passes/cmds/setundef.cc | 39 | ||||
-rw-r--r-- | passes/cmds/show.cc | 117 | ||||
-rw-r--r-- | passes/cmds/splice.cc | 60 | ||||
-rw-r--r-- | passes/cmds/splitnets.cc | 17 | ||||
-rw-r--r-- | passes/cmds/stat.cc | 80 | ||||
-rw-r--r-- | passes/cmds/torder.cc | 4 | ||||
-rw-r--r-- | passes/cmds/trace.cc | 2 |
23 files changed, 983 insertions, 591 deletions
diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 07a5d3ddc..60f20fa6d 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -1,4 +1,5 @@ +OBJS += passes/cmds/exec.o OBJS += passes/cmds/add.o OBJS += passes/cmds/delete.o OBJS += passes/cmds/design.o @@ -33,3 +34,4 @@ OBJS += passes/cmds/blackbox.o OBJS += passes/cmds/ltp.o OBJS += passes/cmds/bugpoint.o OBJS += passes/cmds/scratchpad.o +OBJS += passes/cmds/logger.o diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index dd05ac81f..91f8c2add 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -22,26 +22,61 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static bool is_formal_celltype(const std::string &celltype) +{ + if(celltype == "assert" || celltype == "assume" || celltype == "live" || celltype == "fair" || celltype == "cover") + return true; + else + return false; +} + +static void add_formal(RTLIL::Module *module, const std::string &celltype, const std::string &name, const std::string &enable_name) +{ + std::string escaped_name = RTLIL::escape_id(name); + std::string escaped_enable_name = (enable_name != "") ? RTLIL::escape_id(enable_name) : ""; + RTLIL::Wire *wire = module->wire(escaped_name); + log_assert(is_formal_celltype(celltype)); + + if (wire == nullptr) { + log_error("Could not find wire with name \"%s\".\n", name.c_str()); + } + else { + RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype); + formal_cell->setPort(ID::A, wire); + if(enable_name == "") { + formal_cell->setPort(ID::EN, State::S1); + log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str()); + } + else { + RTLIL::Wire *enable_wire = module->wire(escaped_enable_name); + if(enable_wire == nullptr) + log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str()); + + formal_cell->setPort(ID::EN, enable_wire); + log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str()); + } + } +} + static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output, bool flag_global) { - RTLIL::Wire *wire = NULL; + RTLIL::Wire *wire = nullptr; name = RTLIL::escape_id(name); if (module->count_id(name) != 0) { - if (module->wires_.count(name) > 0) - wire = module->wires_.at(name); + wire = module->wire(name); - if (wire != NULL && wire->width != width) - wire = NULL; + if (wire != nullptr && wire->width != width) + wire = nullptr; - if (wire != NULL && wire->port_input != flag_input) - wire = NULL; + if (wire != nullptr && wire->port_input != flag_input) + wire = nullptr; - if (wire != NULL && wire->port_output != flag_output) - wire = NULL; + if (wire != nullptr && wire->port_output != flag_output) + wire = nullptr; - if (wire == NULL) + if (wire == nullptr) log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str()); log("Module %s already has such an object.\n", module->name.c_str()); @@ -53,7 +88,6 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n wire->port_output = flag_output; if (flag_input || flag_output) { - wire->port_id = module->wires_.size(); module->fixup_ports(); } @@ -63,21 +97,20 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n if (!flag_global) return; - for (auto &it : module->cells_) + for (auto cell : module->cells()) { - if (design->modules_.count(it.second->type) == 0) + RTLIL::Module *mod = design->module(cell->type); + if (mod == nullptr) continue; - - RTLIL::Module *mod = design->modules_.at(it.second->type); if (!design->selected_whole_module(mod->name)) continue; if (mod->get_blackbox_attribute()) continue; - if (it.second->hasPort(name)) + if (cell->hasPort(name)) continue; - it.second->setPort(name, wire); - log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), it.first.c_str(), it.second->type.c_str()); + cell->setPort(name, wire); + log("Added connection %s to cell %s.%s (%s).\n", name.c_str(), module->name.c_str(), cell->name.c_str(), cell->type.c_str()); } } @@ -106,6 +139,12 @@ struct AddPass : public Pass { log("selected modules.\n"); log("\n"); log("\n"); + log(" add {-assert|-assume|-live|-fair|-cover} <name1> [-if <name2>]\n"); + log("\n"); + log("Add an $assert, $assume, etc. cell connected to a wire named name1, with its\n"); + log("enable signal optionally connected to a wire named name2 (default: 1'b1).\n"); + log("\n"); + log("\n"); log(" add -mod <name[s]>\n"); log("\n"); log("Add module[s] with the specified name[s].\n"); @@ -115,6 +154,7 @@ struct AddPass : public Pass { { std::string command; std::string arg_name; + std::string enable_name = ""; bool arg_flag_input = false; bool arg_flag_output = false; bool arg_flag_global = false; @@ -144,6 +184,17 @@ struct AddPass : public Pass { argidx++; break; } + if (arg.length() > 0 && arg[0] == '-' && is_formal_celltype(arg.substr(1))) { + if (argidx + 1 >= args.size()) + break; + command = arg.substr(1); + arg_name = args[++argidx]; + if (argidx + 2 < args.size() && args[argidx + 1] == "-if") { + enable_name = args[argidx + 2]; + argidx += 2; + } + continue; + } break; } @@ -155,17 +206,23 @@ struct AddPass : public Pass { extra_args(args, argidx, design); - for (auto &mod : design->modules_) + bool selected_anything = false; + for (auto module : design->modules()) { - RTLIL::Module *module = mod.second; + log_assert(module != nullptr); if (!design->selected_whole_module(module->name)) continue; - if (module->get_bool_attribute("\\blackbox")) + if (module->get_bool_attribute(ID::blackbox)) continue; - if (command == "wire") + selected_anything = true; + if (is_formal_celltype(command)) + add_formal(module, command, arg_name, enable_name); + else if (command == "wire") add_wire(design, module, arg_name, arg_width, arg_flag_input, arg_flag_output, arg_flag_global); } + if (!selected_anything) + log_warning("No modules selected, or only blackboxes. Nothing was added.\n"); } } AddPass; diff --git a/passes/cmds/blackbox.cc b/passes/cmds/blackbox.cc index d09ed872e..5c0405f15 100644 --- a/passes/cmds/blackbox.cc +++ b/passes/cmds/blackbox.cc @@ -73,7 +73,7 @@ struct BlackboxPass : public Pass { module->remove(remove_wires); - module->set_bool_attribute("\\blackbox"); + module->set_bool_attribute(ID::blackbox); } } } BlackboxPass; diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc index 5a47988ec..ad6a07fa0 100644 --- a/passes/cmds/bugpoint.cc +++ b/passes/cmds/bugpoint.cc @@ -114,8 +114,8 @@ struct BugpointPass : public Pass { return design; RTLIL::Design *design_copy = new RTLIL::Design; - for (auto &it : design->modules_) - design_copy->add(it.second->clone()); + for (auto module : design->modules()) + design_copy->add(module->clone()); Pass::call(design_copy, "proc_clean -quiet"); Pass::call(design_copy, "clean -purge"); @@ -127,21 +127,21 @@ struct BugpointPass : public Pass { RTLIL::Design *simplify_something(RTLIL::Design *design, int &seed, bool stage2, bool modules, bool ports, bool cells, bool connections, bool assigns, bool updates) { RTLIL::Design *design_copy = new RTLIL::Design; - for (auto &it : design->modules_) - design_copy->add(it.second->clone()); + for (auto module : design->modules()) + design_copy->add(module->clone()); int index = 0; if (modules) { - for (auto &it : design_copy->modules_) + for (auto module : design_copy->modules()) { - if (it.second->get_blackbox_attribute()) + if (module->get_blackbox_attribute()) continue; if (index++ == seed) { - log("Trying to remove module %s.\n", it.first.c_str()); - design_copy->remove(it.second); + log("Trying to remove module %s.\n", module->name.c_str()); + design_copy->remove(module); return design_copy; } } @@ -155,7 +155,7 @@ struct BugpointPass : public Pass { for (auto wire : mod->wires()) { - if (!stage2 && wire->get_bool_attribute("$bugpoint")) + if (!stage2 && wire->get_bool_attribute(ID($bugpoint))) continue; if (wire->port_input || wire->port_output) @@ -178,12 +178,12 @@ struct BugpointPass : public Pass { if (mod->get_blackbox_attribute()) continue; - for (auto &it : mod->cells_) + for (auto cell : mod->cells()) { if (index++ == seed) { - log("Trying to remove cell %s.%s.\n", mod->name.c_str(), it.first.c_str()); - mod->remove(it.second); + log("Trying to remove cell %s.%s.\n", mod->name.c_str(), cell->name.c_str()); + mod->remove(cell); return design_copy; } } @@ -220,7 +220,7 @@ struct BugpointPass : public Pass { { log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str()); RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size()); - wire->set_bool_attribute("$bugpoint"); + wire->set_bool_attribute(ID($bugpoint)); wire->port_input = cell->input(it.first); wire->port_output = cell->output(it.first); cell->unsetPort(it.first); @@ -285,7 +285,7 @@ struct BugpointPass : public Pass { } } } - return NULL; + return nullptr; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -433,8 +433,8 @@ struct BugpointPass : public Pass { { Pass::call(design, "design -reset"); crashing_design = clean_design(crashing_design, clean, /*do_delete=*/true); - for (auto &it : crashing_design->modules_) - design->add(it.second->clone()); + for (auto module : crashing_design->modules()) + design->add(module->clone()); delete crashing_design; } } diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 820ecac7b..ba29e6f4b 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -98,49 +98,6 @@ struct CheckPass : public Pass { log_header(design, "Executing CHECK pass (checking for obvious problems).\n"); - pool<IdString> fftypes; - fftypes.insert("$sr"); - fftypes.insert("$ff"); - fftypes.insert("$dff"); - fftypes.insert("$dffe"); - fftypes.insert("$dffsr"); - fftypes.insert("$adff"); - fftypes.insert("$dlatch"); - fftypes.insert("$dlatchsr"); - fftypes.insert("$_DFFE_NN_"); - fftypes.insert("$_DFFE_NP_"); - fftypes.insert("$_DFFE_PN_"); - fftypes.insert("$_DFFE_PP_"); - fftypes.insert("$_DFFSR_NNN_"); - fftypes.insert("$_DFFSR_NNP_"); - fftypes.insert("$_DFFSR_NPN_"); - fftypes.insert("$_DFFSR_NPP_"); - fftypes.insert("$_DFFSR_PNN_"); - fftypes.insert("$_DFFSR_PNP_"); - fftypes.insert("$_DFFSR_PPN_"); - fftypes.insert("$_DFFSR_PPP_"); - fftypes.insert("$_DFF_NN0_"); - fftypes.insert("$_DFF_NN1_"); - fftypes.insert("$_DFF_NP0_"); - fftypes.insert("$_DFF_NP1_"); - fftypes.insert("$_DFF_N_"); - fftypes.insert("$_DFF_PN0_"); - fftypes.insert("$_DFF_PN1_"); - fftypes.insert("$_DFF_PP0_"); - fftypes.insert("$_DFF_PP1_"); - fftypes.insert("$_DFF_P_"); - fftypes.insert("$_DLATCHSR_NNN_"); - fftypes.insert("$_DLATCHSR_NNP_"); - fftypes.insert("$_DLATCHSR_NPN_"); - fftypes.insert("$_DLATCHSR_NPP_"); - fftypes.insert("$_DLATCHSR_PNN_"); - fftypes.insert("$_DLATCHSR_PNP_"); - fftypes.insert("$_DLATCHSR_PPN_"); - fftypes.insert("$_DLATCHSR_PPP_"); - fftypes.insert("$_DLATCH_N_"); - fftypes.insert("$_DLATCH_P_"); - fftypes.insert("$_FF_"); - for (auto module : design->selected_whole_modules_warn()) { if (module->has_processes_warn()) @@ -202,8 +159,8 @@ struct CheckPass : public Pass { if (wire->port_input && !wire->port_output) for (auto bit : sigmap(wire)) if (bit.wire) wire_drivers_count[bit]++; - if (wire->attributes.count("\\init")) { - Const initval = wire->attributes.at("\\init"); + if (wire->attributes.count(ID::init)) { + Const initval = wire->attributes.at(ID::init); for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) if (initval[i] == State::S0 || initval[i] == State::S1) init_bits.insert(sigmap(SigBit(wire, i))); @@ -242,10 +199,10 @@ struct CheckPass : public Pass { { for (auto cell : module->cells()) { - if (fftypes.count(cell->type) == 0) + if (RTLIL::builtin_ff_cell_types().count(cell->type) == 0) continue; - for (auto bit : sigmap(cell->getPort("\\Q"))) + for (auto bit : sigmap(cell->getPort(ID::Q))) init_bits.erase(bit); } diff --git a/passes/cmds/chformal.cc b/passes/cmds/chformal.cc index 7e32da65f..d6e7f2ccf 100644 --- a/passes/cmds/chformal.cc +++ b/passes/cmds/chformal.cc @@ -77,23 +77,23 @@ struct ChformalPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-assert") { - constr_types.insert("$assert"); + constr_types.insert(ID($assert)); continue; } if (args[argidx] == "-assume") { - constr_types.insert("$assume"); + constr_types.insert(ID($assume)); continue; } if (args[argidx] == "-live") { - constr_types.insert("$live"); + constr_types.insert(ID($live)); continue; } if (args[argidx] == "-fair") { - constr_types.insert("$fair"); + constr_types.insert(ID($fair)); continue; } if (args[argidx] == "-cover") { - constr_types.insert("$cover"); + constr_types.insert(ID($cover)); continue; } if (mode == 0 && args[argidx] == "-remove") { @@ -139,11 +139,11 @@ struct ChformalPass : public Pass { extra_args(args, argidx, design); if (constr_types.empty()) { - constr_types.insert("$assert"); - constr_types.insert("$assume"); - constr_types.insert("$live"); - constr_types.insert("$fair"); - constr_types.insert("$cover"); + constr_types.insert(ID($assert)); + constr_types.insert(ID($assume)); + constr_types.insert(ID($live)); + constr_types.insert(ID($fair)); + constr_types.insert(ID($cover)); } if (mode == 0) @@ -171,11 +171,11 @@ struct ChformalPass : public Pass { for (auto wire : module->wires()) { - if (wire->attributes.count("\\init") == 0) + if (wire->attributes.count(ID::init) == 0) continue; SigSpec initsig = sigmap(wire); - Const initval = wire->attributes.at("\\init"); + Const initval = wire->attributes.at(ID::init); for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) { if (initval[i] == State::S0) @@ -187,17 +187,17 @@ struct ChformalPass : public Pass { for (auto cell : module->selected_cells()) { - if (cell->type == "$ff") { - SigSpec D = sigmap(cell->getPort("\\D")); - SigSpec Q = sigmap(cell->getPort("\\Q")); + if (cell->type == ID($ff)) { + SigSpec D = sigmap(cell->getPort(ID::D)); + SigSpec Q = sigmap(cell->getPort(ID::Q)); for (int i = 0; i < GetSize(D); i++) ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false)); } - if (cell->type == "$dff") { - SigSpec D = sigmap(cell->getPort("\\D")); - SigSpec Q = sigmap(cell->getPort("\\Q")); - SigSpec C = sigmap(cell->getPort("\\CLK")); - bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool(); + if (cell->type == ID($dff)) { + SigSpec D = sigmap(cell->getPort(ID::D)); + SigSpec Q = sigmap(cell->getPort(ID::Q)); + SigSpec C = sigmap(cell->getPort(ID::CLK)); + bool clockpol = cell->getParam(ID::CLK_POLARITY).as_bool(); for (int i = 0; i < GetSize(D); i++) ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol)); } @@ -206,15 +206,15 @@ struct ChformalPass : public Pass { for (auto cell : constr_cells) while (true) { - SigSpec A = sigmap(cell->getPort("\\A")); - SigSpec EN = sigmap(cell->getPort("\\EN")); + SigSpec A = sigmap(cell->getPort(ID::A)); + SigSpec EN = sigmap(cell->getPort(ID::EN)); if (ffmap.count(A) == 0 || ffmap.count(EN) == 0) break; if (!init_zero.count(EN)) { - if (cell->type == "$cover") break; - if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break; + if (cell->type == ID($cover)) break; + if (cell->type.in(ID($assert), ID($assume)) && !init_one.count(A)) break; } const auto &A_map = ffmap.at(A); @@ -223,8 +223,8 @@ struct ChformalPass : public Pass { if (A_map.second != EN_map.second) break; - cell->setPort("\\A", A_map.first); - cell->setPort("\\EN", EN_map.first); + cell->setPort(ID::A, A_map.first); + cell->setPort(ID::EN, EN_map.first); } } else @@ -233,18 +233,18 @@ struct ChformalPass : public Pass { for (auto cell : constr_cells) for (int i = 0; i < mode_arg; i++) { - SigSpec orig_a = cell->getPort("\\A"); - SigSpec orig_en = cell->getPort("\\EN"); + SigSpec orig_a = cell->getPort(ID::A); + SigSpec orig_en = cell->getPort(ID::EN); Wire *new_a = module->addWire(NEW_ID); Wire *new_en = module->addWire(NEW_ID); - new_en->attributes["\\init"] = State::S0; + new_en->attributes[ID::init] = State::S0; module->addFf(NEW_ID, orig_a, new_a); module->addFf(NEW_ID, orig_en, new_en); - cell->setPort("\\A", new_a); - cell->setPort("\\EN", new_en); + cell->setPort(ID::A, new_a); + cell->setPort(ID::EN, new_en); } } else @@ -254,26 +254,26 @@ struct ChformalPass : public Pass { for (int i = 0; i < mode_arg; i++) { Wire *w = module->addWire(NEW_ID); - w->attributes["\\init"] = State::S0; + w->attributes[ID::init] = State::S0; module->addFf(NEW_ID, en, w); en = w; } for (auto cell : constr_cells) - cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN"))); + cell->setPort(ID::EN, module->LogicAnd(NEW_ID, en, cell->getPort(ID::EN))); } else if (mode == 'c') { for (auto cell : constr_cells) - if (assert2assume && cell->type == "$assert") - cell->type = "$assume"; - else if (assume2assert && cell->type == "$assume") - cell->type = "$assert"; - else if (live2fair && cell->type == "$live") - cell->type = "$fair"; - else if (fair2live && cell->type == "$fair") - cell->type = "$live"; + if (assert2assume && cell->type == ID($assert)) + cell->type = ID($assume); + else if (assume2assert && cell->type == ID($assume)) + cell->type = ID($assert); + else if (live2fair && cell->type == ID($live)) + cell->type = ID($fair); + else if (fair2live && cell->type == ID($fair)) + cell->type = ID($live); } } } diff --git a/passes/cmds/connect.cc b/passes/cmds/connect.cc index f93bada27..0b0868dfb 100644 --- a/passes/cmds/connect.cc +++ b/passes/cmds/connect.cc @@ -32,9 +32,9 @@ static void unset_drivers(RTLIL::Design *design, RTLIL::Module *module, SigMap & RTLIL::Wire *dummy_wire = module->addWire(NEW_ID, sig.size()); - for (auto &it : module->cells_) - for (auto &port : it.second->connections_) - if (ct.cell_output(it.second->type, port.first)) + for (auto cell : module->cells()) + for (auto &port : cell->connections_) + if (ct.cell_output(cell->type, port.first)) sigmap(port.second).replace(sig, dummy_wire, &port.second); for (auto &conn : module->connections_) @@ -77,15 +77,13 @@ struct ConnectPass : public Pass { } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { - RTLIL::Module *module = NULL; - for (auto &it : design->modules_) { - if (!design->selected(it.second)) - continue; - if (module != NULL) - log_cmd_error("Multiple modules selected: %s, %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(it.first)); - module = it.second; + RTLIL::Module *module = nullptr; + for (auto mod : design->selected_modules()) { + if (module != nullptr) + log_cmd_error("Multiple modules selected: %s, %s\n", log_id(module->name), log_id(mod->name)); + module = mod; } - if (module == NULL) + if (module == nullptr) log_cmd_error("No modules selected.\n"); if (!module->processes.empty()) log_cmd_error("Found processes in selected module.\n"); @@ -130,7 +128,7 @@ struct ConnectPass : public Pass { std::vector<RTLIL::SigBit> lhs = it.first.to_sigbit_vector(); std::vector<RTLIL::SigBit> rhs = it.first.to_sigbit_vector(); for (size_t i = 0; i < lhs.size(); i++) - if (rhs[i].wire != NULL) + if (rhs[i].wire != nullptr) sigmap.add(lhs[i], rhs[i]); } @@ -172,14 +170,14 @@ struct ConnectPass : public Pass { if (flag_nounset) log_cmd_error("Can't use -port together with -nounset.\n"); - if (module->cells_.count(RTLIL::escape_id(port_cell)) == 0) + if (module->cell(RTLIL::escape_id(port_cell)) == nullptr) log_cmd_error("Can't find cell %s.\n", port_cell.c_str()); RTLIL::SigSpec sig; if (!RTLIL::SigSpec::parse_sel(sig, design, module, port_expr)) log_cmd_error("Failed to parse port expression `%s'.\n", port_expr.c_str()); - module->cells_.at(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); + module->cell(RTLIL::escape_id(port_cell))->setPort(RTLIL::escape_id(port_port), sigmap(sig)); } else log_cmd_error("Expected -set, -unset, or -port.\n"); diff --git a/passes/cmds/connwrappers.cc b/passes/cmds/connwrappers.cc index 5a15cbbaf..6ae7c9304 100644 --- a/passes/cmds/connwrappers.cc +++ b/passes/cmds/connwrappers.cc @@ -65,15 +65,13 @@ struct ConnwrappersWorker decls[key] = decl; } - void work(RTLIL::Design *design, RTLIL::Module *module) + void work(RTLIL::Module *module) { std::map<RTLIL::SigBit, std::pair<bool, RTLIL::SigSpec>> extend_map; SigMap sigmap(module); - for (auto &it : module->cells_) + for (auto cell : module->cells()) { - RTLIL::Cell *cell = it.second; - if (!decl_celltypes.count(cell->type)) continue; @@ -105,13 +103,8 @@ struct ConnwrappersWorker } } - for (auto &it : module->cells_) + for (auto cell : module->selected_cells()) { - RTLIL::Cell *cell = it.second; - - if (!design->selected(module, cell)) - continue; - for (auto &conn : cell->connections_) { std::vector<RTLIL::SigBit> sigbits = sigmap(conn.second).to_sigbit_vector(); @@ -141,8 +134,8 @@ struct ConnwrappersWorker } if (old_sig.size()) - log("Connected extended bits of %s.%s:%s: %s -> %s\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), - RTLIL::id2cstr(conn.first), log_signal(old_sig), log_signal(conn.second)); + log("Connected extended bits of %s.%s:%s: %s -> %s\n", log_id(module->name), log_id(cell->name), + log_id(conn.first), log_signal(old_sig), log_signal(conn.second)); } } } @@ -200,9 +193,8 @@ struct ConnwrappersPass : public Pass { log_header(design, "Executing CONNWRAPPERS pass (connect extended ports of wrapper cells).\n"); - for (auto &mod_it : design->modules_) - if (design->selected(mod_it.second)) - worker.work(design, mod_it.second); + for (auto module : design->selected_modules()) + worker.work(module); } } ConnwrappersPass; diff --git a/passes/cmds/copy.cc b/passes/cmds/copy.cc index acd2dba52..99f1f69cf 100644 --- a/passes/cmds/copy.cc +++ b/passes/cmds/copy.cc @@ -44,10 +44,10 @@ struct CopyPass : public Pass { std::string src_name = RTLIL::escape_id(args[1]); std::string trg_name = RTLIL::escape_id(args[2]); - if (design->modules_.count(src_name) == 0) + if (design->module(src_name) == nullptr) log_cmd_error("Can't find source module %s.\n", src_name.c_str()); - if (design->modules_.count(trg_name) != 0) + if (design->module(trg_name) != nullptr) log_cmd_error("Target module name %s already exists.\n", trg_name.c_str()); RTLIL::Module *new_mod = design->module(src_name)->clone(); diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 5822c09f8..b124e3b0f 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -65,27 +65,24 @@ struct DeletePass : public Pass { } extra_args(args, argidx, design); - std::vector<RTLIL::IdString> delete_mods; - - for (auto &mod_it : design->modules_) + std::vector<RTLIL::Module *> delete_mods; + for (auto module : design->modules()) { - if (design->selected_whole_module(mod_it.first) && !flag_input && !flag_output) { - delete_mods.push_back(mod_it.first); + if (design->selected_whole_module(module->name) && !flag_input && !flag_output) { + delete_mods.push_back(module); continue; } - if (!design->selected_module(mod_it.first)) + if (!design->selected_module(module->name)) continue; - RTLIL::Module *module = mod_it.second; - if (flag_input || flag_output) { - for (auto &it : module->wires_) - if (design->selected(module, it.second)) { + for (auto wire : module->wires()) + if (design->selected(module, wire)) { if (flag_input) - it.second->port_input = false; + wire->port_input = false; if (flag_output) - it.second->port_output = false; + wire->port_output = false; } module->fixup_ports(); continue; @@ -96,20 +93,19 @@ struct DeletePass : public Pass { pool<RTLIL::IdString> delete_procs; pool<RTLIL::IdString> delete_mems; - for (auto &it : module->wires_) - if (design->selected(module, it.second)) - delete_wires.insert(it.second); + for (auto wire : module->selected_wires()) + delete_wires.insert(wire); for (auto &it : module->memories) if (design->selected(module, it.second)) delete_mems.insert(it.first); - for (auto &it : module->cells_) { - if (design->selected(module, it.second)) - delete_cells.insert(it.second); - if (it.second->type.in("$memrd", "$memwr") && - delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0) - delete_cells.insert(it.second); + for (auto cell : module->cells()) { + if (design->selected(module, cell)) + delete_cells.insert(cell); + if (cell->type.in(ID($memrd), ID($memwr)) && + delete_mems.count(cell->parameters.at(ID::MEMID).decode_string()) != 0) + delete_cells.insert(cell); } for (auto &it : module->processes) @@ -134,9 +130,8 @@ struct DeletePass : public Pass { module->fixup_ports(); } - for (auto &it : delete_mods) { - delete design->modules_.at(it); - design->modules_.erase(it); + for (auto mod : delete_mods) { + design->remove(mod); } } } DeletePass; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 172addcc1..4612760cc 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 @@ -59,6 +60,11 @@ struct DesignPass : public Pass { log("Push the current design to the stack and then clear the current design.\n"); log("\n"); log("\n"); + log(" design -push-copy\n"); + log("\n"); + log("Push the current design to the stack without clearing the current design.\n"); + log("\n"); + log("\n"); log(" design -pop\n"); log("\n"); log("Reset the current design and pop the last design from the stack.\n"); @@ -100,6 +106,7 @@ struct DesignPass : public Pass { bool reset_mode = false; bool reset_vlog_mode = false; bool push_mode = false; + bool push_copy_mode = false; bool pop_mode = false; bool import_mode = false; RTLIL::Design *copy_from_design = NULL, *copy_to_design = NULL; @@ -125,6 +132,11 @@ struct DesignPass : public Pass { push_mode = true; continue; } + if (!got_mode && args[argidx] == "-push-copy") { + got_mode = true; + push_copy_mode = true; + continue; + } if (!got_mode && args[argidx] == "-pop") { got_mode = true; pop_mode = true; @@ -194,19 +206,19 @@ 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) { for (auto module : copy_src_modules) { - if (module->get_bool_attribute("\\top")) { + if (module->get_bool_attribute(ID::top)) { copy_src_modules.clear(); copy_src_modules.push_back(module); break; @@ -230,8 +242,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 +252,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(ID::top); + copy_to_design->add(t); - queue.insert(copy_to_design->modules_[prefix]); + queue.insert(t); done[mod->name] = prefix; } @@ -268,15 +281,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(ID::top); + copy_to_design->add(t); - queue.insert(copy_to_design->modules_[trg_name]); + queue.insert(t); done[cell->type] = trg_name; } @@ -294,21 +308,22 @@ 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); } } - if (!save_name.empty() || push_mode) + if (!save_name.empty() || push_mode || push_copy_mode) { 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; @@ -317,7 +332,7 @@ struct DesignPass : public Pass { if (saved_designs.count(save_name)) delete saved_designs.at(save_name); - if (push_mode) + if (push_mode || push_copy_mode) pushed_designs.push_back(design_copy); else saved_designs[save_name] = design_copy; @@ -325,9 +340,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 +360,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 new file mode 100644 index 000000000..9a27952d4 --- /dev/null +++ b/passes/cmds/logger.cc @@ -0,0 +1,183 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 Miodrag Milanovic <clifford@clifford.at> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct LoggerPass : public Pass { + LoggerPass() : Pass("logger", "set logger properties") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" logger [options]\n"); + log("\n"); + log("This command sets global logger properties, also available using command line\n"); + log("options.\n"); + log("\n"); + log(" -[no]time\n"); + log(" enable/disable display of timestamp in log output.\n"); + log("\n"); + log(" -[no]stderr\n"); + log(" enable/disable logging errors to stderr.\n"); + log("\n"); + log(" -warn regex\n"); + log(" print a warning for all log messages matching the regex.\n"); + log("\n"); + log(" -nowarn regex\n"); + log(" if a warning message matches the regex, it is printed as regular\n"); + log(" message instead.\n"); + log("\n"); + log(" -werror regex\n"); + log(" if a warning message matches the regex, it is printed as error\n"); + log(" message instead and the tool terminates with a nonzero return code.\n"); + log("\n"); + log(" -[no]debug\n"); + log(" globally enable/disable debug log messages.\n"); + log("\n"); + log(" -experimental <feature>\n"); + log(" do not print warnings for the specified experimental feature\n"); + log("\n"); + log(" -expect <type> <regex> <expected_count>\n"); + log(" expect log,warning or error to appear. In case of error return code is 0.\n"); + log("\n"); + log(" -expect-no-warnings\n"); + log(" gives error in case there is at least one warning that is not expected.\n"); + log("\n"); + } + + void execute(std::vector<std::string> args, RTLIL::Design * design) YS_OVERRIDE + { + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + + if (args[argidx] == "-time") { + log_time = true; + log("Enabled timestamp in logs.\n"); + continue; + } + if (args[argidx] == "-notime") { + log_time = false; + log("Disabled timestamp in logs.\n"); + continue; + } + if (args[argidx] == "-stderr") { + log_error_stderr = true; + log("Enabled loggint errors to stderr.\n"); + continue; + } + if (args[argidx] == "-nostderr") { + log_error_stderr = false; + log("Disabled loggint errors to stderr.\n"); + continue; + } + if (args[argidx] == "-warn" && argidx+1 < args.size()) { + std::string pattern = args[++argidx]; + if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); + try { + log("Added regex '%s' for warnings to warn list.\n", pattern.c_str()); + log_warn_regexes.push_back(YS_REGEX_COMPILE(pattern)); + } + catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + } + continue; + } + if (args[argidx] == "-nowarn" && argidx+1 < args.size()) { + std::string pattern = args[++argidx]; + if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); + try { + log("Added regex '%s' for warnings to nowarn list.\n", pattern.c_str()); + log_nowarn_regexes.push_back(YS_REGEX_COMPILE(pattern)); + } + catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + } + continue; + } + if (args[argidx] == "-werror" && argidx+1 < args.size()) { + std::string pattern = args[++argidx]; + if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); + try { + log("Added regex '%s' for warnings to werror list.\n", pattern.c_str()); + log_werror_regexes.push_back(YS_REGEX_COMPILE(pattern)); + } + catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + } + continue; + } + if (args[argidx] == "-debug") { + log_force_debug = 1; + log("Enabled debug log messages.\n"); + continue; + } + if (args[argidx] == "-nodebug") { + log_force_debug = 0; + log("Disabled debug log messages.\n"); + continue; + } + if (args[argidx] == "-experimental" && argidx+1 < args.size()) { + std::string value = args[++argidx]; + log("Added '%s' experimental ignore list.\n", value.c_str()); + log_experimentals_ignored.insert(value); + continue; + } + if (args[argidx] == "-expect" && argidx+3 < args.size()) { + std::string type = args[++argidx]; + if (type!="error" && type!="warning" && type!="log") + log_cmd_error("Expect command require type to be 'log', 'warning' or 'error' !\n"); + if (type=="error" && log_expect_error.size()>0) + log_cmd_error("Only single error message can be expected !\n"); + std::string pattern = args[++argidx]; + if (pattern.front() == '\"' && pattern.back() == '\"') pattern = pattern.substr(1, pattern.size() - 2); + int count = atoi(args[++argidx].c_str()); + if (count<=0) + log_cmd_error("Number of expected messages must be higher then 0 !\n"); + if (type=="error" && count!=1) + log_cmd_error("Expected error message occurrences must be 1 !\n"); + log("Added regex '%s' for warnings to expected %s list.\n", pattern.c_str(), type.c_str()); + try { + if (type=="error") + log_expect_error.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); + else if (type=="warning") + log_expect_warning.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); + else + log_expect_log.push_back(std::make_pair(YS_REGEX_COMPILE(pattern), LogExpectedItem(pattern, count))); + } + catch (const YS_REGEX_NS::regex_error& e) { + log_cmd_error("Error in regex expression '%s' !\n", pattern.c_str()); + } + continue; + } + if (args[argidx] == "-expect-no-warnings") { + log_expect_no_warnings = true; + continue; + } + break; + } + extra_args(args, argidx, design, false); + } +} LoggerPass; + +PRIVATE_NAMESPACE_END diff --git a/passes/cmds/qwp.cc b/passes/cmds/qwp.cc index adbe89e31..b178ef951 100644 --- a/passes/cmds/qwp.cc +++ b/passes/cmds/qwp.cc @@ -737,7 +737,7 @@ struct QwpWorker for (auto &node : nodes) if (node.cell != nullptr) - node.cell->attributes["\\qwp_position"] = stringf("%f %f", node.pos, node.alt_pos); + node.cell->attributes[ID::qwp_position] = stringf("%f %f", node.pos, node.alt_pos); vector<double> edge_lengths; vector<double> weighted_edge_lengths; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 0f1f05ccb..b64b077e4 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -58,7 +58,7 @@ static bool match_attr_val(const RTLIL::Const &value, std::string pattern, char { RTLIL::SigSpec sig_value; - if (!RTLIL::SigSpec::parse(sig_value, NULL, pattern)) + if (!RTLIL::SigSpec::parse(sig_value, nullptr, pattern)) return false; RTLIL::Const pattern_value = sig_value.as_const(); @@ -152,27 +152,26 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) continue; - if (!lhs.selected_module(mod_it.first)) { - new_sel.selected_modules.insert(mod_it.first); + if (!lhs.selected_module(mod->name)) { + new_sel.selected_modules.insert(mod->name); continue; } - RTLIL::Module *mod = mod_it.second; - for (auto &it : mod->wires_) - if (!lhs.selected_member(mod_it.first, it.first)) - new_sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (!lhs.selected_member(mod->name, wire->name)) + new_sel.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) - if (!lhs.selected_member(mod_it.first, it.first)) - new_sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (!lhs.selected_member(mod_it.first, it.first)) + if (!lhs.selected_member(mod->name, it.first)) new_sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (!lhs.selected_member(mod->name, cell->name)) + new_sel.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) - if (!lhs.selected_member(mod_it.first, it.first)) + if (!lhs.selected_member(mod->name, it.first)) new_sel.selected_members[mod->name].insert(it.first); } @@ -223,15 +222,15 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) { - for (auto &cell_it : mod_it.second->cells_) + for (auto cell : mod->cells()) { - if (design->modules_.count(cell_it.second->type) == 0) + if (design->module(cell->type) == nullptr) continue; - lhs.selected_modules.insert(cell_it.second->type); + lhs.selected_modules.insert(cell->type); } } } @@ -240,21 +239,21 @@ static void select_op_submod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection &lhs) { RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) - if (lhs.selected_module(mod_it.first)) - for (auto &cell_it : mod_it.second->cells_) - if (lhs.selected_member(mod_it.first, cell_it.first) && design->modules_.count(cell_it.second->type)) - new_sel.selected_modules.insert(cell_it.second->type); + for (auto mod : design->modules()) + if (lhs.selected_module(mod->name)) + for (auto cell : mod->cells()) + if (lhs.selected_member(mod->name, cell->name) && (design->module(cell->type) != nullptr)) + new_sel.selected_modules.insert(cell->type); lhs = new_sel; } static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) { RTLIL::Selection new_sel(false); - for (auto &mod_it : design->modules_) - for (auto &cell_it : mod_it.second->cells_) - if (design->modules_.count(cell_it.second->type) && lhs.selected_whole_module(cell_it.second->type)) - new_sel.selected_members[mod_it.first].insert(cell_it.first); + for (auto mod : design->modules()) + for (auto cell : mod->cells()) + if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) + new_sel.selected_members[mod->name].insert(cell->name); lhs = new_sel; } @@ -268,23 +267,23 @@ static void select_op_fullmod(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name)) continue; - if (!lhs.selected_module(mod_it.first)) + if (!lhs.selected_module(mod->name)) continue; - SigMap sigmap(mod_it.second); + SigMap sigmap(mod); SigPool selected_bits; - for (auto &it : mod_it.second->wires_) - if (lhs.selected_member(mod_it.first, it.first)) - selected_bits.add(sigmap(it.second)); + for (auto wire : mod->wires()) + if (lhs.selected_member(mod->name, wire->name)) + selected_bits.add(sigmap(wire)); - for (auto &it : mod_it.second->wires_) - if (!lhs.selected_member(mod_it.first, it.first) && selected_bits.check_any(sigmap(it.second))) - lhs.selected_members[mod_it.first].insert(it.first); + for (auto wire : mod->wires()) + if (!lhs.selected_member(mod->name, wire->name) && selected_bits.check_any(sigmap(wire))) + lhs.selected_members[mod->name].insert(wire->name); } } @@ -323,8 +322,8 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) return; lhs.full_selection = false; - for (auto &it : design->modules_) - lhs.selected_modules.insert(it.first); + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } for (auto &it : rhs.selected_modules) { @@ -334,19 +333,19 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R for (auto &it : rhs.selected_members) { - if (design->modules_.count(it.first) == 0) + if (design->module(it.first) == nullptr) continue; - RTLIL::Module *mod = design->modules_[it.first]; + RTLIL::Module *mod = design->module(it.first); if (lhs.selected_modules.count(mod->name) > 0) { - for (auto &it : mod->wires_) - lhs.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + lhs.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) lhs.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - lhs.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + lhs.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) lhs.selected_members[mod->name].insert(it.first); lhs.selected_modules.erase(mod->name); @@ -367,8 +366,8 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co if (lhs.full_selection) { lhs.full_selection = false; - for (auto &it : design->modules_) - lhs.selected_modules.insert(it.first); + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } std::vector<RTLIL::IdString> del_list; @@ -431,18 +430,17 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v { int sel_objects = 0; bool is_input, is_output; - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { - if (lhs.selected_whole_module(mod_it.first) || !lhs.selected_module(mod_it.first)) + if (lhs.selected_whole_module(mod->name) || !lhs.selected_module(mod->name)) continue; - RTLIL::Module *mod = mod_it.second; std::set<RTLIL::Wire*> selected_wires; auto selected_members = lhs.selected_members[mod->name]; - for (auto &it : mod->wires_) - if (lhs.selected_member(mod_it.first, it.first) && limits.count(it.first) == 0) - selected_wires.insert(it.second); + for (auto wire : mod->wires()) + if (lhs.selected_member(mod->name, wire->name) && limits.count(wire->name) == 0) + selected_wires.insert(wire); for (auto &conn : mod->connections()) { @@ -450,7 +448,7 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v std::vector<RTLIL::SigBit> conn_rhs = conn.second.to_sigbit_vector(); for (size_t i = 0; i < conn_lhs.size(); i++) { - if (conn_lhs[i].wire == NULL || conn_rhs[i].wire == NULL) + if (conn_lhs[i].wire == nullptr || conn_rhs[i].wire == nullptr) continue; if (mode != 'i' && selected_wires.count(conn_rhs[i].wire) && selected_members.count(conn_lhs[i].wire->name) == 0) lhs.selected_members[mod->name].insert(conn_lhs[i].wire->name), sel_objects++, max_objects--; @@ -459,15 +457,15 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v } } - for (auto &cell : mod->cells_) - for (auto &conn : cell.second->connections()) + for (auto cell : mod->cells()) + for (auto &conn : cell->connections()) { char last_mode = '-'; - if (eval_only && !yosys_celltypes.cell_evaluable(cell.second->type)) + if (eval_only && !yosys_celltypes.cell_evaluable(cell->type)) goto exclude_match; for (auto &rule : rules) { last_mode = rule.mode; - if (rule.cell_types.size() > 0 && rule.cell_types.count(cell.second->type) == 0) + if (rule.cell_types.size() > 0 && rule.cell_types.count(cell->type) == 0) continue; if (rule.port_names.size() > 0 && rule.port_names.count(conn.first) == 0) continue; @@ -479,14 +477,14 @@ static int select_op_expand(RTLIL::Design *design, RTLIL::Selection &lhs, std::v if (last_mode == '+') goto exclude_match; include_match: - is_input = mode == 'x' || ct.cell_input(cell.second->type, conn.first); - is_output = mode == 'x' || ct.cell_output(cell.second->type, conn.first); + is_input = mode == 'x' || ct.cell_input(cell->type, conn.first); + is_output = mode == 'x' || ct.cell_output(cell->type, conn.first); for (auto &chunk : conn.second.chunks()) - if (chunk.wire != NULL) { - if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell.first) == 0) + if (chunk.wire != nullptr) { + if (max_objects != 0 && selected_wires.count(chunk.wire) > 0 && selected_members.count(cell->name) == 0) if (mode == 'x' || (mode == 'i' && is_output) || (mode == 'o' && is_input)) - lhs.selected_members[mod->name].insert(cell.first), sel_objects++, max_objects--; - if (max_objects != 0 && selected_members.count(cell.first) > 0 && limits.count(cell.first) == 0 && selected_members.count(chunk.wire->name) == 0) + lhs.selected_members[mod->name].insert(cell->name), sel_objects++, max_objects--; + if (max_objects != 0 && selected_members.count(cell->name) > 0 && limits.count(cell->name) == 0 && selected_members.count(chunk.wire->name) == 0) if (mode == 'x' || (mode == 'i' && is_input) || (mode == 'o' && is_output)) lhs.selected_members[mod->name].insert(chunk.wire->name), sel_objects++, max_objects--; } @@ -627,9 +625,13 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se } } -static void select_stmt(RTLIL::Design *design, std::string arg) +static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_empty_warning = false) { std::string arg_mod, arg_memb; + std::unordered_map<std::string, bool> arg_mod_found; + std::unordered_map<std::string, bool> arg_memb_found; + auto isalpha = [](const char &x) { return ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')); }; + bool prefixed = GetSize(arg) >= 2 && isalpha(arg[0]) && arg[1] == ':'; if (arg.size() == 0) return; @@ -760,19 +762,21 @@ static void select_stmt(RTLIL::Design *design, std::string arg) if (!design->selected_active_module.empty()) { arg_mod = design->selected_active_module; arg_memb = arg; + if (!prefixed) arg_memb_found[arg_memb] = false; } else - if (GetSize(arg) >= 2 && arg[0] >= 'a' && arg[0] <= 'z' && arg[1] == ':') { + if (prefixed && arg[0] >= 'a' && arg[0] <= 'z') { arg_mod = "*", arg_memb = arg; } else { size_t pos = arg.find('/'); if (pos == std::string::npos) { - if (arg.find(':') == std::string::npos || arg.compare(0, 1, "A") == 0) - arg_mod = arg; - else - arg_mod = "*", arg_memb = arg; + arg_mod = arg; + if (!prefixed) arg_mod_found[arg_mod] = false; } else { arg_mod = arg.substr(0, pos); + if (!prefixed) arg_mod_found[arg_mod] = false; arg_memb = arg.substr(pos+1); + bool arg_memb_prefixed = GetSize(arg_memb) >= 2 && isalpha(arg_memb[0]) && arg_memb[1] == ':'; + if (!arg_memb_prefixed) arg_memb_found[arg_memb] = false; } } @@ -785,56 +789,61 @@ static void select_stmt(RTLIL::Design *design, std::string arg) } sel.full_selection = false; - for (auto &mod_it : design->modules_) + for (auto mod : design->modules()) { if (arg_mod.compare(0, 2, "A:") == 0) { - if (!match_attr(mod_it.second->attributes, arg_mod.substr(2))) + if (!match_attr(mod->attributes, arg_mod.substr(2))) + continue; + } else + if (arg_mod.compare(0, 2, "N:") == 0) { + if (!match_ids(mod->name, arg_mod.substr(2))) continue; } else - if (!match_ids(mod_it.first, arg_mod)) + if (!match_ids(mod->name, arg_mod)) continue; + else + arg_mod_found[arg_mod] = true; if (arg_memb == "") { - sel.selected_modules.insert(mod_it.first); + sel.selected_modules.insert(mod->name); continue; } - RTLIL::Module *mod = mod_it.second; if (arg_memb.compare(0, 2, "w:") == 0) { - for (auto &it : mod->wires_) - if (match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "i:") == 0) { - for (auto &it : mod->wires_) - if (it.second->port_input && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->port_input && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "o:") == 0) { - for (auto &it : mod->wires_) - if (it.second->port_output && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->port_output && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "x:") == 0) { - for (auto &it : mod->wires_) - if ((it.second->port_input || it.second->port_output) && match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if ((wire->port_input || wire->port_output) && match_ids(wire->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); } else if (arg_memb.compare(0, 2, "s:") == 0) { size_t delim = arg_memb.substr(2).find(':'); if (delim == std::string::npos) { int width = atoi(arg_memb.substr(2).c_str()); - for (auto &it : mod->wires_) - if (it.second->width == width) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (wire->width == width) + sel.selected_members[mod->name].insert(wire->name); } else { std::string min_str = arg_memb.substr(2, delim); std::string max_str = arg_memb.substr(2+delim+1); int min_width = min_str.empty() ? 0 : atoi(min_str.c_str()); int max_width = max_str.empty() ? -1 : atoi(max_str.c_str()); - for (auto &it : mod->wires_) - if (min_width <= it.second->width && (it.second->width <= max_width || max_width == -1)) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (min_width <= wire->width && (wire->width <= max_width || max_width == -1)) + sel.selected_members[mod->name].insert(wire->name); } } else if (arg_memb.compare(0, 2, "m:") == 0) { @@ -842,15 +851,15 @@ static void select_stmt(RTLIL::Design *design, std::string arg) if (match_ids(it.first, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else - if (arg_memb.compare(0, 2, "c:") ==0) { - for (auto &it : mod->cells_) - if (match_ids(it.first, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + if (arg_memb.compare(0, 2, "c:") == 0) { + for (auto cell : mod->cells()) + if (match_ids(cell->name, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else if (arg_memb.compare(0, 2, "t:") == 0) { - for (auto &it : mod->cells_) - if (match_ids(it.second->type, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_ids(cell->type, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else if (arg_memb.compare(0, 2, "p:") == 0) { for (auto &it : mod->processes) @@ -858,62 +867,82 @@ static void select_stmt(RTLIL::Design *design, std::string arg) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.compare(0, 2, "a:") == 0) { - for (auto &it : mod->wires_) - if (match_attr(it.second->attributes, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_attr(wire->attributes, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(wire->name); for (auto &it : mod->memories) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (match_attr(it.second->attributes, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_attr(cell->attributes, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); for (auto &it : mod->processes) if (match_attr(it.second->attributes, arg_memb.substr(2))) sel.selected_members[mod->name].insert(it.first); } else if (arg_memb.compare(0, 2, "r:") == 0) { - for (auto &it : mod->cells_) - if (match_attr(it.second->parameters, arg_memb.substr(2))) - sel.selected_members[mod->name].insert(it.first); + for (auto cell : mod->cells()) + if (match_attr(cell->parameters, arg_memb.substr(2))) + sel.selected_members[mod->name].insert(cell->name); } else { + std::string orig_arg_memb = arg_memb; if (arg_memb.compare(0, 2, "n:") == 0) arg_memb = arg_memb.substr(2); - for (auto &it : mod->wires_) - if (match_ids(it.first, arg_memb)) - sel.selected_members[mod->name].insert(it.first); + for (auto wire : mod->wires()) + if (match_ids(wire->name, arg_memb)) { + sel.selected_members[mod->name].insert(wire->name); + arg_memb_found[orig_arg_memb] = true; + } for (auto &it : mod->memories) - if (match_ids(it.first, arg_memb)) - sel.selected_members[mod->name].insert(it.first); - for (auto &it : mod->cells_) - if (match_ids(it.first, arg_memb)) + if (match_ids(it.first, arg_memb)) { sel.selected_members[mod->name].insert(it.first); + arg_memb_found[orig_arg_memb] = true; + } + for (auto cell : mod->cells()) + if (match_ids(cell->name, arg_memb)) { + sel.selected_members[mod->name].insert(cell->name); + arg_memb_found[orig_arg_memb] = true; + } for (auto &it : mod->processes) - if (match_ids(it.first, arg_memb)) + if (match_ids(it.first, arg_memb)) { sel.selected_members[mod->name].insert(it.first); + arg_memb_found[orig_arg_memb] = true; + } } } select_filter_active_mod(design, work_stack.back()); + + for (auto &it : arg_mod_found) { + if (it.second == false && !disable_empty_warning) { + log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str()); + } + } + for (auto &it : arg_memb_found) { + if (it.second == false && !disable_empty_warning) { + log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str()); + } + } } static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel) { std::string desc = "Selection contains:\n"; - for (auto mod_it : design->modules_) + for (auto mod : design->modules()) { - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) - desc += stringf("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)); + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)); + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)); + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)); } } return desc; @@ -928,7 +957,7 @@ void handle_extra_select_args(Pass *pass, vector<string> args, size_t argidx, si work_stack.clear(); for (; argidx < args_size; argidx++) { if (args[argidx].compare(0, 1, "-") == 0) { - if (pass != NULL) + if (pass != nullptr) pass->cmd_error(args, argidx, "Unexpected option in selection arguments."); else log_cmd_error("Unexpected option in selection arguments."); @@ -1077,6 +1106,10 @@ struct SelectPass : public Pass { log(" all modules with an attribute matching the given pattern\n"); log(" in addition to = also <, <=, >=, and > are supported\n"); log("\n"); + log(" N:<pattern>\n"); + log(" all modules with a name matching the given pattern\n"); + log(" (i.e. 'N:' is optional as it is the default matching rule)\n"); + log("\n"); log("An <obj_pattern> can be an object name, wildcard expression, or one of\n"); log("the following:\n"); log("\n"); @@ -1267,7 +1300,7 @@ struct SelectPass : public Pass { } if (arg == "-module" && argidx+1 < args.size()) { RTLIL::IdString mod_name = RTLIL::escape_id(args[++argidx]); - if (design->modules_.count(mod_name) == 0) + if (design->module(mod_name) == nullptr) log_cmd_error("No such module: %s\n", id2cstr(mod_name)); design->selected_active_module = mod_name.str(); got_module = true; @@ -1279,7 +1312,8 @@ struct SelectPass : public Pass { } if (arg.size() > 0 && arg[0] == '-') log_cmd_error("Unknown option %s.\n", arg.c_str()); - select_stmt(design, arg); + bool disable_empty_warning = count_mode || assert_none || assert_any || (assert_count != -1) || (assert_max != -1) || (assert_min != -1); + select_stmt(design, arg, disable_empty_warning); sel_str += " " + arg; } @@ -1353,41 +1387,41 @@ struct SelectPass : public Pass { if (list_mode || count_mode || !write_file.empty()) { - #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != NULL) fprintf(f, __VA_ARGS__); total_count++; } + #define LOG_OBJECT(...) { if (list_mode) log(__VA_ARGS__); if (f != nullptr) fprintf(f, __VA_ARGS__); total_count++; } int total_count = 0; - FILE *f = NULL; + FILE *f = nullptr; if (!write_file.empty()) { f = fopen(write_file.c_str(), "w"); yosys_output_files.insert(write_file); - if (f == NULL) + if (f == nullptr) log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } RTLIL::Selection *sel = &design->selection_stack.back(); if (work_stack.size() > 0) sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules_) + for (auto mod : design->modules()) { - if (sel->selected_whole_module(mod_it.first) && list_mode) - log("%s\n", id2cstr(mod_it.first)); - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) - LOG_OBJECT("%s/%s\n", id2cstr(mod_it.first), id2cstr(it.first)) + if (sel->selected_whole_module(mod->name) && list_mode) + log("%s\n", id2cstr(mod->name)); + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(wire->name)) + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(cell->name)) + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it.first)) } } if (count_mode) log("%d objects.\n", total_count); - if (f != NULL) + if (f != nullptr) fclose(f); #undef LOG_OBJECT return; @@ -1448,19 +1482,19 @@ struct SelectPass : public Pass { log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); sel->optimize(design); - for (auto mod_it : design->modules_) - if (sel->selected_module(mod_it.first)) { - for (auto &it : mod_it.second->wires_) - if (sel->selected_member(mod_it.first, it.first)) + for (auto mod : design->modules()) + if (sel->selected_module(mod->name)) { + for (auto wire : mod->wires()) + if (sel->selected_member(mod->name, wire->name)) total_count++; - for (auto &it : mod_it.second->memories) - if (sel->selected_member(mod_it.first, it.first)) + for (auto &it : mod->memories) + if (sel->selected_member(mod->name, it.first)) total_count++; - for (auto &it : mod_it.second->cells_) - if (sel->selected_member(mod_it.first, it.first)) + for (auto cell : mod->cells()) + if (sel->selected_member(mod->name, cell->name)) total_count++; - for (auto &it : mod_it.second->processes) - if (sel->selected_member(mod_it.first, it.first)) + for (auto &it : mod->processes) + if (sel->selected_member(mod->name, it.first)) total_count++; } if (assert_count >= 0 && assert_count != total_count) @@ -1581,15 +1615,13 @@ struct CdPass : public Pass { std::string modname = RTLIL::escape_id(args[1]); - if (design->modules_.count(modname) == 0 && !design->selected_active_module.empty()) { - RTLIL::Module *module = NULL; - if (design->modules_.count(design->selected_active_module) > 0) - module = design->modules_.at(design->selected_active_module); - if (module != NULL && module->cells_.count(modname) > 0) - modname = module->cells_.at(modname)->type.str(); + if (design->module(modname) == nullptr && !design->selected_active_module.empty()) { + RTLIL::Module *module = design->module(design->selected_active_module); + if (module != nullptr && module->cell(modname) != nullptr) + modname = module->cell(modname)->type.str(); } - if (design->modules_.count(modname) > 0) { + if (design->module(modname) != nullptr) { design->selected_active_module = modname; design->selection_stack.back() = RTLIL::Selection(); select_filter_active_mod(design, design->selection_stack.back()); diff --git a/passes/cmds/setattr.cc b/passes/cmds/setattr.cc index 1ccfc2e86..515f5a4ef 100644 --- a/passes/cmds/setattr.cc +++ b/passes/cmds/setattr.cc @@ -38,7 +38,7 @@ struct setunset_t value = RTLIL::Const(set_value.substr(1, GetSize(set_value)-2)); } else { RTLIL::SigSpec sig_value; - if (!RTLIL::SigSpec::parse(sig_value, NULL, set_value)) + if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value)) log_cmd_error("Can't decode value '%s'!\n", set_value.c_str()); value = sig_value.as_const(); } @@ -96,10 +96,8 @@ struct SetattrPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod : design->modules_) + for (auto module : design->modules()) { - RTLIL::Module *module = mod.second; - if (flag_mod) { if (design->selected_whole_module(module->name)) do_setunset(module->attributes, setunset_list); @@ -109,17 +107,17 @@ struct SetattrPass : public Pass { if (!design->selected(module)) continue; - for (auto &it : module->wires_) - if (design->selected(module, it.second)) - do_setunset(it.second->attributes, setunset_list); + for (auto wire : module->wires()) + if (design->selected(module, wire)) + do_setunset(wire->attributes, setunset_list); for (auto &it : module->memories) if (design->selected(module, it.second)) do_setunset(it.second->attributes, setunset_list); - for (auto &it : module->cells_) - if (design->selected(module, it.second)) - do_setunset(it.second->attributes, setunset_list); + for (auto cell : module->cells()) + if (design->selected(module, cell)) + do_setunset(cell->attributes, setunset_list); for (auto &it : module->processes) if (design->selected(module, it.second)) @@ -159,10 +157,10 @@ struct WbflipPass : public Pass { if (!design->selected(module)) continue; - if (module->get_bool_attribute("\\blackbox")) + if (module->get_bool_attribute(ID::blackbox)) continue; - module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox")); + module->set_bool_attribute(ID::whitebox, !module->get_bool_attribute(ID::whitebox)); } } } WbflipPass; @@ -208,19 +206,13 @@ struct SetparamPass : public Pass { } extra_args(args, argidx, design); - for (auto &mod : design->modules_) + for (auto module : design->selected_modules()) { - RTLIL::Module *module = mod.second; - - if (!design->selected(module)) - continue; - - for (auto &it : module->cells_) - if (design->selected(module, it.second)) { - if (!new_cell_type.empty()) - it.second->type = new_cell_type; - do_setunset(it.second->parameters, setunset_list); - } + for (auto cell : module->selected_cells()) { + if (!new_cell_type.empty()) + cell->type = new_cell_type; + do_setunset(cell->parameters, setunset_list); + } } } } SetparamPass; diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index 3eedc86b8..2556d188a 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -359,37 +359,12 @@ struct SetundefPass : public Pass { pool<SigBit> ffbits; pool<Wire*> initwires; - pool<IdString> fftypes; - fftypes.insert("$dff"); - fftypes.insert("$dffe"); - fftypes.insert("$dffsr"); - fftypes.insert("$adff"); - - std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'}; - - for (auto c1 : list_np) - fftypes.insert(stringf("$_DFF_%c_", c1)); - - for (auto c1 : list_np) - for (auto c2 : list_np) - fftypes.insert(stringf("$_DFFE_%c%c_", c1, c2)); - - for (auto c1 : list_np) - for (auto c2 : list_np) - for (auto c3 : list_01) - fftypes.insert(stringf("$_DFF_%c%c%c_", c1, c2, c3)); - - for (auto c1 : list_np) - for (auto c2 : list_np) - for (auto c3 : list_np) - fftypes.insert(stringf("$_DFFSR_%c%c%c_", c1, c2, c3)); - for (auto cell : module->cells()) { - if (!fftypes.count(cell->type)) + if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; - for (auto bit : sigmap(cell->getPort("\\Q"))) + for (auto bit : sigmap(cell->getPort(ID::Q))) ffbits.insert(bit); } @@ -411,7 +386,7 @@ struct SetundefPass : public Pass { for (auto wire : initwires) { - Const &initval = wire->attributes["\\init"]; + Const &initval = wire->attributes[ID::init]; initval.bits.resize(GetSize(wire), State::Sx); for (int i = 0; i < GetSize(wire); i++) { @@ -423,7 +398,7 @@ struct SetundefPass : public Pass { } if (initval.is_fully_undef()) - wire->attributes.erase("\\init"); + wire->attributes.erase(ID::init); } initwires.clear(); @@ -439,14 +414,14 @@ struct SetundefPass : public Pass { if (wire->name[0] == (wire_types ? '\\' : '$')) continue; - if (!wire->attributes.count("\\init")) + if (!wire->attributes.count(ID::init)) continue; - Const &initval = wire->attributes["\\init"]; + Const &initval = wire->attributes[ID::init]; initval.bits.resize(GetSize(wire), State::Sx); if (initval.is_fully_undef()) { - wire->attributes.erase("\\init"); + wire->attributes.erase(ID::init); continue; } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index eeef24bde..155ed0fcd 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -41,8 +41,6 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -using RTLIL::id2cstr; - #undef CLUSTER_CELLS_AND_PORTBOXES struct ShowWorker @@ -101,7 +99,7 @@ struct ShowWorker { sig.sort_and_unify(); for (auto &c : sig.chunks()) { - if (c.wire != NULL) + if (c.wire != nullptr) for (auto &s : color_selections) if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0) return stringf("color=\"%s\"", s.first.c_str()); @@ -218,7 +216,7 @@ struct ShowWorker if (sig.is_chunk()) { const RTLIL::SigChunk &c = sig.as_chunk(); - if (c.wire != NULL && design->selected_member(module->name, c.wire->name)) { + if (c.wire != nullptr && design->selected_member(module->name, c.wire->name)) { if (!range_check || c.wire->width == c.width) return stringf("n%d", id2num(c.wire->name)); } else { @@ -230,7 +228,7 @@ struct ShowWorker return std::string(); } - std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = NULL) + std::string gen_portbox(std::string port, RTLIL::SigSpec sig, bool driver, std::string *node = nullptr) { std::string code; std::string net = gen_signode_simple(sig); @@ -287,7 +285,7 @@ struct ShowWorker else code += stringf("x%d:e -> %s:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", idx, port.c_str(), nextColor(sig).c_str(), widthLabel(sig.size()).c_str()); } - if (node != NULL) + if (node != nullptr) *node = stringf("x%d", idx); } else @@ -300,7 +298,7 @@ struct ShowWorker net_conn_map[net].bits = sig.size(); net_conn_map[net].color = nextColor(sig, net_conn_map[net].color); } - if (node != NULL) + if (node != nullptr) *node = net; } return code; @@ -366,22 +364,20 @@ struct ShowWorker std::set<std::string> all_sources, all_sinks; std::map<std::string, std::string> wires_on_demand; - for (auto &it : module->wires_) { - if (!design->selected_member(module->name, it.first)) - continue; + for (auto wire : module->selected_wires()) { const char *shape = "diamond"; - if (it.second->port_input || it.second->port_output) + if (wire->port_input || wire->port_output) shape = "octagon"; - if (it.first[0] == '\\') { + if (wire->name[0] == '\\') { fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n", - id2num(it.first), shape, findLabel(it.first.str()), - nextColor(RTLIL::SigSpec(it.second), "color=\"black\"").c_str()); - if (it.second->port_input) - all_sources.insert(stringf("n%d", id2num(it.first))); - else if (it.second->port_output) - all_sinks.insert(stringf("n%d", id2num(it.first))); + id2num(wire->name), shape, findLabel(wire->name.str()), + nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str()); + if (wire->port_input) + all_sources.insert(stringf("n%d", id2num(wire->name))); + else if (wire->port_output) + all_sinks.insert(stringf("n%d", id2num(wire->name))); } else { - wires_on_demand[stringf("n%d", id2num(it.first))] = it.first.str(); + wires_on_demand[stringf("n%d", id2num(wire->name))] = wire->name.str(); } } @@ -398,15 +394,12 @@ struct ShowWorker fprintf(f, "}\n"); } - for (auto &it : module->cells_) + for (auto cell : module->selected_cells()) { - if (!design->selected_member(module->name, it.first)) - continue; - std::vector<RTLIL::IdString> in_ports, out_ports; - 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)) in_ports.push_back(conn.first); else out_ports.push_back(conn.first); @@ -419,12 +412,12 @@ struct ShowWorker for (auto &p : in_ports) label_string += stringf("<p%d> %s%s|", id2num(p), escape(p.str()), - genSignedLabels && it.second->hasParam(p.str() + "_SIGNED") && - it.second->getParam(p.str() + "_SIGNED").as_bool() ? "*" : ""); + genSignedLabels && cell->hasParam(p.str() + "_SIGNED") && + cell->getParam(p.str() + "_SIGNED").as_bool() ? "*" : ""); if (label_string[label_string.size()-1] == '|') label_string = label_string.substr(0, label_string.size()-1); - label_string += stringf("}|%s\\n%s|{", findLabel(it.first.str()), escape(it.second->type.str())); + label_string += stringf("}|%s\\n%s|{", findLabel(cell->name.str()), escape(cell->type.str())); for (auto &p : out_ports) label_string += stringf("<p%d> %s|", id2num(p), escape(p.str())); @@ -434,19 +427,19 @@ struct ShowWorker label_string += "}}"; std::string code; - for (auto &conn : it.second->connections()) { - code += gen_portbox(stringf("c%d:p%d", id2num(it.first), id2num(conn.first)), - conn.second, ct.cell_output(it.second->type, conn.first)); + for (auto &conn : cell->connections()) { + code += gen_portbox(stringf("c%d:p%d", id2num(cell->name), id2num(conn.first)), + conn.second, ct.cell_output(cell->type, conn.first)); } #ifdef CLUSTER_CELLS_AND_PORTBOXES if (!code.empty()) fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n", - id2num(it.first), id2num(it.first), label_string.c_str(), findColor(it.first), code.c_str()); + id2num(cell->name), id2num(cell->name), label_string.c_str(), findColor(cell->name), code.c_str()); else #endif fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(it.first), label_string.c_str(), findColor(it.first.str()), code.c_str()); + id2num(cell->name), label_string.c_str(), findColor(cell->name.str()), code.c_str()); } for (auto &it : module->processes) @@ -482,8 +475,8 @@ struct ShowWorker } std::string proc_src = RTLIL::unescape_id(proc->name); - if (proc->attributes.count("\\src") > 0) - proc_src = proc->attributes.at("\\src").decode_string(); + if (proc->attributes.count(ID::src) > 0) + proc_src = proc->attributes.at(ID::src).decode_string(); fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name.str()), proc_src.c_str()); } @@ -491,12 +484,12 @@ struct ShowWorker { bool found_lhs_wire = false; for (auto &c : conn.first.chunks()) { - if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) + if (c.wire == nullptr || design->selected_member(module->name, c.wire->name)) found_lhs_wire = true; } bool found_rhs_wire = false; for (auto &c : conn.second.chunks()) { - if (c.wire == NULL || design->selected_member(module->name, c.wire->name)) + if (c.wire == nullptr || design->selected_member(module->name, c.wire->name)) found_rhs_wire = true; } if (!found_lhs_wire || !found_rhs_wire) @@ -572,23 +565,21 @@ struct ShowWorker design->optimize(); page_counter = 0; - for (auto &mod_it : design->modules_) + for (auto mod : design->selected_modules()) { - module = mod_it.second; - if (!design->selected_module(module->name)) - continue; + module = mod; if (design->selected_whole_module(module->name)) { if (module->get_blackbox_attribute()) { - // log("Skipping blackbox module %s.\n", id2cstr(module->name)); + // log("Skipping blackbox module %s.\n", log_id(module->name)); continue; } else - if (module->cells_.empty() && module->connections().empty() && module->processes.empty()) { - log("Skipping empty module %s.\n", id2cstr(module->name)); + if (module->cells().size() == 0 && module->connections().empty() && module->processes.empty()) { + log("Skipping empty module %s.\n", log_id(module->name)); continue; } else - log("Dumping module %s to page %d.\n", id2cstr(module->name), ++page_counter); + log("Dumping module %s to page %d.\n", log_id(module->name), ++page_counter); } else - log("Dumping selected parts of module %s to page %d.\n", id2cstr(module->name), ++page_counter); + log("Dumping selected parts of module %s to page %d.\n", log_id(module->name), ++page_counter); handle_module(); } } @@ -668,6 +659,10 @@ struct ShowPass : public Pass { log(" -notitle\n"); log(" do not add the module name as graph title to the dot file\n"); log("\n"); + log(" -nobg\n"); + log(" don't run viewer in the background, IE wait for the viewer tool to\n"); + log(" exit before returning\n"); + log("\n"); log("When no <format> is specified, 'dot' is used. When no <format> and <viewer> is\n"); log("specified, 'xdot' is used to display the schematic (POSIX systems only).\n"); log("\n"); @@ -706,6 +701,7 @@ struct ShowPass : public Pass { bool flag_abbreviate = true; bool flag_notitle = false; bool custom_prefix = false; + std::string background = "&"; RTLIL::IdString colorattr; size_t argidx; @@ -787,19 +783,22 @@ struct ShowPass : public Pass { flag_notitle = true; continue; } + if (arg == "-nobg") { + background= ""; + continue; + } break; } extra_args(args, argidx, design); if (format != "ps" && format != "dot") { int modcount = 0; - for (auto &mod_it : design->modules_) { - if (mod_it.second->get_blackbox_attribute()) + for (auto module : design->selected_modules()) { + if (module->get_blackbox_attribute()) continue; - if (mod_it.second->cells_.empty() && mod_it.second->connections().empty()) + if (module->cells().size() == 0 && module->connections().empty()) continue; - if (design->selected_module(mod_it.first)) - modcount++; + modcount++; } if (modcount > 1) log_cmd_error("For formats different than 'ps' or 'dot' only one module must be selected.\n"); @@ -826,7 +825,7 @@ struct ShowPass : public Pass { FILE *f = fopen(dot_file.c_str(), "w"); if (custom_prefix) yosys_output_files.insert(dot_file); - if (f == NULL) { + if (f == nullptr) { for (auto lib : libs) delete lib; log_cmd_error("Can't open dot file `%s' for writing.\n", dot_file.c_str()); @@ -859,21 +858,19 @@ struct ShowPass : public Pass { // system()/cmd.exe does not understand single quotes nor // background tasks on Windows. So we have to pause yosys // until the viewer exits. - #define VIEW_CMD "%s \"%s\"" + std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str()); #else - #define VIEW_CMD "%s '%s' &" + std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str()); #endif - std::string cmd = stringf(VIEW_CMD, viewer_exe.c_str(), out_file.c_str()); - #undef VIEW_CMD log("Exec: %s\n", cmd.c_str()); if (run_command(cmd) != 0) log_cmd_error("Shell command failed!\n"); } else if (format.empty()) { #ifdef __APPLE__ - std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' &", getuid(), dot_file.c_str(), dot_file.c_str()); + std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str()); #else - std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' &", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str()); + std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str()); #endif log("Exec: %s\n", cmd.c_str()); if (run_command(cmd) != 0) @@ -882,8 +879,8 @@ struct ShowPass : public Pass { if (flag_pause) { #ifdef YOSYS_ENABLE_READLINE - char *input = NULL; - while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != NULL) { + char *input = nullptr; + while ((input = readline("Press ENTER to continue (or type 'shell' to open a shell)> ")) != nullptr) { if (input[strspn(input, " \t\r\n")] == 0) break; char *p = input + strspn(input, " \t\r\n"); diff --git a/passes/cmds/splice.cc b/passes/cmds/splice.cc index bafafca4e..ea9e06979 100644 --- a/passes/cmds/splice.cc +++ b/passes/cmds/splice.cc @@ -75,13 +75,13 @@ struct SpliceWorker RTLIL::SigSpec new_sig = sig; if (sig_a.size() != sig.size()) { - RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice"); - cell->parameters["\\OFFSET"] = offset; - cell->parameters["\\A_WIDTH"] = sig_a.size(); - cell->parameters["\\Y_WIDTH"] = sig.size(); - cell->setPort("\\A", sig_a); - cell->setPort("\\Y", module->addWire(NEW_ID, sig.size())); - new_sig = cell->getPort("\\Y"); + RTLIL::Cell *cell = module->addCell(NEW_ID, ID($slice)); + cell->parameters[ID::OFFSET] = offset; + cell->parameters[ID::A_WIDTH] = sig_a.size(); + cell->parameters[ID::Y_WIDTH] = sig.size(); + cell->setPort(ID::A, sig_a); + cell->setPort(ID::Y, module->addWire(NEW_ID, sig.size())); + new_sig = cell->getPort(ID::Y); } sliced_signals_cache[sig] = new_sig; @@ -102,7 +102,7 @@ struct SpliceWorker for (auto &bit : sig.to_sigbit_vector()) { - if (bit.wire == NULL) + if (bit.wire == nullptr) { if (last_bit == 0) chunks.back().append(bit); @@ -132,13 +132,13 @@ struct SpliceWorker RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front()); for (size_t i = 1; i < chunks.size(); i++) { RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]); - RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat"); - cell->parameters["\\A_WIDTH"] = new_sig.size(); - cell->parameters["\\B_WIDTH"] = sig2.size(); - cell->setPort("\\A", new_sig); - cell->setPort("\\B", sig2); - cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size())); - new_sig = cell->getPort("\\Y"); + RTLIL::Cell *cell = module->addCell(NEW_ID, ID($concat)); + cell->parameters[ID::A_WIDTH] = new_sig.size(); + cell->parameters[ID::B_WIDTH] = sig2.size(); + cell->setPort(ID::A, new_sig); + cell->setPort(ID::B, sig2); + cell->setPort(ID::Y, module->addWire(NEW_ID, new_sig.size() + sig2.size())); + new_sig = cell->getPort(ID::Y); } spliced_signals_cache[sig] = new_sig; @@ -149,23 +149,23 @@ struct SpliceWorker void run() { - log("Splicing signals in module %s:\n", RTLIL::id2cstr(module->name)); + log("Splicing signals in module %s:\n", log_id(module->name)); driven_bits.push_back(RTLIL::State::Sm); driven_bits.push_back(RTLIL::State::Sm); - for (auto &it : module->wires_) - if (it.second->port_input) { - RTLIL::SigSpec sig = sigmap(it.second); + for (auto wire : module->wires()) + if (wire->port_input) { + RTLIL::SigSpec sig = sigmap(wire); driven_chunks.insert(sig); for (auto &bit : sig.to_sigbit_vector()) driven_bits.push_back(bit); driven_bits.push_back(RTLIL::State::Sm); } - for (auto &it : module->cells_) - for (auto &conn : it.second->connections()) - if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) { + for (auto cell : module->cells()) + for (auto &conn : cell->connections()) + if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) { RTLIL::SigSpec sig = sigmap(conn.second); driven_chunks.insert(sig); for (auto &bit : sig.to_sigbit_vector()) @@ -180,9 +180,8 @@ struct SpliceWorker SigPool selected_bits; if (!sel_by_cell) - for (auto &it : module->wires_) - if (design->selected(module, it.second)) - selected_bits.add(sigmap(it.second)); + for (auto wire : module->selected_wires()) + selected_bits.add(sigmap(wire)); std::vector<Cell*> mod_cells = module->cells(); @@ -343,17 +342,14 @@ struct SplicePass : public Pass { log_header(design, "Executing SPLICE pass (creating cells for signal splicing).\n"); - for (auto &mod_it : design->modules_) + for (auto module : design->selected_modules()) { - if (!design->selected(mod_it.second)) - continue; - - if (mod_it.second->processes.size()) { - log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str()); + if (module->processes.size()) { + log("Skipping module %s as it contains processes.\n", module->name.c_str()); continue; } - SpliceWorker worker(design, mod_it.second); + SpliceWorker worker(design, module); worker.sel_by_cell = sel_by_cell; worker.sel_by_wire = sel_by_wire; worker.sel_any_bit = sel_any_bit; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index f5a1f17b3..1e7dedd70 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -60,17 +60,17 @@ struct SplitnetsWorker new_wire->port_input = wire->port_input; new_wire->port_output = wire->port_output; - if (wire->attributes.count("\\src")) - new_wire->attributes["\\src"] = wire->attributes.at("\\src"); + if (wire->attributes.count(ID::src)) + new_wire->attributes[ID::src] = wire->attributes.at(ID::src); - if (wire->attributes.count("\\keep")) - new_wire->attributes["\\keep"] = wire->attributes.at("\\keep"); + if (wire->attributes.count(ID::keep)) + new_wire->attributes[ID::keep] = wire->attributes.at(ID::keep); - if (wire->attributes.count("\\init")) { - Const old_init = wire->attributes.at("\\init"), new_init; + if (wire->attributes.count(ID::init)) { + Const old_init = wire->attributes.at(ID::init), new_init; for (int i = offset; i < offset+width; i++) new_init.bits.push_back(i < GetSize(old_init) ? old_init.bits.at(i) : State::Sx); - new_wire->attributes["\\init"] = new_init; + new_wire->attributes[ID::init] = new_init; } std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector(); @@ -141,6 +141,9 @@ struct SplitnetsPass : public Pass { for (auto module : design->selected_modules()) { + if (module->has_processes_warn()) + continue; + SplitnetsWorker worker; if (flag_ports) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index c8e4f3981..6c4bc0e5b 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -79,18 +79,15 @@ struct statdata_t STAT_NUMERIC_MEMBERS #undef X - for (auto &it : mod->wires_) + for (auto wire : mod->selected_wires()) { - if (!design->selected(mod, it.second)) - continue; - - if (it.first[0] == '\\') { + if (wire->name[0] == '\\') { num_pub_wires++; - num_pub_wire_bits += it.second->width; + num_pub_wire_bits += wire->width; } num_wires++; - num_wire_bits += it.second->width; + num_wire_bits += wire->width; } for (auto &it : mod->memories) { @@ -100,31 +97,28 @@ struct statdata_t num_memory_bits += it.second->width * it.second->size; } - for (auto &it : mod->cells_) + for (auto cell : mod->selected_cells()) { - if (!design->selected(mod, it.second)) - continue; - - RTLIL::IdString cell_type = it.second->type; + RTLIL::IdString cell_type = cell->type; if (width_mode) { - if (cell_type.in("$not", "$pos", "$neg", - "$logic_not", "$logic_and", "$logic_or", - "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", - "$lut", "$and", "$or", "$xor", "$xnor", - "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx", - "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt", - "$add", "$sub", "$mul", "$div", "$mod", "$pow", "$alu")) { - int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0; - int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0; - int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0; + if (cell_type.in(ID($not), ID($pos), ID($neg), + ID($logic_not), ID($logic_and), ID($logic_or), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), + ID($lut), ID($and), ID($or), ID($xor), ID($xnor), + ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx), + ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt), + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($alu))) { + int width_a = cell->hasPort(ID::A) ? GetSize(cell->getPort(ID::A)) : 0; + int width_b = cell->hasPort(ID::B) ? GetSize(cell->getPort(ID::B)) : 0; + int width_y = cell->hasPort(ID::Y) ? GetSize(cell->getPort(ID::Y)) : 0; cell_type = stringf("%s_%d", cell_type.c_str(), max<int>({width_a, width_b, width_y})); } - else if (cell_type.in("$mux", "$pmux")) - cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y"))); - else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr")) - cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q"))); + else if (cell_type.in(ID($mux), ID($pmux))) + cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Y))); + else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) + cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(cell->getPort(ID::Q))); } if (!cell_area.empty()) { @@ -157,7 +151,7 @@ struct statdata_t log(" Number of cells: %6d\n", num_cells); for (auto &it : num_cells_by_type) if (it.second) - log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second); + log(" %-26s %6d\n", log_id(it.first), it.second); if (!unknown_cell_area.empty()) { log("\n"); @@ -172,12 +166,12 @@ struct statdata_t if (tech == "xilinx") { - int lut6_cnt = num_cells_by_type["\\LUT6"]; - int lut5_cnt = num_cells_by_type["\\LUT5"]; - int lut4_cnt = num_cells_by_type["\\LUT4"]; - int lut3_cnt = num_cells_by_type["\\LUT3"]; - int lut2_cnt = num_cells_by_type["\\LUT2"]; - int lut1_cnt = num_cells_by_type["\\LUT1"]; + int lut6_cnt = num_cells_by_type[ID(LUT6)]; + int lut5_cnt = num_cells_by_type[ID(LUT5)]; + int lut4_cnt = num_cells_by_type[ID(LUT4)]; + int lut3_cnt = num_cells_by_type[ID(LUT3)]; + int lut2_cnt = num_cells_by_type[ID(LUT2)]; + int lut1_cnt = num_cells_by_type[ID(LUT1)]; int lc_cnt = 0; lc_cnt += lut6_cnt; @@ -235,7 +229,7 @@ struct statdata_t if (gate_costs.count(ctype)) tran_cnt += cnum * gate_costs.at(ctype); - else if (ctype.in("$_DFF_P_", "$_DFF_N_")) + else if (ctype.in(ID($_DFF_P_), ID($_DFF_N_))) tran_cnt += cnum * 16; else tran_cnt_exact = false; @@ -255,7 +249,7 @@ statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTL for (auto &it : num_cells_by_type) if (mod_stat.count(it.first) > 0) { - log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second); + log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, log_id(it.first), it.second); mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second; mod_data.num_cells -= it.second; } else { @@ -281,7 +275,7 @@ void read_liberty_cellarea(dict<IdString, double> &cell_area, string liberty_fil continue; LibertyAst *ar = cell->find("area"); - if (ar != NULL && !ar->value.empty()) + if (ar != nullptr && !ar->value.empty()) cell_area["\\" + cell->args[0]] = atof(ar->value.c_str()); } } @@ -319,7 +313,7 @@ struct StatPass : public Pass { log_header(design, "Printing statistics.\n"); bool width_mode = false; - RTLIL::Module *top_mod = NULL; + RTLIL::Module *top_mod = nullptr; std::map<RTLIL::IdString, statdata_t> mod_stat; dict<IdString, double> cell_area; string techname; @@ -342,9 +336,9 @@ struct StatPass : public Pass { continue; } if (args[argidx] == "-top" && argidx+1 < args.size()) { - if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0) + if (design->module(RTLIL::escape_id(args[argidx+1])) == nullptr) log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str()); - top_mod = design->modules_.at(RTLIL::escape_id(args[++argidx])); + top_mod = design->module(RTLIL::escape_id(args[++argidx])); continue; } break; @@ -357,25 +351,25 @@ struct StatPass : public Pass { for (auto mod : design->selected_modules()) { if (!top_mod && design->full_selection()) - if (mod->get_bool_attribute("\\top")) + if (mod->get_bool_attribute(ID::top)) top_mod = mod; statdata_t data(design, mod, width_mode, cell_area, techname); mod_stat[mod->name] = data; log("\n"); - log("=== %s%s ===\n", RTLIL::id2cstr(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); + log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false); } - if (top_mod != NULL && GetSize(mod_stat) > 1) + if (top_mod != nullptr && GetSize(mod_stat) > 1) { log("\n"); log("=== design hierarchy ===\n"); log("\n"); - log(" %-28s %6d\n", RTLIL::id2cstr(top_mod->name), 1); + log(" %-28s %6d\n", log_id(top_mod->name), 1); statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0); log("\n"); diff --git a/passes/cmds/torder.cc b/passes/cmds/torder.cc index 3c0eac8de..5748ff7f0 100644 --- a/passes/cmds/torder.cc +++ b/passes/cmds/torder.cc @@ -81,9 +81,9 @@ struct TorderPass : public Pass { continue; if (!noautostop && yosys_celltypes.cell_known(cell->type)) { - if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA")) + if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA)) continue; - if (cell->type == "$memrd" && conn.first == "\\DATA") + if (cell->type == ID($memrd) && conn.first == ID::DATA) continue; } diff --git a/passes/cmds/trace.cc b/passes/cmds/trace.cc index cf3e46ace..8446e27b3 100644 --- a/passes/cmds/trace.cc +++ b/passes/cmds/trace.cc @@ -35,7 +35,7 @@ struct TraceMonitor : public RTLIL::Monitor log("#TRACE# Module delete: %s\n", log_id(module)); } - void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE + void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, const RTLIL::SigSpec &sig) YS_OVERRIDE { log("#TRACE# Cell connect: %s.%s.%s = %s (was: %s)\n", log_id(cell->module), log_id(cell), log_id(port), log_signal(sig), log_signal(old_sig)); } |