diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 2ad59c2b7..a4544e135 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -753,6 +753,87 @@ static bool is_passive_net (const db::Net *net, const std::map &ta, const std::vector &tb) const + { + if (ta.size () != tb.size ()) { + return ta.size () < tb.size () ? -1 : 1; + } + for (std::vector::const_iterator i = ta.begin (), j = tb.begin (); i != ta.end (); ++i, ++j) { + int c = compare_transition (*i, *j); + if (c != 0) { + return c; + } + } + return 0; + } + + bool operator() (const NetGraphNode *a, const NetGraphNode *b) const + { + if ((a->end () - a->begin ()) != (b->end () - b->begin ())) { + return (a->end () - a->begin ()) < (b->end () - b->begin ()); + } + + for (NetGraphNode::edge_iterator i = a->begin (), j = b->begin (); i != a->end (); ++i, ++j) { + int c = compare_transitions (i->first, j->first); + if (c != 0) { + return c < 0; + } + } + return false; + } +}; + +} +// @@@ + bool NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, @@ -798,26 +879,35 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, size_t ni1 = g1.node_index_for_net (p->first.first); size_t ni2 = g2.node_index_for_net (p->first.second); - g1.identify (ni1, ni2); - g2.identify (ni2, ni1); + + bool exact_match = (g1.node (ni1) == g2.node (ni2)); + + g1.identify (ni1, ni2, exact_match); + g2.identify (ni2, ni1, exact_match); // in must_match mode, check if the nets are identical - if (p->second && ! (g1.node(ni1) == g2.node(ni2))) { - mp_logger->net_mismatch (p->first.first, p->first.second); - } else { - mp_logger->match_nets (p->first.first, p->first.second); + if (mp_logger) { + if (p->second && ! exact_match) { + mp_logger->net_mismatch (p->first.first, p->first.second); + } else { + mp_logger->match_nets (p->first.first, p->first.second); + } } } else if (p->second && g1.has_node_index_for_net (p->first.first)) { - mp_logger->net_mismatch (p->first.first, 0); + if (mp_logger) { + mp_logger->net_mismatch (p->first.first, 0); + } size_t ni1 = g1.node_index_for_net (p->first.first); g1.identify (ni1, 0); } else if (p->second && g2.has_node_index_for_net (p->first.second)) { - mp_logger->net_mismatch (0, p->first.second); + if (mp_logger) { + mp_logger->net_mismatch (0, p->first.second); + } size_t ni2 = g2.node_index_for_net (p->first.second); g2.identify (ni2, 0); @@ -830,10 +920,24 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, tl::RelativeProgress progress (tl::to_string (tr ("Comparing circuits ")) + c1->name () + "/" + c2->name (), std::max (g1.end () - g1.begin (), g2.end () - g2.begin ()), 1); - // two passes: one without ambiguities, the second one with - bool good = false; + // check if there is anything to do + + bool has_any_unresolved = false; + for (db::NetGraph::node_iterator i1 = g1.begin (); i1 != g1.end () && ! has_any_unresolved; ++i1) { + has_any_unresolved = (! i1->has_other () && i1->net ()); + } + for (db::NetGraph::node_iterator i2 = g2.begin (); i2 != g2.end () && ! has_any_unresolved; ++i2) { + has_any_unresolved = (! i2->has_other () && i2->net ()); + } + + if (! has_any_unresolved) { + good = true; + } + + // two passes: one without ambiguities, the second one with + for (int pass = 0; pass < 2 && ! good; ++pass) { if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) { @@ -863,11 +967,18 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, tl::info << "deducing from present nodes ..."; } + // deduce new identities from known nodes if possible + size_t new_identities = 0; + std::set seen; + for (db::NetGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { - if (i1->has_other () && i1->net ()) { + // note: ambiguous nodes don't contribute additional paths, so skip them + if (i1->has_other () && i1->net () /*@@@&& i1->other_net_index () > 0 && i1->exact_match ()*/ /*@@@&& seen.find (i1.operator-> ()) == seen.end ()*/) { + + seen.insert (i1.operator-> ()); size_t ni = compare.derive_node_identities (i1 - g1.begin ()); if (ni > 0 && ni != failed_match) { diff --git a/src/db/db/dbNetlistCompareCore.cc b/src/db/db/dbNetlistCompareCore.cc index 7f2ae3001..30868e63d 100644 --- a/src/db/db/dbNetlistCompareCore.cc +++ b/src/db/db/dbNetlistCompareCore.cc @@ -191,10 +191,10 @@ public: static void map_pair (TentativeNodeMapping *nm, NetGraph *g1, size_t n1, NetGraph *g2, size_t n2, const DeviceMapperForTargetNode &dm1, const DeviceMapperForTargetNode &dm2, DeviceEquivalenceTracker &device_eq, const SubCircuitMapperForTargetNode &scm1, const SubCircuitMapperForTargetNode &scm2, SubCircuitEquivalenceTracker &subcircuit_eq, - size_t depth) + size_t depth, bool exact_match = true) { - g1->identify (n1, n2); - g2->identify (n2, n1); + g1->identify (n1, n2, exact_match); + g2->identify (n2, n1, exact_match); if (nm) { nm->keep (g1, n1); @@ -398,7 +398,7 @@ NetlistCompareCore::derive_node_identities_for_edges (NetGraphNode::edge_iterato nodes.reserve (ee - e); std::vector other_nodes; - other_nodes.reserve (ee - e); + other_nodes.reserve (ee_other - e_other); tl_assert (e->first == e_other->first); @@ -1024,12 +1024,16 @@ NetlistCompareCore::derive_node_identities_from_ambiguity_group (const NodeRange // And seek further from these pairs - for (std::vector >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) { + if (depth_first) { - size_t ni = mp_graph->node_index_for_net (p->first->net ()); + for (std::vector >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) { - size_t bt_count = derive_node_identities (ni, depth + 1, complexity * n_branch, tentative); - tl_assert (bt_count != failed_match); + size_t ni = mp_graph->node_index_for_net (p->first->net ()); + + size_t bt_count = derive_node_identities (ni, depth + 1, complexity * n_branch, tentative); + tl_assert (bt_count != failed_match); + + } } @@ -1083,12 +1087,14 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo size_t ni = mp_graph->node_index_for_net (n->net ()); size_t other_ni = mp_other_graph->node_index_for_net (n_other->net ()); - TentativeNodeMapping::map_pair (tentative, mp_graph, ni, mp_other_graph, other_ni, dm, dm_other, *device_equivalence, scm, scm_other, *subcircuit_equivalence, depth); + bool exact_match = (mp_graph->node (ni) == mp_other_graph->node (other_ni)); + + TentativeNodeMapping::map_pair (tentative, mp_graph, ni, mp_other_graph, other_ni, dm, dm_other, *device_equivalence, scm, scm_other, *subcircuit_equivalence, depth, exact_match); if (! tentative) { ++*progress; if (logger) { - if (! (mp_graph->node (ni) == mp_other_graph->node (other_ni))) { + if (! exact_match) { // this is a mismatch, but we continue with this if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare || tl::verbosity () >= 40) { tl::info << indent_s << "deduced mismatch (singular): " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); diff --git a/src/db/db/dbNetlistCompareGraph.h b/src/db/db/dbNetlistCompareGraph.h index fd3b28933..e08aa6017 100644 --- a/src/db/db/dbNetlistCompareGraph.h +++ b/src/db/db/dbNetlistCompareGraph.h @@ -112,6 +112,16 @@ public: return m_cat; } + size_t id1 () const + { + return m_id1; + } + + size_t id2 () const + { + return m_id2; + } + private: void *m_ptr; size_t m_cat; @@ -152,7 +162,7 @@ public: typedef std::vector::const_iterator edge_iterator; NetGraphNode () - : mp_net (0) + : mp_net (0), m_other_net_index (invalid_id) { // .. nothing yet .. } @@ -193,12 +203,21 @@ public: size_t other_net_index () const { - return m_other_net_index; + return (m_other_net_index == invalid_id || m_other_net_index == unknown_id) ? m_other_net_index : m_other_net_index / 2; } - void set_other_net (size_t index) + bool exact_match () const { - m_other_net_index = index; + return (m_other_net_index == invalid_id || m_other_net_index == unknown_id) ? false : (m_other_net_index & 1) != 0; + } + + void set_other_net (size_t index, bool exact_match) + { + if (index == invalid_id || index == unknown_id) { + m_other_net_index = index; + } else { + m_other_net_index = (index * 2) + size_t (exact_match ? 1 : 0); + } } void unset_other_net () @@ -297,6 +316,17 @@ struct CompareNodeEdgePair } }; +/** + * @brief A comparator comparing two node pointers + */ +struct CompareNodePtr +{ + bool operator() (const NetGraphNode *a, const NetGraphNode *b) const + { + return a->less (*b, true); + } +}; + } namespace std @@ -395,9 +425,9 @@ public: /** * @brief Establishes an equivalence between two nodes of netlist A (this) and B (other) */ - void identify (size_t net_index, size_t other_net_index) + void identify (size_t net_index, size_t other_net_index, bool exact_match = true) { - m_nodes [net_index].set_other_net (other_net_index); + m_nodes [net_index].set_other_net (other_net_index, exact_match); } /**