From a30bacfcb142a40ed6465c23af89d6978f3001f2 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 14 Mar 2025 14:08:15 +1300 Subject: [PATCH] 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 a48a37834..f9f4cca4a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -779,6 +779,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) @@ -792,6 +794,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) @@ -803,6 +807,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) @@ -821,16 +827,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; @@ -878,10 +881,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; } } @@ -1160,21 +1166,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 b754b4717..56f00fdf6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1166,11 +1166,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; @@ -1178,21 +1180,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 @@ -1282,8 +1292,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 ddd72bb45..0f988e57a 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 8579c6111..7517af80a 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 0d28b8f4a..6cb569b5a 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 098c227f6..c823f10fe 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);