From c24c0933bf6a13225d244b16b585ef60d307d143 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 27 Jun 2021 22:56:28 +0200 Subject: [PATCH] Bugfix: blackbox mode/abstract pins Abstract pins are created when pins are not attached to any or only to passive nets (passive nets are those without device terminals or subcircuit pins). 1. Such pins were treated swappable. Now named pins will not be treated swappable but are mapped by name. This enables blackbox models where the pins are labelled and must correspond to schematic pins. 2. A bug was present which lead to incorrect handling of abstract nets in net compare. --- src/db/db/dbNetlistCompare.cc | 31 +++++++++++------- src/db/unit_tests/dbNetlistCompareTests.cc | 36 ++++++++++----------- testdata/drc/drcSimpleTests_au9a.cir | 6 ++-- testdata/lvs/empty_subcells.lvsdb | 4 +-- testdata/lvs/ringo_simple_blackboxing.lvsdb | 4 +-- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index c3555691e..04b396f76 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -776,8 +776,9 @@ public: { if (is_for_subcircuit ()) { const db::SubCircuit *sc = subcircuit_pair ().first; + size_t pin_id = std::numeric_limits::max () - m_id1; const db::Circuit *c = sc->circuit_ref (); - return std::string ("X") + sc->expanded_name () + " " + c->name (); + return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)"; } else { size_t term_id1 = m_id1; size_t term_id2 = m_id2; @@ -3168,14 +3169,16 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const } static -std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper) +std::vector collect_anonymous_empty_pins (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper) { std::vector pins; for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) { - const db::Net *net = c->net_for_pin (p->id ()); - if ((! net || net->is_passive ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { - pins.push_back (p->id ()); + if (p->name ().empty () && ! circuit_pin_mapper->is_mapped (c, p->id ())) { + const db::Net *net = c->net_for_pin (p->id ()); + if (! net || net->is_passive ()) { + pins.push_back (p->id ()); + } } } @@ -3185,13 +3188,11 @@ std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitP void NetlistComparer::derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper) { - // TODO: All pins with empty nets are treated as equivalent - this as a quick way to - // treat circuits abstracts, although it's not really valid. By doing this, we - // don't capture the case of multiple (abstract) subcircuits wired in different ways. + // NOTE: All unnamed pins with empty nets are treated as equivalent. There is no other criterion to match these pins. std::vector pa, pb; - pa = collect_pins_with_empty_nets (ca, circuit_pin_mapper); - pb = collect_pins_with_empty_nets (cb, circuit_pin_mapper); + pa = collect_anonymous_empty_pins (ca, circuit_pin_mapper); + pb = collect_anonymous_empty_pins (cb, circuit_pin_mapper); circuit_pin_mapper->map_pins (ca, pa); circuit_pin_mapper->map_pins (cb, pb); @@ -3537,7 +3538,13 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, // NOTE: for normalization we map all subcircuits of c1 to c2. // Also, pin swapping will only happen there. + if (options ()->debug_netgraph) { + tl::info << "Netlist graph:"; + } g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper); + if (options ()->debug_netgraph) { + tl::info << "Other netlist graph:"; + } g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper); // Match dummy nodes for null nets @@ -3851,7 +3858,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g mp_logger->match_pins (p.operator-> (), fp->second); } c12_pin_mapping.map_pin (p->id (), fp->second->id ()); - c22_pin_mapping.map_pin (fp->second->id (), p->id ()); + c22_pin_mapping.map_pin (fp->second->id (), fp->second->id ()); } else if (next_abstract != abstract_pins2.end ()) { @@ -3861,7 +3868,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g mp_logger->match_pins (p.operator-> (), *next_abstract); } c12_pin_mapping.map_pin (p->id (), (*next_abstract)->id ()); - c22_pin_mapping.map_pin ((*next_abstract)->id (), p->id ()); + c22_pin_mapping.map_pin ((*next_abstract)->id (), (*next_abstract)->id ()); ++next_abstract; diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 17f102883..3c299b221 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -3822,24 +3822,24 @@ TEST(21_BusLikeAmbiguousConnections) "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_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets OUT8 Q8\n" + "match_nets IN8 A8\n" + "match_nets OUT7 Q7\n" + "match_nets IN7 A7\n" + "match_nets OUT6 Q6\n" + "match_nets IN6 A6\n" + "match_nets OUT5 Q5\n" + "match_nets IN5 A5\n" + "match_nets OUT4 Q4\n" + "match_nets IN4 A4\n" + "match_nets OUT3 Q3\n" + "match_nets IN3 A3\n" + "match_nets OUT2 Q2\n" + "match_nets IN2 A2\n" + "match_nets OUT1 Q1\n" + "match_nets IN1 A1\n" "match_pins IN1 A1\n" "match_pins OUT1 Q1\n" "match_pins IN2 A2\n" diff --git a/testdata/drc/drcSimpleTests_au9a.cir b/testdata/drc/drcSimpleTests_au9a.cir index 8d0e86af5..b106c0428 100644 --- a/testdata/drc/drcSimpleTests_au9a.cir +++ b/testdata/drc/drcSimpleTests_au9a.cir @@ -119,9 +119,9 @@ M$2 3 5 2 7 LVNMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U * cell TIE * pin VDD * pin BULK,VSS -.SUBCKT TIE 2 3 -* net 2 VDD -* net 3 BULK,VSS +.SUBCKT TIE 1 2 +* net 1 VDD +* net 2 BULK,VSS .ENDS TIE * cell EMPTY diff --git a/testdata/lvs/empty_subcells.lvsdb b/testdata/lvs/empty_subcells.lvsdb index 81138e85d..5a0306ccb 100644 --- a/testdata/lvs/empty_subcells.lvsdb +++ b/testdata/lvs/empty_subcells.lvsdb @@ -158,8 +158,8 @@ xref( ) circuit(empty_subcells EMPTY_SUBCELLS match xref( - net(1 1 warning) - net(2 2 warning) + net(1 1 match) + net(2 2 match) circuit(2 1 match) circuit(1 2 match) ) diff --git a/testdata/lvs/ringo_simple_blackboxing.lvsdb b/testdata/lvs/ringo_simple_blackboxing.lvsdb index 31b71eaba..ac20fdda6 100644 --- a/testdata/lvs/ringo_simple_blackboxing.lvsdb +++ b/testdata/lvs/ringo_simple_blackboxing.lvsdb @@ -516,8 +516,8 @@ xref( net(8 4 match) net(5 3 match) net(7 5 match) - net(6 2 warning) - net(9 1 warning) + net(6 2 match) + net(9 1 match) pin(3 3 match) pin(0 2 match) pin(2 4 match)