mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
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.
This commit is contained in:
parent
e44d1d404a
commit
398afd102e
3 changed files with 197 additions and 114 deletions
|
@ -766,8 +766,21 @@ vector<int> RTLIL::AttrObject::get_intvec_attribute(const RTLIL::IdString &id) c
|
|||
return data;
|
||||
}
|
||||
|
||||
bool RTLIL::Selection::boxed_module(const RTLIL::IdString &mod_name) const
|
||||
{
|
||||
if (current_design != nullptr) {
|
||||
auto module = current_design->module(mod_name);
|
||||
return module && module->get_blackbox_attribute();
|
||||
} else {
|
||||
log_warning("Unable to check if module is boxed for null design.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const
|
||||
{
|
||||
if (!selects_boxes && boxed_module(mod_name))
|
||||
return false;
|
||||
if (full_selection)
|
||||
return true;
|
||||
if (selected_modules.count(mod_name) > 0)
|
||||
|
@ -779,6 +792,8 @@ bool RTLIL::Selection::selected_module(const RTLIL::IdString &mod_name) const
|
|||
|
||||
bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) const
|
||||
{
|
||||
if (!selects_boxes && boxed_module(mod_name))
|
||||
return false;
|
||||
if (full_selection)
|
||||
return true;
|
||||
if (selected_modules.count(mod_name) > 0)
|
||||
|
@ -788,6 +803,8 @@ bool RTLIL::Selection::selected_whole_module(const RTLIL::IdString &mod_name) co
|
|||
|
||||
bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const
|
||||
{
|
||||
if (!selects_boxes && boxed_module(mod_name))
|
||||
return false;
|
||||
if (full_selection)
|
||||
return true;
|
||||
if (selected_modules.count(mod_name) > 0)
|
||||
|
@ -800,6 +817,19 @@ bool RTLIL::Selection::selected_member(const RTLIL::IdString &mod_name, const RT
|
|||
|
||||
void RTLIL::Selection::optimize(RTLIL::Design *design)
|
||||
{
|
||||
if (design != current_design) {
|
||||
current_design = design;
|
||||
}
|
||||
|
||||
if (selects_boxes && full_selection) {
|
||||
selected_modules.clear();
|
||||
selected_members.clear();
|
||||
full_selection = false;
|
||||
for (auto mod : current_design->modules()) {
|
||||
selected_modules.insert(mod->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (full_selection) {
|
||||
selected_modules.clear();
|
||||
selected_members.clear();
|
||||
|
@ -810,7 +840,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
|
|||
|
||||
del_list.clear();
|
||||
for (auto mod_name : selected_modules) {
|
||||
if (design->modules_.count(mod_name) == 0)
|
||||
if (current_design->modules_.count(mod_name) == 0)
|
||||
del_list.push_back(mod_name);
|
||||
selected_members.erase(mod_name);
|
||||
}
|
||||
|
@ -819,7 +849,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
|
|||
|
||||
del_list.clear();
|
||||
for (auto &it : selected_members)
|
||||
if (design->modules_.count(it.first) == 0)
|
||||
if (current_design->modules_.count(it.first) == 0)
|
||||
del_list.push_back(it.first);
|
||||
for (auto mod_name : del_list)
|
||||
selected_members.erase(mod_name);
|
||||
|
@ -827,7 +857,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
|
|||
for (auto &it : selected_members) {
|
||||
del_list.clear();
|
||||
for (auto memb_name : it.second)
|
||||
if (design->modules_[it.first]->count_id(memb_name) == 0)
|
||||
if (current_design->modules_[it.first]->count_id(memb_name) == 0)
|
||||
del_list.push_back(memb_name);
|
||||
for (auto memb_name : del_list)
|
||||
it.second.erase(memb_name);
|
||||
|
@ -838,8 +868,8 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
|
|||
for (auto &it : selected_members)
|
||||
if (it.second.size() == 0)
|
||||
del_list.push_back(it.first);
|
||||
else if (it.second.size() == design->modules_[it.first]->wires_.size() + design->modules_[it.first]->memories.size() +
|
||||
design->modules_[it.first]->cells_.size() + design->modules_[it.first]->processes.size())
|
||||
else if (it.second.size() == current_design->modules_[it.first]->wires_.size() + current_design->modules_[it.first]->memories.size() +
|
||||
current_design->modules_[it.first]->cells_.size() + current_design->modules_[it.first]->processes.size())
|
||||
add_list.push_back(it.first);
|
||||
for (auto mod_name : del_list)
|
||||
selected_members.erase(mod_name);
|
||||
|
@ -848,7 +878,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design)
|
|||
selected_modules.insert(mod_name);
|
||||
}
|
||||
|
||||
if (selected_modules.size() == design->modules_.size()) {
|
||||
if (!selects_boxes && selected_modules.size() == current_design->modules_.size()) {
|
||||
full_selection = true;
|
||||
selected_modules.clear();
|
||||
selected_members.clear();
|
||||
|
@ -863,7 +893,7 @@ RTLIL::Design::Design()
|
|||
hashidx_ = hashidx_count;
|
||||
|
||||
refcount_modules_ = 0;
|
||||
selection_stack.push_back(RTLIL::Selection());
|
||||
selection_stack.push_back(RTLIL::Selection(true, false, this));
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
|
||||
|
@ -1127,7 +1157,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
|
|||
std::vector<RTLIL::Module*> result;
|
||||
result.reserve(modules_.size());
|
||||
for (auto &it : modules_)
|
||||
if (selected_module(it.first) && !it.second->get_blackbox_attribute())
|
||||
if (selected_module(it.first))
|
||||
result.push_back(it.second);
|
||||
return result;
|
||||
}
|
||||
|
@ -1137,7 +1167,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
|
|||
std::vector<RTLIL::Module*> result;
|
||||
result.reserve(modules_.size());
|
||||
for (auto &it : modules_)
|
||||
if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute())
|
||||
if (selected_whole_module(it.first))
|
||||
result.push_back(it.second);
|
||||
return result;
|
||||
}
|
||||
|
@ -1146,13 +1176,13 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn(bool incl
|
|||
{
|
||||
std::vector<RTLIL::Module*> result;
|
||||
result.reserve(modules_.size());
|
||||
for (auto &it : modules_)
|
||||
if (it.second->get_blackbox_attribute(include_wb))
|
||||
continue;
|
||||
else if (selected_whole_module(it.first))
|
||||
for (auto &it : modules_) {
|
||||
log_assert(selection_stack.size() > 0 || !it.second->get_blackbox_attribute(include_wb));
|
||||
if (selected_whole_module(it.first))
|
||||
result.push_back(it.second);
|
||||
else if (selected_module(it.first))
|
||||
log_warning("Ignoring partially selected module %s.\n", log_id(it.first));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2431,6 +2461,40 @@ std::vector<RTLIL::Cell*> RTLIL::Module::selected_cells() const
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<RTLIL::Memory*> RTLIL::Module::selected_memories() const
|
||||
{
|
||||
std::vector<RTLIL::Memory*> 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::Process*> RTLIL::Module::selected_processes() const
|
||||
{
|
||||
std::vector<RTLIL::Process*> 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::NamedObject*> RTLIL::Module::selected_members() const
|
||||
{
|
||||
std::vector<RTLIL::NamedObject*> 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());
|
||||
|
|
|
@ -58,6 +58,7 @@ namespace RTLIL
|
|||
|
||||
struct Const;
|
||||
struct AttrObject;
|
||||
struct NamedObject;
|
||||
struct Selection;
|
||||
struct Monitor;
|
||||
struct Design;
|
||||
|
@ -869,6 +870,11 @@ struct RTLIL::AttrObject
|
|||
vector<int> get_intvec_attribute(const RTLIL::IdString &id) const;
|
||||
};
|
||||
|
||||
struct RTLIL::NamedObject : public RTLIL::AttrObject
|
||||
{
|
||||
RTLIL::IdString name;
|
||||
};
|
||||
|
||||
struct RTLIL::SigChunk
|
||||
{
|
||||
RTLIL::Wire *wire;
|
||||
|
@ -1135,11 +1141,14 @@ public:
|
|||
struct RTLIL::Selection
|
||||
{
|
||||
bool full_selection;
|
||||
bool selects_boxes;
|
||||
pool<RTLIL::IdString> selected_modules;
|
||||
dict<RTLIL::IdString, pool<RTLIL::IdString>> selected_members;
|
||||
RTLIL::Design *current_design;
|
||||
|
||||
Selection(bool full = true) : full_selection(full) { }
|
||||
Selection(bool full = true, bool boxes = false, RTLIL::Design *design = nullptr) : full_selection(full), selects_boxes(boxes), current_design(design) { }
|
||||
|
||||
bool boxed_module(const RTLIL::IdString &mod_name) const;
|
||||
bool selected_module(const RTLIL::IdString &mod_name) const;
|
||||
bool selected_whole_module(const RTLIL::IdString &mod_name) const;
|
||||
bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const;
|
||||
|
@ -1290,7 +1299,7 @@ struct RTLIL::Design
|
|||
#endif
|
||||
};
|
||||
|
||||
struct RTLIL::Module : public RTLIL::AttrObject
|
||||
struct RTLIL::Module : public RTLIL::NamedObject
|
||||
{
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
@ -1313,7 +1322,6 @@ public:
|
|||
std::vector<RTLIL::SigSig> connections_;
|
||||
std::vector<RTLIL::Binding*> bindings_;
|
||||
|
||||
RTLIL::IdString name;
|
||||
idict<RTLIL::IdString> avail_parameters;
|
||||
dict<RTLIL::IdString, RTLIL::Const> parameter_default_values;
|
||||
dict<RTLIL::IdString, RTLIL::Memory*> memories;
|
||||
|
@ -1360,6 +1368,9 @@ public:
|
|||
|
||||
std::vector<RTLIL::Wire*> selected_wires() const;
|
||||
std::vector<RTLIL::Cell*> selected_cells() const;
|
||||
std::vector<RTLIL::Memory*> selected_memories() const;
|
||||
std::vector<RTLIL::Process*> selected_processes() const;
|
||||
std::vector<RTLIL::NamedObject*> selected_members() const;
|
||||
|
||||
template<typename T> bool selected(T *member) const {
|
||||
return design->selected_member(name, member->name);
|
||||
|
@ -1645,7 +1656,7 @@ namespace RTLIL_BACKEND {
|
|||
void dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
|
||||
}
|
||||
|
||||
struct RTLIL::Wire : public RTLIL::AttrObject
|
||||
struct RTLIL::Wire : public RTLIL::NamedObject
|
||||
{
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
@ -1668,7 +1679,6 @@ public:
|
|||
void operator=(RTLIL::Wire &other) = delete;
|
||||
|
||||
RTLIL::Module *module;
|
||||
RTLIL::IdString name;
|
||||
int width, start_offset, port_id;
|
||||
bool port_input, port_output, upto, is_signed;
|
||||
|
||||
|
@ -1697,14 +1707,13 @@ inline int GetSize(RTLIL::Wire *wire) {
|
|||
return wire->width;
|
||||
}
|
||||
|
||||
struct RTLIL::Memory : public RTLIL::AttrObject
|
||||
struct RTLIL::Memory : public RTLIL::NamedObject
|
||||
{
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
||||
Memory();
|
||||
|
||||
RTLIL::IdString name;
|
||||
int width, start_offset, size;
|
||||
#ifdef WITH_PYTHON
|
||||
~Memory();
|
||||
|
@ -1712,7 +1721,7 @@ struct RTLIL::Memory : public RTLIL::AttrObject
|
|||
#endif
|
||||
};
|
||||
|
||||
struct RTLIL::Cell : public RTLIL::AttrObject
|
||||
struct RTLIL::Cell : public RTLIL::NamedObject
|
||||
{
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
@ -1729,7 +1738,6 @@ public:
|
|||
void operator=(RTLIL::Cell &other) = delete;
|
||||
|
||||
RTLIL::Module *module;
|
||||
RTLIL::IdString name;
|
||||
RTLIL::IdString type;
|
||||
dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
|
||||
dict<RTLIL::IdString, RTLIL::Const> parameters;
|
||||
|
@ -1822,7 +1830,7 @@ struct RTLIL::SyncRule
|
|||
RTLIL::SyncRule *clone() const;
|
||||
};
|
||||
|
||||
struct RTLIL::Process : public RTLIL::AttrObject
|
||||
struct RTLIL::Process : public RTLIL::NamedObject
|
||||
{
|
||||
Hasher::hash_t hashidx_;
|
||||
[[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; }
|
||||
|
@ -1834,7 +1842,6 @@ protected:
|
|||
~Process();
|
||||
|
||||
public:
|
||||
RTLIL::IdString name;
|
||||
RTLIL::Module *module;
|
||||
RTLIL::CaseRule root_case;
|
||||
std::vector<RTLIL::SyncRule*> syncs;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue