Solved ambiguous bus resolution problem.

This commit is contained in:
Matthias Koefferlein 2019-10-29 23:26:17 +01:00
parent 15fa99c128
commit 3cc38fcfc2
2 changed files with 347 additions and 118 deletions

View File

@ -42,6 +42,18 @@
// (applies to circuits, device classes)
#define COMPARE_CASE_INSENSITIVE
// A constant indicating a failed match
const size_t failed_match = std::numeric_limits<size_t>::max ();
// A constant indicating an unknown match
// const size_t unknown_match = std::numeric_limits<size_t>::max () - 1;
// A constant indicating an invalid ID
const size_t invalid_id = std::numeric_limits<size_t>::max ();
// A constant indicating an unknown ID
const size_t unknown_id = std::numeric_limits<size_t>::max () - 1;
namespace db
{
@ -748,7 +760,17 @@ public:
bool has_other () const
{
return m_other_net_index != std::numeric_limits<size_t>::max ();
return m_other_net_index != invalid_id && m_other_net_index != unknown_id;
}
bool has_any_other () const
{
return m_other_net_index != invalid_id;
}
bool has_unknown_other () const
{
return m_other_net_index == unknown_id;
}
size_t other_net_index () const
@ -763,7 +785,7 @@ public:
void unset_other_net ()
{
m_other_net_index = std::numeric_limits<size_t>::max ();
m_other_net_index = invalid_id;
}
bool empty () const
@ -1018,7 +1040,7 @@ private:
// --------------------------------------------------------------------------------------------------------------------
NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_categorizer, CircuitCategorizer &circuit_categorizer, const DeviceFilter &device_filter, const std::map<const db::Circuit *, CircuitMapper> *circuit_map, const CircuitPinMapper *pin_map)
: mp_net (net), m_other_net_index (std::numeric_limits<size_t>::max ())
: mp_net (net), m_other_net_index (invalid_id)
{
if (! net) {
return;
@ -1124,7 +1146,7 @@ NetGraphNode::NetGraphNode (const db::Net *net, DeviceCategorizer &device_catego
}
NetGraphNode::NetGraphNode (const db::SubCircuit *sc, CircuitCategorizer &circuit_categorizer, const std::map<const db::Circuit *, CircuitMapper> *circuit_map, const CircuitPinMapper *pin_map)
: mp_net (0), m_other_net_index (std::numeric_limits<size_t>::max ())
: mp_net (0), m_other_net_index (invalid_id)
{
std::map<const db::Net *, size_t> n2entry;
@ -1250,7 +1272,7 @@ NetGraphNode::to_string () const
res += "(null)";
}
res += "]";
if (m_other_net_index != std::numeric_limits<size_t>::max ()) {
if (m_other_net_index != invalid_id) {
res += " (other: #" + tl::to_string (m_other_net_index) + ")";
}
res += "\n";
@ -1400,15 +1422,16 @@ struct NodeRange
class TentativeNodeMapping
{
public:
TentativeNodeMapping (NetGraph *g1, NetGraph *g2)
: mp_g1 (g1), mp_g2 (g2)
TentativeNodeMapping ()
{ }
~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);
for (std::vector<std::pair<NetGraph *, size_t> >::const_iterator i = m_to_undo.begin (); i != m_to_undo.end (); ++i) {
i->first->unidentify (i->second);
}
for (std::vector<std::pair<NetGraph *, size_t> >::const_iterator i = m_to_undo_to_unknown.begin (); i != m_to_undo_to_unknown.end (); ++i) {
i->first->identify (i->second, unknown_id);
}
}
@ -1417,17 +1440,40 @@ public:
g1->identify (n1, n2);
g2->identify (n2, n1);
if (nm) {
nm->keep (n1, n2);
nm->keep (g1, n1);
nm->keep (g2, n2);
}
}
static void map_pair_from_unknown (TentativeNodeMapping *nm, NetGraph *g1, size_t n1, NetGraph *g2, size_t n2)
{
g1->identify (n1, n2);
g2->identify (n2, n1);
if (nm) {
nm->keep_for_unknown (g1, n1);
nm->keep_for_unknown (g2, n2);
}
}
static void map_to_unknown (TentativeNodeMapping *nm, NetGraph *g1, size_t n1)
{
g1->identify (n1, unknown_id);
if (nm) {
nm->keep (g1, n1);
}
}
private:
std::vector<std::pair<size_t, size_t> > m_to_undo;
NetGraph *mp_g1, *mp_g2;
std::vector<std::pair<NetGraph *, size_t> > m_to_undo, m_to_undo_to_unknown;
void keep (size_t n1, size_t n2)
void keep (NetGraph *g1, size_t n1)
{
m_to_undo.push_back (std::make_pair (n1, n2));
m_to_undo.push_back (std::make_pair (g1, n1));
}
void keep_for_unknown (NetGraph *g1, size_t n1)
{
m_to_undo_to_unknown.push_back (std::make_pair (g1, n1));
}
};
@ -1561,7 +1607,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent(depth) << "! rejected branch.";
#endif
return std::numeric_limits<size_t>::max ();
return failed_match;
}
// 1:1 pairing is less strict
@ -1571,7 +1617,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent(depth) << "! rejected branch.";
#endif
return std::numeric_limits<size_t>::max ();
return failed_match;
}
}
}
@ -1583,7 +1629,7 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr
size_t bt_count = derive_node_identities_from_node_set (nodes, other_nodes, depth, n_branch, tentative, with_ambiguous, data);
if (bt_count == std::numeric_limits<size_t>::max ()) {
if (bt_count == failed_match) {
if (tentative) {
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent(depth) << "! rejected branch.";
@ -1675,7 +1721,7 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc
}
size_t bt_count = derive_node_identities_for_edges (e, ee, e_other, ee_other, net_index, other_net_index, depth, n_branch, tentative, with_ambiguous, data);
if (bt_count == std::numeric_limits<size_t>::max ()) {
if (bt_count == failed_match) {
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent(depth) << "! rejected pair.";
#endif
@ -1786,12 +1832,12 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "max. depth exhausted (" << depth + 1 << ">" << data->max_depth << ")";
#endif
return std::numeric_limits<size_t>::max ();
return failed_match;
}
if (nodes.size () == 1 && other_nodes.size () == 1) {
if (! nodes.front ()->has_other () && ! other_nodes.front ()->has_other ()) {
if (! nodes.front ()->has_any_other () && ! other_nodes.front ()->has_any_other ()) {
// a single candiate: just take this one -> this may render
// inexact matches, but further propagates net pairing
@ -1816,7 +1862,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
// continue here.
size_t bt_count = derive_node_identities (ni, depth + 1, n_branch, tentative, with_ambiguous, data);
if (bt_count != std::numeric_limits<size_t>::max ()) {
if (bt_count != failed_match) {
new_nodes += bt_count;
} else if (tentative) {
return bt_count;
@ -1824,17 +1870,21 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
new_nodes += 1;
} else if (nodes.front ()->has_unknown_other ()) {
// accept this solution as the pairing is possible
} else if (nodes.front ()->has_other ()) {
// this decision leads to a contradiction
if (data->other->node_index_for_net (other_nodes.front ()->net ()) != nodes.front ()->other_net_index ()) {
return std::numeric_limits<size_t>::max ();
return failed_match;
}
} else {
// mismatch of assignment state
return std::numeric_limits<size_t>::max ();
return failed_match;
}
@ -1851,10 +1901,10 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
while (n1 != nodes.end () && n2 != other_nodes.end ()) {
if ((*n1)->has_other ()) {
if ((*n1)->has_any_other ()) {
++n1;
continue;
} else if ((*n2)->has_other ()) {
} else if ((*n2)->has_any_other ()) {
++n2;
continue;
}
@ -1873,9 +1923,9 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
++nn1;
++nn2;
while (nn1 != nodes.end () && nn2 != other_nodes.end ()) {
if ((*nn1)->has_other ()) {
if ((*nn1)->has_any_other ()) {
++nn1;
} else if ((*nn2)->has_other ()) {
} else if ((*nn2)->has_any_other ()) {
++nn2;
} else if (! (**nn1 == **n1) || ! (**nn2 == **n2)) {
break;
@ -1893,7 +1943,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
// in tentative mode ambiguous nodes don't make a match without
// with_ambiguous
if (num > 1 && tentative && ! with_ambiguous) {
return std::numeric_limits<size_t>::max ();
return failed_match;
}
n1 = nn1;
@ -1910,9 +1960,9 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
// node ranges might have changed - adjust to real count and skip leading pairs assigned already
while (nr->n1 != nr->nn1 && nr->n2 != nr->nn2) {
if ((*nr->n1)->has_other ()) {
if ((*nr->n1)->has_any_other ()) {
++nr->n1;
} else if ((*nr->n2)->has_other ()) {
} else if ((*nr->n2)->has_any_other ()) {
++nr->n2;
} else {
break;
@ -1923,9 +1973,9 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
std::vector<const NetGraphNode *>::const_iterator i1 = nr->n1, i2 = nr->n2;
while (i1 != nr->nn1 && i2 != nr->nn2) {
if ((*i1)->has_other ()) {
if ((*i1)->has_any_other ()) {
++i1;
} else if ((*i2)->has_other ()) {
} else if ((*i2)->has_any_other ()) {
++i2;
} else {
++nr->num;
@ -1940,7 +1990,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
} else if (nr->num == 1) {
if (! (*nr->n1)->has_other () && ! (*nr->n2)->has_other ()) {
if (! (*nr->n1)->has_any_other () && ! (*nr->n2)->has_any_other ()) {
// in tentative mode, reject this choice if both nets are named and
// their names differ -> this favors net matching by name
@ -1949,7 +1999,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "rejecting pair as names are not identical: " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name ();
#endif
return std::numeric_limits<size_t>::max ();
return failed_match;
}
// A single candiate: just take this one -> this may render
@ -1975,24 +2025,28 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
// continue here.
size_t bt_count = derive_node_identities (ni, depth + 1, n_branch, tentative, with_ambiguous, data);
if (bt_count != std::numeric_limits<size_t>::max ()) {
if (bt_count != failed_match) {
new_nodes += bt_count;
new_nodes += 1;
} else if (tentative) {
new_nodes = bt_count;
}
} else if ((*nr->n1)->has_unknown_other ()) {
// accept any other net
} else if ((*nr->n1)->has_other ()) {
// this decision leads to a contradiction
if (data->other->node_index_for_net ((*nr->n2)->net ()) != (*nr->n1)->other_net_index ()) {
return std::numeric_limits<size_t>::max ();
return failed_match;
}
} else {
// mismatch of assignment state
return std::numeric_limits<size_t>::max ();
return failed_match;
}
@ -2001,7 +2055,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch.";
#endif
return std::numeric_limits<size_t>::max ();
return failed_match;
} else {
@ -2009,7 +2063,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
tl::info << indent_s << "analyzing ambiguity group with " << nr->num << " members";
#endif
// sort the ambiguity group such that net names
// sort the ambiguity group such that net names match best
std::vector<std::pair<const NetGraphNode *, const NetGraphNode *> > pairs;
tl::equivalence_clusters<const NetGraphNode *> equivalent_other_nodes;
@ -2019,70 +2073,91 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
sort_node_range_by_best_match (*nr);
}
for (std::vector<const NetGraphNode *>::const_iterator i1 = nr->n1; i1 != nr->nn1; ++i1) {
{
if ((*i1)->has_other ()) {
continue;
// marks the nodes from the ambiguity group as unknown so we don't revisit them (causing deep recursion)
TentativeNodeMapping tn2unknown;
// collect and mark the ambiguity combinations to consider
std::vector<std::vector<const NetGraphNode *>::const_iterator> iters1, iters2;
for (std::vector<const NetGraphNode *>::const_iterator i1 = nr->n1; i1 != nr->nn1; ++i1) {
if (! (*i1)->has_any_other ()) {
iters1.push_back (i1);
size_t ni = node_index_for_net ((*i1)->net ());
TentativeNodeMapping::map_to_unknown (&tn2unknown, this, ni);
}
}
bool any = false;
std::vector<const NetGraphNode *>::const_iterator i2;
for (i2 = nr->n2; i2 != nr->nn2; ++i2) {
if ((*i2)->has_other ()) {
continue;
for (std::vector<const NetGraphNode *>::const_iterator i2 = nr->n2; i2 != nr->nn2; ++i2) {
if (! (*i2)->has_any_other ()) {
iters2.push_back (i2);
size_t other_ni = data->other->node_index_for_net ((*i2)->net ());
TentativeNodeMapping::map_to_unknown (&tn2unknown, data->other, other_ni);
}
}
if (seen.find (*i2) != seen.end ()) {
continue;
}
for (std::vector<std::vector<const NetGraphNode *>::const_iterator>::const_iterator ii1 = iters1.begin (); ii1 != iters1.end (); ++ii1) {
size_t ni = node_index_for_net ((*i1)->net ());
size_t other_ni = data->other->node_index_for_net ((*i2)->net ());
std::vector<const NetGraphNode *>::const_iterator i1 = *ii1;
TentativeNodeMapping tn (this, data->other);
TentativeNodeMapping::map_pair (&tn, this, ni, data->other, other_ni);
bool any = false;
// try this candidate in tentative mode
for (std::vector<std::vector<const NetGraphNode *>::const_iterator>::const_iterator ii2 = iters2.begin (); ii2 != iters2.end (); ++ii2) {
std::vector<const NetGraphNode *>::const_iterator i2 = *ii2;
if (seen.find (*i2) != seen.end ()) {
continue;
}
size_t ni = node_index_for_net ((*i1)->net ());
size_t other_ni = data->other->node_index_for_net ((*i2)->net ());
TentativeNodeMapping tn;
TentativeNodeMapping::map_pair_from_unknown (&tn, this, ni, data->other, other_ni);
// try this candidate in tentative mode
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name ();
tl::info << indent_s << "trying in tentative mode: " << (*i1)->net ()->expanded_name () << " vs. " << (*i2)->net ()->expanded_name ();
#endif
size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, &tn, with_ambiguous, data);
size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, &tn, with_ambiguous, data);
if (bt_count != std::numeric_limits<size_t>::max ()) {
if (bt_count != failed_match) {
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "match found";
tl::info << indent_s << "match found";
#endif
// we have a match ...
// we have a match ...
if (any) {
if (any) {
// there is already a known pair, so we can mark *i2 and the previous *i2 as equivalent
// (makes them ambiguous)
equivalent_other_nodes.same (*i2, pairs.back ().second);
// there is already a known pair, so we can mark *i2 and the previous *i2 as equivalent
// (makes them ambiguous)
equivalent_other_nodes.same (*i2, pairs.back ().second);
} else {
} else {
// identified a new pair
new_nodes += bt_count + 1;
pairs.push_back (std::make_pair (*i1, *i2));
seen.insert (*i2);
any = true;
// identified a new pair
new_nodes += bt_count + 1;
pairs.push_back (std::make_pair (*i1, *i2));
seen.insert (*i2);
any = true;
}
}
}
}
if (! any && tentative) {
if (! any && tentative) {
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << indent_s << "mismatch.";
tl::info << indent_s << "mismatch.";
#endif
// a mismatch - stop here.
return std::numeric_limits<size_t>::max ();
// a mismatch - stop here.
return failed_match;
}
}
}
@ -2123,7 +2198,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector<const NetGraphNode *
size_t ni = node_index_for_net (p->first->net ());
size_t bt_count = derive_node_identities (ni, depth + 1, nr->num * n_branch, tentative, with_ambiguous, data);
tl_assert (bt_count != std::numeric_limits<size_t>::max ());
tl_assert (bt_count != failed_match);
}
@ -2595,7 +2670,7 @@ struct DeviceConnectionDistance
{
int d = 0.0;
for (std::vector<std::pair<size_t, size_t> >::const_iterator i = a.first.begin (), j = b.first.begin (); i != a.first.end () && j != b.first.end (); ++i, ++j) {
if (i->second != j->second || i->second == std::numeric_limits<size_t>::max () || j->second == std::numeric_limits<size_t>::max ()) {
if (i->second != j->second || i->second == invalid_id || j->second == invalid_id) {
++d;
}
}
@ -2673,6 +2748,32 @@ void align (Iter i1, Iter i2, Iter j1, Iter j2, Distance distance)
}
/**
* @brief Returns true, if the given net is passive
* A passive net does not have devices nor (active) pins.
*/
static bool is_passive_net (const db::Net *net, const std::map<const db::Circuit *, CircuitMapper> &circuit_and_pin_mapping)
{
if (net->terminal_count () != 0) {
return false;
}
if (net->subcircuit_pin_count () == 0) {
return true;
}
for (db::Net::const_subcircuit_pin_iterator p = net->begin_subcircuit_pins (); p != net->end_subcircuit_pins (); ++p) {
const db::Circuit *c = p->subcircuit ()->circuit ();
std::map<const db::Circuit *, CircuitMapper>::const_iterator ic;
ic = circuit_and_pin_mapping.find (c);
if (ic != circuit_and_pin_mapping.end () && ic->second.has_other_pin_for_this_pin (p->pin_id ())) {
return false;
}
}
return true;
}
bool
NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
db::DeviceCategorizer &device_categorizer,
@ -2743,7 +2844,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
data.logger = mp_logger;
size_t ni = g1.derive_node_identities (i1 - g1.begin (), 0, 1, 0 /*not tentative*/, pass > 0 /*with ambiguities*/, &data);
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
if (ni > 0 && ni != failed_match) {
new_identities += ni;
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << ni << " new identities.";
@ -2777,8 +2878,12 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
}
if (nodes.empty () || other_nodes.empty ()) {
if (! nodes.empty () || ! other_nodes.empty ()) {
good = false;
// active mismatched nodes give an error
for (std::vector<const NetGraphNode *>::const_iterator n = nodes.begin (); n != nodes.end () && good; ++n) {
good = is_passive_net ((*n)->net (), c12_circuit_and_pin_mapping);
}
for (std::vector<const NetGraphNode *>::const_iterator n = other_nodes.begin (); n != other_nodes.end () && good; ++n) {
good = is_passive_net ((*n)->net (), c22_circuit_and_pin_mapping);
}
// this assumes that we don't gain anything here. Stop now.
break;
@ -2796,7 +2901,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
data.logger = mp_logger;
size_t ni = g1.derive_node_identities_from_node_set (nodes, other_nodes, 0, 1, 0 /*not tentative*/, pass > 0 /*with ambiguities*/, &data);
if (ni > 0 && ni != std::numeric_limits<size_t>::max ()) {
if (ni > 0 && ni != failed_match) {
new_identities += ni;
#if defined(PRINT_DEBUG_NETCOMPARE)
tl::info << ni << " new identities.";
@ -2836,12 +2941,20 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
void
NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *pin2, bool &good, bool &pin_mismatch) const
{
// Determine whether the pin in question is used - only in this case we will report an error.
// Otherwise, the report will be "match" against 0.
const db::Circuit *c = pin1 ? c1 : c2;
const db::Pin *pin = pin1 ? pin1 : pin2;
// If the pin isn't connected internally inside the circuit we can ignore it
if (c->net_for_pin (pin->id ()) && c->net_for_pin (pin->id ())->is_passive ()) {
if (mp_logger) {
mp_logger->match_pins (pin1, pin2);
}
return;
}
// Determine whether the pin in question is used - only in this case we will report an error.
// Otherwise, the report will be "match" against 0.
bool is_not_connected = true;
for (db::Circuit::const_refs_iterator r = c->begin_refs (); r != c->end_refs () && is_not_connected; ++r) {
const db::SubCircuit *sc = r.operator-> ();
@ -2870,43 +2983,46 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
// Report pin assignment
// This step also does the pin identity mapping.
// try to assign floating pins by name with higher prio
std::map<std::string, std::pair<const db::Pin *, const db::Pin *> > floating_pins_by_name;
// try to assign abstract pins by name with higher prio
// NOTE: An "abstract" pin is a concept that is used in the context of circuit abstracts where the circuits is
// intentionally emptied. An "abstract pin" is not just a floating pin. An abstract does not have a net while
// a floating pin has a net, but this net is passive - i.e. not attached to any device.
std::map<std::string, std::pair<const db::Pin *, const db::Pin *> > abstract_pins_by_name;
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
const db::Net *net = c2->net_for_pin (p->id ());
if (!net && !p->name ().empty ()) {
floating_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> ();
abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.second = p.operator-> ();
}
}
for (db::Circuit::const_pin_iterator p = c1->begin_pins (); p != c1->end_pins (); ++p) {
const db::Net *net = c1->net_for_pin (p->id ());
if (!net && !p->name ().empty ()) {
floating_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> ();
abstract_pins_by_name.insert (std::make_pair (normalize_name (p->name ()), std::make_pair ((const db::Pin *) 0, (const db::Pin *) 0))).first->second.first = p.operator-> ();
}
}
std::map<const db::Pin *, const db::Pin *> floating_pin_name_mapping;
for (std::map<std::string, std::pair<const db::Pin *, const db::Pin *> >::const_iterator i = floating_pins_by_name.begin (); i != floating_pins_by_name.end (); ++i) {
std::map<const db::Pin *, const db::Pin *> abstract_pin_name_mapping;
for (std::map<std::string, std::pair<const db::Pin *, const db::Pin *> >::const_iterator i = abstract_pins_by_name.begin (); i != abstract_pins_by_name.end (); ++i) {
if (i->second.first && i->second.second) {
floating_pin_name_mapping [i->second.first] = i->second.second;
floating_pin_name_mapping [i->second.second] = i->second.first;
abstract_pin_name_mapping [i->second.first] = i->second.second;
abstract_pin_name_mapping [i->second.second] = i->second.first;
}
}
std::vector<const db::Pin *> floating_pins;
std::vector<const db::Pin *> abstract_pins;
std::multimap<size_t, const db::Pin *> net2pin;
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
const db::Net *net = c2->net_for_pin (p->id ());
if (net) {
net2pin.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
} else if (floating_pin_name_mapping.find (p.operator-> ()) == floating_pin_name_mapping.end ()) {
floating_pins.push_back (p.operator-> ());
} else if (abstract_pin_name_mapping.find (p.operator-> ()) == abstract_pin_name_mapping.end ()) {
abstract_pins.push_back (p.operator-> ());
}
}
std::vector<const db::Pin *>::iterator next_float = floating_pins.begin ();
std::vector<const db::Pin *>::iterator next_abstract = abstract_pins.begin ();
CircuitMapper &c12_pin_mapping = c12_circuit_and_pin_mapping [c1];
c12_pin_mapping.set_other (c2);
@ -2920,10 +3036,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
const db::Net *net = c1->net_for_pin (p->id ());
if (! net) {
std::map<const db::Pin *, const db::Pin *>::const_iterator fp = floating_pin_name_mapping.find (p.operator-> ());
if (fp != floating_pin_name_mapping.end ()) {
std::map<const db::Pin *, const db::Pin *>::const_iterator fp = abstract_pin_name_mapping.find (p.operator-> ());
if (fp != abstract_pin_name_mapping.end ()) {
// assign a floating pin - this is a dummy assignment which is mitigated
// assign an abstract pin - this is a dummy assignment which is mitigated
// by declaring the pins equivalent in derive_pin_equivalence
if (mp_logger) {
mp_logger->match_pins (p.operator-> (), fp->second);
@ -2931,17 +3047,17 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
c12_pin_mapping.map_pin (p->id (), fp->second->id ());
c22_pin_mapping.map_pin (fp->second->id (), p->id ());
} else if (next_float != floating_pins.end ()) {
} else if (next_abstract != abstract_pins.end ()) {
// assign a floating pin - this is a dummy assignment which is mitigated
// assign an abstract pin - this is a dummy assignment which is mitigated
// by declaring the pins equivalent in derive_pin_equivalence
if (mp_logger) {
mp_logger->match_pins (p.operator-> (), *next_float);
mp_logger->match_pins (p.operator-> (), *next_abstract);
}
c12_pin_mapping.map_pin (p->id (), (*next_float)->id ());
c22_pin_mapping.map_pin ((*next_float)->id (), p->id ());
c12_pin_mapping.map_pin (p->id (), (*next_abstract)->id ());
c22_pin_mapping.map_pin ((*next_abstract)->id (), p->id ());
++next_float;
++next_abstract;
} else {
@ -2957,11 +3073,8 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
const db::NetGraphNode &n = *(g1.begin () + g1.node_index_for_net (net));
if (! n.has_other ()) {
handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch);
continue;
}
std::multimap<size_t, const db::Pin *>::iterator np = net2pin.find (n.other_net_index ());
@ -2994,9 +3107,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
handle_pin_mismatch (c1, 0, c2, np->second, good, pin_mismatch);
}
while (next_float != floating_pins.end ()) {
handle_pin_mismatch (c1, 0, c2, *next_float, good, pin_mismatch);
++next_float;
// abstract pins must match.
while (next_abstract != abstract_pins.end ()) {
handle_pin_mismatch (c1, 0, c2, *next_abstract, good, pin_mismatch);
++next_abstract;
}
}
@ -3028,7 +3142,7 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph
bool mapped = true;
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {
if (! g1.begin () [i->second].has_other ()) {
i->second = std::numeric_limits<size_t>::max (); // normalization
i->second = invalid_id; // normalization
mapped = false;
}
}
@ -3062,7 +3176,7 @@ NetlistComparer::do_device_assignment (const db::Circuit *c1, const db::NetGraph
bool mapped = true;
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {
if (! g2.begin () [i->second].has_other ()) {
i->second = std::numeric_limits<size_t>::max (); // normalization
i->second = invalid_id; // normalization
mapped = false;
} else {
i->second = g2.begin () [i->second].other_net_index ();

View File

@ -3246,7 +3246,122 @@ TEST(21_BusLikeAmbiguousConnections)
std::string txt = logger.text ();
EXPECT_EQ (txt,
""
"begin_circuit INV8 INV8\n"
"match_nets IN1 IN1\n"
"match_nets IN2 IN2\n"
"match_nets IN3 IN3\n"
"match_nets IN4 IN4\n"
"match_nets IN5 IN5\n"
"match_nets IN6 IN6\n"
"match_nets IN7 IN7\n"
"match_nets IN8 IN8\n"
"match_nets OUT1 OUT1\n"
"match_nets OUT2 OUT2\n"
"match_nets OUT3 OUT3\n"
"match_nets OUT4 OUT4\n"
"match_nets OUT5 OUT5\n"
"match_nets OUT6 OUT6\n"
"match_nets OUT7 OUT7\n"
"match_nets OUT8 OUT8\n"
"match_nets VDD VDD\n"
"match_nets VSS VSS\n"
"match_pins IN1 IN1\n"
"match_pins OUT1 OUT1\n"
"match_pins IN2 IN2\n"
"match_pins OUT2 OUT2\n"
"match_pins IN3 IN3\n"
"match_pins OUT3 OUT3\n"
"match_pins IN4 IN4\n"
"match_pins OUT4 OUT4\n"
"match_pins IN5 IN5\n"
"match_pins OUT5 OUT5\n"
"match_pins IN6 IN6\n"
"match_pins OUT6 OUT6\n"
"match_pins IN7 IN7\n"
"match_pins OUT7 OUT7\n"
"match_pins IN8 IN8\n"
"match_pins OUT8 OUT8\n"
"match_pins VDD VDD\n"
"match_pins VSS VSS\n"
"end_circuit INV8 INV8 MATCH\n"
"begin_circuit INV8_WRAP INV8_WRAP\n"
"match_ambiguous_nets VDD VDD\n"
"match_ambiguous_nets VSS VSS\n"
"match_ambiguous_nets IN1 A1\n"
"match_ambiguous_nets IN2 A2\n"
"match_ambiguous_nets IN3 A3\n"
"match_ambiguous_nets IN4 A4\n"
"match_ambiguous_nets IN5 A5\n"
"match_ambiguous_nets IN6 A6\n"
"match_ambiguous_nets IN7 A7\n"
"match_ambiguous_nets IN8 A8\n"
"match_ambiguous_nets OUT1 Q1\n"
"match_ambiguous_nets OUT2 Q2\n"
"match_ambiguous_nets OUT3 Q3\n"
"match_ambiguous_nets OUT4 Q4\n"
"match_ambiguous_nets OUT5 Q5\n"
"match_ambiguous_nets OUT6 Q6\n"
"match_ambiguous_nets OUT7 Q7\n"
"match_ambiguous_nets OUT8 Q8\n"
"match_pins IN1 A1\n"
"match_pins OUT1 Q1\n"
"match_pins IN2 A2\n"
"match_pins OUT2 Q2\n"
"match_pins IN3 A3\n"
"match_pins OUT3 Q3\n"
"match_pins IN4 A4\n"
"match_pins OUT4 Q4\n"
"match_pins IN5 A5\n"
"match_pins OUT5 Q5\n"
"match_pins IN6 A6\n"
"match_pins OUT6 Q6\n"
"match_pins IN7 A7\n"
"match_pins OUT7 Q7\n"
"match_pins IN8 A8\n"
"match_pins OUT8 Q8\n"
"match_pins VDD VDD\n"
"match_pins VSS VSS\n"
"match_subcircuits INV8 INV8\n"
"end_circuit INV8_WRAP INV8_WRAP MATCH\n"
"begin_circuit TOP TOP\n"
"match_nets VSS VSS\n"
"match_nets VDD VDD\n"
"match_nets IN8 A8\n"
"match_nets OUT8 Q8\n"
"match_nets IN7 A7\n"
"match_nets OUT7 Q7\n"
"match_nets IN6 A6\n"
"match_nets OUT6 Q6\n"
"match_nets IN5 A5\n"
"match_nets OUT5 Q5\n"
"match_nets IN4 A4\n"
"match_nets OUT4 Q4\n"
"match_nets IN3 A3\n"
"match_nets OUT3 Q3\n"
"match_nets IN2 A2\n"
"match_nets OUT2 Q2\n"
"match_nets IN1 A1\n"
"match_nets OUT1 Q1\n"
"match_pins IN1 A1\n"
"match_pins OUT1 Q1\n"
"match_pins IN2 A2\n"
"match_pins OUT2 Q2\n"
"match_pins IN3 A3\n"
"match_pins OUT3 Q3\n"
"match_pins IN4 A4\n"
"match_pins OUT4 Q4\n"
"match_pins IN5 A5\n"
"match_pins OUT5 Q5\n"
"match_pins IN6 A6\n"
"match_pins OUT6 Q6\n"
"match_pins IN7 A7\n"
"match_pins OUT7 Q7\n"
"match_pins IN8 A8\n"
"match_pins OUT8 Q8\n"
"match_pins VDD VDD\n"
"match_pins VSS VSS\n"
"match_subcircuits INV8 INV8\n"
"end_circuit TOP TOP MATCH"
);
EXPECT_EQ (good, true);
}