mirror of https://github.com/KLayout/klayout.git
WIP: netlist compare (better backtracking)
This commit is contained in:
parent
e855d8df35
commit
4e85ae7db0
|
|
@ -29,7 +29,7 @@
|
||||||
#include "tlLog.h"
|
#include "tlLog.h"
|
||||||
|
|
||||||
// verbose debug output
|
// verbose debug output
|
||||||
// #define PRINT_DEBUG_NETCOMPARE
|
#define PRINT_DEBUG_NETCOMPARE
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
@ -482,7 +482,6 @@ public:
|
||||||
const db::Circuit *cr = sc->circuit_ref ();
|
const db::Circuit *cr = sc->circuit_ref ();
|
||||||
|
|
||||||
size_t this_pin_id = pin_id;
|
size_t this_pin_id = pin_id;
|
||||||
pin_id = pin_map->normalize_pin_id (cr, pin_id);
|
|
||||||
|
|
||||||
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
|
std::map<const db::Circuit *, CircuitMapper>::const_iterator icm = circuit_map->find (cr);
|
||||||
if (icm == circuit_map->end ()) {
|
if (icm == circuit_map->end ()) {
|
||||||
|
|
@ -505,6 +504,10 @@ public:
|
||||||
cr = cm->other ();
|
cr = cm->other ();
|
||||||
pin_id = cm->other_pin_from_this_pin (pin_id);
|
pin_id = cm->other_pin_from_this_pin (pin_id);
|
||||||
|
|
||||||
|
// realize pin swapping by normalization of pin ID
|
||||||
|
|
||||||
|
pin_id = pin_map->normalize_pin_id (cr, pin_id);
|
||||||
|
|
||||||
// we cannot afford creating edges from all to all other pins, so we just create edges to the previous and next
|
// we cannot afford creating edges from all to all other pins, so we just create edges to the previous and next
|
||||||
// pin. This may take more iterations to solve, but should be equivalent.
|
// pin. This may take more iterations to solve, but should be equivalent.
|
||||||
|
|
||||||
|
|
@ -786,6 +789,8 @@ struct CompareNodePtr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TentativeNodeMapping;
|
||||||
|
|
||||||
class NetDeviceGraph
|
class NetDeviceGraph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -859,9 +864,9 @@ public:
|
||||||
* If tentative is true, assignments will not be retained and just the
|
* If tentative is true, assignments will not be retained and just the
|
||||||
* status is reported.
|
* status is reported.
|
||||||
*/
|
*/
|
||||||
size_t derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, bool tentative, bool with_ambiguous);
|
size_t derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
||||||
|
|
||||||
size_t derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, bool tentative, bool with_ambiguous);
|
size_t derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<NetGraphNode> m_nodes;
|
std::vector<NetGraphNode> m_nodes;
|
||||||
|
|
@ -869,6 +874,63 @@ private:
|
||||||
const db::Circuit *mp_circuit;
|
const db::Circuit *mp_circuit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct NodeRange
|
||||||
|
{
|
||||||
|
NodeRange (size_t _num, std::vector<const NetGraphNode *>::const_iterator _n1, std::vector<const NetGraphNode *>::const_iterator _nn1, std::vector<const NetGraphNode *>::const_iterator _n2, std::vector<const NetGraphNode *>::const_iterator _nn2)
|
||||||
|
: num (_num), n1 (_n1), nn1 (_nn1), n2 (_n2), nn2 (_nn2)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const NodeRange &other) const
|
||||||
|
{
|
||||||
|
return num < other.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num;
|
||||||
|
std::vector<const NetGraphNode *>::const_iterator n1, nn1, n2, nn2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class TentativeNodeMapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TentativeNodeMapping (NetDeviceGraph *g1, NetDeviceGraph *g2)
|
||||||
|
: mp_g1 (g1), mp_g2 (g2)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~TentativeNodeMapping ()
|
||||||
|
{
|
||||||
|
for (std::vector<std::pair<size_t, size_t> >::const_iterator i = m_to_undo.begin (); i != m_to_undo.end (); ++i) {
|
||||||
|
mp_g1->unidentify (i->first);
|
||||||
|
mp_g2->unidentify (i->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void map_pair (TentativeNodeMapping *nm, NetDeviceGraph *g1, size_t n1, NetDeviceGraph *g2, size_t n2)
|
||||||
|
{
|
||||||
|
g1->identify (n1, n2);
|
||||||
|
g2->identify (n2, n1);
|
||||||
|
if (nm) {
|
||||||
|
nm->keep (n1, n2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::pair<size_t, size_t> > m_to_undo;
|
||||||
|
NetDeviceGraph *mp_g1, *mp_g2;
|
||||||
|
|
||||||
|
void keep (size_t n1, size_t n2)
|
||||||
|
{
|
||||||
|
m_to_undo.push_back (std::make_pair (n1, n2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// @@@ make attribute
|
// @@@ make attribute
|
||||||
const size_t depth_max = 8;
|
const size_t depth_max = 8;
|
||||||
const size_t n_branch_max = 100;
|
const size_t n_branch_max = 100;
|
||||||
|
|
@ -910,14 +972,21 @@ NetDeviceGraph::build (const db::Circuit *c, DeviceCategorizer &device_categoriz
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, bool tentative, bool with_ambiguous)
|
NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
||||||
{
|
{
|
||||||
NetGraphNode *n = & m_nodes[net_index];
|
NetGraphNode *n = & m_nodes[net_index];
|
||||||
NetGraphNode *nother = & other.m_nodes[n->other_net_index ()];
|
NetGraphNode *nother = & other.m_nodes[n->other_net_index ()];
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
std::string indent;
|
||||||
|
for (size_t d = 0; d < depth; ++d) {
|
||||||
|
indent += " ";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
if (! tentative) {
|
if (! tentative) {
|
||||||
tl::info << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << nother->net ()->expanded_name ();
|
tl::info << indent << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << nother->net ()->expanded_name ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -943,9 +1012,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
|
|
||||||
for (NetGraphNode::edge_iterator i = e; i != ee; ++i) {
|
for (NetGraphNode::edge_iterator i = e; i != ee; ++i) {
|
||||||
const NetGraphNode *n = &m_nodes[i->second.first];
|
const NetGraphNode *n = &m_nodes[i->second.first];
|
||||||
if (! n->has_other ()) {
|
nodes.push_back (n);
|
||||||
nodes.push_back (n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! nodes.empty ()) { // if non-ambiguous, non-assigned
|
if (! nodes.empty ()) { // if non-ambiguous, non-assigned
|
||||||
|
|
@ -964,9 +1031,7 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
for (NetGraphNode::edge_iterator i = e_other; i != ee_other && count_other < 2; ++i) {
|
for (NetGraphNode::edge_iterator i = e_other; i != ee_other && count_other < 2; ++i) {
|
||||||
|
|
||||||
const NetGraphNode *n = &other.m_nodes[i->second.first];
|
const NetGraphNode *n = &other.m_nodes[i->second.first];
|
||||||
if (! n->has_other ()) {
|
other_nodes.push_back (n);
|
||||||
other_nodes.push_back (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -981,15 +1046,18 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
|
|
||||||
// for the purpose of match evaluation we require an exact match of the node structure
|
// for the purpose of match evaluation we require an exact match of the node structure
|
||||||
|
|
||||||
if (tentative && (nodes.size () > 1 || other_nodes.size () > 1)) {
|
if (tentative) {
|
||||||
|
|
||||||
if (nodes.size () != other_nodes.size ()) {
|
if (nodes.size () != other_nodes.size ()) {
|
||||||
return std::numeric_limits<size_t>::max ();
|
return std::numeric_limits<size_t>::max ();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < nodes.size (); ++i) {
|
// 1:1 pairing is less strict
|
||||||
if (! (*nodes[i] == *other_nodes[i]) || nodes[i]->has_other () != other_nodes[i]->has_other ()) {
|
if (nodes.size () > 1 || other_nodes.size () > 1) {
|
||||||
return std::numeric_limits<size_t>::max ();
|
for (size_t i = 0; i < nodes.size (); ++i) {
|
||||||
|
if (! (*nodes[i] == *other_nodes[i])) {
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1016,37 +1084,23 @@ NetDeviceGraph::derive_node_identities (size_t net_index, NetDeviceGraph &other,
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
if (! tentative && new_nodes > 0) {
|
if (! tentative && new_nodes > 0) {
|
||||||
tl::info << "finished pair deduction: " << n->net ()->expanded_name () << " vs. " << nother->net ()->expanded_name () << " with " << new_nodes << " new pairs";
|
tl::info << indent << "finished pair deduction: " << n->net ()->expanded_name () << " vs. " << nother->net ()->expanded_name () << " with " << new_nodes << " new pairs";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return new_nodes;
|
return new_nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct NodeRange
|
|
||||||
{
|
|
||||||
NodeRange (size_t _num, std::vector<const NetGraphNode *>::const_iterator _n1, std::vector<const NetGraphNode *>::const_iterator _nn1, std::vector<const NetGraphNode *>::const_iterator _n2, std::vector<const NetGraphNode *>::const_iterator _nn2)
|
|
||||||
: num (_num), n1 (_n1), nn1 (_nn1), n2 (_n2), nn2 (_nn2)
|
|
||||||
{
|
|
||||||
// .. nothing yet ..
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator< (const NodeRange &other) const
|
|
||||||
{
|
|
||||||
return num < other.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t num;
|
|
||||||
std::vector<const NetGraphNode *>::const_iterator n1, nn1, n2, nn2;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, bool tentative, bool with_ambiguous)
|
NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const NetGraphNode *> &nodes, const std::vector<const NetGraphNode *> &other_nodes, NetDeviceGraph &other, size_t depth, size_t n_branch, NetlistCompareLogger *logger, CircuitPinMapper *circuit_pin_mapper, TentativeNodeMapping *tentative, bool with_ambiguous)
|
||||||
{
|
{
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
std::string indent;
|
||||||
|
for (size_t d = 0; d < depth; ++d) {
|
||||||
|
indent += " ";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t new_nodes = 0;
|
size_t new_nodes = 0;
|
||||||
|
|
||||||
if (depth + 1 == depth_max) {
|
if (depth + 1 == depth_max) {
|
||||||
|
|
@ -1055,30 +1109,50 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
if (nodes.size () == 1 && other_nodes.size () == 1) {
|
if (nodes.size () == 1 && other_nodes.size () == 1) {
|
||||||
|
|
||||||
// a single candiate: just take this one -> this may render
|
if (! nodes.front ()->has_other () && ! other_nodes.front ()->has_other ()) {
|
||||||
// inexact matches, but further propagates net pairing
|
|
||||||
|
|
||||||
if (! tentative) {
|
// a single candiate: just take this one -> this may render
|
||||||
|
// inexact matches, but further propagates net pairing
|
||||||
|
|
||||||
size_t ni = node_index_for_net (nodes.front ()->net ());
|
size_t ni = node_index_for_net (nodes.front ()->net ());
|
||||||
size_t other_ni = other.node_index_for_net (other_nodes.front ()->net ());
|
size_t other_ni = other.node_index_for_net (other_nodes.front ()->net ());
|
||||||
|
|
||||||
identify (ni, other_ni);
|
TentativeNodeMapping::map_pair (tentative, this, ni, &other, other_ni);
|
||||||
other.identify (other_ni, ni);
|
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name ();
|
tl::info << indent << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name ();
|
||||||
#endif
|
#endif
|
||||||
if (logger) {
|
if (! tentative) {
|
||||||
logger->match_nets (nodes.front ()->net (), other_nodes.front ()->net ());
|
if (logger) {
|
||||||
|
logger->match_nets (nodes.front ()->net (), other_nodes.front ()->net ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unconditionally continue here.
|
// continue here.
|
||||||
derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
|
|
||||||
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
|
new_nodes += bt_count;
|
||||||
|
} else if (tentative) {
|
||||||
|
return bt_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_nodes += 1;
|
||||||
|
|
||||||
|
} else if (nodes.front ()->has_other ()) {
|
||||||
|
|
||||||
|
// this decision leads to a contradiction
|
||||||
|
if (other.node_index_for_net (other_nodes.front ()->net ()) != nodes.front ()->other_net_index ()) {
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// mismatch of assignment state
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new_nodes += 1;
|
|
||||||
return new_nodes;
|
return new_nodes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1155,36 +1229,50 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
// A single candiate: just take this one -> this may render
|
// A single candiate: just take this one -> this may render
|
||||||
// inexact matches, but further propagates net pairing
|
// inexact matches, but further propagates net pairing
|
||||||
|
|
||||||
|
size_t ni = node_index_for_net ((*nr->n1)->net ());
|
||||||
|
size_t other_ni = other.node_index_for_net ((*nr->n2)->net ());
|
||||||
|
|
||||||
|
TentativeNodeMapping::map_pair (tentative, this, ni, &other, other_ni);
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name ();
|
||||||
|
#endif
|
||||||
if (! tentative) {
|
if (! tentative) {
|
||||||
|
|
||||||
size_t ni = node_index_for_net ((*nr->n1)->net ());
|
|
||||||
size_t other_ni = other.node_index_for_net ((*nr->n2)->net ());
|
|
||||||
|
|
||||||
identify (ni, other_ni);
|
|
||||||
other.identify (other_ni, ni);
|
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
|
||||||
tl::info << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name ();
|
|
||||||
#endif
|
|
||||||
if (logger) {
|
if (logger) {
|
||||||
logger->match_nets ((*nr->n1)->net (), (*nr->n2)->net ());
|
logger->match_nets ((*nr->n1)->net (), (*nr->n2)->net ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// unconditionally continue here.
|
|
||||||
derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new_nodes += 1;
|
// continue here.
|
||||||
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, n_branch, logger, circuit_pin_mapper, tentative, with_ambiguous);
|
||||||
|
|
||||||
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
|
new_nodes += bt_count;
|
||||||
|
new_nodes += 1;
|
||||||
|
} else if (tentative) {
|
||||||
|
new_nodes = bt_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ((*nr->n1)->has_other ()) {
|
||||||
|
|
||||||
|
// this decision leads to a contradiction
|
||||||
|
if (other.node_index_for_net ((*nr->n2)->net ()) != (*nr->n1)->other_net_index ()) {
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// mismatch of assignment state
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (nr->num * n_branch > n_branch_max) {
|
||||||
|
|
||||||
|
return std::numeric_limits<size_t>::max ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (nr->num * n_branch > n_branch_max) {
|
|
||||||
return std::numeric_limits<size_t>::max ();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
|
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
|
||||||
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
|
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
|
||||||
std::set<const NetGraphNode *> seen;
|
std::set<const NetGraphNode *> seen;
|
||||||
|
|
@ -1211,17 +1299,20 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
size_t ni = node_index_for_net ((*i1)->net ());
|
size_t ni = node_index_for_net ((*i1)->net ());
|
||||||
size_t other_ni = other.node_index_for_net ((*i2)->net ());
|
size_t other_ni = other.node_index_for_net ((*i2)->net ());
|
||||||
|
|
||||||
identify (ni, other_ni);
|
TentativeNodeMapping tn (this, &other);
|
||||||
other.identify (other_ni, ni);
|
TentativeNodeMapping::map_pair (&tn, this, ni, &other, other_ni);
|
||||||
|
|
||||||
// try this candidate in tentative mode
|
// try this candidate in tentative mode
|
||||||
size_t bt_count = derive_node_identities (ni, other, depth + 1, nr->num * n_branch, logger, circuit_pin_mapper, true /*tentative*/, with_ambiguous);
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name ();
|
||||||
unidentify (ni);
|
#endif
|
||||||
other.unidentify (other_ni);
|
size_t bt_count = derive_node_identities (ni, other, depth + 1, nr->num * n_branch, logger, circuit_pin_mapper, &tn, with_ambiguous);
|
||||||
|
|
||||||
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
if (bt_count != std::numeric_limits<size_t>::max ()) {
|
||||||
|
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "match found";
|
||||||
|
#endif
|
||||||
// we have a match ...
|
// we have a match ...
|
||||||
|
|
||||||
if (any) {
|
if (any) {
|
||||||
|
|
@ -1245,6 +1336,9 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! any && tentative) {
|
if (! any && tentative) {
|
||||||
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
tl::info << indent << "mismatch.";
|
||||||
|
#endif
|
||||||
// a mismatch - stop here.
|
// a mismatch - stop here.
|
||||||
return std::numeric_limits<size_t>::max ();
|
return std::numeric_limits<size_t>::max ();
|
||||||
}
|
}
|
||||||
|
|
@ -1253,46 +1347,6 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
if (! tentative) {
|
if (! tentative) {
|
||||||
|
|
||||||
// collect ambiguous nodes and mark their pins as swappable
|
|
||||||
|
|
||||||
std::map<const NetGraphNode *, const NetGraphNode *> other2this;
|
|
||||||
for (std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) {
|
|
||||||
other2this.insert (std::make_pair (p->second, p->first));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t cid = 1; cid <= equivalent_other_nodes.size (); ++cid) {
|
|
||||||
|
|
||||||
tl::equivalence_clusters<const NetGraphNode *>::cluster_iterator c = equivalent_other_nodes.begin_cluster (cid);
|
|
||||||
const NetGraphNode *c1 = other2this[(*c)->first];
|
|
||||||
|
|
||||||
tl::equivalence_clusters<const NetGraphNode *>::cluster_iterator cc = c;
|
|
||||||
++cc;
|
|
||||||
for ( ; cc != equivalent_other_nodes.end_cluster (cid); ++cc) {
|
|
||||||
|
|
||||||
for (db::Net::const_pin_iterator pp = (*cc)->first->net ()->begin_pins (); pp != (*cc)->first->net ()->end_pins (); ++pp) {
|
|
||||||
for (db::Net::const_pin_iterator p = (*c)->first->net ()->begin_pins (); p != (*c)->first->net ()->end_pins (); ++p) {
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
|
||||||
tl::info << "pin swapping due to ambiguous nets for circuit (B) " << other.circuit ()->name () << ": " << pp->pin ()->expanded_name () << " and " << p->pin ()->expanded_name ();
|
|
||||||
#endif
|
|
||||||
circuit_pin_mapper->map_pins (other.circuit (), pp->pin_id (), p->pin_id ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const NetGraphNode *cc1 = other2this[(*cc)->first];
|
|
||||||
|
|
||||||
for (db::Net::const_pin_iterator pp = cc1->net ()->begin_pins (); pp != cc1->net ()->end_pins (); ++pp) {
|
|
||||||
for (db::Net::const_pin_iterator p = c1->net ()->begin_pins (); p != c1->net ()->end_pins (); ++p) {
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
|
||||||
tl::info << "pin swapping due to ambiguous nets for circuit (A) " << circuit ()->name () << ": " << pp->pin ()->expanded_name () << " and " << p->pin ()->expanded_name ();
|
|
||||||
#endif
|
|
||||||
circuit_pin_mapper->map_pins (circuit (), pp->pin_id (), p->pin_id ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// issue the matching pairs
|
// issue the matching pairs
|
||||||
|
|
||||||
for (std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) {
|
for (std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) {
|
||||||
|
|
@ -1300,11 +1354,10 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
size_t ni = node_index_for_net (p->first->net ());
|
size_t ni = node_index_for_net (p->first->net ());
|
||||||
size_t other_ni = other.node_index_for_net (p->second->net ());
|
size_t other_ni = other.node_index_for_net (p->second->net ());
|
||||||
|
|
||||||
identify (ni, other_ni);
|
TentativeNodeMapping::map_pair (tentative, this, ni, &other, other_ni);
|
||||||
other.identify (other_ni, ni);
|
|
||||||
|
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
tl::info << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name ();
|
tl::info << indent << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name ();
|
||||||
#endif
|
#endif
|
||||||
if (logger) {
|
if (logger) {
|
||||||
bool ambiguous = equivalent_other_nodes.has_attribute (p->second);
|
bool ambiguous = equivalent_other_nodes.has_attribute (p->second);
|
||||||
|
|
@ -1328,6 +1381,17 @@ NetDeviceGraph::derive_node_identities_from_node_set (const std::vector<const Ne
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
for (std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> >::const_iterator p = pairs.begin (); p != pairs.end (); ++p) {
|
||||||
|
|
||||||
|
size_t ni = node_index_for_net (p->first->net ());
|
||||||
|
size_t other_ni = other.node_index_for_net (p->second->net ());
|
||||||
|
|
||||||
|
TentativeNodeMapping::map_pair (tentative, this, ni, &other, other_ni);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1643,7 +1707,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
||||||
|
|
||||||
for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) {
|
for (db::NetDeviceGraph::node_iterator i1 = g1.begin (); i1 != g1.end (); ++i1) {
|
||||||
if (i1->has_other () && i1->net ()) {
|
if (i1->has_other () && i1->net ()) {
|
||||||
size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), false /*not tentative*/, pass > 0 /*with ambiguities*/);
|
size_t ni = g1.derive_node_identities (i1 - g1.begin (), g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||||
new_identities += ni;
|
new_identities += ni;
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
|
@ -1686,7 +1750,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
||||||
std::sort (nodes.begin (), nodes.end (), CompareNodePtr ());
|
std::sort (nodes.begin (), nodes.end (), CompareNodePtr ());
|
||||||
std::sort (other_nodes.begin (), other_nodes.end (), CompareNodePtr ());
|
std::sort (other_nodes.begin (), other_nodes.end (), CompareNodePtr ());
|
||||||
|
|
||||||
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), false /*not tentative*/, pass > 0 /*with ambiguities*/);
|
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, g2, 0, 1, mp_logger, mp_circuit_pin_mapper.get (), 0 /*not tentative*/, pass > 0 /*with ambiguities*/);
|
||||||
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
|
||||||
new_identities += ni;
|
new_identities += ni;
|
||||||
#if defined(PRINT_DEBUG_NETCOMPARE)
|
#if defined(PRINT_DEBUG_NETCOMPARE)
|
||||||
|
|
|
||||||
|
|
@ -335,9 +335,8 @@ TEST(1_SimpleInverter)
|
||||||
EXPECT_EQ (logger.text (),
|
EXPECT_EQ (logger.text (),
|
||||||
"begin_circuit INV INV\n"
|
"begin_circuit INV INV\n"
|
||||||
"match_nets VDD VDD\n"
|
"match_nets VDD VDD\n"
|
||||||
"match_nets OUT OUT\n"
|
|
||||||
"match_nets IN IN\n"
|
|
||||||
"match_nets VSS VSS\n"
|
"match_nets VSS VSS\n"
|
||||||
|
"match_nets IN IN\n"
|
||||||
"match_pins $0 $1\n"
|
"match_pins $0 $1\n"
|
||||||
"match_pins $1 $3\n"
|
"match_pins $1 $3\n"
|
||||||
"match_pins $2 $0\n"
|
"match_pins $2 $0\n"
|
||||||
|
|
@ -2072,10 +2071,11 @@ TEST(17_InherentlyAmbiguousDecoder)
|
||||||
" device NMOS $3 (S=VSS,G=A,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
" device NMOS $3 (S=VSS,G=A,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
" device NMOS $4 (S=INT,G=B,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
" device NMOS $4 (S=INT,G=B,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||||
"end;\n"
|
"end;\n"
|
||||||
"circuit DECODER ($0=A,$1=B,$2=NQ0,$3=NQ1,$4=NQ2,$5=NQ3,$6=VDD,$7=VSS);\n"
|
// BTW: this shows that pin swapping can't be automated ...
|
||||||
" subcircuit NAND $1 ($0=B,$1=B,$2=NB,$3=VDD,$4=VSS);\n"
|
"circuit DECODER ($0=B,$1=A,$2=NQ0,$3=NQ1,$4=NQ2,$5=NQ3,$6=VDD,$7=VSS);\n"
|
||||||
" subcircuit NAND $2 ($0=A,$1=NB,$2=NQ1,$3=VDD,$4=VSS);\n"
|
" subcircuit NAND $1 ($0=A,$1=A,$2=NA,$3=VDD,$4=VSS);\n"
|
||||||
" subcircuit NAND $3 ($0=A,$1=A,$2=NA,$3=VDD,$4=VSS);\n"
|
" subcircuit NAND $2 ($0=B,$1=B,$2=NB,$3=VDD,$4=VSS);\n"
|
||||||
|
" subcircuit NAND $3 ($0=A,$1=NB,$2=NQ1,$3=VDD,$4=VSS);\n"
|
||||||
" subcircuit NAND $4 ($0=A,$1=B,$2=NQ3,$3=VDD,$4=VSS);\n"
|
" subcircuit NAND $4 ($0=A,$1=B,$2=NQ3,$3=VDD,$4=VSS);\n"
|
||||||
" subcircuit NAND $5 ($0=NA,$1=NB,$2=NQ0,$3=VDD,$4=VSS);\n"
|
" subcircuit NAND $5 ($0=NA,$1=NB,$2=NQ0,$3=VDD,$4=VSS);\n"
|
||||||
" subcircuit NAND $6 ($0=NA,$1=B,$2=NQ2,$3=VDD,$4=VSS);\n"
|
" subcircuit NAND $6 ($0=NA,$1=B,$2=NQ2,$3=VDD,$4=VSS);\n"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue