From bdf5e3c12422b6d8ed4b59efedd1ab14d3424819 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 30 Sep 2019 21:58:13 +0200 Subject: [PATCH] WIP: fake pin debug issue with LVS Fake pins: pins that happen because something connects to a cell at an unexpected position. Such a pin is difficult to find. The solution is to keep those nets and nur purge them so these nets can be identified in the layout. Here: is_floating? will be true only if there are no pins. Hence nets with pins are not removed. is_passive is introduced for nets - passive nets are such that don't have elements, but a pin. Circuits are purged if they only have passive nets. --- src/db/db/dbCircuit.cc | 2 +- src/db/db/dbDeviceClass.cc | 4 +- src/db/db/dbNet.h | 10 +++- src/db/db/dbNetlist.cc | 4 +- src/db/db/dbNetlistCompare.cc | 4 +- src/db/db/gsiDeclDbNetlist.cc | 9 +++- src/db/unit_tests/dbNetlistTests.cc | 7 ++- testdata/algo/lvs_test2_au.lvsdb.1 | 75 ++++++++++++++++++++--------- testdata/algo/lvs_test2b_au.lvsdb.1 | 75 ++++++++++++++++++++--------- 9 files changed, 136 insertions(+), 54 deletions(-) diff --git a/src/db/db/dbCircuit.cc b/src/db/db/dbCircuit.cc index 35cd1ca6e..f608a9f77 100644 --- a/src/db/db/dbCircuit.cc +++ b/src/db/db/dbCircuit.cc @@ -545,7 +545,7 @@ void Circuit::purge_nets () { std::vector nets_to_be_purged; for (net_iterator n = begin_nets (); n != end_nets (); ++n) { - if (n->is_floating () && n->pin_count () == 0) { + if (n->is_floating ()) { nets_to_be_purged.push_back (n.operator-> ()); } } diff --git a/src/db/db/dbDeviceClass.cc b/src/db/db/dbDeviceClass.cc index d16daf212..7ae697472 100644 --- a/src/db/db/dbDeviceClass.cc +++ b/src/db/db/dbDeviceClass.cc @@ -136,13 +136,13 @@ bool AllDeviceParametersAreEqual::equal (const db::Device &a, const db::Device & // DeviceClass class implementation DeviceClass::DeviceClass () - : mp_netlist (0), m_strict (false) + : m_strict (false), mp_netlist (0) { // .. nothing yet .. } DeviceClass::DeviceClass (const DeviceClass &other) - : gsi::ObjectBase (other), tl::Object (other), tl::UniqueId (other), mp_netlist (0), m_strict (false) + : gsi::ObjectBase (other), tl::Object (other), tl::UniqueId (other), m_strict (false), mp_netlist (0) { operator= (other); } diff --git a/src/db/db/dbNet.h b/src/db/db/dbNet.h index dd476652a..25e19324f 100644 --- a/src/db/db/dbNet.h +++ b/src/db/db/dbNet.h @@ -603,9 +603,17 @@ public: } /** - * @brief Returns true, if the net is floating (there is no active element on the net) + * @brief Returns true, if the net is floating (there is no device, no subcircuit and no pin) */ bool is_floating () const + { + return (m_subcircuit_pins.size () + m_terminals.size () + m_pins.size ()) < 1; + } + + /** + * @brief Returns true, if the net is passive (there is no active element on the net) + */ + bool is_passive () const { return (m_subcircuit_pins.size () + m_terminals.size ()) < 1; } diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 56d4befdd..98e8a089e 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -488,10 +488,10 @@ void Netlist::purge () // purge floating, disconnected nets circuit->purge_nets (); - // if only floating net - connected to a pin - are left, consider this circuit for purging + // if only passive nets are left, consider this circuit for purging bool purge_candidate = ! circuit->dont_purge (); for (db::Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets () && purge_candidate; ++n) { - purge_candidate = n->is_floating (); + purge_candidate = n->is_passive (); } if (purge_candidate) { diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 1124dae2d..7eedbe941 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -320,7 +320,7 @@ public: } else if (! ca) { same (cb, ca); } else if (! cb) { - // makeing a object same as null will make this device being ignored + // making a object same as null will make this device being ignored m_cat_by_ptr [ca] = 0; return; } @@ -2428,7 +2428,7 @@ std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitP 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_floating ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { + if ((! net || net->is_passive ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { pins.push_back (p->id ()); } } diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 9e59ea3c2..899925c45 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -567,7 +567,14 @@ Class decl_dbNet ("db", "Net", ) + gsi::method ("is_floating?", &db::Net::is_floating, "@brief Returns true, if the net is floating.\n" - "Floating nets are those who don't have any or only a single connection (pin_count + terminal_count < 2)." + "Floating nets are those which don't have any device or subcircuit on it and are not connected through a pin." + ) + + gsi::method ("is_passive?", &db::Net::is_passive, + "@brief Returns true, if the net is passive.\n" + "Passive nets don't have devices or subcircuits on it. They can be exposed through a pin.\n" + "\\is_floating? implies \\is_passive?.\n" + "\n" + "This method has been introduced in version 0.26.1.\n" ) + gsi::method ("is_internal?", &db::Net::is_internal, "@brief Returns true, if the net is an internal net.\n" diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 38cb3d709..1dc2f196f 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -752,6 +752,7 @@ TEST(6_Net) EXPECT_EQ (n.pin_count (), size_t (0)); EXPECT_EQ (n.terminal_count (), size_t (0)); EXPECT_EQ (n.is_floating (), true); + EXPECT_EQ (n.is_passive (), true); EXPECT_EQ (n.is_internal (), false); } @@ -781,6 +782,7 @@ TEST(7_NetTerminalsEditing) EXPECT_EQ (n1->terminal_count (), size_t (1)); EXPECT_EQ (n1->pin_count (), size_t (0)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), false); d2->connect_terminal (1, n1); @@ -789,6 +791,7 @@ TEST(7_NetTerminalsEditing) EXPECT_EQ (n1->terminal_count (), size_t (2)); EXPECT_EQ (n1->pin_count (), size_t (0)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), true); EXPECT_EQ (d1->net_for_terminal (0), n1); @@ -871,7 +874,8 @@ TEST(8_NetSubCircuitsEditing) EXPECT_EQ (n1->terminal_count (), size_t (0)); EXPECT_EQ (n1->pin_count (), size_t (1)); - EXPECT_EQ (n1->is_floating (), true); + EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), true); EXPECT_EQ (n1->is_internal (), false); EXPECT_NE (n1->pin_count (), size_t (0)); @@ -886,6 +890,7 @@ TEST(8_NetSubCircuitsEditing) EXPECT_EQ (n1->pin_count (), size_t (1)); EXPECT_EQ (n1->subcircuit_pin_count (), size_t (1)); EXPECT_EQ (n1->is_floating (), false); + EXPECT_EQ (n1->is_passive (), false); EXPECT_EQ (n1->is_internal (), false); sc2->connect_pin (1, n1); diff --git a/testdata/algo/lvs_test2_au.lvsdb.1 b/testdata/algo/lvs_test2_au.lvsdb.1 index 5526f557a..23a4ccef6 100644 --- a/testdata/algo/lvs_test2_au.lvsdb.1 +++ b/testdata/algo/lvs_test2_au.lvsdb.1 @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) net(2 2 mismatch) net(3 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(4 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) pin(1 1 match) pin(2 2 match) pin(4 3 match) + pin(3 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) ) diff --git a/testdata/algo/lvs_test2b_au.lvsdb.1 b/testdata/algo/lvs_test2b_au.lvsdb.1 index 612ed7a51..9828a5742 100644 --- a/testdata/algo/lvs_test2b_au.lvsdb.1 +++ b/testdata/algo/lvs_test2b_au.lvsdb.1 @@ -918,23 +918,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1017,23 +1018,24 @@ reference( net(2 name('2')) net(3 name('3')) net(4 name('4')) - net(5 name('6')) - net(6 name('7')) + net(5 name('5')) + net(6 name('6')) + net(7 name('7')) # Outgoing pins and their connections to nets pin(1 name('1')) pin(2 name('2')) pin(3 name('3')) pin(4 name('4')) - pin(name('5')) - pin(5 name('6')) - pin(6 name('7')) + pin(5 name('5')) + pin(6 name('6')) + pin(7 name('7')) # Subcircuits and their connections circuit(1 INV2 name($2) - pin(0 6) + pin(0 7) pin(1 4) - pin(2 5) + pin(2 6) pin(3 3) pin(4 2) pin(5 1) @@ -1068,28 +1070,57 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(4 () mismatch) net(2 2 mismatch) net(3 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(4 5 mismatch) + net(6 6 match) + net(7 7 mismatch) net(1 1 mismatch) - pin(() 4 mismatch) - pin(3 () mismatch) pin(1 1 match) pin(2 2 match) pin(4 3 match) + pin(3 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) - circuit(() 1 mismatch) - circuit(1 () mismatch) circuit(2 () mismatch) + circuit(1 1 mismatch) ) ) - circuit(RINGO RINGO skipped + circuit(RINGO RINGO nomatch xref( + net(() 7 mismatch) + net(() 9 mismatch) + net(() 11 mismatch) + net(() 6 mismatch) + net(() 8 mismatch) + net(5 () mismatch) + net(6 () mismatch) + net(7 () mismatch) + net(9 () mismatch) + net(11 () mismatch) + net(12 () mismatch) + net(10 1 mismatch) + net(8 10 mismatch) + net(1 5 mismatch) + net(2 2 match) + net(3 3 match) + net(4 4 match) + pin(() 0 match) + pin(0 () match) + pin(1 1 match) + pin(2 2 match) + pin(3 3 match) + circuit(() 2 mismatch) + circuit(() 3 mismatch) + circuit(() 4 mismatch) + circuit(() 5 mismatch) + circuit(2 () mismatch) + circuit(3 () mismatch) + circuit(4 () mismatch) + circuit(5 () mismatch) + circuit(1 1 mismatch) ) ) )