From 400becb6b6fa8ce0231a50172afd0cc65737499e Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 20 Mar 2024 02:03:53 +0100 Subject: [PATCH] Bugfix: proper handling of soft-connected instance connectors --- src/db/db/dbHierNetworkProcessor.cc | 56 ++++++++++++++-------------- src/lvs/unit_tests/lvsSimpleTests.cc | 6 +++ 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 6ed288b23..d05560fab 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -858,19 +858,20 @@ void local_clusters::join_cluster_with (typename local_cluster::id_type id, typename local_cluster::id_type with_id) { tl_assert (id > 0); - if (with_id == 0 || with_id > m_clusters.size () || id > m_clusters.size ()) { - return; + + if (with_id > 0 && with_id <= m_clusters.size () && id <= m_clusters.size ()) { + + // TODO: this const_cast is required. But we know what we're doing ... + local_cluster *with = const_cast *> (& m_clusters.objects ().item (with_id - 1)); + local_cluster *first = const_cast *> (& m_clusters.objects ().item (id - 1)); + first->join_with (*with); + + // NOTE: we cannot really delete a cluster as this would shift the indexes. So + // we just clear them. + with->clear (); + } - // TODO: this const_cast is required. But we know what we're doing ... - local_cluster *with = const_cast *> (& m_clusters.objects ().item (with_id - 1)); - local_cluster *first = const_cast *> (& m_clusters.objects ().item (id - 1)); - first->join_with (*with); - - // NOTE: we cannot really delete a cluster as this would shift the indexes. So - // we just clear them. - with->clear (); - // take care of soft connections std::set conn_down = downward_soft_connections (with_id); @@ -1821,22 +1822,6 @@ public: } - for (typename std::list >::const_iterator sc = m_cm2join_sets.begin (); sc != m_cm2join_sets.end (); ++sc) { - - if (sc->empty ()) { - // dropped ones are empty - continue; - } - - typename std::set::const_iterator c = sc->begin (); - typename std::set::const_iterator cc = c; - for (++cc; cc != sc->end (); ++cc) { - mp_cell_clusters->join_cluster_with (*c, *cc); - m_soft_connections.erase (std::make_pair (*c < *cc ? *c : *cc, *c < *cc ? *cc : *c)); - } - - } - for (auto sc = m_soft_connections.begin (); sc != m_soft_connections.end (); ++sc) { if (sc->second == 0) { @@ -1851,6 +1836,23 @@ public: } } + + for (typename std::list >::const_iterator sc = m_cm2join_sets.begin (); sc != m_cm2join_sets.end (); ++sc) { + + if (sc->empty ()) { + // dropped ones are empty + continue; + } + + typename std::set::const_iterator c = sc->begin (); + typename std::set::const_iterator cc = c; + for (++cc; cc != sc->end (); ++cc) { + mp_cell_clusters->join_cluster_with (*c, *cc); + // @@@ m_soft_connections.erase (std::make_pair (*c < *cc ? *c : *cc, *c < *cc ? *cc : *c)); + } + + } + } // needs explicit implementation because we have two base classes: diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index a5603bd3f..fe7f97127 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -301,3 +301,9 @@ TEST(40_DeviceExtractorErrors) run_test (_this, "custom_resistors", "custom_resistors.gds", true, false /*no LVS*/); } +// Basic soft connection +TEST(50_SoftConnection) +{ + run_test (_this, "soft_connect1", "soft_connect1.gds", true, false /*no LVS*/); +} +