mirror of https://github.com/YosysHQ/yosys.git
rtlil: fix twine handling
This commit is contained in:
parent
63043901ea
commit
54a3baa2de
|
|
@ -1515,6 +1515,7 @@ RTLIL::Design::Design()
|
||||||
hashidx_ = hashidx_count;
|
hashidx_ = hashidx_count;
|
||||||
|
|
||||||
refcount_modules_ = 0;
|
refcount_modules_ = 0;
|
||||||
|
selected_active_module = Twine::Null;
|
||||||
push_full_selection();
|
push_full_selection();
|
||||||
|
|
||||||
RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
|
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
|
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 false;
|
||||||
return selection().selected_module(mod_name);
|
return selection().selected_module(mod_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTLIL::Design::selected_whole_module(TwineRef mod_name) const
|
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 false;
|
||||||
return selection().selected_whole_module(mod_name);
|
return selection().selected_whole_module(mod_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTLIL::Design::selected_member(TwineRef mod_name, TwineRef memb_name) const
|
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 false;
|
||||||
return selection().selected_member(mod_name, memb_name);
|
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);
|
copy_src_into(this, this->design, new_mod, new_mod->design);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dict<RTLIL::Wire*, RTLIL::Wire*> wire_map;
|
||||||
|
|
||||||
if (src_id_verbatim) {
|
if (src_id_verbatim) {
|
||||||
// Per-AttrObject meta clone via dst design's pool. TwineRefs for
|
// Per-AttrObject meta clone via dst design's pool. TwineRefs for
|
||||||
// src attributes transfer verbatim (twines was wholesale-copied).
|
// 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).
|
// Preserve name already set by addWire/addCell (in dst's pool).
|
||||||
TwineRef saved_name = dst_obj->meta_ ? dst_obj->meta_->name : Twine::Null;
|
TwineRef saved_name = dst_obj->meta_ ? dst_obj->meta_->name : Twine::Null;
|
||||||
// Recycle old meta slot (no field releases — name's retain lives on).
|
// 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_);
|
new_mod->design->free_obj_meta(dst_obj->meta_);
|
||||||
|
}
|
||||||
// Alloc new meta and struct-copy (src field is valid; name from
|
// Alloc new meta and struct-copy (src field is valid; name from
|
||||||
// src pool is stale and will be overwritten).
|
// src pool is stale and will be overwritten).
|
||||||
dst_obj->meta_ = new_mod->design->alloc_obj_meta();
|
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;
|
const RTLIL::Wire *o = it->second;
|
||||||
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
|
TwineRef dst_name = new_mod->design->twines.copy_from(design->twines, it->first);
|
||||||
RTLIL::Wire *w = new_mod->addWire(dst_name, o->width);
|
RTLIL::Wire *w = new_mod->addWire(dst_name, o->width);
|
||||||
|
wire_map[it->second] = w;
|
||||||
w->start_offset = o->start_offset;
|
w->start_offset = o->start_offset;
|
||||||
w->port_id = o->port_id;
|
w->port_id = o->port_id;
|
||||||
w->port_input = o->port_input;
|
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).
|
// designs share the same pool (same-design clone).
|
||||||
for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) {
|
for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) {
|
||||||
TwineRef dst_id = new_mod->design->twines.copy_from(design->twines, it->first);
|
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) {
|
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
|
struct RewriteSigSpecWorker
|
||||||
{
|
{
|
||||||
RTLIL::Module *mod;
|
const dict<RTLIL::Wire*, RTLIL::Wire*> &wire_map;
|
||||||
void operator()(RTLIL::SigSpec &sig)
|
void operator()(RTLIL::SigSpec &sig)
|
||||||
{
|
{
|
||||||
sig.rewrite_wires([this](RTLIL::Wire *&wire) {
|
sig.rewrite_wires([this](RTLIL::Wire *&wire) {
|
||||||
// wire points to original module; look up by name in new module.
|
// wire still points at the source module's wire; remap it to the
|
||||||
// Use the IdString materialisation path: works for both same-design
|
// freshly cloned wire via the identity map built during the copy.
|
||||||
// and cross-design clones without assuming pool identity.
|
// Lookup-by-name is ambiguous across pools (distinct refs can share
|
||||||
wire = mod->wire(wire->meta_->name);
|
// 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 rewriteSigSpecWorker{wire_map};
|
||||||
rewriteSigSpecWorker.mod = new_mod;
|
|
||||||
new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
|
new_mod->rewrite_sigspecs(rewriteSigSpecWorker);
|
||||||
new_mod->fixup_ports();
|
new_mod->fixup_ports();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue