From 428dbdcc60cb92242f8a8368e682ef2574f89065 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:44:45 +1300 Subject: [PATCH 01/22] 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 e9b648b0433..b700e94db94 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -760,8 +760,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) @@ -773,6 +786,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) @@ -782,6 +797,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) @@ -794,6 +811,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(); @@ -804,7 +834,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); } @@ -813,7 +843,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); @@ -821,7 +851,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); @@ -832,8 +862,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); @@ -842,7 +872,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(); @@ -857,7 +887,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)); @@ -1121,7 +1151,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; } @@ -1131,7 +1161,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; } @@ -1140,13 +1170,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; } @@ -2376,6 +2406,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 0f3984ab8fc..acc43dc2376 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; @@ -839,6 +840,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; @@ -1094,11 +1100,14 @@ struct RTLIL::SigSpec 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; @@ -1249,7 +1258,7 @@ struct RTLIL::Design #endif }; -struct RTLIL::Module : public RTLIL::AttrObject +struct RTLIL::Module : public RTLIL::NamedObject { unsigned int hashidx_; unsigned int hash() const { return hashidx_; } @@ -1272,7 +1281,6 @@ struct RTLIL::Module : public RTLIL::AttrObject std::vector connections_; std::vector bindings_; - RTLIL::IdString name; idict avail_parameters; dict parameter_default_values; dict memories; @@ -1315,6 +1323,9 @@ struct RTLIL::Module : public RTLIL::AttrObject 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); @@ -1600,7 +1611,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 { unsigned int hashidx_; unsigned int hash() const { return hashidx_; } @@ -1623,7 +1634,6 @@ struct RTLIL::Wire : public RTLIL::AttrObject 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; @@ -1639,14 +1649,13 @@ inline int GetSize(RTLIL::Wire *wire) { return wire->width; } -struct RTLIL::Memory : public RTLIL::AttrObject +struct RTLIL::Memory : public RTLIL::NamedObject { unsigned int hashidx_; unsigned int hash() const { return hashidx_; } Memory(); - RTLIL::IdString name; int width, start_offset, size; #ifdef WITH_PYTHON ~Memory(); @@ -1654,7 +1663,7 @@ struct RTLIL::Memory : public RTLIL::AttrObject #endif }; -struct RTLIL::Cell : public RTLIL::AttrObject +struct RTLIL::Cell : public RTLIL::NamedObject { unsigned int hashidx_; unsigned int hash() const { return hashidx_; } @@ -1671,7 +1680,6 @@ struct RTLIL::Cell : public RTLIL::AttrObject void operator=(RTLIL::Cell &other) = delete; RTLIL::Module *module; - RTLIL::IdString name; RTLIL::IdString type; dict connections_; dict parameters; @@ -1764,7 +1772,7 @@ struct RTLIL::SyncRule RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process : public RTLIL::AttrObject +struct RTLIL::Process : public RTLIL::NamedObject { unsigned int hashidx_; unsigned int hash() const { return hashidx_; } @@ -1776,7 +1784,6 @@ struct RTLIL::Process : public RTLIL::AttrObject ~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 aec4c964b28..1b1b7ca4304 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,17 +310,31 @@ 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.full_selection) { - lhs.full_selection = true; - lhs.selected_modules.clear(); - lhs.selected_members.clear(); - return; + 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 (lhs.full_selection) + if (rhs.full_selection) { + 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; + } for (auto &it : rhs.selected_members) for (auto &it2 : it.second) @@ -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; From 1d1833439ca70bfa352127ac4c3bd2c1d29d69f1 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:44:50 +1300 Subject: [PATCH 02/22] tests/select: Add tests for selections with boxes --- tests/select/{blackboxes.ys => boxes.v} | 12 -------- tests/select/boxes_dummy.ys | 13 +++++++++ tests/select/boxes_equals_clean.ys | 7 +++++ tests/select/boxes_equals_name.ys | 7 +++++ tests/select/boxes_equals_operators.ys | 38 +++++++++++++++++++++++++ tests/select/boxes_equals_pattern.ys | 7 +++++ tests/select/boxes_equals_wildcard.ys | 6 ++++ tests/select/boxes_no_equals.ys | 7 +++++ tests/select/boxes_no_equals_clean.ys | 18 ++++++++++++ 9 files changed, 103 insertions(+), 12 deletions(-) rename tests/select/{blackboxes.ys => boxes.v} (51%) create mode 100644 tests/select/boxes_dummy.ys create mode 100644 tests/select/boxes_equals_clean.ys create mode 100644 tests/select/boxes_equals_name.ys create mode 100644 tests/select/boxes_equals_operators.ys create mode 100644 tests/select/boxes_equals_pattern.ys create mode 100644 tests/select/boxes_equals_wildcard.ys create mode 100644 tests/select/boxes_no_equals.ys create mode 100644 tests/select/boxes_no_equals_clean.ys diff --git a/tests/select/blackboxes.ys b/tests/select/boxes.v similarity index 51% rename from tests/select/blackboxes.ys rename to tests/select/boxes.v index 9bfe92c6bf8..696b265230a 100644 --- a/tests/select/blackboxes.ys +++ b/tests/select/boxes.v @@ -1,4 +1,3 @@ -read_verilog -specify < Date: Wed, 20 Nov 2024 09:10:57 +1300 Subject: [PATCH 03/22] Unify Design::selected_modules variants Now uses two enums, one to control whether or not to include partially selected modules (and what to do if they are encountered), and one to control whether or not to include boxed modules (and what to do if they are encountered). Mark Design::selected{modules, whole_modules}() deprecated and make them provide warnings on boxes. There are a lot of places that use them and I can't always tell which ones support boxed modules and which don't. --- kernel/rtlil.cc | 73 +++++++++++++++++++++++++++++++------------------ kernel/rtlil.h | 41 +++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 29 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index b700e94db94..3b19094de7e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1146,37 +1146,58 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } -std::vector RTLIL::Design::selected_modules() const -{ - std::vector result; - result.reserve(modules_.size()); - for (auto &it : modules_) - if (selected_module(it.first)) - result.push_back(it.second); - return result; -} -std::vector RTLIL::Design::selected_whole_modules() const +std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { + bool include_partials = partials == RTLIL::SELECT_ALL; + bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) == 0; + bool ignore_wb = (partials & RTLIL::SB_INCL_WB) != 0; std::vector result; result.reserve(modules_.size()); for (auto &it : modules_) - if (selected_whole_module(it.first)) - result.push_back(it.second); - return result; -} - -std::vector RTLIL::Design::selected_whole_modules_warn(bool include_wb) const -{ - std::vector result; - result.reserve(modules_.size()); - 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)); - } + if (selected_whole_module(it.first) || (include_partials && selected_module(it.first))) { + if (!(exclude_boxes && it.second->get_blackbox_attribute(ignore_wb))) + result.push_back(it.second); + else + switch (boxes) + { + case RTLIL::SB_UNBOXED_WARN: + log_warning("Ignoring boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_WARN: + log_warning("Ignoring blackbox module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_UNBOXED_ERR: + log_error("Unsupported boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_ERR: + log_error("Unsupported blackbox module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_UNBOXED_CMDERR: + log_cmd_error("Unsupported boxed module %s.\n", log_id(it.first)); + break; + case RTLIL::SB_EXCL_BB_CMDERR: + log_cmd_error("Unsupported blackbox module %s.\n", log_id(it.first)); + break; + default: + break; + } + } else if (!include_partials && selected_module(it.first)) { + switch(partials) + { + case RTLIL::SELECT_WHOLE_WARN: + log_warning("Ignoring partially selected module %s.\n", log_id(it.first)); + break; + case RTLIL::SELECT_WHOLE_ERR: + log_error("Unsupported partially selected module %s.\n", log_id(it.first)); + break; + case RTLIL::SELECT_WHOLE_CMDERR: + log_cmd_error("Unsupported partially selected module %s.\n", log_id(it.first)); + break; + default: + break; + } + } return result; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index acc43dc2376..92167b19dac 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -56,6 +56,30 @@ namespace RTLIL CONST_FLAG_REAL = 4 // only used for parameters }; + enum SelectPartials : unsigned char { + SELECT_ALL = 0, // include partial modules + SELECT_WHOLE_ONLY = 1, // ignore partial modules + SELECT_WHOLE_WARN = 2, // call log_warning on partial module + SELECT_WHOLE_ERR = 3, // call log_error on partial module + SELECT_WHOLE_CMDERR = 4 // call log_cmd_error on partial module + }; + + enum SelectBoxes : unsigned char { + SB_ALL = 0, // include boxed modules + SB_WARN = 1, // helper for log_warning + SB_ERR = 2, // helper for log_error + SB_CMDERR = 3, // helper for log_cmd_error + SB_UNBOXED_ONLY = 4, // ignore boxed modules + SB_UNBOXED_WARN = 5, // call log_warning on boxed module + SB_UNBOXED_ERR = 6, // call log_error on boxed module + SB_UNBOXED_CMDERR = 7, // call log_cmd_error on boxed module + SB_INCL_WB = 8, // helper for white boxes + SB_EXCL_BB_ONLY = 12, // ignore black boxes, but not white boxes + SB_EXCL_BB_WARN = 13, // call log_warning on black boxed module + SB_EXCL_BB_ERR = 14, // call log_error on black boxed module + SB_EXCL_BB_CMDERR = 15 // call log_cmd_error on black boxed module + }; + struct Const; struct AttrObject; struct NamedObject; @@ -1250,9 +1274,20 @@ struct RTLIL::Design } - std::vector selected_modules() const; - std::vector selected_whole_modules() const; - std::vector selected_whole_modules_warn(bool include_wb = false) const; + std::vector selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes = SB_ALL) const; + + [[deprecated("Use selected_unboxed_modules() to maintain prior behaviour, or consider one of the other selected module helpers.")]] + std::vector selected_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } + std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } + std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } + std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } + + [[deprecated("Use select_unboxed_whole_modules() to maintain prior behaviour, or consider one of the other selected whole module helpers.")]] + std::vector selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_WARN); } + std::vector all_selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_ALL); } + std::vector selected_whole_modules_warn(bool include_wb = false) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } + std::vector selected_unboxed_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_ONLY); } + std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } #ifdef WITH_PYTHON static std::map *get_all_designs(void); #endif From 334cedeb5cd7294ff827ee9228bee8c1f14ce163 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:22:44 +1300 Subject: [PATCH 04/22] Can clean boxed modules If a selection contains a boxed module, but does not select boxes, it should be removed from the selection. --- kernel/rtlil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3b19094de7e..9ecf7c90bff 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -834,7 +834,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto mod_name : selected_modules) { - if (current_design->modules_.count(mod_name) == 0) + if (current_design->modules_.count(mod_name) == 0 || (!selects_boxes && boxed_module(mod_name))) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -843,7 +843,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (current_design->modules_.count(it.first) == 0) + if (current_design->modules_.count(it.first) == 0 || (!selects_boxes && boxed_module(it.first))) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); From a3b6b603f2b0cfcbea0ede2c6b7473e7d2af151b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:27:35 +1300 Subject: [PATCH 05/22] rtlil: Add selection helpers New methods on Design to push/pop selection instead of accessing the selection stack directly. Includes methods for pushing a full/complete/empty selection. Also helper methods on modules to check `is_selected` and `is_selected_whole`. --- kernel/rtlil.cc | 39 +++++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 9 +++++++++ 2 files changed, 48 insertions(+) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 9ecf7c90bff..3cf760de0f0 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1146,6 +1146,35 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } +void RTLIL::Design::push_selection(RTLIL::Selection sel) +{ + sel.current_design = this; + selection_stack.push_back(sel); +} + +void RTLIL::Design::push_empty_selection() +{ + RTLIL::Selection sel(false, false, this); + push_selection(sel); +} + +void RTLIL::Design::push_full_selection() +{ + RTLIL::Selection sel(true, false, this); + push_selection(sel); +} + +void RTLIL::Design::push_complete_selection() +{ + RTLIL::Selection sel(true, true, this); + sel.optimize(this); + push_selection(sel); +} + +void RTLIL::Design::pop_selection() +{ + selection_stack.pop_back(); +} std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { @@ -2407,6 +2436,16 @@ bool RTLIL::Module::has_processes_warn() const return !processes.empty(); } +bool RTLIL::Module::is_selected() const +{ + return design->selected_module(this->name); +} + +bool RTLIL::Module::is_selected_whole() const +{ + return design->selected_whole_module(this->name); +} + std::vector RTLIL::Module::selected_wires() const { std::vector result; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 92167b19dac..b89f4698841 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1239,6 +1239,12 @@ struct RTLIL::Design bool selected_module(RTLIL::Module *mod) const; bool selected_whole_module(RTLIL::Module *mod) const; + void push_selection(RTLIL::Selection sel); + void push_empty_selection(); + void push_full_selection(); + void push_complete_selection(); + void pop_selection(); + RTLIL::Selection &selection() { return selection_stack.back(); } @@ -1356,6 +1362,9 @@ struct RTLIL::Module : public RTLIL::NamedObject bool has_memories_warn() const; bool has_processes_warn() const; + bool is_selected() const; + bool is_selected_whole() const; + std::vector selected_wires() const; std::vector selected_cells() const; std::vector selected_memories() const; From c4f0ad99b2de54f74f2a645336d382132254cf0e Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:38:33 +1300 Subject: [PATCH 06/22] Use selection helpers Catch more uses of selection constructor without assigning a design. --- backends/rtlil/rtlil_backend.cc | 4 +- .../source/code_examples/extensions/my_cmd.cc | 4 +- .../extending_yosys/extensions.rst | 2 +- kernel/driver.cc | 2 +- kernel/register.cc | 24 ++++---- kernel/rtlil.cc | 8 +-- kernel/rtlil.h | 6 +- kernel/yosys.cc | 10 ++-- passes/cmds/add.cc | 2 +- passes/cmds/design.cc | 6 +- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 60 ++++++++++--------- passes/cmds/show.cc | 8 +-- passes/cmds/stat.cc | 2 +- passes/cmds/viz.cc | 4 +- passes/hierarchy/submod.cc | 2 +- passes/sat/cutpoint.cc | 2 +- passes/techmap/abc9.cc | 4 +- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/abc_new.cc | 4 +- passes/techmap/aigmap.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- 22 files changed, 84 insertions(+), 78 deletions(-) diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index 113f1a61513..ae60ee6c704 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -304,8 +304,8 @@ void RTLIL_BACKEND::dump_conn(std::ostream &f, std::string indent, const RTLIL:: void RTLIL_BACKEND::dump_module(std::ostream &f, std::string indent, RTLIL::Module *module, RTLIL::Design *design, bool only_selected, bool flag_m, bool flag_n) { - bool print_header = flag_m || design->selected_whole_module(module->name); - bool print_body = !flag_n || !design->selected_whole_module(module->name); + bool print_header = flag_m || module->is_selected_whole(); + bool print_body = !flag_n || !module->is_selected_whole(); if (print_header) { diff --git a/docs/source/code_examples/extensions/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc index 36ddbe1758f..e6660469c64 100644 --- a/docs/source/code_examples/extensions/my_cmd.cc +++ b/docs/source/code_examples/extensions/my_cmd.cc @@ -51,10 +51,10 @@ struct Test2Pass : public Pass { Test2Pass() : Pass("test2", "demonstrating sigmap on test module") { } void execute(std::vector, RTLIL::Design *design) override { - if (design->selection_stack.back().empty()) + if (design->selection().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); - RTLIL::Module *module = design->modules_.at("\\test"); + RTLIL::Module *module = design->module("\\test"); RTLIL::SigSpec a(module->wire("\\a")), x(module->wire("\\x")), y(module->wire("\\y")); log("%d %d %d\n", a == x, x == y, y == a); // will print "0 0 0" diff --git a/docs/source/yosys_internals/extending_yosys/extensions.rst b/docs/source/yosys_internals/extending_yosys/extensions.rst index 4063641d479..ecfe95fd43a 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -241,7 +241,7 @@ Use ``log_cmd_error()`` to report a recoverable error: .. code:: C++ - if (design->selection_stack.back().empty()) + if (design->selection().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); Use ``log_assert()`` and ``log_abort()`` instead of ``assert()`` and ``abort()``. diff --git a/kernel/driver.cc b/kernel/driver.cc index 65f09099303..23bdf2400c1 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -106,7 +106,7 @@ void run(const char *command) log_last_error = ""; } catch (...) { while (GetSize(yosys_get_design()->selection_stack) > selSize) - yosys_get_design()->selection_stack.pop_back(); + yosys_get_design()->pop_selection(); throw; } } diff --git a/kernel/register.cc b/kernel/register.cc index d6e765ce416..627becef562 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -318,18 +318,18 @@ void Pass::call(RTLIL::Design *design, std::vector args) pass_register[args[0]]->execute(args, design); pass_register[args[0]]->post_execute(state); while (design->selection_stack.size() > orig_sel_stack_pos) - design->selection_stack.pop_back(); + design->pop_selection(); } void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command) { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(selection); + design->push_selection(selection); Pass::call(design, command); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -337,11 +337,11 @@ void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &sele { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module.clear(); - design->selection_stack.push_back(selection); + design->push_selection(selection); Pass::call(design, args); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -349,12 +349,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::str { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->selection_stack.push_back(RTLIL::Selection(false)); - design->selection_stack.back().select(module); + design->push_empty_selection(); + design->select(module); Pass::call(design, command); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -362,12 +362,12 @@ void Pass::call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::vec { std::string backup_selected_active_module = design->selected_active_module; design->selected_active_module = module->name.str(); - design->selection_stack.push_back(RTLIL::Selection(false)); - design->selection_stack.back().select(module); + design->push_empty_selection(); + design->select(module); Pass::call(design, args); - design->selection_stack.pop_back(); + design->pop_selection(); design->selected_active_module = backup_selected_active_module; } @@ -745,7 +745,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f } while (design->selection_stack.size() > orig_sel_stack_pos) - design->selection_stack.pop_back(); + design->pop_selection(); } struct SimHelper { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 3cf760de0f0..95e6014137f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -887,7 +887,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - selection_stack.push_back(RTLIL::Selection(true, false, this)); + push_full_selection(); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -1115,7 +1115,7 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_module(mod_name); + return selection().selected_module(mod_name); } bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const @@ -1124,7 +1124,7 @@ bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_whole_module(mod_name); + return selection().selected_whole_module(mod_name); } bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL::IdString& memb_name) const @@ -1133,7 +1133,7 @@ bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL return false; if (selection_stack.size() == 0) return true; - return selection_stack.back().selected_member(mod_name, memb_name); + return selection().selected_member(mod_name, memb_name); } bool RTLIL::Design::selected_module(RTLIL::Module *mod) const diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b89f4698841..1bfe8c31323 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1254,7 +1254,7 @@ struct RTLIL::Design } bool full_selection() const { - return selection_stack.back().full_selection; + return selection().full_selection; } template bool selected(T1 *module) const { @@ -1267,14 +1267,14 @@ struct RTLIL::Design template void select(T1 *module) { if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection_stack.back(); + RTLIL::Selection &sel = selection(); sel.select(module); } } template void select(T1 *module, T2 *member) { if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection_stack.back(); + RTLIL::Selection &sel = selection(); sel.select(module, member); } } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 774c7f37dc4..35cc81c5e2c 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -674,11 +674,11 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); - if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { + if (!design->selection_stack.empty() && !design->full_selection()) { if (design->selected_active_module.empty()) str += "*"; - else if (design->selection_stack.back().selected_modules.size() != 1 || design->selection_stack.back().selected_members.size() != 0 || - design->selection_stack.back().selected_modules.count(design->selected_active_module) == 0) + else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || + design->selection().selected_modules.count(design->selected_active_module) == 0) str += "*"; } snprintf(buffer, 100, "%s> ", str.c_str()); @@ -799,7 +799,7 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a if (in_repl) { auto design = yosys_get_design(); while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); + design->pop_selection(); log_reset_stack(); } Tcl_SetResult(interp, (char *)"Yosys command produced an error", TCL_STATIC); @@ -1458,7 +1458,7 @@ void shell(RTLIL::Design *design) Pass::call(design, command); } catch (log_cmd_error_exception) { while (design->selection_stack.size() > 1) - design->selection_stack.pop_back(); + design->pop_selection(); log_reset_stack(); } design->check(); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index c0951725403..833d6006d03 100644 --- a/passes/cmds/add.cc +++ b/passes/cmds/add.cc @@ -102,7 +102,7 @@ static void add_wire(RTLIL::Design *design, RTLIL::Module *module, std::string n RTLIL::Module *mod = design->module(cell->type); if (mod == nullptr) continue; - if (!design->selected_whole_module(mod->name)) + if (!mod->is_selected_whole()) continue; if (mod->get_blackbox_attribute()) continue; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 168d38563fd..910c9e366bf 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -216,8 +216,8 @@ struct DesignPass : public Pass { RTLIL::Selection sel; if (argidx != args.size()) { handle_extra_select_args(this, args, argidx, args.size(), copy_from_design); - sel = copy_from_design->selection_stack.back(); - copy_from_design->selection_stack.pop_back(); + sel = copy_from_design->selection(); + copy_from_design->pop_selection(); argidx = args.size(); } @@ -368,7 +368,7 @@ struct DesignPass : public Pass { design->selection_vars.clear(); design->selected_active_module.clear(); - design->selection_stack.push_back(RTLIL::Selection()); + design->push_full_selection(); } if (reset_mode || reset_vlog_mode || !load_name.empty() || push_mode || pop_mode) diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 197bd931966..ddd72bb4566 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -340,7 +340,7 @@ struct SccPass : public Pass { int origSelectPos = design->selection_stack.size() - 1; extra_args(args, argidx, design); - RTLIL::Selection newSelection(false); + RTLIL::Selection newSelection(false, false, design); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1b1b7ca4304..4db1c2f28ae 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -687,7 +687,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { if (design->selection_stack.size() > 0) - work_stack.push_back(design->selection_stack.back()); + work_stack.push_back(design->selection()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -1031,9 +1031,9 @@ 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, false, design)); + design->push_empty_selection(); else - design->selection_stack.push_back(work_stack.back()); + design->push_selection(work_stack.back()); } // extern decl. in register.h @@ -1420,7 +1420,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - RTLIL::Selection sel(false); + RTLIL::Selection sel(false, false, design); string line; while (std::getline(f, line)) { @@ -1461,7 +1461,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset); if (work_stack.size() == 0 && got_module) { - RTLIL::Selection sel; + RTLIL::Selection sel(true, false, design); select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1474,13 +1474,15 @@ struct SelectPass : public Pass { log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection_stack.back() = RTLIL::Selection(true, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection_stack.back() = RTLIL::Selection(false, false, design); + design->pop_selection(); + design->push_empty_selection(); return; } @@ -1496,8 +1498,8 @@ struct SelectPass : public Pass { log_error("Can't open '%s' for writing: %s\n", write_file.c_str(), strerror(errno)); } if (work_stack.size() > 0) - design->selection_stack.push_back(work_stack.back()); - RTLIL::Selection *sel = &design->selection_stack.back(); + design->push_selection(work_stack.back()); + RTLIL::Selection *sel = &design->selection(); sel->optimize(design); for (auto mod : design->selected_modules()) { @@ -1515,7 +1517,7 @@ struct SelectPass : public Pass { if (f != nullptr) fclose(f); if (work_stack.size() > 0) - design->selection_stack.pop_back(); + design->pop_selection(); #undef LOG_OBJECT return; } @@ -1524,8 +1526,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to add to selection.\n"); - select_op_union(design, design->selection_stack.back(), work_stack.back()); - design->selection_stack.back().optimize(design); + select_op_union(design, design->selection(), work_stack.back()); + design->selection().optimize(design); return; } @@ -1533,8 +1535,8 @@ struct SelectPass : public Pass { { if (work_stack.size() == 0) log_cmd_error("Nothing to delete from selection.\n"); - select_op_diff(design, design->selection_stack.back(), work_stack.back()); - design->selection_stack.back().optimize(design); + select_op_diff(design, design->selection(), work_stack.back()); + design->selection().optimize(design); return; } @@ -1574,7 +1576,7 @@ 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); + design->push_selection(*sel); sel->optimize(design); for (auto mod : design->selected_modules()) { module_count++; @@ -1604,7 +1606,7 @@ 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(); + design->pop_selection(); return; } @@ -1625,7 +1627,7 @@ struct SelectPass : public Pass { } if (work_stack.size() == 0) { - RTLIL::Selection &sel = design->selection_stack.back(); + RTLIL::Selection &sel = design->selection(); if (sel.full_selection) log("*\n"); for (auto &it : sel.selected_modules) @@ -1636,8 +1638,8 @@ struct SelectPass : public Pass { return; } - design->selection_stack.back() = work_stack.back(); - design->selection_stack.back().optimize(design); + design->selection() = work_stack.back(); + design->selection().optimize(design); } } SelectPass; @@ -1677,7 +1679,8 @@ 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, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); return; } @@ -1686,7 +1689,8 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->selection_stack.back() = RTLIL::Selection(true, false, design); + design->pop_selection(); + design->push_full_selection(); design->selected_active_module = std::string(); while (1) @@ -1703,9 +1707,10 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(true, false, design); - select_filter_active_mod(design, design->selection_stack.back()); - design->selection_stack.back().optimize(design); + design->pop_selection(); + design->push_full_selection(); + select_filter_active_mod(design, design->selection()); + design->selection().optimize(design); return; } @@ -1722,9 +1727,10 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->selection_stack.back() = RTLIL::Selection(true, false, design); - select_filter_active_mod(design, design->selection_stack.back()); - design->selection_stack.back().optimize(design); + design->pop_selection(); + design->push_full_selection(); + select_filter_active_mod(design, design->selection()); + design->selection().optimize(design); return; } diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 82b5c6bcf35..8a1bd58c433 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -802,8 +802,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection_stack.back(); - design->selection_stack.pop_back(); + data.second = design->selection(); + design->pop_selection(); color_selections.push_back(data); continue; } @@ -811,8 +811,8 @@ struct ShowPass : public Pass { std::pair data; data.first = args[++argidx], argidx++; handle_extra_select_args(this, args, argidx, argidx+1, design); - data.second = design->selection_stack.back(); - design->selection_stack.pop_back(); + data.second = design->selection(); + design->pop_selection(); label_selections.push_back(data); continue; } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 5bbbb278906..97a2886d40f 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -468,7 +468,7 @@ struct StatPass : public Pass { first_module = false; } else { log("\n"); - log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); + log("=== %s%s ===\n", log_id(mod->name), mod->is_selected_whole() ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false); } diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 3655f3f491b..c302ec67302 100644 --- a/passes/cmds/viz.cc +++ b/passes/cmds/viz.cc @@ -950,8 +950,8 @@ struct VizPass : public Pass { auto type = arg == "-g" || arg == "-G" ? VizConfig::TYPE_G : arg == "-u" || arg == "-U" ? VizConfig::TYPE_U : arg == "-x" || arg == "-X" ? VizConfig::TYPE_X : VizConfig::TYPE_S; - config.groups.push_back({type, design->selection_stack.back()}); - design->selection_stack.pop_back(); + config.groups.push_back({type, design->selection()}); + design->pop_selection(); continue; } if (arg == "-0" || arg == "-1" || arg == "-2" || arg == "-3" || arg == "-4" || diff --git a/passes/hierarchy/submod.cc b/passes/hierarchy/submod.cc index 52fd59cf82a..facc5d17365 100644 --- a/passes/hierarchy/submod.cc +++ b/passes/hierarchy/submod.cc @@ -246,7 +246,7 @@ struct SubmodWorker SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) : design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name) { - if (!design->selected_whole_module(module->name) && opt_name.empty()) + if (!module->is_selected_whole() && opt_name.empty()) return; if (module->processes.size() > 0) { diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index bca6a5ec629..e86b964e580 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -57,7 +57,7 @@ struct CutpointPass : public Pass { for (auto module : design->selected_modules()) { - if (design->selected_whole_module(module->name)) { + if (module->is_selected_whole()) { log("Making all outputs of module %s cut points, removing module contents.\n", log_id(module)); module->new_connections(std::vector()); for (auto cell : vector(module->cells())) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index a96a82659ac..56fa4b0117d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -400,7 +400,7 @@ struct Abc9Pass : public ScriptPass } log_push(); - active_design->selection().select(mod); + active_design->select(mod); if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); @@ -452,7 +452,7 @@ struct Abc9Pass : public ScriptPass log_pop(); } - active_design->selection_stack.pop_back(); + active_design->pop_selection(); } } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 378f29042b3..018cd7cfe42 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -454,7 +454,7 @@ void prep_bypass(RTLIL::Design *design) void prep_dff(RTLIL::Design *design) { - auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false, false, design))); auto &modules_sel = r.first->second; for (auto module : design->selected_modules()) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index eefe34f84c7..433881b0201 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -128,7 +128,7 @@ struct AbcNewPass : public ScriptPass { exe_options = abc_exe_options; log_header(active_design, "Mapping module '%s'.\n", log_id(mod)); log_push(); - active_design->selection().select(mod); + active_design->select(mod); } run(stringf(" abc9_ops -write_box %s/input.box", tmpdir.c_str())); @@ -144,7 +144,7 @@ struct AbcNewPass : public ScriptPass { } if (!help_mode) { - active_design->selection_stack.pop_back(); + active_design->pop_selection(); } } } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 4836ebe3484..b51ad912ef9 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -172,7 +172,7 @@ struct AigmapPass : public Pass { if (select_mode) { log_assert(!design->selection_stack.empty()); - RTLIL::Selection& sel = design->selection_stack.back(); + RTLIL::Selection& sel = design->selection(); sel.selected_members[module->name] = std::move(new_sel); } diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 0167891571f..098c227f639 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - RTLIL::Selection sel(false); + RTLIL::Selection sel(false, false, module->design); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); From 15b921c0ad14d6f1195da4bfa5b2d8fd439978bc Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:40:12 +1300 Subject: [PATCH 07/22] rtlil: Design::top_module() can be const Since it doesn't change anything and is just a lookup. --- kernel/rtlil.cc | 2 +- kernel/rtlil.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 95e6014137f..8e597bcd07a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -932,7 +932,7 @@ const RTLIL::Module *RTLIL::Design::module(const RTLIL::IdString& name) const return modules_.count(name) ? modules_.at(name) : NULL; } -RTLIL::Module *RTLIL::Design::top_module() +RTLIL::Module *RTLIL::Design::top_module() const { RTLIL::Module *module = nullptr; int module_count = 0; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 1bfe8c31323..9b008b7aab5 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1205,7 +1205,7 @@ struct RTLIL::Design RTLIL::ObjRange modules(); RTLIL::Module *module(const RTLIL::IdString &name); const RTLIL::Module *module(const RTLIL::IdString &name) const; - RTLIL::Module *top_module(); + RTLIL::Module *top_module() const; bool has(const RTLIL::IdString &id) const { return modules_.count(id) != 0; From 5d9d77a0c2f47d3a77bc1705badbc7fadc6c3d44 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:38:23 +1300 Subject: [PATCH 08/22] Fixing selections --- kernel/rtlil.cc | 2 +- passes/cmds/select.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8e597bcd07a..af1d55bfd2d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1179,7 +1179,7 @@ void RTLIL::Design::pop_selection() std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const { bool include_partials = partials == RTLIL::SELECT_ALL; - bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) == 0; + bool exclude_boxes = (partials & RTLIL::SB_UNBOXED_ONLY) != 0; bool ignore_wb = (partials & RTLIL::SB_INCL_WB) != 0; std::vector result; result.reserve(modules_.size()); diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 4db1c2f28ae..1eed7c818ba 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1000,7 +1000,7 @@ 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->selected_modules()) + for (auto mod : design->all_selected_modules()) { if (whole_modules && sel->selected_whole_module(mod->name)) desc += stringf("%s\n", id2cstr(mod->name)); @@ -1501,7 +1501,7 @@ struct SelectPass : public Pass { design->push_selection(work_stack.back()); RTLIL::Selection *sel = &design->selection(); sel->optimize(design); - for (auto mod : design->selected_modules()) + for (auto mod : design->all_selected_modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); @@ -1578,7 +1578,7 @@ struct SelectPass : public Pass { RTLIL::Selection *sel = &work_stack.back(); design->push_selection(*sel); sel->optimize(design); - for (auto mod : design->selected_modules()) { + for (auto mod : design->all_selected_modules()) { module_count++; for ([[maybe_unused]] auto member_name : mod->selected_members()) total_count++; @@ -1777,7 +1777,7 @@ struct LsPass : public Pass { { std::vector matches; - for (auto mod : design->selected_modules()) + for (auto mod : design->all_selected_modules()) matches.push_back(mod->name); if (!matches.empty()) { From c120abec7cc3e589fae99fad863d573921ce58cd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:01:42 +1300 Subject: [PATCH 09/22] Fix describe_selection_for_assert If the current selection is not the provided selection, push the provided selection. --- passes/cmds/select.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1eed7c818ba..54b6f0a4253 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -999,6 +999,8 @@ 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) { + bool push_selection = &design->selection() != sel; + if (push_selection) design->push_selection(*sel); std::string desc = "Selection contains:\n"; for (auto mod : design->all_selected_modules()) { @@ -1007,6 +1009,7 @@ static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::S for (auto it : mod->selected_members()) desc += stringf("%s/%s\n", id2cstr(mod->name), id2cstr(it->name)); } + if (push_selection) design->pop_selection(); return desc; } From ac5058a785c0024787cca4048678f6e0381c9b16 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:03:52 +1300 Subject: [PATCH 10/22] Fix select_op_random ignoring boxes --- passes/cmds/select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 54b6f0a4253..8579c6111fc 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -228,7 +228,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false, false, design); + lhs = RTLIL::Selection(false, lhs.selects_boxes, design); while (!objects.empty() && count-- > 0) { From ae949538086295f7a8ba60c3a822df9713823a71 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:29:22 +1300 Subject: [PATCH 11/22] abc9: Use push_empty_selection() --- passes/techmap/abc9.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 56fa4b0117d..1313fbd7383 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -391,7 +391,7 @@ struct Abc9Pass : public ScriptPass } else { auto selected_modules = active_design->selected_modules(); - active_design->selection_stack.emplace_back(false); + active_design->push_empty_selection(); for (auto mod : selected_modules) { if (mod->processes.size() > 0) { @@ -402,6 +402,7 @@ struct Abc9Pass : public ScriptPass log_push(); active_design->select(mod); + // this check does nothing because the above line adds the whole module to the selection if (!active_design->selected_whole_module(mod)) log_error("Can't handle partially selected module %s!\n", log_id(mod)); From c0a04b88230f71db7b06b56dd58f356471728d24 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:31:09 +1300 Subject: [PATCH 12/22] tests: Fixes for boxes cxxrtl `test_unconnected_output` and simple_abc9 `abc9.v` both expect boxed modules in the outputs, so make sure they work as expected. --- tests/cxxrtl/run-test.sh | 2 +- tests/simple_abc9/run-test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cxxrtl/run-test.sh b/tests/cxxrtl/run-test.sh index fd11a378379..ee299fc829d 100755 --- a/tests/cxxrtl/run-test.sh +++ b/tests/cxxrtl/run-test.sh @@ -13,5 +13,5 @@ run_subtest value run_subtest value_fuzz # Compile-only test. -../../yosys -p "read_verilog test_unconnected_output.v; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" +../../yosys -p "read_verilog test_unconnected_output.v; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" ${CC:-gcc} -std=c++11 -c -o cxxrtl-test-unconnected_output -I../../backends/cxxrtl/runtime cxxrtl-test-unconnected_output.cc diff --git a/tests/simple_abc9/run-test.sh b/tests/simple_abc9/run-test.sh index b75e54dd3fe..5669321acb0 100755 --- a/tests/simple_abc9/run-test.sh +++ b/tests/simple_abc9/run-test.sh @@ -49,6 +49,6 @@ exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v *.sv EXTRA_FLAGS="-f \"veri clean; \ check -assert * abc9_test037 %d; \ select -assert-none t:${DOLLAR}_NOT_ t:${DOLLAR}_AND_ %%; \ - setattr -mod -unset blackbox -unset whitebox'" + setattr -mod -unset blackbox -unset whitebox =*'" # NOTE: Skip 'check -assert' on abc9_test037 because it intentionally has a combinatorial loop From 8e642220154a3ebb649f42c3e2b821af8e943b98 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:10:24 +1300 Subject: [PATCH 13/22] Add Selection::complete_selection Used to select all modules including boxes, set when both `full` and `boxes` are true in the constructor, pulling down `full_selection`. Add `Selection::selects_all()` method as short hand for `full_selection || complete_selection`. Update selection operations to account for complete selections. Add static methods to `Selection` for creating a new empty/full/complete selection to make it clearer to users when doing so. Use said static methods to replace most instances of the `Selection` constructor. Update `Selection::optimize` to use --- kernel/rtlil.cc | 36 +++++++++--------- kernel/rtlil.h | 22 ++++++++--- passes/cmds/scc.cc | 2 +- passes/cmds/select.cc | 75 ++++++++++++++++++++++++-------------- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/nlutmap.cc | 2 +- 6 files changed, 86 insertions(+), 53 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index af1d55bfd2d..db2d1bb03f6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -773,6 +773,8 @@ bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const { + if (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -786,6 +788,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 (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -797,6 +801,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 (complete_selection) + return true; if (!selects_boxes && boxed_module(mod_name)) return false; if (full_selection) @@ -815,16 +821,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) current_design = design; } - if (selects_boxes && full_selection) { - selected_modules.clear(); - selected_members.clear(); + if (selects_boxes && full_selection) + complete_selection = true; + if (complete_selection) { full_selection = false; - for (auto mod : current_design->modules()) { - selected_modules.insert(mod->name); - } - return; + selects_boxes = true; } - if (full_selection) { + if (selects_all()) { selected_modules.clear(); selected_members.clear(); return; @@ -872,10 +875,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) { - full_selection = true; + if (selected_modules.size() == current_design->modules_.size()) { selected_modules.clear(); selected_members.clear(); + if (selects_boxes) + complete_selection = true; + else + full_selection = true; } } @@ -1154,21 +1160,17 @@ void RTLIL::Design::push_selection(RTLIL::Selection sel) void RTLIL::Design::push_empty_selection() { - RTLIL::Selection sel(false, false, this); - push_selection(sel); + push_selection(RTLIL::Selection::EmptySelection(this)); } void RTLIL::Design::push_full_selection() { - RTLIL::Selection sel(true, false, this); - push_selection(sel); + push_selection(RTLIL::Selection::FullSelection(this)); } void RTLIL::Design::push_complete_selection() { - RTLIL::Selection sel(true, true, this); - sel.optimize(this); - push_selection(sel); + push_selection(RTLIL::Selection::CompleteSelection(this)); } void RTLIL::Design::pop_selection() diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 9b008b7aab5..12780697476 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1125,11 +1125,13 @@ struct RTLIL::Selection { bool full_selection; bool selects_boxes; + bool complete_selection; pool selected_modules; dict> selected_members; RTLIL::Design *current_design; - Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { } + Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : + full_selection(full && !boxes), selects_boxes(boxes), complete_selection(full && boxes), current_design(design) { } bool boxed_module(const RTLIL::IdString &mod_name) const; bool selected_module(const RTLIL::IdString &mod_name) const; @@ -1137,21 +1139,29 @@ struct RTLIL::Selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; void optimize(RTLIL::Design *design); + bool selects_all() const { + return full_selection || complete_selection; + } + template void select(T1 *module) { - if (!full_selection && selected_modules.count(module->name) == 0) { + if (!selects_all() && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); } } template void select(T1 *module, T2 *member) { - if (!full_selection && selected_modules.count(module->name) == 0) + if (!selects_all() && selected_modules.count(module->name) == 0) selected_members[module->name].insert(member->name); } bool empty() const { - return !full_selection && selected_modules.empty() && selected_members.empty(); + return !selects_all() && selected_modules.empty() && selected_members.empty(); } + + static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; + static Selection FullSelection(RTLIL::Design *design = nullptr) { return Selection(true, false, design); }; + static Selection CompleteSelection(RTLIL::Design *design = nullptr) { return Selection(true, true, design); }; }; struct RTLIL::Monitor @@ -1241,8 +1251,8 @@ struct RTLIL::Design void push_selection(RTLIL::Selection sel); void push_empty_selection(); - void push_full_selection(); - void push_complete_selection(); + void push_full_selection(); // all modules excluding boxes + void push_complete_selection(); // all modules including boxes void pop_selection(); RTLIL::Selection &selection() { diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index ddd72bb4566..0f988e57a53 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -340,7 +340,7 @@ struct SccPass : public Pass { int origSelectPos = design->selection_stack.size() - 1; extra_args(args, argidx, design); - RTLIL::Selection newSelection(false, false, design); + auto newSelection = RTLIL::Selection::EmptySelection(design); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 8579c6111fc..7517af80a77 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,35 +141,40 @@ 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) +static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs) { - if (!lhs.full_selection) + if (!lhs.selects_all()) return; - lhs.current_design = design; lhs.selected_modules.clear(); for (auto mod : design->modules()) { - if (mod->get_blackbox_attribute()) + if (!lhs.selects_boxes && mod->get_blackbox_attribute()) continue; lhs.selected_modules.insert(mod->name); } + lhs.full_selection = false; + lhs.complete_selection = false; } static void select_op_neg(RTLIL::Design *design, RTLIL::Selection &lhs) { - if (lhs.full_selection) { + if (lhs.selects_all()) { lhs.full_selection = false; + lhs.complete_selection = false; lhs.selected_modules.clear(); lhs.selected_members.clear(); return; } - if (!lhs.selects_boxes && lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { - lhs.full_selection = true; + if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { + if (lhs.selects_boxes) + lhs.complete_selection = true; + else + lhs.full_selection = true; return; } - RTLIL::Selection new_sel(false); + auto new_sel = RTLIL::Selection::EmptySelection(); for (auto mod : design->modules()) { @@ -312,10 +317,17 @@ static void select_op_alias(RTLIL::Design *design, RTLIL::Selection &lhs) static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (lhs.complete_selection) + return; + else if (rhs.complete_selection) { + lhs.complete_selection = true; + lhs.optimize(design); + return; + } + if (rhs.selects_boxes) { if (lhs.full_selection) { - full_select_no_box(design, lhs); - lhs.full_selection = false; + select_all(design, lhs); } lhs.selects_boxes = true; } @@ -325,7 +337,7 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const if (rhs.full_selection) { if (lhs.selects_boxes) { auto new_rhs = RTLIL::Selection(rhs); - full_select_no_box(design, new_rhs); + select_all(design, new_rhs); for (auto mod : new_rhs.selected_modules) lhs.selected_modules.insert(mod); } else { @@ -348,10 +360,19 @@ static void select_op_union(RTLIL::Design* design, RTLIL::Selection &lhs, const static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const RTLIL::Selection &rhs) { + if (rhs.complete_selection) { + lhs.full_selection = false; + lhs.complete_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + return; + } + if (rhs.full_selection) { if (lhs.selects_boxes) { auto new_rhs = RTLIL::Selection(rhs); - full_select_no_box(design, new_rhs); + select_all(design, new_rhs); + select_all(design, lhs); for (auto mod : new_rhs.selected_modules) { lhs.selected_modules.erase(mod); lhs.selected_members.erase(mod); @@ -364,12 +385,10 @@ static void select_op_diff(RTLIL::Design *design, RTLIL::Selection &lhs, const R return; } - if (lhs.full_selection) { - if (rhs.empty()) - return; - full_select_no_box(design, lhs); - lhs.full_selection = false; - } + if (rhs.empty() || lhs.empty()) + return; + + select_all(design, lhs); for (auto &it : rhs.selected_modules) { lhs.selected_modules.erase(it); @@ -406,14 +425,16 @@ 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.complete_selection) + return; + if (rhs.full_selection && !lhs.selects_boxes) return; - if (lhs.full_selection) { - lhs.full_selection = false; - for (auto mod : design->modules()) - lhs.selected_modules.insert(mod->name); - } + if (lhs.empty() || rhs.empty()) + return; + + select_all(design, lhs); std::vector del_list; @@ -1050,7 +1071,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection(false, false, design); + return RTLIL::Selection::EmptySelection(design); return work_stack.back(); } @@ -1423,7 +1444,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - RTLIL::Selection sel(false, false, design); + auto sel = RTLIL::Selection::EmptySelection(design); string line; while (std::getline(f, line)) { @@ -1464,7 +1485,7 @@ struct SelectPass : public Pass { log_cmd_error("Option -unset can not be combined with -list, -write, -count, -set, %s.\n", common_flagset); if (work_stack.size() == 0 && got_module) { - RTLIL::Selection sel(true, false, design); + auto sel = RTLIL::Selection::FullSelection(design); select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1616,7 +1637,7 @@ struct SelectPass : public Pass { if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection(false, false, design); + design->selection_vars[set_name] = RTLIL::Selection::EmptySelection(design); else design->selection_vars[set_name] = work_stack.back(); return; diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 018cd7cfe42..41e220a019d 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -454,7 +454,7 @@ void prep_bypass(RTLIL::Design *design) void prep_dff(RTLIL::Design *design) { - auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false, false, design))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection::EmptySelection(design))); auto &modules_sel = r.first->second; for (auto module : design->selected_modules()) diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index 098c227f639..c823f10fe3a 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - RTLIL::Selection sel(false, false, module->design); + auto sel = RTLIL::Selection::EmptySelection(module->design); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); From c9fcad02d5c74ec2101c10a30c35cacb343405cf Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:13:43 +1300 Subject: [PATCH 14/22] Selecting a blackbox sets selects_boxes --- kernel/rtlil.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 12780697476..95bb8af2083 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1147,12 +1147,17 @@ struct RTLIL::Selection if (!selects_all() && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); + if (module->get_blackbox_attribute()) + selects_boxes = true; } } template void select(T1 *module, T2 *member) { - if (!selects_all() && selected_modules.count(module->name) == 0) + if (!selects_all() && selected_modules.count(module->name) == 0) { selected_members[module->name].insert(member->name); + if (module->get_blackbox_attribute()) + selects_boxes = true; + } } bool empty() const { From 270c55ec15522f96351a6d3dd674c12382935545 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:20:12 +1300 Subject: [PATCH 15/22] select.cc: Re-add '=' to empty selection warning --- passes/cmds/select.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 7517af80a77..c42c0ead27c 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -1008,12 +1008,16 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp 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()); + std::string selection_str = select_blackboxes ? "=" : ""; + selection_str += it.first; + log_warning("Selection \"%s\" did not match any module.\n", selection_str.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()); + std::string selection_str = select_blackboxes ? "=" : ""; + selection_str += it.first; + log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str()); } } } From 11ee9caaaed900ff42e024a5d4badc44150df447 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:21:57 +1300 Subject: [PATCH 16/22] abc9.cc: Call select =* Or rather, say we're calling `select =*`, but actually bypass the select command to avoid the warning that can pop up if there is nothing to select. --- passes/techmap/abc9.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 1313fbd7383..3a79c0dbf33 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -306,6 +306,8 @@ struct Abc9Pass : public ScriptPass } run("design -stash $abc9"); run("design -load $abc9_map"); + if (help_mode) run("select =*"); + else active_design->push_complete_selection(); run("proc"); run("wbflip"); run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); @@ -369,6 +371,8 @@ struct Abc9Pass : public ScriptPass if (saved_designs.count("$abc9_holes") || help_mode) { run("design -stash $abc9"); run("design -load $abc9_holes"); + if (help_mode) run("select =*"); + else active_design->push_complete_selection(); run("techmap -wb -map %$abc9 -map +/techmap.v"); run("opt -purge"); run("aigmap"); From 4ab59a99346463d30ea0c6274c9b0704b36478c9 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:40:55 +1300 Subject: [PATCH 17/22] select.cc: Fix %i when rhs is empty --- passes/cmds/select.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index c42c0ead27c..bb1055c676c 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -431,9 +431,17 @@ static void select_op_intersect(RTLIL::Design *design, RTLIL::Selection &lhs, co if (rhs.full_selection && !lhs.selects_boxes) return; - if (lhs.empty() || rhs.empty()) + if (lhs.empty()) return; + if (rhs.empty()) { + lhs.full_selection = false; + lhs.complete_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); + return; + } + select_all(design, lhs); std::vector del_list; From edbb3cb92c28588ea493b89db6d8366eb2275335 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 28 Nov 2024 09:39:53 +1300 Subject: [PATCH 18/22] abc9: Use techmap -autoproc Fixes quicklogic/pp3 problem with `dffepc` including processes. Also means the preceding `proc` is safe to remove (and may result in some small speedup by doing so). --- passes/techmap/abc9.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 3a79c0dbf33..fe5cc7af1fe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -308,9 +308,8 @@ struct Abc9Pass : public ScriptPass run("design -load $abc9_map"); if (help_mode) run("select =*"); else active_design->push_complete_selection(); - run("proc"); run("wbflip"); - run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); + run("techmap -autoproc -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); run("opt -nodffe -nosdff"); if (dff_mode || help_mode) { if (!help_mode) From 1cb5e3d92ac348dc01dfea0f52c47d3a756113bd Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:33:55 +1300 Subject: [PATCH 19/22] Design::selection_stack should never be empty Add a `log_assert` for it in `Design::check()`. Remove unneeded checks in other places. --- kernel/rtlil.cc | 14 ++++++++------ kernel/rtlil.h | 12 ++++-------- kernel/yosys.cc | 2 +- passes/cmds/select.cc | 5 ++--- passes/techmap/aigmap.cc | 1 - 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index db2d1bb03f6..e3df4081985 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1096,6 +1096,7 @@ void RTLIL::Design::sort() void RTLIL::Design::check() { #ifndef NDEBUG + log_assert(!selection_stack.empty()); for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); @@ -1119,8 +1120,6 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_module(mod_name); } @@ -1128,8 +1127,6 @@ bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_whole_module(mod_name); } @@ -1137,8 +1134,6 @@ bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - if (selection_stack.size() == 0) - return true; return selection().selected_member(mod_name, memb_name); } @@ -1176,6 +1171,9 @@ void RTLIL::Design::push_complete_selection() void RTLIL::Design::pop_selection() { selection_stack.pop_back(); + // Default to a full_selection if we ran out of stack + if (selection_stack.empty()) + push_full_selection(); } std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes) const @@ -2311,6 +2309,10 @@ void RTLIL::Module::check() log_assert(!packed_memids.count(memid)); packed_memids.insert(memid); } + auto cell_mod = design->module(it.first); + if (cell_mod != nullptr) { + log_assert(!it.second->get_blackbox_attribute()); + } } for (auto &it : processes) { diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 95bb8af2083..77034d5db96 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1281,17 +1281,13 @@ struct RTLIL::Design } template void select(T1 *module) { - if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection(); - sel.select(module); - } + RTLIL::Selection &sel = selection(); + sel.select(module); } template void select(T1 *module, T2 *member) { - if (selection_stack.size() > 0) { - RTLIL::Selection &sel = selection(); - sel.select(module, member); - } + RTLIL::Selection &sel = selection(); + sel.select(module, member); } diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 35cc81c5e2c..f75961c8366 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -674,7 +674,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) str += "yosys"; if (!design->selected_active_module.empty()) str += stringf(" [%s]", RTLIL::unescape_id(design->selected_active_module).c_str()); - if (!design->selection_stack.empty() && !design->full_selection()) { + if (!design->full_selection()) { if (design->selected_active_module.empty()) str += "*"; else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index bb1055c676c..1ed1987c857 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -715,8 +715,7 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { - if (design->selection_stack.size() > 0) - work_stack.push_back(design->selection()); + work_stack.push_back(design->selection()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -1507,7 +1506,7 @@ struct SelectPass : public Pass { work_stack.pop_back(); } - log_assert(design->selection_stack.size() > 0); + log_assert(!design->selection_stack.empty()); if (clear_mode) { design->pop_selection(); diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index b51ad912ef9..19e568a6147 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -171,7 +171,6 @@ struct AigmapPass : public Pass { module->remove(cell); if (select_mode) { - log_assert(!design->selection_stack.empty()); RTLIL::Selection& sel = design->selection(); sel.selected_members[module->name] = std::move(new_sel); } From ed5ca08d91316a708a57c491cbb791244db3ec84 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 28 Nov 2024 11:35:59 +1300 Subject: [PATCH 20/22] abc_new: Use push_empty_selection() --- passes/techmap/abc_new.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/techmap/abc_new.cc b/passes/techmap/abc_new.cc index 433881b0201..9222b92fad9 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -110,7 +110,7 @@ struct AbcNewPass : public ScriptPass { if (!help_mode) { selected_modules = active_design->selected_whole_modules_warn(); - active_design->selection_stack.emplace_back(false); + active_design->push_empty_selection(); } else { selected_modules = {nullptr}; run("foreach module in selection"); From 7cbccc20fb822e5d10d618972273b153894a8b69 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:08:17 +1300 Subject: [PATCH 21/22] firrtl: Drop full_selection check Change `top` pointer default to `nullptr` to avoid issues with `Design->top_module()` only operating on the current selection. Calls to other passes (`bmuxmap` etc) will only operate on the current selection, and may cause problems when those cells are unprocessed, but this is consistent with the other backends that only operate on the full designs and will hopefully be fixed in another PR soon :) --- backends/firrtl/firrtl.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index eac0c971913..ceb805dcb0a 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1215,9 +1215,6 @@ struct FirrtlBackend : public Backend { } extra_args(f, filename, args, argidx); - if (!design->full_selection()) - log_cmd_error("This command only operates on fully selected designs!\n"); - log_header(design, "Executing FIRRTL backend.\n"); log_push(); @@ -1230,7 +1227,7 @@ struct FirrtlBackend : public Backend { autoid_counter = 0; // Get the top module, or a reasonable facsimile - we need something for the circuit name. - Module *top = design->top_module(); + Module *top = nullptr; Module *last = nullptr; // Generate module and wire names. for (auto module : design->modules()) { From 4c0f68ba3bb7a9c5adb0c3e7fd101d901e51491c Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:33:15 +1300 Subject: [PATCH 22/22] Drop deprecation on Design::selected_modules() Instead, change the default `Design::selected_modules()` to match the behaviour (i.e. `selected_unboxed_modules_warn()`) because it's a lot of files to touch and they don't really _need_ to be updated. Also change `Design::selected_whole_modules()` users over to `Design::selected_unboxed_whole_modules()`, except `attrmap` because I'm not convinced it should be ignoring boxes. So instead, leave the deprecation warning for that one use and come back to the pass another time. --- kernel/rtlil.h | 4 +--- passes/opt/opt_clean.cc | 2 +- passes/sat/sim.cc | 4 ++-- passes/techmap/clockgate.cc | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 77034d5db96..aa21797435a 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1291,10 +1291,8 @@ struct RTLIL::Design } - std::vector selected_modules(RTLIL::SelectPartials partials, RTLIL::SelectBoxes boxes = SB_ALL) const; + std::vector selected_modules(RTLIL::SelectPartials partials = SELECT_ALL, RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN) const; - [[deprecated("Use selected_unboxed_modules() to maintain prior behaviour, or consider one of the other selected module helpers.")]] - std::vector selected_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } std::vector selected_unboxed_modules_warn() const { return selected_modules(SELECT_ALL, SB_UNBOXED_WARN); } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 51212fa0ec6..43d52eb615d 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -734,7 +734,7 @@ struct CleanPass : public Pass { count_rm_cells = 0; count_rm_wires = 0; - for (auto module : design->selected_whole_modules()) { + for (auto module : design->selected_unboxed_whole_modules()) { if (module->has_processes()) continue; rmunused_module(module, purge_mode, ys_debug(), true); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index c3fa213f6e5..8b2a8f1b270 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2887,7 +2887,7 @@ struct SimPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_whole_modules(); + auto mods = design->selected_unboxed_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); @@ -3016,7 +3016,7 @@ struct Fst2TbPass : public Pass { if (!top_mod) log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { - auto mods = design->selected_whole_modules(); + auto mods = design->selected_unboxed_whole_modules(); if (GetSize(mods) != 1) log_cmd_error("Only one top module must be selected.\n"); top_mod = mods.front(); diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 94088435310..0682ab9ff63 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -331,7 +331,7 @@ struct ClockgatePass : public Pass { dict clk_nets; int gated_flop_count = 0; - for (auto module : design->selected_whole_modules()) { + for (auto module : design->selected_unboxed_whole_modules()) { for (auto cell : module->cells()) { if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue;