mirror of https://github.com/KLayout/klayout.git
WIP: finalized refactoring.
This commit is contained in:
parent
07daed2878
commit
87e658acf0
|
|
@ -1189,7 +1189,7 @@ public:
|
|||
*/
|
||||
void finish (const db::Instance *i, unsigned int /*p1*/)
|
||||
{
|
||||
add_single_inst (*i);
|
||||
consider_single_inst (*i);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1295,161 +1295,6 @@ private:
|
|||
std::map<InteractionKeyForClustersType, std::vector<std::pair<size_t, size_t> > > m_interaction_cache_for_clusters;
|
||||
instance_interaction_cache_type *mp_instance_interaction_cache;
|
||||
|
||||
#if 0 // @@@
|
||||
/**
|
||||
* @brief Handles the cluster interactions between two instances or instance arrays
|
||||
* @param common The region under investigation (seen from the top level)
|
||||
* @param i1 The index of the child cell 1
|
||||
* @param p1 The instantiation path to the child cell (not including i1)
|
||||
* @param t1 The accumulated transformation of the path, not including i1
|
||||
* @param i2 The index of the child cell 2
|
||||
* @param p2 The instantiation path to the child cell (not including i2)
|
||||
* @param t2 The accumulated transformation of the path, not including i2
|
||||
*/
|
||||
void add_pair (const box_type &common, const db::Instance &i1, const std::vector<ClusterInstElement> &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector<ClusterInstElement> &p2, const db::ICplxTrans &t2, std::list<std::pair<ClusterInstance, ClusterInstance> > &interacting_clusters_out)
|
||||
{
|
||||
if (is_breakout_cell (mp_breakout_cells, i1.cell_index ()) || is_breakout_cell (mp_breakout_cells, i2.cell_index ())) {
|
||||
return;
|
||||
}
|
||||
|
||||
box_type bb1 = (*mp_cbc) (i1.cell_index ());
|
||||
box_type b1 = i1.cell_inst ().bbox (*mp_cbc).transformed (t1);
|
||||
|
||||
box_type bb2 = (*mp_cbc) (i2.cell_index ());
|
||||
box_type b2 = i2.cell_inst ().bbox (*mp_cbc).transformed (t2);
|
||||
|
||||
box_type common_all = common & b1 & b2;
|
||||
|
||||
if (common_all.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
db::ICplxTrans tt2 = t2 * i2.complex_trans ();
|
||||
db::ICplxTrans tt1 = t1 * i1.complex_trans ();
|
||||
|
||||
db::ICplxTrans tt21 = tt1.inverted () * tt2;
|
||||
InstanceToInstanceInteraction ii_key (i1.cell_index (), i1.cell_inst ().delegate (), i2.cell_index (), i2.cell_inst ().delegate (), tt21);
|
||||
|
||||
#if 0 // @@@
|
||||
instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key);
|
||||
if (ii != mp_instance_interaction_cache->end ()) {
|
||||
// take from cache if possible
|
||||
--> problem: cluster pairs need to be relative to the initial cell, hence we can't cache the target cluster. only the source one!!!
|
||||
for (cluster_instance_pair_list_type::const_iterator ic = ii->second.second.begin (); ic != ii->second.second.end (); ++ic) {
|
||||
interacting_clusters_out.push_back (std::pair<ClusterInstance, ClusterInstance> ());
|
||||
interacting_clusters_out.back ().first = make_path (ic->first.id (), p1);
|
||||
interacting_clusters_out.back ().second = make_path (ic->second.id (), p2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
std::list<std::pair<ClusterInstance, ClusterInstance> > &interacting_clusters = mp_instance_interaction_cache->insert (std::make_pair (ii_key, std::make_pair (tt1, cluster_instance_pair_list_type ()))).first->second.second;
|
||||
|
||||
#endif
|
||||
|
||||
std::list<std::pair<ClusterInstance, ClusterInstance> > interacting_clusters; // @@@
|
||||
|
||||
if (false /*@@@*/&& i1.size () == 1 && i2.size () == 1) {
|
||||
|
||||
// single-to-single instance interactions
|
||||
|
||||
// TODO: can't we just add the new item to the path and remove it later?
|
||||
std::vector<ClusterInstElement> pp1;
|
||||
pp1.reserve (p1.size () + 1);
|
||||
pp1.insert (pp1.end (), p1.begin (), p1.end ());
|
||||
pp1.push_back (ClusterInstElement (i1.cell_index (), i1.complex_trans (), i1.prop_id ()));
|
||||
|
||||
// skip interactions between identical instances (duplicate instance removal)
|
||||
if (i1.cell_index () != i2.cell_index () || tt1 != tt2) {
|
||||
|
||||
std::vector<ClusterInstElement> pp2;
|
||||
pp2.reserve (p2.size () + 1);
|
||||
pp2.insert (pp2.end (), p2.begin (), p2.end ());
|
||||
pp2.push_back (ClusterInstElement (i2.cell_index (), i2.complex_trans (), i2.prop_id ()));
|
||||
|
||||
add_single_pair (common_all, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2, interacting_clusters);
|
||||
|
||||
// dive into cell of i2
|
||||
const db::Cell &cell2 = mp_layout->cell (i2.cell_index ());
|
||||
for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common_all.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
||||
add_pair (common_all, i1, p1, t1, *jj2, pp2, tt2, interacting_clusters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// dive into cell of i1
|
||||
const db::Cell &cell1 = mp_layout->cell (i1.cell_index ());
|
||||
for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common_all.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) {
|
||||
add_pair (common_all, *jj1, pp1, tt1, i2, p2, t2, interacting_clusters);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// array interactions
|
||||
|
||||
db::ICplxTrans t1i = t1.inverted ();
|
||||
db::ICplxTrans t2i = t2.inverted ();
|
||||
|
||||
for (db::CellInstArray::iterator ii1 = i1.begin_touching (common_all.transformed (t1i), mp_layout); ! ii1.at_end (); ++ii1) {
|
||||
|
||||
db::ICplxTrans tt1 = t1 * i1.complex_trans (*ii1);
|
||||
box_type ib1 = bb1.transformed (tt1);
|
||||
|
||||
std::vector<ClusterInstElement> pp1;
|
||||
pp1.reserve (p1.size () + 1);
|
||||
pp1.insert (pp1.end (), p1.begin (), p1.end ());
|
||||
pp1.push_back (ClusterInstElement (i1.cell_index (), i1.complex_trans (*ii1), i1.prop_id ()));
|
||||
|
||||
for (db::CellInstArray::iterator ii2 = i2.begin_touching (ib1.transformed (t2i), mp_layout); ! ii2.at_end (); ++ii2) {
|
||||
|
||||
db::ICplxTrans tt2 = t2 * i2.complex_trans (*ii2);
|
||||
if (i1.cell_index () == i2.cell_index () && tt1 == tt2) {
|
||||
// skip interactions between identical instances (duplicate instance removal)
|
||||
continue;
|
||||
}
|
||||
|
||||
box_type ib2 = bb2.transformed (tt2);
|
||||
|
||||
box_type common12 = ib1 & ib2 & common;
|
||||
|
||||
if (! common12.empty ()) {
|
||||
|
||||
std::vector<ClusterInstElement> pp2;
|
||||
pp2.reserve (p2.size () + 1);
|
||||
pp2.insert (pp2.end (), p2.begin (), p2.end ());
|
||||
pp2.push_back (ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ()));
|
||||
|
||||
add_single_pair (common12, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2, interacting_clusters);
|
||||
|
||||
// dive into cell of ii2
|
||||
const db::Cell &cell2 = mp_layout->cell (i2.cell_index ());
|
||||
for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common12.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
||||
add_pair (common12, i1, p1, t1, *jj2, pp2, tt2, interacting_clusters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
box_type common1 = ib1 & b2 & common;
|
||||
|
||||
if (! common1.empty ()) {
|
||||
|
||||
// dive into cell of ii1
|
||||
const db::Cell &cell1 = mp_layout->cell (i1.cell_index ());
|
||||
for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common1.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) {
|
||||
add_pair (common1, *jj1, pp1, tt1, i2, p2, t2, interacting_clusters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interacting_clusters_out.insert (interacting_clusters_out.end (), interacting_clusters.begin (), interacting_clusters.end ());
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Investigate a pair of instances
|
||||
*
|
||||
|
|
@ -1500,7 +1345,7 @@ private:
|
|||
if (ii != mp_instance_interaction_cache->end ()) {
|
||||
|
||||
// use cached interactions
|
||||
interacting_clusters = ii->second.second;
|
||||
interacting_clusters = ii->second;
|
||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = interacting_clusters.begin (); i != interacting_clusters.end (); ++i) {
|
||||
// translate the property IDs
|
||||
i->first.set_inst_prop_id (i1.prop_id ());
|
||||
|
|
@ -1518,7 +1363,7 @@ private:
|
|||
db::ICplxTrans t1i = t1.inverted ();
|
||||
db::ICplxTrans t2i = t2.inverted ();
|
||||
|
||||
// @@@ optimize for single inst?
|
||||
// TODO: optimize for single inst?
|
||||
for (db::CellInstArray::iterator ii1 = i1element.at_end () ? i1.begin_touching (common_all.transformed (t1i), mp_layout) : i1element; ! ii1.at_end (); ++ii1) {
|
||||
|
||||
db::ICplxTrans i1t = i1.complex_trans (*ii1);
|
||||
|
|
@ -1594,99 +1439,20 @@ private:
|
|||
|
||||
}
|
||||
|
||||
std::pair<db::ICplxTrans, cluster_instance_pair_list_type> &cached = (*mp_instance_interaction_cache) [ii_key];
|
||||
cached.first = i1.complex_trans (); // @@@ remove or twofold transformation
|
||||
cached.second = interacting_clusters;
|
||||
cluster_instance_pair_list_type &cached = (*mp_instance_interaction_cache) [ii_key];
|
||||
cached = interacting_clusters;
|
||||
|
||||
// normalize transformations in cache
|
||||
db::ICplxTrans i1ti = i1t.inverted (), i2ti = i2t.inverted ();
|
||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = cached.second.begin (); i != cached.second.end (); ++i) {
|
||||
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = cached.begin (); i != cached.end (); ++i) {
|
||||
i->first.transform (i1ti);
|
||||
i->second.transform (i2ti);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the cluster interactions between two specific instances
|
||||
* @param common The region under investigation (seen from the top level)
|
||||
* @param ci1 The cell index of the child cell 1
|
||||
* @param p1 The instantiation path to the child cell (last element is the instance to ci1)
|
||||
* @param t1 The accumulated transformation of the path p1
|
||||
* @param ci2 The cell index of the child cell 2
|
||||
* @param p2 The instantiation path to the child cell (last element is the instance to ci2)
|
||||
* @param t2 The accumulated transformation of the path p2
|
||||
* @brief Computes a list of interacting clusters for two instances
|
||||
*/
|
||||
// @@@ remove
|
||||
void add_single_pair (const box_type &common,
|
||||
db::cell_index_type ci1, const std::vector<ClusterInstElement> &p1, const db::ICplxTrans &t1,
|
||||
db::cell_index_type ci2, const std::vector<ClusterInstElement> &p2, const db::ICplxTrans &t2,
|
||||
cluster_instance_pair_list_type &interacting_clusters)
|
||||
{
|
||||
if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
db::ICplxTrans t1i = t1.inverted ();
|
||||
db::ICplxTrans t2i = t2.inverted ();
|
||||
db::ICplxTrans t21 = t1i * t2;
|
||||
|
||||
box_type common2 = common.transformed (t2i);
|
||||
|
||||
// NOTE: make_path may disturb the iteration (because of modification), hence
|
||||
// we first collect and then process the interactions.
|
||||
const std::vector<std::pair<size_t, size_t> > *interactions;
|
||||
|
||||
InteractionKeyForClustersType ikey (ci1, ci2, t21, common2);
|
||||
|
||||
typename std::map<InteractionKeyForClustersType, std::vector<std::pair<size_t, size_t> > >::const_iterator ici = m_interaction_cache_for_clusters.find (ikey);
|
||||
if (ici != m_interaction_cache_for_clusters.end ()) {
|
||||
|
||||
interactions = &ici->second;
|
||||
|
||||
} else {
|
||||
|
||||
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);
|
||||
|
||||
std::vector<std::pair<size_t, size_t> > new_interactions;
|
||||
db::ICplxTrans t12 = t2i * t1;
|
||||
|
||||
for (typename db::local_clusters<T>::touching_iterator i = cl1.begin_touching (common2.transformed (t21)); ! 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 bc2 = (common2 & i->bbox ().transformed (t12));
|
||||
for (typename db::local_clusters<T>::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) {
|
||||
|
||||
if (i->interacts (*j, t21, *mp_conn)) {
|
||||
new_interactions.push_back (std::make_pair (i->id (), j->id ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::pair<size_t, size_t> > &out = m_interaction_cache_for_clusters [ikey];
|
||||
out = new_interactions;
|
||||
interactions = &out;
|
||||
|
||||
}
|
||||
|
||||
for (std::vector<std::pair<size_t, size_t> >::const_iterator ii = interactions->begin (); ii != interactions->end (); ++ii) {
|
||||
|
||||
ClusterInstance k1 = make_path (ii->first, p1);
|
||||
ClusterInstance k2 = make_path (ii->second, p2);
|
||||
|
||||
interacting_clusters.push_back (std::make_pair (k1, k2));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::pair<size_t, size_t> > &
|
||||
compute_instance_interactions (const box_type &common,
|
||||
db::cell_index_type ci1, const db::ICplxTrans &t1,
|
||||
|
|
@ -1746,7 +1512,7 @@ private:
|
|||
/**
|
||||
* @brief Single instance treatment
|
||||
*/
|
||||
void add_single_inst (const db::Instance &i)
|
||||
void consider_single_inst (const db::Instance &i)
|
||||
{
|
||||
if (is_breakout_cell (mp_breakout_cells, i.cell_index ())) {
|
||||
return;
|
||||
|
|
@ -1981,18 +1747,11 @@ private:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Makes a valid path to a child cluster
|
||||
* @brief Makes cluster connections from all parents of a cell into this cell and to the given cluster
|
||||
*
|
||||
* Cluster connections can only cross one level of hierarchy. This method
|
||||
* creates necessary dummy entries for the given path.
|
||||
* After calling this method, the cluster instance in ci is guaranteed to have connections from all
|
||||
* parent cells. One of these connections represents the instance ci.
|
||||
*/
|
||||
// @@@ remove
|
||||
ClusterInstance make_path (id_type id, const std::vector<ClusterInstElement> &path) const
|
||||
{
|
||||
return mp_tree->make_path (*mp_layout, *mp_cell, id, path);
|
||||
}
|
||||
|
||||
// @@@
|
||||
void propagate_cluster_inst (ClusterInstance &ci, db::cell_index_type pci, const db::ICplxTrans &trans, db::properties_id_type prop_id) const
|
||||
{
|
||||
size_t id_new = mp_tree->propagate_cluster_inst (*mp_layout, *mp_cell, ci, pci, true);
|
||||
|
|
@ -2142,134 +1901,6 @@ hier_clusters<T>::propagate_cluster_inst (const db::Layout &layout, const db::Ce
|
|||
return id_new;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
ClusterInstance
|
||||
hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<ClusterInstElement> &path)
|
||||
{
|
||||
std::vector<ClusterInstElement>::const_iterator p = path.end ();
|
||||
tl_assert (p != path.begin ());
|
||||
|
||||
while (true) {
|
||||
|
||||
--p;
|
||||
|
||||
ClusterInstance ci (id, p->inst_cell_index (), p->inst_trans (), p->inst_prop_id ());
|
||||
if (p == path.begin ()) {
|
||||
|
||||
// if we're attaching to a child which is root yet, we need to promote the
|
||||
// cluster to the parent in all places
|
||||
connected_clusters<T> &child_cc = clusters_per_cell (p->inst_cell_index ());
|
||||
if (child_cc.is_root (id)) {
|
||||
|
||||
std::set<std::pair<db::cell_index_type, ClusterInstance> > seen; // to avoid duplicate connections
|
||||
|
||||
const db::Cell &child_cell = layout.cell (p->inst_cell_index ());
|
||||
for (db::Cell::parent_inst_iterator pi = child_cell.begin_parent_insts (); ! pi.at_end (); ++pi) {
|
||||
|
||||
db::Instance child_inst = pi->child_inst ();
|
||||
|
||||
connected_clusters<T> &parent_cc = clusters_per_cell (pi->parent_cell_index ());
|
||||
for (db::CellInstArray::iterator pii = child_inst.begin (); ! pii.at_end (); ++pii) {
|
||||
|
||||
ClusterInstance ci2 (id, child_inst.cell_index (), child_inst.complex_trans (*pii), child_inst.prop_id ());
|
||||
if ((cell.cell_index () != pi->parent_cell_index () || ci != ci2) && seen.find (std::make_pair (pi->parent_cell_index (), ci2)) == seen.end ()) {
|
||||
|
||||
size_t id_dummy;
|
||||
|
||||
const typename db::local_cluster<T>::global_nets &gn = child_cc.cluster_by_id (id).get_global_nets ();
|
||||
if (gn.empty ()) {
|
||||
id_dummy = parent_cc.insert_dummy ();
|
||||
} else {
|
||||
local_cluster<T> *lc = parent_cc.insert ();
|
||||
lc->set_global_nets (gn);
|
||||
id_dummy = lc->id ();
|
||||
}
|
||||
|
||||
parent_cc.add_connection (id_dummy, ci2);
|
||||
seen.insert (std::make_pair (pi->parent_cell_index (), ci2));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
child_cc.reset_root (id);
|
||||
|
||||
}
|
||||
|
||||
return ci;
|
||||
|
||||
}
|
||||
|
||||
db::cell_index_type pci = p [-1].inst_cell_index ();
|
||||
connected_clusters<T> &target_cc = clusters_per_cell (pci);
|
||||
size_t parent_cluster = target_cc.find_cluster_with_connection (ci);
|
||||
|
||||
if (parent_cluster > 0) {
|
||||
|
||||
// taken parent
|
||||
id = parent_cluster;
|
||||
|
||||
} else {
|
||||
|
||||
size_t id_new = 0;
|
||||
|
||||
// if we're attaching to a child which is root yet, we need to promote the
|
||||
// cluster to the parent in all places
|
||||
connected_clusters<T> &child_cc = clusters_per_cell (p->inst_cell_index ());
|
||||
if (child_cc.is_root (id)) {
|
||||
|
||||
std::set<std::pair<db::cell_index_type, ClusterInstance> > seen; // to avoid duplicate connections
|
||||
|
||||
const db::Cell &child_cell = layout.cell (p->inst_cell_index ());
|
||||
for (db::Cell::parent_inst_iterator pi = child_cell.begin_parent_insts (); ! pi.at_end (); ++pi) {
|
||||
|
||||
db::Instance child_inst = pi->child_inst ();
|
||||
|
||||
connected_clusters<T> &parent_cc = clusters_per_cell (pi->parent_cell_index ());
|
||||
for (db::CellInstArray::iterator pii = child_inst.begin (); ! pii.at_end (); ++pii) {
|
||||
|
||||
ClusterInstance ci2 (id, child_inst.cell_index (), child_inst.complex_trans (*pii), child_inst.prop_id ());
|
||||
if (seen.find (std::make_pair (pi->parent_cell_index (), ci2)) == seen.end ()) {
|
||||
|
||||
size_t id_dummy;
|
||||
|
||||
const typename db::local_cluster<T>::global_nets &gn = child_cc.cluster_by_id (id).get_global_nets ();
|
||||
if (gn.empty ()) {
|
||||
id_dummy = parent_cc.insert_dummy ();
|
||||
} else {
|
||||
local_cluster<T> *lc = parent_cc.insert ();
|
||||
lc->set_global_nets (gn);
|
||||
id_dummy = lc->id ();
|
||||
}
|
||||
|
||||
parent_cc.add_connection (id_dummy, ci2);
|
||||
seen.insert (std::make_pair (pi->parent_cell_index (), ci2));
|
||||
|
||||
if (pci == pi->parent_cell_index () && ci == ci2) {
|
||||
id_new = id_dummy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
child_cc.reset_root (id);
|
||||
|
||||
}
|
||||
|
||||
// no parent -> create vertical connector
|
||||
id = id_new;
|
||||
tl_assert (id != 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void
|
||||
hier_clusters<T>::do_build (cell_clusters_box_converter<T> &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence, const std::set<db::cell_index_type> *breakout_cells)
|
||||
|
|
@ -2562,27 +2193,26 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
// NOTE: don't use the gc pointer - it may become invalid during make_path (will also do a local.insert)
|
||||
size_t gcid = gc->id ();
|
||||
|
||||
for (std::set<ClusterInstance>::const_iterator ci = ge->second.begin (); ci != ge->second.end (); ++ci) {
|
||||
for (std::set<ClusterInstance>::const_iterator i = ge->second.begin (); i != ge->second.end (); ++i) {
|
||||
|
||||
if (! ci->has_instance ()) {
|
||||
if (! i->has_instance ()) {
|
||||
|
||||
local.join_cluster_with (gcid, ci->id ());
|
||||
local.remove_cluster (ci->id ());
|
||||
local.join_cluster_with (gcid, i->id ());
|
||||
local.remove_cluster (i->id ());
|
||||
|
||||
} else {
|
||||
|
||||
std::vector<ClusterInstElement> p;
|
||||
p.push_back (*ci);
|
||||
ClusterInstance k = make_path (layout, cell, ci->id (), p);
|
||||
// ensures the cluster is propagated so we can connect it with another
|
||||
propagate_cluster_inst (layout, cell, *i, cell.cell_index (), false);
|
||||
|
||||
size_t other_id = local.find_cluster_with_connection (k);
|
||||
size_t other_id = local.find_cluster_with_connection (*i);
|
||||
if (other_id == gcid) {
|
||||
// shouldn't happen, but duplicate instances may trigger this
|
||||
} else if (other_id) {
|
||||
local.join_cluster_with (gcid, other_id);
|
||||
local.remove_cluster (other_id);
|
||||
} else {
|
||||
local.add_connection (gcid, k);
|
||||
local.add_connection (gcid, *i);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -769,7 +769,6 @@ struct InstanceToInstanceInteraction
|
|||
|
||||
bool operator== (const InstanceToInstanceInteraction &other) const
|
||||
{
|
||||
static const db::array_base_ptr_cmp_f arr_less;
|
||||
return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21) &&
|
||||
equal_array_delegates (array1, other.array1) &&
|
||||
equal_array_delegates (array2, other.array2);
|
||||
|
|
@ -799,7 +798,7 @@ struct InstanceToInstanceInteraction
|
|||
db::ICplxTrans t21;
|
||||
};
|
||||
|
||||
typedef std::map<InstanceToInstanceInteraction, std::pair<db::ICplxTrans, cluster_instance_pair_list_type> > instance_interaction_cache_type;
|
||||
typedef std::map<InstanceToInstanceInteraction, cluster_instance_pair_list_type> instance_interaction_cache_type;
|
||||
|
||||
template <class T> class hier_clusters;
|
||||
template <class T> class connected_clusters;
|
||||
|
|
@ -974,7 +973,7 @@ class DB_PUBLIC_TEMPLATE hier_clusters
|
|||
{
|
||||
public:
|
||||
typedef typename local_cluster<T>::box_type box_type;
|
||||
typedef std::map<InstanceToInstanceInteraction, std::pair<db::ICplxTrans, cluster_instance_pair_list_type> > instance_interaction_cache_type;
|
||||
typedef std::map<InstanceToInstanceInteraction, cluster_instance_pair_list_type> instance_interaction_cache_type;
|
||||
|
||||
/**
|
||||
* @brief Creates an empty set of clusters
|
||||
|
|
@ -1022,15 +1021,12 @@ public:
|
|||
void clear ();
|
||||
|
||||
/**
|
||||
* @brief Makes a valid path to a child cluster
|
||||
* @brief Ensures a cluster instance is connected from all parents of the instantiated cell
|
||||
*
|
||||
* Cluster connections can only cross one level of hierarchy. This method
|
||||
* creates necessary dummy entries for the given path.
|
||||
* If "with_self" is true, the specified instance "ci" is included in the connections. Otherwise
|
||||
* there is not connection made for this instance.
|
||||
*/
|
||||
ClusterInstance make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<ClusterInstElement> &path);
|
||||
|
||||
// @@@
|
||||
size_t propagate_cluster_inst (const db::Layout &layout, const Cell &cell, const ClusterInstance &ci, db::cell_index_type pci, bool with_self);
|
||||
size_t propagate_cluster_inst (const db::Layout &layout, const Cell &cell, const ClusterInstance &ci, db::cell_index_type parent_ci, bool with_self);
|
||||
|
||||
private:
|
||||
void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters<unsigned int> *attr_equivalence);
|
||||
|
|
|
|||
|
|
@ -159,8 +159,9 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
|
|||
// Make sure we create one subcircuit for each instance of cells which do have circuits
|
||||
// associated.
|
||||
for (db::Cell::const_iterator inst = cell.begin (); ! inst.at_end (); ++inst) {
|
||||
// @@@ ARRAY EXPANSION!!!
|
||||
make_subcircuit (circuit, inst->cell_index (), inst->complex_trans (), subcircuits, circuits);
|
||||
for (db::CellInstArray::iterator ii = inst->begin (); ! ii.at_end (); ++ii) {
|
||||
make_subcircuit (circuit, inst->cell_index (), inst->complex_trans (*ii), subcircuits, circuits);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue