diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 8ac6a9581..2fe29c4ec 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -525,16 +525,21 @@ public: typedef typename local_cluster::box_type box_type; hnp_interaction_receiver (const Connectivity &conn, const db::ICplxTrans &trans) - : mp_conn (&conn), m_any (false), m_trans (trans) + : mp_conn (&conn), m_any (false), m_soft_mode (0), m_trans (trans) { // .. nothing yet .. } void add (const T *s1, unsigned int l1, const T *s2, unsigned int l2) { - int soft; // @@@ + int soft = 0; if (mp_conn->interacts (*s1, l1, *s2, l2, m_trans, soft)) { - m_any = true; + if (soft == 0 || (m_soft_mode != 0 && m_soft_mode != soft)) { + m_soft_mode = 0; + m_any = true; + } else { + m_soft_mode = soft; + } } } @@ -543,9 +548,15 @@ public: return m_any; } + int soft_mode () const + { + return m_soft_mode; + } + private: const Connectivity *mp_conn; bool m_any; + int m_soft_mode; db::ICplxTrans m_trans; }; @@ -596,7 +607,7 @@ local_cluster::interacts (const db::Cell &cell, const db::ICplxTrans &trans, Connectivity::layer_iterator le = conn.end_connected (s->first); for (Connectivity::layer_iterator l = conn.begin_connected (s->first); l != le; ++l) { - box += cell.bbox (l->first); // @@@ soft connections? + box += cell.bbox (l->first); } if (! box.empty () && ! s->second.begin_touching (box.transformed (trans), bc).at_end ()) { @@ -610,7 +621,7 @@ local_cluster::interacts (const db::Cell &cell, const db::ICplxTrans &trans, template bool -local_cluster::interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn) const +local_cluster::interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft) const { db::box_convert bc; @@ -669,7 +680,13 @@ local_cluster::interacts (const local_cluster &other, const db::ICplxTrans } hnp_interaction_receiver rec (conn, trans); - return ! scanner.process (rec, 1 /*==touching*/, bc, bc_t); + + if (! scanner.process (rec, 1 /*==touching*/, bc, bc_t) || rec.soft_mode () != 0) { + soft = rec.soft_mode (); + return true; + } else { + return false; + } } template @@ -970,7 +987,7 @@ struct cluster_building_receiver if (m_separate_attributes && p1.second != p2.second) { return; } - int soft; // @@@ + int soft = 0; if (! mp_conn->interacts (*s1, p1.first, *s2, p2.first, soft)) { return; } @@ -982,34 +999,88 @@ struct cluster_building_receiver if (ic2 == m_shape_to_clusters.end ()) { - m_clusters.push_back (cluster_value ()); - typename std::list::iterator c = --m_clusters.end (); - c->first.push_back (std::make_pair (s1, p1)); - c->first.push_back (std::make_pair (s2, p2)); + if (soft != 0) { - m_shape_to_clusters.insert (std::make_pair (s1, c)); - m_shape_to_clusters.insert (std::make_pair (s2, c)); + m_clusters.push_back (cluster_value ()); + typename std::list::iterator c1 = --m_clusters.end (); + m_clusters.push_back (cluster_value ()); + typename std::list::iterator c2 = --m_clusters.end (); + c1->first.push_back (std::make_pair (s1, p1)); + c2->first.push_back (std::make_pair (s2, p2)); + + m_shape_to_clusters.insert (std::make_pair (s1, c1)); + m_shape_to_clusters.insert (std::make_pair (s2, c2)); + + register_soft_connection (c1, c2, soft); + + } else { + + m_clusters.push_back (cluster_value ()); + typename std::list::iterator c = --m_clusters.end (); + c->first.push_back (std::make_pair (s1, p1)); + c->first.push_back (std::make_pair (s2, p2)); + + m_shape_to_clusters.insert (std::make_pair (s1, c)); + m_shape_to_clusters.insert (std::make_pair (s2, c)); + + } } else { - ic2->second->first.push_back (std::make_pair (s1, p1)); - m_shape_to_clusters.insert (std::make_pair (s1, ic2->second)); + if (soft != 0) { + + m_clusters.push_back (cluster_value ()); + typename std::list::iterator c1 = --m_clusters.end (); + + c1->first.push_back (std::make_pair (s1, p1)); + m_shape_to_clusters.insert (std::make_pair (s1, c1)); + + register_soft_connection (c1, ic2->second, soft); + + } else { + + ic2->second->first.push_back (std::make_pair (s1, p1)); + m_shape_to_clusters.insert (std::make_pair (s1, ic2->second)); + + } } } else if (ic2 == m_shape_to_clusters.end ()) { - ic1->second->first.push_back (std::make_pair (s2, p2)); - m_shape_to_clusters.insert (std::make_pair (s2, ic1->second)); + if (soft != 0) { + + m_clusters.push_back (cluster_value ()); + typename std::list::iterator c2 = --m_clusters.end (); + + c2->first.push_back (std::make_pair (s2, p2)); + m_shape_to_clusters.insert (std::make_pair (s2, c2)); + + register_soft_connection (ic1->second, c2, soft); + + } else { + + ic1->second->first.push_back (std::make_pair (s2, p2)); + m_shape_to_clusters.insert (std::make_pair (s2, ic1->second)); + + } } else if (ic1->second != ic2->second) { - // join clusters: use the larger one as the target + if (soft != 0) { + + register_soft_connection (ic1->second, ic2->second, soft); - if (ic1->second->first.size () < ic2->second->first.size ()) { - join (ic2->second, ic1->second); } else { - join (ic1->second, ic2->second); + + // join clusters: use the larger one as the target + + if (ic1->second->first.size () < ic2->second->first.size ()) { + join (ic2->second, ic1->second); + } else { + join (ic1->second, ic2->second); + } + } } @@ -1034,20 +1105,42 @@ struct cluster_building_receiver db::Connectivity::global_nets_iterator ge = mp_conn->end_global_connections (p.first); for (db::Connectivity::global_nets_iterator g = mp_conn->begin_global_connections (p.first); g != ge; ++g) { - typename std::map::iterator>::iterator icg = m_global_to_clusters.find (g->first); // @@@ soft connections + typename std::map::iterator>::iterator icg = m_global_to_clusters.find (g->first); if (icg == m_global_to_clusters.end ()) { - ic->second->second.insert (g->first); // @@@ soft connections? - m_global_to_clusters.insert (std::make_pair (g->first, ic->second)); // @@@ soft connections? + if (g->second != 0) { + + // soft connection to a new global cluster + m_clusters.push_back (cluster_value ()); + typename std::list::iterator cg = --m_clusters.end (); + + m_global_to_clusters.insert (std::make_pair (g->first, cg)); + + register_soft_connection (ic->second, cg, g->second); + + } else { + + ic->second->second.insert (g->first); + m_global_to_clusters.insert (std::make_pair (g->first, ic->second)); + + } } else if (ic->second != icg->second) { - // join clusters - if (ic->second->first.size () < icg->second->first.size ()) { - join (icg->second, ic->second); + if (g->second != 0) { + + register_soft_connection (ic->second, icg->second, g->second); + } else { - join (ic->second, icg->second); + + // join clusters + if (ic->second->first.size () < icg->second->first.size ()) { + join (icg->second, ic->second); + } else { + join (ic->second, icg->second); + } + } } @@ -1078,6 +1171,13 @@ private: m_clusters.erase (ic2); } + + void register_soft_connection (typename std::list::iterator ic1, typename std::list::iterator ic2, int soft) + { + + // @@@ TODO: implement + + } }; template @@ -1687,7 +1787,7 @@ private: if (! bb1.empty ()) { db::Connectivity::layer_iterator lbe = mp_conn->end_connected (*la); for (db::Connectivity::layer_iterator lb = mp_conn->begin_connected (*la); lb != lbe && ! any; ++lb) { - db::box_convert bcb (*mp_layout, lb->first); // @@@ soft connections? + db::box_convert bcb (*mp_layout, lb->first); box_type bb2 = i2.cell_inst ().bbox (bcb).transformed (t2); any = bb1.touches (bb2); } @@ -1860,7 +1960,9 @@ private: box_type bc2 = (common2 & i->bbox ().transformed (t12)); for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) { - if ((! m_separate_attributes || i->same_attrs (*j)) && i->interacts (*j, t21, *mp_conn)) { + int soft = 0; + if ((! m_separate_attributes || i->same_attrs (*j)) && i->interacts (*j, t21, *mp_conn, soft)) { + // @@@ soft mode? new_interactions.push_back (std::make_pair (i->id (), j->id ())); } @@ -2032,8 +2134,13 @@ private: for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (c1.bbox ().transformed (t2.inverted ())); ! j.at_end (); ++j) { - if ((! m_separate_attributes || c1.same_attrs (*j)) && c1.interacts (*j, t2, *mp_conn)) { - interactions.push_back (std::make_pair (c1.id (), j->id ())); + int soft = 0; + if ((! m_separate_attributes || c1.same_attrs (*j)) && c1.interacts (*j, t2, *mp_conn, soft)) { + if (soft != 0) { + // @@@ TODO: soft mode + } else { + interactions.push_back (std::make_pair (c1.id (), j->id ())); + } } } diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 72bb54302..e0c51fd53 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -327,7 +327,7 @@ public: * "trans" is the transformation which is applied to the other cluster before * the test. */ - bool interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn) const; + bool interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft) const; /** * @brief Tests whether this cluster interacts with the given cell diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 4bf968152..4bf49e1d3 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -1218,7 +1218,8 @@ size_t LayoutToNetlist::search_net (const db::ICplxTrans &trans, const db::Cell const db::local_clusters &lcc = net_clusters ().clusters_per_cell (cell->cell_index ()); for (db::local_clusters::touching_iterator i = lcc.begin_touching (local_box); ! i.at_end (); ++i) { const db::local_cluster &lc = *i; - if (lc.interacts (test_cluster, trans, m_conn)) { + int soft = 0; + if (lc.interacts (test_cluster, trans, m_conn, soft)) { return lc.id (); } } diff --git a/src/db/unit_tests/dbHierNetworkProcessorTests.cc b/src/db/unit_tests/dbHierNetworkProcessorTests.cc index 4034b099a..6c771ec19 100644 --- a/src/db/unit_tests/dbHierNetworkProcessorTests.cc +++ b/src/db/unit_tests/dbHierNetworkProcessorTests.cc @@ -293,21 +293,22 @@ TEST(11_LocalClusterInteractBasic) db::local_cluster cluster; db::local_cluster cluster2; + int soft; - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster.add (db::PolygonRef (poly, repo), 0); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster2.add (db::PolygonRef (poly, repo), 0); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (10, 20))), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1000))), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1001))), conn), false); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 2000))), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (10, 20))), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1000))), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1001))), conn, soft), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 2000))), conn, soft), false); cluster.clear (); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); } TEST(11_LocalClusterInteractDifferentLayers) @@ -326,28 +327,29 @@ TEST(11_LocalClusterInteractDifferentLayers) db::local_cluster cluster; db::local_cluster cluster2; + int soft; - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster.add (db::PolygonRef (poly, repo), 0); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster2.add (db::PolygonRef (poly, repo), 1); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (10, 20))), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1000))), conn), true); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1001))), conn), false); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 2000))), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (10, 20))), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1000))), conn, soft), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 1001))), conn, soft), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (db::Trans (db::Vector (0, 2000))), conn, soft), false); cluster.clear (); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster.add (db::PolygonRef (poly, repo), 2); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); // not connected + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); // not connected cluster.clear (); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), false); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), false); cluster.add (db::PolygonRef (poly, repo), 1); - EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn), true); + EXPECT_EQ (cluster.interacts (cluster2, db::ICplxTrans (), conn, soft), true); } static std::string obj2string (const db::PolygonRef &ref)