From 1a8a95b472e99e623114a8b07bb4e0d009ceed91 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Sat, 6 Jun 2026 13:32:57 +0200 Subject: [PATCH] rtlil: fix masquerade --- frontends/ast/ast.cc | 27 ++++++++++++++++++++++++++- frontends/ast/ast.h | 1 + frontends/rpc/rpc_frontend.cc | 13 ++++++------- kernel/rtlil.cc | 15 +++++++++++++-- kernel/rtlil.h | 11 +++++++++++ passes/cmds/box_derive.cc | 2 +- passes/cmds/design.cc | 15 +++------------ passes/cmds/select.cc | 4 ++-- passes/techmap/abc9_ops.cc | 2 +- passes/techmap/clkbufmap.cc | 16 ++++++++-------- passes/techmap/iopadmap.cc | 10 +++++----- 11 files changed, 77 insertions(+), 39 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 9b12e9ca7..941f13a9b 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1931,6 +1931,7 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dictdesign = 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; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 2a672f010..bee277108 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -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; }; diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index bc5ef013d..189b86697 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -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); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index bcdbbd452..bc10c820f 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -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; } diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 479abe541..b7e950726 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -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; diff --git a/passes/cmds/box_derive.cc b/passes/cmds/box_derive.cc index 2d5ee2440..0a68113fd 100644 --- a/passes/cmds/box_derive.cc +++ b/passes/cmds/box_derive.cc @@ -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; diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc index 205452d3d..94172e051 100644 --- a/passes/cmds/design.cc +++ b/passes/cmds/design.cc @@ -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)); } } diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 375469bbb..6f7c55ad6 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -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)); } } diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index b753b8235..259bf4155 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -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()); diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index b94a80767..36ee9c898 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -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))); } } diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index f566b89fb..ba29d257a 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -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 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))