Deep search for pin shapes, added shapes_of_terminal

This commit is contained in:
Matthias Koefferlein 2024-06-06 19:54:56 +02:00
parent 7388aa13a6
commit c44b8097dd
3 changed files with 107 additions and 19 deletions

View File

@ -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<db::NetShape> &c, const db::Net *other_net, const db::ICplxTrans &sc_trans, const db::ICplxTrans &trans, std::map<unsigned int, db::Region> &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<unsigned int, std::vector<const db::NetShape *> > 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<unsigned int, db::Region>
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<unsigned int, db::Region>
LayoutToNetlist::shapes_of_terminal (const db::NetTerminalRef &terminal, const db::ICplxTrans &trans) const
{
std::map<unsigned int, db::Region> 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<unsigned int, std::vector<const db::NetShape *> > 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;

View File

@ -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<unsigned int, db::Region> 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<unsigned int, db::Region> 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<const db::Net *> *nets, bool with_device_cells);
void collect_shapes_of_pin (const local_cluster<db::NetShape> &c, const db::Net *other_net, const db::ICplxTrans &sc_trans, const db::ICplxTrans &trans, std::map<unsigned int, db::Region> &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);

View File

@ -679,20 +679,40 @@ Class<db::LayoutToNetlist> 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."
) +