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
This commit is contained in:
Greeshma Manjegowda 2026-07-24 16:34:40 -05:00
parent 7defa51862
commit 8c7b1921d2
1 changed files with 12 additions and 0 deletions

View File

@ -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;
}