diff --git a/src/dbSta/include/db_sta/dbNetwork.hh b/src/dbSta/include/db_sta/dbNetwork.hh index 9d2fbf19b26..9c1998c938c 100644 --- a/src/dbSta/include/db_sta/dbNetwork.hh +++ b/src/dbSta/include/db_sta/dbNetwork.hh @@ -360,7 +360,10 @@ class dbNetwork : public ConcreteNetwork // Return the highest net above the given net. // - If the net is a flat net, return it. - // - If the net is a hier net, return the modnet in the highest hierarchy. + // - If the net is a hier net (dbModNet), return the associated flat dbNet. + // This ensures parasitic externality checks in ensureParasiticNode work + // correctly: net_ is always a flat net, so the comparison net != net_ + // must also operate on flat nets. Net* highestNetAbove(Net* net) const override; //////////////////////////////////////////////////////////////// diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 4a104e6754c..b62c26d8df7 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -2016,9 +2016,18 @@ void dbNetwork::visitConnectedPins(const Net* net, } } +// Caution: +//- Network::highestConnectedNet(Net *net) retrieves the highest hierarchical +// net connected to the given net. +// - But `dbNetwork::highestConnectedNet(Net* net)` retrieves the corresponding +// flat net for the given net. +// - It behaves differently to cope with the issue 9724. +// - This redefinition may cause another issue later when +// `Network::highestConnectedNet(Net *net)` is used elsewhere. const Net* dbNetwork::highestConnectedNet(Net* net) const { - return net; + const Net* flat = findFlatNet(net); + return flat ? flat : net; } //////////////////////////////////////////////////////////////// @@ -5198,11 +5207,15 @@ Net* dbNetwork::highestNetAbove(Net* net) const } if (modnet) { + // Return the flat net associated with this mod net. + // Parasitic externality checks in + // ConcreteParasiticNetwork::ensureParasiticNode compare against net_ which + // is always a flat net (set via makeParasiticNetwork). Returning the + // highest mod net causes all pin nodes on hierarchically-connected nets to + // compare unequal to net_ and be incorrectly marked as external, making + // node_count_ = 0 and crashing PRIMA in measureThresholds. if (dbNet* related_dbnet = modnet->findRelatedNet()) { - if (odb::dbModNet* highest_modnet - = related_dbnet->findModNetInHighestHier()) { - return dbToSta(highest_modnet); // Found the highest modnet - } + return dbToSta(related_dbnet); } } diff --git a/src/dbSta/test/cpp/TestDbSta.cc b/src/dbSta/test/cpp/TestDbSta.cc index d752d0421b1..f1c9c549d34 100644 --- a/src/dbSta/test/cpp/TestDbSta.cc +++ b/src/dbSta/test/cpp/TestDbSta.cc @@ -77,9 +77,11 @@ TEST_F(TestDbSta, TestHierarchyConnectivity) ASSERT_NE(modnet_out2, nullptr); Net* sta_modnet_out2 = db_network_->dbToSta(modnet_out2); ASSERT_NE(sta_modnet_out2, nullptr); + // highestNetAbove on a mod net now returns the associated flat dbNet, not the + // highest mod net, so that parasitic externality checks work correctly. Net* sta_highest_modnet_out = db_network_->highestNetAbove(sta_modnet_mod_out); - ASSERT_EQ(sta_highest_modnet_out, sta_modnet_out2); + ASSERT_EQ(sta_highest_modnet_out, sta_dbnet_out2); // Check get_ports -of_object Net* NetTermIterator* term_iter = db_network_->termIterator(sta_dbnet_out2); diff --git a/src/sta b/src/sta index ffda41536fe..41ad5c62b8f 160000 --- a/src/sta +++ b/src/sta @@ -1 +1 @@ -Subproject commit ffda41536fe1cff4a3a9eed7caf9f810f63234e0 +Subproject commit 41ad5c62b8f6f2596d9b1983255c0928537bdd31