From 68d4426bf35874bca7300c4d8b7769d5406b7741 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Wed, 29 Apr 2026 19:20:56 +0000 Subject: [PATCH 1/2] fix for sta-1648 in read_spef Signed-off-by: dsengupta0628 --- parasitics/SpefReader.cc | 39 ++++++++++++++++++++++++++++++++++++- parasitics/SpefReaderPvt.hh | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 05141673..35a99c51 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -133,10 +133,39 @@ SpefReader::setBusBrackets(char left, bus_brkt_right_ = right; } +std::string +SpefReader::stripped(std::string_view spef_name) const +{ + std::string out; + out.reserve(spef_name.size()); + for (size_t i = 0; i < spef_name.size(); i++) { + char ch = spef_name[i]; + if (ch == '\\' && i + 1 < spef_name.size()) + out += spef_name[++i]; + else + out += ch; + } + return out; +} + Instance * SpefReader::findInstanceRelative(std::string_view name) { - return sdc_network_->findInstanceRelative(instance_, name); + // Network::findInstanceRelative splits at unescaped '/' and walks + // hierarchy. That misses flat instance names with a literal '/' (e.g. + // post-CTS buffers like "u_x/g1234") because there is no parent module + // matching the pre-'/' segment; it also misses bracket-escaped names + // ("bus\[0\]") whose unescaped form is what the DEF reader stored. + // dbNetwork::findInstance has a flat block_->findInst() fallback that + // both cases need. + Instance *inst = sdc_network_->findInstanceRelative(instance_, name); + if (inst == nullptr) + inst = network_->findInstance(name); + if (inst == nullptr && name.find('\\') != std::string_view::npos) + inst = network_->findInstance(stripped(name)); + debugPrint(debug_, "spef_lookup", 1, "findInstance '{}' -> {}", name, + inst ? "found" : "miss"); + return inst; } Net * @@ -147,6 +176,14 @@ SpefReader::findNetRelative(std::string_view name) // don't follow the rules. if (net == nullptr) net = sdc_network_->findNetRelative(instance_, name); + // dbNetwork::findNet at top scope does a literal block_->findNet() which + // finds flat names with '/' that findNetRelative cannot. + if (net == nullptr) + net = network_->findNet(instance_, name); + if (net == nullptr && name.find('\\') != std::string_view::npos) + net = network_->findNet(instance_, stripped(name)); + debugPrint(debug_, "spef_lookup", 1, "findNet '{}' -> {}", name, + net ? "found" : "miss"); return net; } diff --git a/parasitics/SpefReaderPvt.hh b/parasitics/SpefReaderPvt.hh index 4b1b90ff..22fa9b9d 100644 --- a/parasitics/SpefReaderPvt.hh +++ b/parasitics/SpefReaderPvt.hh @@ -121,6 +121,7 @@ private: Pin *findPortPinRelative(std::string_view name); Net *findNetRelative(std::string_view name); Instance *findInstanceRelative(std::string_view name); + std::string stripped(std::string_view spef_name) const; ParasiticNode *findParasiticNode(std::string_view name, bool local_only); From 1e6e43bb48b5f370983bf3c643e1a2d519a2b316 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Thu, 30 Apr 2026 01:14:22 +0000 Subject: [PATCH 2/2] gemini feedback Signed-off-by: dsengupta0628 --- parasitics/SpefReader.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 35a99c51..1c6a5f41 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -160,9 +160,9 @@ SpefReader::findInstanceRelative(std::string_view name) // both cases need. Instance *inst = sdc_network_->findInstanceRelative(instance_, name); if (inst == nullptr) - inst = network_->findInstance(name); + inst = network_->findChild(instance_, name); if (inst == nullptr && name.find('\\') != std::string_view::npos) - inst = network_->findInstance(stripped(name)); + inst = network_->findChild(instance_, stripped(name)); debugPrint(debug_, "spef_lookup", 1, "findInstance '{}' -> {}", name, inst ? "found" : "miss"); return inst;