From 7adb81e36e956b912a3356507a36189319c8fcf6 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Tue, 21 Jul 2026 19:20:42 +0200 Subject: [PATCH] rtlil: register a cloned cell's ports with the signorm index addCell(name, other) assigned connections_ wholesale, so a clone made while the module carries an index was invisible to it: its inputs were absent from the fanout and its outputs claimed no driver. The first setPort on the clone then tried to retract entries that had never been made and tripped the `erased' assertion. Go through setPort instead, which also interposes a wire wherever the original is still driving the net. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01MQU5XCqDYY8MbivGkNRrDo --- kernel/rtlil.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index e77ad14fb..4e78485a6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3824,14 +3824,22 @@ RTLIL::Cell *RTLIL::Module::addCell(TwineRef name, const RTLIL::Cell *other) type = this->design->twines.copy_from(src_design->twines, other->type_impl); RTLIL::Cell *cell = addCell(name, type); - if (cross_pool) { - for (auto &c : other->connections_) - cell->connections_[this->design->twines.copy_from(src_design->twines, c.first)] = c.second; - } else { - cell->connections_ = other->connections_; - } cell->parameters = other->parameters; cell->attributes = other->attributes; + + // Storing the connections directly would leave a signorm index blind to + // the clone: its inputs would be absent from the fanout and its outputs + // would claim no driver, so the first setPort on the clone would try to + // retract entries that were never made. Go through setPort there, which + // also interposes a wire wherever the original is still driving the net. + bool indexed = signorm_indexed(); + for (auto &c : other->connections_) { + TwineRef port = cross_pool ? this->design->twines.copy_from(src_design->twines, c.first) : c.first; + if (indexed) + cell->setPort(port, c.second); + else + cell->connections_[port] = c.second; + } if (src_design && this->design) copy_src_into(other, src_design, cell, this->design); return cell;