diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index a4544e135..e0dce0c28 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -753,86 +753,87 @@ static bool is_passive_net (const db::Net *net, const std::map > signatures; - if ((a.subcircuit () != 0) != (b.subcircuit () != 0)) { - return (a.subcircuit () != 0) < (b.subcircuit () != 0) ? -1 : 1; + for (db::NetGraph::node_iterator n = g.begin (); n != g.end (); ++n) { + std::pair key (subcircuit_signature (*n), device_signature (*n)); + if (signatures.find (key) == signatures.end ()) { + signatures.insert (key); + } else { + m_redundant.insert (n->net ()); } - - if (a.subcircuit () != 0) { - SubCircuitCompare scc; - if (! scc.equals (std::make_pair (a.subcircuit (), a.cat ()), std::make_pair (b.subcircuit (), b.cat ()))) { - return scc (std::make_pair (a.subcircuit (), a.cat ()), std::make_pair (b.subcircuit (), b.cat ())) ? -1 : 1; - } - } - - return a.id1 () < b.id1 (); - - } else { - - if ((a.device () != 0) != (b.device () != 0)) { - return (a.device () != 0) < (b.device () != 0) ? -1 : 1; - } - - if (a.device () != 0) { - DeviceCompare dc; - if (! dc.equals (std::make_pair (a.device (), a.cat ()), std::make_pair (b.device (), b.cat ()))) { - return dc (std::make_pair (a.device (), a.cat ()), std::make_pair (b.device (), b.cat ())) ? -1 : 1; - } - } - - if (a.id1 () != b.id1 ()) { - return a.id1 () < b.id1 (); - } - return a.id2 () < b.id2 (); - } } - int compare_transitions (const std::vector &ta, const std::vector &tb) const + bool is_redundant (const db::NetGraphNode &n) 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; + return m_redundant.find (n.net ()) != m_redundant.end (); } - 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 ()); - } +private: + typedef std::vector > subcircuit_signature_t; + typedef std::vector > device_signature_t; - 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; + std::set m_redundant; + + subcircuit_signature_t subcircuit_signature (const db::NetGraphNode &n) const + { + std::map count; + for (db::NetGraphNode::edge_iterator e = n.begin (); e != n.end (); ++e) { + for (std::vector::const_iterator t = e->first.begin (); t != e->first.end (); ++t) { + if (t->is_for_subcircuit ()) { + count [t->subcircuit ()] += 1; + } } } - return false; + + return subcircuit_signature_t (count.begin (), count.end ()); + } + + device_signature_t device_signature (const db::NetGraphNode &n) const + { + std::map count; + for (db::NetGraphNode::edge_iterator e = n.begin (); e != n.end (); ++e) { + for (std::vector::const_iterator t = e->first.begin (); t != e->first.end (); ++t) { + if (! t->is_for_subcircuit ()) { + count [t->device ()] += 1; + } + } + } + + return device_signature_t (count.begin (), count.end ()); } }; } -// @@@ bool NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, @@ -936,6 +937,11 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, good = true; } + // build the redundant node cache + + RedundantNodeCache redundant_nodes; + redundant_nodes.fill (g1); + // two passes: one without ambiguities, the second one with for (int pass = 0; pass < 2 && ! good; ++pass) { @@ -971,27 +977,33 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, size_t new_identities = 0; - std::set seen; + printf("@@@1\n"); fflush(stdout); for (db::NetGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) { // 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 ()*/) { + if (i1->has_other () && i1->net () && i1->other_net_index () > 0 && i1->exact_match ()) { - seen.insert (i1.operator-> ()); + if (! redundant_nodes.is_redundant (*i1)) { - size_t ni = compare.derive_node_identities (i1 - g1.begin ()); - if (ni > 0 && ni != failed_match) { - new_identities += ni; - if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) { - tl::info << ni << " new identities."; + size_t ni = compare.derive_node_identities (i1 - g1.begin ()); + if (ni > 0 && ni != failed_match) { + new_identities += ni; + if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) { + tl::info << ni << " new identities."; + } } + + } else { + printf("@@@ skipped redundant node: %s\n", i1->net()->expanded_name ().c_str()); fflush(stdout); } } } + printf("@@@2\n"); fflush(stdout); + if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) { tl::info << "checking topological identity ..."; }