diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index ceb805dcb..eac0c9719 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1215,6 +1215,9 @@ 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(); @@ -1227,7 +1230,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 = nullptr; + Module *top = design->top_module(); Module *last = nullptr; // Generate module and wire names. for (auto module : design->modules()) { diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index ae60ee6c7..113f1a615 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 || module->is_selected_whole(); - bool print_body = !flag_n || !module->is_selected_whole(); + bool print_header = flag_m || design->selected_whole_module(module->name); + bool print_body = !flag_n || !design->selected_whole_module(module->name); if (print_header) { diff --git a/docs/source/code_examples/extensions/my_cmd.cc b/docs/source/code_examples/extensions/my_cmd.cc index e6660469c..36ddbe175 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().empty()) + if (design->selection_stack.back().empty()) log_cmd_error("This command can't operator on an empty selection!\n"); - RTLIL::Module *module = design->module("\\test"); + RTLIL::Module *module = design->modules_.at("\\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 d30dd2bae..b02c4cd99 100644 --- a/docs/source/yosys_internals/extending_yosys/extensions.rst +++ b/docs/source/yosys_internals/extending_yosys/extensions.rst @@ -237,7 +237,7 @@ Use ``log_cmd_error()`` to report a recoverable error: .. code:: C++ - if (design->selection().empty()) + if (design->selection_stack.back().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 eb1326ce0..a3d85bd90 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -111,7 +111,7 @@ void run(const char *command) log_last_error = ""; } catch (...) { while (GetSize(yosys_get_design()->selection_stack) > selSize) - yosys_get_design()->pop_selection(); + yosys_get_design()->selection_stack.pop_back(); throw; } } diff --git a/kernel/register.cc b/kernel/register.cc index c52bfb5b8..fcb6ca769 100644 --- a/kernel/register.cc +++ b/kernel/register.cc @@ -260,18 +260,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->pop_selection(); + design->selection_stack.pop_back(); } 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->push_selection(selection); + design->selection_stack.push_back(selection); Pass::call(design, command); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -279,11 +279,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->push_selection(selection); + design->selection_stack.push_back(selection); Pass::call(design, args); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -291,12 +291,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->push_empty_selection(); - design->select(module); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); Pass::call(design, command); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -304,12 +304,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->push_empty_selection(); - design->select(module); + design->selection_stack.push_back(RTLIL::Selection(false)); + design->selection_stack.back().select(module); Pass::call(design, args); - design->pop_selection(); + design->selection_stack.pop_back(); design->selected_active_module = backup_selected_active_module; } @@ -651,7 +651,7 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f } while (design->selection_stack.size() > orig_sel_stack_pos) - design->pop_selection(); + design->selection_stack.pop_back(); } struct SimHelper { diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 637cc9be3..3b9a4a8b1 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -766,23 +766,8 @@ 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 (complete_selection) - return true; - if (!selects_boxes && boxed_module(mod_name)) - return false; if (full_selection) return true; if (selected_modules.count(mod_name) > 0) @@ -794,10 +779,6 @@ 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) return true; if (selected_modules.count(mod_name) > 0) @@ -807,10 +788,6 @@ 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) return true; if (selected_modules.count(mod_name) > 0) @@ -823,17 +800,7 @@ 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) - complete_selection = true; - if (complete_selection) { - full_selection = false; - selects_boxes = true; - } - if (selects_all()) { + if (full_selection) { selected_modules.clear(); selected_members.clear(); return; @@ -843,7 +810,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 || (!selects_boxes && boxed_module(mod_name))) + if (design->modules_.count(mod_name) == 0) del_list.push_back(mod_name); selected_members.erase(mod_name); } @@ -852,7 +819,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) del_list.clear(); for (auto &it : selected_members) - if (current_design->modules_.count(it.first) == 0 || (!selects_boxes && boxed_module(it.first))) + if (design->modules_.count(it.first) == 0) del_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -860,7 +827,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) for (auto &it : selected_members) { del_list.clear(); for (auto memb_name : it.second) - if (current_design->modules_[it.first]->count_id(memb_name) == 0) + if (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); @@ -871,8 +838,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() == 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()) + 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()) add_list.push_back(it.first); for (auto mod_name : del_list) selected_members.erase(mod_name); @@ -881,24 +848,13 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) selected_modules.insert(mod_name); } - if (selected_modules.size() == current_design->modules_.size()) { + if (selected_modules.size() == design->modules_.size()) { + full_selection = true; selected_modules.clear(); selected_members.clear(); - if (selects_boxes) - complete_selection = true; - else - full_selection = true; } } -void RTLIL::Selection::clear() -{ - full_selection = false; - complete_selection = false; - selected_modules.clear(); - selected_members.clear(); -} - RTLIL::Design::Design() : verilog_defines (new define_map_t) { @@ -907,7 +863,7 @@ RTLIL::Design::Design() hashidx_ = hashidx_count; refcount_modules_ = 0; - push_full_selection(); + selection_stack.push_back(RTLIL::Selection()); #ifdef WITH_PYTHON RTLIL::Design::get_all_designs()->insert(std::pair(hashidx_, this)); @@ -952,7 +908,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() const +RTLIL::Module *RTLIL::Design::top_module() { RTLIL::Module *module = nullptr; int module_count = 0; @@ -1110,7 +1066,6 @@ 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); @@ -1134,21 +1089,27 @@ bool RTLIL::Design::selected_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_module(mod_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_module(mod_name); } bool RTLIL::Design::selected_whole_module(const RTLIL::IdString& mod_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_whole_module(mod_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_whole_module(mod_name); } bool RTLIL::Design::selected_member(const RTLIL::IdString& mod_name, const RTLIL::IdString& memb_name) const { if (!selected_active_module.empty() && mod_name != selected_active_module) return false; - return selection().selected_member(mod_name, memb_name); + if (selection_stack.size() == 0) + return true; + return selection_stack.back().selected_member(mod_name, memb_name); } bool RTLIL::Design::selected_module(RTLIL::Module *mod) const @@ -1161,86 +1122,37 @@ bool RTLIL::Design::selected_whole_module(RTLIL::Module *mod) const return selected_whole_module(mod->name); } -void RTLIL::Design::push_selection(RTLIL::Selection sel) +std::vector RTLIL::Design::selected_modules() const { - sel.current_design = this; - selection_stack.push_back(sel); -} - -void RTLIL::Design::push_empty_selection() -{ - push_selection(RTLIL::Selection::EmptySelection(this)); -} - -void RTLIL::Design::push_full_selection() -{ - push_selection(RTLIL::Selection::FullSelection(this)); -} - -void RTLIL::Design::push_complete_selection() -{ - push_selection(RTLIL::Selection::CompleteSelection(this)); -} - -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 -{ - 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) || (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; - } - } + if (selected_module(it.first) && !it.second->get_blackbox_attribute()) + result.push_back(it.second); + return result; +} + +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()) + 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_) + if (it.second->get_blackbox_attribute(include_wb)) + continue; + else 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; } @@ -2372,13 +2284,6 @@ 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) { - // assertion check below to make sure that there are no - // cases where a cell has a blackbox attribute since - // that is deprecated - log_assert(!it.second->get_blackbox_attribute()); - } } for (auto &it : processes) { @@ -2506,16 +2411,6 @@ 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; @@ -2536,40 +2431,6 @@ 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 52e7a17e7..f1bd96be7 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -56,33 +56,8 @@ 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; struct Selection; struct Monitor; struct Design; @@ -894,11 +869,6 @@ 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; @@ -1164,94 +1134,32 @@ public: struct RTLIL::Selection { - // selection includes boxed modules - bool selects_boxes; - // selection covers full design, including boxed modules - bool complete_selection; - // selection covers full design, not including boxed modules bool full_selection; pool selected_modules; dict> selected_members; - RTLIL::Design *current_design; - // create a new selection - Selection( - // should the selection cover the full design - bool full = true, - // should the selection include boxed modules - bool boxes = false, - // the design to select from - RTLIL::Design *design = nullptr - ) : - full_selection(full && !boxes), selects_boxes(boxes), complete_selection(full && boxes), current_design(design) { } + Selection(bool full = true) : full_selection(full) { } - // checks if the given module exists in the current design and is a - // boxed module, warning the user if the current design is not set - bool boxed_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is included in this selection bool selected_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is wholly included in this selection, - // i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; - - // checks if the given member from the given module is included in this - // selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; - - // optimizes this selection for the given design by: - // - removing non-existent modules and members, any boxed modules and - // their members (if selection does not include boxes), and any - // partially selected modules with no selected members; - // - marking partially selected modules as wholly selected if all - // members of that module are selected; and - // - marking selection as a complete_selection if all modules in the - // given design are selected, or a full_selection if it does not - // include boxes. void optimize(RTLIL::Design *design); - // checks if selection covers full design (may or may not include - // boxed-modules) - bool selects_all() const { - return full_selection || complete_selection; - } - - // add whole module to this selection template void select(T1 *module) { - if (!selects_all() && selected_modules.count(module->name) == 0) { + if (!full_selection && selected_modules.count(module->name) == 0) { selected_modules.insert(module->name); selected_members.erase(module->name); - if (module->get_blackbox_attribute()) - selects_boxes = true; } } - // add member of module to this selection template void select(T1 *module, T2 *member) { - if (!selects_all() && selected_modules.count(module->name) == 0) { + if (!full_selection && selected_modules.count(module->name) == 0) selected_members[module->name].insert(member->name); - if (module->get_blackbox_attribute()) - selects_boxes = true; - } } - // checks if selection is empty bool empty() const { - return !selects_all() && selected_modules.empty() && selected_members.empty(); + return !full_selection && selected_modules.empty() && selected_members.empty(); } - - // clear this selection, leaving it empty - void clear(); - - // create a new selection which is empty - static Selection EmptySelection(RTLIL::Design *design = nullptr) { return Selection(false, false, design); }; - - // create a new selection with all non-boxed modules - static Selection FullSelection(RTLIL::Design *design = nullptr) { return Selection(true, false, design); }; - - // create a new selection with all modules, including boxes - static Selection CompleteSelection(RTLIL::Design *design = nullptr) { return Selection(true, true, design); }; }; struct RTLIL::Monitor @@ -1305,7 +1213,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() const; + RTLIL::Module *top_module(); bool has(const RTLIL::IdString &id) const { return modules_.count(id) != 0; @@ -1332,118 +1240,57 @@ struct RTLIL::Design void check(); void optimize(); - // checks if the given module is included in the current selection bool selected_module(const RTLIL::IdString &mod_name) const; - - // checks if the given module is wholly included in the current - // selection, i.e. not partially selected bool selected_whole_module(const RTLIL::IdString &mod_name) const; - - // checks if the given member from the given module is included in the - // current selection bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const; - // checks if the given module is included in the current selection bool selected_module(RTLIL::Module *mod) const; - - // checks if the given module is wholly included in the current - // selection, i.e. not partially selected bool selected_whole_module(RTLIL::Module *mod) const; - // push the given selection to the selection stack - void push_selection(RTLIL::Selection sel); - // push a new selection to the selection stack, with nothing selected - void push_empty_selection(); - // push a new selection to the selection stack, with all non-boxed - // modules selected - void push_full_selection(); - // push a new selection to the selection stack, with all modules - // selected including boxes - void push_complete_selection(); - // pop the current selection from the stack, returning to a full - // selection (no boxes) if the stack is empty - void pop_selection(); - - // get the current selection RTLIL::Selection &selection() { return selection_stack.back(); } - // get the current selection const RTLIL::Selection &selection() const { return selection_stack.back(); } - // is the current selection a full selection (no boxes) bool full_selection() const { - return selection().full_selection; + return selection_stack.back().full_selection; } - // is the given module in the current selection template bool selected(T1 *module) const { return selected_module(module->name); } - // is the given member of the given module in the current selection template bool selected(T1 *module, T2 *member) const { return selected_member(module->name, member->name); } - // add whole module to the current selection template void select(T1 *module) { - RTLIL::Selection &sel = selection(); - sel.select(module); + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module); + } } - // add member of module to the current selection template void select(T1 *module, T2 *member) { - RTLIL::Selection &sel = selection(); - sel.select(module, member); + if (selection_stack.size() > 0) { + RTLIL::Selection &sel = selection_stack.back(); + sel.select(module, member); + } } - // returns all selected modules - std::vector selected_modules( - // controls if partially selected modules are included - RTLIL::SelectPartials partials = SELECT_ALL, - // controls if boxed modules are included - RTLIL::SelectBoxes boxes = SB_UNBOXED_WARN - ) const; - - // returns all selected modules, and may include boxes - std::vector all_selected_modules() const { return selected_modules(SELECT_ALL, SB_ALL); } - // returns all selected unboxed modules, silently ignoring any boxed - // modules in the selection - std::vector selected_unboxed_modules() const { return selected_modules(SELECT_ALL, SB_UNBOXED_ONLY); } - // returns all selected unboxed modules, warning the user if any boxed - // modules have been ignored - 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); } - // returns all selected whole modules, silently ignoring partially - // selected modules, and may include boxes - std::vector all_selected_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_ALL); } - // returns all selected whole modules, warning the user if any partially - // selected or boxed modules have been ignored; optionally includes - // selected whole modules with the 'whitebox' attribute - std::vector selected_whole_modules_warn( - // should whole modules with the 'whitebox' attribute be - // included - bool include_wb = false - ) const { return selected_modules(SELECT_WHOLE_WARN, include_wb ? SB_EXCL_BB_WARN : SB_UNBOXED_WARN); } - // returns all selected unboxed whole modules, silently ignoring - // partially selected or boxed modules - std::vector selected_unboxed_whole_modules() const { return selected_modules(SELECT_WHOLE_ONLY, SB_UNBOXED_ONLY); } - // returns all selected unboxed whole modules, warning the user if any - // partially selected or boxed modules have been ignored - std::vector selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); } + std::vector selected_modules() const; + std::vector selected_whole_modules() const; + std::vector selected_whole_modules_warn(bool include_wb = false) const; #ifdef WITH_PYTHON static std::map *get_all_designs(void); #endif }; -struct RTLIL::Module : public RTLIL::NamedObject +struct RTLIL::Module : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1466,6 +1313,7 @@ public: std::vector connections_; std::vector bindings_; + RTLIL::IdString name; idict avail_parameters; dict parameter_default_values; dict memories; @@ -1510,14 +1358,8 @@ public: 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; - std::vector selected_processes() const; - std::vector selected_members() const; template bool selected(T *member) const { return design->selected_member(name, member->name); @@ -1803,7 +1645,7 @@ namespace RTLIL_BACKEND { void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire); } -struct RTLIL::Wire : public RTLIL::NamedObject +struct RTLIL::Wire : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1826,6 +1668,7 @@ public: void operator=(RTLIL::Wire &other) = delete; RTLIL::Module *module; + RTLIL::IdString name; int width, start_offset, port_id; bool port_input, port_output, upto, is_signed; @@ -1854,13 +1697,14 @@ inline int GetSize(RTLIL::Wire *wire) { return wire->width; } -struct RTLIL::Memory : public RTLIL::NamedObject +struct RTLIL::Memory : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } Memory(); + RTLIL::IdString name; int width, start_offset, size; #ifdef WITH_PYTHON ~Memory(); @@ -1868,7 +1712,7 @@ struct RTLIL::Memory : public RTLIL::NamedObject #endif }; -struct RTLIL::Cell : public RTLIL::NamedObject +struct RTLIL::Cell : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1885,6 +1729,7 @@ public: void operator=(RTLIL::Cell &other) = delete; RTLIL::Module *module; + RTLIL::IdString name; RTLIL::IdString type; dict connections_; dict parameters; @@ -1977,7 +1822,7 @@ struct RTLIL::SyncRule RTLIL::SyncRule *clone() const; }; -struct RTLIL::Process : public RTLIL::NamedObject +struct RTLIL::Process : public RTLIL::AttrObject { Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -1989,6 +1834,7 @@ protected: ~Process(); public: + RTLIL::IdString name; RTLIL::Module *module; RTLIL::CaseRule root_case; std::vector syncs; diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index e970779d7..be39ca4a0 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -114,7 +114,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->pop_selection(); + design->selection_stack.pop_back(); log_reset_stack(); } Tcl_SetResult(interp, (char *)"Yosys command produced an error", TCL_STATIC); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 9b0bc92ce..a5520e6ef 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -312,11 +312,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->full_selection()) { + if (!design->selection_stack.empty() && !design->selection_stack.back().full_selection) { if (design->selected_active_module.empty()) str += "*"; - else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || - design->selection().selected_modules.count(design->selected_active_module) == 0) + 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) str += "*"; } snprintf(buffer, 100, "%s> ", str.c_str()); @@ -979,7 +979,7 @@ void shell(RTLIL::Design *design) Pass::call(design, command); } catch (log_cmd_error_exception) { while (design->selection_stack.size() > 1) - design->pop_selection(); + design->selection_stack.pop_back(); log_reset_stack(); } design->check(); diff --git a/passes/cmds/add.cc b/passes/cmds/add.cc index 833d6006d..c09517254 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 (!mod->is_selected_whole()) + if (!design->selected_whole_module(mod->name)) continue; if (mod->get_blackbox_attribute()) continue; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 910c9e366..168d38563 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(); - copy_from_design->pop_selection(); + sel = copy_from_design->selection_stack.back(); + copy_from_design->selection_stack.pop_back(); argidx = args.size(); } @@ -368,7 +368,7 @@ struct DesignPass : public Pass { design->selection_vars.clear(); design->selected_active_module.clear(); - design->push_full_selection(); + design->selection_stack.push_back(RTLIL::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 0f988e57a..197bd9319 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); - auto newSelection = RTLIL::Selection::EmptySelection(design); + RTLIL::Selection newSelection(false); int scc_counter = 0; for (auto mod : design->selected_modules()) diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 1d75091af..aec4c964b 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -141,42 +141,24 @@ static bool match_attr(const dict &attributes, co return match_attr(attributes, match_expr, std::string(), 0); } -static void select_all(RTLIL::Design *design, RTLIL::Selection &lhs) -{ - if (!lhs.selects_all()) - return; - lhs.current_design = design; - lhs.selected_modules.clear(); - for (auto mod : design->modules()) { - 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.selects_all()) { - lhs.clear(); + if (lhs.full_selection) { + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } if (lhs.selected_modules.size() == 0 && lhs.selected_members.size() == 0) { - if (lhs.selects_boxes) - lhs.complete_selection = true; - else - lhs.full_selection = true; + lhs.full_selection = true; return; } - auto new_sel = RTLIL::Selection::EmptySelection(); + RTLIL::Selection new_sel(false); 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)) { @@ -230,7 +212,7 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c } } - lhs = RTLIL::Selection(false, lhs.selects_boxes, design); + lhs = RTLIL::Selection(false); while (!objects.empty() && count-- > 0) { @@ -261,7 +243,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, lhs.selects_boxes, design); + RTLIL::Selection new_sel(false); for (auto mod : design->modules()) if (lhs.selected_module(mod->name)) for (auto cell : mod->cells()) @@ -272,7 +254,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, lhs.selects_boxes, design); + RTLIL::Selection new_sel(false); for (auto mod : design->modules()) for (auto cell : mod->cells()) if ((design->module(cell->type) != nullptr) && lhs.selected_whole_module(cell->type)) @@ -292,8 +274,6 @@ 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)) @@ -312,38 +292,18 @@ 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) +static void select_op_union(RTLIL::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) { - select_all(design, lhs); - } - lhs.selects_boxes = true; - } - else if (lhs.full_selection) - return; - if (rhs.full_selection) { - if (lhs.selects_boxes) { - auto new_rhs = RTLIL::Selection(rhs); - select_all(design, new_rhs); - for (auto mod : new_rhs.selected_modules) - lhs.selected_modules.insert(mod); - } else { - lhs.clear(); - lhs.full_selection = true; - } + lhs.full_selection = true; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } + if (lhs.full_selection) + return; + for (auto &it : rhs.selected_members) for (auto &it2 : it.second) lhs.selected_members[it.first].insert(it2); @@ -356,30 +316,20 @@ 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.clear(); - return; - } - if (rhs.full_selection) { - if (lhs.selects_boxes) { - auto new_rhs = RTLIL::Selection(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); - } - } else { - lhs.clear(); - } + lhs.full_selection = false; + lhs.selected_modules.clear(); + lhs.selected_members.clear(); return; } - if (rhs.empty() || lhs.empty()) - return; - - select_all(design, lhs); + if (lhs.full_selection) { + if (!rhs.full_selection && rhs.selected_modules.size() == 0 && rhs.selected_members.size() == 0) + return; + lhs.full_selection = false; + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); + } for (auto &it : rhs.selected_modules) { lhs.selected_modules.erase(it); @@ -416,46 +366,38 @@ 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) + if (rhs.full_selection) return; - if (rhs.full_selection && !lhs.selects_boxes) - return; - - if (lhs.empty()) - return; - - if (rhs.empty()) { - lhs.clear(); - return; + if (lhs.full_selection) { + lhs.full_selection = false; + for (auto mod : design->modules()) + lhs.selected_modules.insert(mod->name); } - select_all(design, lhs); - std::vector del_list; - 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 : 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 &it : del_list) lhs.selected_modules.erase(it); del_list.clear(); for (auto &it : lhs.selected_members) { - if (rhs.selected_whole_module(it.first)) + if (rhs.selected_modules.count(it.first) > 0) continue; - if (!rhs.selected_module(it.first)) { + if (rhs.selected_members.count(it.first) == 0) { del_list.push_back(it.first); continue; } std::vector del_list2; for (auto &it2 : it.second) - if (!rhs.selected_member(it.first, it2)) + if (rhs.selected_members.at(it.first).count(it2) == 0) del_list2.push_back(it2); for (auto &it2 : del_list2) it.second.erase(it2); @@ -668,7 +610,9 @@ static void select_filter_active_mod(RTLIL::Design *design, RTLIL::Selection &se return; if (sel.full_selection) { - sel.clear(); + sel.full_selection = false; + sel.selected_modules.clear(); + sel.selected_members.clear(); sel.selected_modules.insert(design->selected_active_module); return; } @@ -701,7 +645,8 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp if (arg[0] == '%') { if (arg == "%") { - work_stack.push_back(design->selection()); + if (design->selection_stack.size() > 0) + work_stack.push_back(design->selection_stack.back()); } else if (arg == "%%") { while (work_stack.size() > 1) { @@ -851,16 +796,15 @@ static void select_stmt(RTLIL::Design *design, std::string arg, bool disable_emp } } - bool full_selection = (arg == "*" && arg_mod == "*"); - work_stack.push_back(RTLIL::Selection(full_selection, select_blackboxes, design)); + work_stack.push_back(RTLIL::Selection()); RTLIL::Selection &sel = work_stack.back(); - if (sel.full_selection) { - if (sel.selects_boxes) sel.optimize(design); + if (arg == "*" && arg_mod == "*" && select_blackboxes) { 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()) @@ -1001,33 +945,38 @@ 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) { - std::string selection_str = select_blackboxes ? "=" : ""; - selection_str += it.first; - log_warning("Selection \"%s\" did not match any module.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any module.\n", it.first.c_str()); } } for (auto &it : arg_memb_found) { if (it.second == false && !disable_empty_warning) { - std::string selection_str = select_blackboxes ? "=" : ""; - selection_str += it.first; - log_warning("Selection \"%s\" did not match any object.\n", selection_str.c_str()); + log_warning("Selection \"%s\" did not match any object.\n", it.first.c_str()); } } } static std::string describe_selection_for_assert(RTLIL::Design *design, RTLIL::Selection *sel, 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()) + for (auto mod : design->modules()) { - 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)); + 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 (push_selection) design->pop_selection(); return desc; } @@ -1052,9 +1001,9 @@ void handle_extra_select_args(Pass *pass, const vector &args, size_t arg work_stack.pop_back(); } if (work_stack.empty()) - design->push_empty_selection(); + design->selection_stack.push_back(RTLIL::Selection(false)); else - design->push_selection(work_stack.back()); + design->selection_stack.push_back(work_stack.back()); } // extern decl. in register.h @@ -1068,7 +1017,7 @@ RTLIL::Selection eval_select_args(const vector &args, RTLIL::Design *des work_stack.pop_back(); } if (work_stack.empty()) - return RTLIL::Selection::EmptySelection(design); + return RTLIL::Selection(false); return work_stack.back(); } @@ -1441,7 +1390,7 @@ struct SelectPass : public Pass { if (f.fail()) log_error("Can't open '%s' for reading: %s\n", read_file.c_str(), strerror(errno)); - auto sel = RTLIL::Selection::EmptySelection(design); + RTLIL::Selection sel(false); string line; while (std::getline(f, line)) { @@ -1482,7 +1431,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) { - auto sel = RTLIL::Selection::FullSelection(design); + RTLIL::Selection sel; select_filter_active_mod(design, sel); work_stack.push_back(sel); } @@ -1492,16 +1441,16 @@ struct SelectPass : public Pass { work_stack.pop_back(); } - log_assert(!design->selection_stack.empty()); + log_assert(design->selection_stack.size() > 0); if (clear_mode) { - design->selection() = RTLIL::Selection::FullSelection(design); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); return; } if (none_mode) { - design->selection() = RTLIL::Selection::EmptySelection(design); + design->selection_stack.back() = RTLIL::Selection(false); return; } @@ -1516,17 +1465,28 @@ 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) - design->push_selection(work_stack.back()); - RTLIL::Selection *sel = &design->selection(); + sel = &work_stack.back(); sel->optimize(design); - for (auto mod : design->all_selected_modules()) + for (auto mod : design->modules()) { if (sel->selected_whole_module(mod->name) && list_mode) log("%s\n", id2cstr(mod->name)); - if (!list_mod_mode) - for (auto it : mod->selected_members()) - LOG_OBJECT("%s/%s\n", id2cstr(mod->name), id2cstr(it->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 (count_mode) { @@ -1535,8 +1495,6 @@ struct SelectPass : public Pass { } if (f != nullptr) fclose(f); - if (work_stack.size() > 0) - design->pop_selection(); #undef LOG_OBJECT return; } @@ -1545,8 +1503,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(), work_stack.back()); - design->selection().optimize(design); + select_op_union(design, design->selection_stack.back(), work_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1554,8 +1512,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(), work_stack.back()); - design->selection().optimize(design); + select_op_diff(design, design->selection_stack.back(), work_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1595,13 +1553,23 @@ struct SelectPass : public Pass { if (work_stack.size() == 0) log_cmd_error("No selection to check.\n"); RTLIL::Selection *sel = &work_stack.back(); - design->push_selection(*sel); sel->optimize(design); - for (auto mod : design->all_selected_modules()) { - module_count++; - for ([[maybe_unused]] auto member_name : mod->selected_members()) - total_count++; - } + 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++; + } if (assert_modcount >= 0 && assert_modcount != module_count) { log_error("Assertion failed: selection contains %d modules instead of the asserted %d:%s\n", @@ -1625,14 +1593,13 @@ 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->pop_selection(); return; } if (!set_name.empty()) { if (work_stack.size() == 0) - design->selection_vars[set_name] = RTLIL::Selection::EmptySelection(design); + design->selection_vars[set_name] = RTLIL::Selection(false); else design->selection_vars[set_name] = work_stack.back(); return; @@ -1646,7 +1613,7 @@ struct SelectPass : public Pass { } if (work_stack.size() == 0) { - RTLIL::Selection &sel = design->selection(); + RTLIL::Selection &sel = design->selection_stack.back(); if (sel.full_selection) log("*\n"); for (auto &it : sel.selected_modules) @@ -1657,8 +1624,8 @@ struct SelectPass : public Pass { return; } - design->selection() = work_stack.back(); - design->selection().optimize(design); + design->selection_stack.back() = work_stack.back(); + design->selection_stack.back().optimize(design); } } SelectPass; @@ -1698,8 +1665,7 @@ struct CdPass : public Pass { log_cmd_error("Invalid number of arguments.\n"); if (args.size() == 1 || args[1] == "/") { - design->pop_selection(); - design->push_full_selection(); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); return; } @@ -1708,8 +1674,7 @@ struct CdPass : public Pass { { string modname = design->selected_active_module; - design->pop_selection(); - design->push_full_selection(); + design->selection_stack.back() = RTLIL::Selection(true); design->selected_active_module = std::string(); while (1) @@ -1726,10 +1691,9 @@ struct CdPass : public Pass { continue; design->selected_active_module = modname; - design->pop_selection(); - design->push_full_selection(); - select_filter_active_mod(design, design->selection()); - design->selection().optimize(design); + design->selection_stack.back() = RTLIL::Selection(); + select_filter_active_mod(design, design->selection_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1746,10 +1710,9 @@ struct CdPass : public Pass { if (design->module(modname) != nullptr) { design->selected_active_module = modname; - design->pop_selection(); - design->push_full_selection(); - select_filter_active_mod(design, design->selection()); - design->selection().optimize(design); + design->selection_stack.back() = RTLIL::Selection(); + select_filter_active_mod(design, design->selection_stack.back()); + design->selection_stack.back().optimize(design); return; } @@ -1796,7 +1759,7 @@ struct LsPass : public Pass { { std::vector matches; - for (auto mod : design->all_selected_modules()) + for (auto mod : design->selected_modules()) matches.push_back(mod->name); if (!matches.empty()) { diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 8a1bd58c4..82b5c6bcf 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(); - design->pop_selection(); + data.second = design->selection_stack.back(); + design->selection_stack.pop_back(); 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(); - design->pop_selection(); + data.second = design->selection_stack.back(); + design->selection_stack.pop_back(); label_selections.push_back(data); continue; } diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 7e25615bb..7e51b6cb1 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), mod->is_selected_whole() ? "" : " (partially selected)"); + log("=== %s%s ===\n", log_id(mod->name), design->selected_whole_module(mod->name) ? "" : " (partially selected)"); log("\n"); data.log_data(mod->name, false); } diff --git a/passes/cmds/viz.cc b/passes/cmds/viz.cc index 131e799ab..9dd68bd00 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()}); - design->pop_selection(); + config.groups.push_back({type, design->selection_stack.back()}); + design->selection_stack.pop_back(); 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 facc5d173..52fd59cf8 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 (!module->is_selected_whole() && opt_name.empty()) + if (!design->selected_whole_module(module->name) && opt_name.empty()) return; if (module->processes.size() > 0) { diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 620b38813..c37c03607 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_unboxed_whole_modules()) { + for (auto module : design->selected_whole_modules()) { if (module->has_processes()) continue; rmunused_module(module, purge_mode, ys_debug(), true); diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index 263a3a4c8..88f995dda 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 (module->is_selected_whole()) { + if (design->selected_whole_module(module->name)) { 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/sat/sim.cc b/passes/sat/sim.cc index dd2f1d255..8fac93b98 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_unboxed_whole_modules(); + auto mods = design->selected_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_unboxed_whole_modules(); + auto mods = design->selected_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/abc9.cc b/passes/techmap/abc9.cc index fe5cc7af1..a96a82659 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -306,10 +306,9 @@ 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 -autoproc -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); + run("techmap -wb -map %$abc9 -map +/techmap.v A:abc9_flop"); run("opt -nodffe -nosdff"); if (dff_mode || help_mode) { if (!help_mode) @@ -370,8 +369,6 @@ 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"); @@ -394,7 +391,7 @@ struct Abc9Pass : public ScriptPass } else { auto selected_modules = active_design->selected_modules(); - active_design->push_empty_selection(); + active_design->selection_stack.emplace_back(false); for (auto mod : selected_modules) { if (mod->processes.size() > 0) { @@ -403,9 +400,8 @@ struct Abc9Pass : public ScriptPass } log_push(); - active_design->select(mod); + active_design->selection().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)); @@ -456,7 +452,7 @@ struct Abc9Pass : public ScriptPass log_pop(); } - active_design->pop_selection(); + active_design->selection_stack.pop_back(); } } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 6cb569b5a..4c7667a43 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::EmptySelection(design))); + auto r = design->selection_vars.insert(std::make_pair(ID($abc9_flops), RTLIL::Selection(false))); 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 dfa2e2f71..5be823916 100644 --- a/passes/techmap/abc_new.cc +++ b/passes/techmap/abc_new.cc @@ -139,7 +139,7 @@ struct AbcNewPass : public ScriptPass { if (!help_mode) { selected_modules = order_modules(active_design, active_design->selected_whole_modules_warn()); - active_design->push_empty_selection(); + active_design->selection_stack.emplace_back(false); } else { selected_modules = {nullptr}; run("foreach module in selection"); @@ -157,7 +157,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->select(mod); + active_design->selection().select(mod); } std::string script_save; @@ -194,7 +194,7 @@ struct AbcNewPass : public ScriptPass { } if (!help_mode) { - active_design->pop_selection(); + active_design->selection_stack.pop_back(); } } } diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 19e568a61..4836ebe34 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -171,7 +171,8 @@ struct AigmapPass : public Pass { module->remove(cell); if (select_mode) { - RTLIL::Selection& sel = design->selection(); + log_assert(!design->selection_stack.empty()); + RTLIL::Selection& sel = design->selection_stack.back(); sel.selected_members[module->name] = std::move(new_sel); } diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 6a12e2005..363f998db 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -333,7 +333,7 @@ struct ClockgatePass : public Pass { dict clk_nets; int gated_flop_count = 0; - for (auto module : design->selected_unboxed_whole_modules()) { + for (auto module : design->selected_whole_modules()) { for (auto cell : module->cells()) { if (!RTLIL::builtin_ff_cell_types().count(cell->type)) continue; diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc index c823f10fe..016789157 100644 --- a/passes/techmap/nlutmap.cc +++ b/passes/techmap/nlutmap.cc @@ -42,7 +42,7 @@ struct NlutmapWorker RTLIL::Selection get_selection() { - auto sel = RTLIL::Selection::EmptySelection(module->design); + RTLIL::Selection sel(false); for (auto cell : module->cells()) if (!mapped_cells.count(cell)) sel.select(module, cell); diff --git a/tests/cxxrtl/run-test.sh b/tests/cxxrtl/run-test.sh index ee299fc82..fd11a3783 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; select =*; proc; clean; write_cxxrtl cxxrtl-test-unconnected_output.cc" +../../yosys -p "read_verilog test_unconnected_output.v; 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/select/boxes.v b/tests/select/blackboxes.ys similarity index 51% rename from tests/select/boxes.v rename to tests/select/blackboxes.ys index 696b26523..9bfe92c6b 100644 --- a/tests/select/boxes.v +++ b/tests/select/blackboxes.ys @@ -1,3 +1,4 @@ +read_verilog -specify <