This commit is contained in:
Matthias Koefferlein 2024-06-02 23:04:03 +02:00
parent 4eeb5be9ea
commit 09a690f5f6
5 changed files with 90 additions and 6 deletions

View File

@ -524,8 +524,8 @@ class DB_PUBLIC hnp_interaction_receiver
public:
typedef typename local_cluster<T>::box_type box_type;
hnp_interaction_receiver (const Connectivity &conn, const db::ICplxTrans &trans)
: mp_conn (&conn), m_any (false), m_soft_mode (0), m_trans (trans)
hnp_interaction_receiver (const Connectivity &conn, const db::ICplxTrans &trans, std::map<unsigned int, std::set<const T *> > *interacting_this, std::map<unsigned int, std::set<const T *> > *interacting_other)
: mp_conn (&conn), m_any (false), m_soft_mode (0), m_trans (trans), mp_interacting_this (interacting_this), mp_interacting_other (interacting_other)
{
// .. nothing yet ..
}
@ -534,9 +534,17 @@ public:
{
int soft = 0;
if (mp_conn->interacts (*s1, l1, *s2, l2, m_trans, soft)) {
if (mp_interacting_this) {
(*mp_interacting_this) [l1].insert (s1);
}
if (mp_interacting_other) {
(*mp_interacting_this) [l2].insert (s2);
}
if (soft == 0 || (m_soft_mode != 0 && m_soft_mode != soft)) {
m_soft_mode = 0;
m_any = true;
if (! mp_interacting_other && ! mp_interacting_this) {
m_any = true;
}
} else {
m_soft_mode = soft;
}
@ -558,6 +566,7 @@ private:
bool m_any;
int m_soft_mode;
db::ICplxTrans m_trans;
std::map<unsigned int, std::set<const T *> > *mp_interacting_this, *mp_interacting_other;
};
template <class T, class Trans>
@ -619,9 +628,31 @@ local_cluster<T>::interacts (const db::Cell &cell, const db::ICplxTrans &trans,
return false;
}
template <class T>
static
void collect_interactions_in_original_order (const std::map<unsigned int, typename local_cluster<T>::tree_type> &shapes, const std::map<unsigned int, std::set<const T *> > &interacting, std::map<unsigned int, std::vector<const T *> > &interacting_out)
{
for (typename std::map<unsigned int, std::set<const T *> >::const_iterator i = interacting.begin (); i != interacting.end (); ++i) {
std::vector<const T *> &t = interacting_out [i->first];
auto s = shapes.find (i->first);
if (s == shapes.end ()) {
continue;
}
t.reserve (t.size () + i->second.size ());
for (auto j = s->second.begin (); j != s->second.end (); ++j) {
if (i->second.find (j.operator-> ()) != i->second.end ()) {
t.push_back (j.operator-> ());
}
}
}
}
template <class T>
bool
local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft) const
local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft, std::map<unsigned int, std::vector<const T *> > *interacting_this, std::map<unsigned int, std::vector<const T *> > *interacting_other) const
{
db::box_convert<T> bc;
@ -679,11 +710,25 @@ local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans
}
}
hnp_interaction_receiver<T> rec (conn, trans);
std::map<unsigned int, std::set<const T *> > is_this, is_other;
std::map<unsigned int, std::set<const T *> > *p_is_this = interacting_this ? &is_this : 0;
std::map<unsigned int, std::set<const T *> > *p_is_other = interacting_other ? &is_other : 0;
hnp_interaction_receiver<T> rec (conn, trans, p_is_this, p_is_other);
if (! scanner.process (rec, 1 /*==touching*/, bc, bc_t) || rec.soft_mode () != 0) {
if (p_is_this) {
collect_interactions_in_original_order (m_shapes, *p_is_this, *interacting_this);
}
if (p_is_other) {
collect_interactions_in_original_order (other.m_shapes, *p_is_other, *interacting_other);
}
soft = rec.soft_mode ();
return true;
} else {
return false;
}

View File

@ -326,8 +326,10 @@ public:
*
* "trans" is the transformation which is applied to the other cluster before
* the test.
* If non-null "interacting_this" will receive all interacting shapes from *this in case of success.
* If non-null "interacting_other" will receive all interacting shapes from other in case of success.
*/
bool interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft) const;
bool interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn, int &soft, std::map<unsigned int, std::vector<const T *> > *interacting_this = 0, std::map<unsigned int, std::vector<const T *> > *interacting_other = 0) const;
/**
* @brief Tests whether this cluster interacts with the given cell

View File

@ -1308,6 +1308,14 @@ static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const
return true;
}
std::map<unsigned int, db::Region>
LayoutToNetlist::shapes_of_pin (const db::NetSubcircuitPinRef &pin, const db::ICplxTrans &trans) const
{
// @@@
}
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
{
unsigned int lid = layer_of (of_layer);

View File

@ -828,6 +828,19 @@ public:
return m_net_clusters;
}
/**
* @brief Gets the shapes that make the subcircuit pin
*
* This method looks up all shapes from the subcircuit that interact with the shapes of the net
* the subcircuit pin 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, 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 Returns all shapes of a specific net and layer.
*

View File

@ -678,6 +678,22 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
gsi::method ("netlist", &db::LayoutToNetlist::netlist,
"@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"
"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"
"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"
"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"),
"@brief Returns all shapes of a specific net and layer.\n"
"If 'recursive'' is true, the returned region will contain the shapes of\n"