diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index d8ed3d9a9..5d0568a73 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -538,22 +538,25 @@ public: (*mp_interacting_this) [l1].insert (s1); } if (mp_interacting_other) { - (*mp_interacting_this) [l2].insert (s2); + (*mp_interacting_other) [l2].insert (s2); } if (soft == 0 || (m_soft_mode != 0 && m_soft_mode != soft)) { m_soft_mode = 0; - if (! mp_interacting_other && ! mp_interacting_this) { - m_any = true; - } + m_any = true; } else { m_soft_mode = soft; } } } + bool any () const + { + return m_any || m_soft_mode != 0; + } + bool stop () const { - return m_any; + return m_any && ! mp_interacting_other && ! mp_interacting_this; } int soft_mode () const @@ -715,8 +718,9 @@ local_cluster::interacts (const local_cluster &other, const db::ICplxTrans std::map > *p_is_other = interacting_other ? &is_other : 0; hnp_interaction_receiver rec (conn, trans, p_is_this, p_is_other); + scanner.process (rec, 1 /*==touching*/, bc, bc_t); - if (! scanner.process (rec, 1 /*==touching*/, bc, bc_t) || rec.soft_mode () != 0) { + if (rec.any ()) { if (p_is_this) { collect_interactions_in_original_order (m_shapes, *p_is_this, *interacting_this); diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index e503518f9..bc8c2a958 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -1311,9 +1311,43 @@ static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const std::map LayoutToNetlist::shapes_of_pin (const db::NetSubcircuitPinRef &pin, const db::ICplxTrans &trans) const { + std::map result; - // @@@ + const db::Net *net = pin.net (); + if (! net || ! net->circuit () || ! pin.subcircuit () || ! pin.subcircuit ()->circuit_ref ()) { + return result; + } + auto cc = m_net_clusters.clusters_per_cell (net->circuit ()->cell_index ()); + auto c = cc.cluster_by_id (net->cluster_id ()); + + double dbu = internal_layout ()->dbu (); + db::ICplxTrans sc_trans = db::CplxTrans (dbu).inverted () * pin.subcircuit ()->trans () * db::CplxTrans (dbu); + + const db::Net *other_net = pin.subcircuit ()->circuit_ref ()->net_for_pin (pin.pin_id ()); + if (! other_net) { + return result; + } + + auto cc_other = m_net_clusters.clusters_per_cell (pin.subcircuit ()->circuit_ref ()->cell_index ()); + auto c_other = cc_other.cluster_by_id (other_net->cluster_id ()); + + std::map > interacting; + int soft = 0; + if (! c.interacts (c_other, sc_trans, m_conn, soft, 0, &interacting)) { + return result; + } + + auto t = trans * sc_trans; + + for (auto i = interacting.begin (); i != interacting.end (); ++i) { + db::Region &r = result [i->first]; + for (auto s = i->second.begin (); s != i->second.end (); ++s) { + deliver_shape (**s, r, t, 0); + } + } + + return result; } void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to, db::properties_id_type propid, const ICplxTrans &trans) const diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index 26b670fc5..c6a817149 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -692,6 +692,8 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "also by touching subcircuits. In that case, the nets do not have shapes of their own and this function cannot detect\n" "the pin shapes.\n" "\n" + "The call of this method is not cheap, specificially if large nets are involved.\n" + "\n" "This method has been introduced in version 0.29.2." ) + gsi::factory ("shapes_of_net", (db::Region *(db::LayoutToNetlist::*) (const db::Net &, const db::Region &, bool, const db::ICplxTrans &) const) &db::LayoutToNetlist::shapes_of_net, gsi::arg ("net"), gsi::arg ("of_layer"), gsi::arg ("recursive", true), gsi::arg ("trans", db::ICplxTrans (), "unity"),