mirror of https://github.com/KLayout/klayout.git
WIP: hier netlist processort: performance improvement in instance-to-instance checking, leaner output of net shapes.
This commit is contained in:
parent
72f838f8ee
commit
e439d50111
|
|
@ -330,6 +330,8 @@ template <class T>
|
|||
bool
|
||||
local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn) const
|
||||
{
|
||||
db::box_convert<T> bc;
|
||||
|
||||
const_cast<local_cluster<T> *> (this)->ensure_sorted ();
|
||||
|
||||
box_type common = other.bbox ().transformed (trans) & bbox ();
|
||||
|
|
@ -339,35 +341,59 @@ local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans
|
|||
|
||||
box_type common_for_other = common.transformed (trans.inverted ());
|
||||
|
||||
db::box_scanner2<T, unsigned int, T, unsigned int> scanner;
|
||||
transformed_box <T, db::ICplxTrans> bc_t (trans);
|
||||
db::box_convert<T> bc;
|
||||
// shortcut evaluation for disjunct layers
|
||||
|
||||
bool any = false;
|
||||
std::set<unsigned int> ll1;
|
||||
for (typename std::map<unsigned int, tree_type>::const_iterator s = m_shapes.begin (); s != m_shapes.end (); ++s) {
|
||||
for (typename tree_type::touching_iterator i = s->second.begin_touching (common, bc); ! i.at_end (); ++i) {
|
||||
scanner.insert1 (i.operator-> (), s->first);
|
||||
any = true;
|
||||
if (! s->second.begin_touching (common, bc).at_end ()) {
|
||||
ll1.insert (s->first);
|
||||
}
|
||||
}
|
||||
|
||||
if (ll1.empty ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<unsigned int> ll2;
|
||||
for (typename std::map<unsigned int, tree_type>::const_iterator s = other.m_shapes.begin (); s != other.m_shapes.end (); ++s) {
|
||||
if (! s->second.begin_touching (common_for_other, bc).at_end ()) {
|
||||
ll2.insert (s->first);
|
||||
}
|
||||
}
|
||||
|
||||
if (ll2.empty ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool any = false;
|
||||
|
||||
for (std::set<unsigned int>::const_iterator i = ll1.begin (); i != ll1.end () && !any; ++i) {
|
||||
db::Connectivity::layer_iterator je = conn.end_connected (*i);
|
||||
for (db::Connectivity::layer_iterator j = conn.begin_connected (*i); j != je && !any; ++j) {
|
||||
any = (ll2.find (*j) != ll2.end ());
|
||||
}
|
||||
}
|
||||
if (! any) {
|
||||
return false;
|
||||
}
|
||||
|
||||
any = false;
|
||||
// detailed analysis
|
||||
|
||||
db::box_scanner2<T, unsigned int, T, unsigned int> scanner;
|
||||
transformed_box <T, db::ICplxTrans> bc_t (trans);
|
||||
|
||||
for (typename std::map<unsigned int, tree_type>::const_iterator s = m_shapes.begin (); s != m_shapes.end (); ++s) {
|
||||
for (typename tree_type::touching_iterator i = s->second.begin_touching (common, bc); ! i.at_end (); ++i) {
|
||||
scanner.insert1 (i.operator-> (), s->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (typename std::map<unsigned int, tree_type>::const_iterator s = other.m_shapes.begin (); s != other.m_shapes.end (); ++s) {
|
||||
for (typename tree_type::touching_iterator i = s->second.begin_touching (common_for_other, bc); ! i.at_end (); ++i) {
|
||||
scanner.insert2 (i.operator-> (), s->first);
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! any) {
|
||||
return false;
|
||||
}
|
||||
|
||||
interaction_receiver<T> rec (conn, trans);
|
||||
return ! scanner.process (rec, 1 /*==touching*/, bc, bc_t);
|
||||
}
|
||||
|
|
@ -1037,6 +1063,8 @@ private:
|
|||
db::cell_index_type ci1, const std::vector<db::InstElement> &p1, const db::ICplxTrans &t1,
|
||||
db::cell_index_type ci2, const std::vector<db::InstElement> &p2, const db::ICplxTrans &t2)
|
||||
{
|
||||
const db::Cell &cell2 = mp_layout->cell (ci2);
|
||||
|
||||
const db::local_clusters<T> &cl1 = mp_tree->clusters_per_cell (ci1);
|
||||
const db::local_clusters<T> &cl2 = mp_tree->clusters_per_cell (ci2);
|
||||
|
||||
|
|
@ -1046,6 +1074,11 @@ private:
|
|||
|
||||
for (typename db::local_clusters<T>::touching_iterator i = cl1.begin_touching (common.transformed (t1i)); ! i.at_end (); ++i) {
|
||||
|
||||
// skip the test, if this cluster doesn't interact with the whole cell2
|
||||
if (! i->interacts (cell2, t21, *mp_conn)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
box_type bc1 = common & i->bbox ().transformed (t1);
|
||||
for (typename db::local_clusters<T>::touching_iterator j = cl2.begin_touching (bc1.transformed (t2i)); ! j.at_end (); ++j) {
|
||||
|
||||
|
|
|
|||
|
|
@ -209,6 +209,16 @@ const db::hier_clusters<db::PolygonRef> &LayoutToNetlist::net_clusters () const
|
|||
return m_netex.clusters ();
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static void deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
} else {
|
||||
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
}
|
||||
|
||||
db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const
|
||||
{
|
||||
unsigned int lid = layer_of (of_layer);
|
||||
|
|
@ -224,7 +234,7 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
|||
const db::local_cluster<db::PolygonRef> &lc = m_netex.clusters ().clusters_per_cell (ci).cluster_by_id (net.cluster_id ());
|
||||
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (lid); !s.at_end (); ++s) {
|
||||
res->insert (s->obj ().transformed (s->trans ()));
|
||||
deliver_shape (*s, *res, db::UnitTrans ());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -235,7 +245,7 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
|||
db::cell_index_type ci = circuit->cell_index ();
|
||||
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (m_netex.clusters (), lid, ci, net.cluster_id ()); !rci.at_end (); ++rci) {
|
||||
res->insert (rci->obj ().transformed (rci.trans () * db::ICplxTrans (rci->trans ())));
|
||||
deliver_shape (*rci, *res, rci.trans ());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue