This commit is contained in:
Matthias Koefferlein 2021-09-19 17:26:28 +02:00
parent a42d761e95
commit 930423bcc7
3 changed files with 174 additions and 27 deletions

View File

@ -753,6 +753,87 @@ static bool is_passive_net (const db::Net *net, const std::map<const db::Circuit
return true;
}
// @@@
namespace
{
struct CompareNodePtrSimple
{
int compare_transition (const Transition &a, const Transition &b) const
{
if (a.is_for_subcircuit () != b.is_for_subcircuit ()) {
return a.is_for_subcircuit () < b.is_for_subcircuit () ? -1 : 1;
}
if (a.is_for_subcircuit ()) {
if ((a.subcircuit () != 0) != (b.subcircuit () != 0)) {
return (a.subcircuit () != 0) < (b.subcircuit () != 0) ? -1 : 1;
}
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<Transition> &ta, const std::vector<Transition> &tb) const
{
if (ta.size () != tb.size ()) {
return ta.size () < tb.size () ? -1 : 1;
}
for (std::vector<Transition>::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<const db::NetGraphNode *, CompareNodePtr> 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) {

View File

@ -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<NodeEdgePair> 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<std::pair<const NetGraphNode *, const NetGraphNode *> >::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<std::pair<const NetGraphNode *, const NetGraphNode *> >::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 ();

View File

@ -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<edge_type>::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);
}
/**