From c44b8097dd338ed0db83e53de80d0126a9e61b43 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 6 Jun 2024 19:54:56 +0200 Subject: [PATCH] Deep search for pin shapes, added shapes_of_terminal --- src/db/db/dbLayoutToNetlist.cc | 78 ++++++++++++++++++++++----- src/db/db/dbLayoutToNetlist.h | 18 ++++++- src/db/db/gsiDeclDbLayoutToNetlist.cc | 30 +++++++++-- 3 files changed, 107 insertions(+), 19 deletions(-) diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index bc8c2a958..0fc0f40ad 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -1308,6 +1308,43 @@ static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const return true; } +void +LayoutToNetlist::collect_shapes_of_pin (const local_cluster &c, const db::Net *other_net, const db::ICplxTrans &sc_trans, const db::ICplxTrans &trans, std::map &result) const +{ + if (! other_net || ! other_net->circuit ()) { + return; + } + + auto cc_other = m_net_clusters.clusters_per_cell (other_net->circuit ()->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)) { + + 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); + } + } + + } + + double dbu = internal_layout ()->dbu (); + + for (auto p = other_net->begin_subcircuit_pins (); p != other_net->end_subcircuit_pins (); ++p) { + + db::ICplxTrans sc_trans2 = sc_trans * db::CplxTrans (dbu).inverted () * p->subcircuit ()->trans () * db::CplxTrans (dbu); + const db::Net *other_net2 = p->subcircuit ()->circuit_ref ()->net_for_pin (p->pin_id ()); + + collect_shapes_of_pin (c, other_net2, sc_trans2, trans, result); + + } +} + std::map LayoutToNetlist::shapes_of_pin (const db::NetSubcircuitPinRef &pin, const db::ICplxTrans &trans) const { @@ -1323,28 +1360,45 @@ LayoutToNetlist::shapes_of_pin (const db::NetSubcircuitPinRef &pin, const db::IC 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) { + + collect_shapes_of_pin (c, other_net, sc_trans, trans, result); + + return result; +} + +std::map +LayoutToNetlist::shapes_of_terminal (const db::NetTerminalRef &terminal, const db::ICplxTrans &trans) const +{ + std::map result; + + const db::Net *net = terminal.net (); + if (! net || ! net->circuit () || ! terminal.device () || ! terminal.device ()->device_abstract ()) { 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 ()); + 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 d_trans = db::CplxTrans (dbu).inverted () * terminal.device ()->trans () * db::CplxTrans (dbu); + + auto cc_other = m_net_clusters.clusters_per_cell (terminal.device ()->device_abstract ()->cell_index ()); + auto c_other = cc_other.cluster_by_id (terminal.device ()->device_abstract ()->cluster_id_for_terminal (terminal.terminal_id ())); std::map > interacting; int soft = 0; - if (! c.interacts (c_other, sc_trans, m_conn, soft, 0, &interacting)) { - return result; - } + if (c.interacts (c_other, d_trans, m_conn, soft, 0, &interacting)) { - auto t = trans * sc_trans; + auto t = trans * d_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); + 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; diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index f1b426392..4d1d1ef49 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -836,11 +836,24 @@ public: * shapes, transformed into the coordinate space of the net. * * Note that this method only considers top-down interactions between the shapes of the net - * and subcircuits, not between subcircuits. It is useful only for certain topologies - i.e. - * digital nets connecting gate cells. + * and subcircuits on any level below, but not between subcircuits. + * It is useful only for certain topologies - i.e. digital nets connecting gate cells. */ std::map shapes_of_pin (const db::NetSubcircuitPinRef &pin, const db::ICplxTrans &trans = db::ICplxTrans ()) const; + /** + * @brief Gets the shapes that make the device terminal + * + * This method looks up all shapes from the device terminals that interact with the shapes of the net + * the device terminal lives in. It will return a map of layer index vs. Region with these + * shapes, transformed into the coordinate space of the net. + * + * Note that this method only considers top-down interactions between the shapes of the net + * and subcircuits on any level below, but not between subcircuits and devices. + * It is useful for flat-extracted netlists for example. + */ + std::map shapes_of_terminal (const db::NetTerminalRef &terminal, const db::ICplxTrans &trans = db::ICplxTrans ()) const; + /** * @brief Returns all shapes of a specific net and layer. * @@ -1112,6 +1125,7 @@ private: void ensure_layout () const; std::string make_new_name (const std::string &stem = std::string ()); db::CellMapping make_cell_mapping_into (db::Layout &layout, db::Cell &cell, const std::vector *nets, bool with_device_cells); + void collect_shapes_of_pin (const local_cluster &c, const db::Net *other_net, const db::ICplxTrans &sc_trans, const db::ICplxTrans &trans, std::map &result) const; void connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b); size_t connect_global_impl (const db::ShapeCollection &l, const std::string &gn); void soft_connect_impl (const db::ShapeCollection &a, const db::ShapeCollection &b); diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index c6a817149..3d11ee518 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -679,20 +679,40 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "@brief gets the netlist extracted (0 if no extraction happened yet)\n" ) + gsi::method ("shapes_of_pin", &db::LayoutToNetlist::shapes_of_pin, gsi::arg ("pin"), gsi::arg ("trans", db::ICplxTrans (), "unity"), - "@brief Returns all shapes of the given subcircuit pin.\n" - "This will return all shapes from the subcircuit attached by the given pin that interact with the net.\n" - "This method returns a \Region object with the shapes per layer where interactions are found.\n" + "@brief Returns all shapes of the given subcircuit pin that make a connection to the net the pin lives in.\n" + "This will return all shapes from the subcircuit attached by the given pin that interact with the net the pin lives in.\n" + "This method returns a \\Region object with the shapes per layer where interactions are found.\n" "The layers are given as layer indexes.\n" "\n" "The returned shapes are already transformed into the coordinate system of the net (see \\shapes_of_net for example).\n" "An additional transformation can be applied using the optional \\trans argument.\n" "\n" - "Note, that this method only considers interations between net shapes and subcircuits, not between subcircuits.\n" + "Note, that this method only considers interations between net shapes and subcircuits on every level below, " + "but not between subcircuits.\n" "It can be used for example for digital nets connecting gate cells. In the general case however, nets may be formed\n" "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" + "The call of this method may not be cheap, specificially if large nets are involved.\n" + "\n" + "This method has been introduced in version 0.29.2." + ) + + gsi::method ("shapes_of_terminal", &db::LayoutToNetlist::shapes_of_terminal, gsi::arg ("terminal"), gsi::arg ("trans", db::ICplxTrans (), "unity"), + "@brief Returns all shapes of the given device terminal that make a connection to the net the terminal lives in.\n" + "This will return all shapes from the device attached by the given terminal that interact with the net the terminal lives in.\n" + "This method returns a \\Region object with the shapes per layer where interactions are found.\n" + "The layers are given as layer indexes.\n" + "\n" + "The returned shapes are already transformed into the coordinate system of the net (see \\shapes_of_net for example).\n" + "An additional transformation can be applied using the optional \\trans argument.\n" + "\n" + "Note, that this method only considers interations between net shapes and the device connected by the terminal, " + "but not between subcircuits on the net and the device.\n" + "It can be used for example for flat-extracted, transistor-level netlists. In the general case however, nets may be formed\n" + "also by subcircuits touching devices. In that case, the nets do not have shapes of their own and this function cannot detect\n" + "the terminal shapes.\n" + "\n" + "The call of this method may not be cheap, specificially if large nets are involved.\n" "\n" "This method has been introduced in version 0.29.2." ) +