diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index ae5a3a32b..51fbc5b2a 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -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::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::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::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::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::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::max () / 2; - } - - std::pair &device_pair () - { - return *reinterpret_cast *> ((void *) &m_ref); - } - - const std::pair &device_pair () const - { - return *reinterpret_cast *> ((const void *) &m_ref); - } - - std::pair &subcircuit_pair () - { - return *reinterpret_cast *> ((void *) &m_ref); - } - - const std::pair &subcircuit_pair () const - { - return *reinterpret_cast *> ((const void *) &m_ref); - } - - private: - char m_ref [sizeof (std::pair)]; - size_t m_id1, m_id2; - }; - typedef std::pair, std::pair > edge_type; static void swap_edges (edge_type &e1, edge_type &e2) @@ -953,7 +977,7 @@ public: edge_iterator find_edge (const std::vector &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::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 generic_mapper_for_target_node { @@ -1659,9 +1654,9 @@ public: size_t ni = e.second.first; std::set > &dev = for_node_nc (ni); - for (std::vector::const_iterator j = e.first.begin (); j != e.first.end (); ++j) { + for (std::vector::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 > &sc = for_node_nc (ni); - for (std::vector::const_iterator j = e.first.begin (); j != e.first.end (); ++j) { + for (std::vector::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::const_iterator t1 = e.first.begin (), tt1 = e.first.end (); - std::vector::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end (); + std::vector::const_iterator t1 = e.first.begin (), tt1 = e.first.end (); + std::vector::const_iterator t2 = e_other.first.begin (), tt2 = e_other.first.end (); std::vector p1, p2; while (t1 != tt1 && t2 != tt2) { - std::vector::const_iterator t10 = t1, t20 = t2; + std::vector::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::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) { + for (std::vector::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::const_iterator t = i->second->first.begin (); t != i->second->first.end(); ++t) { + for (std::vector::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::const_iterator t = e->first.begin (); t != e->first.end (); ++t) { + for (std::vector::const_iterator t = e->first.begin (); t != e->first.end (); ++t) { if (t->is_for_subcircuit ()) { return true; }