mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-15 03:35:40 +00:00
rtlil: fix twine handling
This commit is contained in:
parent
63043901ea
commit
54a3baa2de
1 changed files with 23 additions and 12 deletions
|
|
@ -1515,6 +1515,7 @@ RTLIL::Design::Design()
|
|||
hashidx_ = hashidx_count;
|
||||
|
||||
refcount_modules_ = 0;
|
||||
selected_active_module = Twine::Null;
|
||||
push_full_selection();
|
||||
|
||||
RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
|
||||
|
|
@ -1740,21 +1741,21 @@ void RTLIL::Design::clone_into(RTLIL::Design *dst) const
|
|||
|
||||
bool RTLIL::Design::selected_module(TwineRef mod_name) const
|
||||
{
|
||||
if (selected_active_module && mod_name != selected_active_module)
|
||||
if (selected_active_module != Twine::Null && mod_name != selected_active_module)
|
||||
return false;
|
||||
return selection().selected_module(mod_name);
|
||||
}
|
||||
|
||||
bool RTLIL::Design::selected_whole_module(TwineRef mod_name) const
|
||||
{
|
||||
if (selected_active_module && mod_name != selected_active_module)
|
||||
if (selected_active_module != Twine::Null && mod_name != selected_active_module)
|
||||
return false;
|
||||
return selection().selected_whole_module(mod_name);
|
||||
}
|
||||
|
||||
bool RTLIL::Design::selected_member(TwineRef mod_name, TwineRef memb_name) const
|
||||
{
|
||||
if (selected_active_module && mod_name != selected_active_module)
|
||||
if (selected_active_module != Twine::Null && mod_name != selected_active_module)
|
||||
return false;
|
||||
return selection().selected_member(mod_name, memb_name);
|
||||
}
|
||||
|
|
@ -3177,6 +3178,8 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
copy_src_into(this, this->design, new_mod, new_mod->design);
|
||||
}
|
||||
|
||||
dict<RTLIL::Wire*, RTLIL::Wire*> wire_map;
|
||||
|
||||
if (src_id_verbatim) {
|
||||
// Per-AttrObject meta clone via dst design's pool. TwineRefs for
|
||||
// src attributes transfer verbatim (twines was wholesale-copied).
|
||||
|
|
@ -3187,8 +3190,11 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
// Preserve name already set by addWire/addCell (in dst's pool).
|
||||
TwineRef saved_name = dst_obj->meta_ ? dst_obj->meta_->name : Twine::Null;
|
||||
// Recycle old meta slot (no field releases — name's retain lives on).
|
||||
if (dst_obj->meta_)
|
||||
if (dst_obj->meta_) {
|
||||
dst_obj->meta_->name = Twine::Null;
|
||||
dst_obj->meta_->src = Twine::Null;
|
||||
new_mod->design->free_obj_meta(dst_obj->meta_);
|
||||
}
|
||||
// Alloc new meta and struct-copy (src field is valid; name from
|
||||
// src pool is stale and will be overwritten).
|
||||
dst_obj->meta_ = new_mod->design->alloc_obj_meta();
|
||||
|
|
@ -3199,6 +3205,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
const RTLIL::Wire *o = it->second;
|
||||
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
RTLIL::Wire *w = new_mod->addWire(dst_name, o->width);
|
||||
wire_map[it->second] = w;
|
||||
w->start_offset = o->start_offset;
|
||||
w->port_id = o->port_id;
|
||||
w->port_input = o->port_input;
|
||||
|
|
@ -3275,7 +3282,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
// designs share the same pool (same-design clone).
|
||||
for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) {
|
||||
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||
new_mod->addWire(dst_id, it->second);
|
||||
wire_map[it->second] = new_mod->addWire(dst_id, it->second);
|
||||
}
|
||||
|
||||
for (auto it = memories.rbegin(); it != memories.rend(); ++it) {
|
||||
|
|
@ -3296,20 +3303,24 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons
|
|||
|
||||
struct RewriteSigSpecWorker
|
||||
{
|
||||
RTLIL::Module *mod;
|
||||
const dict<RTLIL::Wire*, RTLIL::Wire*> &wire_map;
|
||||
void operator()(RTLIL::SigSpec &sig)
|
||||
{
|
||||
sig.rewrite_wires([this](RTLIL::Wire *&wire) {
|
||||
// wire points to original module; look up by name in new module.
|
||||
// Use the IdString materialisation path: works for both same-design
|
||||
// and cross-design clones without assuming pool identity.
|
||||
wire = mod->wire(wire->meta_->name);
|
||||
// wire still points at the source module's wire; remap it to the
|
||||
// freshly cloned wire via the identity map built during the copy.
|
||||
// Lookup-by-name is ambiguous across pools (distinct refs can share
|
||||
// flattened content), so we map by source pointer instead. Wires
|
||||
// already owned by the destination (e.g. from a prior cloneInto
|
||||
// into the same module) aren't in the map and are left as-is.
|
||||
auto it = wire_map.find(wire);
|
||||
if (it != wire_map.end())
|
||||
wire = it->second;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
RewriteSigSpecWorker rewriteSigSpecWorker;
|
||||
rewriteSigSpecWorker.mod = new_mod;
|
||||
RewriteSigSpecWorker rewriteSigSpecWorker{wire_map};
|
||||
new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
|
||||
new_mod->fixup_ports();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue