mirror of https://github.com/KLayout/klayout.git
Some refactoring.
This commit is contained in:
parent
2f3e113db0
commit
d018805c23
|
|
@ -668,6 +668,40 @@ struct CompareData
|
|||
tl::RelativeProgress *progress;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// A generic triplet of object category and two IDs
|
||||
// Used as a key for device terminal edges and subcircuit edges
|
||||
|
||||
class CatAndIds
|
||||
{
|
||||
public:
|
||||
CatAndIds (size_t cat, size_t id1, size_t id2)
|
||||
: m_cat (cat), m_id1 (id1), m_id2 (id2)
|
||||
{ }
|
||||
|
||||
bool operator== (const CatAndIds &other) const
|
||||
{
|
||||
return m_cat == other.m_cat && m_id1 == other.m_id1 && m_id2 == other.m_id2;
|
||||
}
|
||||
|
||||
bool operator< (const CatAndIds &other) const
|
||||
{
|
||||
if (m_cat != other.m_cat) {
|
||||
return m_cat < other.m_cat;
|
||||
}
|
||||
if (m_id1 != other.m_id1) {
|
||||
return m_id1 < other.m_id1;
|
||||
}
|
||||
if (m_id2 != other.m_id2) {
|
||||
return m_id2 < other.m_id2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_cat, m_id1, m_id2;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// NetGraphNode definition and implementation
|
||||
|
||||
|
|
@ -676,6 +710,156 @@ static size_t translate_terminal_id (size_t tid, const db::Device *device)
|
|||
return device->device_class () ? device->device_class ()->normalize_terminal_id (tid) : tid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents one transition within a net graph edge
|
||||
*
|
||||
* Each transition connects two pins of subcircuits or terminals of devices.
|
||||
* An edge is basically a collection of transitions.
|
||||
*/
|
||||
class Transition
|
||||
{
|
||||
public:
|
||||
Transition (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id)
|
||||
{
|
||||
m_ptr = (void *) device;
|
||||
m_cat = device_category;
|
||||
m_id1 = terminal1_id;
|
||||
m_id2 = terminal2_id;
|
||||
}
|
||||
|
||||
Transition (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id)
|
||||
{
|
||||
m_ptr = (void *) subcircuit;
|
||||
m_cat = subcircuit_category;
|
||||
m_id1 = std::numeric_limits<size_t>::max () - pin1_id;
|
||||
m_id2 = pin2_id;
|
||||
}
|
||||
|
||||
CatAndIds make_key () const
|
||||
{
|
||||
return CatAndIds (m_cat, m_id1, m_id2);
|
||||
}
|
||||
|
||||
bool operator< (const Transition &other) const
|
||||
{
|
||||
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
|
||||
return is_for_subcircuit () < other.is_for_subcircuit ();
|
||||
}
|
||||
|
||||
if (is_for_subcircuit ()) {
|
||||
|
||||
if ((subcircuit () != 0) != (other.subcircuit () != 0)) {
|
||||
return (subcircuit () != 0) < (other.subcircuit () != 0);
|
||||
}
|
||||
|
||||
if (subcircuit () != 0) {
|
||||
SubCircuitCompare scc;
|
||||
if (! scc.equals (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()))) {
|
||||
return scc (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((device () != 0) != (other.device () != 0)) {
|
||||
return (device () != 0) < (other.device () != 0);
|
||||
}
|
||||
|
||||
if (device () != 0) {
|
||||
DeviceCompare dc;
|
||||
if (! dc.equals (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()))) {
|
||||
return dc (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_id1 != other.m_id1) {
|
||||
return m_id1 < other.m_id1;
|
||||
}
|
||||
return m_id2 < other.m_id2;
|
||||
}
|
||||
|
||||
bool operator== (const Transition &other) const
|
||||
{
|
||||
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_for_subcircuit ()) {
|
||||
|
||||
if ((subcircuit () != 0) != (other.subcircuit () != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (subcircuit () != 0) {
|
||||
SubCircuitCompare scc;
|
||||
if (! scc.equals (std::make_pair (subcircuit (), cat ()), std::make_pair (other.subcircuit (), other.cat ()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((device () != 0) != (other.device () != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device () != 0) {
|
||||
DeviceCompare dc;
|
||||
if (! dc.equals (std::make_pair (device (), cat ()), std::make_pair (other.device (), other.cat ()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (m_id1 == other.m_id1 && m_id2 == other.m_id2);
|
||||
}
|
||||
|
||||
std::string to_string () const
|
||||
{
|
||||
if (is_for_subcircuit ()) {
|
||||
const db::SubCircuit *sc = subcircuit ();
|
||||
size_t pin_id = std::numeric_limits<size_t>::max () - m_id1;
|
||||
const db::Circuit *c = sc->circuit_ref ();
|
||||
return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)";
|
||||
} else {
|
||||
size_t term_id1 = m_id1;
|
||||
size_t term_id2 = m_id2;
|
||||
const db::Device *d = device ();
|
||||
const db::DeviceClass *dc = d->device_class ();
|
||||
return std::string ("D") + d->expanded_name () + " " + dc->name () + " "
|
||||
+ "(" + dc->terminal_definitions () [term_id1].name () + ")->(" + dc->terminal_definitions () [term_id2].name () + ")";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_for_subcircuit () const
|
||||
{
|
||||
return m_id1 > std::numeric_limits<size_t>::max () / 2;
|
||||
}
|
||||
|
||||
const db::Device *device () const
|
||||
{
|
||||
return (const db::Device *) m_ptr;
|
||||
}
|
||||
|
||||
const db::SubCircuit *subcircuit () const
|
||||
{
|
||||
return (const db::SubCircuit *) m_ptr;
|
||||
}
|
||||
|
||||
size_t cat () const
|
||||
{
|
||||
return m_cat;
|
||||
}
|
||||
|
||||
private:
|
||||
void *m_ptr;
|
||||
size_t m_cat;
|
||||
size_t m_id1, m_id2;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A node within the net graph
|
||||
*
|
||||
|
|
@ -691,166 +875,6 @@ static size_t translate_terminal_id (size_t tid, const db::Device *device)
|
|||
class NetGraphNode
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Represents one transition within an edge_iterator
|
||||
*
|
||||
* Each transition connects two pins of subcircuits or terminals
|
||||
* of devices.
|
||||
* An edge is basically a collection of transitions.
|
||||
*/
|
||||
struct Transition
|
||||
{
|
||||
|
||||
Transition (const db::Device *device, size_t device_category, size_t terminal1_id, size_t terminal2_id)
|
||||
{
|
||||
device_pair ().first = device;
|
||||
device_pair ().second = device_category;
|
||||
m_id1 = terminal1_id;
|
||||
m_id2 = terminal2_id;
|
||||
}
|
||||
|
||||
Transition (const db::SubCircuit *subcircuit, size_t subcircuit_category, size_t pin1_id, size_t pin2_id)
|
||||
{
|
||||
subcircuit_pair ().first = subcircuit;
|
||||
subcircuit_pair ().second = subcircuit_category;
|
||||
m_id1 = std::numeric_limits<size_t>::max () - pin1_id;
|
||||
m_id2 = pin2_id;
|
||||
}
|
||||
|
||||
size_t id1 () const
|
||||
{
|
||||
return m_id1;
|
||||
}
|
||||
|
||||
size_t id2 () const
|
||||
{
|
||||
return m_id2;
|
||||
}
|
||||
|
||||
bool operator< (const Transition &other) const
|
||||
{
|
||||
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
|
||||
return is_for_subcircuit () < other.is_for_subcircuit ();
|
||||
}
|
||||
|
||||
if (is_for_subcircuit ()) {
|
||||
|
||||
if ((subcircuit_pair ().first != 0) != (other.subcircuit_pair ().first != 0)) {
|
||||
return (subcircuit_pair ().first != 0) < (other.subcircuit_pair ().first != 0);
|
||||
}
|
||||
|
||||
if (subcircuit_pair ().first != 0) {
|
||||
SubCircuitCompare scc;
|
||||
if (! scc.equals (subcircuit_pair (), other.subcircuit_pair ())) {
|
||||
return scc (subcircuit_pair (), other.subcircuit_pair ());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((device_pair ().first != 0) != (other.device_pair ().first != 0)) {
|
||||
return (device_pair ().first != 0) < (other.device_pair ().first != 0);
|
||||
}
|
||||
|
||||
if (device_pair ().first != 0) {
|
||||
DeviceCompare dc;
|
||||
if (! dc.equals (device_pair (), other.device_pair ())) {
|
||||
return dc (device_pair (), other.device_pair ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_id1 != other.m_id1) {
|
||||
return m_id1 < other.m_id1;
|
||||
}
|
||||
return m_id2 < other.m_id2;
|
||||
}
|
||||
|
||||
bool operator== (const Transition &other) const
|
||||
{
|
||||
if (is_for_subcircuit () != other.is_for_subcircuit ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_for_subcircuit ()) {
|
||||
|
||||
if ((subcircuit_pair ().first != 0) != (other.subcircuit_pair ().first != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (subcircuit_pair ().first != 0) {
|
||||
SubCircuitCompare scc;
|
||||
if (! scc.equals (subcircuit_pair (), other.subcircuit_pair ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ((device_pair ().first != 0) != (other.device_pair ().first != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device_pair ().first != 0) {
|
||||
DeviceCompare dc;
|
||||
if (! dc.equals (device_pair (), other.device_pair ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (m_id1 == other.m_id1 && m_id2 == other.m_id2);
|
||||
}
|
||||
|
||||
std::string to_string () const
|
||||
{
|
||||
if (is_for_subcircuit ()) {
|
||||
const db::SubCircuit *sc = subcircuit_pair ().first;
|
||||
size_t pin_id = std::numeric_limits<size_t>::max () - m_id1;
|
||||
const db::Circuit *c = sc->circuit_ref ();
|
||||
return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)";
|
||||
} else {
|
||||
size_t term_id1 = m_id1;
|
||||
size_t term_id2 = m_id2;
|
||||
const db::Device *d = device_pair ().first;
|
||||
const db::DeviceClass *dc = d->device_class ();
|
||||
return std::string ("D") + d->expanded_name () + " " + dc->name () + " "
|
||||
+ "(" + dc->terminal_definitions () [term_id1].name () + ")->(" + dc->terminal_definitions () [term_id2].name () + ")";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_for_subcircuit () const
|
||||
{
|
||||
return m_id1 > std::numeric_limits<size_t>::max () / 2;
|
||||
}
|
||||
|
||||
std::pair<const db::Device *, size_t> &device_pair ()
|
||||
{
|
||||
return *reinterpret_cast<std::pair<const db::Device *, size_t> *> ((void *) &m_ref);
|
||||
}
|
||||
|
||||
const std::pair<const db::Device *, size_t> &device_pair () const
|
||||
{
|
||||
return *reinterpret_cast<const std::pair<const db::Device *, size_t> *> ((const void *) &m_ref);
|
||||
}
|
||||
|
||||
std::pair<const db::SubCircuit *, size_t> &subcircuit_pair ()
|
||||
{
|
||||
return *reinterpret_cast<std::pair<const db::SubCircuit *, size_t> *> ((void *) &m_ref);
|
||||
}
|
||||
|
||||
const std::pair<const db::SubCircuit *, size_t> &subcircuit_pair () const
|
||||
{
|
||||
return *reinterpret_cast<const std::pair<const db::SubCircuit *, size_t> *> ((const void *) &m_ref);
|
||||
}
|
||||
|
||||
private:
|
||||
char m_ref [sizeof (std::pair<const void *, size_t>)];
|
||||
size_t m_id1, m_id2;
|
||||
};
|
||||
|
||||
typedef std::pair<std::vector<Transition>, std::pair<size_t, const db::Net *> > edge_type;
|
||||
|
||||
static void swap_edges (edge_type &e1, edge_type &e2)
|
||||
|
|
@ -953,7 +977,7 @@ public:
|
|||
|
||||
edge_iterator find_edge (const std::vector<Transition> &edge) const
|
||||
{
|
||||
edge_iterator res = std::lower_bound (begin (), end (), edge, NetGraphNode::EdgeToEdgeOnlyCompare ());
|
||||
edge_iterator res = std::lower_bound (begin (), end (), edge, EdgeToEdgeOnlyCompare ());
|
||||
if (res == end () || res->first != edge) {
|
||||
return end ();
|
||||
} else {
|
||||
|
|
@ -1373,9 +1397,9 @@ NetGraphNode::expand_subcircuit_nodes (NetGraph *graph)
|
|||
for (std::vector<Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
|
||||
tl_assert (t->is_for_subcircuit ());
|
||||
if (! sc) {
|
||||
sc = t->subcircuit_pair ().first;
|
||||
sc = t->subcircuit ();
|
||||
} else {
|
||||
tl_assert (sc == t->subcircuit_pair ().first);
|
||||
tl_assert (sc == t->subcircuit ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1542,35 +1566,6 @@ struct NodeRange
|
|||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct CatAndIds
|
||||
{
|
||||
public:
|
||||
CatAndIds (size_t _cat, size_t _id1, size_t _id2)
|
||||
: cat (_cat), id1 (_id1), id2 (_id2)
|
||||
{ }
|
||||
|
||||
bool operator== (const CatAndIds &other) const
|
||||
{
|
||||
return cat == other.cat && id1 == other.id1 && id2 == other.id2;
|
||||
}
|
||||
|
||||
bool operator< (const CatAndIds &other) const
|
||||
{
|
||||
if (cat != other.cat) {
|
||||
return cat < other.cat;
|
||||
}
|
||||
if (id1 != other.id1) {
|
||||
return id1 < other.id1;
|
||||
}
|
||||
if (id2 != other.id2) {
|
||||
return id2 < other.id2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t cat, id1, id2;
|
||||
};
|
||||
|
||||
template <class Obj>
|
||||
class generic_mapper_for_target_node
|
||||
{
|
||||
|
|
@ -1659,9 +1654,9 @@ public:
|
|||
|
||||
size_t ni = e.second.first;
|
||||
std::set<std::pair<CatAndIds, const Device *> > &dev = for_node_nc (ni);
|
||||
for (std::vector<NetGraphNode::Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
|
||||
for (std::vector<Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
|
||||
if (! j->is_for_subcircuit ()) {
|
||||
dev.insert (std::make_pair (CatAndIds (j->device_pair ().second, j->id1 (), j->id2 ()), j->device_pair ().first));
|
||||
dev.insert (std::make_pair (j->make_key (), j->device ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1686,9 +1681,9 @@ public:
|
|||
|
||||
size_t ni = e.second.first;
|
||||
std::set<std::pair<CatAndIds, const SubCircuit *> > &sc = for_node_nc (ni);
|
||||
for (std::vector<NetGraphNode::Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
|
||||
for (std::vector<Transition>::const_iterator j = e.first.begin (); j != e.first.end (); ++j) {
|
||||
if (j->is_for_subcircuit ()) {
|
||||
sc.insert (std::make_pair (CatAndIds (j->subcircuit_pair ().second, j->id1 (), j->id2 ()), j->subcircuit_pair ().first));
|
||||
sc.insert (std::make_pair (j->make_key (), j->subcircuit ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1903,21 +1898,21 @@ NetGraph::build (const db::Circuit *c, DeviceCategorizer &device_categorizer, Ci
|
|||
*/
|
||||
static bool edges_are_compatible (const NetGraphNode::edge_type &e, const NetGraphNode::edge_type &e_other, const DeviceEquivalenceTracker &device_eq, const SubCircuitEquivalenceTracker &sc_eq)
|
||||
{
|
||||
std::vector<NetGraphNode::Transition>::const_iterator t1 = e.first.begin (), tt1 = e.first.end ();
|
||||
std::vector<NetGraphNode::Transition>::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end ();
|
||||
std::vector<Transition>::const_iterator t1 = e.first.begin (), tt1 = e.first.end ();
|
||||
std::vector<Transition>::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end ();
|
||||
|
||||
std::vector<void *> p1, p2;
|
||||
|
||||
while (t1 != tt1 && t2 != tt2) {
|
||||
|
||||
std::vector<NetGraphNode::Transition>::const_iterator t10 = t1, t20 = t2;
|
||||
std::vector<Transition>::const_iterator t10 = t1, t20 = t2;
|
||||
|
||||
p1.clear ();
|
||||
while (t1 != tt1 && *t1 == *t10) {
|
||||
if (t1->is_for_subcircuit ()) {
|
||||
p1.push_back ((void *) sc_eq.other (t1->subcircuit_pair ().first));
|
||||
p1.push_back ((void *) sc_eq.other (t1->subcircuit ()));
|
||||
} else {
|
||||
p1.push_back ((void *) device_eq.other (t1->device_pair ().first));
|
||||
p1.push_back ((void *) device_eq.other (t1->device ()));
|
||||
}
|
||||
++t1;
|
||||
}
|
||||
|
|
@ -1925,9 +1920,9 @@ static bool edges_are_compatible (const NetGraphNode::edge_type &e, const NetGra
|
|||
p2.clear ();
|
||||
while (t2 != tt2 && *t2 == *t20) {
|
||||
if (t2->is_for_subcircuit ()) {
|
||||
p2.push_back ((void *) (sc_eq.other (t2->subcircuit_pair ().first) ? t2->subcircuit_pair ().first : 0));
|
||||
p2.push_back ((void *) (sc_eq.other (t2->subcircuit ()) ? t2->subcircuit () : 0));
|
||||
} else {
|
||||
p2.push_back ((void *) (device_eq.other (t2->device_pair ().first) ? t2->device_pair ().first : 0));
|
||||
p2.push_back ((void *) (device_eq.other (t2->device ()) ? t2->device () : 0));
|
||||
}
|
||||
++t2;
|
||||
}
|
||||
|
|
@ -2004,7 +1999,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
|
|||
first = false;
|
||||
}
|
||||
tl::info << indent (depth) << " " << (nn->net () ? nn->net ()->expanded_name ().c_str() : "(null)") << " via: " << tl::noendl;
|
||||
for (std::vector<NetGraphNode::Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
|
||||
for (std::vector<Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
|
||||
tl::info << (t != i->second->first.begin () ? "; " : "") << t->to_string() << tl::noendl;
|
||||
}
|
||||
tl::info << "";
|
||||
|
|
@ -2019,7 +2014,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
|
|||
first = false;
|
||||
}
|
||||
tl::info << indent(depth) << " " << (nn->net() ? nn->net()->expanded_name().c_str() : "(null)") << " via: " << tl::noendl;
|
||||
for (std::vector<NetGraphNode::Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
|
||||
for (std::vector<Transition>::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) {
|
||||
tl::info << (t != i->second->first.begin () ? "; " : "") << t->to_string() << tl::noendl;
|
||||
}
|
||||
tl::info << "";
|
||||
|
|
@ -2079,7 +2074,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
|
|||
static bool has_subcircuits (db::NetGraphNode::edge_iterator e, db::NetGraphNode::edge_iterator ee)
|
||||
{
|
||||
while (e != ee) {
|
||||
for (std::vector<NetGraphNode::Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
|
||||
for (std::vector<Transition>::const_iterator t = e->first.begin (); t != e->first.end (); ++t) {
|
||||
if (t->is_for_subcircuit ()) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue