From 398afd102e036000d9a7b19b08d4f474cb85bba1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:05:39 +1300 Subject: [PATCH] Refactor full_selection The `Design::selected_*()` methods no longer unconditionally skip boxed modules. Instead, selections are now box and design aware. The selection constructor now optionally takes a design pointer, and has a new `selects_boxes` flag. If the selection has an assigned design, then `Selection::selected_*()` will only return true for boxed modules if the selects_boxes flag is set. A warning is raised if a selection is checked and no design is set. Selections can change design via the `Selection::optimize()` method. Most places that iterate over `Design::modules()` and check `Selection::selected_module()` should instead use `Design::selected_modules()`. Since boxed modules should only ever be selected explicitly, and `full_selection` (now) refers to all non-boxed modules, `Selection::optimize()` will clear the `full_selection` flag if the `selects_boxes` flag is enabled, and instead explicitly selects all modules (including boxed modules). This also means that `full_selection` will only get automatically applied to a design without any boxed modules. These changes necessitated a number of changes to `select.cc` in order to support this functionality when operating on selections, in particular when combining selections (e.g. by union or difference). To minimize redundancy, a number of places that previously iterated over `design->modules()` now push the current selection to the design, use `design->selected_modules()`, and then pop the selection when done. Introduce `RTLIL::NamedObject`, to allow for iterating over all members of a module with a single iterator instead of needing to iterate over wires, cells, memories, and processes separately. Also implement `Module::selected_{memories, processes, members}()` to match wires and cells methods. The `selected_members()` method combines each of the other `selected_*()` methods into a single list. --- kernel/rtlil.cc | 90 +++++++++++++++++--- kernel/rtlil.h | 29 ++++--- passes/cmds/select.cc | 192 ++++++++++++++++++++++-------------------- 3 files changed, 197 insertions(+), 114 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3b9a4a8b1..8c40e83d3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -766,8 +766,21 @@ vector RTLIL::AttrObject::get_intvec_attribute(const RTLIL::IdString &id) c return data; } +bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const +{ + if (current_design != nullptr) { + auto module = current_design->module(mod_name); + return module && module->get_blackbox_attribute(); + } else { + log_warning("Unable to check if module is boxed for null design.\n"); + return false; + } +} + bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -779,6 +792,8 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -788,6 +803,8 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const { + if (!selects_boxes && boxed_module(mod_name)) + return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -800,6 +817,19 @@ bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RT void RTLIL::Selection::optimize(RTLIL::Design *design) { + if (design != current_design) { + current_design = design; + } + + if (selects_boxes && full_selection) { + selected_modules.clear(); + selected_members.clear(); + full_selection = false; + for (auto mod : current_design->modules()) { + selected_modules.insert(mod->name); + } + return; + } if (full_selection) { selected_modules.clear(); selected_members.clear(); @@ -810,7 +840,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (design->modules_.count(mod_name) == 0) + if (current_design->modules_.count(mod_name) == 0) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -819,7 +849,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (design->modules_.count(it.first) == 0) + if (current_design->modules_.count(it.first) == 0) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -827,7 +857,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) { del_list.clear(); for (auto memb_name : it.second) - if (design->modules_[it.first]->count_id(memb_name) == 0) + if (current_design->modules_[it.first]->count_id(memb_name) == 0) del_list.push_back(memb_name); for (auto memb_name : del_list) it.second.erase(memb_name); @@ -838,8 +868,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) if (it.second.size() == 0) del_list.push_back(it.first); - else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() + - design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size()) + else if (it.second.size() == current_design->modules_[it.first]->wires_.size() + current_design->modules_[it.first]->memories.size() + + current_design->modules_[it.first]->cells_.size() + current_design->modules_[it.first]->processes.size()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -848,7 +878,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (selected_modules.size() == design->modules_.size()) { + if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) { full_selection = true; selected_modules.clear(); selected_members.clear(); @@ -863,7 +893,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - selection_stack.push_back(RTLIL::Selection()); + selection_stack.push_back(RTLIL::Selection(true, false, this)); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -1127,7 +1157,7 @@ std::vector RTLIL::Design::selected_modules() const std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_module(it.first) && !it.second->get_blackbox_attribute()) + if (selected_module(it.first)) result.push_back(it.second); return result; } @@ -1137,7 +1167,7 @@ std::vector RTLIL::Design::selected_whole_modules() const std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute()) + if (selected_whole_module(it.first)) result.push_back(it.second); return result; } @@ -1146,13 +1176,13 @@ std::vector RTLIL::Design::selected_whole_modules_warn(bool incl { std::vector result; result.reserve(modules_.size()); - for (auto &it : modules_) - if (it.second->get_blackbox_attribute(include_wb)) - continue; - else if (selected_whole_module(it.first)) + for (auto &it : modules_) { + log_assert(selection_stack.size() > 0 || !it.second->get_blackbox_attribute(include_wb)); + if (selected_whole_module(it.first)) result.push_back(it.second); else if (selected_module(it.first)) log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); + } return result; } @@ -2431,6 +2461,40 @@ std::vector RTLIL::Module::selected_cells() const return result; } +std::vector RTLIL::Module::selected_memories() const +{ + std::vector result; + result.reserve(memories.size()); + for (auto &it : memories) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Module::selected_processes() const +{ + std::vector result; + result.reserve(processes.size()); + for (auto &it : processes) + if (design->selected(this, it.second)) + result.push_back(it.second); + return result; +} + +std::vector RTLIL::Module::selected_members() const +{ + std::vector result; + auto cells = selected_cells(); + auto memories = selected_memories(); + auto wires = selected_wires(); + auto processes = selected_processes(); + result.insert(result.end(), cells.begin(), cells.end()); + result.insert(result.end(), memories.begin(), memories.end()); + result.insert(result.end(), wires.begin(), wires.end()); + result.insert(result.end(), processes.begin(), processes.end()); + return result; +} + void RTLIL::Module::add(RTLIL::Wire *wire) { log_assert(!wire->name.empty()); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f1bd96be7..ee75237f3 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -58,6 +58,7 @@ namespace RTLIL struct Const; struct AttrObject; + struct NamedObject; struct Selection; struct Monitor; struct Design; @@ -869,6 +870,11 @@ struct RTLIL::AttrObject vector get_intvec_attribute(const RTLIL::IdString &id) const; }; +struct RTLIL::NamedObject : public RTLIL::AttrObject +{ + RTLIL::IdString name; +}; + struct RTLIL::SigChunk { RTLIL::Wire *wire; @@ -1135,11 +1141,14 @@ public: struct RTLIL::Selection { bool full_selection; + bool selects_boxes; pool selected_modules; dict> selected_members; + RTLIL::Design *current_design; - Selection(bool full = true) : full_selection(full) { } + Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { } + bool boxed_module(const RTLIL::IdString &mod_name) const; bool selected_module(const RTLIL::IdString &mod_name) const; bool selected_whole_module(const RTLIL::IdString &mod_name) const; bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; @@ -1290,7 +1299,7 @@ struct RTLIL::Design #endif }; -struct RTLIL::Module : public RTLIL::AttrObject +struct RTLIL::Module : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1313,7 +1322,6 @@ public: std::vector connections_; std::vector bindings_; - RTLIL::IdString name; idict avail_parameters; dict parameter_default_values; dict memories; @@ -1360,6 +1368,9 @@ public: std::vector selected_wires() const; std::vector selected_cells() const; + std::vector selected_memories() const; + std::vector selected_processes() const; + std::vector selected_members() const; template bool selected(T *member) const { return design->selected_member(name, member->name); @@ -1645,7 +1656,7 @@ namespace RTLIL_BACKEND { void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); } -struct RTLIL::Wire : public RTLIL::AttrObject +struct RTLIL::Wire : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1668,7 +1679,6 @@ public: void operator=(RTLIL::Wire &other) = delete; RTLIL::Module *module; - RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output, upto, is_signed; @@ -1697,14 +1707,13 @@ inline int GetSize(RTLIL::Wire *wire) { return wire->width; } -struct RTLIL::Memory : public RTLIL::AttrObject +struct RTLIL::Memory : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } Memory(); - RTLIL::IdString name; int width, start_offset, size; #ifdef WITH_PYTHON ~Memory(); @@ -1712,7 +1721,7 @@ struct RTLIL::Memory : public RTLIL::AttrObject #endif }; -struct RTLIL::Cell : public RTLIL::AttrObject +struct RTLIL::Cell : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1729,7 +1738,6 @@ public: void operator=(RTLIL::Cell &other) = delete; RTLIL::Module *module; - RTLIL::IdString name; RTLIL::IdString type; dict connections_; dict parameters; @@ -1822,7 +1830,7 @@ struct RTLIL::SyncRule RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process : public RTLIL::AttrObject +struct RTLIL::Process : public RTLIL::NamedObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1834,7 +1842,6 @@ protected: ~Process(); public: - RTLIL::IdString name; RTLIL::Module *module; RTLIL::CaseRule root_case; std::vector syncs; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index aec4c964b..1b1b7ca43 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,6 +141,20 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } +static void full_select_no_box(RTLIL::Design *design, RTLIL::Selection &lhs) +{ + if (!lhs.full_selection) + return; + + lhs.current_design = design; + lhs.selected_modules.clear(); + for (auto mod : design->modules()) { + if (mod->get_blackbox_attribute()) + continue; + lhs.selected_modules.insert(mod->name); + } +} + static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { if (lhs.full_selection) { @@ -150,7 +164,7 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) return; } - if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { + if (!lhs.selects_boxes && lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { lhs.full_selection = true; return; } @@ -159,6 +173,8 @@ static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) for (auto mod : design->modules()) { + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) + continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) { @@ -212,7 +228,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false); + lhs = RTLIL::Selection(false, false, design); while (!objects.empty() && count-- > 0) { @@ -243,7 +259,7 @@ 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); + RTLIL::Selection new_sel(false, lhs.selects_boxes, design); for (auto mod : design->modules()) if (lhs.selected_module(mod->name)) for (auto cell : mod->cells()) @@ -254,7 +270,7 @@ static void select_op_cells_to_modules(RTLIL::Design *design, RTLIL::Selection & static void select_op_module_to_cells(RTLIL::Design *design, RTLIL::Selection &lhs) { - RTLIL::Selection new_sel(false); + RTLIL::Selection new_sel(false, lhs.selects_boxes, design); for (auto mod : design->modules()) for (auto cell : mod->cells()) if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) @@ -274,6 +290,8 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) { for (auto mod : design->modules()) { + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) + continue; if (lhs.selected_whole_module(mod->name)) continue; if (!lhs.selected_module(mod->name)) @@ -292,18 +310,32 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) } } -static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) +static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (rhs.selects_boxes) { + if (lhs.full_selection) { + full_select_no_box(design, lhs); + lhs.full_selection = false; + } + lhs.selects_boxes = true; + } + else if (lhs.full_selection) + return; + if (rhs.full_selection) { - lhs.full_selection = true; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + if (lhs.selects_boxes) { + auto new_rhs = RTLIL::Selection(rhs); + full_select_no_box(design, new_rhs); + for (auto mod : new_rhs.selected_modules) + lhs.selected_modules.insert(mod); + } else { + lhs.full_selection = true; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + } return; } - if (lhs.full_selection) - return; - for (auto &it : rhs.selected_members) for (auto &it2 : it.second) lhs.selected_members[it.first].insert(it2); @@ -317,18 +349,26 @@ static void select_op_union(RTLIL::Design*, RTLIL::Selection &lhs, const RTLIL:: static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { if (rhs.full_selection) { - lhs.full_selection = false; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); + if (lhs.selects_boxes) { + auto new_rhs = RTLIL::Selection(rhs); + full_select_no_box(design, new_rhs); + for (auto mod : new_rhs.selected_modules) { + lhs.selected_modules.erase(mod); + lhs.selected_members.erase(mod); + } + } else { + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + } return; } if (lhs.full_selection) { - if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) + if (rhs.empty()) return; + full_select_no_box(design, lhs); lhs.full_selection = false; - for (auto mod : design->modules()) - lhs.selected_modules.insert(mod->name); } for (auto &it : rhs.selected_modules) { @@ -366,7 +406,7 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { - if (rhs.full_selection) + if (rhs.full_selection && !lhs.selects_boxes) return; if (lhs.full_selection) { @@ -377,27 +417,28 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co std::vector del_list; - for (auto &it : lhs.selected_modules) - if (rhs.selected_modules.count(it) == 0) { - if (rhs.selected_members.count(it) > 0) - for (auto &it2 : rhs.selected_members.at(it)) - lhs.selected_members[it].insert(it2); - del_list.push_back(it); - } + for (auto mod_name : lhs.selected_modules) { + if (rhs.selected_whole_module(mod_name)) + continue; + if (rhs.selected_module(mod_name)) + for (auto memb_name : rhs.selected_members.at(mod_name)) + lhs.selected_members[mod_name].insert(memb_name); + del_list.push_back(mod_name); + } for (auto &it : del_list) lhs.selected_modules.erase(it); del_list.clear(); for (auto &it : lhs.selected_members) { - if (rhs.selected_modules.count(it.first) > 0) + if (rhs.selected_whole_module(it.first)) continue; - if (rhs.selected_members.count(it.first) == 0) { + if (!rhs.selected_module(it.first)) { del_list.push_back(it.first); continue; } std::vector del_list2; for (auto &it2 : it.second) - if (rhs.selected_members.at(it.first).count(it2) == 0) + if (!rhs.selected_member(it.first, it2)) del_list2.push_back(it2); for (auto &it2 : del_list2) it.second.erase(it2); @@ -796,15 +837,16 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp } } - work_stack.push_back(RTLIL::Selection()); + bool full_selection = (arg == "*" && arg_mod == "*"); + work_stack.push_back(RTLIL::Selection(full_selection, select_blackboxes, design)); RTLIL::Selection &sel = work_stack.back(); - if (arg == "*" && arg_mod == "*" && select_blackboxes) { + if (sel.full_selection) { + if (sel.selects_boxes) sel.optimize(design); select_filter_active_mod(design, work_stack.back()); return; } - sel.full_selection = false; for (auto mod : design->modules()) { if (!select_blackboxes && mod->get_blackbox_attribute()) @@ -958,24 +1000,12 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, bool whole_modules = false) { std::string desc = "Selection contains:\n"; - for (auto mod : design->modules()) + for (auto mod : design->selected_modules()) { - if (sel->selected_module(mod->name)) { - if (whole_modules && sel->selected_whole_module(mod->name)) - desc += stringf("%s\n", id2cstr(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)); - } + if (whole_modules && sel->selected_whole_module(mod->name)) + desc += stringf("%s\n", id2cstr(mod->name)); + for (auto it : mod->selected_members()) + desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); } return desc; } @@ -1001,7 +1031,7 @@ void handle_extra_select_args(Pass *pass, const vector &args, size_t arg work_stack.pop_back(); } if (work_stack.empty()) - design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.push_back(RTLIL::Selection(false, false, design)); else design->selection_stack.push_back(work_stack.back()); } @@ -1017,7 +1047,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection(false); + return RTLIL::Selection(false, false, design); return work_stack.back(); } @@ -1444,13 +1474,13 @@ struct SelectPass : public Pass { log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection_stack.back() = RTLIL::Selection(false); + design->selection_stack.back() = RTLIL::Selection(false, false, design); return; } @@ -1465,28 +1495,17 @@ struct SelectPass : public Pass { 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(); + design->selection_stack.push_back(work_stack.back()); + RTLIL::Selection *sel = &design->selection_stack.back(); sel->optimize(design); - for (auto mod : design->modules()) + for (auto mod : design->selected_modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); - if (sel->selected_module(mod->name) && !list_mod_mode) { - 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 (!list_mod_mode) + for (auto it : mod->selected_members()) + LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)) } if (count_mode) { @@ -1495,6 +1514,8 @@ struct SelectPass : public Pass { } if (f != nullptr) fclose(f); + if (work_stack.size() > 0) + design->selection_stack.pop_back(); #undef LOG_OBJECT return; } @@ -1553,23 +1574,13 @@ struct SelectPass : public Pass { if (work_stack.size() == 0) log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); + design->selection_stack.push_back(*sel); sel->optimize(design); - for (auto mod : design->modules()) - if (sel->selected_module(mod->name)) { - module_count++; - for (auto wire : mod->wires()) - if (sel->selected_member(mod->name, wire->name)) - total_count++; - for (auto &it : mod->memories) - if (sel->selected_member(mod->name, it.first)) - total_count++; - for (auto cell : mod->cells()) - if (sel->selected_member(mod->name, cell->name)) - total_count++; - for (auto &it : mod->processes) - if (sel->selected_member(mod->name, it.first)) - total_count++; - } + for (auto mod : design->selected_modules()) { + module_count++; + for ([[maybe_unused]] auto member_name : mod->selected_members()) + total_count++; + } if (assert_modcount >= 0 && assert_modcount != module_count) { log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n", @@ -1593,13 +1604,14 @@ struct SelectPass : public Pass { log_error("Assertion failed: selection contains %d elements, less than the minimum number %d:%s\n%s", total_count, assert_min, sel_str.c_str(), desc.c_str()); } + design->selection_stack.pop_back(); return; } if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection(false); + design->selection_vars[set_name] = RTLIL::Selection(false, false, design); else design->selection_vars[set_name] = work_stack.back(); return; @@ -1665,7 +1677,7 @@ struct CdPass : public Pass { log_cmd_error("Invalid number of arguments.\n"); if (args.size() == 1 || args[1] == "/") { - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); return; } @@ -1674,7 +1686,7 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->selection_stack.back() = RTLIL::Selection(true); + design->selection_stack.back() = RTLIL::Selection(true, false, design); design->selected_active_module = std::string(); while (1) @@ -1691,7 +1703,7 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(); + design->selection_stack.back() = RTLIL::Selection(true, false, design); select_filter_active_mod(design, design->selection_stack.back()); design->selection_stack.back().optimize(design); return; @@ -1710,7 +1722,7 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(); + design->selection_stack.back() = RTLIL::Selection(true, false, design); select_filter_active_mod(design, design->selection_stack.back()); design->selection_stack.back().optimize(design); return;