mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
a42d761e95
commit
930423bcc7
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue