From 8c7b1921d208f82e4e7a8a03bd0ee76fb3e9bbad Mon Sep 17 00:00:00 2001 From: Greeshma Manjegowda Date: Fri, 24 Jul 2026 16:34:40 -0500 Subject: [PATCH] ast: guard against module name collision during reprocessing process_module() could hit the modules_.count(module->name) == 0 assertion in Design::add() when a module gets reprocessed via AstModule::reprocess_if_necessary(). This happens for a parameterized module that instantiates a submodule inside a generate block, where the submodule only becomes available after the enclosing module's initial derivation. In that case, process_module() could attempt to register a module under a name that was already occupied. Guard the design add call in process_module() by removing any stale module already registered under the target name before adding the newly generated one. Verified against the reproduction case in issue #6002 (multiply elaborates successfully without crashing) and confirmed the previously working divide case produces identical output before and after this change. Fixes #6002 --- frontends/ast/ast.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 7e7c7e615..f2f179a0c 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1325,6 +1325,18 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d log("--- END OF RTLIL DUMP ---\n"); } + // Guard against a module with this name already being registered -- + // this can happen when reprocessing/re-deriving a module (e.g. via + // AstModule::reprocess_if_necessary()) causes the same parameterized + // module to be (re)generated more than once before the earlier + // in-flight copy has been added/removed. Without this, the + // "modules_.count(module->name) == 0" assertion in Design::add() + // below can fail. + if (RTLIL::Module *existing = design->module(module->name)) { + if (existing != current_module) + design->remove(existing); + } + design->add(current_module); return current_module; }