mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
4eeb5be9ea
commit
09a690f5f6
|
|
@ -524,8 +524,8 @@ class DB_PUBLIC hnp_interaction_receiver
|
||||||
public:
|
public:
|
||||||
typedef typename local_cluster<T>::box_type box_type;
|
typedef typename local_cluster<T>::box_type box_type;
|
||||||
|
|
||||||
hnp_interaction_receiver (const Connectivity &conn, const db::ICplxTrans &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_conn (&conn), m_any (false), m_soft_mode (0), m_trans (trans), mp_interacting_this (interacting_this), mp_interacting_other (interacting_other)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -534,9 +534,17 @@ public:
|
||||||
{
|
{
|
||||||
int soft = 0;
|
int soft = 0;
|
||||||
if (mp_conn->interacts (*s1, l1, *s2, l2, m_trans, soft)) {
|
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)) {
|
if (soft == 0 || (m_soft_mode != 0 && m_soft_mode != soft)) {
|
||||||
m_soft_mode = 0;
|
m_soft_mode = 0;
|
||||||
|
if (! mp_interacting_other && ! mp_interacting_this) {
|
||||||
m_any = true;
|
m_any = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m_soft_mode = soft;
|
m_soft_mode = soft;
|
||||||
}
|
}
|
||||||
|
|
@ -558,6 +566,7 @@ private:
|
||||||
bool m_any;
|
bool m_any;
|
||||||
int m_soft_mode;
|
int m_soft_mode;
|
||||||
db::ICplxTrans m_trans;
|
db::ICplxTrans m_trans;
|
||||||
|
std::map<unsigned int, std::set<const T *> > *mp_interacting_this, *mp_interacting_other;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class Trans>
|
template <class T, class Trans>
|
||||||
|
|
@ -619,9 +628,31 @@ local_cluster<T>::interacts (const db::Cell &cell, const db::ICplxTrans &trans,
|
||||||
return false;
|
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>
|
template <class T>
|
||||||
bool
|
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;
|
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 (! 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 ();
|
soft = rec.soft_mode ();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -326,8 +326,10 @@ public:
|
||||||
*
|
*
|
||||||
* "trans" is the transformation which is applied to the other cluster before
|
* "trans" is the transformation which is applied to the other cluster before
|
||||||
* the test.
|
* 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
|
* @brief Tests whether this cluster interacts with the given cell
|
||||||
|
|
|
||||||
|
|
@ -1308,6 +1308,14 @@ static bool deliver_shapes_of_net (bool recursive, const db::Netlist *nl, const
|
||||||
return true;
|
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
|
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);
|
unsigned int lid = layer_of (of_layer);
|
||||||
|
|
|
||||||
|
|
@ -828,6 +828,19 @@ public:
|
||||||
return m_net_clusters;
|
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.
|
* @brief Returns all shapes of a specific net and layer.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,22 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
|
||||||
gsi::method ("netlist", &db::LayoutToNetlist::netlist,
|
gsi::method ("netlist", &db::LayoutToNetlist::netlist,
|
||||||
"@brief gets the netlist extracted (0 if no extraction happened yet)\n"
|
"@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"),
|
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"
|
"@brief Returns all shapes of a specific net and layer.\n"
|
||||||
"If 'recursive'' is true, the returned region will contain the shapes of\n"
|
"If 'recursive'' is true, the returned region will contain the shapes of\n"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue