mirror of https://github.com/KLayout/klayout.git
Fixed crash by introducing a new scheme for storing cluster refs
The previous implementation was based on the Instance pointers, but these got invalidated during device cell construction. Now an explicit copy of the instance is kept.
This commit is contained in:
parent
d4ed21f42a
commit
9b31bd3214
|
|
@ -314,8 +314,8 @@ public:
|
|||
|
||||
const db::connected_clusters<db::Edge>::connections_type &conn = cc.connections_for_cluster (cid);
|
||||
for (db::connected_clusters<db::Edge>::connections_type::const_iterator i = conn.begin (); i != conn.end (); ++i) {
|
||||
const db::Shapes &cc_shapes = merged (i->id (), i->inst ().inst_ptr.cell_index (), false);
|
||||
merged_child_clusters.push_back (std::make_pair (&cc_shapes, i->inst ().complex_trans ()));
|
||||
const db::Shapes &cc_shapes = merged (i->id (), i->inst_cell_index (), false);
|
||||
merged_child_clusters.push_back (std::make_pair (&cc_shapes, i->inst_trans ()));
|
||||
}
|
||||
|
||||
// collect the edges to merge ..
|
||||
|
|
|
|||
|
|
@ -351,8 +351,8 @@ private:
|
|||
|
||||
const db::connected_clusters<db::PolygonRef>::connections_type &conn = cc.connections_for_cluster (cid);
|
||||
for (db::connected_clusters<db::PolygonRef>::connections_type::const_iterator i = conn.begin (); i != conn.end (); ++i) {
|
||||
const db::Shapes &cc_shapes = compute_merged (i->id (), i->inst ().inst_ptr.cell_index (), false, min_wc);
|
||||
merged_child_clusters.push_back (std::make_pair (&cc_shapes, i->inst ().complex_trans ()));
|
||||
const db::Shapes &cc_shapes = compute_merged (i->id (), i->inst_cell_index (), false, min_wc);
|
||||
merged_child_clusters.push_back (std::make_pair (&cc_shapes, i->inst_trans ()));
|
||||
}
|
||||
|
||||
m_ep.clear ();
|
||||
|
|
|
|||
|
|
@ -1116,13 +1116,13 @@ public:
|
|||
|
||||
struct ClusterInstanceInteraction
|
||||
{
|
||||
ClusterInstanceInteraction (size_t _cluster_id, size_t _other_cluster_id, const std::vector<db::InstElement> &_other_path)
|
||||
ClusterInstanceInteraction (size_t _cluster_id, size_t _other_cluster_id, const std::vector<ClusterInstElement> &_other_path)
|
||||
: cluster_id (_cluster_id), other_cluster_id (_other_cluster_id), other_path (_other_path)
|
||||
{ }
|
||||
|
||||
size_t cluster_id;
|
||||
size_t other_cluster_id;
|
||||
std::vector<db::InstElement> other_path;
|
||||
std::vector<ClusterInstElement> other_path;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1139,7 +1139,7 @@ public:
|
|||
*/
|
||||
void add (const db::Instance *i1, unsigned int /*p1*/, const db::Instance *i2, unsigned int /*p2*/)
|
||||
{
|
||||
std::vector<db::InstElement> p;
|
||||
std::vector<ClusterInstElement> p;
|
||||
db::ICplxTrans t;
|
||||
add_pair (box_type::world (), *i1, p, t, *i2, p, t);
|
||||
}
|
||||
|
|
@ -1159,7 +1159,7 @@ public:
|
|||
*/
|
||||
void add (const local_cluster<T> *c1, unsigned int /*p1*/, const db::Instance *i2, unsigned int /*p2*/)
|
||||
{
|
||||
std::vector<db::InstElement> p;
|
||||
std::vector<ClusterInstElement> p;
|
||||
db::ICplxTrans t;
|
||||
add_pair (*c1, *i2, p, t);
|
||||
}
|
||||
|
|
@ -1233,7 +1233,7 @@ private:
|
|||
* @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<db::InstElement> &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector<db::InstElement> &p2, const db::ICplxTrans &t2)
|
||||
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)
|
||||
{
|
||||
box_type bb1 = (*mp_cbc) (i1.cell_index ());
|
||||
box_type b1 = i1.cell_inst ().bbox (*mp_cbc).transformed (t1);
|
||||
|
|
@ -1255,10 +1255,10 @@ private:
|
|||
db::ICplxTrans tt1 = t1 * i1.complex_trans (*ii1);
|
||||
box_type ib1 = bb1.transformed (tt1);
|
||||
|
||||
std::vector<db::InstElement> pp1;
|
||||
std::vector<ClusterInstElement> pp1;
|
||||
pp1.reserve (p1.size () + 1);
|
||||
pp1.insert (pp1.end (), p1.begin (), p1.end ());
|
||||
pp1.push_back (db::InstElement (i1, ii1));
|
||||
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) {
|
||||
|
||||
|
|
@ -1269,10 +1269,10 @@ private:
|
|||
|
||||
if (! common12.empty ()) {
|
||||
|
||||
std::vector<db::InstElement> pp2;
|
||||
std::vector<ClusterInstElement> pp2;
|
||||
pp2.reserve (p2.size () + 1);
|
||||
pp2.insert (pp2.end (), p2.begin (), p2.end ());
|
||||
pp2.push_back (db::InstElement (i2, ii2));
|
||||
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);
|
||||
|
||||
|
|
@ -1312,8 +1312,8 @@ private:
|
|||
* @param t2 The accumulated transformation of the path p2
|
||||
*/
|
||||
void add_single_pair (const box_type &common,
|
||||
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)
|
||||
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)
|
||||
{
|
||||
const db::Cell &cell2 = mp_layout->cell (ci2);
|
||||
|
||||
|
|
@ -1399,8 +1399,8 @@ private:
|
|||
db::ICplxTrans tt = i.complex_trans (*ii);
|
||||
box_type ib = bb.transformed (tt);
|
||||
|
||||
std::vector<db::InstElement> pp;
|
||||
pp.push_back (db::InstElement (i, ii));
|
||||
std::vector<ClusterInstElement> pp;
|
||||
pp.push_back (ClusterInstElement (i.cell_index (), i.complex_trans (*ii), i.prop_id ()));
|
||||
|
||||
bool any = false;
|
||||
bool first = true;
|
||||
|
|
@ -1417,8 +1417,8 @@ private:
|
|||
|
||||
if (ib.touches (ib2)) {
|
||||
|
||||
std::vector<db::InstElement> pp2;
|
||||
pp2.push_back (db::InstElement (i, ii2));
|
||||
std::vector<ClusterInstElement> pp2;
|
||||
pp2.push_back (ClusterInstElement (i.cell_index (), i.complex_trans (*ii2), i.prop_id ()));
|
||||
|
||||
box_type common = (ib & ib2);
|
||||
add_single_pair (common, i.cell_index (), pp, tt, i.cell_index (), pp2, tt2);
|
||||
|
|
@ -1427,7 +1427,7 @@ private:
|
|||
// as these self-interactions are expected to be the same always (regular array), we can skip this test the next times.
|
||||
if (first) {
|
||||
for (db::Cell::touching_iterator jj2 = cell.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) {
|
||||
std::vector<db::InstElement> p;
|
||||
std::vector<ClusterInstElement> p;
|
||||
db::ICplxTrans t;
|
||||
add_pair (common, i, p, t, *jj2, pp2, tt2);
|
||||
}
|
||||
|
|
@ -1456,7 +1456,7 @@ private:
|
|||
* @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 local_cluster<T> &c1, const db::Instance &i2, const std::vector<db::InstElement> &p2, const db::ICplxTrans &t2)
|
||||
void add_pair (const local_cluster<T> &c1, const db::Instance &i2, const std::vector<ClusterInstElement> &p2, const db::ICplxTrans &t2)
|
||||
{
|
||||
box_type b1 = c1.bbox ();
|
||||
|
||||
|
|
@ -1470,10 +1470,10 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<db::InstElement> pp2;
|
||||
std::vector<ClusterInstElement> pp2;
|
||||
pp2.reserve (p2.size () + 1);
|
||||
pp2.insert (pp2.end (), p2.begin (), p2.end ());
|
||||
pp2.push_back (db::InstElement ());
|
||||
pp2.push_back (ClusterInstElement ());
|
||||
|
||||
for (db::CellInstArray::iterator ii2 = i2.begin_touching ((b1 & b2).transformed (t2.inverted ()), mp_layout); ! ii2.at_end (); ++ii2) {
|
||||
|
||||
|
|
@ -1482,7 +1482,7 @@ private:
|
|||
|
||||
if (b1.touches (ib2) && c1.interacts (cell2, tt2, *mp_conn)) {
|
||||
|
||||
pp2.back () = db::InstElement (i2, ii2);
|
||||
pp2.back () = ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ());
|
||||
add_single_pair (c1, i2.cell_index (), pp2, tt2);
|
||||
|
||||
// dive into cell of ii2
|
||||
|
|
@ -1503,7 +1503,7 @@ private:
|
|||
* @param t2 The accumulated transformation of the path
|
||||
*/
|
||||
void add_single_pair (const local_cluster<T> &c1,
|
||||
db::cell_index_type ci2, const std::vector<db::InstElement> &p2, const db::ICplxTrans &t2)
|
||||
db::cell_index_type ci2, const std::vector<ClusterInstElement> &p2, const db::ICplxTrans &t2)
|
||||
{
|
||||
// NOTE: make_path may disturb the iteration (because of modification), hence
|
||||
// we first collect and then process the interactions.
|
||||
|
|
@ -1598,7 +1598,7 @@ private:
|
|||
* Cluster connections can only cross one level of hierarchy. This method
|
||||
* creates necessary dummy entries for the given path.
|
||||
*/
|
||||
ClusterInstance make_path (id_type id, const std::vector<db::InstElement> &path) const
|
||||
ClusterInstance make_path (id_type id, const std::vector<ClusterInstElement> &path) const
|
||||
{
|
||||
return mp_tree->make_path (*mp_layout, *mp_cell, id, path);
|
||||
}
|
||||
|
|
@ -1629,30 +1629,32 @@ private:
|
|||
|
||||
template <class T>
|
||||
ClusterInstance
|
||||
hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<db::InstElement> &path)
|
||||
hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<ClusterInstElement> &path)
|
||||
{
|
||||
std::vector<db::InstElement>::const_iterator p = path.end ();
|
||||
std::vector<ClusterInstElement>::const_iterator p = path.end ();
|
||||
tl_assert (p != path.begin ());
|
||||
|
||||
while (true) {
|
||||
|
||||
--p;
|
||||
|
||||
ClusterInstance ci (id, *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_ptr.cell_index ());
|
||||
connected_clusters<T> &child_cc = clusters_per_cell (p->inst_cell_index ());
|
||||
if (child_cc.is_root (id)) {
|
||||
|
||||
const db::Cell &child_cell = layout.cell (p->inst_ptr.cell_index ());
|
||||
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) {
|
||||
|
||||
connected_clusters<T> &parent_cc = clusters_per_cell (pi->parent_cell_index ());
|
||||
for (db::CellInstArray::iterator pii = pi->child_inst ().begin (); ! pii.at_end (); ++pii) {
|
||||
db::Instance child_inst = pi->child_inst ();
|
||||
|
||||
ClusterInstance ci2 (id, db::InstElement (pi->child_inst (), pii));
|
||||
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) {
|
||||
|
||||
size_t id_dummy;
|
||||
|
|
@ -1682,7 +1684,7 @@ hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, siz
|
|||
|
||||
}
|
||||
|
||||
db::cell_index_type pci = p [-1].inst_ptr.cell_index ();
|
||||
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);
|
||||
|
||||
|
|
@ -1697,14 +1699,16 @@ hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, siz
|
|||
|
||||
// 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_ptr.cell_index ());
|
||||
connected_clusters<T> &child_cc = clusters_per_cell (p->inst_cell_index ());
|
||||
if (child_cc.is_root (id)) {
|
||||
|
||||
const db::Cell &child_cell = layout.cell (p->inst_ptr.cell_index ());
|
||||
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 = pi->child_inst ().begin (); ! pii.at_end (); ++pii) {
|
||||
for (db::CellInstArray::iterator pii = child_inst.begin (); ! pii.at_end (); ++pii) {
|
||||
|
||||
size_t id_dummy;
|
||||
|
||||
|
|
@ -1717,7 +1721,7 @@ hier_clusters<T>::make_path (const db::Layout &layout, const db::Cell &cell, siz
|
|||
id_dummy = lc->id ();
|
||||
}
|
||||
|
||||
ClusterInstance ci2 (id, db::InstElement (pi->child_inst (), pii));
|
||||
ClusterInstance ci2 (id, child_inst.cell_index (), child_inst.complex_trans (*pii), child_inst.prop_id ());
|
||||
parent_cc.add_connection (id_dummy, ci2);
|
||||
|
||||
if (pci == pi->parent_cell_index () && ci == ci2) {
|
||||
|
|
@ -1835,7 +1839,7 @@ public:
|
|||
void
|
||||
add (const std::set<size_t> &global_nets, size_t cluster_id)
|
||||
{
|
||||
add (global_nets, ClusterInstance (cluster_id, db::InstElement ()));
|
||||
add (global_nets, ClusterInstance (cluster_id));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2004,7 +2008,7 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
|
||||
if (! cl->get_global_nets ().empty ()) {
|
||||
for (db::Instance::cell_inst_array_type::iterator i = inst->begin (); !i.at_end (); ++i) {
|
||||
global_net_clusters.add (cl->get_global_nets (), db::ClusterInstance (cl->id (), db::InstElement (*inst, i)));
|
||||
global_net_clusters.add (cl->get_global_nets (), db::ClusterInstance (cl->id (), inst->cell_index (), inst->complex_trans (*i), inst->prop_id ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2015,7 +2019,7 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
|
||||
for (typename db::connected_clusters<T>::const_iterator cl = local.begin (); cl != local.end (); ++cl) {
|
||||
if (! cl->get_global_nets ().empty ()) {
|
||||
global_net_clusters.add (cl->get_global_nets (), db::ClusterInstance (cl->id (), db::InstElement ()));
|
||||
global_net_clusters.add (cl->get_global_nets (), db::ClusterInstance (cl->id ()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2030,15 +2034,15 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
|
||||
for (std::set<ClusterInstance>::const_iterator ci = ge->second.begin (); ci != ge->second.end (); ++ci) {
|
||||
|
||||
if (ci->inst ().array_inst.at_end ()) {
|
||||
if (! ci->has_instance ()) {
|
||||
|
||||
local.join_cluster_with (gcid, ci->id ());
|
||||
local.remove_cluster (ci->id ());
|
||||
|
||||
} else {
|
||||
|
||||
std::vector<db::InstElement> p;
|
||||
p.push_back (ci->inst ());
|
||||
std::vector<ClusterInstElement> p;
|
||||
p.push_back (*ci);
|
||||
ClusterInstance k = make_path (layout, cell, ci->id (), p);
|
||||
|
||||
size_t other_id = local.find_cluster_with_connection (k);
|
||||
|
|
@ -2201,7 +2205,7 @@ void recursive_cluster_shape_iterator<T>::next_conn ()
|
|||
if (m_conn_iter_stack.back ().first != m_conn_iter_stack.back ().second) {
|
||||
|
||||
const ClusterInstance &cli = *m_conn_iter_stack.back ().first;
|
||||
down (cli.inst ().inst_ptr.cell_index (), cli.id (), cli.inst ().complex_trans ());
|
||||
down (cli.inst_cell_index (), cli.id (), cli.inst_trans ());
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -2297,7 +2301,7 @@ void recursive_cluster_iterator<T>::next_conn ()
|
|||
if (m_conn_iter_stack.back ().first != m_conn_iter_stack.back ().second) {
|
||||
|
||||
const ClusterInstance &cli = *m_conn_iter_stack.back ().first;
|
||||
down (cli.inst ().inst_ptr.cell_index (), cli.id ());
|
||||
down (cli.inst_cell_index (), cli.id ());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -2395,7 +2399,7 @@ incoming_cluster_connections<T>::ensure_computed_parent (db::cell_index_type ci)
|
|||
const connected_clusters<T> &cc = ((const hier_clusters<T> *) mp_hc.get ())->clusters_per_cell (ci);
|
||||
for (typename connected_clusters<T>::connections_iterator x = cc.begin_connections (); x != cc.end_connections (); ++x) {
|
||||
for (typename connected_clusters<T>::connections_type::const_iterator xx = x->second.begin (); xx != x->second.end (); ++xx) {
|
||||
m_incoming [xx->inst ().inst_ptr.cell_index ()][xx->id ()].push_back (IncomingClusterInstance (ci, x->first, xx->inst ()));
|
||||
m_incoming [xx->inst_cell_index ()][xx->id ()].push_back (IncomingClusterInstance (ci, x->first, *xx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <limits>
|
||||
|
||||
namespace tl {
|
||||
class RelativeProgress;
|
||||
|
|
@ -522,20 +523,136 @@ private:
|
|||
void apply_attr_equivalences (const tl::equivalence_clusters<unsigned int> &attr_equivalence);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The instance information for a cluster
|
||||
*/
|
||||
class DB_PUBLIC ClusterInstElement
|
||||
{
|
||||
public:
|
||||
ClusterInstElement (const db::InstElement &ie)
|
||||
{
|
||||
if (ie.array_inst.at_end ()) {
|
||||
|
||||
m_inst_cell_index = std::numeric_limits<db::cell_index_type>::max ();
|
||||
m_inst_trans = db::ICplxTrans ();
|
||||
m_inst_prop_id = 0;
|
||||
|
||||
} else {
|
||||
|
||||
m_inst_cell_index = ie.inst_ptr.cell_index ();
|
||||
m_inst_trans = ie.complex_trans ();
|
||||
m_inst_prop_id = ie.inst_ptr.prop_id ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ClusterInstElement (db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id)
|
||||
: m_inst_cell_index (inst_cell_index), m_inst_trans (inst_trans), m_inst_prop_id (inst_prop_id)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ClusterInstElement ()
|
||||
: m_inst_cell_index (std::numeric_limits<db::cell_index_type>::max ()), m_inst_trans (), m_inst_prop_id (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the cluster does not have an instance
|
||||
*/
|
||||
bool has_instance () const
|
||||
{
|
||||
return m_inst_cell_index != std::numeric_limits<db::cell_index_type>::max ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the cell index of the cell which is instantiated
|
||||
*/
|
||||
db::cell_index_type inst_cell_index () const
|
||||
{
|
||||
return m_inst_cell_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the instance transformation
|
||||
*/
|
||||
const db::ICplxTrans &inst_trans () const
|
||||
{
|
||||
return m_inst_trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the instance properties id
|
||||
*/
|
||||
db::properties_id_type inst_prop_id () const
|
||||
{
|
||||
return m_inst_prop_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const ClusterInstElement &other) const
|
||||
{
|
||||
return m_inst_cell_index == other.m_inst_cell_index && m_inst_trans == other.m_inst_trans && m_inst_prop_id == other.m_inst_prop_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inequality
|
||||
*/
|
||||
bool operator!= (const ClusterInstElement &other) const
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Less operator
|
||||
*/
|
||||
bool operator< (const ClusterInstElement &other) const
|
||||
{
|
||||
if (m_inst_cell_index != other.m_inst_cell_index) {
|
||||
return m_inst_cell_index < other.m_inst_cell_index;
|
||||
}
|
||||
if (m_inst_trans != other.m_inst_trans) {
|
||||
return m_inst_trans < other.m_inst_trans;
|
||||
}
|
||||
return m_inst_prop_id < other.m_inst_prop_id;
|
||||
}
|
||||
|
||||
private:
|
||||
db::cell_index_type m_inst_cell_index;
|
||||
db::ICplxTrans m_inst_trans;
|
||||
db::properties_id_type m_inst_prop_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A connection to a cluster in a child instance
|
||||
*/
|
||||
class DB_PUBLIC ClusterInstance
|
||||
: public ClusterInstElement
|
||||
{
|
||||
public:
|
||||
ClusterInstance (size_t id, const db::InstElement &inst)
|
||||
: m_id (id), m_inst (inst)
|
||||
ClusterInstance (size_t id, db::cell_index_type inst_cell_index, const db::ICplxTrans &inst_trans, db::properties_id_type inst_prop_id)
|
||||
: ClusterInstElement (inst_cell_index, inst_trans, inst_prop_id), m_id (id)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ClusterInstance (size_t id, const db::InstElement &inst_element)
|
||||
: ClusterInstElement (inst_element), m_id (id)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ClusterInstance (size_t id)
|
||||
: ClusterInstElement (), m_id (id)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ClusterInstance ()
|
||||
: m_id (0), m_inst ()
|
||||
: ClusterInstElement (), m_id (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -548,20 +665,12 @@ public:
|
|||
return m_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the instance path
|
||||
*/
|
||||
const db::InstElement &inst () const
|
||||
{
|
||||
return m_inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Equality
|
||||
*/
|
||||
bool operator== (const ClusterInstance &other) const
|
||||
{
|
||||
return m_id == other.m_id && m_inst == other.m_inst;
|
||||
return m_id == other.m_id && ClusterInstElement::operator== (other);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -580,12 +689,11 @@ public:
|
|||
if (m_id != other.m_id) {
|
||||
return m_id < other.m_id;
|
||||
}
|
||||
return m_inst < other.m_inst;
|
||||
return ClusterInstElement::operator< (other);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_id;
|
||||
db::InstElement m_inst;
|
||||
};
|
||||
|
||||
template <class T> class hier_clusters;
|
||||
|
|
@ -813,7 +921,7 @@ public:
|
|||
* Cluster connections can only cross one level of hierarchy. This method
|
||||
* creates necessary dummy entries for the given path.
|
||||
*/
|
||||
ClusterInstance make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<db::InstElement> &path);
|
||||
ClusterInstance make_path (const db::Layout &layout, const db::Cell &cell, size_t id, const std::vector<ClusterInstElement> &path);
|
||||
|
||||
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);
|
||||
|
|
@ -1004,7 +1112,7 @@ private:
|
|||
class DB_PUBLIC IncomingClusterInstance
|
||||
{
|
||||
public:
|
||||
IncomingClusterInstance (db::cell_index_type pc, size_t parent_cluster_id, const db::InstElement &inst)
|
||||
IncomingClusterInstance (db::cell_index_type pc, size_t parent_cluster_id, const ClusterInstance &inst)
|
||||
: m_parent_cell (pc), m_parent_cluster_id (parent_cluster_id), m_inst (inst)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -1036,7 +1144,7 @@ public:
|
|||
/**
|
||||
* @brief Gets the instance path
|
||||
*/
|
||||
const db::InstElement &inst () const
|
||||
const ClusterInstance &inst () const
|
||||
{
|
||||
return m_inst;
|
||||
}
|
||||
|
|
@ -1066,7 +1174,7 @@ public:
|
|||
private:
|
||||
db::cell_index_type m_parent_cell;
|
||||
size_t m_parent_cluster_id;
|
||||
db::InstElement m_inst;
|
||||
ClusterInstance m_inst;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
const connections_type &connections = clusters.connections_for_cluster (cid);
|
||||
for (connections_type::const_iterator c = connections.begin (); c != connections.end (); ++c) {
|
||||
|
||||
db::cell_index_type subci = c->inst ().inst_ptr.cell_index ();
|
||||
db::cell_index_type subci = c->inst_cell_index ();
|
||||
size_t subcid = c->id ();
|
||||
|
||||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type>::const_iterator cm = cmap.find (std::make_pair (subci, subcid));
|
||||
|
|
@ -590,7 +590,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
}
|
||||
|
||||
if (cm->second != std::numeric_limits<db::cell_index_type>::max ()) {
|
||||
db::CellInstArray ci (db::CellInst (cm->second), tr_wo_mag * c->inst ().complex_trans ());
|
||||
db::CellInstArray ci (db::CellInst (cm->second), tr_wo_mag * c->inst_trans ());
|
||||
ci.transform_into (tr_mag);
|
||||
target_cell->insert (ci);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
std::map<db::CellInstArray, std::list<Connections> >::const_iterator c = connections.find (i->cell_inst ());
|
||||
if (c != connections.end ()) {
|
||||
for (std::list<Connections>::const_iterator j = c->second.begin (); j != c->second.end (); ++j) {
|
||||
l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, *i));
|
||||
l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans (), i->prop_id ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
|
|||
|
||||
std::map<size_t, size_t> &c2p = pins_per_cluster_per_cell [*cid];
|
||||
|
||||
std::map<db::InstElement, db::SubCircuit *> subcircuits;
|
||||
std::map<std::pair<db::cell_index_type, db::ICplxTrans>, db::SubCircuit *> subcircuits;
|
||||
|
||||
for (connected_clusters_type::all_iterator c = clusters.begin_all (); ! c.at_end (); ++c) {
|
||||
|
||||
|
|
@ -243,15 +243,16 @@ void NetlistExtractor::connect_devices (db::Circuit *circuit,
|
|||
const connected_clusters_type::connections_type &connections = clusters.connections_for_cluster (cid);
|
||||
for (connected_clusters_type::connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) {
|
||||
|
||||
const db::Instance &inst = i->inst ().inst_ptr;
|
||||
db::cell_index_type inst_cell_index = i->inst_cell_index ();
|
||||
db::properties_id_type inst_prop_id = i->inst_prop_id ();
|
||||
|
||||
// only consider devices in this pass
|
||||
db::Device *device = device_from_instance (inst.prop_id (), circuit);
|
||||
db::Device *device = device_from_instance (inst_prop_id, circuit);
|
||||
if (! device) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const db::local_cluster<db::PolygonRef> &dc = mp_clusters->clusters_per_cell (inst.cell_index ()).cluster_by_id (i->id ());
|
||||
const db::local_cluster<db::PolygonRef> &dc = mp_clusters->clusters_per_cell (inst_cell_index).cluster_by_id (i->id ());
|
||||
|
||||
// connect the net to the terminal of the device: take the terminal ID from the properties on the
|
||||
// device cluster
|
||||
|
|
@ -278,41 +279,46 @@ void NetlistExtractor::make_and_connect_subcircuits (db::Circuit *circuit,
|
|||
const connected_clusters_type &clusters,
|
||||
size_t cid,
|
||||
db::Net *net,
|
||||
std::map<db::InstElement, db::SubCircuit *> &subcircuits,
|
||||
std::map<std::pair<db::cell_index_type, db::ICplxTrans>, db::SubCircuit *> &subcircuits,
|
||||
const std::map<db::cell_index_type, db::Circuit *> &circuits,
|
||||
const std::map<db::cell_index_type, std::map<size_t, size_t> > &pins_per_cluster)
|
||||
{
|
||||
const connected_clusters_type::connections_type &connections = clusters.connections_for_cluster (cid);
|
||||
for (connected_clusters_type::connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) {
|
||||
|
||||
db::cell_index_type inst_cell_index = i->inst_cell_index ();
|
||||
db::properties_id_type inst_prop_id = i->inst_prop_id ();
|
||||
const db::ICplxTrans &inst_trans = i->inst_trans ();
|
||||
|
||||
// skip devices in this pass
|
||||
if (instance_is_device (i->inst ().inst_ptr.prop_id ())) {
|
||||
if (instance_is_device (inst_prop_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::SubCircuit *subcircuit = 0;
|
||||
db::cell_index_type ccid = i->inst ().inst_ptr.cell_index ();
|
||||
|
||||
std::map<db::InstElement, db::SubCircuit *>::const_iterator j = subcircuits.find (i->inst ());
|
||||
std::pair<db::cell_index_type, db::ICplxTrans> subcircuit_key (inst_cell_index, inst_trans);
|
||||
|
||||
std::map<std::pair<db::cell_index_type, db::ICplxTrans>, db::SubCircuit *>::const_iterator j = subcircuits.find (subcircuit_key);
|
||||
if (j == subcircuits.end ()) {
|
||||
|
||||
// make subcircuit if required
|
||||
|
||||
std::map<db::cell_index_type, db::Circuit *>::const_iterator k = circuits.find (ccid);
|
||||
std::map<db::cell_index_type, db::Circuit *>::const_iterator k = circuits.find (inst_cell_index);
|
||||
tl_assert (k != circuits.end ()); // because we walk bottom-up
|
||||
|
||||
subcircuit = new db::SubCircuit (k->second);
|
||||
db::CplxTrans dbu_trans (mp_layout->dbu ());
|
||||
subcircuit->set_trans (dbu_trans * i->inst ().complex_trans () * dbu_trans.inverted ());
|
||||
subcircuit->set_trans (dbu_trans * inst_trans * dbu_trans.inverted ());
|
||||
circuit->add_subcircuit (subcircuit);
|
||||
subcircuits.insert (std::make_pair (i->inst (), subcircuit));
|
||||
subcircuits.insert (std::make_pair (subcircuit_key, subcircuit));
|
||||
|
||||
} else {
|
||||
subcircuit = j->second;
|
||||
}
|
||||
|
||||
// create the pin connection to the subcircuit
|
||||
std::map<db::cell_index_type, std::map<size_t, size_t> >::const_iterator icc2p = pins_per_cluster.find (ccid);
|
||||
std::map<db::cell_index_type, std::map<size_t, size_t> >::const_iterator icc2p = pins_per_cluster.find (inst_cell_index);
|
||||
tl_assert (icc2p != pins_per_cluster.end ());
|
||||
std::map<size_t, size_t>::const_iterator ip = icc2p->second.find (i->id ());
|
||||
tl_assert (ip != icc2p->second.end ());
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ private:
|
|||
const connected_clusters_type &clusters,
|
||||
size_t cid,
|
||||
db::Net *net,
|
||||
std::map<db::InstElement, db::SubCircuit *> &subcircuits,
|
||||
std::map<std::pair<cell_index_type, ICplxTrans>, SubCircuit *> &subcircuits,
|
||||
const std::map<db::cell_index_type, db::Circuit *> &circuits,
|
||||
const std::map<db::cell_index_type, std::map<size_t, size_t> > &pins_per_cluster);
|
||||
|
||||
|
|
|
|||
|
|
@ -634,13 +634,13 @@ TEST(30_LocalConnectedClusters)
|
|||
EXPECT_EQ (x.size (), size_t (3));
|
||||
ix = x.begin ();
|
||||
EXPECT_EQ (ix->id (), size_t (1));
|
||||
EXPECT_EQ (ix->inst () == db::InstElement (i1), true);
|
||||
EXPECT_EQ (*ix == db::ClusterInstance (ix->id (), i1.cell_index (), i1.complex_trans (), i1.prop_id ()), true);
|
||||
++ix;
|
||||
EXPECT_EQ (ix->id (), size_t (2));
|
||||
EXPECT_EQ (ix->inst () == db::InstElement (i2), true);
|
||||
EXPECT_EQ (*ix == db::ClusterInstance (ix->id (), i2.cell_index (), i2.complex_trans (), i2.prop_id ()), true);
|
||||
++ix;
|
||||
EXPECT_EQ (ix->id (), size_t (1));
|
||||
EXPECT_EQ (ix->inst () == db::InstElement (i2), true);
|
||||
EXPECT_EQ (*ix == db::ClusterInstance (ix->id (), i2.cell_index (), i2.complex_trans (), i2.prop_id ()), true);
|
||||
|
||||
x = cc.connections_for_cluster (2);
|
||||
EXPECT_EQ (x.size (), size_t (0));
|
||||
|
|
@ -753,7 +753,7 @@ static std::string path2string (const db::Layout &ly, db::cell_index_type ci, co
|
|||
std::string res = ly.cell_name (ci);
|
||||
for (std::vector<db::ClusterInstance>::const_iterator p = path.begin (); p != path.end (); ++p) {
|
||||
res += "/";
|
||||
res += ly.cell_name (p->inst ().inst_ptr.cell_index ());
|
||||
res += ly.cell_name (p->inst_cell_index ());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
@ -936,9 +936,9 @@ static void copy_cluster_shapes (const std::string *&attrs, db::Shapes &out, db:
|
|||
const connections_type &connections = clusters.connections_for_cluster (cluster_id);
|
||||
for (connections_type::const_iterator i = connections.begin (); i != connections.end (); ++i) {
|
||||
|
||||
db::ICplxTrans t = trans * i->inst ().complex_trans ();
|
||||
db::ICplxTrans t = trans * i->inst_trans ();
|
||||
|
||||
db::cell_index_type cci = i->inst ().inst_ptr.cell_index ();
|
||||
db::cell_index_type cci = i->inst_cell_index ();
|
||||
copy_cluster_shapes (attrs, out, cci, hc, i->id (), t, conn);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue