diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 306d52628..3e808c03e 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1567,6 +1567,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) input_error("Memory `%s' with non-constant width or size!\n", str); RTLIL::Memory *memory = new RTLIL::Memory; + memory->module = current_module; set_src_attr(memory, this); memory->name = str; memory->width = children[0]->range_left - children[0]->range_right + 1; diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc index 8d2d1bdd2..fb704dfa7 100644 --- a/frontends/json/jsonparse.cc +++ b/frontends/json/jsonparse.cc @@ -604,6 +604,7 @@ void json_import(Design *design, string &modname, JsonNode *node) RTLIL::Memory *mem = new RTLIL::Memory; mem->name = memory_name; + mem->module = module; if (memory_node->type != 'D') log_error("JSON memory node '%s' is not a dictionary.\n", memory_name.unescape()); diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 4dcca6b89..7b0eedc6b 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -680,6 +680,7 @@ struct RTLILFrontendWorker { void parse_memory() { RTLIL::Memory *memory = new RTLIL::Memory; + memory->module = current_module; memory->absorb_attrs(&design->src_twines, std::move(attrbuf)); int width = 1; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6b876c0f1..34ab12a42 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1625,6 +1625,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma { RTLIL::Memory *memory = new RTLIL::Memory; memory->name = RTLIL::escape_id(net->Name()); + memory->module = module; log_assert(module->count_id(memory->name) == 0); module->memories[memory->name] = memory; import_attributes(memory->attributes, net, nl); diff --git a/kernel/mem.cc b/kernel/mem.cc index f75a3cca7..6d3bba551 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -294,6 +294,7 @@ void Mem::emit() { memid = NEW_ID; mem = new RTLIL::Memory; mem->name = memid; + mem->module = module; module->memories[memid] = mem; } mem->width = width; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 1fc91be8c..601d3693e 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3611,6 +3611,7 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name) { RTLIL::Memory *mem = new RTLIL::Memory; mem->name = std::move(name); + mem->module = this; memories[mem->name] = mem; return mem; } @@ -3619,14 +3620,15 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memor { RTLIL::Memory *mem = new RTLIL::Memory; mem->name = std::move(name); + mem->module = this; mem->width = other->width; mem->start_offset = other->start_offset; mem->size = other->size; mem->attributes = other->attributes; { - // Memory has no module backpointer of its own — we can't know its - // source pool from `other` alone. Drop src in the rare clone-of- - // memory path; addMemory(name) is the common one and starts fresh. + // Clone path drops src for now — caller responsible for migrating + // src across the design boundary if needed. addMemory(name) is the + // common case. (void)other; } memories[mem->name] = mem; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ae6cbb3f8..1f8d2299b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -2286,6 +2286,13 @@ struct RTLIL::Memory : public RTLIL::NamedObject Memory(); + // Back-pointer to the owning module — same role as Cell::module / + // Wire::module. Set by Module::addMemory / the frontends that + // construct Memory free-standing before attaching to a module. + // Lets Memory's src access (and the upcoming per-Design meta vector + // lookup) resolve uniformly via module->design. + RTLIL::Module *module = nullptr; + int width, start_offset, size; #ifdef YOSYS_ENABLE_PYTHON ~Memory();