rtlil: fix masquerade

This commit is contained in:
Emil J. Tywoniak 2026-06-06 13:32:57 +02:00
parent 2d3b7e9c92
commit 1a8a95b472
11 changed files with 77 additions and 39 deletions

View File

@ -1931,6 +1931,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id
RTLIL::Module *AstModule::clone() const
{
AstModule *new_mod = new AstModule;
new_mod->design = design;
new_mod->name = name;
cloneInto(new_mod);
@ -1955,8 +1956,32 @@ RTLIL::Module *AstModule::clone(RTLIL::Design *dst, bool src_id_verbatim) const
AstModule *new_mod = new AstModule;
new_mod->design = dst;
new_mod->name = name;
dst->add(new_mod);
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
new_mod->ast = ast->clone();
new_mod->nolatches = nolatches;
new_mod->nomeminit = nomeminit;
new_mod->nomem2reg = nomem2reg;
new_mod->mem2reg = mem2reg;
new_mod->noblackbox = noblackbox;
new_mod->lib = lib;
new_mod->nowb = nowb;
new_mod->noopt = noopt;
new_mod->icells = icells;
new_mod->pwires = pwires;
new_mod->autowire = autowire;
return new_mod;
}
RTLIL::Module *AstModule::clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim) const
{
AstModule *new_mod = new AstModule;
new_mod->design = dst;
new_mod->name = target_name;
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
new_mod->ast = ast->clone();
new_mod->nolatches = nolatches;

View File

@ -403,6 +403,7 @@ namespace AST
bool reprocess_if_necessary(RTLIL::Design *design) override;
RTLIL::Module *clone() const override;
RTLIL::Module *clone(RTLIL::Design *dst, bool src_id_verbatim = false) const override;
RTLIL::Module *clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim = false) const override;
void loadconfig() const;
};

View File

@ -214,13 +214,11 @@ struct RpcModule : RTLIL::Module {
log("Importing `%s' as `%s'.\n", module.first.unescape(), mangled_name);
module.second->name = mangled_name;
module.second->design = design;
module.second->attributes.erase(ID::top);
if (!module.second->has_attribute(ID::hdlname))
module.second->set_string_attribute(ID::hdlname, module.first.str());
design->modules_[mangled_name] = module.second;
derived_design->modules_.erase(module.first);
RTLIL::IdString original_name = module.first;
RTLIL::Module *t = module.second->clone(design, RTLIL::IdString(mangled_name));
t->attributes.erase(ID::top);
if (!t->has_attribute(ID::hdlname))
t->set_string_attribute(ID::hdlname, original_name.str());
}
delete derived_design;
@ -588,6 +586,7 @@ cleanup_path:
for (auto &module_name : server->get_module_names()) {
log("Linking module `%s'.\n", module_name);
RpcModule *module = new RpcModule;
module->design = design;
module->name = "$abstract\\" + module_name;
module->server = server;
design->add(module);

View File

@ -258,7 +258,8 @@ void RTLIL::OwningIdString::collect_garbage()
for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) {
for (RTLIL::Module *module : design->modules()) {
collectors[0].trace_named(*module);
collectors[0].trace_keys(module->attributes);
collectors[0].trace(RTLIL::IdString(module->name));
ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000));
subpool.run([&collectors, module](const ParallelDispatchThreadPool::RunCtx &ctx) {
for (int i : ctx.item_range(module->cells_size()))
@ -3266,8 +3267,18 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, bool src_id_verbatim) co
RTLIL::Module *new_mod = new RTLIL::Module;
new_mod->design = dst;
new_mod->name = name;
dst->add(new_mod);
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
return new_mod;
}
RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim) const
{
RTLIL::Module *new_mod = new RTLIL::Module;
new_mod->design = dst;
new_mod->name = target_name;
cloneInto(new_mod, src_id_verbatim);
dst->add(new_mod);
return new_mod;
}

View File

@ -2807,6 +2807,13 @@ public:
// still hits the (now-unused) inline base field. Writing requires
// module->design to be set first.
struct RTLIL::ModuleNameMasq {
// Copying/moving is forbidden: a ModuleNameMasq derives its identity from
// `this` via offsetof(Module, name), so any instance not embedded in a
// Module would resolve to garbage. All conversions go through
// operator IdString() at the embedded location.
ModuleNameMasq() = default;
ModuleNameMasq(const ModuleNameMasq&) = delete;
ModuleNameMasq(ModuleNameMasq&&) = delete;
operator RTLIL::IdString() const;
ModuleNameMasq& operator=(RTLIL::IdString id);
// Without this, `new_mod->name = src_mod->name` invokes the implicit
@ -2951,6 +2958,10 @@ public:
// preserve their type (AstModule). `src_id_verbatim` is forwarded to
// cloneInto.
virtual RTLIL::Module *clone(RTLIL::Design *dst, bool src_id_verbatim = false) const;
// As above, but additionally renames the new module to `target_name` in
// `dst`. Used when source and destination designs may contain modules
// with the same name and the new one must take a different identity.
virtual RTLIL::Module *clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim = false) const;
bool has_memories() const;
bool has_processes() const;

View File

@ -94,7 +94,7 @@ struct BoxDerivePass : Pass {
if (base_override)
base = base_override;
auto index = std::make_pair(base->name, cell->parameters);
auto index = std::make_pair(RTLIL::IdString(base->name), cell->parameters);
if (cell->parameters.empty())
continue;

View File

@ -268,11 +268,8 @@ struct DesignPass : public Pass {
{
log("Importing %s as %s.\n", mod, RTLIL::unescape_id(prefix));
RTLIL::Module *t = mod->clone();
t->name = prefix;
t->design = copy_to_design;
RTLIL::Module *t = mod->clone(copy_to_design, RTLIL::IdString(prefix));
t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(t);
done[mod->name] = prefix;
@ -300,11 +297,8 @@ struct DesignPass : public Pass {
if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name));
RTLIL::Module *t = fmod->clone();
t->name = trg_name;
t->design = copy_to_design;
RTLIL::Module *t = fmod->clone(copy_to_design, RTLIL::IdString(trg_name));
t->attributes.erase(ID::top);
copy_to_design->add(t);
queue.insert(t);
done[cell->type] = trg_name;
@ -327,10 +321,7 @@ struct DesignPass : public Pass {
if (copy_to_design->module(trg_name) != nullptr)
copy_to_design->remove(copy_to_design->module(trg_name));
RTLIL::Module *t = mod->clone();
t->name = trg_name;
t->design = copy_to_design;
copy_to_design->add(t);
mod->clone(copy_to_design, RTLIL::IdString(trg_name));
}
}

View File

@ -239,12 +239,12 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c
for (auto cell : mod->cells()) {
if (lhs.selected_member(mod->name, cell->name))
objects.push_back(make_pair(mod->name, cell->name));
objects.push_back(make_pair(RTLIL::IdString(mod->name), cell->name));
}
for (auto wire : mod->wires()) {
if (lhs.selected_member(mod->name, wire->name))
objects.push_back(make_pair(mod->name, wire->name));
objects.push_back(make_pair(RTLIL::IdString(mod->name), wire->name));
}
}

View File

@ -45,7 +45,7 @@ void check(RTLIL::Design *design, bool dff_mode)
if (it == m->attributes.end())
continue;
auto id = it->second.as_int();
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name));
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), RTLIL::IdString(m->name)));
if (!r.second)
log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
m, id, r.first->second.unescape());

View File

@ -145,16 +145,16 @@ struct ClkbufmapPass : public Pass {
auto wire = module->wire(port);
if (wire->get_bool_attribute(ID::clkbuf_driver))
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
if (wire->get_bool_attribute(ID::clkbuf_sink))
for (int i = 0; i < GetSize(wire); i++)
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
auto it = wire->attributes.find(ID::clkbuf_inv);
if (it != wire->attributes.end()) {
IdString in_name = RTLIL::escape_id(it->second.decode_string());
for (int i = 0; i < GetSize(wire); i++) {
inv_ports_out[make_pair(module->name, make_pair(wire->name, i))] = make_pair(in_name, i);
inv_ports_in[make_pair(module->name, make_pair(in_name, i))] = make_pair(wire->name, i);
inv_ports_out[make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))] = make_pair(in_name, i);
inv_ports_in[make_pair(RTLIL::IdString(module->name), make_pair(in_name, i))] = make_pair(wire->name, i);
}
}
}
@ -236,7 +236,7 @@ struct ClkbufmapPass : public Pass {
// some buffer higher up in the hierarchy.
if (wire->port_output)
for (int i = 0; i < GetSize(wire); i++)
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
continue;
}
@ -249,7 +249,7 @@ struct ClkbufmapPass : public Pass {
if (buf_wire_bits.count(mapped_wire_bit)) {
// Already buffered downstream. If this is an output, mark it.
if (wire->port_output)
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
} else if (!sink_wire_bits.count(mapped_wire_bit)) {
// Nothing to do.
} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) {
@ -288,7 +288,7 @@ struct ClkbufmapPass : public Pass {
// A clock input in a submodule -- mark it, let higher level
// worry about it.
if (wire->port_input)
sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
}
}
if (!input_bits.empty()) {
@ -320,7 +320,7 @@ struct ClkbufmapPass : public Pass {
SigBit wire_bit(wire, i);
SigBit mapped_wire_bit = sigmap(wire_bit);
if (buffered_bits.count(mapped_wire_bit))
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
}
}

View File

@ -217,7 +217,7 @@ struct IopadmapPass : public Pass {
// Collect explicitly-marked already-buffered SigBits.
for (auto wire : module->wires())
if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(module->name, wire->name)))
if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(RTLIL::IdString(module->name), wire->name)))
for (int i = 0; i < GetSize(wire); i++)
buf_bits.insert(sigmap(SigBit(wire, i)));
@ -233,7 +233,7 @@ struct IopadmapPass : public Pass {
if (wire->port_input || wire->port_output)
for (int i = 0; i < GetSize(wire); i++)
if (buf_bits.count(sigmap(SigBit(wire, i)))) {
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
log("Marking already mapped port: %s.%s[%d].\n", module, wire, i);
}
}
@ -293,7 +293,7 @@ struct IopadmapPass : public Pass {
SigBit wire_bit(wire, i);
Cell *tbuf_cell = nullptr;
if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))))
continue;
if (tbuf_bits.count(wire_bit))
@ -370,7 +370,7 @@ struct IopadmapPass : public Pass {
if (!toutpad_portname_pad.empty())
rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad));
}
buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)));
}
}
}
@ -384,7 +384,7 @@ struct IopadmapPass : public Pass {
pool<int> skip_bit_indices;
for (int i = 0; i < GetSize(wire); i++)
if (buf_ports.count(make_pair(module->name, make_pair(wire->name, i))))
if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))))
skip_bit_indices.insert(i);
if (GetSize(wire) == GetSize(skip_bit_indices))