diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index f15013901..69918db97 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -383,6 +383,48 @@ private: }; template class hier_clusters; +template class connected_clusters; + +/** + * @brief An iterator delivering all clusters of a connected_clusters set + */ +template +class DB_PUBLIC connected_clusters_iterator +{ +public: + typedef typename local_cluster::id_type value_type; + + connected_clusters_iterator (const connected_clusters &c); + + connected_clusters_iterator &operator++ () + { + if (! m_lc_iter.at_end ()) { + ++m_lc_iter; + } else if (m_x_iter != m_x_iter_end) { + ++m_x_iter; + } + return *this; + } + + bool at_end () const + { + return m_lc_iter.at_end () && m_x_iter == m_x_iter_end; + } + + value_type operator* () const + { + if (m_lc_iter.at_end ()) { + return m_x_iter->first; + } else { + return m_lc_iter->id (); + } + } + +private: + typename local_clusters::const_iterator m_lc_iter; + typedef std::list connections_type; + typename std::map::id_type, connections_type>::const_iterator m_x_iter, m_x_iter_end; +}; /** * @brief Local clusters with connections to clusters from child cells @@ -394,6 +436,7 @@ class DB_PUBLIC connected_clusters public: typedef std::list connections_type; typedef typename local_clusters::box_type box_type; + typedef connected_clusters_iterator all_iterator; /** * @brief Constructor @@ -429,11 +472,38 @@ public: */ void join_cluster_with (typename local_cluster::id_type id, typename local_cluster::id_type with_id); + /** + * @brief An iterator delivering all clusters (even the connectors) + * + * This iterator will deliver ID's rather than cluster objects. + */ + all_iterator begin_all () const + { + return connected_clusters_iterator (*this); + } + private: + template friend class connected_clusters_iterator; + std::map::id_type, connections_type> m_connections; std::map::id_type> m_rev_connections; }; +template +connected_clusters_iterator::connected_clusters_iterator (const connected_clusters &c) + : m_lc_iter (c.begin ()) +{ + size_t max_id = 0; + for (typename connected_clusters::const_iterator i = c.begin (); i != c.end (); ++i) { + if (i->id () > max_id) { + max_id = i->id (); + } + } + + m_x_iter = c.m_connections.lower_bound (max_id + 1); + m_x_iter_end = c.m_connections.end (); +} + template class cell_clusters_box_converter; /** diff --git a/src/db/unit_tests/dbHierNetworkProcessorTests.cc b/src/db/unit_tests/dbHierNetworkProcessorTests.cc index 3ca36d282..e92130442 100644 --- a/src/db/unit_tests/dbHierNetworkProcessorTests.cc +++ b/src/db/unit_tests/dbHierNetworkProcessorTests.cc @@ -421,7 +421,7 @@ static void normalize_layer (db::Layout &layout, unsigned int layer) } } -static void copy_cluster_shapes (db::Shapes &out, db::cell_index_type ci, const db::hier_clusters &hc, const db::local_cluster &cluster, const db::ICplxTrans &trans, const db::Connectivity &conn) +static void copy_cluster_shapes (db::Shapes &out, db::cell_index_type ci, const db::hier_clusters &hc, db::local_cluster::id_type cluster_id, const db::ICplxTrans &trans, const db::Connectivity &conn) { // use property #1 to code the cell name @@ -431,9 +431,12 @@ static void copy_cluster_shapes (db::Shapes &out, db::cell_index_type ci, const pm.insert (std::make_pair (pn_id, tl::Variant (out.layout ()->cell_name (ci)))); db::properties_id_type cell_pid = pr.properties_id (pm); + const db::connected_clusters &clusters = hc.clusters_per_cell (ci); + const db::local_cluster &lc = clusters.cluster_by_id (cluster_id); + // copy the shapes from this cell for (db::Connectivity::layer_iterator l = conn.begin_layers (); l != conn.end_layers (); ++l) { - for (db::local_cluster::shape_iterator s = cluster.begin (*l); ! s.at_end (); ++s) { + for (db::local_cluster::shape_iterator s = lc.begin (*l); ! s.at_end (); ++s) { db::Polygon poly = s->obj ().transformed (trans * db::ICplxTrans (s->trans ())); out.insert (db::PolygonWithProperties (poly, cell_pid)); } @@ -443,13 +446,13 @@ static void copy_cluster_shapes (db::Shapes &out, db::cell_index_type ci, const // copy the shapes from the child cells too typedef db::connected_clusters::connections_type connections_type; - const connections_type &connections = hc.clusters_per_cell (ci).connections_for_cluster (cluster.id ()); + const connections_type &connections = clusters.connections_for_cluster (cluster_id); for (connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) { db::ICplxTrans t = trans * i->inst ().complex_trans (); db::cell_index_type cci = i->inst ().inst_ptr.cell_index (); - copy_cluster_shapes (out, cci, hc, hc.clusters_per_cell (cci).cluster_by_id (i->id ()), t, conn); + copy_cluster_shapes (out, cci, hc, i->id (), t, conn); } } @@ -510,7 +513,7 @@ static void run_hc_test (tl::TestBase *_this, const std::string &file, const std for (db::Layout::top_down_const_iterator td = ly.begin_top_down (); td != ly.end_top_down (); ++td) { const db::connected_clusters &clusters = hc.clusters_per_cell (*td); - for (db::connected_clusters::const_iterator c = clusters.begin (); ! c.at_end (); ++c) { + for (db::connected_clusters::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) { net_layers.push_back (std::make_pair (0, ly.insert_layer ())); @@ -543,22 +546,32 @@ static void run_hc_test (tl::TestBase *_this, const std::string &file, const std db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/" + au_file); } -TEST(40_HierClusters) +TEST(41_HierClusters) { run_hc_test (_this, "hc_test_l1.gds", "hc_test_au1.gds"); } -TEST(41_HierClusters) +TEST(42_HierClusters) { run_hc_test (_this, "hc_test_l2.gds", "hc_test_au2.gds"); } -TEST(42_HierClusters) +TEST(43_HierClusters) { run_hc_test (_this, "hc_test_l3.gds", "hc_test_au3.gds"); } -TEST(43_HierClusters) +TEST(44_HierClusters) { run_hc_test (_this, "hc_test_l4.gds", "hc_test_au4.gds"); } + +TEST(45_HierClusters) +{ + run_hc_test (_this, "hc_test_l5.gds", "hc_test_au5.gds"); +} + +TEST(46_HierClusters) +{ + run_hc_test (_this, "hc_test_l6.gds", "hc_test_au6.gds"); +} diff --git a/testdata/algo/hc_test_au5.gds b/testdata/algo/hc_test_au5.gds new file mode 100644 index 000000000..9ca93f454 Binary files /dev/null and b/testdata/algo/hc_test_au5.gds differ diff --git a/testdata/algo/hc_test_au6.gds b/testdata/algo/hc_test_au6.gds new file mode 100644 index 000000000..520e0bbfd Binary files /dev/null and b/testdata/algo/hc_test_au6.gds differ diff --git a/testdata/algo/hc_test_l5.gds b/testdata/algo/hc_test_l5.gds new file mode 100644 index 000000000..1ed519c46 Binary files /dev/null and b/testdata/algo/hc_test_l5.gds differ diff --git a/testdata/algo/hc_test_l6.gds b/testdata/algo/hc_test_l6.gds new file mode 100644 index 000000000..38ff58c9c Binary files /dev/null and b/testdata/algo/hc_test_l6.gds differ