From 506cfc1c6fd1600308d208a65861c4df40b44328 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 30 Sep 2019 20:58:55 +0200 Subject: [PATCH 01/31] WIP: attempt to retain nets which don't have active elements but pins. This is supposed to simplify debugging in case of fake pins. When removing those nets, the pin is very difficult to find. --- src/db/db/dbCircuit.cc | 2 +- src/db/db/dbNetlist.cc | 10 +++++++++- src/db/unit_tests/dbLayoutToNetlistTests.cc | 2 +- src/db/unit_tests/dbNetlistTests.cc | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/db/db/dbCircuit.cc b/src/db/db/dbCircuit.cc index f608a9f77..35cd1ca6e 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 ()) { + if (n->is_floating () && n->pin_count () == 0) { nets_to_be_purged.push_back (n.operator-> ()); } } diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 429ea8b7d..56d4befdd 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -485,8 +485,16 @@ void Netlist::purge () Circuit *circuit = c.operator-> (); + // purge floating, disconnected nets circuit->purge_nets (); - if (circuit->begin_nets () == circuit->end_nets () && ! circuit->dont_purge ()) { + + // if only floating net - connected to a pin - 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 (); + } + + if (purge_candidate) { // No nets left: delete the subcircuits that refer to us and finally delete the circuit while (circuit->begin_refs () != circuit->end_refs ()) { diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index c4b7ca373..011322222 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -1096,7 +1096,7 @@ TEST(3_GlobalNetConnections) " subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n" " subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n" "end;\n" - "circuit INV2 ($1=(null),IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=(null));\n" + "circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n" " device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" " device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n" " device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" diff --git a/src/db/unit_tests/dbNetlistTests.cc b/src/db/unit_tests/dbNetlistTests.cc index 9de025763..38cb3d709 100644 --- a/src/db/unit_tests/dbNetlistTests.cc +++ b/src/db/unit_tests/dbNetlistTests.cc @@ -1380,7 +1380,7 @@ TEST(22_BlankCircuit) nl2.purge (); EXPECT_EQ (nl2.to_string (), - "circuit RINGO (IN=(null),OSC=OSC,VSS=VSS,VDD=VDD);\n" + "circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n" " subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n" " subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n" "end;\n" From bdf5e3c12422b6d8ed4b59efedd1ab14d3424819 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 30 Sep 2019 21:58:13 +0200 Subject: [PATCH 02/31] 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) ) ) ) From a3cecb2ebe046e049c70fd4960d21d12002168ea Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 30 Sep 2019 23:08:15 +0200 Subject: [PATCH 03/31] WIP: enable multiple layout versions of one schematic circuit using 'same_circuit' --- src/db/db/dbNetlistCompare.cc | 100 ++- src/lvs/unit_tests/lvsSimpleTests.cc | 6 + testdata/lvs/ringo_layout_var.cir | 102 +++ testdata/lvs/ringo_layout_var.gds | Bin 0 -> 12456 bytes testdata/lvs/ringo_layout_var.lvs | 78 ++ testdata/lvs/ringo_layout_var.lvsdb | 1076 ++++++++++++++++++++++++++ 6 files changed, 1319 insertions(+), 43 deletions(-) create mode 100644 testdata/lvs/ringo_layout_var.cir create mode 100644 testdata/lvs/ringo_layout_var.gds create mode 100644 testdata/lvs/ringo_layout_var.lvs create mode 100644 testdata/lvs/ringo_layout_var.lvsdb diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 7eedbe941..593810056 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -492,10 +492,11 @@ public: if (ca && has_cat_for (ca)) { throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + ca->name ()); } +#if 0 // can pair multiple layout cells with one schematic circuit if (cb && has_cat_for (cb)) { throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + cb->name ()); } - +#endif generic_categorizer::same (ca, cb); } @@ -2274,13 +2275,13 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const bool good = true; - std::map > cat2circuits; + std::map, std::vector > > cat2circuits; std::set verified_circuits_a, verified_circuits_b; for (db::Netlist::const_circuit_iterator i = a->begin_circuits (); i != a->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].first = i.operator-> (); + cat2circuits[cat].first.push_back (i.operator-> ()); } else { // skip circuit (but count it as verified) verified_circuits_a.insert (i.operator-> ()); @@ -2290,7 +2291,7 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const for (db::Netlist::const_circuit_iterator i = b->begin_circuits (); i != b->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].second = i.operator-> (); + cat2circuits[cat].second.push_back (i.operator-> ()); } else { // skip circuit (but count it as verified) verified_circuits_b.insert (i.operator-> ()); @@ -2342,11 +2343,21 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const // check for circuits that don't match - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first || ! i->second.second) { + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { good = false; if (mp_logger) { - mp_logger->circuit_mismatch (i->second.first, i->second.second); + for (std::vector::const_iterator j = i->second.second.begin (); j != i->second.second.end (); ++j) { + mp_logger->circuit_mismatch (0, *j); + } + } + } + if (i->second.second.empty ()) { + good = false; + if (mp_logger) { + for (std::vector::const_iterator j = i->second.first.begin (); j != i->second.first.end (); ++j) { + mp_logger->circuit_mismatch (*j, 0); + } } } } @@ -2355,59 +2366,62 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const for (db::Netlist::const_bottom_up_circuit_iterator c = a->begin_bottom_up (); c != a->end_bottom_up (); ++c) { - size_t ccat = circuit_categorizer.cat_for_circuit (c.operator-> ()); + const db::Circuit *ca = c.operator-> (); + + size_t ccat = circuit_categorizer.cat_for_circuit (ca); if (! ccat) { continue; } - std::map >::const_iterator i = cat2circuits.find (ccat); + std::map, std::vector > >::const_iterator i = cat2circuits.find (ccat); tl_assert (i != cat2circuits.end ()); + tl_assert (! i->second.first.empty ()); + if (i->second.second.empty ()) { + continue; + } - if (i->second.first && i->second.second) { + // NOTE: there can only be one schematic circuit + tl_assert (i->second.second.size () == size_t (1)); + const db::Circuit *cb = i->second.second.front (); - const db::Circuit *ca = i->second.first; - const db::Circuit *cb = i->second.second; + std::vector > empty; + const std::vector > *net_identity = ∅ + std::map, std::vector > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); + if (sn != m_same_nets.end ()) { + net_identity = &sn->second; + } - std::vector > empty; - const std::vector > *net_identity = ∅ - std::map, std::vector > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); - if (sn != m_same_nets.end ()) { - net_identity = &sn->second; - } - - if (all_subcircuits_verified (ca, verified_circuits_a) && all_subcircuits_verified (cb, verified_circuits_b)) { + if (all_subcircuits_verified (ca, verified_circuits_a) && all_subcircuits_verified (cb, verified_circuits_b)) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << "treating circuit: " << ca->name () << " vs. " << cb->name (); + tl::info << "treating circuit: " << ca->name () << " vs. " << cb->name (); #endif - if (mp_logger) { - mp_logger->begin_circuit (ca, cb); - } + if (mp_logger) { + mp_logger->begin_circuit (ca, cb); + } - bool pin_mismatch = false; - bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping); - if (! g) { - good = false; - } + bool pin_mismatch = false; + bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping); + if (! g) { + good = false; + } - if (! pin_mismatch) { - verified_circuits_a.insert (ca); - verified_circuits_b.insert (cb); - } + if (! pin_mismatch) { + verified_circuits_a.insert (ca); + verified_circuits_b.insert (cb); + } - derive_pin_equivalence (ca, cb, &circuit_pin_mapper); + derive_pin_equivalence (ca, cb, &circuit_pin_mapper); - if (mp_logger) { - mp_logger->end_circuit (ca, cb, g); - } + if (mp_logger) { + mp_logger->end_circuit (ca, cb, g); + } - } else { - - if (mp_logger) { - mp_logger->circuit_skipped (ca, cb); - good = false; - } + } else { + if (mp_logger) { + mp_logger->circuit_skipped (ca, cb); + good = false; } } diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 2fa9252d2..3df15643e 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -154,3 +154,9 @@ TEST(16_floating) { run_test (_this, "floating", "floating.gds", false, "TOP"); } + +TEST(17_layout_variants) +{ + run_test (_this, "ringo_layout_var", "ringo_layout_var.gds"); +} + diff --git a/testdata/lvs/ringo_layout_var.cir b/testdata/lvs/ringo_layout_var.cir new file mode 100644 index 000000000..93b5336ec --- /dev/null +++ b/testdata/lvs/ringo_layout_var.cir @@ -0,0 +1,102 @@ +* Extracted by KLayout + +* cell RINGO +* pin FB +* pin VDD +* pin OUT +* pin ENABLE +* pin VSS +.SUBCKT RINGO 11 12 13 14 15 +* net 11 FB +* net 12 VDD +* net 13 OUT +* net 14 ENABLE +* net 15 VSS +* cell instance $1 r0 *1 1.8,0 +X$1 12 1 15 12 11 14 15 ND2X1 +* cell instance $2 r0 *1 4.2,0 +X$2 12 2 15 12 1 15 INVX1B +* cell instance $3 r0 *1 6,0 +X$3 12 3 15 12 2 15 INVX1 +* cell instance $4 r0 *1 7.8,0 +X$4 12 4 15 12 3 15 INVX1B +* cell instance $5 r0 *1 9.6,0 +X$5 12 5 15 12 4 15 INVX1 +* cell instance $6 r0 *1 11.4,0 +X$6 12 6 15 12 5 15 INVX1B +* cell instance $7 r0 *1 13.2,0 +X$7 12 7 15 12 6 15 INVX1 +* cell instance $8 r0 *1 15,0 +X$8 12 8 15 12 7 15 INVX1 +* cell instance $9 r0 *1 16.8,0 +X$9 12 9 15 12 8 15 INVX1 +* cell instance $10 r0 *1 18.6,0 +X$10 12 10 15 12 9 15 INVX1 +* cell instance $11 r0 *1 20.4,0 +X$11 12 11 15 12 10 15 INVX1 +* cell instance $12 r0 *1 22.2,0 +X$12 12 13 15 12 11 15 INVX1 +.ENDS RINGO + +* cell INVX1B +* pin VDD +* pin OUT +* pin VSS +* pin +* pin IN +* pin SUBSTRATE +.SUBCKT INVX1B 1 2 3 4 5 6 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 IN +* net 6 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U +.ENDS INVX1B + +* cell INVX1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin IN +* pin SUBSTRATE +.SUBCKT INVX1 1 2 3 4 5 6 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 IN +* net 6 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U +.ENDS INVX1 + +* cell ND2X1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin B +* pin A +* pin SUBSTRATE +.SUBCKT ND2X1 1 2 3 4 5 6 7 +* net 1 VDD +* net 2 OUT +* net 3 VSS +* net 5 B +* net 6 A +* net 7 SUBSTRATE +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 2 6 1 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.3375P PS=3.85U PD=1.95U +* device instance $2 r0 *1 1.55,5.8 PMOS +M$2 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.3375P AD=0.6375P PS=1.95U PD=3.85U +* device instance $3 r0 *1 0.85,2.135 NMOS +M$3 3 6 8 7 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.21375P PS=2.75U PD=1.4U +* device instance $4 r0 *1 1.55,2.135 NMOS +M$4 8 5 2 7 NMOS L=0.25U W=0.95U AS=0.21375P AD=0.40375P PS=1.4U PD=2.75U +.ENDS ND2X1 diff --git a/testdata/lvs/ringo_layout_var.gds b/testdata/lvs/ringo_layout_var.gds new file mode 100644 index 0000000000000000000000000000000000000000..e5a18d6f95875b515405d272516106b11092fba0 GIT binary patch literal 12456 zcmeHNUx-~t9iIE|+`BiM?q(CS+3ih@S}}yBx=F;gNKMuxc4Kxo-K=37w3JdL6cG_0 zM5Opo#6KVviWDtjQP3(P#fMP(P)Z4*Pt^xo`XGI%Qqm%!57Ni3-#0VgIWza}nS0Ns zeR2=Xe#>vpcYZT-e!rP-=3JARdVSsWYW4QN%$T{u>^F6DPx!y-)U$Jo3&!kgwC+3k z(=UAW`XAoA=hX9`-T2L=HPdUA^SW7fe&yVQOY^4LF(%txH!YLhRyW4XO*S?+Hy=}h zmooJeSjQEXrLjDK$ZEm_^Ozq{c$W9FTrW5ive~;(e0^gUyB0DkSk45|n?Qff5 zBelG=a^Yy+({QBFvp=FG84));XH5NfLfI{rj1=y_iQeJi#Ksfg&K4*;u$0exRLHMA ze{n;2;ysjWY`NEON+M_SD1Ju2ieLWQ!& zd{Y{!t$(^m72?Ud!v5bPAMZ2F6hspv!ba6LBApSYh*E?JWsf6m(7!Sw%o6@DJ22>f z%>OVlrTGG)8~tc8vydr5*@310*+$++B#-SD${zDg!{p;1WfRPJ7BbCYRA>DU&$Pwm zi|g|Xrr9;7JEgU7e6oRev~J9J&-KIA`uX41*5=^#hheSH*}QgdGzM`F)?YJb7oI?z zdI@9rw*qAc+CGfgbve(W>=Sj2U1tIg zZ(fA(f?tc6ky;3seL~p}m-FeDe2d`GKlv7APw?rN{UoyA^e>b>)qnEXPa^wGzEJjI z{mc7s?JS9Y6M)_YuiszlE}=_-yysr1L*^&H2w!_Q|w=^68&E`p;4Jm>;N2 zn|{nidr|u_4~4P=!~PHOXFdO*=L=;Amhx*48MF64Xg_e~QMCVO1!ZvWurqp^4n3ROL4u|H6fB@cjys&18#y_Nd~WBR8?Z)~|eR z&3i{+agVmUSPyN`<$peY!bP7juZa1zf{!)x8DsW5<gS zr^DGftYuH&?Rk`4bG~o?0H6Ae&*{GB_(Iu%_U#Q>&pTPRG{1yhlJk?VnRDFBZeuSR zWGTkyVHLD>BP_BLqbTndD`P9+% zc|-;Bv`_aS;`?-uKOwL=)q-b4rF|QYyFFFp{knaQ%hnr+Bd?hTp9~F~>#dH?vi)ap!$R@~SFJ`lT|oc+L5z zGGrX(_E;H4@lU^_DodArR5tefHQeXTnd8j9HdbcpG2*TtV`e#0;1vF^{TFkd$CTbP zxTH&|GRBb2LfNb6Rr0AIr_We0|{n%*juh-){;o9*x7U9kN^*@2cnj$wl08%ggr-?}xuOMc^! z)yvz`yPe~MinU7n;hXCo^zuo(oT_S_T5)27>;=#6xUoyBaD4P2Kcw426j%rIOqG*v2gZ^)^pbDluM^xLfJ<@{aRZ*jfrfuwS`}dn6K5p z7?D-|e1fd%YbIIM*G#hdz8FQ{fSFU%|8Tj*ol9fY?O=$q1H-pAz~`LD=WsVho>2C_ z9aQiQ6TCUcCAP0PH7DdVeSPRZ__cwnpZ=}GgKs&$P!6%~B{~Dm| zXVZLgS;!5G?7*b|*~^Z9d(ZKOvICR+CbEmZnr}FMj2$@rAMj zll~8YNB;-jcl;b>$5&OcG~R{LJG z|0d$lV^EjmAIQ-Em*Mwu#}~>DwEQY-7I(ruw*%eQ7aQ^$eLGk`{>fb+$B(->VsM51 zPwoP_^CF+vzY83`3p>4Ze(gaxAAR2D+FE_y4)=7U`I^|kyM-^H9gEReT=&STK5vuN zH*XKbz4C+aiuVg;uaY<9GjE6`d6SGA^7!6~!BrAB?hbrQvzK^6+4Ze$c-*WmE`MbO z1JJd*cmGAleoLVS$7S1r+Rl{wE@tb-|6aV${<;f)?ys|o!t%cHQvWlHI^Tc!!&!ol zY0G@%I}x+5*4CA@wR^Zw8m^cA#KJ!J;`7mSqh5afb5T#=)Bn=PGAA!bOx3~}&*!EG z+8c83_Et4_G37+=6yu+W{wspJFt}B!%l?v5y?M z9iK?vXRtyG$@lf8{*PRDd?I;woh^`jUth|ff7S7c8MjlTfTUY;G z%uv47U=9COi=Ww|--T4+`#H5clbv2Zxp3}uq|!!e!MJNVPTJ3Sjf=Ia*);zHzFG psd, "G" => pgate, "W" => nwell, + "tS" => psd, "tD" => psd, "tG" => poly, "tW" => nwell }) + +# NMOS transistor device extraction +extract_devices(mos4("NMOS"), { "SD" => nsd, "G" => ngate, "W" => bulk, + "tS" => nsd, "tD" => nsd, "tG" => poly, "tW" => bulk }) + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, contact) +connect(nsd, contact) +connect(poly, contact) +connect(ntie, contact) +connect(nwell, ntie) +connect(ptie, contact) +connect(contact, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(ptie, "SUBSTRATE") + +# Compare section + +netlist.simplify + +# both INVX1 and INVX1B are the same schematic cell +same_circuits("INVX1", "INVX1") +same_circuits("INVX1B", "INVX1") + +compare + diff --git a/testdata/lvs/ringo_layout_var.lvsdb b/testdata/lvs/ringo_layout_var.lvsdb new file mode 100644 index 000000000..35a52028c --- /dev/null +++ b/testdata/lvs/ringo_layout_var.lvsdb @@ -0,0 +1,1076 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX1B + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23025 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-20175 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(13 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(15 name(VSS) + rect(l8 (1110 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-21741 -391) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-23700 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-20175 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(11 name(FB)) + pin(12 name(VDD)) + pin(13 name(OUT)) + pin(14 name(ENABLE)) + pin(15 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 12) + pin(1 1) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 14) + pin(6 15) + ) + circuit(2 INVX1B location(4200 0) + pin(0 12) + pin(1 2) + pin(2 15) + pin(3 12) + pin(4 1) + pin(5 15) + ) + circuit(3 INVX1 location(6000 0) + pin(0 12) + pin(1 3) + pin(2 15) + pin(3 12) + pin(4 2) + pin(5 15) + ) + circuit(4 INVX1B location(7800 0) + pin(0 12) + pin(1 4) + pin(2 15) + pin(3 12) + pin(4 3) + pin(5 15) + ) + circuit(5 INVX1 location(9600 0) + pin(0 12) + pin(1 5) + pin(2 15) + pin(3 12) + pin(4 4) + pin(5 15) + ) + circuit(6 INVX1B location(11400 0) + pin(0 12) + pin(1 6) + pin(2 15) + pin(3 12) + pin(4 5) + pin(5 15) + ) + circuit(7 INVX1 location(13200 0) + pin(0 12) + pin(1 7) + pin(2 15) + pin(3 12) + pin(4 6) + pin(5 15) + ) + circuit(8 INVX1 location(15000 0) + pin(0 12) + pin(1 8) + pin(2 15) + pin(3 12) + pin(4 7) + pin(5 15) + ) + circuit(9 INVX1 location(16800 0) + pin(0 12) + pin(1 9) + pin(2 15) + pin(3 12) + pin(4 8) + pin(5 15) + ) + circuit(10 INVX1 location(18600 0) + pin(0 12) + pin(1 10) + pin(2 15) + pin(3 12) + pin(4 9) + pin(5 15) + ) + circuit(11 INVX1 location(20400 0) + pin(0 12) + pin(1 11) + pin(2 15) + pin(3 12) + pin(4 10) + pin(5 15) + ) + circuit(12 INVX1 location(22200 0) + pin(0 12) + pin(1 13) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 15) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX1B INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(10 15 match) + net(2 7 match) + net(3 8 match) + net(4 9 match) + net(5 10 match) + net(6 11 match) + net(7 12 match) + net(8 13 match) + net(9 14 match) + net(14 4 match) + net(11 3 match) + net(13 5 match) + net(12 2 match) + net(15 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(3 3 match) + circuit(5 5 match) + circuit(7 7 match) + circuit(8 8 match) + circuit(9 9 match) + circuit(10 10 match) + circuit(11 11 match) + circuit(12 12 match) + circuit(2 2 match) + circuit(4 4 match) + circuit(6 6 match) + circuit(1 1 match) + ) + ) +) From 0bc2321ade7993d2ac83bde6f297237595826e38 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 30 Sep 2019 23:17:42 +0200 Subject: [PATCH 04/31] Some code cleanup. --- src/db/db/dbNetlistCompare.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 593810056..96682f9ef 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -489,14 +489,10 @@ public: void same_circuit (const db::Circuit *ca, const db::Circuit *cb) { // no arbitrary cross-pairing + // NOTE: many layout circuits are allowed for one schematic to account for layout alternatives. if (ca && has_cat_for (ca)) { throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + ca->name ()); } -#if 0 // can pair multiple layout cells with one schematic circuit - if (cb && has_cat_for (cb)) { - throw tl::Exception (tl::to_string (tr ("Circuit is already paired with other circuit: ")) + cb->name ()); - } -#endif generic_categorizer::same (ca, cb); } From ca747771acbde817a67ca5fcc3c46adb7845f868 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 1 Oct 2019 00:21:27 +0200 Subject: [PATCH 05/31] Allow preempt LVS configuration same_nets, equivalent_pins, same_circuits and same_device_classes can now be given at the beginning of the LVS script. This will simplify building universal scripts with the run specific part at the beginning (one "load" section). The price are somewhat less specific error messages when something fails in these methods. --- src/lvs/lvs/built-in-macros/_lvs_netter.rb | 40 ++++++++++++++++--- testdata/lvs/ringo_layout_var.lvs | 8 ++-- ...ngo_simple_net_and_circuit_equivalence.lvs | 4 +- testdata/lvs/ringo_simple_pin_swapping.lvs | 4 +- .../lvs/ringo_simple_same_device_classes.lvs | 4 +- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index 23335311b..c6317d310 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -48,6 +48,7 @@ module LVS def initialize(engine) super + @comparer_config = [] end def _make_data @@ -161,6 +162,11 @@ module LVS nl = _ensure_two_netlists lvs_data.reference = nl[1] + # execute the configuration commands + @comparer_config.each do |cc| + cc.call + end + lvs_data.compare(@comparer) end @@ -217,6 +223,12 @@ module LVS n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") end + @comparer_config << lambda { self._same_nets(ca, a, cb, b) } + + end + + def _same_nets(ca, a, cb, b) + ( nl_a, nl_b ) = _ensure_two_netlists if ca.is_a?(String) @@ -234,13 +246,13 @@ module LVS if circuit_a && circuit_b if a.is_a?(String) - net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist: #{a} (for circuit #{circuit_a})") + net_a = circuit_a.net_by_name(a) || raise("Not a valid net name in extracted netlist in 'same_nets': #{a} (for circuit #{circuit_a})") else net_a = a end if b.is_a?(String) - net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist: #{b} (for circuit #{circuit_b})") + net_b = circuit_b.net_by_name(b) || raise("Not a valid net name in extracted netlist in 'same_nets': #{b} (for circuit #{circuit_b})") else net_b = b end @@ -271,6 +283,12 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_circuits' need to be strings or nil") + @comparer_config << lambda { self._same_circuits(a, b) } + + end + + def _same_circuits(a, b) + ( nl_a, nl_b ) = _ensure_two_netlists circuit_a = a && nl_a.circuit_by_name(a) @@ -301,9 +319,15 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_device_classes' need to be strings or nil") + @comparer_config << lambda { self._same_device_classes(a, b) } + + end + + def _same_device_classes(a, b) + ( nl_a, nl_b ) = _ensure_two_netlists - dc_a = a && (nl_a.device_class_by_name(a) || raise("Not a valid device class in extracted netlist: #{a}")) + dc_a = a && (nl_a.device_class_by_name(a) || raise("Not a valid device class in extracted netlist in 'same_device_class': #{a}")) dc_b = b && nl_b.device_class_by_name(b) # NOTE: a device class is allowed to be missing in the reference netlist because the @@ -347,6 +371,12 @@ module LVS raise("All pin arguments of 'equivalent_pins' need to be strings or numbers") end + @comparer_config << lambda { self._equivalent_pins(circuit, *pins) } + + end + + def _equivalent_pins(circuit, *pins) + ( nl_a, nl_b ) = _ensure_two_netlists circuit_b = nl_b.circuit_by_name(circuit) @@ -357,9 +387,9 @@ module LVS pin_ids_b = pins.collect do |p| if p.is_a?(String) - pin = circuit_b.pin_by_name(p) || raise("Not a valid pin name in circuit '#{circuit}': #{p}") + pin = circuit_b.pin_by_name(p) || raise("Not a valid pin name in circuit '#{circuit}' in 'equivalent_pins': #{p}") else - pin = pins_by_index[p.to_i] || raise("Not a valid pin index in circuit '#{circuit}': #{p}") + pin = pins_by_index[p.to_i] || raise("Not a valid pin index in circuit '#{circuit}' in 'equivalent_pins': #{p}") end pin.id end diff --git a/testdata/lvs/ringo_layout_var.lvs b/testdata/lvs/ringo_layout_var.lvs index 4f6c718e3..afe79c3e2 100644 --- a/testdata/lvs/ringo_layout_var.lvs +++ b/testdata/lvs/ringo_layout_var.lvs @@ -5,6 +5,10 @@ report_lvs($lvs_test_target_lvsdb, true) target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") +# both INVX1 and INVX1B are the same schematic cell +same_circuits("INVX1", "INVX1") +same_circuits("INVX1B", "INVX1") + schematic("ringo.cir") deep @@ -70,9 +74,5 @@ connect_global(ptie, "SUBSTRATE") netlist.simplify -# both INVX1 and INVX1B are the same schematic cell -same_circuits("INVX1", "INVX1") -same_circuits("INVX1B", "INVX1") - compare diff --git a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs index 878c69698..7ff601882 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvs @@ -7,6 +7,9 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") schematic("ringo.cir") +# preempt configuration (see below) +same_nets("top", "ENABLE", "RINGO", "ENABLE") + deep # Drawing layers @@ -71,7 +74,6 @@ connect_global(ptie, "SUBSTRATE") same_circuits("top", "RINGO") same_circuits("INV", "INVX1") same_circuits("DOESNOTEXIST", "DOESNOTEXIST2") -same_nets("top", "ENABLE", "RINGO", "ENABLE") same_nets("DOESNOTEXIST", "ENABLE", "DOESNOTEXIST2", "ENABLE") netlist.simplify diff --git a/testdata/lvs/ringo_simple_pin_swapping.lvs b/testdata/lvs/ringo_simple_pin_swapping.lvs index dcfa49dd4..d54d3f1fa 100644 --- a/testdata/lvs/ringo_simple_pin_swapping.lvs +++ b/testdata/lvs/ringo_simple_pin_swapping.lvs @@ -7,6 +7,9 @@ target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") schematic("ringo_pin_swapping.cir") +# preempt configuration +equivalent_pins("ND2X1", 4, 5) + deep # Drawing layers @@ -68,7 +71,6 @@ connect_global(ptie, "SUBSTRATE") # Compare section -equivalent_pins("ND2X1", 4, 5) equivalent_pins("DOESNOTEXIST", 4, 5) netlist.simplify diff --git a/testdata/lvs/ringo_simple_same_device_classes.lvs b/testdata/lvs/ringo_simple_same_device_classes.lvs index 9a2bad4d1..8005d70cc 100644 --- a/testdata/lvs/ringo_simple_same_device_classes.lvs +++ b/testdata/lvs/ringo_simple_same_device_classes.lvs @@ -8,6 +8,9 @@ target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout") schematic("ringo.cir") +# preempt configuration +same_device_classes("PM", "PMOS") + deep # Drawing layers @@ -90,7 +93,6 @@ connect_global(ptie, "SUBSTRATE") netlist.simplify -same_device_classes("PM", "PMOS") same_device_classes("NM", "NMOS") same_device_classes("PMHV", "PMOSHV") same_device_classes("NMHV", "NMOSHV") From f8476bdf266d25421dc198bfafc90681c543a045 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 5 Oct 2019 09:30:38 +0200 Subject: [PATCH 06/31] Fixed an issue with 'align' in LVS scripts - with multiple layout cells assigned to one schematic, align won't give the right results. --- src/db/db/dbNetlistCompare.cc | 26 ++++----- src/db/db/dbNetlistDeviceExtractorClasses.cc | 2 + src/lvs/lvs/built-in-macros/_lvs_netter.rb | 55 ++++++++++++-------- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 96682f9ef..afbc3b41e 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -2224,39 +2224,39 @@ NetlistComparer::unmatched_circuits (db::Netlist *a, db::Netlist *b, std::vector // we need to create a copy because this method is supposed to be const. db::CircuitCategorizer circuit_categorizer = *mp_circuit_categorizer; - std::map > cat2circuits; + std::map, std::vector > > cat2circuits; for (db::Netlist::circuit_iterator i = a->begin_circuits (); i != a->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].first = i.operator-> (); + cat2circuits[cat].first.push_back (i.operator-> ()); } } for (db::Netlist::circuit_iterator i = b->begin_circuits (); i != b->end_circuits (); ++i) { size_t cat = circuit_categorizer.cat_for_circuit (i.operator-> ()); if (cat) { - cat2circuits[cat].second = i.operator-> (); + cat2circuits[cat].second.push_back (i.operator-> ()); } } size_t na = 0, nb = 0; - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first) { - ++nb; - } else if (! i->second.second) { - ++na; + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { + nb += i->second.second.size (); + } else if (i->second.second.empty ()) { + na += i->second.first.size (); } } in_a.reserve (na); in_b.reserve (nb); - for (std::map >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { - if (! i->second.first) { - in_b.push_back (i->second.second); - } else if (! i->second.second) { - in_a.push_back (i->second.first); + for (std::map, std::vector > >::const_iterator i = cat2circuits.begin (); i != cat2circuits.end (); ++i) { + if (i->second.first.empty ()) { + in_b.insert (in_b.end (), i->second.second.begin (), i->second.second.end ()); + } else if (i->second.second.empty ()) { + in_a.insert (in_a.end (), i->second.first.begin (), i->second.first.end ()); } } } diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index 01406124e..8d1a059f2 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -101,9 +101,11 @@ db::Connectivity NetlistDeviceExtractorMOS3Transistor::get_connectivity (const d // The layer definition is diff, gate db::Connectivity conn; +if (false) { // @@@ // collect all connected diffusion shapes conn.connect (sdiff, sdiff); conn.connect (ddiff, ddiff); +} // @@@ // collect all connected gate shapes conn.connect (gate, gate); // connect gate with diff to detect gate/diffusion boundary diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index c6317d310..594929da0 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -66,7 +66,6 @@ module LVS @lvs.generator = @engine._generator @l2n = @lvs - @comparer = RBA::NetlistComparer::new end @@ -121,7 +120,9 @@ module LVS nl = _ensure_two_netlists - unmatched_a = @comparer.unmatched_circuits_a(*nl) + comparer = self._comparer + + unmatched_a = comparer.unmatched_circuits_a(*nl) # check whether we're about to flatten away the internal top cell - that's bad top_cell = l2n_data.internal_top_cell.name @@ -136,7 +137,7 @@ module LVS end # flatten schematic circuits for which there is no corresponding layout cell - @comparer.unmatched_circuits_b(*nl).each do |c| + comparer.unmatched_circuits_b(*nl).each do |c| @engine.info("Flatten schematic circuit (no layout): #{c.name}") nl[1].flatten_circuit(c) end @@ -162,12 +163,20 @@ module LVS nl = _ensure_two_netlists lvs_data.reference = nl[1] + lvs_data.compare(self._comparer) + + end + + def _comparer + + comparer = RBA::NetlistComparer::new + # execute the configuration commands @comparer_config.each do |cc| - cc.call + cc.call(comparer) end - lvs_data.compare(@comparer) + return comparer end @@ -223,11 +232,11 @@ module LVS n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") end - @comparer_config << lambda { self._same_nets(ca, a, cb, b) } + @comparer_config << lambda { |comparer| self._same_nets(comparer, ca, a, cb, b) } end - def _same_nets(ca, a, cb, b) + def _same_nets(comparer, ca, a, cb, b) ( nl_a, nl_b ) = _ensure_two_netlists @@ -258,7 +267,7 @@ module LVS end if net_a && net_b - @comparer.same_nets(net_a, net_b) + comparer.same_nets(net_a, net_b) end end @@ -283,11 +292,11 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_circuits' need to be strings or nil") - @comparer_config << lambda { self._same_circuits(a, b) } + @comparer_config << lambda { |comparer| self._same_circuits(comparer, a, b) } end - def _same_circuits(a, b) + def _same_circuits(comparer, a, b) ( nl_a, nl_b ) = _ensure_two_netlists @@ -295,7 +304,7 @@ module LVS circuit_b = b && nl_b.circuit_by_name(b) if circuit_a && circuit_b - @comparer.same_circuits(circuit_a, circuit_b) + comparer.same_circuits(circuit_a, circuit_b) end end @@ -319,11 +328,11 @@ module LVS a.is_a?(String) || a == nil || b.is_a?(String) || b == nil || raise("Both arguments of 'same_device_classes' need to be strings or nil") - @comparer_config << lambda { self._same_device_classes(a, b) } + @comparer_config << lambda { |comparer| self._same_device_classes(comparer, a, b) } end - def _same_device_classes(a, b) + def _same_device_classes(comparer, a, b) ( nl_a, nl_b ) = _ensure_two_netlists @@ -333,7 +342,7 @@ module LVS # NOTE: a device class is allowed to be missing in the reference netlist because the # device may simply not be used there. if dc_b - @comparer.same_device_classes(dc_a, dc_b) + comparer.same_device_classes(dc_a, dc_b) end end @@ -371,11 +380,11 @@ module LVS raise("All pin arguments of 'equivalent_pins' need to be strings or numbers") end - @comparer_config << lambda { self._equivalent_pins(circuit, *pins) } + @comparer_config << lambda { |comparer| self._equivalent_pins(comparer, circuit, *pins) } end - def _equivalent_pins(circuit, *pins) + def _equivalent_pins(comparer, circuit, *pins) ( nl_a, nl_b ) = _ensure_two_netlists @@ -394,7 +403,7 @@ module LVS pin.id end - @comparer.equivalent_pins(circuit_b, pin_ids_b) + comparer.equivalent_pins(circuit_b, pin_ids_b) end @@ -459,7 +468,8 @@ module LVS def min_caps(value) lvs_data - @comparer.min_capacitance = value.to_f + v = value.to_f + @comparer_config << lambda { |comparer| comparer.min_capacitance = v } end # %LVS% @@ -471,7 +481,8 @@ module LVS def max_res(value) lvs_data - @comparer.max_resistance = value.to_f + v = value.to_f + @comparer_config << lambda { |comparer| comparer.max_resistance = v } end # %LVS% @@ -490,7 +501,8 @@ module LVS def max_depth(value) lvs_data - @comparer.max_depth = value.to_i + v = value.to_i + @comparer_config << lambda { |comparer| comparer.max_depth = v } end # @name max_branch_complexity @@ -511,7 +523,8 @@ module LVS def max_branch_complexity(value) lvs_data - @comparer.max_branch_complexity = value.to_i + v = value.to_i + @comparer_config << lambda { |comparer| comparer.max_branch_complexity = v } end end From 5c44a546764142d7c086cd553a7d9f4b2c58461f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 16 Oct 2019 00:49:33 +0200 Subject: [PATCH 07/31] Bugfix: don't try to extract netlist on errors --- src/drc/drc/built-in-macros/_drc_engine.rb | 10 +++++----- src/drc/drc/built-in-macros/_drc_netter.rb | 4 ++++ src/lvs/lvs/built-in-macros/_lvs_engine.rb | 4 ++-- src/lvs/lvs/built-in-macros/_lvs_netter.rb | 4 ++++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 997255a24..81c601bbc 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1461,22 +1461,22 @@ CODE end # save the netlist if required - if @target_netlist_file && @netter && @netter.l2n_data + if @target_netlist_file && @netter && @netter._l2n_data writer = @target_netlist_format || RBA::NetlistSpiceWriter::new netlist_file = _make_path(@target_netlist_file) info("Writing netlist: #{netlist_file} ..") - self.netlist.write(netlist_file, writer, @target_netlist_comment || "") + netlist.write(netlist_file, writer, @target_netlist_comment || "") end # save the netlist database if requested - if @output_l2ndb_file && @netter && @netter.l2n_data + if @output_l2ndb_file && @netter && @netter._l2n_data l2ndb_file = _make_path(@output_l2ndb_file) info("Writing netlist database: #{l2ndb_file} ..") - @netter.l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long) + @netter._l2n_data.write_l2n(l2ndb_file, !@output_l2ndb_long) end @@ -1484,7 +1484,7 @@ CODE _before_cleanup # show the data in the browser - if view && @show_l2ndb && @netter && @netter.l2n_data + if view && @show_l2ndb && @netter && @netter._l2n_data # NOTE: to prevent the netter destroying the database, we need to take it l2ndb = _take_data diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 1a7f70ef6..acf00645c 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -383,6 +383,10 @@ module DRC l2ndb end + def _l2n_data + @netlisted && self.l2n_data + end + private def cleanup diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb index b7a1dc2b7..8186eb2eb 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb @@ -43,11 +43,11 @@ module LVS def _before_cleanup # save the netlist database if requested - if @output_lvsdb_file && @netter && @netter.lvs_data && @netter.lvs_data.xref + if @output_lvsdb_file && @netter && @netter._lvs_data && @netter._lvs_data.xref lvsdb_file = _make_path(@output_lvsdb_file) info("Writing LVS database: #{lvsdb_file} ..") - @netter.lvs_data.write(lvsdb_file, !@output_lvsdb_long) + @netter._lvs_data.write(lvsdb_file, !@output_lvsdb_long) end diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index 594929da0..f04df659b 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -94,6 +94,10 @@ module LVS data end + def _lvs_data + _l2n_data && @lvs + end + # %LVS% # @name align # @brief Aligns the extracted netlist vs. the schematic From 991778f718aaa107a049dd8d5ac3bee7204dd644 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 16 Oct 2019 00:49:41 +0200 Subject: [PATCH 08/31] "breakout cells": attempt to provide a solution for SRAM Breakout cells can be specified to shortcut hierarchy evaluation for some cells. This allows treating SRAM cells as isolated entities - specifically when it comes to extracting devices. --- src/db/db/dbDeepRegion.cc | 14 +- src/db/db/dbDeepShapeStore.cc | 224 +++++++++++++++++++++++--- src/db/db/dbDeepShapeStore.h | 124 +++++++++++--- src/db/db/dbHierNetworkProcessor.cc | 29 ++-- src/db/db/dbHierNetworkProcessor.h | 8 +- src/db/db/dbHierProcessor.cc | 26 +-- src/db/db/dbHierProcessor.h | 16 +- src/db/db/dbNetlistDeviceExtractor.cc | 13 +- src/db/db/dbNetlistDeviceExtractor.h | 5 +- src/db/db/gsiDeclDbDeepShapeStore.cc | 144 +++++++++++++++++ src/db/db/gsiDeclDbRegion.cc | 4 +- 11 files changed, 515 insertions(+), 92 deletions(-) diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 78ca0ac83..7134c59d1 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -527,7 +527,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const db::BoolAndOrNotLocalOperation op (and_op); - db::local_processor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&m_deep_layer.layout ()), const_cast (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), m_deep_layer.breakout_cells (), other->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (m_deep_layer.store ()->threads ()); proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ()); @@ -1501,7 +1501,9 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), other_deep ? &other_deep->deep_layer ().layout () : const_cast (&polygons.layout ()), - other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&polygons.initial_cell ())); + other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&polygons.initial_cell ()), + m_deep_layer.breakout_cells (), + other_deep ? other_deep->deep_layer ().breakout_cells () : 0); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); @@ -1892,7 +1894,7 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to db::InteractingLocalOperation op (mode, touching, inverse); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); if (split_after) { @@ -1929,7 +1931,7 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse) cons db::InteractingWithEdgeLocalOperation op (inverse); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); if (split_after) { @@ -1968,7 +1970,7 @@ DeepRegion::pull_generic (const Region &other, int mode, bool touching) const db::PullLocalOperation op (mode, touching); - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); if (split_after) { @@ -2004,7 +2006,7 @@ DeepRegion::pull_generic (const Edges &other) const db::PullWithEdgeLocalOperation op; - db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell ()); + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell (), polygons.breakout_cells (), other_edges.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); proc.run (&op, polygons.layer (), other_edges.layer (), dl_out.layer ()); diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index db8ce5d01..726ba86eb 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -81,7 +81,6 @@ DeepLayer &DeepLayer::operator= (const DeepLayer &other) return *this; } - DeepLayer::~DeepLayer () { if (mp_store.get ()) { @@ -139,6 +138,12 @@ DeepLayer::add_from (const DeepLayer &dl) } } +const std::set * +DeepLayer::breakout_cells () const +{ + return store ()->breakout_cells (layout_index ()); +} + void DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const { @@ -251,16 +256,114 @@ struct DeepShapeStore::LayoutHolder // ---------------------------------------------------------------------------------- +DeepShapeStoreState::DeepShapeStoreState () + : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) +{ + // .. nothing yet .. +} + +void DeepShapeStoreState::set_text_enlargement (int enl) +{ + m_text_enlargement = enl; +} + +int DeepShapeStoreState::text_enlargement () const +{ + return m_text_enlargement; +} + +void DeepShapeStoreState::set_text_property_name (const tl::Variant &pn) +{ + m_text_property_name = pn; +} + +const tl::Variant & +DeepShapeStoreState::text_property_name () const +{ + return m_text_property_name; +} + +const std::set * +DeepShapeStoreState::breakout_cells (unsigned int layout_index) const +{ + const std::set &boc = (const_cast (this))->ensure_breakout_cells (layout_index); + if (boc.empty ()) { + return 0; + } else { + return &boc; + } +} + +void +DeepShapeStoreState::clear_breakout_cells (unsigned int layout_index) +{ + ensure_breakout_cells (layout_index).clear (); +} + +void +DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set &boc) +{ + ensure_breakout_cells (layout_index) = boc; +} + +void +DeepShapeStoreState::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci) +{ + ensure_breakout_cells (layout_index).insert (ci); +} + +void +DeepShapeStoreState::add_breakout_cells (unsigned int layout_index, const std::set &cc) +{ + ensure_breakout_cells (layout_index).insert (cc.begin (), cc.end ()); +} + +void +DeepShapeStoreState::set_threads (int n) +{ + m_threads = n; +} + +int +DeepShapeStoreState::threads () const +{ + return m_threads; +} + +void +DeepShapeStoreState::set_max_area_ratio (double ar) +{ + m_max_area_ratio = ar; +} + +double +DeepShapeStoreState::max_area_ratio () const +{ + return m_max_area_ratio; +} + +void +DeepShapeStoreState::set_max_vertex_count (size_t n) +{ + m_max_vertex_count = n; +} + +size_t +DeepShapeStoreState::max_vertex_count () const +{ + return m_max_vertex_count; +} + +// ---------------------------------------------------------------------------------- + static size_t s_instance_count = 0; DeepShapeStore::DeepShapeStore () - : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) { ++s_instance_count; } DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu) - : m_threads (1), m_max_area_ratio (3.0), m_max_vertex_count (16), m_text_property_name (), m_text_enlargement (-1) { ++s_instance_count; @@ -292,17 +395,17 @@ DeepLayer DeepShapeStore::create_from_flat (const db::Region ®ion, bool for_n unsigned int layer = layout ().insert_layer (); if (max_area_ratio == 0.0) { - max_area_ratio = m_max_area_ratio; + max_area_ratio = m_state.max_area_ratio (); } if (max_vertex_count == 0) { - max_vertex_count = m_max_vertex_count; + max_vertex_count = m_state.max_vertex_count (); } db::Shapes *shapes = &initial_cell ().shapes (layer); db::Box world = db::Box::world (); // The chain of operators for producing clipped and reduced polygon references - db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), m_text_enlargement, m_text_property_name); + db::PolygonReferenceHierarchyBuilderShapeReceiver refs (&layout (), text_enlargement (), text_property_name ()); db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count); // try to maintain the texts on top level - go through shape iterator @@ -399,12 +502,95 @@ const db::Cell &DeepShapeStore::const_initial_cell (unsigned int n) const void DeepShapeStore::set_text_enlargement (int enl) { - m_text_enlargement = enl; + m_state.set_text_enlargement (enl); +} + +int DeepShapeStore::text_enlargement () const +{ + return m_state.text_enlargement (); } void DeepShapeStore::set_text_property_name (const tl::Variant &pn) { - m_text_property_name = pn; + m_state.set_text_property_name (pn); +} + +const tl::Variant &DeepShapeStore::text_property_name () const +{ + return m_state.text_property_name (); +} + +const std::set * +DeepShapeStore::breakout_cells (unsigned int layout_index) const +{ + return m_state.breakout_cells (layout_index); +} + +void +DeepShapeStore::clear_breakout_cells (unsigned int layout_index) +{ + m_state.clear_breakout_cells (layout_index); +} + +void +DeepShapeStore::set_breakout_cells (unsigned int layout_index, const std::set &boc) +{ + m_state.set_breakout_cells (layout_index, boc); +} + +void +DeepShapeStore::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci) +{ + m_state.add_breakout_cell (layout_index, ci); +} + +void +DeepShapeStore::add_breakout_cells (unsigned int layout_index, const std::set &cc) +{ + m_state.add_breakout_cells (layout_index, cc); +} + +void DeepShapeStore::set_threads (int n) +{ + m_state.set_threads (n); +} + +int DeepShapeStore::threads () const +{ + return m_state.threads (); +} + +void DeepShapeStore::set_max_area_ratio (double ar) +{ + m_state.set_max_area_ratio (ar); +} + +double DeepShapeStore::max_area_ratio () const +{ + return m_state.max_area_ratio (); +} + +void DeepShapeStore::set_max_vertex_count (size_t n) +{ + m_state.set_max_vertex_count (n); +} + +size_t DeepShapeStore::max_vertex_count () const +{ + return m_state.max_vertex_count (); +} + +void DeepShapeStore::push_state () +{ + m_state_stack.push_back (m_state); +} + +void DeepShapeStore::pop_state () +{ + if (! m_state_stack.empty ()) { + m_state = m_state_stack.back (); + m_state_stack.pop_back (); + } } bool DeepShapeStore::is_valid_layout_index (unsigned int n) const @@ -429,21 +615,6 @@ size_t DeepShapeStore::instance_count () return s_instance_count; } -void DeepShapeStore::set_threads (int n) -{ - m_threads = n; -} - -void DeepShapeStore::set_max_area_ratio (double ar) -{ - m_max_area_ratio = ar; -} - -void DeepShapeStore::set_max_vertex_count (size_t n) -{ - m_max_vertex_count = n; -} - void DeepShapeStore::add_ref (unsigned int layout, unsigned int layer) { tl::MutexLocker locker (&m_lock); @@ -474,6 +645,7 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer) if ((m_layouts[layout]->refs -= 1) <= 0) { delete m_layouts[layout]; m_layouts[layout] = 0; + clear_breakout_cells (layout); } } @@ -542,10 +714,10 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator &si, double max_area_ratio, size_t max_vertex_count, const db::ICplxTrans &trans) { if (max_area_ratio == 0.0) { - max_area_ratio = m_max_area_ratio; + max_area_ratio = m_state.max_area_ratio (); } if (max_vertex_count == 0) { - max_vertex_count = m_max_vertex_count; + max_vertex_count = m_state.max_vertex_count (); } unsigned int layout_index = layout_for_iter (si, trans); @@ -557,7 +729,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator builder.set_target_layer (layer_index); // The chain of operators for producing clipped and reduced polygon references - db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, m_text_enlargement, m_text_property_name); + db::PolygonReferenceHierarchyBuilderShapeReceiver refs (& layout, text_enlargement (), text_property_name ()); db::ReducingHierarchyBuilderShapeReceiver red (&refs, max_area_ratio, max_vertex_count); db::ClippingHierarchyBuilderShapeReceiver clip (&red); diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 0a5404f35..2219e4d46 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -40,6 +40,7 @@ namespace db { class DeepShapeStore; +class DeepShapeStoreState; class Region; class Edges; @@ -132,6 +133,13 @@ public: return m_layout; } + /** + * @brief Gets the list of breakout cells if there are some + * "breakout cells" are cells which are not considered to participate in hierarchical operations, + * neither as sibling nor in parent-child relationships. + */ + const std::set *breakout_cells () const; + /** * @brief Inserts the layer into the given layout, starting from the given cell and into the given layer */ @@ -200,6 +208,52 @@ private: unsigned int m_layer; }; +/** + * @brief An object holding the state of a DeepShapeStore + */ +class DB_PUBLIC DeepShapeStoreState +{ +public: + DeepShapeStoreState (); + + void set_threads (int n); + int threads () const; + + void set_max_vertex_count (size_t n); + size_t max_vertex_count () const; + + void set_max_area_ratio (double ar); + double max_area_ratio () const; + + void set_text_property_name (const tl::Variant &pn); + const tl::Variant &text_property_name () const; + + void set_text_enlargement (int enl); + int text_enlargement () const; + + const std::set *breakout_cells (unsigned int layout_index) const; + void clear_breakout_cells (unsigned int layout_index); + void set_breakout_cells (unsigned int layout_index, const std::set &boc); + void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci); + void add_breakout_cells (unsigned int layout_index, const std::set &cc); + +private: + int m_threads; + double m_max_area_ratio; + size_t m_max_vertex_count; + tl::Variant m_text_property_name; + std::vector > m_breakout_cells; + int m_text_enlargement; + + std::set &ensure_breakout_cells (unsigned int layout_index) + { + if (m_breakout_cells.size () <= size_t (layout_index)) { + m_breakout_cells.resize (layout_index + 1, std::set ()); + } + return m_breakout_cells [layout_index]; + } +}; + struct DB_PUBLIC RecursiveShapeIteratorCompareForTargetHierarchy { bool operator () (const std::pair &a, const std::pair &b) const @@ -514,10 +568,7 @@ public: /** * @brief Gets the number of threads */ - int threads () const - { - return m_threads; - } + int threads () const; /** * @brief Sets the maximum vertex count default value @@ -531,10 +582,7 @@ public: /** * @brief Gets the maximum vertex count */ - size_t max_vertex_count () const - { - return m_max_vertex_count; - } + size_t max_vertex_count () const; /** * @brief Sets the max. area ratio for bounding box vs. polygon area @@ -548,10 +596,7 @@ public: /** * @brief Gets the max. area ratio */ - double max_area_ratio () const - { - return m_max_area_ratio; - } + double max_area_ratio () const; /** * @brief Sets the text property name @@ -566,10 +611,7 @@ public: /** * @brief Gets the text property name */ - const tl::Variant &text_property_name () const - { - return m_text_property_name; - } + const tl::Variant &text_property_name () const; /** * @brief Sets the text enlargement value @@ -584,10 +626,45 @@ public: /** * @brief Gets the text enlargement value */ - int text_enlargement () const - { - return m_text_enlargement; - } + int text_enlargement () const; + + /** + * @brief Gets the breakout cells for a given layout + * Returns 0 if there are no breakout cells for this layout. + */ + const std::set *breakout_cells (unsigned int layout_index) const; + + /** + * @brief Clears the breakout cell list for a given layout + */ + void clear_breakout_cells (unsigned int layout_index); + + /** + * @brief Sets the breakout cell list for a given layout + */ + void set_breakout_cells (unsigned int layout_index, const std::set &boc); + + /** + * @brief Adds a breakout cell for a given layout + */ + void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci); + + /** + * @brief Adds breakout cells for a given layout + */ + void add_breakout_cells (unsigned int layout_index, const std::set &cc); + + /** + * @brief Pushes the state on the state stack + * The state involves threads, max_area_ratio, max_vertex_count, the breakout cells and + * the text representation properties (enlargement, property name). + */ + void push_state (); + + /** + * @brief Pops the state (see @ref push_state) + */ + void pop_state (); private: friend class DeepLayer; @@ -614,11 +691,8 @@ private: std::map > m_layers_for_flat; std::map, size_t> m_flat_region_id; layout_map_type m_layout_map; - int m_threads; - double m_max_area_ratio; - size_t m_max_vertex_count; - tl::Variant m_text_property_name; - int m_text_enlargement; + DeepShapeStoreState m_state; + std::list m_state_stack; tl::Mutex m_lock; struct DeliveryMappingCacheKey diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index f2e88a520..6a455f3d3 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1117,11 +1117,11 @@ void hier_clusters::clear () template void -hier_clusters::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) +hier_clusters::build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells) { clear (); cell_clusters_box_converter cbc (layout, *this); - do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence); + do_build (cbc, layout, cell, shape_flags, conn, attr_equivalence, breakout_cells); } namespace @@ -1793,7 +1793,7 @@ hier_clusters::make_path (const db::Layout &layout, const db::Cell &cell, siz template void -hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence) +hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells) { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity, tl::to_string (tr ("Computing shape clusters"))); @@ -1835,7 +1835,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou todo.push_back (*c); } else { tl_assert (! todo.empty ()); - build_hier_connections_for_cells (cbc, layout, todo, conn, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress); done.insert (todo.begin (), todo.end ()); todo.clear (); todo.push_back (*c); @@ -1845,7 +1845,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou } - build_hier_connections_for_cells (cbc, layout, todo, conn, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress); } } @@ -1865,10 +1865,10 @@ hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell template void -hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, tl::RelativeProgress &progress) +hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress) { for (std::vector::const_iterator c = cells.begin (); c != cells.end (); ++c) { - build_hier_connections (cbc, layout, layout.cell (*c), conn); + build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells); ++progress; } } @@ -1950,9 +1950,14 @@ private: } +static bool is_breakout_cell (const std::set *breakout_cells, db::cell_index_type ci) +{ + return breakout_cells && breakout_cells->find (ci) != breakout_cells->end (); +} + template void -hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn) +hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells) { std::string msg = tl::to_string (tr ("Computing hierarchical clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ())); if (tl::verbosity () >= m_base_verbosity + 20) { @@ -1992,7 +1997,9 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c db::box_scanner bs (true, desc); for (std::vector::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) { - bs.insert (inst.operator-> (), 0); + if (! is_breakout_cell (breakout_cells, inst->cell_index ())) { + bs.insert (inst.operator-> (), 0); + } } bs.process (*rec, 1 /*touching*/, cibc); @@ -2026,7 +2033,9 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c } for (std::vector::const_iterator inst = inst_storage.begin (); inst != inst_storage.end (); ++inst) { - bs2.insert2 (inst.operator-> (), 0); + if (! is_breakout_cell (breakout_cells, inst->cell_index ())) { + bs2.insert2 (inst.operator-> (), 0); + } } bs2.process (*rec, 1 /*touching*/, local_cluster_box_convert (), cibc); diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 03d2df07c..dc68e1c7a 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -912,7 +912,7 @@ public: /** * @brief Builds a hierarchy of clusters from a cell hierarchy and given connectivity */ - void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0); + void build (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0, const std::set *breakout_cells = 0); /** * @brief Gets the connected clusters for a given cell @@ -951,9 +951,9 @@ public: private: void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence); - void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn); - void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, tl::RelativeProgress &progress); - void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence = 0); + void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells); + void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress); + void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells); std::map > m_per_cell_clusters; int m_base_verbosity; diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 1385deea2..30374c11d 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1046,15 +1046,21 @@ template class DB_PUBLIC local_processor_result_computation_task -local_processor::local_processor (db::Layout *layout, db::Cell *top) - : mp_subject_layout (layout), mp_intruder_layout (layout), mp_subject_top (top), mp_intruder_top (top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) +local_processor::local_processor (db::Layout *layout, db::Cell *top, const std::set *breakout_cells) + : mp_subject_layout (layout), mp_intruder_layout (layout), + mp_subject_top (top), mp_intruder_top (top), + mp_subject_breakout_cells (breakout_cells), mp_intruder_breakout_cells (breakout_cells), + m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) { // .. nothing yet .. } template -local_processor::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top) - : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), mp_subject_top (subject_top), mp_intruder_top (intruder_top), m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) +local_processor::local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_top, const std::set *subject_breakout_cells, const std::set *intruder_breakout_cells) + : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), + mp_subject_top (subject_top), mp_intruder_top (intruder_top), + mp_subject_breakout_cells (subject_breakout_cells), mp_intruder_breakout_cells (intruder_breakout_cells), + m_nthreads (0), m_max_vertex_count (0), m_area_ratio (0.0), m_base_verbosity (30), m_progress (0), mp_progress (0) { // .. nothing yet .. } @@ -1265,10 +1271,10 @@ void local_processor::compute_contexts (local_processor_contextsbegin (); !i.at_end (); ++i) { unsigned int iid = ++id; - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), iid); } - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), iid); } } @@ -1276,14 +1282,14 @@ void local_processor::compute_contexts (local_processor_contextsbegin (); !i.at_end (); ++i) { - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), ++id); } } if (intruder_cell) { for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) { - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), ++id); } } @@ -1306,7 +1312,7 @@ void local_processor::compute_contexts (local_processor_contexts rec (mp_subject_layout, contexts.subject_layer (), dist, &interactions); for (db::Cell::const_iterator i = subject_cell->begin (); !i.at_end (); ++i) { - if (! inst_bcs (i->cell_inst ()).empty ()) { + if (! inst_bcs (i->cell_inst ()).empty () && ! subject_cell_is_breakout (i->cell_index ())) { scanner.insert1 (&i->cell_inst (), 0); } } @@ -1701,7 +1707,7 @@ local_processor::compute_local_cell (const db::local_processor_conte } else if (intruder_cell) { // TODO: can we confine this search to the subject's (sized) bounding box? for (db::Cell::const_iterator i = intruder_cell->begin (); !i.at_end (); ++i) { - if (! inst_bci (i->cell_inst ()).empty ()) { + if (! inst_bci (i->cell_inst ()).empty () && ! intruder_cell_is_breakout (i->cell_index ())) { scanner.insert2 (&i->cell_inst (), ++inst_id); } } diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 6444c8753..fcef32df4 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -368,8 +368,8 @@ template class DB_PUBLIC local_processor { public: - local_processor (db::Layout *layout, db::Cell *top); - local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell); + local_processor (db::Layout *layout, db::Cell *top, const std::set *breakout_cells = 0); + local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set *subject_breakout_cells = 0, const std::set *intruder_breakout_cells = 0); void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer); void compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, unsigned int intruder_layer) const; void compute_results (local_processor_contexts &contexts, const local_operation *op, unsigned int output_layer) const; @@ -427,6 +427,8 @@ private: const db::Layout *mp_intruder_layout; db::Cell *mp_subject_top; const db::Cell *mp_intruder_top; + const std::set *mp_subject_breakout_cells; + const std::set *mp_intruder_breakout_cells; std::string m_description; unsigned int m_nthreads; size_t m_max_vertex_count; @@ -445,6 +447,16 @@ private: void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const; void compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::unordered_set &result) const; std::pair effective_instance (local_processor_contexts &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const; + + bool subject_cell_is_breakout (db::cell_index_type ci) const + { + return mp_subject_breakout_cells && mp_subject_breakout_cells->find (ci) != mp_subject_breakout_cells->end (); + } + + bool intruder_cell_is_breakout (db::cell_index_type ci) const + { + return mp_intruder_breakout_cells && mp_intruder_breakout_cells->find (ci) != mp_intruder_breakout_cells->end (); + } }; } diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index 5f1bc66c0..aa5b9f84a 100644 --- a/src/db/db/dbNetlistDeviceExtractor.cc +++ b/src/db/db/dbNetlistDeviceExtractor.cc @@ -75,7 +75,7 @@ std::string NetlistDeviceExtractorError::to_string () const // NetlistDeviceExtractor implementation NetlistDeviceExtractor::NetlistDeviceExtractor (const std::string &name) - : mp_layout (0), m_cell_index (0), m_device_scaling (1.0), mp_circuit (0) + : mp_layout (0), m_cell_index (0), mp_breakout_cells (0), m_device_scaling (1.0), mp_circuit (0) { m_name = name; m_terminal_id_propname_id = 0; @@ -184,13 +184,13 @@ void NetlistDeviceExtractor::extract (db::DeepShapeStore &dss, unsigned int layo } - extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling); + extract_without_initialize (dss.layout (layout_index), dss.initial_cell (layout_index), clusters, layers, device_scaling, dss.breakout_cells (layout_index)); } -void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling) +void NetlistDeviceExtractor::extract (db::Layout &layout, db::Cell &cell, const std::vector &layers, db::Netlist *nl, hier_clusters_type &clusters, double device_scaling, const std::set *breakout_cells) { initialize (nl); - extract_without_initialize (layout, cell, clusters, layers, device_scaling); + extract_without_initialize (layout, cell, clusters, layers, device_scaling, breakout_cells); } namespace { @@ -203,7 +203,7 @@ struct ExtractorCacheValueType { } -void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling) +void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling, const std::set *breakout_cells) { tl_assert (layers.size () == m_layer_definitions.size ()); @@ -214,6 +214,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db: m_layers = layers; mp_clusters = &clusters; m_device_scaling = device_scaling; + mp_breakout_cells = breakout_cells; // terminal properties are kept in a property with the terminal_property_name name m_terminal_id_propname_id = mp_layout->properties_repository ().prop_name_id (terminal_id_property_name ()); @@ -246,7 +247,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db: db::Connectivity device_conn = get_connectivity (layout, layers); db::hier_clusters device_clusters; - device_clusters.build (layout, cell, shape_iter_flags, device_conn); + device_clusters.build (layout, cell, shape_iter_flags, device_conn, 0, breakout_cells); tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices"))); diff --git a/src/db/db/dbNetlistDeviceExtractor.h b/src/db/db/dbNetlistDeviceExtractor.h index 5143b9c7f..e91961377 100644 --- a/src/db/db/dbNetlistDeviceExtractor.h +++ b/src/db/db/dbNetlistDeviceExtractor.h @@ -263,7 +263,7 @@ public: * * NOTE: The extractor expects "PolygonRef" type layers. */ - void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0); + void extract (Layout &layout, Cell &cell, const std::vector &layers, Netlist *netlist, hier_clusters_type &clusters, double device_scaling = 1.0, const std::set *breakout_cells = 0); /** * @brief Extracts the devices from a list of regions @@ -533,6 +533,7 @@ private: db::properties_id_type m_terminal_id_propname_id, m_device_id_propname_id, m_device_class_propname_id; hier_clusters_type *mp_clusters; db::cell_index_type m_cell_index; + const std::set *mp_breakout_cells; double m_device_scaling; db::Circuit *mp_circuit; db::DeviceClass *mp_device_class; @@ -553,7 +554,7 @@ private: */ void initialize (db::Netlist *nl); - void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling); + void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector &layers, double device_scaling, const std::set *breakout_cells); void push_new_devices (const Vector &disp_cache); void push_cached_devices (const tl::vector &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp); }; diff --git a/src/db/db/gsiDeclDbDeepShapeStore.cc b/src/db/db/gsiDeclDbDeepShapeStore.cc index 471c6fe67..085f5366e 100644 --- a/src/db/db/gsiDeclDbDeepShapeStore.cc +++ b/src/db/db/gsiDeclDbDeepShapeStore.cc @@ -22,10 +22,78 @@ #include "gsiDecl.h" #include "dbDeepShapeStore.h" +#include "tlGlobPattern.h" namespace gsi { +static void set_or_add_breakout_cells (db::DeepShapeStore *dss, const std::string &pattern, bool add, unsigned int layout_index = std::numeric_limits::max ()) +{ + // set or add for all + if (layout_index == std::numeric_limits::max ()) { + for (unsigned int l = 0; l < dss->layouts (); ++l) { + set_or_add_breakout_cells (dss, pattern, add, l); + } + return; + } + + std::set cc; + + if (! pattern.empty ()) { + tl::GlobPattern p (pattern); + const db::Layout &ly = dss->layout (layout_index); + for (db::Layout::const_iterator ci = ly.begin (); ci != ly.end (); ++ci) { + if (p.match (ly.cell_name (ci->cell_index ()))) { + cc.insert (ci->cell_index ()); + } + } + } + + if (! add) { + dss->clear_breakout_cells (layout_index); + } + if (! cc.empty ()) { + dss->add_breakout_cells (layout_index, cc); + } +} + +static void clear_breakout_cells (db::DeepShapeStore *dss) +{ + set_or_add_breakout_cells (dss, std::string (), false); +} + +static void set_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector &cc) +{ + std::set cs (cc.begin (), cc.end ()); + dss->set_breakout_cells (layout_index, cs); +} + +static void set_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, false, layout_index); +} + +static void set_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, false); +} + +static void add_breakout_cells (db::DeepShapeStore *dss, unsigned int layout_index, const std::vector &cc) +{ + std::set cs (cc.begin (), cc.end ()); + dss->add_breakout_cells (layout_index, cs); +} + +static void add_breakout_cells2 (db::DeepShapeStore *dss, unsigned int layout_index, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, true, layout_index); +} + +static void add_breakout_cells3 (db::DeepShapeStore *dss, const std::string &pattern) +{ + set_or_add_breakout_cells (dss, pattern, true); +} + Class decl_dbDeepShapeStore ("db", "DeepShapeStore", gsi::method ("instance_count", &db::DeepShapeStore::instance_count, "@hide\n" @@ -84,6 +152,82 @@ Class decl_dbDeepShapeStore ("db", "DeepShapeStore", ) + gsi::method ("text_enlargement", &db::DeepShapeStore::text_enlargement, "@brief Gets the text enlargement value.\n" + ) + + gsi::method ("clear_breakout_cells", &db::DeepShapeStore::clear_breakout_cells, gsi::arg ("layout_index"), + "@brief Clears the breakout cells\n" + "Breakout cells are a feature by which hierarchy handling can be disabled for specific cells. " + "If cells are specified as breakout cells, they don't interact with neighbor or parent cells, hence " + "are virtually isolated. Breakout cells are useful to shortcut hierarchy evaluation for cells which " + "are otherwise difficult to handle. An example are memory array cells with overlaps to their neighbors: " + "a precise handling of such cells would generate variants and the boundary of the array. Although precise, " + "this behavior leads to partial flattening and propagation of shapes. In consequence, this will also " + "result in wrong device detection in LVS applications. In such cases, these array cells can be declared " + "'breakout cells' which makes them isolated entities and variant generation does not happen.\n" + "\n" + "See also \\set_breakout_cells and \\add_breakout_cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("clear_breakout_cells", &clear_breakout_cells, + "@brief Clears the breakout cells\n" + "See the other variant of \\clear_breakout_cells for details.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"), + "@brief Sets the breakout cell list (as cell indexes) for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"), + "@brief Sets the breakout cell list (as cell name pattern) for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("set_breakout_cells", &set_breakout_cells3, gsi::arg ("pattern"), + "@brief Sets the breakout cell list (as cell name pattern) for the all layouts inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cells"), + "@brief Adds cell indexes to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cell", &add_breakout_cells, gsi::arg ("layout_index"), gsi::arg ("cell_index"), + "@brief Adds a cell indexe to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells2, gsi::arg ("layout_index"), gsi::arg ("pattern"), + "@brief Adds cells (given by a cell name pattern) to the breakout cell list for the given layout inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method_ext ("add_breakout_cells", &add_breakout_cells3, gsi::arg ("pattern"), + "@brief Adds cells (given by a cell name pattern) to the breakout cell list to all layouts inside the store\n" + "See \\clear_breakout_cells for an explanation of breakout cells.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method ("push_state", &db::DeepShapeStore::push_state, + "@brief Pushes the store's state on the state state\n" + "This will save the stores state (\\threads, \\max_vertex_count, \\max_area_ratio, breakout cells ...) on " + "the state stack. \\pop_state can be used to restore the state.\n" + "\n" + "This method has been added in version 0.26.1\n" + ) + + gsi::method ("pop_state", &db::DeepShapeStore::pop_state, + "@brief Restores the store's state on the state state\n" + "This will restore the state pushed by \\push_state.\n" + "\n" + "This method has been added in version 0.26.1\n" ), "@brief An opaque layout heap for the deep region processor\n" "\n" diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 7e60ba869..3fcc353da 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -35,6 +35,8 @@ #include "tlGlobPattern.h" #include +#include +#include namespace gsi { @@ -801,7 +803,7 @@ Class decl_Region ("db", "Region", "See \\strict_handling= for a description of this attribute.\n" "\n" "This method has been introduced in version 0.23.2." - ) + + ) + method ("min_coherence=", &db::Region::set_min_coherence, gsi::arg ("f"), "@brief Enable or disable minimum coherence\n" "If minimum coherence is set, the merge operations (explicit merge with \\merge or\n" From a3b2e3a154e8260b147374c5c2fe1d6187b72f5f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 16 Oct 2019 01:10:08 +0200 Subject: [PATCH 09/31] Bugfix for glob pattern with empty alternative. --- src/tl/tl/tlGlobPattern.cc | 34 +++++++++++++++++++++++++ src/tl/unit_tests/tlGlobPatternTests.cc | 23 +++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/tl/tl/tlGlobPattern.cc b/src/tl/tl/tlGlobPattern.cc index cf27d70cb..9e52c3f7d 100644 --- a/src/tl/tl/tlGlobPattern.cc +++ b/src/tl/tl/tlGlobPattern.cc @@ -238,6 +238,38 @@ private: GlobPatternString &operator= (const GlobPatternString &); }; +class GlobPatternEmpty + : public GlobPatternOp +{ +public: + GlobPatternEmpty () + : GlobPatternOp () + { + // .. nothing yet .. + } + + virtual GlobPatternOp *clone () const + { + GlobPatternEmpty *op = new GlobPatternEmpty (); + init_clone (op); + return op; + } + + virtual bool is_const () const + { + return next () == 0; + } + + virtual bool match (const char *s, std::vector *e) const + { + return GlobPatternOp::match (s, e); + } + +private: + GlobPatternEmpty (const GlobPatternEmpty &); + GlobPatternEmpty &operator= (const GlobPatternString &); +}; + class GlobPatternPass : public GlobPatternOp { @@ -602,6 +634,8 @@ compile_emit_alt (GlobPatternOp *&op_head, GlobPatternOp *&op, const char *&p, b GlobPatternOp *alt = compile (p, false, cs, false, true); if (alt) { alt_op->add_choice (alt); + } else { + alt_op->add_choice (new GlobPatternEmpty ()); } if (*p == ',') { ++p; diff --git a/src/tl/unit_tests/tlGlobPatternTests.cc b/src/tl/unit_tests/tlGlobPatternTests.cc index d53ef95e8..80dacc9a7 100644 --- a/src/tl/unit_tests/tlGlobPatternTests.cc +++ b/src/tl/unit_tests/tlGlobPatternTests.cc @@ -163,6 +163,7 @@ TEST(6) EXPECT_EQ (a.match ("abcg"), true); EXPECT_EQ (a.match ("adg"), true); + EXPECT_EQ (a.match ("ad"), false); EXPECT_EQ (a.match ("ag"), false); EXPECT_EQ (a.match ("abch"), false); EXPECT_EQ (a.match ("adh"), false); @@ -173,11 +174,33 @@ TEST(6) EXPECT_EQ (aa.match ("abcg"), true); EXPECT_EQ (aa.match ("adg"), true); + EXPECT_EQ (aa.match ("ad"), false); EXPECT_EQ (aa.match ("ag"), false); EXPECT_EQ (aa.match ("abch"), false); EXPECT_EQ (aa.match ("adh"), false); EXPECT_EQ (aa.match ("ah"), false); + a = tl::GlobPattern ("a{,d}g"); + + EXPECT_EQ (a.match ("abcg"), false); + EXPECT_EQ (a.match ("ad"), false); + EXPECT_EQ (a.match ("adg"), true); + EXPECT_EQ (a.match ("ag"), true); + EXPECT_EQ (a.match ("a"), false); + EXPECT_EQ (a.match ("abch"), false); + EXPECT_EQ (a.match ("adh"), false); + EXPECT_EQ (a.match ("ah"), false); + + a = tl::GlobPattern ("a{,d}"); + + EXPECT_EQ (a.match ("abcg"), false); + EXPECT_EQ (a.match ("ad"), true); + EXPECT_EQ (a.match ("adg"), false); + EXPECT_EQ (a.match ("ag"), false); + EXPECT_EQ (a.match ("a"), true); + EXPECT_EQ (a.match ("abch"), false); + EXPECT_EQ (a.match ("adh"), false); + EXPECT_EQ (a.match ("ah"), false); } TEST(7) From 9e1c8b44c7b073ad6b26cef01e746f03ad7f213a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 16 Oct 2019 18:59:38 +0200 Subject: [PATCH 10/31] Introducing cheats for LVS/device extraction/booleans --- src/drc/drc/built-in-macros/_drc_engine.rb | 102 +++++++++++++++++++++ src/lay/lay/doc/about/drc_ref_global.xml | 92 +++++++++++++++++++ src/lay/lay/doc/about/drc_ref_layer.xml | 70 ++++++++++++-- 3 files changed, 256 insertions(+), 8 deletions(-) diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 81c601bbc..1d5879673 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1120,6 +1120,108 @@ module DRC @def_source = layout.clip(*args) nil end + + # %DRC% + # @name cheat + # @brief Hierarchy cheats + # @synopsis cheat(args) { block } + # + # Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation + # for certain cells and consider their local configuration only. + # Cheats are useful for example when dealing with memory arrays. Often + # such arrays are build from unit cells and those often overlap with their + # neighbors. Now, if the hierarchical engine encounters such a situation, it + # will first analyse all these interactions (which can be expensive) and then + # it may come to the conclusion that boundary instances need to be handled + # differently than inside instances. This in turn might lead to propagation of + # shapes and in an LVS context to device externalisation: because some devices + # might have different parameters for boundary cells than for inside cells, the + # device instances can no longer be kept inside the unit cell. Specifically for + # memory arrays, this is not desired as eventually this leads to flattening + # of the whole array. + # + # The solution is to cheat: provided the unit cell is fully fledged and neighbors + # do not disturb the unit cell's configuration in critical ways, the unit cell + # can be treated as being isolated and results are put together in the usual way. + # + # Cheats can be applied on layout operations - specifically booleans - and device + # extraction operations. Cheats are only effective in \deep mode. + # + # For booleans, a cheat means that the cheating cell's boolean results are computed + # locally and are combined afterwards. A cheat is introduced this way: + # + # @code + # deep + # + # l1 = input(1, 0) + # l2 = input(2, 0) + # + # # usual booleans + # l1and2 = l1 & l2 + # + # # will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode: + # l1minus2 = cheat("UNIT_CELL) { l1 - l2 } + # @/code + # + # The cheat block can also be wrapped in do .. end statements and can return multiple + # layer objects: + # + # @code + # deep + # + # l1 = input(1, 0) + # l2 = input(2, 0) + # + # # computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL" + # l1and2, l1minus2 = cheat("UNIT_CELL) do + # [ l1 & l2, l1 - l2 ] + # end + # @/code + # + # (Technically, the cheat code block is a Ruby Proc and cannot create variables + # outside it's scope. Hence the results of this code block have to be passed + # through the "cheat" method). + # + # To apply cheats for device extraction, use the following scheme: + # + # @code + # deep + # + # poly = input(1, 0) + # active = input(2, 0) + # + # sd = active - poly + # gate = active & poly + # + # # device extraction with cheating for "UNIT_CELL": + # cheat("UNIT_CELL") do + # extract_devices(mos3("NMOS"), { "SD" => sd, "G" => gate, "tS" => sd, "tD" => sd, "tG" => poly } + # end + # @/code + # + # The argument to the cheat method is a list of cell name pattern (glob-style + # pattern). For example: + # + # @code + # cheat("UNIT_CELL*") { ... } + # cheat("UNIT_CELL1", "UNIT_CELL2") { ... } + # cheat("UNIT_CELL{1,2}") { ... } + # @/code + # + # For LVS applications, it's usually sufficient to cheat in the device extraction step. + # Cheats have been introduced in version 0.26.1. + + def cheat(*args, &block) + if _dss + _dss.push_state + args.flatten.each { |a| _dss.add_breakout_cells(a.to_s) } + ret = block.call + _dss.pop_state + else + ret = block.call + end + ret + end # make some DRCLayer methods available as functions # for the engine diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml index ef89cacdd..623d30d1e 100644 --- a/src/lay/lay/doc/about/drc_ref_global.xml +++ b/src/lay/lay/doc/about/drc_ref_global.xml @@ -92,6 +92,98 @@ cell("MACRO") l1 = input(1, 0)

+

"cheat" - Hierarchy cheats

+ +

Usage:

+
    +
  • cheat(args) { block }
  • +
+

+Hierarchy cheats can be used in deep mode to shortcut hierarchy evaluation +for certain cells and consider their local configuration only. +Cheats are useful for example when dealing with memory arrays. Often +such arrays are build from unit cells and those often overlap with their +neighbors. Now, if the hierarchical engine encounters such a situation, it +will first analyse all these interactions (which can be expensive) and then +it may come to the conclusion that boundary instances need to be handled +differently than inside instances. This in turn might lead to propagation of +shapes and in an LVS context to device externalisation: because some devices +might have different parameters for boundary cells than for inside cells, the +device instances can no longer be kept inside the unit cell. Specifically for +memory arrays, this is not desired as eventually this leads to flattening +of the whole array. +

+The solution is to cheat: provided the unit cell is fully fledged and neighbors +do not disturb the unit cell's configuration in critical ways, the unit cell +can be treated as being isolated and results are put together in the usual way. +

+Cheats can be applied on layout operations - specifically booleans - and device +extraction operations. Cheats are only effective in deep mode. +

+For booleans, a cheat means that the cheating cell's boolean results are computed +locally and are combined afterwards. A cheat is introduced this way: +

+

+deep
+
+l1 = input(1, 0)
+l2 = input(2, 0)
+
+# usual booleans
+l1and2 = l1 & l2
+
+# will compute "UNIT_CELL" isolated and everything else in normal hierarchical mode:
+l1minus2 = cheat("UNIT_CELL) { l1 - l2 }
+
+

+The cheat block can also be wrapped in do .. end statements and can return multiple +layer objects: +

+

+deep
+
+l1 = input(1, 0)
+l2 = input(2, 0)
+
+# computes both AND and NOT of l1 and l2 with cheating for "UNIT_CELL"
+l1and2, l1minus2 = cheat("UNIT_CELL) do
+[ l1 & l2, l1 - l2 ]
+end
+
+

+(Technically, the check code block is a Ruby Proc and cannot create variables +outside it's scope. Hence the results of this code block have to be passed +through the "cheat" method). +

+To apply cheats for device extraction, use the following scheme: +

+

+deep
+
+poly = input(1, 0)
+active = input(2, 0)
+
+sd = active - poly
+gate = active & poly
+
+# device extraction with cheating for "UNIT_CELL":
+cheat("UNIT_CELL") do
+extract_devices(mos3("NMOS"), { "SD" => sd, "G" => gate, "tS" => sd, "tD" => sd, "tG" => poly }
+end
+
+

+The argument to the cheat method is a list of cell name pattern (glob-style +pattern). For example: +

+

+cheat("UNIT_CELL*") { ... }
+cheat("UNIT_CELL1", "UNIT_CELL2") { ... }
+cheat("UNIT_CELL{1,2}") { ... }
+
+

+For LVS applications, it's usually sufficient to cheat in the device extraction step. +Cheats have been introduced in version 0.26.1. +

"clear_connections" - Clears all connections stored so far

Usage:

diff --git a/src/lay/lay/doc/about/drc_ref_layer.xml b/src/lay/lay/doc/about/drc_ref_layer.xml index f996764b9..fb9d591c5 100644 --- a/src/lay/lay/doc/about/drc_ref_layer.xml +++ b/src/lay/lay/doc/about/drc_ref_layer.xml @@ -735,7 +735,7 @@ This method is available for edge layers. The argument must be a polygon layer.

This method selects all shapes or regions from self which touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_interacting. @@ -1085,7 +1085,7 @@ The following image shows the effect of the "not_inside" method (input1: red, in

This method selects all shapes or regions from self which do not touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_not_interacting. @@ -1134,7 +1134,7 @@ The following image shows the effect of the "not_outside" method (input1: red, i

This method selects all shapes or regions from self which do not overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected.

The "not_overlapping" method is equivalent to the outside method. It is provided @@ -1322,7 +1322,7 @@ The following images show the effect of the overlap check (layer1: red, layer2:

This method selects all shapes or regions from self which overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It returns a new layer containing the selected shapes. A version which modifies self is select_overlapping. @@ -1372,6 +1372,60 @@ parameter is 0, special edge pairs with an area of 0 will be dropped.

  • layer.polygons?
+

"pull_inside" - Selects shapes or regions of other which are inside polygons from the this region

+ +

Usage:

+
    +
  • layer.pull_inside(other)
  • +
+

+This method selects all shapes or regions from other which are inside polygons from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_inside, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method is available for polygon layers. Other needs to be a polygon layer too. +

+

"pull_interacting" - Selects shapes or edges of other which touch or overlap shapes from the this region

+ +

Usage:

+
    +
  • layer.pull_interacting(other)
  • +
+

+This method selects all shapes or regions from other which touch or overlap shapes from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_interacting, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method will neither modify self nor other. +

+This method is available for polygon layers. Other can be an edge or polygon layer. +Edges or polygons can be selected with respect to polygons of self. +

+

"pull_overlapping" - Selects shapes or regions of other which overlap shapes from the this region

+ +

Usage:

+
    +
  • layer.pull_overlapping(other)
  • +
+

+This method selects all shapes or regions from other which overlap shapes from this +region. Unless other is in raw mode (see raw), coherent regions are selected from other, +otherwise individual shapes are selected. +

+The functionality is similar to select_overlapping, but chosing shapes from other rather +than from self. Because in deep mode the hierarchy reference comes from self, this method +provides a way to pull shapes from other to the hierarchy to self. +

+This method is available for polygon layers. Other needs to be a polygon layer too. +

"raw" - Marks a layer as raw

Usage:

@@ -1562,7 +1616,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is interacting. @@ -1595,7 +1649,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which do not touch or overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_interacting. @@ -1628,7 +1682,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which do not overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is not_overlapping. @@ -1661,7 +1715,7 @@ This method is available for polygon layers.

This method selects all shapes or regions from self which overlap shapes from the other -region. If self is in raw mode (see raw), coherent regions are selected from self, +region. Unless self is in raw mode (see raw), coherent regions are selected from self, otherwise individual shapes are selected. It modifies self to contain the selected shapes. A version which does not modify self is overlapping. From cd4516393b903d546d40b0cfd2d1aef4ffdefa42 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 17 Oct 2019 01:54:41 +0200 Subject: [PATCH 11/31] WIP: bugfix (breakout cell handling) and performance 1.) Bugfix: breakout cells also need to be handled when diving down inside the hier cluster builder 2.) Performance: cache cell interactions --- src/db/db/dbHierNetworkProcessor.cc | 127 ++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 26 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 6a455f3d3..2ecf41291 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -60,6 +60,13 @@ template void insert_transformed (db::Layout & /* shapes.insert (s.transformed (t)); } +// ------------------------------------------------------------------------------ + +static bool is_breakout_cell (const std::set *breakout_cells, db::cell_index_type ci) +{ + return breakout_cells && breakout_cells->find (ci) != breakout_cells->end (); +} + // ------------------------------------------------------------------------------ // Connectivity implementation @@ -1159,8 +1166,8 @@ public: /** * @brief Constructor */ - hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn) - : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn) + hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells) + : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn), mp_breakout_cells (breakout_cells) { mp_cell_clusters = &cell_clusters; } @@ -1180,9 +1187,7 @@ public: */ void finish (const db::Instance *i, unsigned int /*p1*/) { - if (i->size () > 1) { - add_single_inst (*i); - } + add_single_inst (*i); } /** @@ -1243,16 +1248,51 @@ public: } private: + struct InteractionKeyType + { + InteractionKeyType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21, const box_type &_box) + : ci1 (_ci1), ci2 (_ci2), t21 (_t21), box (_box) + { } + + bool operator== (const InteractionKeyType &other) const + { + return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21) && box == other.box; + } + + bool operator< (const InteractionKeyType &other) const + { + if (ci1 != other.ci1) { + return ci1 < other.ci1; + } + if (ci2 != other.ci2) { + return ci2 < other.ci2; + } + if (! t21.equal (other.t21)) { + return t21.less (other.t21); + } + if (box != other.box) { + return box < other.box; + } + return false; + } + + db::cell_index_type ci1, ci2; + db::ICplxTrans t21; + box_type box; + }; + const db::Layout *mp_layout; const db::Cell *mp_cell; db::connected_clusters *mp_cell_clusters; hier_clusters *mp_tree; const cell_clusters_box_converter *mp_cbc; const db::Connectivity *mp_conn; + const std::set *mp_breakout_cells; typedef std::list > join_set_list; std::map m_cm2join_map; join_set_list m_cm2join_sets; std::list m_ci_interactions; + std::map > > m_interaction_cache; /** * @brief Handles the cluster interactions between two instances or instance arrays @@ -1266,6 +1306,10 @@ private: */ void add_pair (const box_type &common, const db::Instance &i1, const std::vector &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2) { + if (is_breakout_cell (mp_breakout_cells, i1.cell_index ()) || is_breakout_cell (mp_breakout_cells, i2.cell_index ())) { + return; + } + box_type bb1 = (*mp_cbc) (i1.cell_index ()); box_type b1 = i1.cell_inst ().bbox (*mp_cbc).transformed (t1); @@ -1351,38 +1395,62 @@ private: db::cell_index_type ci1, const std::vector &p1, const db::ICplxTrans &t1, db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) { - const db::Cell &cell2 = mp_layout->cell (ci2); - - const db::local_clusters &cl1 = mp_tree->clusters_per_cell (ci1); - const db::local_clusters &cl2 = mp_tree->clusters_per_cell (ci2); + if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) { + return; + } db::ICplxTrans t1i = t1.inverted (); db::ICplxTrans t2i = t2.inverted (); db::ICplxTrans t21 = t1i * t2; + box_type common2 = common.transformed (t2i); + // NOTE: make_path may disturb the iteration (because of modification), hence // we first collect and then process the interactions. - std::vector > interactions; + const std::vector > *interactions; - for (typename db::local_clusters::touching_iterator i = cl1.begin_touching (common.transformed (t1i)); ! i.at_end (); ++i) { + InteractionKeyType ikey (ci1, ci2, t21, common2); - // skip the test, if this cluster doesn't interact with the whole cell2 - if (! i->interacts (cell2, t21, *mp_conn)) { - continue; - } + typename std::map > >::const_iterator ici = m_interaction_cache.find (ikey); + if (ici != m_interaction_cache.end ()) { - box_type bc1 = common & i->bbox ().transformed (t1); - for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc1.transformed (t2i)); ! j.at_end (); ++j) { + interactions = &ici->second; + + } else { + + const db::Cell &cell2 = mp_layout->cell (ci2); + + const db::local_clusters &cl1 = mp_tree->clusters_per_cell (ci1); + const db::local_clusters &cl2 = mp_tree->clusters_per_cell (ci2); + + std::vector > new_interactions; + db::ICplxTrans t12 = t2i * t1; + + for (typename db::local_clusters::touching_iterator i = cl1.begin_touching (common2.transformed (t21)); ! i.at_end (); ++i) { + + // skip the test, if this cluster doesn't interact with the whole cell2 + if (! i->interacts (cell2, t21, *mp_conn)) { + continue; + } + + box_type bc2 = (common2 & i->bbox ().transformed (t12)); + for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc2); ! j.at_end (); ++j) { + + if (i->interacts (*j, t21, *mp_conn)) { + new_interactions.push_back (std::make_pair (i->id (), j->id ())); + } - if (i->interacts (*j, t21, *mp_conn)) { - interactions.push_back (std::make_pair (i->id (), j->id ())); } } + std::vector > &out = m_interaction_cache [ikey]; + out = new_interactions; + interactions = &out; + } - for (std::vector >::const_iterator ii = interactions.begin (); ii != interactions.end (); ++ii) { + for (std::vector >::const_iterator ii = interactions->begin (); ii != interactions->end (); ++ii) { ClusterInstance k1 = make_path (ii->first, p1); ClusterInstance k2 = make_path (ii->second, p2); @@ -1427,6 +1495,10 @@ private: */ void add_single_inst (const db::Instance &i) { + if (is_breakout_cell (mp_breakout_cells, i.cell_index ())) { + return; + } + box_type bb = (*mp_cbc) (i.cell_index ()); const db::Cell &cell = mp_layout->cell (i.cell_index ()); @@ -1494,6 +1566,10 @@ private: */ void add_pair (const local_cluster &c1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2) { + if (is_breakout_cell (mp_breakout_cells, i2.cell_index ())) { + return; + } + box_type b1 = c1.bbox (); box_type bb2 = (*mp_cbc) (i2.cell_index ()); @@ -1541,6 +1617,10 @@ private: void add_single_pair (const local_cluster &c1, db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) { + if (is_breakout_cell (mp_breakout_cells, ci2)) { + return; + } + // NOTE: make_path may disturb the iteration (because of modification), hence // we first collect and then process the interactions. @@ -1950,11 +2030,6 @@ private: } -static bool is_breakout_cell (const std::set *breakout_cells, db::cell_index_type ci) -{ - return breakout_cells && breakout_cells->find (ci) != breakout_cells->end (); -} - template void hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells) @@ -1969,7 +2044,7 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c // NOTE: this is a receiver for both the child-to-child and // local to child interactions. - std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn)); + std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells)); cell_inst_clusters_box_converter cibc (cbc); // The box scanner needs pointers so we have to first store the instances From 611f62e73f7fc8643abcc1de6bd37e48fb139622 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 17 Oct 2019 22:47:43 +0200 Subject: [PATCH 12/31] Removed debug leftover code --- src/db/db/dbNetlistDeviceExtractorClasses.cc | 3 --- src/db/unit_tests/dbDeepShapeStoreTests.cc | 13 +++++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/db/db/dbNetlistDeviceExtractorClasses.cc b/src/db/db/dbNetlistDeviceExtractorClasses.cc index 8d1a059f2..20215b670 100644 --- a/src/db/db/dbNetlistDeviceExtractorClasses.cc +++ b/src/db/db/dbNetlistDeviceExtractorClasses.cc @@ -92,7 +92,6 @@ db::Connectivity NetlistDeviceExtractorMOS3Transistor::get_connectivity (const d } else { - tl_assert (layers.size () >= 4); unsigned int sdiff = layers [0]; @@ -101,11 +100,9 @@ db::Connectivity NetlistDeviceExtractorMOS3Transistor::get_connectivity (const d // The layer definition is diff, gate db::Connectivity conn; -if (false) { // @@@ // collect all connected diffusion shapes conn.connect (sdiff, sdiff); conn.connect (ddiff, ddiff); -} // @@@ // collect all connected gate shapes conn.connect (gate, gate); // connect gate with diff to detect gate/diffusion boundary diff --git a/src/db/unit_tests/dbDeepShapeStoreTests.cc b/src/db/unit_tests/dbDeepShapeStoreTests.cc index 9ef242efe..f2f8eaf91 100644 --- a/src/db/unit_tests/dbDeepShapeStoreTests.cc +++ b/src/db/unit_tests/dbDeepShapeStoreTests.cc @@ -208,3 +208,16 @@ TEST(4_FlatAndEmptyInput) EXPECT_EQ ((dr1 - dr3).to_string (), "(0,0;0,1000;1000,1000;1000,0)"); } +TEST(5_State) +{ + db::DeepShapeStore store; + + store.set_threads (4); + EXPECT_EQ (store.threads (), 4); + store.push_state (); + store.set_threads (2); + EXPECT_EQ (store.threads (), 2); + store.pop_state (); + EXPECT_EQ (store.threads (), 4); +} + From bf1800087773561d77bae331bce6a0b056b54fa6 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 18 Oct 2019 00:25:51 +0200 Subject: [PATCH 13/31] Added tests (breakout cells, LVS cheats) --- src/db/unit_tests/dbDeepRegionTests.cc | 38 + src/db/unit_tests/dbDeepShapeStoreTests.cc | 58 +- src/db/unit_tests/dbNetlistExtractorTests.cc | 195 +++++ src/lvs/unit_tests/lvsSimpleTests.cc | 5 + testdata/algo/deep_region_au26.gds | Bin 0 -> 1200 bytes testdata/algo/deep_region_l26.gds | Bin 0 -> 620 bytes testdata/algo/device_extract_au10.gds | Bin 0 -> 8894 bytes testdata/algo/device_extract_l10.gds | Bin 0 -> 3078 bytes testdata/lvs/invchain_cheat.lvs | 73 ++ testdata/lvs/invchain_cheat.lvsdb | 757 +++++++++++++++++++ testdata/lvs/invchain_for_cheat.cir | 85 +++ testdata/lvs/invchain_for_cheat.gds | Bin 0 -> 3078 bytes 12 files changed, 1204 insertions(+), 7 deletions(-) create mode 100644 testdata/algo/deep_region_au26.gds create mode 100644 testdata/algo/deep_region_l26.gds create mode 100644 testdata/algo/device_extract_au10.gds create mode 100644 testdata/algo/device_extract_l10.gds create mode 100644 testdata/lvs/invchain_cheat.lvs create mode 100644 testdata/lvs/invchain_cheat.lvsdb create mode 100644 testdata/lvs/invchain_for_cheat.cir create mode 100644 testdata/lvs/invchain_for_cheat.gds diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index e6d3b7dc3..a9f2c84dd 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -1452,6 +1452,44 @@ TEST(25_Pull) } } +TEST(26_BreakoutCells) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_l26.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + + dss.add_breakout_cell (0, ly.cell_by_name ("CHILD").second); + + db::Region r12 = r1 & r2; + db::Region r1m2 = r1 - r2; + db::Region r21 = r2 & r1; + db::Region r2m1 = r2 - r1; + + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (100, 0)), r12); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (101, 0)), r1m2); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (102, 0)), r21); + ly.insert (top_cell.cell_index (), ly.get_layer (db::LayerProperties (103, 0)), r2m1); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au26.gds"); +} + TEST(100_Integration) { db::Layout ly; diff --git a/src/db/unit_tests/dbDeepShapeStoreTests.cc b/src/db/unit_tests/dbDeepShapeStoreTests.cc index f2f8eaf91..9aadfa660 100644 --- a/src/db/unit_tests/dbDeepShapeStoreTests.cc +++ b/src/db/unit_tests/dbDeepShapeStoreTests.cc @@ -210,14 +210,58 @@ TEST(4_FlatAndEmptyInput) TEST(5_State) { - db::DeepShapeStore store; + db::DeepShapeStore store ("TOP", 0.01); + EXPECT_EQ (store.layout ().dbu (), 0.01); store.set_threads (4); EXPECT_EQ (store.threads (), 4); - store.push_state (); - store.set_threads (2); - EXPECT_EQ (store.threads (), 2); - store.pop_state (); - EXPECT_EQ (store.threads (), 4); -} + store.set_max_area_ratio (2.5); + EXPECT_EQ (store.max_area_ratio (), 2.5); + store.set_max_vertex_count (100); + EXPECT_EQ (store.max_vertex_count (), size_t (100)); + store.set_text_enlargement (5); + EXPECT_EQ (store.text_enlargement (), 5); + store.set_text_property_name (tl::Variant ("x")); + EXPECT_EQ (store.text_property_name ().to_string (), "x"); + EXPECT_EQ (store.breakout_cells (0) == 0, true); + { + std::set boc; + boc.insert (5); + store.set_breakout_cells (0, boc); + EXPECT_EQ (store.breakout_cells (0) == 0, false); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), false); + store.add_breakout_cell (0, 3); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), true); + } + + store.push_state (); + + store.set_threads (2); + store.set_max_area_ratio (1); + store.set_max_vertex_count (10); + store.set_text_enlargement (1); + store.set_text_property_name (tl::Variant ("y")); + EXPECT_EQ (store.threads (), 2); + EXPECT_EQ (store.max_area_ratio (), 1.0); + EXPECT_EQ (store.max_vertex_count (), size_t (10)); + EXPECT_EQ (store.text_enlargement (), 1); + EXPECT_EQ (store.text_property_name ().to_string (), "y"); + + store.clear_breakout_cells (0); + EXPECT_EQ (store.breakout_cells (0) == 0, true); + + store.pop_state (); + + EXPECT_EQ (store.threads (), 4); + EXPECT_EQ (store.max_area_ratio (), 2.5); + EXPECT_EQ (store.max_vertex_count (), size_t (100)); + EXPECT_EQ (store.text_enlargement (), 5); + EXPECT_EQ (store.text_property_name ().to_string (), "x"); + + EXPECT_EQ (store.breakout_cells (0) == 0, false); + EXPECT_EQ (store.breakout_cells (0)->find (5) != store.breakout_cells (0)->end (), true); + EXPECT_EQ (store.breakout_cells (0)->find (3) != store.breakout_cells (0)->end (), true); +} diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index 932334032..e04637320 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -2108,3 +2108,198 @@ TEST(9_StrictDeviceExtraction) db::compare_layouts (_this, ly, au); } + +TEST(10_DeviceExtractionWithBreakoutCells) +{ + db::Layout ly; + db::LayerMap lmap; + + unsigned int nwell = define_layer (ly, lmap, 1); + unsigned int active = define_layer (ly, lmap, 2); + unsigned int poly = define_layer (ly, lmap, 3); + unsigned int poly_lbl = define_layer (ly, lmap, 3, 1); + unsigned int diff_cont = define_layer (ly, lmap, 4); + unsigned int poly_cont = define_layer (ly, lmap, 5); + unsigned int metal1 = define_layer (ly, lmap, 6); + unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1); + unsigned int via1 = define_layer (ly, lmap, 7); + unsigned int metal2 = define_layer (ly, lmap, 8); + unsigned int metal2_lbl = define_layer (ly, lmap, 8, 1); + + { + db::LoadLayoutOptions options; + options.get_options ().layer_map = lmap; + options.get_options ().create_other_layers = false; + + std::string fn (tl::testsrc ()); + fn = tl::combine_path (fn, "testdata"); + fn = tl::combine_path (fn, "algo"); + fn = tl::combine_path (fn, "device_extract_l10.gds"); + + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly, options); + } + + db::Cell &tc = ly.cell (*ly.begin_top_down ()); + + db::DeepShapeStore dss; + dss.set_text_enlargement (1); + dss.set_text_property_name (tl::Variant ("LABEL")); + + // original layers + db::Region rnwell (db::RecursiveShapeIterator (ly, tc, nwell), dss); + db::Region ractive (db::RecursiveShapeIterator (ly, tc, active), dss); + db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss); + db::Region rpoly_lbl (db::RecursiveShapeIterator (ly, tc, poly_lbl), dss); + db::Region rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss); + db::Region rpoly_cont (db::RecursiveShapeIterator (ly, tc, poly_cont), dss); + db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss); + db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss); + db::Region rvia1 (db::RecursiveShapeIterator (ly, tc, via1), dss); + db::Region rmetal2 (db::RecursiveShapeIterator (ly, tc, metal2), dss); + db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss); + + // derived regions + + db::Region rpactive = ractive & rnwell; + db::Region rpgate = rpactive & rpoly; + db::Region rpsd = rpactive - rpgate; + + db::Region rnactive = ractive - rnwell; + db::Region rngate = rnactive & rpoly; + db::Region rnsd = rnactive - rngate; + + // return the computed layers into the original layout and write it for debugging purposes + + unsigned int lpgate = ly.insert_layer (db::LayerProperties (20, 0)); // 20/0 -> P Gate + unsigned int lngate = ly.insert_layer (db::LayerProperties (21, 0)); // 21/0 -> N Gate + unsigned int lpdiff = ly.insert_layer (db::LayerProperties (22, 0)); // 22/0 -> P Diffusion + unsigned int lndiff = ly.insert_layer (db::LayerProperties (23, 0)); // 23/0 -> N Diffusion + + rpgate.insert_into (&ly, tc.cell_index (), lpgate); + rngate.insert_into (&ly, tc.cell_index (), lngate); + rpsd.insert_into (&ly, tc.cell_index (), lpdiff); + rnsd.insert_into (&ly, tc.cell_index (), lndiff); + + // perform the extraction + + db::Netlist nl; + db::hier_clusters cl; + + db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS"); + db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS"); + + db::NetlistDeviceExtractor::input_layers dl; + + dss.push_state (); + std::set boc; + boc.insert (dss.layout (0).cell_by_name ("INV").second); + dss.set_breakout_cells (0, boc); + + dl["SD"] = &rpsd; + dl["G"] = &rpgate; + dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes + pmos_ex.extract (dss, 0, dl, nl, cl); + + dl["SD"] = &rnsd; + dl["G"] = &rngate; + dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes + nmos_ex.extract (dss, 0, dl, nl, cl); + + dss.pop_state (); + + // perform the net extraction + + db::NetlistExtractor net_ex; + + db::Connectivity conn; + // Intra-layer + conn.connect (rpsd); + conn.connect (rnsd); + conn.connect (rpoly); + conn.connect (rdiff_cont); + conn.connect (rpoly_cont); + conn.connect (rmetal1); + conn.connect (rvia1); + conn.connect (rmetal2); + // Inter-layer + conn.connect (rpsd, rdiff_cont); + conn.connect (rnsd, rdiff_cont); + conn.connect (rpoly, rpoly_cont); + conn.connect (rpoly_cont, rmetal1); + conn.connect (rdiff_cont, rmetal1); + conn.connect (rmetal1, rvia1); + conn.connect (rvia1, rmetal2); + conn.connect (rpoly, rpoly_lbl); // attaches labels + conn.connect (rmetal1, rmetal1_lbl); // attaches labels + conn.connect (rmetal2, rmetal2_lbl); // attaches labels + + // extract the nets + + net_ex.extract_nets (dss, 0, conn, nl, cl); + + // debug layers produced for nets + // 202/0 -> Active + // 203/0 -> Poly + // 204/0 -> Diffusion contacts + // 205/0 -> Poly contacts + // 206/0 -> Metal1 + // 207/0 -> Via1 + // 208/0 -> Metal2 + // 210/0 -> N source/drain + // 211/0 -> P source/drain + std::map dump_map; + dump_map [layer_of (rpsd) ] = ly.insert_layer (db::LayerProperties (210, 0)); + dump_map [layer_of (rnsd) ] = ly.insert_layer (db::LayerProperties (211, 0)); + dump_map [layer_of (rpoly) ] = ly.insert_layer (db::LayerProperties (203, 0)); + dump_map [layer_of (rdiff_cont)] = ly.insert_layer (db::LayerProperties (204, 0)); + dump_map [layer_of (rpoly_cont)] = ly.insert_layer (db::LayerProperties (205, 0)); + dump_map [layer_of (rmetal1) ] = ly.insert_layer (db::LayerProperties (206, 0)); + dump_map [layer_of (rvia1) ] = ly.insert_layer (db::LayerProperties (207, 0)); + dump_map [layer_of (rmetal2) ] = ly.insert_layer (db::LayerProperties (208, 0)); + + // write nets to layout + db::CellMapping cm = dss.cell_mapping_to_original (0, &ly, tc.cell_index ()); + dump_nets_to_layout (nl, cl, ly, dump_map, cm); + + std::string nl_au_string = + "circuit INVCHAIN ();" + " subcircuit INV3 $1 ($1=$9,$2=$7,$3=$8,$4=IN,$5=$9,$6=$6,$7=$2,$8=$6,$9=$4,$10=$3,$11=VDD,$12=VSS);" + " subcircuit INV2 $2 ($1=$8,$2=$11,$3=$9,$4=$10,$5=$8,$6=$11,$7=$3,$8=OUT,$9=$3,$10=OUT,$11=$6,$12=$5,$13=VDD,$14=VSS);" + " subcircuit INV $3 ($1=VSS,$2=VDD,$3=$11,$4=OUT,$5=$5,$6=$5,$7=$10,$8=$10);" + "end;" + "circuit INV2 ($1=$I16,$2=$I15,$3=$I14,$4=$I13,$5=$I12,$6=$I11,$7=$I10,$8=$I9,$9=$I8,$10=$I7,$11=$I6,$12=$I5,$13=$I4,$14=$I2);" + " subcircuit INV $1 ($1=$I2,$2=$I4,$3=$I14,$4=$I6,$5=$I8,$6=$I10,$7=$I16,$8=$I12);" + " subcircuit INV $2 ($1=$I2,$2=$I4,$3=$I13,$4=$I5,$5=$I7,$6=$I9,$7=$I15,$8=$I11);" + "end;" + "circuit INV ($1=$1,$2=$2,$3=$3,$4=$4,$5=$5,$6=$9,$7=$I8,$8=$I7);" + " device PMOS $1 (S=$4,G=$3,D=$2) (L=0.25,W=0.95,AS=0.79325,AD=0.26125,PS=3.57,PD=1.5);" + " device PMOS $2 (S=$2,G=$I8,D=$5) (L=0.25,W=0.95,AS=0.26125,AD=0.03325,PS=1.5,PD=1.97);" + " device NMOS $3 (S=$4,G=$3,D=$1) (L=0.25,W=0.95,AS=0.79325,AD=0.26125,PS=3.57,PD=1.5);" + " device NMOS $4 (S=$1,G=$I7,D=$9) (L=0.25,W=0.95,AS=0.26125,AD=0.03325,PS=1.5,PD=1.97);" + " subcircuit TRANS $1 ($1=$4,$2=$1,$3=$3);" + " subcircuit TRANS $2 ($1=$4,$2=$2,$3=$3);" + "end;" + "circuit TRANS ($1=$1,$2=$2,$3=$3);" + "end;" + "circuit INV3 ($1=$I17,$2=$I16,$3=$I15,$4=$I14,$5=$I12,$6=$I11,$7=$I9,$8=$I8,$9=$I7,$10=$I5,$11=$I4,$12=$I2);" + " subcircuit INV $1 ($1=$I2,$2=$I4,$3=$I15,$4=$I5,$5=$I8,$6=$I11,$7=$I17,$8=$I12);" + " subcircuit INV $2 ($1=$I2,$2=$I4,$3=$I14,$4=$I9,$5=$I7,$6=$I7,$7=$I16,$8=$I16);" + " subcircuit INV $3 ($1=$I2,$2=$I4,$3=$I16,$4=$I7,$5=$I9,$6=$I9,$7=$I14,$8=$I14);" + "end;" + ; + + // compare netlist as string + CHECKPOINT (); + db::compare_netlist (_this, nl, nl_au_string); + + // compare the collected test data + + std::string au = tl::testsrc (); + au = tl::combine_path (au, "testdata"); + au = tl::combine_path (au, "algo"); + au = tl::combine_path (au, "device_extract_au10.gds"); + + db::compare_layouts (_this, ly, au); +} diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 3df15643e..278369787 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -160,3 +160,8 @@ TEST(17_layout_variants) run_test (_this, "ringo_layout_var", "ringo_layout_var.gds"); } +TEST(18_cheats) +{ + run_test (_this, "invchain_cheat", "invchain_for_cheat.gds"); +} + diff --git a/testdata/algo/deep_region_au26.gds b/testdata/algo/deep_region_au26.gds new file mode 100644 index 0000000000000000000000000000000000000000..48204b20260ca62e1bdf4c93517e526f8e844792 GIT binary patch literal 1200 zcmbV~ze)o^5XQf3E}P>}^9RAg^nwW5i53AhMS=kZBLq9aKeca=Qo$mnU~`>5f=}QZ zh*{j)C=ZrG50Y zfBO0MebD*XO<%7DXjPVQ)?QpXE{XxWYEXh*GXQq#W%opuO~<6b;R{epSvj9;)DZqA z&qn!gjCSP9~33RbBE{JrL7YU#^9h@aJUf5p%H zCx&<*T=)I|*kWw$;OyM*Flq8e=eFoJT&Qji^KQ9ER}J?6(3RSvznIwa6d-+0f$bkr z&O6oftNR14-~FVdH23&Xlq$2j=7YcZAN_;-pUnqS>OY!_QvU_>tNZik=^S%K|CD#3 S{Rez;e)hq>^!)DrqX@r-dWysV literal 0 HcmV?d00001 diff --git a/testdata/algo/deep_region_l26.gds b/testdata/algo/deep_region_l26.gds new file mode 100644 index 0000000000000000000000000000000000000000..cc4063959904737146dbf06ee96d319b0caa5b45 GIT binary patch literal 620 zcmZQzV_;&6V31*CVt>rQ#URKa4kX!-*$f;^Y(Ab&3=AU7tagr_=HADaf3S4fp}$~u zR0x9%D;|ApY{8*GeJmUd3~ani42%qHd`t`s3_1eLK$7AA{}&TLGy{Xx3Ei-a$;H6HAq26NO^Oj{G>mI`2YV^pdiSdAX*)0id_SOhKU0e5aUJ;HntG|0Ei2@gkbI^(TzagA@qWM zARPg6A;bkpeh14HdLZPWzC(!tkY45&3=AN;X8{9))(->?69>{bLWhANaRu0XFbxWw T2_2Bo0ns1;m4}563kw4PIt)k@ literal 0 HcmV?d00001 diff --git a/testdata/algo/device_extract_au10.gds b/testdata/algo/device_extract_au10.gds new file mode 100644 index 0000000000000000000000000000000000000000..613e8b0ca8222841f361b7559dcdeec6a96ee58e GIT binary patch literal 8894 zcmc&(-D_M$6ra7jd$ZYYlekS&W201AL8R0sXsV*|W5lnUkrMXs^9zms|XVyyswml&f9z~9MVMv-^-mw4naV`VS#$X`a0clS4n z?tYEAX9>wq=oT7hL6M6#letc8h)2FNzjBTFj3T$O zF?=U;%}&0;J306|?<6C5T25Hl+aC8q6ta~KoL9OR7$MVg!ou3@t&rGBTAg-`kajRQ zZ&Bo_*#6{ZLS+m1A0yX*%@4reY*FMu_g2X8H$B7r)(rCnMGkcNKU@7#bPK0ya2I3i z6Q%07T?9owxT|oq?49Cd5=BX8ijEeYGKvqEoea+NY($9KnzTxXVB)MKk^ZV4-ruZ7)PmZOf?iYt2 zdlFmdkyZbfr+Qb9CwJAkFG}sI!_WG9zju{Q@WV%`BWnzkwYStL zTMfo_HodwdahKFwttEQF6dyW@^@0u`_fGNNJH;pcv=09KdhgKnzeq1?cFo~K_Xh6D z|E70ugdzG^&ctS0@-i<6b4Hstd5@8yL!8CBC(h4dcSe2&yEAg~H>G7yHp5dhX8O*U z&7A>H=R5i)isRsT+LBRJT0M?TSI)R*Qzgz_TeD4_j@j5zw{BM4T%nF?pus)D(68Jh z2#S25k>JY--6`){-~Kh5Yt&^U*F3vz!ymBr<9wjEl3vQQ$4c=Lonk#!hA*A3XGfgj zOXn+{u%O6O9dX0@Px}V{J$pP8zZBoUqc;3es~ub0 zlsB=U$W#71e5!!NXOvg2pvb%PIbNhk;wJkb`@(Td#BZCmpY&3ESbtvM&g0$q!B>ML1y2vx}cl49pJdf<;x0RsCEx%9SJ{o^FdG7Gs!s1G2(!N!k4qB=0Z^J(1 z3}GE-|KU}OA_w}s6|y>a$NgnOXB+w`MufH7N{xSOQRKi!j1iz0{ZWo%wp#8M_Vocj&E&p)h_uyz|Y{CkU}lgGVu z@;e3JXq$L*w)xGX`)B&XC~wX5SR1u2XDocE@+L06iTc4$QQzpNS8Cj`v-?yswg%sD z9gSU9?PcHanzu%L3Bub-*G)&Oc}F#$K!0$Z7s&B+&*6OaI<>NL)Gw_hl=Jk57pLd9y$T9d6T<6 z=jFV$%}GqW0*jo)EI+Q$x>EP6;CcKaT}K|jNT-y?FVfxR@r!h%t@u0HSfKEh-&Rp| zh1-GdneFuh)B2~sUf|SH`?9LSahz^GO-6h2d(#cv6UFZS1iwVROYlq7_yoU1Uz6aM z=;fU6WyNZriNC{->$$G${px)lzetah$1l>?XFxwy+>7JJUsT| zvZ)4!k8c>7uW!5YA9TIIyc0`HJ?6Fk^q+?>ZnWO~e2?`=ug^SF&HCC$^U~{~Q>fL{ EzszKx5dZ)H literal 0 HcmV?d00001 diff --git a/testdata/algo/device_extract_l10.gds b/testdata/algo/device_extract_l10.gds new file mode 100644 index 0000000000000000000000000000000000000000..43446a79f5d1373fbe0489d6d0c11e2abbef03d5 GIT binary patch literal 3078 zcma);&u~53kXY;)8=Y8IJ-)G(#^2l*cQ7z-- zzfzI9X$5VewejENJKo{Z14PTS?!Nl9U1P8B{MtSIc>B#8lM_^P)4ihSO&qI_A1BKB zL|(T;4tXVqh_>})!*Fqb7&bODi83FFvM-bxXHssN^>cB*;h=pU7Z}chpDi`sm~Z7{ zCX?(V?-2Wz8mGxLAAL8%nHPq$V1x4uHJ+ZIJf%E#=(|;;hy-# z+u|!V4z~2W_J|+s6kn-v(D)tI=zytFzasVOt;t*>3Tp0w2c}B#n`@SLSt}nktG!KI z`KE2_DC1xvW83j7FYNfS+$l5l7j5r0vkA;IdT^vZIv$(RfZTC$t9j+v+tz@HK3{$Txn!jGu& z>`Y?)Vm?vVH2XsK%J0NyYP^;24xrx%)(>=#V*Rj>N{xdl^Cwz8C3%>fzxK$I^GEHe zer2WPXL8T^qtgQ psd, "G" => pgate, + "tS" => psd, "tD" => psd, "tG" => poly }) + + # NMOS transistor device extraction + extract_devices(mos3("NMOS"), { "SD" => nsd, "G" => ngate, + "tS" => nsd, "tD" => nsd, "tG" => poly }) + +end + +# Define connectivity for netlist extraction + +# Inter-layer +connect(psd, diff_cont) +connect(nsd, diff_cont) +connect(poly, poly_cont) +connect(diff_cont, metal1) +connect(poly_cont, metal1) +connect(metal1, via1) +connect(via1, metal2) + +# Global +connect_global(bulk, "SUBSTRATE") + +# Compare section + +netlist.simplify + +compare + diff --git a/testdata/lvs/invchain_cheat.lvsdb b/testdata/lvs/invchain_cheat.lvsdb new file mode 100644 index 000000000..7e0338182 --- /dev/null +++ b/testdata/lvs/invchain_cheat.lvsdb @@ -0,0 +1,757 @@ +#%lvsdb-klayout +J( + W(INVCHAIN) + U(0.001) + L(l3 '3/0') + L(l6 '4/0') + L(l7 '2/0') + L(l8 '6/0') + L(l9 '7/0') + L(l10 '8/0') + L(l11) + L(l2) + L(l5) + C(l3 l3 l7) + C(l6 l6 l8 l2 l5) + C(l7 l3 l7 l8) + C(l8 l6 l7 l8 l9) + C(l9 l8 l9 l10) + C(l10 l9 l10) + C(l11 l11) + C(l2 l6 l2) + C(l5 l6 l5) + G(l11 SUBSTRATE) + D(D$PMOS PMOS + T(S + R(l2 (-960 -475) (835 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l2 (125 -475) (550 950)) + ) + ) + D(D$PMOS$1 PMOS + T(S + R(l2 (-675 -475) (550 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l2 (125 -475) (35 950)) + ) + ) + D(D$NMOS NMOS + T(S + R(l5 (-960 -475) (835 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l5 (125 -475) (550 950)) + ) + ) + D(D$NMOS$1 NMOS + T(S + R(l5 (-675 -475) (550 950)) + ) + T(G + R(l3 (-125 -475) (250 950)) + ) + T(D + R(l5 (125 -475) (35 950)) + ) + ) + X(INV + R((-1500 -800) (3000 4600)) + N(1 + R(l6 (290 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l5 (-1375 -925) (550 950)) + ) + N(2 + R(l6 (290 2490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -690) (360 760)) + R(l9 (-305 -705) (250 250)) + R(l9 (-250 150) (250 250)) + R(l10 (-2025 -775) (3000 900)) + R(l2 (-1375 -925) (550 950)) + ) + N(3 + R(l3 (-125 -250) (250 2500)) + R(l3 (-250 -3050) (250 1600)) + R(l3 (-250 1200) (250 1600)) + ) + N(4 + R(l6 (-510 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-290 -3530) (360 2840)) + R(l8 (-360 -2800) (360 760)) + R(l8 (-360 2040) (360 760)) + R(l2 (-740 -855) (835 950)) + R(l5 (-835 -3750) (835 950)) + ) + N(5 + R(l2 (925 2325) (35 950)) + ) + N(6 + R(l5 (925 -475) (35 950)) + ) + N(7) + N(8) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + D(1 D$PMOS + Y(0 2800) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 2) + ) + D(2 D$PMOS$1 + Y(800 2800) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 2) + T(G 7) + T(D 5) + ) + D(3 D$NMOS + Y(0 0) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 1) + ) + D(4 D$NMOS$1 + Y(800 0) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 1) + T(G 8) + T(D 6) + ) + ) + X(INV2 + R((0 0) (5500 4600)) + N(1) + N(2) + N(3) + N(4) + N(5) + N(6) + N(7) + N(8) + N(9) + N(10) + N(11 + R(l6 (1790 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(12 + R(l6 (3490 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(13 + R(l6 (990 3290) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(14 + R(l6 (990 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + P(9) + P(10) + P(11) + P(12) + P(13) + P(14) + X(1 INV M O(180) Y(1500 800) + P(0 14) + P(1 13) + P(2 3) + P(3 11) + P(4 9) + P(5 7) + P(6 1) + P(7 5) + ) + X(2 INV Y(4000 800) + P(0 14) + P(1 13) + P(2 4) + P(3 12) + P(4 10) + P(5 8) + P(6 2) + P(7 6) + ) + ) + X(INV3 + R((0 0) (6300 4600)) + N(1) + N(2) + N(3) + N(4) + N(5) + N(6) + N(7 + R(l6 (990 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(8) + N(9 + R(l6 (2590 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(10 + R(l6 (4290 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(11 + R(l6 (1790 3290) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(12 + R(l6 (1790 490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-3590 -690) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + P(1) + P(2) + P(3) + P(4) + P(5) + P(6) + P(7) + P(8) + P(9) + P(10) + P(11) + P(12) + X(1 INV Y(4800 800) + P(0 12) + P(1 11) + P(2 3) + P(3 10) + P(4 8) + P(5 6) + P(6 1) + P(7 5) + ) + X(2 INV Y(1500 800) + P(0 12) + P(1 11) + P(2 4) + P(3 7) + P(4 9) + P(5 9) + P(6 2) + P(7 2) + ) + X(3 INV M O(180) Y(2300 800) + P(0 12) + P(1 11) + P(2 2) + P(3 9) + P(4 7) + P(5 7) + P(6 4) + P(7 4) + ) + ) + X(INVCHAIN + R((-1500 -800) (10400 4600)) + N(1 + R(l6 (490 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(2 + R(l6 (3790 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(3 + R(l6 (1405 990) (220 220)) + R(l6 (-535 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (20 -2270) (440 520)) + ) + N(4 + R(l6 (7090 990) (220 220)) + R(l6 (-1220 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (-65 -2185) (1105 350)) + ) + N(5 + R(l6 (4705 990) (220 220)) + R(l6 (-535 -1520) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (20 -2270) (440 520)) + ) + N(6 + R(l3 (-1295 925) (1235 350)) + ) + N(7 + R(l3 (445 805) (480 550)) + ) + N(8 + R(l3 (1345 925) (1945 350)) + ) + N(9 + R(l3 (3745 805) (480 550)) + ) + N(10 + R(l3 (4645 925) (1945 350)) + ) + N(11 + R(l3 (7045 805) (480 550)) + ) + N(12 + R(l6 (7690 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 2180) (220 220)) + R(l6 (-220 180) (220 220)) + ) + N(13 + R(l6 (6890 2490) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-3520 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-6820 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (3010 -690) (360 760)) + R(l8 (-3660 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + R(l8 (-6960 -760) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + N(14 + R(l6 (6890 -310) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-3520 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-6820 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (-220 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l6 (3080 -620) (220 220)) + R(l6 (-220 180) (220 220)) + R(l8 (3010 -690) (360 760)) + R(l8 (-3660 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + R(l8 (-6960 -760) (360 760)) + R(l8 (-360 -760) (360 760)) + R(l8 (2940 -760) (360 760)) + ) + X(1 INV3 Y(-1500 -800) + P(0 9) + P(1 7) + P(2 8) + P(3 6) + P(4 9) + P(5 5) + P(6 1) + P(7 5) + P(8 3) + P(9 2) + P(10 13) + P(11 14) + ) + X(2 INV2 Y(2600 -800) + P(0 8) + P(1 11) + P(2 9) + P(3 10) + P(4 8) + P(5 11) + P(6 2) + P(7 12) + P(8 2) + P(9 12) + P(10 5) + P(11 4) + P(12 13) + P(13 14) + ) + X(3 INV M O(180) Y(7400 0) + P(0 14) + P(1 13) + P(2 11) + P(3 12) + P(4 4) + P(5 4) + P(6 10) + P(7 10) + ) + ) +) +H( + X(TRANS + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + ) + X(INV + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + D(1 PMOS + I($1) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 2) + T(B 4) + ) + D(2 PMOS + I($2) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 2) + T(G 7) + T(D 5) + T(B 2) + ) + D(3 NMOS + I($3) + E(L 0.25) + E(W 0.95) + E(AS 0.79325) + E(AD 0.26125) + E(PS 3.57) + E(PD 1.5) + T(S 4) + T(G 3) + T(D 1) + T(B 4) + ) + D(4 NMOS + I($4) + E(L 0.25) + E(W 0.95) + E(AS 0.26125) + E(AD 0.03325) + E(PS 1.5) + E(PD 1.97) + T(S 1) + T(G 8) + T(D 6) + T(B 1) + ) + X(1 TRANS I($1) + P(0 4) + P(1 1) + P(2 3) + ) + X(2 TRANS I($2) + P(0 4) + P(1 2) + P(2 3) + ) + ) + X(INV3 + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + N(9 I('9')) + N(10 I('10')) + N(11 I('11')) + N(12 I('12')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + P(9 I('9')) + P(10 I('10')) + P(11 I('11')) + P(12 I('12')) + X(1 INV I($1) + P(0 12) + P(1 11) + P(2 3) + P(3 10) + P(4 8) + P(5 6) + P(6 1) + P(7 5) + ) + X(2 INV I($2) + P(0 12) + P(1 11) + P(2 4) + P(3 7) + P(4 9) + P(5 9) + P(6 2) + P(7 2) + ) + X(3 INV I($3) + P(0 12) + P(1 11) + P(2 2) + P(3 9) + P(4 7) + P(5 7) + P(6 4) + P(7 4) + ) + ) + X(INV2 + N(1 I('1')) + N(2 I('2')) + N(3 I('3')) + N(4 I('4')) + N(5 I('5')) + N(6 I('6')) + N(7 I('7')) + N(8 I('8')) + N(9 I('9')) + N(10 I('10')) + N(11 I('11')) + N(12 I('12')) + N(13 I('13')) + N(14 I('14')) + P(1 I('1')) + P(2 I('2')) + P(3 I('3')) + P(4 I('4')) + P(5 I('5')) + P(6 I('6')) + P(7 I('7')) + P(8 I('8')) + P(9 I('9')) + P(10 I('10')) + P(11 I('11')) + P(12 I('12')) + P(13 I('13')) + P(14 I('14')) + X(1 INV I($1) + P(0 14) + P(1 13) + P(2 3) + P(3 11) + P(4 9) + P(5 7) + P(6 1) + P(7 5) + ) + X(2 INV I($2) + P(0 14) + P(1 13) + P(2 4) + P(3 12) + P(4 10) + P(5 8) + P(6 2) + P(7 6) + ) + ) + X(INVCHAIN + N(1 I('9')) + N(2 I('7')) + N(3 I('8')) + N(4 I('6')) + N(5 I('5')) + N(6 I('1')) + N(7 I('3')) + N(8 I('2')) + N(9 I('13')) + N(10 I('14')) + N(11 I('11')) + N(12 I('10')) + N(13 I('12')) + N(14 I('4')) + X(1 INV3 I($1) + P(0 1) + P(1 2) + P(2 3) + P(3 4) + P(4 1) + P(5 5) + P(6 6) + P(7 5) + P(8 7) + P(9 8) + P(10 9) + P(11 10) + ) + X(2 INV2 I($2) + P(0 3) + P(1 11) + P(2 1) + P(3 12) + P(4 3) + P(5 11) + P(6 8) + P(7 13) + P(8 8) + P(9 13) + P(10 5) + P(11 14) + P(12 9) + P(13 10) + ) + X(3 INV I($3) + P(0 10) + P(1 9) + P(2 11) + P(3 13) + P(4 14) + P(5 14) + P(6 12) + P(7 12) + ) + ) +) +Z( + X(() TRANS 0 + Z( + ) + ) + X(INV INV S + Z( + ) + ) + X(INV2 INV2 S + Z( + ) + ) + X(INV3 INV3 S + Z( + ) + ) + X(INVCHAIN INVCHAIN S + Z( + ) + ) +) diff --git a/testdata/lvs/invchain_for_cheat.cir b/testdata/lvs/invchain_for_cheat.cir new file mode 100644 index 000000000..1aae680d3 --- /dev/null +++ b/testdata/lvs/invchain_for_cheat.cir @@ -0,0 +1,85 @@ + +* cell INVCHAIN +.SUBCKT INVCHAIN +* cell instance $1 r0 *1 -1.5,-0.8 +X$1 9 7 8 6 9 5 1 5 3 2 13 14 INV3 +* cell instance $2 r0 *1 2.6,-0.8 +X$2 8 11 9 10 8 11 2 12 2 12 5 4 13 14 INV2 +* cell instance $3 m90 *1 7.4,0 +X$3 14 13 11 12 4 4 10 10 INV +.ENDS INVCHAIN + +* cell INV3 +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV3 1 2 3 4 5 6 7 8 9 10 11 12 +* cell instance $1 r0 *1 4.8,0.8 +X$1 12 11 3 10 8 6 1 5 INV +* cell instance $2 r0 *1 1.5,0.8 +X$2 12 11 4 7 9 9 2 2 INV +* cell instance $3 m90 *1 2.3,0.8 +X$3 12 11 2 9 7 7 4 4 INV +.ENDS INV3 + +* cell INV2 +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 +* cell instance $1 m90 *1 1.5,0.8 +X$1 14 13 3 11 9 7 1 5 INV +* cell instance $2 r0 *1 4,0.8 +X$2 14 13 4 12 10 8 2 6 INV +.ENDS INV2 + +* cell INV +* pin +* pin +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV 1 2 3 4 5 6 7 8 +* cell instance $1 r0 *1 0,0 +X$1 4 1 3 TRANS +* cell instance $2 r0 *1 0,2.8 +X$2 4 2 3 TRANS +* device instance $1 r0 *1 0,2.8 PMOS +M$1 4 3 2 4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U +* device instance $2 r0 *1 0.8,2.8 PMOS +M$2 2 7 5 2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U +* device instance $3 r0 *1 0,0 NMOS +M$3 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U +* device instance $4 r0 *1 0.8,0 NMOS +M$4 1 8 6 1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U +.ENDS INV + +* cell TRANS +* pin +* pin +* pin +.SUBCKT TRANS 1 2 3 +.ENDS TRANS diff --git a/testdata/lvs/invchain_for_cheat.gds b/testdata/lvs/invchain_for_cheat.gds new file mode 100644 index 0000000000000000000000000000000000000000..43446a79f5d1373fbe0489d6d0c11e2abbef03d5 GIT binary patch literal 3078 zcma);&u~53kXY;)8=Y8IJ-)G(#^2l*cQ7z-- zzfzI9X$5VewejENJKo{Z14PTS?!Nl9U1P8B{MtSIc>B#8lM_^P)4ihSO&qI_A1BKB zL|(T;4tXVqh_>})!*Fqb7&bODi83FFvM-bxXHssN^>cB*;h=pU7Z}chpDi`sm~Z7{ zCX?(V?-2Wz8mGxLAAL8%nHPq$V1x4uHJ+ZIJf%E#=(|;;hy-# z+u|!V4z~2W_J|+s6kn-v(D)tI=zytFzasVOt;t*>3Tp0w2c}B#n`@SLSt}nktG!KI z`KE2_DC1xvW83j7FYNfS+$l5l7j5r0vkA;IdT^vZIv$(RfZTC$t9j+v+tz@HK3{$Txn!jGu& z>`Y?)Vm?vVH2XsK%J0NyYP^;24xrx%)(>=#V*Rj>N{xdl^Cwz8C3%>fzxK$I^GEHe zer2WPXL8T^qtgQ Date: Sat, 19 Oct 2019 21:44:29 +0200 Subject: [PATCH 14/31] WIP: caching of cell interactions in net cluster builder for speedup - test data needs update! --- src/db/db/dbHierNetworkProcessor.cc | 190 +++++++++++++++++----------- src/db/db/dbHierNetworkProcessor.h | 43 ++++++- 2 files changed, 156 insertions(+), 77 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 2ecf41291..a497541a4 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1166,8 +1166,8 @@ public: /** * @brief Constructor */ - hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells) - : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn), mp_breakout_cells (breakout_cells) + hc_receiver (const db::Layout &layout, const db::Cell &cell, db::connected_clusters &cell_clusters, hier_clusters &tree, const cell_clusters_box_converter &cbc, const db::Connectivity &conn, const std::set *breakout_cells, typename hier_clusters::instance_interaction_cache_type *instance_interaction_cache) + : mp_layout (&layout), mp_cell (&cell), mp_tree (&tree), mp_cbc (&cbc), mp_conn (&conn), mp_breakout_cells (breakout_cells), mp_instance_interaction_cache (instance_interaction_cache) { mp_cell_clusters = &cell_clusters; } @@ -1177,9 +1177,32 @@ public: */ void add (const db::Instance *i1, unsigned int /*p1*/, const db::Instance *i2, unsigned int /*p2*/) { - std::vector p; - db::ICplxTrans t; - add_pair (box_type::world (), *i1, p, t, *i2, p, t); + db::ICplxTrans t1 = i1->complex_trans (); + db::ICplxTrans t2 = i2->complex_trans (); + db::ICplxTrans t21 = t1.inverted () * t2; + + std::list > *ic = 0; + db::ICplxTrans ic_trans; + + InstanceToInstanceInteraction ii_key (i1->cell_index (), i2->cell_index (), t21); + + instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key); + if (ii != mp_instance_interaction_cache->end ()) { + + ic = &ii->second.second; + ic_trans = t1 * ii->second.first.inverted (); + + } else { + + ic = &mp_instance_interaction_cache->insert (std::make_pair (ii_key, std::make_pair (t1, cluster_instance_pair_list_type ()))).first->second.second; + + std::vector p; + db::ICplxTrans t; + add_pair (box_type::world (), *i1, p, t, *i2, p, t, *ic); + + } + + connect_clusters (*ic, ic_trans); } /** @@ -1248,27 +1271,22 @@ public: } private: - struct InteractionKeyType + struct InteractionKeyForClustersType + : public InstanceToInstanceInteraction { - InteractionKeyType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21, const box_type &_box) - : ci1 (_ci1), ci2 (_ci2), t21 (_t21), box (_box) + InteractionKeyForClustersType (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21, const box_type &_box) + : InstanceToInstanceInteraction (_ci1, _ci2, _t21), box (_box) { } - bool operator== (const InteractionKeyType &other) const + bool operator== (const InteractionKeyForClustersType &other) const { - return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21) && box == other.box; + return InstanceToInstanceInteraction::operator== (other) && box == other.box; } - bool operator< (const InteractionKeyType &other) const + bool operator< (const InteractionKeyForClustersType &other) const { - if (ci1 != other.ci1) { - return ci1 < other.ci1; - } - if (ci2 != other.ci2) { - return ci2 < other.ci2; - } - if (! t21.equal (other.t21)) { - return t21.less (other.t21); + if (! InstanceToInstanceInteraction::operator== (other)) { + return InstanceToInstanceInteraction::operator< (other); } if (box != other.box) { return box < other.box; @@ -1276,8 +1294,6 @@ private: return false; } - db::cell_index_type ci1, ci2; - db::ICplxTrans t21; box_type box; }; @@ -1292,7 +1308,8 @@ private: std::map m_cm2join_map; join_set_list m_cm2join_sets; std::list m_ci_interactions; - std::map > > m_interaction_cache; + std::map > > m_interaction_cache_for_clusters; + instance_interaction_cache_type *mp_instance_interaction_cache; /** * @brief Handles the cluster interactions between two instances or instance arrays @@ -1304,7 +1321,7 @@ private: * @param p2 The instantiation path to the child cell (not including i2) * @param t2 The accumulated transformation of the path, not including i2 */ - void add_pair (const box_type &common, const db::Instance &i1, const std::vector &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2) + void add_pair (const box_type &common, const db::Instance &i1, const std::vector &p1, const db::ICplxTrans &t1, const db::Instance &i2, const std::vector &p2, const db::ICplxTrans &t2, std::list > &interacting_clusters) { if (is_breakout_cell (mp_breakout_cells, i1.cell_index ()) || is_breakout_cell (mp_breakout_cells, i2.cell_index ())) { return; @@ -1354,12 +1371,12 @@ private: pp2.insert (pp2.end (), p2.begin (), p2.end ()); pp2.push_back (ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ())); - add_single_pair (common12, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2); + add_single_pair (common12, i1.cell_index (), pp1, tt1, i2.cell_index (), pp2, tt2, interacting_clusters); // dive into cell of ii2 const db::Cell &cell2 = mp_layout->cell (i2.cell_index ()); for (db::Cell::touching_iterator jj2 = cell2.begin_touching (common12.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) { - add_pair (common12, i1, p1, t1, *jj2, pp2, tt2); + add_pair (common12, i1, p1, t1, *jj2, pp2, tt2, interacting_clusters); } } @@ -1373,7 +1390,7 @@ private: // dive into cell of ii1 const db::Cell &cell1 = mp_layout->cell (i1.cell_index ()); for (db::Cell::touching_iterator jj1 = cell1.begin_touching (common1.transformed (tt1.inverted ())); ! jj1.at_end (); ++jj1) { - add_pair (common1, *jj1, pp1, tt1, i2, p2, t2); + add_pair (common1, *jj1, pp1, tt1, i2, p2, t2, interacting_clusters); } } @@ -1393,7 +1410,8 @@ private: */ void add_single_pair (const box_type &common, db::cell_index_type ci1, const std::vector &p1, const db::ICplxTrans &t1, - db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) + db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2, + cluster_instance_pair_list_type &interacting_clusters) { if (is_breakout_cell (mp_breakout_cells, ci1) || is_breakout_cell (mp_breakout_cells, ci2)) { return; @@ -1409,10 +1427,10 @@ private: // we first collect and then process the interactions. const std::vector > *interactions; - InteractionKeyType ikey (ci1, ci2, t21, common2); + InteractionKeyForClustersType ikey (ci1, ci2, t21, common2); - typename std::map > >::const_iterator ici = m_interaction_cache.find (ikey); - if (ici != m_interaction_cache.end ()) { + typename std::map > >::const_iterator ici = m_interaction_cache_for_clusters.find (ikey); + if (ici != m_interaction_cache_for_clusters.end ()) { interactions = &ici->second; @@ -1444,49 +1462,14 @@ private: } - std::vector > &out = m_interaction_cache [ikey]; + std::vector > &out = m_interaction_cache_for_clusters [ikey]; out = new_interactions; interactions = &out; } for (std::vector >::const_iterator ii = interactions->begin (); ii != interactions->end (); ++ii) { - - ClusterInstance k1 = make_path (ii->first, p1); - ClusterInstance k2 = make_path (ii->second, p2); - - id_type x1 = mp_cell_clusters->find_cluster_with_connection (k1); - id_type x2 = mp_cell_clusters->find_cluster_with_connection (k2); - - if (x1 == 0) { - - if (x2 == 0) { - - id_type connector = mp_cell_clusters->insert_dummy (); - mp_cell_clusters->add_connection (connector, k1); - mp_cell_clusters->add_connection (connector, k2); - - } else { - mp_cell_clusters->add_connection (x2, k1); - } - - } else if (x2 == 0) { - - mp_cell_clusters->add_connection (x1, k2); - - } else if (x1 != x2) { - - // for instance-to-instance interactions the number of connections is more important for the - // cost of the join operation: make the one with more connections the target - if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) { - std::swap (x1, x2); - } - - mp_cell_clusters->join_cluster_with (x1, x2); - mp_cell_clusters->remove_cluster (x2); - - } - + interacting_clusters.push_back (std::make_pair (make_path (ii->first, p1), make_path (ii->second, p2))); } } @@ -1528,8 +1511,10 @@ private: std::vector pp2; pp2.push_back (ClusterInstElement (i.cell_index (), i.complex_trans (*ii2), i.prop_id ())); + cluster_instance_pair_list_type interacting_clusters; + box_type common = (ib & ib2); - add_single_pair (common, i.cell_index (), pp, tt, i.cell_index (), pp2, tt2); + add_single_pair (common, i.cell_index (), pp, tt, i.cell_index (), pp2, tt2, interacting_clusters); // dive into cell of ii2 - this is a self-interaction of a cell with parts of itself // as these self-interactions are expected to be the same always (regular array), we can skip this test the next times. @@ -1537,10 +1522,12 @@ private: for (db::Cell::touching_iterator jj2 = cell.begin_touching (common.transformed (tt2.inverted ())); ! jj2.at_end (); ++jj2) { std::vector p; db::ICplxTrans t; - add_pair (common, i, p, t, *jj2, pp2, tt2); + add_pair (common, i, p, t, *jj2, pp2, tt2, interacting_clusters); } } + connect_clusters (interacting_clusters, db::ICplxTrans ()); + any = true; } @@ -1595,6 +1582,7 @@ private: if (b1.touches (ib2) && c1.interacts (cell2, tt2, *mp_conn)) { pp2.back () = ClusterInstElement (i2.cell_index (), i2.complex_trans (*ii2), i2.prop_id ()); + add_single_pair (c1, i2.cell_index (), pp2, tt2); // dive into cell of ii2 @@ -1718,6 +1706,56 @@ private: { return mp_tree->make_path (*mp_layout, *mp_cell, id, path); } + + /** + * @brief Establishes connections between the cluster instances listed in the argument + */ + void connect_clusters (const cluster_instance_pair_list_type &interacting_clusters, const db::ICplxTrans &ic_trans) + { + for (cluster_instance_pair_list_type::const_iterator ic = interacting_clusters.begin (); ic != interacting_clusters.end (); ++ic) { + + ClusterInstance k1 = ic->first; + ClusterInstance k2 = ic->second; + + if (! ic_trans.is_unity ()) { + k1.transform (ic_trans); + k2.transform (ic_trans); + } + + id_type x1 = mp_cell_clusters->find_cluster_with_connection (k1); + id_type x2 = mp_cell_clusters->find_cluster_with_connection (k2); + + if (x1 == 0) { + + if (x2 == 0) { + + id_type connector = mp_cell_clusters->insert_dummy (); + mp_cell_clusters->add_connection (connector, k1); + mp_cell_clusters->add_connection (connector, k2); + + } else { + mp_cell_clusters->add_connection (x2, k1); + } + + } else if (x2 == 0) { + + mp_cell_clusters->add_connection (x1, k2); + + } else if (x1 != x2) { + + // for instance-to-instance interactions the number of connections is more important for the + // cost of the join operation: make the one with more connections the target + if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) { + std::swap (x1, x2); + } + + mp_cell_clusters->join_cluster_with (x1, x2); + mp_cell_clusters->remove_cluster (x2); + + } + + } + } }; template @@ -1895,6 +1933,8 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou // build the hierarchical connections bottom-up and for all cells whose children are computed already + instance_interaction_cache_type instance_interaction_cache; + { tl::SelfTimer timer (tl::verbosity () > m_base_verbosity + 10, tl::to_string (tr ("Computing hierarchical shape clusters"))); tl::RelativeProgress progress (tl::to_string (tr ("Computing hierarchical clusters")), called.size (), 1); @@ -1915,7 +1955,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou todo.push_back (*c); } else { tl_assert (! todo.empty ()); - build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); done.insert (todo.begin (), todo.end ()); todo.clear (); todo.push_back (*c); @@ -1925,7 +1965,7 @@ hier_clusters::do_build (cell_clusters_box_converter &cbc, const db::Layou } - build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress); + build_hier_connections_for_cells (cbc, layout, todo, conn, breakout_cells, progress, instance_interaction_cache); } } @@ -1945,10 +1985,10 @@ hier_clusters::build_local_cluster (const db::Layout &layout, const db::Cell template void -hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress) +hier_clusters::build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache) { for (std::vector::const_iterator c = cells.begin (); c != cells.end (); ++c) { - build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells); + build_hier_connections (cbc, layout, layout.cell (*c), conn, breakout_cells, instance_interaction_cache); ++progress; } } @@ -2032,7 +2072,7 @@ private: template void -hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells) +hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache) { std::string msg = tl::to_string (tr ("Computing hierarchical clusters for cell: ")) + std::string (layout.cell_name (cell.cell_index ())); if (tl::verbosity () >= m_base_verbosity + 20) { @@ -2044,7 +2084,7 @@ hier_clusters::build_hier_connections (cell_clusters_box_converter &cbc, c // NOTE: this is a receiver for both the child-to-child and // local to child interactions. - std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells)); + std::auto_ptr > rec (new hc_receiver (layout, cell, local, *this, cbc, conn, breakout_cells, &instance_interaction_cache)); cell_inst_clusters_box_converter cibc (cbc); // The box scanner needs pointers so we have to first store the instances diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index dc68e1c7a..3415cba35 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -33,6 +33,8 @@ #include "tlEquivalenceClusters.h" #include +#include +#include #include #include @@ -722,6 +724,42 @@ private: size_t m_id; }; +typedef std::list > cluster_instance_pair_list_type; + +/** + * @brief A helper struct to describe a pair of cell instances with a specific relative transformation + */ +struct InstanceToInstanceInteraction +{ + InstanceToInstanceInteraction (db::cell_index_type _ci1, db::cell_index_type _ci2, const db::ICplxTrans &_t21) + : ci1 (_ci1), ci2 (_ci2), t21 (_t21) + { } + + bool operator== (const InstanceToInstanceInteraction &other) const + { + return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21); + } + + bool operator< (const InstanceToInstanceInteraction &other) const + { + if (ci1 != other.ci1) { + return ci1 < other.ci1; + } + if (ci2 != other.ci2) { + return ci2 < other.ci2; + } + if (! t21.equal (other.t21)) { + return t21.less (other.t21); + } + return false; + } + + db::cell_index_type ci1, ci2; + db::ICplxTrans t21; +}; + +typedef std::map > instance_interaction_cache_type; + template class hier_clusters; template class connected_clusters; @@ -895,6 +933,7 @@ class DB_PUBLIC hier_clusters { public: typedef typename local_cluster::box_type box_type; + typedef std::map > instance_interaction_cache_type; /** * @brief Creates an empty set of clusters @@ -951,8 +990,8 @@ public: private: void build_local_cluster (const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence); - void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells); - void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress); + void build_hier_connections (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, const db::Connectivity &conn, const std::set *breakout_cells, instance_interaction_cache_type &instance_interaction_cache); + void build_hier_connections_for_cells (cell_clusters_box_converter &cbc, const db::Layout &layout, const std::vector &cells, const db::Connectivity &conn, const std::set *breakout_cells, tl::RelativeProgress &progress, instance_interaction_cache_type &instance_interaction_cache); void do_build (cell_clusters_box_converter &cbc, const db::Layout &layout, const db::Cell &cell, db::ShapeIterator::flags_type shape_flags, const db::Connectivity &conn, const tl::equivalence_clusters *attr_equivalence, const std::set *breakout_cells); std::map > m_per_cell_clusters; From f0635589f7c3affc3f7d0975a5b83d45e1f1d72c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 20 Oct 2019 23:24:36 +0200 Subject: [PATCH 15/31] WIP: fixed cell cluster interaction cache. --- src/db/db/dbHierNetworkProcessor.cc | 35 +++++++++++++++++------------ src/db/db/dbHierNetworkProcessor.h | 8 +++++++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index a497541a4..4ab81f142 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1181,28 +1181,33 @@ public: db::ICplxTrans t2 = i2->complex_trans (); db::ICplxTrans t21 = t1.inverted () * t2; - std::list > *ic = 0; - db::ICplxTrans ic_trans; - InstanceToInstanceInteraction ii_key (i1->cell_index (), i2->cell_index (), t21); instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key); if (ii != mp_instance_interaction_cache->end ()) { - ic = &ii->second.second; - ic_trans = t1 * ii->second.first.inverted (); + db::ICplxTrans ic_trans = t1 * ii->second.first.inverted (); + connect_clusters (ii->second.second, &ic_trans, i1->prop_id (), i2->prop_id ()); } else { - ic = &mp_instance_interaction_cache->insert (std::make_pair (ii_key, std::make_pair (t1, cluster_instance_pair_list_type ()))).first->second.second; + std::list > &ic = mp_instance_interaction_cache->insert (std::make_pair (ii_key, std::make_pair (t1, cluster_instance_pair_list_type ()))).first->second.second; std::vector p; db::ICplxTrans t; - add_pair (box_type::world (), *i1, p, t, *i2, p, t, *ic); + add_pair (box_type::world (), *i1, p, t, *i2, p, t, ic); + +#if 1 + // For debugging: ensures the instance properties are configured properly (important for cache consistency) + for (cluster_instance_pair_list_type::const_iterator i = ic.begin (); i != ic.end (); ++i) { + tl_assert (i->first.inst_prop_id () == i1->prop_id ()); + tl_assert (i->second.inst_prop_id () == i2->prop_id ()); + } +#endif + + connect_clusters (ic); } - - connect_clusters (*ic, ic_trans); } /** @@ -1526,7 +1531,7 @@ private: } } - connect_clusters (interacting_clusters, db::ICplxTrans ()); + connect_clusters (interacting_clusters); any = true; @@ -1710,16 +1715,18 @@ private: /** * @brief Establishes connections between the cluster instances listed in the argument */ - void connect_clusters (const cluster_instance_pair_list_type &interacting_clusters, const db::ICplxTrans &ic_trans) + void connect_clusters (const cluster_instance_pair_list_type &interacting_clusters, const db::ICplxTrans *ic_trans = 0, db::properties_id_type prop_id1 = 0, db::properties_id_type prop_id2 = 0) { for (cluster_instance_pair_list_type::const_iterator ic = interacting_clusters.begin (); ic != interacting_clusters.end (); ++ic) { ClusterInstance k1 = ic->first; ClusterInstance k2 = ic->second; - if (! ic_trans.is_unity ()) { - k1.transform (ic_trans); - k2.transform (ic_trans); + if (ic_trans) { + k1.transform (*ic_trans); + k1.set_inst_prop_id (prop_id1); + k2.transform (*ic_trans); + k2.set_inst_prop_id (prop_id2); } id_type x1 = mp_cell_clusters->find_cluster_with_connection (k1); diff --git a/src/db/db/dbHierNetworkProcessor.h b/src/db/db/dbHierNetworkProcessor.h index 3415cba35..a47e93bd8 100644 --- a/src/db/db/dbHierNetworkProcessor.h +++ b/src/db/db/dbHierNetworkProcessor.h @@ -610,6 +610,14 @@ public: return m_inst_prop_id; } + /** + * @brief Sets the instance properties id + */ + void set_inst_prop_id (db::properties_id_type pid) + { + m_inst_prop_id = pid; + } + /** * @brief Transform with the given transformation */ From 36ee1efe167245722f8f71a1bf06f65f4d3f89e8 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 21 Oct 2019 22:14:36 +0200 Subject: [PATCH 16/31] WIP: speedup LVS 'align' by flattening top-down --- src/db/db/dbNetlist.cc | 24 +++++++++++++++++++ src/db/db/dbNetlist.h | 6 +++++ src/db/db/gsiDeclDbNetlist.cc | 14 ++++++----- src/lvs/lvs/built-in-macros/_lvs_netter.rb | 7 +++--- testdata/ruby/dbNetlist.rb | 27 +++++++++++++++------- 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 98e8a089e..62056542c 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -380,6 +380,30 @@ void Netlist::purge_circuit (Circuit *circuit) remove_circuit (circuit); } +void Netlist::flatten_circuits (const std::vector &circuits) +{ + if (circuits.empty ()) { + return; + } + + std::set circuits_set (circuits.begin (), circuits.end ()); + + std::vector to_flatten; + to_flatten.reserve (circuits.size ()); + + // Before flatten, we sort top-down. This optimizes for the case of flattening away + // some hierarchy above a certain circuit. + for (top_down_circuit_iterator c = begin_top_down (); c != end_top_down (); ++c) { + if (circuits_set.find (c.operator-> ()) != circuits_set.end ()) { + to_flatten.push_back (c.operator-> ()); + } + } + + for (std::vector::const_iterator c = to_flatten.begin (); c != to_flatten.end (); ++c) { + flatten_circuit (*c); + } +} + void Netlist::flatten_circuit (Circuit *circuit) { tl_assert (circuit != 0); diff --git a/src/db/db/dbNetlist.h b/src/db/db/dbNetlist.h index 760fa381f..ff961036b 100644 --- a/src/db/db/dbNetlist.h +++ b/src/db/db/dbNetlist.h @@ -174,6 +174,12 @@ public: */ void flatten_circuit (Circuit *circuit); + /** + * @brief Flattens the given circuits + * This is basically equivalent to calling flatten on all given circuits, but more efficient. + */ + void flatten_circuits (const std::vector &circuits); + /** * @brief Flattens the netlist */ diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index 899925c45..85f985571 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -1345,7 +1345,7 @@ static void read_netlist (db::Netlist *nl, const std::string &file, db::NetlistR static void flatten_circuit_by_name (db::Netlist *nl, const std::string &name_pattern) { - std::list > circuits_to_flatten; + std::vector circuits_to_flatten; tl::GlobPattern pat (name_pattern); for (db::Netlist::circuit_iterator c = nl->begin_circuits (); c != nl->end_circuits (); ++c) { if (pat.match (c->name ())) { @@ -1353,11 +1353,7 @@ static void flatten_circuit_by_name (db::Netlist *nl, const std::string &name_pa } } - for (std::list >::iterator c = circuits_to_flatten.begin (); c != circuits_to_flatten.end (); ++c) { - if (c->get ()) { - nl->flatten_circuit (c->get ()); - } - } + nl->flatten_circuits (circuits_to_flatten); } static void blank_circuit_by_name (db::Netlist *nl, const std::string &name_pattern) @@ -1399,6 +1395,12 @@ Class decl_dbNetlist ("db", "Netlist", "@brief Flattens all circuits of the netlist\n" "After calling this method, only the top circuits will remain." ) + + gsi::method ("flatten_circuits", &db::Netlist::flatten_circuits, + "@brief Flattens all given circuits of the netlist\n" + "This method is equivalent to calling \\flatten_circuit for all given circuits, but more efficient.\n" + "\n" + "This method has been introduced in version 0.26.1" + ) + gsi::method ("flatten_circuit", &db::Netlist::flatten_circuit, gsi::arg ("circuit"), "@brief Flattens a subcircuit\n" "This method will substitute all instances (subcircuits) of the given circuit by it's " diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index f04df659b..41c639a04 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -137,14 +137,15 @@ module LVS # flatten layout cells for which there is no corresponding schematic circuit unmatched_a.each do |c| @engine.info("Flatten layout cell (no schematic): #{c.name}") - nl[0].flatten_circuit(c) end + nl[0].flatten_circuits(unmatched_a) # flatten schematic circuits for which there is no corresponding layout cell - comparer.unmatched_circuits_b(*nl).each do |c| + unmatched_b = comparer.unmatched_circuits_b(*nl) + unmatched_b.each do |c| @engine.info("Flatten schematic circuit (no layout): #{c.name}") - nl[1].flatten_circuit(c) end + nl[1].flatten_circuits(unmatched_b) end diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index 3609096b1..1a391a0ba 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -841,25 +841,36 @@ end; END nl3 = nl2.dup - nl2.flatten_circuit(nl2.circuit_by_name("PTRANS")) - nl2.flatten_circuit(nl2.circuit_by_name("NTRANS")) + nl3.flatten_circuit(nl3.circuit_by_name("NTRANS")) + nl3.flatten_circuit(nl3.circuit_by_name("PTRANS")) - assert_equal(nl2.to_s, <<"END") + assert_equal(nl3.to_s, <<"END") circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5); device PMOS $1 (S=$5,G=IN,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); - device PMOS $2 (S=$5,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); - device NMOS $3 (S=$4,G=IN,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); - device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); + device NMOS $2 (S=$4,G=IN,D=$2) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); + device NMOS $3 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); + device PMOS $4 (S=$5,G=$2,D=OUT) (L=0.25,W=0.95,AS=0,AD=0,PS=0,PD=0); end; END - nl3.flatten_circuit("{N,P}TRANS") - assert_equal(nl3.to_s, nl2.to_s) + nl4 = nl2.dup + nl4.flatten_circuit("{P,N}TRANS") + assert_equal(nl4.to_s, nl3.to_s) + + nl4 = nl2.dup + nl4.flatten_circuits([ nl4.circuit_by_name("PTRANS"), nl4.circuit_by_name("NTRANS") ]) + assert_equal(nl4.to_s, nl3.to_s) nl2 = nl.dup nl2.flatten_circuit("*") # smoke test assert_equal(nl2.to_s, "") + nl2 = nl.dup + cc = [] + nl2.each_circuit { |c| cc << c } + nl2.flatten_circuits(cc) + assert_equal(nl2.to_s, "") + end def test_12_BlankAndPurgeCircuits From 4ce37160d57195a7dd1decdd3820e3c23fcb5870 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 23 Oct 2019 23:46:25 +0200 Subject: [PATCH 17/31] Two bug fixes in net compare (tests required): - name compare of net names wasn't always case insensitive - tentative evaluation was sometimes continued even after a contradiction was detected because the return codes of different edge examinations were not combined correctly. --- src/db/db/dbNetlistCompare.cc | 27 ++++++++++++++++++---- src/lvs/lvs/built-in-macros/_lvs_netter.rb | 4 ---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index afbc3b41e..d51a4b33c 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -32,7 +32,7 @@ // verbose debug output // TODO: make this a feature? -// #define PRINT_DEBUG_NETCOMPARE +#define PRINT_DEBUG_NETCOMPARE // verbose net graph output // TODO: make this a feature? @@ -1561,6 +1561,9 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr if (tentative) { if (nodes.size () != other_nodes.size ()) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif return std::numeric_limits::max (); } @@ -1568,6 +1571,9 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr if (nodes.size () > 1 || other_nodes.size () > 1) { for (size_t i = 0; i < nodes.size (); ++i) { if (! (*nodes[i] == *other_nodes[i])) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif return std::numeric_limits::max (); } } @@ -1582,6 +1588,9 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr if (bt_count == std::numeric_limits::max ()) { if (tentative) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected branch."; +#endif return bt_count; } } else { @@ -1617,6 +1626,8 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc #if defined(PRINT_DEBUG_NETCOMPARE) if (! tentative) { tl::info << indent(depth) << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); + } else { + tl::info << indent(depth) << "tentatively deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); } #endif @@ -1661,7 +1672,15 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc ++ee_other; } - new_nodes += derive_node_identities_for_edges (e, ee, e_other, ee_other, net_index, other_net_index, depth, n_branch, tentative, with_ambiguous, data); + 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::max ()) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair."; +#endif + return bt_count; + } else { + new_nodes += bt_count; + } } @@ -1686,7 +1705,7 @@ namespace { bool operator() (const NetGraphNode *a, const NetGraphNode *b) const { tl_assert (a->net () && b->net ()); - return a->net ()->name () < b->net ()->name (); + return name_compare (a->net ()->name (), b->net ()->name ()) < 0; } }; @@ -1747,7 +1766,7 @@ static bool net_names_are_different (const db::Net *a, const db::Net *b) if (! a || ! b || a->name ().empty () || b->name ().empty ()) { return false; } else { - return (a->name () != b->name ()); + return name_compare (a->name (), b->name ()) != 0; } } diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index 41c639a04..ca5fcf5fa 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -472,7 +472,6 @@ module LVS # with a capacitance values below the given threshold (in Farad). def min_caps(value) - lvs_data v = value.to_f @comparer_config << lambda { |comparer| comparer.min_capacitance = v } end @@ -485,7 +484,6 @@ module LVS # with a resistance value above the given threshold (in Farad). def max_res(value) - lvs_data v = value.to_f @comparer_config << lambda { |comparer| comparer.max_resistance = v } end @@ -505,7 +503,6 @@ module LVS # as the seeds for this deduction path. The default value is 8. def max_depth(value) - lvs_data v = value.to_i @comparer_config << lambda { |comparer| comparer.max_depth = v } end @@ -527,7 +524,6 @@ module LVS # complexity. def max_branch_complexity(value) - lvs_data v = value.to_i @comparer_config << lambda { |comparer| comparer.max_branch_complexity = v } end From 3a8d5d97794b67b147b93491a905257e048f09f5 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 23 Oct 2019 23:49:03 +0200 Subject: [PATCH 18/31] Removed debug code. --- src/db/db/dbNetlistCompare.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index d51a4b33c..fe8d42481 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -32,7 +32,7 @@ // verbose debug output // TODO: make this a feature? -#define PRINT_DEBUG_NETCOMPARE +// #define PRINT_DEBUG_NETCOMPARE // verbose net graph output // TODO: make this a feature? From ac479c30bc41a0288a796ff78da811504d0024c4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 24 Oct 2019 00:23:03 +0200 Subject: [PATCH 19/31] Fixed unit tests. --- src/db/unit_tests/dbNetlistCompareTests.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 7d2443e95..ca749198d 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -2605,8 +2605,8 @@ TEST(17_InherentlyAmbiguousDecoder) "match_nets NQ1 NQ1\n" "match_nets NQ2 NQ2\n" "match_nets NQ3 NQ3\n" - "match_ambiguous_nets NA NA\n" - "match_ambiguous_nets NB NB\n" + "match_nets NA NA\n" + "match_nets NB NB\n" "match_nets B B\n" "match_nets A A\n" "match_pins $0 $1\n" From 373a3db1ec719058d5927e608e8170e6ba28b607 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 24 Oct 2019 23:58:30 +0200 Subject: [PATCH 20/31] WIP: netlist comparer - increase default depth and added test The test is specific for symmetric circuits with manifold symmetry axes. --- src/db/db/dbNetlistCompare.cc | 4 +- src/db/unit_tests/dbNetlistCompareTests.cc | 207 +++++++++++++++++++++ 2 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index fe8d42481..e6f282df5 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -2166,8 +2166,8 @@ NetlistComparer::NetlistComparer (NetlistCompareLogger *logger) m_cap_threshold = -1.0; // not set m_res_threshold = -1.0; // not set - m_max_depth = 8; - m_max_n_branch = 100; + m_max_depth = 50; + m_max_n_branch = 500; m_dont_consider_net_names = false; } diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index ca749198d..22f61046a 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -2796,3 +2796,210 @@ TEST(18_ClockTree) EXPECT_EQ (good, true); } +TEST(19_SymmetricCircuit) +{ + // Test test requires a certain depth, name sensitivity to resolve ambiguities and + // tests the backtracking paths. + + const char *nls1 = + "circuit DECODE (VDD=VDD,nn1_=nn1_,nn1=nn1,q0=q0,q0_=q0_,q1_=q1_,q1=q1,nn2=nn2,nn2_=nn2_,a0=a0,a0_=a0_,g1=g1,g0=g0,gtp=gtp,VSS=VSS,WELL=$14);" + " device PMOS4 $1 (S=VDD,G=$44,D=q1_,B=VDD) (L=1.2,W=7);" + " device PMOS4 $2 (S=q1_,G=$44,D=q1,B=VDD) (L=1.2,W=7);" + " device PMOS4 $3 (S=q1,G=$44,D=VDD,B=VDD) (L=1.2,W=7);" + " device PMOS4 $4 (S=VDD,G=$44,D=q0,B=VDD) (L=1.2,W=7);" + " device PMOS4 $5 (S=q0,G=$44,D=q0_,B=VDD) (L=1.2,W=7);" + " device PMOS4 $6 (S=q0_,G=$44,D=VDD,B=VDD) (L=1.2,W=7);" + " device PMOS4 $7 (S=q0_,G=$11,D=nn2_,B=VDD) (L=1.2,W=5);" + " device PMOS4 $8 (S=nn2_,G=$13,D=q1_,B=VDD) (L=1.2,W=5);" + " device PMOS4 $9 (S=VDD,G=g0,D=$39,B=VDD) (L=1.2,W=3);" + " device PMOS4 $10 (S=$39,G=g1,D=VDD,B=VDD) (L=1.2,W=3);" + " device PMOS4 $11 (S=VDD,G=a0_,D=$11,B=VDD) (L=1.2,W=10);" + " device PMOS4 $12 (S=$11,G=$44,D=VDD,B=VDD) (L=1.2,W=10);" + " device PMOS4 $13 (S=q0,G=$11,D=nn2,B=VDD) (L=1.2,W=5);" + " device PMOS4 $14 (S=nn1_,G=$13,D=$9,B=$14) (L=1.2,W=11);" + " device PMOS4 $15 (S=$4,G=$11,D=nn1_,B=$14) (L=1.2,W=11);" + " device PMOS4 $16 (S=VDD,G=$44,D=$13,B=VDD) (L=1.2,W=10);" + " device PMOS4 $17 (S=$13,G=a0,D=VDD,B=VDD) (L=1.2,W=10);" + " device PMOS4 $18 (S=$6,G=$11,D=nn1,B=$14) (L=1.2,W=11);" + " device PMOS4 $19 (S=nn1,G=$13,D=$8,B=$14) (L=1.2,W=11);" + " device PMOS4 $20 (S=VDD,G=$41,D=$44,B=VDD) (L=1.2,W=15);" + " device PMOS4 $21 (S=nn2,G=$13,D=q1,B=VDD) (L=1.2,W=5);" + " device PMOS4 $22 (S=VDD,G=$39,D=$37,B=VDD) (L=1.2,W=6);" + " device PMOS4 $23 (S=VDD,G=$42,D=$41,B=VDD) (L=1.2,W=3);" + " device PMOS4 $24 (S=gtp,G=$39,D=$42,B=VDD) (L=1.2,W=16);" + " device NMOS4 $25 (S=$44,G=$41,D=VSS,B=VSS) (L=1.2,W=22);" + " device NMOS4 $26 (S=VSS,G=$39,D=$37,B=VSS) (L=1.2,W=9);" + " device NMOS4 $27 (S=q0_,G=$6,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 $28 (S=VSS,G=$8,D=q1_,B=VSS) (L=1.2,W=1);" + " device NMOS4 $29 (S=$13,G=$44,D=$35,B=VSS) (L=1.2,W=19);" + " device NMOS4 $30 (S=$35,G=a0,D=VSS,B=VSS) (L=1.2,W=19);" + " device NMOS4 $31 (S=gtp,G=$37,D=$42,B=VSS) (L=1.2,W=16);" + " device NMOS4 $32 (S=VSS,G=$39,D=$42,B=VSS) (L=1.2,W=20);" + " device NMOS4 $33 (S=VSS,G=$4,D=q0,B=VSS) (L=1.2,W=1);" + " device NMOS4 $34 (S=VSS,G=$11,D=$6,B=VSS) (L=1.2,W=18);" + " device NMOS4 $35 (S=$9,G=$13,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 $36 (S=VSS,G=$11,D=$4,B=VSS) (L=1.2,W=18);" + " device NMOS4 $37 (S=q1,G=$9,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 $38 (S=$8,G=$13,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 $39 (S=VSS,G=a0_,D=$34,B=VSS) (L=1.2,W=19);" + " device NMOS4 $40 (S=$34,G=$44,D=$11,B=VSS) (L=1.2,W=19);" + " device NMOS4 $41 (S=VSS,G=g0,D=$40,B=VSS) (L=1.2,W=17);" + " device NMOS4 $42 (S=$40,G=g1,D=$39,B=VSS) (L=1.2,W=17);" + " device NMOS4 $43 (S=VSS,G=$42,D=$41,B=VSS) (L=1.2,W=2);" + "end;" + ; + + const char *nls2 = + "circuit DECODE (A0=A0,A0_=A0_,Q0=Q0,Q0_=Q0_,Q1=Q1,Q1_=Q1_,NN2=NN2,NN2_=NN2_,NN1=NN1,NN1_=NN1_,G0=G0,G1=G1,NN3=NN3,VDD=VDD,VSS=VSS,WELL=WELL);" + " device NMOS4 '0' (S=HNET44,G=A0,D=VSS,B=VSS) (L=1.2,W=19);" + " device NMOS4 '1' (S=CS1,G=YI,D=HNET44,B=VSS) (L=1.2,W=19);" + " device PMOS4 '10' (S=VDD,G=G0,D=NET194,B=VDD) (L=1.2,W=3);" + " device PMOS4 '11' (S=VDD,G=G1,D=NET194,B=VDD) (L=1.2,W=3);" + " device NMOS4 '12' (S=NET200,G=CS0,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 '13' (S=VSS,G=CS1,D=NET175,B=VSS) (L=1.2,W=18);" + " device NMOS4 '14' (S=VSS,G=CS0,D=NET181,B=VSS) (L=1.2,W=18);" + " device NMOS4 '15' (S=NET215,G=CS1,D=VSS,B=VSS) (L=1.2,W=18);" + " device NMOS4 '16' (S=Q1,G=NET175,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 '17' (S=VSS,G=NET200,D=Q0,B=VSS) (L=1.2,W=1);" + " device NMOS4 '18' (S=Q0_,G=NET181,D=VSS,B=VSS) (L=1.2,W=1);" + " device NMOS4 '19' (S=VSS,G=NET215,D=Q1_,B=VSS) (L=1.2,W=1);" + " device PMOS4 '2' (S=VDD,G=A0,D=CS1,B=VDD) (L=1.2,W=10);" + " device NMOS4 '20' (S=NET189,G=NET193,D=NN3,B=VSS) (L=1.2,W=16);" + " device NMOS4 '21' (S=VSS,G=NET194,D=NET189,B=VSS) (L=1.2,W=20);" + " device PMOS4 '22' (S=VDD,G=NET194,D=NET193,B=VDD) (L=1.2,W=6);" + " device NMOS4 '23' (S=NET193,G=NET194,D=VSS,B=VSS) (L=1.2,W=9);" + " device PMOS4 '24' (S=VDD,G=NET189,D=WL1_EN_,B=VDD) (L=1.2,W=3);" + " device NMOS4 '25' (S=WL1_EN_,G=NET189,D=VSS,B=VSS) (L=1.2,W=2);" + " device PMOS4 '26' (S=VDD,G=WL1_EN_,D=YI,B=VDD) (L=1.2,W=15);" + " device NMOS4 '27' (S=YI,G=WL1_EN_,D=VSS,B=VSS) (L=1.2,W=22);" + " device PMOS4 '28' (S=NN1_,G=CS0,D=NET200,B=WELL) (L=1.2,W=11);" + " device PMOS4 '29' (S=NET175,G=CS1,D=NN1_,B=WELL) (L=1.2,W=11);" + " device PMOS4 '3' (S=VDD,G=YI,D=CS1,B=VDD) (L=1.2,W=10);" + " device PMOS4 '30' (S=NET181,G=CS0,D=NN1,B=WELL) (L=1.2,W=11);" + " device PMOS4 '31' (S=Q1,G=CS1,D=NN2,B=VDD) (L=1.2,W=5);" + " device PMOS4 '32' (S=NN2,G=CS0,D=Q0,B=VDD) (L=1.2,W=5);" + " device PMOS4 '33' (S=NN1,G=CS1,D=NET215,B=WELL) (L=1.2,W=11);" + " device PMOS4 '34' (S=Q0_,G=CS0,D=NN2_,B=VDD) (L=1.2,W=5);" + " device PMOS4 '35' (S=NN2_,G=CS1,D=Q1_,B=VDD) (L=1.2,W=5);" + " device PMOS4 '36' (S=NN3,G=NET194,D=NET189,B=VDD) (L=1.2,W=16);" + " device PMOS4 '37' (S=VDD,G=YI,D=Q1,B=VDD) (L=1.2,W=7);" + " device PMOS4 '38' (S=VDD,G=YI,D=Q0_,B=VDD) (L=1.2,W=7);" + " device PMOS4 '39' (S=VDD,G=YI,D=Q0,B=VDD) (L=1.2,W=7);" + " device NMOS4 '4' (S=HNET48,G=A0_,D=VSS,B=VSS) (L=1.2,W=19);" + " device PMOS4 '40' (S=Q0_,G=YI,D=Q0,B=VDD) (L=1.2,W=7);" + " device PMOS4 '41' (S=Q1,G=YI,D=Q1_,B=VDD) (L=1.2,W=7);" + " device PMOS4 '42' (S=VDD,G=YI,D=Q1_,B=VDD) (L=1.2,W=7);" + " device NMOS4 '5' (S=CS0,G=YI,D=HNET48,B=VSS) (L=1.2,W=19);" + " device PMOS4 '6' (S=VDD,G=A0_,D=CS0,B=VDD) (L=1.2,W=10);" + " device PMOS4 '7' (S=VDD,G=YI,D=CS0,B=VDD) (L=1.2,W=10);" + " device NMOS4 '8' (S=HNET52,G=G0,D=VSS,B=VSS) (L=1.2,W=17);" + " device NMOS4 '9' (S=NET194,G=G1,D=HNET52,B=VSS) (L=1.2,W=17);" + "end;" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "begin_circuit DECODE DECODE\n" + "match_nets $41 WL1_EN_\n" + "match_nets VDD VDD\n" + "match_nets $39 NET194\n" + "match_nets g0 G0\n" + "match_nets $40 HNET52\n" + "match_nets VSS VSS\n" + "match_nets $42 NET189\n" + "match_nets gtp NN3\n" + "match_nets $37 NET193\n" + "match_nets g1 G1\n" + "match_nets $44 YI\n" + "match_nets $14 WELL\n" + "match_nets $8 NET215\n" + "match_nets $9 NET175\n" + "match_nets $6 NET181\n" + "match_nets $4 NET200\n" + "match_nets nn1 NN1\n" + "match_nets $11 CS0\n" + "match_nets $13 CS1\n" + "match_nets nn2 NN2\n" + "match_nets nn2_ NN2_\n" + "match_nets q0 Q0\n" + "match_nets q1 Q1\n" + "match_nets q0_ Q0_\n" + "match_nets q1_ Q1_\n" + "match_nets a0_ A0_\n" + "match_nets $34 HNET48\n" + "match_nets nn1_ NN1_\n" + "match_nets a0 A0\n" + "match_nets $35 HNET44\n" + "match_pins VDD VDD\n" + "match_pins nn1_ NN1_\n" + "match_pins nn1 NN1\n" + "match_pins q0 Q0\n" + "match_pins q0_ Q0_\n" + "match_pins q1_ Q1_\n" + "match_pins q1 Q1\n" + "match_pins nn2 NN2\n" + "match_pins nn2_ NN2_\n" + "match_pins a0 A0\n" + "match_pins a0_ A0_\n" + "match_pins g1 G1\n" + "match_pins g0 G0\n" + "match_pins gtp NN3\n" + "match_pins VSS VSS\n" + "match_pins WELL WELL\n" + "match_devices $30 0\n" + "match_devices $29 1\n" + "match_devices $9 10\n" + "match_devices $10 11\n" + "match_devices $36 12\n" + "match_devices $35 13\n" + "match_devices $34 14\n" + "match_devices $38 15\n" + "match_devices $37 16\n" + "match_devices $33 17\n" + "match_devices $27 18\n" + "match_devices $28 19\n" + "match_devices $17 2\n" + "match_devices $31 20\n" + "match_devices $32 21\n" + "match_devices $22 22\n" + "match_devices $26 23\n" + "match_devices $23 24\n" + "match_devices $43 25\n" + "match_devices $20 26\n" + "match_devices $25 27\n" + "match_devices $15 28\n" + "match_devices $14 29\n" + "match_devices $16 3\n" + "match_devices $18 30\n" + "match_devices $21 31\n" + "match_devices $13 32\n" + "match_devices $19 33\n" + "match_devices $7 34\n" + "match_devices $8 35\n" + "match_devices $24 36\n" + "match_devices $3 37\n" + "match_devices $6 38\n" + "match_devices $4 39\n" + "match_devices $39 4\n" + "match_devices $5 40\n" + "match_devices $2 41\n" + "match_devices $1 42\n" + "match_devices $40 5\n" + "match_devices $11 6\n" + "match_devices $12 7\n" + "match_devices $41 8\n" + "match_devices $42 9\n" + "end_circuit DECODE DECODE MATCH" + ); + EXPECT_EQ (good, true); +} From e25d4784eac42c1d5d599531608126966ceeb355 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 26 Oct 2019 01:48:50 +0200 Subject: [PATCH 21/31] Updated tests. --- src/db/unit_tests/dbLayoutToNetlistTests.cc | 12 +-- .../algo/device_extract_au1_rebuild_nr.gds | Bin 11642 -> 9458 bytes .../algo/device_extract_au1_rebuild_pf.gds | Bin 49364 -> 49364 bytes .../algo/device_extract_au1_rebuild_pr.gds | Bin 29092 -> 29092 bytes .../algo/device_extract_au1_with_rec_nets.gds | Bin 50630 -> 50630 bytes .../algo/device_extract_au2_with_rec_nets.gds | Bin 38230 -> 38234 bytes .../algo/device_extract_au3_with_rec_nets.gds | Bin 46966 -> 46966 bytes .../algo/device_extract_au4_with_rec_nets.gds | Bin 49526 -> 49526 bytes .../device_extract_au5_flattened_circuits.gds | Bin 114198 -> 114198 bytes .../algo/device_extract_au5_with_rec_nets.gds | Bin 70670 -> 70670 bytes testdata/algo/l2n_writer_au_2.gds | Bin 13334 -> 13338 bytes testdata/algo/l2n_writer_au_2b.txt | 28 +++--- testdata/algo/l2n_writer_au_2s.txt | 28 +++--- testdata/algo/lvs_test1_au.lvsdb.1 | 92 +++++++++--------- testdata/algo/lvs_test1b_au.lvsdb.1 | 92 +++++++++--------- testdata/algo/lvs_test2_au.lvsdb.1 | 92 +++++++++--------- testdata/algo/lvs_test2b_au.lvsdb.1 | 92 +++++++++--------- testdata/lvs/floating.cir | 8 +- testdata/lvs/floating.lvsdb | 32 +++--- testdata/lvs/invchain_cheat.lvsdb | 66 ++++++------- testdata/lvs/ringo_mixed_hierarchy.cir | 8 +- testdata/lvs/ringo_mixed_hierarchy.lvsdb | 32 +++--- ...ringo_simple_simplification_with_align.cir | 20 ++-- ...o_simple_simplification_with_align.lvsdb.1 | 20 ++-- testdata/python/dbLayoutToNetlist.py | 28 +++--- testdata/ruby/dbLayoutToNetlist.rb | 28 +++--- 26 files changed, 339 insertions(+), 339 deletions(-) diff --git a/src/db/unit_tests/dbLayoutToNetlistTests.cc b/src/db/unit_tests/dbLayoutToNetlistTests.cc index 011322222..53947ec0c 100644 --- a/src/db/unit_tests/dbLayoutToNetlistTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistTests.cc @@ -792,7 +792,7 @@ TEST(2_Probing) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I18"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I3"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I5"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -835,7 +835,7 @@ TEST(2_Probing) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I18"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I3"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I5"); } TEST(3_GlobalNetConnections) @@ -1073,7 +1073,7 @@ TEST(3_GlobalNetConnections) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -1116,7 +1116,7 @@ TEST(3_GlobalNetConnections) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); } TEST(4_GlobalNetDeviceExtraction) @@ -1360,7 +1360,7 @@ TEST(4_GlobalNetDeviceExtraction) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); // doesn't do anything here, but we test that this does not destroy anything: l2n.netlist ()->combine_devices (); @@ -1403,7 +1403,7 @@ TEST(4_GlobalNetDeviceExtraction) EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "(null)"); EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22"); - EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4"); + EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I6"); } TEST(5_DeviceExtractionWithDeviceCombination) diff --git a/testdata/algo/device_extract_au1_rebuild_nr.gds b/testdata/algo/device_extract_au1_rebuild_nr.gds index 0050d5e7d6016f3aa29e90dad05e1bca5be11742..256f5daf91365ff2277f034898be6bc7154ec45c 100644 GIT binary patch literal 9458 zcmcgy--}dL96vKVduMhWL)X;@kq8-~z|7rQcNIz0-3I)2Pv`#dkO-j1fR6r+vj_}=R5a%?%Z?l9Yr68k9^Pf$35R) z=X;K8B2%rtVYXGO^}kKiY&8{AH9PdbO`{sU+C6N{*wFBSL!V9`{q6g^`)04bbos00 zMYC-2nqgzEL&2&%9yxv`0T|9AUenDq%Er}_1wH-UU z!5Ciwt|5aR3LR*(*JXc79^bu8^7u`We1bv;YWYapH@9H_9CX}*+!K2r6l ziXBR9QiVb%DwZpi{0^I_BCaY~AGl&|9zO+}qpC}g&CDD|KRV63e0Z96C%cv1$$F_> zYKxS^iA9yaqLJ{iE%xQFsu`7k*kKjF8;tQ4;9uCGL!pQBm*gma87osHk8gJ<^l<)S zuRlZP93kY+z;;_u=!B)bth+yV;>6ESBY(L&J$akRCa*W;Sp4rc=k3sQT&0Y0%yhz1 zo>dmR^Gg%$NmFZLCK&aU4+pSdU}P^MOdAYm~Ylo?J`pB*0yr(5(+(4yDCFS4j$aW@{}1Q$0&4* zS@YHk^%mPf#~5ke8u|h94x>freH$BhIPxCW|G;-StmBLu9y3PJ;NMPPnfWYTtK&AJ zqp2=z{fIrF2a6v$K7Q@#Uak0YwD}#qr_JVt)+T%|dfv(V@E&R-!fAicmT5%C3e%Yw zh()Rf#5bvk$mGzg0L9lIk(5pqJ)FqBxX1+5)9Leh6GWSF9YLXoE1u-AFPsUahvs<7Jw~AudO4$V4!oOe zPTI4iaf3StqtNqm7CXCzDxYMmeGPfs&;*4J4CE~AZ-@K`jI|{oZis?H2WokBL$os< z>@$j8L7}JY`|>;CpB2dOq)rC^eJLn(!csNU!p*Dg60_(nrzyOJuRd0*E1^0G;7W7zJAvxD2+n`>8V4BK7#eQ>*-={!GMefYBc`qfolwthQ%t=$dDBxffI zdva^5rSwA>%o7^4Nr@Kqp@0;YwHFLkZYn0Z<(^sZG-3?0X<6Cg1K3(Od_3?X2 zraoQ0rS06qm0Vks}Crh1!j!Wl#SeMSeFqh7$Fqh7hFqe*h zm`g`B%%x)$=F$-ea}D0_mKHF9XT_;gDo&28AWn{}AWn{}AWn{}AWn{}AWn{}AWn{} zAWn{}AWn{J@Hib?n8}Wln=7?OcYjiETE?uti#zXUjP>)zoO}m&UWY;l>idIwlY-py zkUz*+$EkYq8sr@c9cbkXIs|5Vnv`ET9PT%IHyPRPrd6GFZqMGGCH+qD;8%Pz-U|o= z?*z(ccpvzJe8yNm54q3DXN*Em`Ao?h^Cm`P@+~3xdili!g`SdEK8M{SXfjsSEk9WezdrpEme*1zN_CX&%pb%YWr2rx;=OD)@gpoS#NhI zrwZ2h6s%{@81DO_-}P$UWf0wD-F4pJdPbM>HKxvuX6p1dtdJQ kRKYs#$+_~lzvr%_Y38o;YqRsdSN*+rm_B(_f30Tz2kJ{eOQ+^q?bf(4mAWy(<}$nlkCowV&*)GXK6ot**LD*c zQ~Es&!w&>yozPUaK)+^ky^f{5b~1g!^Lvp^Ao((;{I#I0JNwi-o!zk0O^;xwkyo`- zetG`PvDrDz-b(UJv8!F! z(M`tiDsT-9j#1Wu5qo3yr}Po`BI)CIg7g!Vb)eP{w10CO{x87BZRni`lcxk_JwmVS zQ5idw_@oSlO=K)*DxEugB8xbyMBaDCMm&B5KAWmakk3pGqaK~(T|PKRyOZ6@?nLgi zOYM<3oOo3H6^n!ed)&ZZl{1Qe*kKvJHyOjLz(26V7-hXTe@Tz{%UGHqeZ(H4toPmuRFmH#R;w)thLtZCz zI$7m$W_Dq`)isq7^aM>i4yuvCjuJdIo~Rxh1=3GrXZ2|G2mMX={o0#oGgjGemK87+ zR#tMYfFqx#t=Rnr?!*3L+1||RS_)QYQ58;1r7!o$VH>Ubdg0eom zm-P#Jv^1AGgK`PGiEg*SxMW*d=aTeRg&bgBD=V5yT#cOagSjMjVlJrOia3N{+`hym zx^;<5jIvH>Jl*-zS&G^SHDE%J!~H*n?eB^z%#l&O#n+u+yVTx{LTWlWvN7o8BB)amX||vlIuU zGwi>5WOBeI62&7_pmh#NU+fr(ZN=(3TQ2p7pR76+>}Nd|Iu+;aQZ_bJRQE{Kesm;s zD$bFJjg8eb4FCCyswrdR7UzectoN>_q({|~_353H@{3W{39YCC`lYX8BM8h z*aaOE{LfC$FSllpGxQFp>Pz%yH(vbKgg1}VU**cb9j}+F!=L zonn4+wf~qq1H`QT`NsUr(f(sb0q{O&?aw#n4mxrCMEr8)23~5tW7htBV}AZl|1o3S z>m9T9=Nt2hef`ILV1SslKi`+-v($KLdv;p~mydOW=8YVYig zCw?B@be(qg#7}yL+6dJ4V?|XHZ;e5ZD{8D+R%LTwbB1AyD*2h{wz*+{s&Gw*(l(&lZ^sS zJJ~4Uw3CejPCMBs;IxyC0!};GDB!e{jRHdIE%n`zG0SgZ zO!hHj?V>Sf-@x28Mp*~y`HuST2YOFK|0rV(UGdrL(2r5pfi7=;n7Pm-?UqKM33^_P^qdy)y|19GJ3g;^5UkJFN18!AuUh|)0Gy<}uVhHo z^f!^>ya- u%$H+^k$Zla%jC*2Ys!^R6v#0X%+<%7GgpqHnJdRUI#=G#kR$sm74si*y2Jmh&``Ce)n;Yy7vBG2pTv#S2x#+<(u5sZ}1hEeUOHIC#3b7H$EJ$OSERgQCxgd>$ z6DB<+A7XC2%;a+gUXvf>vrKL%@Y~!_kR}FFvY}OKGgEs2Gl(6~EwwqX>xBS_tuR?? b@`2etlM811ZRVM?0qhW<*ybAx|HuIVqC9in delta 525 zcmcc8$b6-dS&4y-fr%-CL57iu{V@Y812cmdgB*hrGJB$uayC{81|Bvx7ZpEW|6mnE z1{QV(1{qeIhA?o!)DluTaf5g!cI&`K1OTlgWCX~vkRV6DUUj*Qj<3b8$p?y{|P@60kH)nr6y^DMS-l%ewrB^Akhy-QkyRs3h+SLlmFR* zl>mh&``Ce)n;Yy7vBG2pTv#S2x#+<(u5sZ}WHg-Im?Ay-N~#f*RglIqSs>kOb3qyh zCsb%kK1}jVfzRXz`7Dzg3j8)V6r_oPOxn;YwVA0sfEmON=$6`?*Y!dG#8#LrHTl47 XpUDNY{WkN=*#LF~P;B#!g@5D#Tb^?y diff --git a/testdata/algo/device_extract_au1_rebuild_pr.gds b/testdata/algo/device_extract_au1_rebuild_pr.gds index 36c92dfb00cd11e92c1e59c0e74c7692c32c3574..948e2a8c6c7ff8724554f4cb28208483af0718e6 100644 GIT binary patch delta 2458 zcma*oy=xO;9KiACuF0jIskBX^=QZ`^dezoyX^gcs21{wwCYV@~TH0_}M5HJP4k9H4 zDvoY)2of9|vMKm-4x#uLh=Y?#=@vI}5eEqw>?uNo`;u%Ae4o#gColI)wJufbk|7i! z%gZ7v$$`31g)Sr^i{aMwBV#Dy9g4TT!|Ux`l6SEi5*Vi}BdT-}iuw>G{Dj{55p5}i ztN@}?H=$-XB3&i)R7JG8n@}={sMup2iBAb%pAf!)5K%vV)An|cCC8`iJ4VK5rgs+4 z4rfN(MJL#4?7=H&y>#zNFQQr>p+rBTWJ0{2sH)}X@i6+gM^&g0Zg9`V)}UqQ@?>}VyKHI%e;AW!*fiDprWMAT=sIojJ10L zg!*r9+ns+-UHI?Rjn=W*y8e5tySeSLI~Q2Y&*lnkA65}ol(}?%?n-)bHJw{JX~tvD z%i#;~@i^+y$CTcVtWYwJq53d}DsckU*Kt(&2~^D(s#|eX;Ym~vPNOfzsncQoex~M%`{y+~I6f)4(>h|$jIDL(ox8K&W$%A! z=Uxia`bA8o45o7S8@*O}fm4Cg5~meT)^qx$C$C~^uG*xk*Rqt9>!0Z@|F{t%rLR3y Fe*+l%I9LDx delta 2457 zcma*oy=xO;9KiACu9r(ZTWOm_(E6{rMD-y;iD5)*enLBbM85)rNih9WrR>M zjA$!Ds1-pJ8YNU6C1lqRV)}Fl)6c`0hGUqf$NFfpEa|r@u478{t7=NmWv>);quUc8 zw10cM?)-D=@_(mRI>%<``tPyM=B~%?USK7^kSlb3SVcfp7t{I0tLc@EbZ+&uK4aJ~ zk6wh2$JWLlQ+hkGPAPUA)rTomiIb?loBq;y@ diff --git a/testdata/algo/device_extract_au1_with_rec_nets.gds b/testdata/algo/device_extract_au1_with_rec_nets.gds index 1bc3662a113181bf85ed1fd465beb5481ad444c5..b03ebd333b2035c62f66bcced3536282db2fad02 100644 GIT binary patch delta 1201 zcmZ|Oze@sP9LMqJ?(EFFPBh9u%fb}Q!9fcxEKEod#OUZ330*@GI5>rSK~P9gd}nK^ z25G1cGV*Yca0ra%3<_HNBZ8)e`)m)qo;Q3Sp66*-gmy*nF_H27IveJA>o=2_n{kY1 zf&c3>-}s<8Y!m>zbj^XDI3RkB_i*Ns{w_e0dSq0E#4aFm_o68z+Zu@Uvb2KeONLcW zfz^Y(&Vv&lI6D?V+b&3H52WB2Bq;#tX9Ch|7}9ODV+oo*7&ah^YJOo^Q?vQZqUO&= zW5i7k=|=nt9k)FDiKv)@w3&gV<{+h)AkC~o3Kt;xwjjB7AW6j$FSz`~5v0=fi2y1` zt!gzVYTZ@MMc=!JpYBpGSxIfok)x5M(?*K=jVNh0ncf;xG-_AKh)3wzn5RP{Nm*H; r#B_wtZT7!?7dD0b#}V>Mc6z*tP{`Rwj%FQ9@zLBD_-IVmTD!t8Y~Q&N delta 1201 zcmZ|Oze@sP7zgn8?o9LaOd$=jGR(jn1kVBu3lmZVF*^E1f;JR^gHyN{1cd~}Guu=R z(oh{_bcch4LtsQ>1qH4B5m8gaeW&+@&+~=n;eDS@P3Y7FKQl9)Ut>cYZ~0;z>tk-_ zW1j!_6aSdo7}g5_9^Z_C?l~Z8gZFaAA@x;&B=*=)Dr9~GM1#Gk3(>j?LTXi9M)YZe zshk8;w~i(cCf;*(O@KB%kkVdA!BI%!IHd0hNKau%SJAF1X!v1RzuBzh=a))KHlJB2 z1+tMiagzh89y>?lR%bpCl~a(48AwVFQhE{6^a`YK0g`_Ml4lE&SRNh$kDoYzRJk}3 zK+4&uTa1a?*L7o2cW&U)ov9TIDcUSKwIm&DDGD6QRJ7XZS(_rCLn1vU(}O-o`+AbH rHi;5(nNF>azq;S^MT?S8l<4kKrjW}{&Q=q2@!r}M_()tWwYP;IW~ROl diff --git a/testdata/algo/device_extract_au2_with_rec_nets.gds b/testdata/algo/device_extract_au2_with_rec_nets.gds index 228fa0ef10d816e2a87ffb3928a25c7c67f9cf82..231a700560c8ae0a2e6d982fdf1b85acdb79562e 100644 GIT binary patch delta 927 zcmcb%is{xWCM5s_Qwod3{nh?3``8F$n1$q%A(jMqM~s~oVtx&V)8CV z95S0%F-bFG*R=T-GfpWkR&HFnwAgOrkeV#Tfy)(KoaIbfSUt-i#>N)p=Nc04=@(`c z;OH3?ui|Msd7^;$=0n^|S#Y?#M&KbXsUp!&Y?GJB*iBB7ahUu_#%Xejtnp-VS%=Bf zWqpC-#*?oD+2L}&VDag4mU8S23^J@ZBWbgq{8?O938>(d`lNA|MFYEkMWFr-^7M1} z2YS}f9PHaax;TBi&FDTZC#*8ZDK*aqr_>}zoKkIWvT`^AeMbsTsaH+C%s6!Qw9RG5 zE;ZS%Z!UJ3%^&)3rOe3+6Pg%JCku)R6Ns_Qwp24EzkD3?d9D?1@UsqSz&(qH#!^x{Y08@-9Xk zGMiU1Ni$;CwD}e@PAM){Zd|&w*ly#Hnk>bE%N1Oly9J@nmsXhso1r zeSzY}ldl8W;c~uU@#%7wa_kHYGOQ>OgB)R-_2kduvPwV&r_?8nvn=Y^{VN3ZZ;+>- zyFbvgmXjUi#Ww%b#p&4{M)z^KV2wFWsRcGTrKULIl(8OpwSx`)vP`q86aFTKI+ere9mXrTYQr&!gQZo|( DVn>eG diff --git a/testdata/algo/device_extract_au3_with_rec_nets.gds b/testdata/algo/device_extract_au3_with_rec_nets.gds index 7660693961c43b8f1e7456be97611c0bd977f268..77f48da85e1ff6db9584f1cde6f6a1800e2f619b 100644 GIT binary patch delta 1048 zcmezNj_KPwCM5s_Qwod3{nh?KoLP?_CzIRQS1^?(KsYd-Nr64c^4xt znN>`4vFq6!!z|5+L#l@br_>%+Zd|(Vu-(QXHTet&F8A%>#38eJ4OcmnHr4=Q5MyHt z@^cM|_w)-h3UKrcidXS8W0?FwPi%7v?@|^Vo{|%Kh)YUDd=KYj0Y#_DEzE|Kn-v=- zJ1aU&W>)f@JVD8Lva=G9t=usAFpzFm_MI%CVm$e8DQ-P1eEqKQ2KM4$l>w=a zr&NPGPN@=~xvDr~L9Iwu1BX<^tX^guQorWTWyc}4X6ale98z&Ba7j%TSdA-N99oSl n?N9!+risyPvf?^nLh-$9ttu0fks(m2s_QwpY4Dt*N42%q7$n1$q%A(jMqM~s~oVtx&V)8CV zTr#Ve=3>{gIfhx95r|u940#}J4`;T)G)bO*>|#lit*&bAij#_MywjMMu|EbilS!wg%T zQaw&Mr5fCEN|pG`RmBktYDKadIHV$G^)lm-`ZaehI}WKeOXo7-kcwM@OKP&fYFydk q&}v+1fAXg_O^ha!71s$9itlA>RhgI!je$xfC-ZFJ-TZldGdlp3A*Rg$ diff --git a/testdata/algo/device_extract_au4_with_rec_nets.gds b/testdata/algo/device_extract_au4_with_rec_nets.gds index c8000ad0af98236fe29a74e89e01e43d7e5464b7..69d52a8499ca12781d3a58554969a5b79e3092df 100644 GIT binary patch delta 1048 zcmey?#Qd#^S&4y-fr%-CL57iu{V@XUY_D>p7(ci3*@keYmk1DE^uaN>~JyoRfsNgHbbF^I9T z1^Ky##C!UM83j0c2F0s*nlViNpeMFDg?A|n4o}GmJ;Ws?BEE-nvVfw~BYKEBj6sP%)l-SQ*Gxshph0&OX^$#Zr!)fkB29 zXH0LFQay{y>OYz|rS9pSWzobQ03y%;2=erE_Xqmk$PnWFSH?KKzr^A`E;r1u#VOU} zgj1@)9j8=@&s;4Wv7lBitBXS_Vo5JE4yj+u=d$CFTC;vG6Ar1kO}L~c3v9)eEe>tP omG&op+SbHqHd%3pFroNfwq2Ep$;c3>RB|%UF5b delta 1048 zcmey?#Qd#^S&4y-fr%-CL57iu{V@Y8gB*i6gB61qGJB$uvM6?msAwD#r*31Hn7oS- zm&_`rx!Cn=j$xK'wgf>UY_D>p7(ci3*@keYmk1DE^uaN>~JyoRfsNgHbbF^I9T z1^Ky##C!UM83j0c2F0s*nlMcMpeMFDg?A|n4o}GmJ;Ws?BEE-nvVfx9=zBwBi1%L^s_Qwod3{nh?3>*xM$n1$q%A!~$Hb!wXW0%=n#hlNJ zL+YQvT`n9_AEa?gJyN^NrGeEI3?gi7L4K|w@j;$`?*8#Ao<@d~9c9Ef|1;c*%bpW9 z_i;(>amOjOAqc0`l31KlGcx8{;_$B5B3T<8QZ@HtIdDk5dv=!(htz|wcX8>u^beQR z_9N_!cRAFthpiAB8*0!_pJ2i$w*8&}<5nCtZC@b?G!DB1x6e|-E!U%sTdvLow_JfO z<6M0l_9^8u${OL23z^Rt%Z@|t*fPf3+}P!&Z`;J^ja_QH*k;BSMkXV}=>c09Rkk14 Z!nhjDo4A=#a{8KWjJ(??Z)0p`2LS3Uh%5jA delta 888 zcmbRChi%#)HYEl&1}3Hm1{p>s_QwqD4AKk?3`z`q$n1$q%A!~$Hb!wXW0%=n#hlNJ zL+YQvT`n9_AEa?gJyN^NrGeEI3?gi7L4K|w@j;$`?*8#Ao`%Mg9c9Ef|1;c*%bpW9 z_i;(>amOjOAqc0`l31KlGcx8{;_$B5B3T<8QZ@HtIdDk5dv=!(htz|wcX8>u^beQR z_9N_!cRAFthpiAB8*0!_pJ2i$w*8&}<5nCtZC@b?G!DB1x6e|-E!U%sTdvLow_JfO z<6M0l_9^8u${OL23z^Rt%Z@|t*fPf3+}P!&Z`;J^ja_QH*k;BSMn=Qw{#zJTw;$NT bxSEm4(0Ka9&5V-M*KA|t-9C96V>3Gd(}9pA diff --git a/testdata/algo/device_extract_au5_with_rec_nets.gds b/testdata/algo/device_extract_au5_with_rec_nets.gds index 799ab844eb00e7ddeac23ad2d9472f8f9191c4c6..6f30100c642a0f7f558036e3b2d19d8eedf3d2ea 100644 GIT binary patch delta 941 zcmeBM!P2*aMTvopfr%-CL57iu{V@X~9WO*5gc)X0m1tWDsFv3-WUfi4XGhbN7!|@ia2rJm2mN zE;|}L@8gmx3Bf6q5sy|fg8M(K2@-Vit F0|1h?iYovB delta 941 zcmeBM!P2*aMTvopfr%-CL57iu{V@Y8gB*i6gEoUDGJB$uvM6?msA%jG8&5?uVwc%$ z#e_?0@+#)JI5fqu%*JIN4;xOYJ?yt}=~}}njYDek9j@CrTyciGoEe8y1iuK^~9WO*5gc)X0m1tWDsFv3-WUfi4XGhbN7!|@ia8vJm2mN zE;|}L@8gmx3Bf6q5sy|fg8M(K2@-Vit F0|1Bgq-_8I diff --git a/testdata/algo/l2n_writer_au_2.gds b/testdata/algo/l2n_writer_au_2.gds index ad232c88802491914579fcbfffed27b62957cef4..35478aff1ecc7976d0b904ba1589ad5600a61d8c 100644 GIT binary patch delta 1658 zcmaizKS)AR7{$N$d_Ggm$WkoC|5^~FzM!QjAc`dIad9O^+I^-G`7fZ+Y%>%IS`_uaMa6c4m*50KBs(m5JfX_Do1 zB475U=G%LbWFTVujx7J)?8y-UB;>NNn6uc2-u0ooeRTJ(ey%CE0<_2O6+l|=0&)Y%cmQcCh^WoLg2Zp68fOq< yo55Qrf5UbHI~yjKm@D8=OQ9$_Y$Lp5G@1WG$efBD43bgS1W^f}Dh}41D}4iypwiI* delta 1652 zcmaizze@sP7{}i`&pS`d;N;B6ywuZ%AUky{iSS4C%OpiaC~;DfTx)Z02;zl?hK2~* zLb$CVs;#E}fFP*d8Vee_62aiU$}KN^p3nDr?&Wz;>nHU9;R(x@h?il7H)11`WX$-) z{_}AlD4TQM$9vW*5P}o|^=E=}X zV}NYBP*GRnMy;I?Nuv9{ocVpzXI}!4wj$G{Qi6035}7VfVNa$H1L>MSIw1KH(vClA z?&+C;3v35%1{>xQ?Lg908-BP@-J929^kaIQx|GI96BfCr@)qU#K!(P~Vgx3TgMN$b`4 diff --git a/testdata/algo/l2n_writer_au_2b.txt b/testdata/algo/l2n_writer_au_2b.txt index c232887a5..8709c5c46 100644 --- a/testdata/algo/l2n_writer_au_2b.txt +++ b/testdata/algo/l2n_writer_au_2b.txt @@ -270,6 +270,12 @@ circuit(INV2PAIR rect(diff_cont (-220 180) (220 220)) ) net(4 + rect(diff_cont (2390 3690) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -2620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + ) + net(5 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 -220) (220 220)) @@ -283,7 +289,7 @@ circuit(INV2PAIR rect(metal1 (-3000 -760) (360 760)) rect(metal1 (-360 -760) (360 760)) ) - net(5 + net(6 rect(diff_cont (4230 490) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 -220) (220 220)) @@ -297,12 +303,6 @@ circuit(INV2PAIR rect(metal1 (-3000 -760) (360 760)) rect(metal1 (-360 -760) (360 760)) ) - net(6 - rect(diff_cont (2390 3690) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -2620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - ) net(7) net(8 rect(diff_cont (5030 3690) (220 220)) @@ -315,8 +315,8 @@ circuit(INV2PAIR # Outgoing pins and their connections to nets pin(1 name(BULK)) pin(2) - pin(4) pin(5) + pin(6) pin(7) pin(8) pin(9) @@ -326,18 +326,18 @@ circuit(INV2PAIR pin(0 9) pin(1 7) pin(2 3) - pin(3 6) - pin(4 5) - pin(5 4) + pin(3 4) + pin(4 6) + pin(5 5) pin(6 1) ) circuit(2 INV2 location(4340 800) pin(0 9) - pin(1 6) + pin(1 4) pin(2 2) pin(3 8) - pin(4 5) - pin(5 4) + pin(4 6) + pin(5 5) pin(6 1) ) diff --git a/testdata/algo/l2n_writer_au_2s.txt b/testdata/algo/l2n_writer_au_2s.txt index c12295b2d..e90dd3e1d 100644 --- a/testdata/algo/l2n_writer_au_2s.txt +++ b/testdata/algo/l2n_writer_au_2s.txt @@ -238,6 +238,12 @@ X(INV2PAIR R(diff_cont (-220 180) (220 220)) ) N(4 + R(diff_cont (2390 3690) (220 220)) + R(diff_cont (-220 -620) (220 220)) + R(diff_cont (-220 -2620) (220 220)) + R(diff_cont (-220 -620) (220 220)) + ) + N(5 R(diff_cont (4230 3290) (220 220)) R(diff_cont (-220 180) (220 220)) R(diff_cont (-220 -220) (220 220)) @@ -251,7 +257,7 @@ X(INV2PAIR R(metal1 (-3000 -760) (360 760)) R(metal1 (-360 -760) (360 760)) ) - N(5 + N(6 R(diff_cont (4230 490) (220 220)) R(diff_cont (-220 180) (220 220)) R(diff_cont (-220 -220) (220 220)) @@ -265,12 +271,6 @@ X(INV2PAIR R(metal1 (-3000 -760) (360 760)) R(metal1 (-360 -760) (360 760)) ) - N(6 - R(diff_cont (2390 3690) (220 220)) - R(diff_cont (-220 -620) (220 220)) - R(diff_cont (-220 -2620) (220 220)) - R(diff_cont (-220 -620) (220 220)) - ) N(7) N(8 R(diff_cont (5030 3690) (220 220)) @@ -281,8 +281,8 @@ X(INV2PAIR N(9) P(1 I(BULK)) P(2) - P(4) P(5) + P(6) P(7) P(8) P(9) @@ -290,18 +290,18 @@ X(INV2PAIR P(0 9) P(1 7) P(2 3) - P(3 6) - P(4 5) - P(5 4) + P(3 4) + P(4 6) + P(5 5) P(6 1) ) X(2 INV2 Y(4340 800) P(0 9) - P(1 6) + P(1 4) P(2 2) P(3 8) - P(4 5) - P(5 4) + P(4 6) + P(5 5) P(6 1) ) ) diff --git a/testdata/algo/lvs_test1_au.lvsdb.1 b/testdata/algo/lvs_test1_au.lvsdb.1 index add09797d..b32d9f40d 100644 --- a/testdata/algo/lvs_test1_au.lvsdb.1 +++ b/testdata/algo/lvs_test1_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test1b_au.lvsdb.1 b/testdata/algo/lvs_test1b_au.lvsdb.1 index 460cae8e7..556dcc6dd 100644 --- a/testdata/algo/lvs_test1b_au.lvsdb.1 +++ b/testdata/algo/lvs_test1b_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test2_au.lvsdb.1 b/testdata/algo/lvs_test2_au.lvsdb.1 index 23a4ccef6..40eb31bb7 100644 --- a/testdata/algo/lvs_test2_au.lvsdb.1 +++ b/testdata/algo/lvs_test2_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1070,17 +1070,17 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(4 5 mismatch) + net(2 5 mismatch) net(6 6 match) net(7 7 mismatch) net(1 1 mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) - pin(3 4 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) diff --git a/testdata/algo/lvs_test2b_au.lvsdb.1 b/testdata/algo/lvs_test2b_au.lvsdb.1 index 9828a5742..2b3360370 100644 --- a/testdata/algo/lvs_test2b_au.lvsdb.1 +++ b/testdata/algo/lvs_test2b_au.lvsdb.1 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1070,17 +1070,17 @@ xref( ) circuit(INV2PAIR INV2PAIR nomatch xref( - net(2 2 mismatch) - net(3 3 mismatch) + net(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(4 5 mismatch) + net(2 5 mismatch) net(6 6 match) net(7 7 mismatch) net(1 1 mismatch) - pin(1 1 match) - pin(2 2 match) + pin(2 1 match) + pin(3 2 match) pin(4 3 match) - pin(3 4 match) + pin(1 4 match) pin(5 5 match) pin(6 6 match) pin(0 0 match) diff --git a/testdata/lvs/floating.cir b/testdata/lvs/floating.cir index ced9a2759..edd64b16f 100644 --- a/testdata/lvs/floating.cir +++ b/testdata/lvs/floating.cir @@ -43,8 +43,8 @@ X$2 3 5 2 6 INVX1 * net 2 VDD * net 3 IN * net 4 VSS -* device instance $1 r0 *1 0.85,2.135 NMOS -M$1 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U -* device instance $2 r0 *1 0.85,5.8 PMOS -M$2 2 3 1 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 2 3 1 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U .ENDS INVX1 diff --git a/testdata/lvs/floating.lvsdb b/testdata/lvs/floating.lvsdb index 3775e7da4..abb305d27 100644 --- a/testdata/lvs/floating.lvsdb +++ b/testdata/lvs/floating.lvsdb @@ -135,20 +135,7 @@ layout( pin(4 name(VSS)) # Devices and their connections - device(1 D$NMOS - location(850 2135) - param(L 0.25) - param(W 0.95) - param(AS 0.40375) - param(AD 0.40375) - param(PS 2.75) - param(PD 2.75) - terminal(S 4) - terminal(G 3) - terminal(D 1) - terminal(B 4) - ) - device(2 D$PMOS + device(1 D$PMOS location(850 5800) param(L 0.25) param(W 1.5) @@ -161,6 +148,19 @@ layout( terminal(D 1) terminal(B 2) ) + device(2 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 4) + terminal(G 3) + terminal(D 1) + terminal(B 4) + ) ) circuit(DINV @@ -430,8 +430,8 @@ xref( pin(0 1 match) pin(1 2 match) pin(3 3 match) - device(1 1 match) - device(2 2 match) + device(2 1 match) + device(1 2 match) ) ) circuit(TOP TOP match diff --git a/testdata/lvs/invchain_cheat.lvsdb b/testdata/lvs/invchain_cheat.lvsdb index 7e0338182..7f128c691 100644 --- a/testdata/lvs/invchain_cheat.lvsdb +++ b/testdata/lvs/invchain_cheat.lvsdb @@ -244,17 +244,17 @@ J( X(INV3 R((0 0) (6300 4600)) N(1) - N(2) - N(3) - N(4) - N(5) - N(6) - N(7 + N(2 R(l6 (990 490) (220 220)) R(l6 (-220 180) (220 220)) R(l6 (-220 2180) (220 220)) R(l6 (-220 180) (220 220)) ) + N(3) + N(4) + N(5) + N(6) + N(7) N(8) N(9 R(l6 (2590 490) (220 220)) @@ -302,35 +302,35 @@ J( P(10) P(11) P(12) - X(1 INV Y(4800 800) + X(1 INV Y(1500 800) P(0 12) P(1 11) - P(2 3) - P(3 10) - P(4 8) - P(5 6) + P(2 5) + P(3 2) + P(4 9) + P(5 9) P(6 1) + P(7 1) + ) + X(2 INV M O(180) Y(2300 800) + P(0 12) + P(1 11) + P(2 1) + P(3 9) + P(4 2) + P(5 2) + P(6 5) P(7 5) ) - X(2 INV Y(1500 800) + X(3 INV Y(4800 800) P(0 12) P(1 11) P(2 4) - P(3 7) - P(4 9) - P(5 9) - P(6 2) - P(7 2) - ) - X(3 INV M O(180) Y(2300 800) - P(0 12) - P(1 11) - P(2 2) - P(3 9) - P(4 7) + P(3 10) + P(4 8) P(5 7) - P(6 4) - P(7 4) + P(6 3) + P(7 6) ) ) X(INVCHAIN @@ -440,13 +440,13 @@ J( R(l8 (2940 -760) (360 760)) ) X(1 INV3 Y(-1500 -800) - P(0 9) - P(1 7) - P(2 8) - P(3 6) - P(4 9) - P(5 5) - P(6 1) + P(0 7) + P(1 1) + P(2 9) + P(3 8) + P(4 6) + P(5 9) + P(6 5) P(7 5) P(8 3) P(9 2) diff --git a/testdata/lvs/ringo_mixed_hierarchy.cir b/testdata/lvs/ringo_mixed_hierarchy.cir index 8e98d778a..e82ebea9b 100644 --- a/testdata/lvs/ringo_mixed_hierarchy.cir +++ b/testdata/lvs/ringo_mixed_hierarchy.cir @@ -57,8 +57,8 @@ M$4 15 1 4 16 NMOS L=0.25U W=0.95U AS=0.21375P AD=0.40375P PS=1.4U PD=2.75U * net 3 VSS * net 5 IN * net 6 SUBSTRATE -* device instance $1 r0 *1 0.85,2.135 NMOS -M$1 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U -* device instance $2 r0 *1 0.85,5.8 PMOS -M$2 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $1 r0 *1 0.85,5.8 PMOS +M$1 1 5 2 4 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U +* device instance $2 r0 *1 0.85,2.135 NMOS +M$2 3 5 2 6 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U .ENDS INVX1 diff --git a/testdata/lvs/ringo_mixed_hierarchy.lvsdb b/testdata/lvs/ringo_mixed_hierarchy.lvsdb index 796a8d02b..d71d08c6a 100644 --- a/testdata/lvs/ringo_mixed_hierarchy.lvsdb +++ b/testdata/lvs/ringo_mixed_hierarchy.lvsdb @@ -190,20 +190,7 @@ layout( pin(6 name(SUBSTRATE)) # Devices and their connections - device(1 D$NMOS$2 - location(850 2135) - param(L 0.25) - param(W 0.95) - param(AS 0.40375) - param(AD 0.40375) - param(PS 2.75) - param(PD 2.75) - terminal(S 3) - terminal(G 5) - terminal(D 2) - terminal(B 6) - ) - device(2 D$PMOS$2 + device(1 D$PMOS$2 location(850 5800) param(L 0.25) param(W 1.5) @@ -216,6 +203,19 @@ layout( terminal(D 2) terminal(B 4) ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) ) circuit(RINGO @@ -825,8 +825,8 @@ xref( pin(5 5 match) pin(0 0 match) pin(2 2 match) - device(1 2 match) - device(2 1 match) + device(2 2 match) + device(1 1 match) ) ) circuit(RINGO RINGO match diff --git a/testdata/lvs/ringo_simple_simplification_with_align.cir b/testdata/lvs/ringo_simple_simplification_with_align.cir index c24088217..3af85ddd7 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.cir +++ b/testdata/lvs/ringo_simple_simplification_with_align.cir @@ -26,16 +26,16 @@ X$5 6 4 9 6 3 9 INVX1 X$6 6 5 9 6 4 9 INVX1 * cell instance $7 r0 *1 22.2,0 X$7 5 6 7 9 6 9 INVX2 -* cell instance $17 r0 *1 7.8,0 -X$17 6 12 9 6 10 9 INVX1 -* cell instance $18 r0 *1 9.6,0 -X$18 6 13 9 6 12 9 INVX1 -* cell instance $19 r0 *1 11.4,0 -X$19 6 14 9 6 13 9 INVX1 -* cell instance $20 r0 *1 13.2,0 -X$20 6 15 9 6 14 9 INVX1 -* cell instance $21 r0 *1 15,0 -X$21 6 11 9 6 15 9 INVX1 +* cell instance $13 r0 *1 7.8,0 +X$13 6 12 9 6 10 9 INVX1 +* cell instance $14 r0 *1 9.6,0 +X$14 6 13 9 6 12 9 INVX1 +* cell instance $15 r0 *1 11.4,0 +X$15 6 14 9 6 13 9 INVX1 +* cell instance $16 r0 *1 13.2,0 +X$16 6 15 9 6 14 9 INVX1 +* cell instance $17 r0 *1 15,0 +X$17 6 11 9 6 15 9 INVX1 .ENDS RINGO * cell INVX2 diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 index b0e4b5871..609357e5f 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.1 @@ -711,7 +711,7 @@ layout( pin(4 6) pin(5 9) ) - circuit(17 INVX1 location(7800 0) + circuit(13 INVX1 location(7800 0) pin(0 6) pin(1 12) pin(2 9) @@ -719,7 +719,7 @@ layout( pin(4 10) pin(5 9) ) - circuit(18 INVX1 location(9600 0) + circuit(14 INVX1 location(9600 0) pin(0 6) pin(1 13) pin(2 9) @@ -727,7 +727,7 @@ layout( pin(4 12) pin(5 9) ) - circuit(19 INVX1 location(11400 0) + circuit(15 INVX1 location(11400 0) pin(0 6) pin(1 14) pin(2 9) @@ -735,7 +735,7 @@ layout( pin(4 13) pin(5 9) ) - circuit(20 INVX1 location(13200 0) + circuit(16 INVX1 location(13200 0) pin(0 6) pin(1 15) pin(2 9) @@ -743,7 +743,7 @@ layout( pin(4 14) pin(5 9) ) - circuit(21 INVX1 location(15000 0) + circuit(17 INVX1 location(15000 0) pin(0 6) pin(1 11) pin(2 9) @@ -1147,11 +1147,11 @@ xref( pin(4 0 match) circuit(2 2 match) circuit(3 3 match) - circuit(17 4 match) - circuit(18 5 match) - circuit(19 6 match) - circuit(20 7 match) - circuit(21 8 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) circuit(4 9 match) circuit(5 10 match) circuit(6 11 match) diff --git a/testdata/python/dbLayoutToNetlist.py b/testdata/python/dbLayoutToNetlist.py index 11e395309..f5faace5c 100644 --- a/testdata/python/dbLayoutToNetlist.py +++ b/testdata/python/dbLayoutToNetlist.py @@ -191,8 +191,8 @@ circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5); end; circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -272,8 +272,8 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -387,14 +387,14 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (); subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD); - subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD); - subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD); + subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21,$7=VDD); + subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5,$7=VDD); subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD); subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD); end; -circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1); - subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK); - subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK); +circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2,$7=$I1); + subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5,BULK=BULK); + subcircuit INV2 $2 ($1=$I1,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5,BULK=BULK); end; circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK); device PMOS $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); @@ -416,14 +416,14 @@ end; self.assertEqual(str(l2n.netlist()), """circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS); subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD); - subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD); - subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD); + subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21,$7=VDD); + subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5,$7=VDD); subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD); subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD); end; -circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1); - subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK); - subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK); +circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2,$7=$I1); + subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5,BULK=BULK); + subcircuit INV2 $2 ($1=$I1,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5,BULK=BULK); end; circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK); device PMOS $1 (S=$3,G=IN,D=VDD,B=$1) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); diff --git a/testdata/ruby/dbLayoutToNetlist.rb b/testdata/ruby/dbLayoutToNetlist.rb index 727ab064a..aed45f75b 100644 --- a/testdata/ruby/dbLayoutToNetlist.rb +++ b/testdata/ruby/dbLayoutToNetlist.rb @@ -227,8 +227,8 @@ circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5); end; circuit RINGO (); subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD); - subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD); - subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); + subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I37,$4=VSS,$5=VDD); + subcircuit INV2 $3 (IN=$I37,$2=$I39,OUT=$I1,$4=VSS,$5=VDD); subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD); subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD); subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD); @@ -309,8 +309,8 @@ END assert_equal(l2n.netlist.to_s, < Date: Tue, 29 Oct 2019 22:53:37 +0100 Subject: [PATCH 22/31] WIP: bugfix ambiguous bus-like pins and net compare. --- src/db/db/dbNetlistCompare.cc | 43 ++-- src/db/unit_tests/dbNetlistCompareTests.cc | 248 +++++++++++++++++++++ 2 files changed, 269 insertions(+), 22 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index e6f282df5..a80d705cd 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -660,12 +660,9 @@ public: std::string to_string () const { if (is_for_subcircuit ()) { - size_t pin_id1 = std::numeric_limits::max () - m_id1; - size_t pin_id2 = m_id2; const db::SubCircuit *sc = subcircuit_pair ().first; const db::Circuit *c = sc->circuit_ref (); - return std::string ("X") + sc->expanded_name () + " " + c->name () + " " - + "(" + c->pin_by_id (pin_id1)->expanded_name () + ")->(" + c->pin_by_id (pin_id2)->expanded_name () + ")"; + return std::string ("X") + sc->expanded_name () + " " + c->name (); } else { size_t term_id1 = m_id1; size_t term_id2 = m_id2; @@ -854,7 +851,7 @@ std::string indent (size_t depth) { std::string s; for (size_t d = 0; d < depth; ++d) { - s += " "; + s += "| "; } return s; } @@ -1599,6 +1596,11 @@ NetGraph::derive_node_identities_for_edges (NetGraphNode::edge_iterator e, NetGr } +#if defined(PRINT_DEBUG_NETCOMPARE) + if (! new_nodes) { + tl::info << indent(depth) << "! no updates."; + } +#endif return new_nodes; } @@ -1774,18 +1776,15 @@ size_t NetGraph::derive_node_identities_from_node_set (std::vector &nodes, std::vector &other_nodes, size_t depth, size_t n_branch, TentativeNodeMapping *tentative, bool with_ambiguous, CompareData *data) { #if defined(PRINT_DEBUG_NETCOMPARE) - std::string indent; - for (size_t d = 0; d < depth; ++d) { - indent += " "; - } - indent += "*" + tl::to_string (n_branch) + " "; + std::string indent_s = indent (depth); + indent_s += "*" + tl::to_string (n_branch) + " "; #endif size_t new_nodes = 0; if (depth > data->max_depth) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "max. depth exhausted (" << depth + 1 << ">" << data->max_depth << ")"; + tl::info << indent_s << "max. depth exhausted (" << depth + 1 << ">" << data->max_depth << ")"; #endif return std::numeric_limits::max (); } @@ -1803,7 +1802,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorother, other_ni); #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name (); + tl::info << indent_s << "deduced match (singular): " << nodes.front ()->net ()->expanded_name () << " vs. " << other_nodes.front ()->net ()->expanded_name (); #endif if (data->logger && ! tentative) { if (! (node (ni) == data->other->node (other_ni))) { @@ -1948,7 +1947,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectordont_consider_net_names && net_names_are_different ((*nr->n1)->net (), (*nr->n2)->net ())) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "rejecting pair as names are not identical: " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); + 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::max (); } @@ -1962,7 +1961,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorother, other_ni); #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); + tl::info << indent_s << "deduced match (singular): " << (*nr->n1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); #endif if (data->logger && ! tentative) { if (! (node (ni) == data->other->node (other_ni))) { @@ -2000,14 +1999,14 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum * n_branch > data->max_n_branch) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch."; + tl::info << indent_s << "max. complexity exhausted (" << nr->num << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch."; #endif return std::numeric_limits::max (); } else { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "analyzing ambiguity group with " << nr->num << " members"; + tl::info << indent_s << "analyzing ambiguity group with " << nr->num << " members"; #endif // sort the ambiguity group such that net names @@ -2047,14 +2046,14 @@ NetGraph::derive_node_identities_from_node_set (std::vectornet ()->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); if (bt_count != std::numeric_limits::max ()) { #if defined(PRINT_DEBUG_NETCOMPARE) - tl::info << indent << "match found"; + tl::info << indent_s << "match found"; #endif // we have a match ... @@ -2080,7 +2079,7 @@ NetGraph::derive_node_identities_from_node_set (std::vector::max (); @@ -2101,9 +2100,9 @@ NetGraph::derive_node_identities_from_node_set (std::vectorsecond)) { - tl::info << indent << "deduced ambiguous match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); + tl::info << indent_s << "deduced ambiguous match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); } else { - tl::info << indent << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); + tl::info << indent_s << "deduced match: " << p->first->net ()->expanded_name () << " vs. " << p->second->net ()->expanded_name (); } #endif if (data->logger) { @@ -2142,7 +2141,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum << " members"; + tl::info << indent_s << "finished analysis of ambiguity group with " << nr->num << " members"; #endif } diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 22f61046a..13bff2075 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -3003,3 +3003,251 @@ TEST(19_SymmetricCircuit) ); EXPECT_EQ (good, true); } + +TEST(20_BusLikeConnections) +{ + // Test test requires a certain depth and tests the backtracking paths. + + const char *nls1 = + "circuit INV (IN=IN,OUT=OUT,VDD=VDD,VSS=VSS);\n" + " device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + "end;\n" + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I1 (IN=IN1,OUT=OUT1,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I2 (IN=IN2,OUT=OUT2,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I3 (IN=IN3,OUT=OUT3,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I4 (IN=IN4,OUT=OUT4,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I5 (IN=IN5,OUT=OUT5,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I6 (IN=IN6,OUT=OUT6,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I7 (IN=IN7,OUT=OUT7,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I8 (IN=IN8,OUT=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit INV8_WRAP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + const char *nls2 = + "circuit INV (OUT=OUT,IN=IN,VDD=VDD,VSS=VSS);\n" + " device PMOS $1 (S=VDD,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + " device NMOS $2 (S=VSS,G=IN,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n" + "end;\n" + "circuit INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I1 (OUT=Q1,IN=A1,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I8 (OUT=Q8,IN=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I3 (OUT=Q3,IN=A3,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I7 (OUT=Q7,IN=A7,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I4 (OUT=Q4,IN=A4,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I2 (OUT=Q2,IN=A2,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I6 (OUT=Q6,IN=A6,VDD=VDD,VSS=VSS);\n" + " subcircuit INV I5 (OUT=Q5,IN=A5,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit INV8_WRAP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "begin_circuit INV INV\n" + "match_nets VDD VDD\n" + "match_nets OUT OUT\n" + "match_nets IN IN\n" + "match_nets VSS VSS\n" + "match_pins IN IN\n" + "match_pins OUT OUT\n" + "match_pins VDD VDD\n" + "match_pins VSS VSS\n" + "match_devices $1 $1\n" + "match_devices $2 $2\n" + "end_circuit INV INV MATCH\n" + "begin_circuit INV8 INV8\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\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_nets OUT1 Q1\n" + "match_nets OUT2 Q2\n" + "match_nets OUT3 Q3\n" + "match_nets OUT4 Q4\n" + "match_nets OUT5 Q5\n" + "match_nets OUT6 Q6\n" + "match_nets OUT7 Q7\n" + "match_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 I1 I1\n" + "match_subcircuits I8 I8\n" + "match_subcircuits I3 I3\n" + "match_subcircuits I7 I7\n" + "match_subcircuits I4 I4\n" + "match_subcircuits I2 I2\n" + "match_subcircuits I6 I6\n" + "match_subcircuits I5 I5\n" + "end_circuit INV8 INV8 MATCH\n" + "begin_circuit INV8_WRAP INV8_WRAP\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 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); +} + +TEST(21_BusLikeAmbiguousConnections) +{ + // Test test requires a certain depth and tests the backtracking paths. + + const char *nls1 = + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + // NOTE: passive nets make the pins ambiguous + "end;\n" + "circuit INV8_WRAP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + const char *nls2 = + "circuit INV8 (IN1=IN1,OUT1=OUT1,IN2=IN2,OUT2=OUT2,IN3=IN3,OUT3=OUT3,IN4=IN4,OUT4=OUT4,IN5=IN5,OUT5=OUT5,IN6=IN6,OUT6=OUT6,IN7=IN7,OUT7=OUT7,IN8=IN8,OUT8=OUT8,VDD=VDD,VSS=VSS);\n" + // NOTE: passive nets make the pins ambiguous + "end;\n" + "circuit INV8_WRAP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8 INV8 (IN1=A1,OUT1=Q1,IN2=A2,OUT2=Q2,IN3=A3,OUT3=Q3,IN4=A4,OUT4=Q4,IN5=A5,OUT5=Q5,IN6=A6,OUT6=Q6,IN7=A7,OUT7=Q7,IN8=A8,OUT8=Q8,VDD=VDD,VSS=VSS);\n" + "end;\n" + "circuit TOP (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + " subcircuit INV8_WRAP INV8 (Q1=Q1,A1=A1,Q2=Q2,A2=A2,Q3=Q3,A3=A3,Q4=Q4,A4=A4,Q5=Q5,A5=A5,Q6=Q6,A6=A6,Q7=Q7,A7=A7,Q8=Q8,A8=A8,VDD=VDD,VSS=VSS);\n" + "end;\n" + ; + + db::Netlist nl1, nl2; + prep_nl (nl1, nls1); + prep_nl (nl2, nls2); + + NetlistCompareTestLogger logger; + db::NetlistComparer comp (&logger); + + bool good = comp.compare (&nl1, &nl2); + + std::string txt = logger.text (); + + EXPECT_EQ (txt, + "" + ); + EXPECT_EQ (good, true); +} + From 3cc38fcfc2a26941ec2e362433981480c62e5c03 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 29 Oct 2019 23:26:17 +0100 Subject: [PATCH 23/31] Solved ambiguous bus resolution problem. --- src/db/db/dbNetlistCompare.cc | 348 ++++++++++++++------- src/db/unit_tests/dbNetlistCompareTests.cc | 117 ++++++- 2 files changed, 347 insertions(+), 118 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index a80d705cd..9b21eda88 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -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::max (); + +// A constant indicating an unknown match +// const size_t unknown_match = std::numeric_limits::max () - 1; + +// A constant indicating an invalid ID +const size_t invalid_id = std::numeric_limits::max (); + +// A constant indicating an unknown ID +const size_t unknown_id = std::numeric_limits::max () - 1; + namespace db { @@ -748,7 +760,17 @@ public: bool has_other () const { - return m_other_net_index != std::numeric_limits::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::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 *circuit_map, const CircuitPinMapper *pin_map) - : mp_net (net), m_other_net_index (std::numeric_limits::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 *circuit_map, const CircuitPinMapper *pin_map) - : mp_net (0), m_other_net_index (std::numeric_limits::max ()) + : mp_net (0), m_other_net_index (invalid_id) { std::map n2entry; @@ -1250,7 +1272,7 @@ NetGraphNode::to_string () const res += "(null)"; } res += "]"; - if (m_other_net_index != std::numeric_limits::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 >::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 >::const_iterator i = m_to_undo.begin (); i != m_to_undo.end (); ++i) { + i->first->unidentify (i->second); + } + for (std::vector >::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 > m_to_undo; - NetGraph *mp_g1, *mp_g2; + std::vector > 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::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::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::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::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" << data->max_depth << ")"; #endif - return std::numeric_limits::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::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::vectorhas_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::max (); + return failed_match; } } else { // mismatch of assignment state - return std::numeric_limits::max (); + return failed_match; } @@ -1851,10 +1901,10 @@ NetGraph::derive_node_identities_from_node_set (std::vectorhas_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::vectorhas_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 1 && tentative && ! with_ambiguous) { - return std::numeric_limits::max (); + return failed_match; } n1 = nn1; @@ -1910,9 +1960,9 @@ NetGraph::derive_node_identities_from_node_set (std::vectorn1 != 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_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::vectornum == 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::vectorn1)->net ()->expanded_name () << " vs. " << (*nr->n2)->net ()->expanded_name (); #endif - return std::numeric_limits::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::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::max (); + return failed_match; } } else { // mismatch of assignment state - return std::numeric_limits::max (); + return failed_match; } @@ -2001,7 +2055,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum << "*" << n_branch << ">" << data->max_n_branch << ") - mismatch."; #endif - return std::numeric_limits::max (); + return failed_match; } else { @@ -2009,7 +2063,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectornum << " members"; #endif - // sort the ambiguity group such that net names + // sort the ambiguity group such that net names match best std::vector > pairs; tl::equivalence_clusters equivalent_other_nodes; @@ -2019,70 +2073,91 @@ NetGraph::derive_node_identities_from_node_set (std::vector::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::const_iterator> iters1, iters2; + + for (std::vector::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_iterator i2; - for (i2 = nr->n2; i2 != nr->nn2; ++i2) { - - if ((*i2)->has_other ()) { - continue; + for (std::vector::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::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_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::const_iterator>::const_iterator ii2 = iters2.begin (); ii2 != iters2.end (); ++ii2) { + + std::vector::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::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::max (); + // a mismatch - stop here. + return failed_match; + } + } } @@ -2123,7 +2198,7 @@ NetGraph::derive_node_identities_from_node_set (std::vectorfirst->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::max ()); + tl_assert (bt_count != failed_match); } @@ -2595,7 +2670,7 @@ struct DeviceConnectionDistance { int d = 0.0; for (std::vector >::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::max () || j->second == std::numeric_limits::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 &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_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::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_iterator n = nodes.begin (); n != nodes.end () && good; ++n) { + good = is_passive_net ((*n)->net (), c12_circuit_and_pin_mapping); + } + for (std::vector::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::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 > 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 > 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 floating_pin_name_mapping; - for (std::map >::const_iterator i = floating_pins_by_name.begin (); i != floating_pins_by_name.end (); ++i) { + std::map abstract_pin_name_mapping; + for (std::map >::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 floating_pins; + std::vector abstract_pins; std::multimap 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::iterator next_float = floating_pins.begin (); + std::vector::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_iterator fp = floating_pin_name_mapping.find (p.operator-> ()); - if (fp != floating_pin_name_mapping.end ()) { + std::map::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::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 >::iterator i = k.begin (); i != k.end (); ++i) { if (! g1.begin () [i->second].has_other ()) { - i->second = std::numeric_limits::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 >::iterator i = k.begin (); i != k.end (); ++i) { if (! g2.begin () [i->second].has_other ()) { - i->second = std::numeric_limits::max (); // normalization + i->second = invalid_id; // normalization mapped = false; } else { i->second = g2.begin () [i->second].other_net_index (); diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 13bff2075..820b61b1f 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -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); } From 73556d6edcea9501a7e4029443c3033e792c339e Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 30 Oct 2019 23:55:08 +0100 Subject: [PATCH 24/31] Netlist compare issue fixed In tentative mode, node equivalence shall not be assumed if the nodes have edges which don't appear in the other node. --- src/db/db/dbNetlistCompare.cc | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index 9b21eda88..bdfdc1943 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -32,7 +32,7 @@ // verbose debug output // TODO: make this a feature? -// #define PRINT_DEBUG_NETCOMPARE +#define PRINT_DEBUG_NETCOMPARE // verbose net graph output // TODO: make this a feature? @@ -1676,6 +1676,9 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc tl::info << indent(depth) << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); } else { tl::info << indent(depth) << "tentatively deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); +if (n->net()->expanded_name() == "$I30" && n_other->net ()->expanded_name () == "DWSA_0") { +printf("@@@ BANG!\n"); +} } #endif @@ -1730,12 +1733,46 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc new_nodes += bt_count; } + } else if (tentative) { + // in tentative mode an exact match is required: no having the same edges for a node disqualifies the node + // as matching. +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair for missing edge."; +#endif + return failed_match; } e = ee; } + if (tentative) { + + // in tentative mode, again an exact match is required + + for (NetGraphNode::edge_iterator e_other = n_other->begin (); e_other != n_other->end (); ) { + + NetGraphNode::edge_iterator ee_other = e_other; + ++ee_other; + + while (ee_other != n_other->end () && ee_other->first == e_other->first) { + ++ee_other; + } + + NetGraphNode::edge_iterator e = n->find_edge (e_other->first); + if (e == n->end ()) { +#if defined(PRINT_DEBUG_NETCOMPARE) + tl::info << indent(depth) << "! rejected pair for missing edge."; +#endif + return failed_match; + } + + e_other = ee_other; + + } + + } + #if defined(PRINT_DEBUG_NETCOMPARE) if (! tentative && new_nodes > 0) { tl::info << indent(depth) << "finished pair deduction: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name () << " with " << new_nodes << " new pairs"; From 679aecd11fa7ec38fdec8407073ff7e0dfbb6b55 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 31 Oct 2019 00:51:54 +0100 Subject: [PATCH 25/31] Removed debug output. --- src/db/db/dbNetlistCompare.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index bdfdc1943..7ca7590b2 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -32,7 +32,7 @@ // verbose debug output // TODO: make this a feature? -#define PRINT_DEBUG_NETCOMPARE +// #define PRINT_DEBUG_NETCOMPARE // verbose net graph output // TODO: make this a feature? @@ -1676,9 +1676,6 @@ NetGraph::derive_node_identities (size_t net_index, size_t depth, size_t n_branc tl::info << indent(depth) << "deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); } else { tl::info << indent(depth) << "tentatively deducing from pair: " << n->net ()->expanded_name () << " vs. " << n_other->net ()->expanded_name (); -if (n->net()->expanded_name() == "$I30" && n_other->net ()->expanded_name () == "DWSA_0") { -printf("@@@ BANG!\n"); -} } #endif @@ -2787,7 +2784,7 @@ 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. + * A passive net does not have devices nor pins except those which are ignored (not mapped). */ static bool is_passive_net (const db::Net *net, const std::map &circuit_and_pin_mapping) { @@ -2800,7 +2797,7 @@ static bool is_passive_net (const db::Net *net, const std::mapbegin_subcircuit_pins (); p != net->end_subcircuit_pins (); ++p) { - const db::Circuit *c = p->subcircuit ()->circuit (); + const db::Circuit *c = p->subcircuit ()->circuit_ref (); std::map::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 ())) { From 627b248f7e683c1897f9dc25686ba2e91f0ccaca Mon Sep 17 00:00:00 2001 From: klayoutmatthias Date: Sat, 2 Nov 2019 01:26:37 +0100 Subject: [PATCH 26/31] Enhanced compatibility between platforms (problem was: order of execution of argument expressions) --- src/db/db/dbHierNetworkProcessor.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 4ab81f142..3c85dc9be 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1474,7 +1474,12 @@ private: } for (std::vector >::const_iterator ii = interactions->begin (); ii != interactions->end (); ++ii) { - interacting_clusters.push_back (std::make_pair (make_path (ii->first, p1), make_path (ii->second, p2))); + + ClusterInstance k1 = make_path (ii->first, p1); + ClusterInstance k2 = make_path (ii->second, p2); + + interacting_clusters.push_back (std::make_pair (k1, k2)); + } } From 7910ddc6a339f0846074429440c2c0bf7cce96e7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 2 Nov 2019 20:39:59 +0100 Subject: [PATCH 27/31] Fixed a compiler warning, testcase update (part 1) --- src/db/db/dbLibrary.cc | 2 +- ...act_au10.gds => device_extract_au10.gds.1} | Bin testdata/algo/device_extract_au10.gds.2 | Bin 0 -> 8894 bytes testdata/lvs/invchain_cheat.cir.1 | 30 +++++++++++++ testdata/lvs/invchain_cheat.cir.2 | 30 +++++++++++++ .../lvs/ringo_simple_dummy_device.lvsdb.2 | 12 ++--- .../lvs/ringo_simple_simplification.lvsdb.2 | 22 ++++----- ...o_simple_simplification_with_align.lvsdb.2 | 42 +++++++++--------- 8 files changed, 99 insertions(+), 39 deletions(-) rename testdata/algo/{device_extract_au10.gds => device_extract_au10.gds.1} (100%) create mode 100644 testdata/algo/device_extract_au10.gds.2 create mode 100644 testdata/lvs/invchain_cheat.cir.1 create mode 100644 testdata/lvs/invchain_cheat.cir.2 diff --git a/src/db/db/dbLibrary.cc b/src/db/db/dbLibrary.cc index 71989274e..008af5085 100644 --- a/src/db/db/dbLibrary.cc +++ b/src/db/db/dbLibrary.cc @@ -36,7 +36,7 @@ Library::Library() } Library::Library(const Library &d) - : gsi::ObjectBase (), m_name (d.m_name), m_description (d.m_description), m_id (0), m_layout (d.m_layout) + : gsi::ObjectBase (), tl::Object (), m_name (d.m_name), m_description (d.m_description), m_id (0), m_layout (d.m_layout) { // .. nothing yet .. } diff --git a/testdata/algo/device_extract_au10.gds b/testdata/algo/device_extract_au10.gds.1 similarity index 100% rename from testdata/algo/device_extract_au10.gds rename to testdata/algo/device_extract_au10.gds.1 diff --git a/testdata/algo/device_extract_au10.gds.2 b/testdata/algo/device_extract_au10.gds.2 new file mode 100644 index 0000000000000000000000000000000000000000..6b279ff1937d3fc78bccf465b7163456ca82f615 GIT binary patch literal 8894 zcmc&)&1+m$6hHH3=4CRSPGXv-#zv_!f{Rj{rk{wVsVOwHrp3gf#S&a}>&m4Ci*@0~ ze?S5ev4ZYIMf{?O6ltYO-H0tEpbP0j>b76c-?`_Wckg@iX6C(z(m?oybMNn-k9+Pt z=RQIq1;I-+RSAavpmh`w(N=2ve^Vm}kIo+?8n4#(&%U$g$iDBj6F40uI zH*Yiy7Y;2gFTF6ku(;frp<06|Tp!S73fo4{Xf=wWx1#9o8Y5A43$&k6R5>Hn9wMp@ zQ2~8BVtqe3eMFTfqUio5!RS2jK6G1DInd~{_NMr-@g(!{yPNqARSxv|SA6|+9s18< zjqBjOK@`j>s@!04f2Xtj#aaP=F9}BHfj8J+L6!IRmwD{3U}ZP+*k3`F_x3l6?tO!~ z=NQ>f=PNS_g4Lcx2CYELHQ)tBl^e_xU0>U-SliX4 zHlpE;qOEmVv?;0_SXA52ENwUi2Uwe6>$02}MU|^Io4HsB)ms|HbK#qT4uC!`lQ~pAyw^ zyC|xBcw6CUxjV(nB#x5F6ca5zWgIO*l^gV}O?iv)ui0Dd;pgnFLzM&j@L|IdiB{#1 zL`zZSK%bwA7WD6zXjQ(KXbGyEF;}!&VK~=Wc>dU8Co@(!EvK*+PTjpz93%LNI_IA{ z8Bf^SH`cVueE7f0>&AQG``T4sS-`824 zj;#8>JT<#|Jh`jheNk#xJ$|>Z4|-SG*LYVwOH1vl$M5#^0q!dD*Yu+3B%4H|V}5r! zO|8)?td$>g8oK7}$T4T8dycK8fq!2oYjL_y(WuLXNK7F6H-{Z60h#&e(t=I93+P<*uxPN{ooPK!|v!Be< zH?gA1Q~oFT;-~XlML1MZvV@a+7;a%bATRlE+GX!G0f4|~p7$Ju}Mv_q8x zjn9R3ZjbxRgw8SO;}|p6?hs9W=TPOqQablxDVy5~o$dF5$`W$4l8f z)5GRA_L6O5WSd7mcBt}xab9;;;>^f#9=Ym}<7~%E*^Dq`#<_yHux*TNb8yk2%6r?4 zI~;bIuhKxaIr!V5%3*sMo97p>l+6wAenao`kLYBq-9ZoVgG1ISIXj~`7tXs?z-6ns)|^HZ@8Yu9;^1VZ)7#M zMtljv+sf2UPpf@LHJ?I#UXwTuwrJ`vy`bQAYPvAaLPFH!Fj{1P=j!7tI*B={wIIq!Q}vD#dkxuplp2%au@{%{C;xAR<>MQM;hWoT t@<&rIFz>|TVxM`fKl9JS7dKvSZm!RItT)d*Tg?XA$Me$bp;M^U=wF|Yo?8F_ literal 0 HcmV?d00001 diff --git a/testdata/lvs/invchain_cheat.cir.1 b/testdata/lvs/invchain_cheat.cir.1 new file mode 100644 index 000000000..ebb1e0e31 --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.1 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$9 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$9 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/invchain_cheat.cir.2 b/testdata/lvs/invchain_cheat.cir.2 new file mode 100644 index 000000000..559a90f2a --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.2 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$8 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$8 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 b/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 index f4780ff2d..3c0b06564 100644 --- a/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 +++ b/testdata/lvs/ringo_simple_dummy_device.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -371,9 +371,9 @@ layout( net(2 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 rect(l8 (6510 3010) (180 180)) diff --git a/testdata/lvs/ringo_simple_simplification.lvsdb.2 b/testdata/lvs/ringo_simple_simplification.lvsdb.2 index 2492067a3..77e688c6e 100644 --- a/testdata/lvs/ringo_simple_simplification.lvsdb.2 +++ b/testdata/lvs/ringo_simple_simplification.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -389,8 +389,8 @@ layout( rect(l11 (1100 -300) (300 300)) rect(l11 (-1101 399) (2 2)) rect(l11 (799 -2101) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) ) net(3 name(OUT) rect(l8 (1110 5160) (180 180)) @@ -486,9 +486,9 @@ layout( net(1 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(2 rect(l8 (6510 3010) (180 180)) @@ -554,9 +554,9 @@ layout( rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) - rect(l2 (4550 -1500) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l2 (-3600 -1500) (425 1500)) rect(l9 (-19575 -450) (500 1500)) rect(l9 (22900 -1500) (500 1500)) ) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 index 2492067a3..909c14e3d 100644 --- a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.2 @@ -163,9 +163,9 @@ layout( rect(l11 (-1751 1099) (300 1400)) rect(l11 (1100 -1700) (300 300)) rect(l11 (-300 0) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(3 name(VSS) rect(l8 (410 1770) (180 180)) @@ -389,8 +389,8 @@ layout( rect(l11 (1100 -300) (300 300)) rect(l11 (-1101 399) (2 2)) rect(l11 (799 -2101) (300 1400)) - rect(l2 (-375 -1450) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-1750 -1450) (425 1500)) + rect(l2 (950 -1500) (425 1500)) ) net(3 name(OUT) rect(l8 (1110 5160) (180 180)) @@ -486,9 +486,9 @@ layout( net(1 rect(l8 (4710 3010) (180 180)) rect(l11 (-850 -240) (610 300)) - rect(l2 (-1175 1800) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l6 (950 -4890) (425 950)) + rect(l2 (-2550 1800) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l6 (-425 -4890) (425 950)) ) net(2 rect(l8 (6510 3010) (180 180)) @@ -554,9 +554,9 @@ layout( rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) rect(l2 (1375 -1500) (425 1500)) - rect(l2 (4550 -1500) (425 1500)) - rect(l2 (-1800 -1500) (425 1500)) - rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (950 -1500) (425 1500)) + rect(l2 (-3600 -1500) (425 1500)) rect(l9 (-19575 -450) (500 1500)) rect(l9 (22900 -1500) (500 1500)) ) @@ -711,7 +711,7 @@ layout( pin(4 6) pin(5 9) ) - circuit(17 INVX1 location(7800 0) + circuit(13 INVX1 location(7800 0) pin(0 6) pin(1 12) pin(2 9) @@ -719,7 +719,7 @@ layout( pin(4 10) pin(5 9) ) - circuit(18 INVX1 location(9600 0) + circuit(14 INVX1 location(9600 0) pin(0 6) pin(1 13) pin(2 9) @@ -727,7 +727,7 @@ layout( pin(4 12) pin(5 9) ) - circuit(19 INVX1 location(11400 0) + circuit(15 INVX1 location(11400 0) pin(0 6) pin(1 14) pin(2 9) @@ -735,7 +735,7 @@ layout( pin(4 13) pin(5 9) ) - circuit(20 INVX1 location(13200 0) + circuit(16 INVX1 location(13200 0) pin(0 6) pin(1 15) pin(2 9) @@ -743,7 +743,7 @@ layout( pin(4 14) pin(5 9) ) - circuit(21 INVX1 location(15000 0) + circuit(17 INVX1 location(15000 0) pin(0 6) pin(1 11) pin(2 9) @@ -1147,11 +1147,11 @@ xref( pin(4 0 match) circuit(2 2 match) circuit(3 3 match) - circuit(17 4 match) - circuit(18 5 match) - circuit(19 6 match) - circuit(20 7 match) - circuit(21 8 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) circuit(4 9 match) circuit(5 10 match) circuit(6 11 match) From 5d2528a4507d07dc441f2e6d0059668fed2b7928 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 2 Nov 2019 20:46:32 +0100 Subject: [PATCH 28/31] Fixed unit tests for Windows --- testdata/buddies/buddies.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testdata/buddies/buddies.rb b/testdata/buddies/buddies.rb index 2cdfbbb7f..982111f61 100644 --- a/testdata/buddies/buddies.rb +++ b/testdata/buddies/buddies.rb @@ -72,7 +72,7 @@ class Buddies_TestClass < TestBase assert_equal(File.exists?(out_file), true) assert_equal(log, bin + "\n") - File.open(out_file, "rb") do |file| + File.open(out_file, "r") do |file| sig = file.read(4).unpack('N').first assert_equal(sig, signatures[bin]) end From 388e555fbca0324342c1e80fe310a7820c93fb5f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 Nov 2019 00:09:26 +0100 Subject: [PATCH 29/31] Another attempt to fix unit tests on Windows (CRLF/LF issue) --- testdata/buddies/buddies.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testdata/buddies/buddies.rb b/testdata/buddies/buddies.rb index 982111f61..4f3caddaa 100644 --- a/testdata/buddies/buddies.rb +++ b/testdata/buddies/buddies.rb @@ -56,6 +56,11 @@ class Buddies_TestClass < TestBase "strm2txt" => 0x62656769, } + # Windows CRLF -> LF translation + signature_equiv = { + 0x300d0a53 => 0x300a5345 + } + %w(strm2cif strm2dxf strm2gds strm2gdstxt strm2oas strm2txt).each do |bin| puts "Testing #{bin} ..." @@ -72,8 +77,9 @@ class Buddies_TestClass < TestBase assert_equal(File.exists?(out_file), true) assert_equal(log, bin + "\n") - File.open(out_file, "r") do |file| + File.open(out_file, "rb") do |file| sig = file.read(4).unpack('N').first + sig = signature_equiv[sig] || sig assert_equal(sig, signatures[bin]) end From 3dffe91f8899ea1252137f06110c1eca61095500 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 Nov 2019 02:30:52 +0100 Subject: [PATCH 30/31] Attempt to fix testdata for MSVC --- testdata/algo/lvs_test1_au.lvsdb.2 | 92 +- testdata/algo/lvs_test2_au.lvsdb.2 | 163 ++- testdata/lvs/invchain_cheat.cir.3 | 30 + ...out_var.lvsdb => ringo_layout_var.lvsdb.1} | 0 testdata/lvs/ringo_layout_var.lvsdb.2 | 1076 +++++++++++++++ .../lvs/ringo_simple_dummy_device.lvsdb.3 | 1028 +++++++++++++++ .../lvs/ringo_simple_simplification.lvsdb.3 | 1162 +++++++++++++++++ ...o_simple_simplification_with_align.lvsdb.3 | 1162 +++++++++++++++++ 8 files changed, 4601 insertions(+), 112 deletions(-) create mode 100644 testdata/lvs/invchain_cheat.cir.3 rename testdata/lvs/{ringo_layout_var.lvsdb => ringo_layout_var.lvsdb.1} (100%) create mode 100644 testdata/lvs/ringo_layout_var.lvsdb.2 create mode 100644 testdata/lvs/ringo_simple_dummy_device.lvsdb.3 create mode 100644 testdata/lvs/ringo_simple_simplification.lvsdb.3 create mode 100644 testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 diff --git a/testdata/algo/lvs_test1_au.lvsdb.2 b/testdata/algo/lvs_test1_au.lvsdb.2 index dac6d562b..bba5f19c4 100644 --- a/testdata/algo/lvs_test1_au.lvsdb.2 +++ b/testdata/algo/lvs_test1_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test2_au.lvsdb.2 b/testdata/algo/lvs_test2_au.lvsdb.2 index 84e349abc..7ceccdcd8 100644 --- a/testdata/algo/lvs_test2_au.lvsdb.2 +++ b/testdata/algo/lvs_test2_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -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(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 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(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 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/lvs/invchain_cheat.cir.3 b/testdata/lvs/invchain_cheat.cir.3 new file mode 100644 index 000000000..be921871d --- /dev/null +++ b/testdata/lvs/invchain_cheat.cir.3 @@ -0,0 +1,30 @@ +* Extracted by KLayout + +.SUBCKT INVCHAIN +X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3 +X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2 +X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV +.ENDS INVCHAIN + +.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2 +X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV +X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV +X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV +.ENDS INV3 + +.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5 ++ \$I4 \$I2 +X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV +X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV +.ENDS INV2 + +.SUBCKT INV \$1 \$2 \$3 \$4 \$7 \$10 \$I8 \$I7 +M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$2 \$2 \$I8 \$7 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U ++ PD=1.5U +M$4 \$1 \$I7 \$10 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U ++ PD=1.97U +.ENDS INV diff --git a/testdata/lvs/ringo_layout_var.lvsdb b/testdata/lvs/ringo_layout_var.lvsdb.1 similarity index 100% rename from testdata/lvs/ringo_layout_var.lvsdb rename to testdata/lvs/ringo_layout_var.lvsdb.1 diff --git a/testdata/lvs/ringo_layout_var.lvsdb.2 b/testdata/lvs/ringo_layout_var.lvsdb.2 new file mode 100644 index 000000000..f7ed4588d --- /dev/null +++ b/testdata/lvs/ringo_layout_var.lvsdb.2 @@ -0,0 +1,1076 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX1B + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23025 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-20175 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(13 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(15 name(VSS) + rect(l8 (1110 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-21741 -391) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-23700 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-20175 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(11 name(FB)) + pin(12 name(VDD)) + pin(13 name(OUT)) + pin(14 name(ENABLE)) + pin(15 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 12) + pin(1 1) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 14) + pin(6 15) + ) + circuit(2 INVX1B location(4200 0) + pin(0 12) + pin(1 2) + pin(2 15) + pin(3 12) + pin(4 1) + pin(5 15) + ) + circuit(3 INVX1 location(6000 0) + pin(0 12) + pin(1 3) + pin(2 15) + pin(3 12) + pin(4 2) + pin(5 15) + ) + circuit(4 INVX1B location(7800 0) + pin(0 12) + pin(1 4) + pin(2 15) + pin(3 12) + pin(4 3) + pin(5 15) + ) + circuit(5 INVX1 location(9600 0) + pin(0 12) + pin(1 5) + pin(2 15) + pin(3 12) + pin(4 4) + pin(5 15) + ) + circuit(6 INVX1B location(11400 0) + pin(0 12) + pin(1 6) + pin(2 15) + pin(3 12) + pin(4 5) + pin(5 15) + ) + circuit(7 INVX1 location(13200 0) + pin(0 12) + pin(1 7) + pin(2 15) + pin(3 12) + pin(4 6) + pin(5 15) + ) + circuit(8 INVX1 location(15000 0) + pin(0 12) + pin(1 8) + pin(2 15) + pin(3 12) + pin(4 7) + pin(5 15) + ) + circuit(9 INVX1 location(16800 0) + pin(0 12) + pin(1 9) + pin(2 15) + pin(3 12) + pin(4 8) + pin(5 15) + ) + circuit(10 INVX1 location(18600 0) + pin(0 12) + pin(1 10) + pin(2 15) + pin(3 12) + pin(4 9) + pin(5 15) + ) + circuit(11 INVX1 location(20400 0) + pin(0 12) + pin(1 11) + pin(2 15) + pin(3 12) + pin(4 10) + pin(5 15) + ) + circuit(12 INVX1 location(22200 0) + pin(0 12) + pin(1 13) + pin(2 15) + pin(3 12) + pin(4 11) + pin(5 15) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX1B INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(10 15 match) + net(2 7 match) + net(3 8 match) + net(4 9 match) + net(5 10 match) + net(6 11 match) + net(7 12 match) + net(8 13 match) + net(9 14 match) + net(14 4 match) + net(11 3 match) + net(13 5 match) + net(12 2 match) + net(15 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(3 3 match) + circuit(5 5 match) + circuit(7 7 match) + circuit(8 8 match) + circuit(9 9 match) + circuit(10 10 match) + circuit(11 11 match) + circuit(12 12 match) + circuit(2 2 match) + circuit(4 4 match) + circuit(6 6 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 b/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 new file mode 100644 index 000000000..f4780ff2d --- /dev/null +++ b/testdata/lvs/ringo_simple_dummy_device.lvsdb.3 @@ -0,0 +1,1028 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS$1 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$2 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((0 350) (27600 7650)) + + # Nets with their geometries + net(1 + rect(l4 (26050 2800) (525 550)) + rect(l4 (-525 -300) (300 300)) + rect(l4 (-25 -2000) (250 1450)) + rect(l8 (-465 310) (180 180)) + rect(l11 (-240 -240) (300 300)) + ) + net(2 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(7 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(8 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(9 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(10 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 name(VDD) + rect(l3 (500 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l3 (0 -3500) (600 3500)) + rect(l8 (-26490 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-21741 859) (2 2)) + rect(l11 (-2351 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l2 (-24825 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l9 (-21975 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(14 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(16 name(VSS) + rect(l8 (26010 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (520 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-25780 -890) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (1260 -40) (300 1360)) + rect(l11 (400 -1360) (300 1360)) + rect(l11 (-24001 -1711) (2 2)) + rect(l11 (-1901 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l11 (0 -800) (600 800)) + rect(l6 (-25500 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3650 -1010) (425 950)) + rect(l6 (-1100 -950) (425 950)) + rect(l10 (-25375 -2150) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + + # Outgoing pins and their connections to nets + pin(12 name(FB)) + pin(13 name(VDD)) + pin(14 name(OUT)) + pin(15 name(ENABLE)) + pin(16 name(VSS)) + + # Devices and their connections + device(1 D$NMOS + location(26450 2075) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 16) + terminal(G 1) + terminal(D 16) + terminal(B 16) + ) + + # Subcircuits and their connections + circuit(3 ND2X1 location(1800 0) + pin(0 13) + pin(1 2) + pin(2 16) + pin(3 13) + pin(4 12) + pin(5 15) + pin(6 16) + ) + circuit(4 INVX1 location(4200 0) + pin(0 13) + pin(1 3) + pin(2 16) + pin(3 13) + pin(4 2) + pin(5 16) + ) + circuit(5 INVX1 location(6000 0) + pin(0 13) + pin(1 4) + pin(2 16) + pin(3 13) + pin(4 3) + pin(5 16) + ) + circuit(6 INVX1 location(7800 0) + pin(0 13) + pin(1 5) + pin(2 16) + pin(3 13) + pin(4 4) + pin(5 16) + ) + circuit(7 INVX1 location(9600 0) + pin(0 13) + pin(1 6) + pin(2 16) + pin(3 13) + pin(4 5) + pin(5 16) + ) + circuit(8 INVX1 location(11400 0) + pin(0 13) + pin(1 7) + pin(2 16) + pin(3 13) + pin(4 6) + pin(5 16) + ) + circuit(9 INVX1 location(13200 0) + pin(0 13) + pin(1 8) + pin(2 16) + pin(3 13) + pin(4 7) + pin(5 16) + ) + circuit(10 INVX1 location(15000 0) + pin(0 13) + pin(1 9) + pin(2 16) + pin(3 13) + pin(4 8) + pin(5 16) + ) + circuit(11 INVX1 location(16800 0) + pin(0 13) + pin(1 10) + pin(2 16) + pin(3 13) + pin(4 9) + pin(5 16) + ) + circuit(12 INVX1 location(18600 0) + pin(0 13) + pin(1 11) + pin(2 16) + pin(3 13) + pin(4 10) + pin(5 16) + ) + circuit(13 INVX1 location(20400 0) + pin(0 13) + pin(1 12) + pin(2 16) + pin(3 13) + pin(4 11) + pin(5 16) + ) + circuit(14 INVX1 location(22200 0) + pin(0 13) + pin(1 14) + pin(2 16) + pin(3 13) + pin(4 12) + pin(5 16) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(NMOS MOS4) + class(PMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + net(16 name(DUMMY)) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Devices and their connections + device(1 NMOS + name($1) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 16) + terminal(D 1) + terminal(B 1) + ) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX1 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(2 6 match) + net(11 15 match) + net(3 7 match) + net(4 8 match) + net(5 9 match) + net(6 10 match) + net(7 11 match) + net(8 12 match) + net(9 13 match) + net(10 14 match) + net(1 16 match) + net(15 4 match) + net(12 3 match) + net(14 5 match) + net(13 2 match) + net(16 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + device(1 1 match) + circuit(4 2 match) + circuit(5 3 match) + circuit(6 4 match) + circuit(7 5 match) + circuit(8 6 match) + circuit(9 7 match) + circuit(10 8 match) + circuit(11 9 match) + circuit(12 10 match) + circuit(13 11 match) + circuit(14 12 match) + circuit(3 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_simplification.lvsdb.3 b/testdata/lvs/ringo_simple_simplification.lvsdb.3 new file mode 100644 index 000000000..2492067a3 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification.lvsdb.3 @@ -0,0 +1,1162 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-225 -1300) (675 450)) + rect(l4 (0 -1100) (250 1950)) + rect(l4 (-1225 -1850) (300 300)) + rect(l4 (675 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-950 -2000) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (450 -5390) (250 1450)) + rect(l4 (-950 -1450) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(2 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-1640 -240) (300 1400)) + rect(l11 (-650 300) (2400 800)) + rect(l11 (-2050 -1100) (300 300)) + rect(l11 (1100 -300) (300 300)) + rect(l11 (-1101 399) (2 2)) + rect(l11 (799 -2101) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + ) + net(3 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(4 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (1220 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-1640 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-650 0) (300 1360)) + rect(l11 (-1101 -1761) (2 2)) + rect(l6 (724 859) (425 950)) + rect(l6 (-1800 -950) (425 950)) + ) + net(5 + rect(l3 (-100 4500) (2600 3500)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(IN)) + pin(2 name(VDD)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + device(D$PMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 5800) + param(L 0.25) + param(W 3) + param(AS 0.975) + param(AD 0.975) + param(PS 5.8) + param(PD 5.8) + terminal(S 2) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 2135) + param(L 0.25) + param(W 1.9) + param(AS 0.6175) + param(AD 0.6175) + param(PS 4.15) + param(PD 4.15) + terminal(S 4) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((600 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 name(VDD) + rect(l3 (1100 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-22341 859) (2 2)) + rect(l11 (-1751 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23625 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (4550 -1500) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-19575 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(7 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(8 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(9 name(VSS) + rect(l8 (1710 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-22341 -391) (2 2)) + rect(l11 (-1301 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-24300 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (4550 -950) (425 950)) + rect(l6 (-1800 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-19575 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + net(10 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(5 name(FB)) + pin(6 name(VDD)) + pin(7 name(OUT)) + pin(8 name(ENABLE)) + pin(9 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 6) + pin(1 1) + pin(2 9) + pin(3 6) + pin(4 5) + pin(5 8) + pin(6 9) + ) + circuit(2 INVX1 location(4200 0) + pin(0 6) + pin(1 2) + pin(2 9) + pin(3 6) + pin(4 1) + pin(5 9) + ) + circuit(3 INVX1 location(6000 0) + pin(0 6) + pin(1 10) + pin(2 9) + pin(3 6) + pin(4 2) + pin(5 9) + ) + circuit(4 INVX1 location(16800 0) + pin(0 6) + pin(1 3) + pin(2 9) + pin(3 6) + pin(4 11) + pin(5 9) + ) + circuit(5 INVX1 location(18600 0) + pin(0 6) + pin(1 4) + pin(2 9) + pin(3 6) + pin(4 3) + pin(5 9) + ) + circuit(6 INVX1 location(20400 0) + pin(0 6) + pin(1 5) + pin(2 9) + pin(3 6) + pin(4 4) + pin(5 9) + ) + circuit(7 INVX2 location(22200 0) + pin(0 5) + pin(1 6) + pin(2 7) + pin(3 9) + pin(4 6) + pin(5 9) + ) + circuit(17 INVX1 location(7800 0) + pin(0 6) + pin(1 12) + pin(2 9) + pin(3 6) + pin(4 10) + pin(5 9) + ) + circuit(18 INVX1 location(9600 0) + pin(0 6) + pin(1 13) + pin(2 9) + pin(3 6) + pin(4 12) + pin(5 9) + ) + circuit(19 INVX1 location(11400 0) + pin(0 6) + pin(1 14) + pin(2 9) + pin(3 6) + pin(4 13) + pin(5 9) + ) + circuit(20 INVX1 location(13200 0) + pin(0 6) + pin(1 15) + pin(2 9) + pin(3 6) + pin(4 14) + pin(5 9) + ) + circuit(21 INVX1 location(15000 0) + pin(0 6) + pin(1 11) + pin(2 9) + pin(3 6) + pin(4 15) + pin(5 9) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 3) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 1.9) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX2 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX2 INVX2 match + xref( + net(5 4 match) + net(1 5 match) + net(3 2 match) + net(6 6 match) + net(2 1 match) + net(4 3 match) + pin(4 3 match) + pin(0 4 match) + pin(2 1 match) + pin(5 5 match) + pin(1 0 match) + pin(3 2 match) + device(3 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(4 15 match) + net(2 7 match) + net(10 8 match) + net(12 9 match) + net(13 10 match) + net(14 11 match) + net(15 12 match) + net(11 13 match) + net(3 14 match) + net(8 4 match) + net(5 3 match) + net(7 5 match) + net(6 2 match) + net(9 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(2 2 match) + circuit(3 3 match) + circuit(17 4 match) + circuit(18 5 match) + circuit(19 6 match) + circuit(20 7 match) + circuit(21 8 match) + circuit(4 9 match) + circuit(5 10 match) + circuit(6 11 match) + circuit(7 12 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 new file mode 100644 index 000000000..60f468222 --- /dev/null +++ b/testdata/lvs/ringo_simple_simplification_with_align.lvsdb.3 @@ -0,0 +1,1162 @@ +#%lvsdb-klayout + +# Layout +layout( + top(RINGO) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 '1/0') + layer(l4 '5/0') + layer(l8 '8/0') + layer(l11 '9/0') + layer(l12 '10/0') + layer(l13 '11/0') + layer(l7) + layer(l2) + layer(l9) + layer(l6) + layer(l10) + + # Mask layer connectivity + connect(l3 l3 l9) + connect(l4 l4 l8) + connect(l8 l4 l8 l11 l2 l9 l6 l10) + connect(l11 l8 l11 l12) + connect(l12 l11 l12 l13) + connect(l13 l12 l13) + connect(l7 l7) + connect(l2 l8 l2) + connect(l9 l3 l8 l9) + connect(l6 l8 l6) + connect(l10 l8 l10) + + # Global nets and connectivity + global(l7 SUBSTRATE) + global(l10 SUBSTRATE) + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Device abstracts section + # Device abstracts list the pin shapes of the devices. + device(D$PMOS PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (450 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$2 PMOS + terminal(S + rect(l2 (-550 -750) (425 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (425 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (450 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-575 -475) (450 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + device(D$NMOS$2 NMOS + terminal(S + rect(l6 (-550 -475) (425 950)) + ) + terminal(G + rect(l4 (-125 -475) (250 950)) + ) + terminal(D + rect(l6 (125 -475) (425 950)) + ) + terminal(B + rect(l7 (-125 -475) (250 950)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -790) (300 1700)) + rect(l11 (-1350 0) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l2 (-276 -2151) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1810 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-1580 3760) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + polygon(l11 (-240 -4180) (0 1390) (490 0) (0 -300) (-190 0) (0 -1090)) + rect(l11 (-110 1390) (300 1400)) + polygon(l11 (-1890 0) (0 600) (300 0) (0 -300) (1590 0) (0 -300)) + rect(l11 (-141 -501) (2 2)) + rect(l11 (-1751 1099) (300 1400)) + rect(l11 (1100 -1700) (300 300)) + rect(l11 (-300 0) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-1151 -401) (2 2)) + rect(l6 (-951 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2600 3500)) + ) + net(5 name(B) + rect(l4 (1425 2860) (250 1940)) + rect(l4 (-345 -950) (300 300)) + rect(l4 (-205 650) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-285 1050) (180 180)) + rect(l11 (-71 -91) (2 2)) + rect(l11 (-171 -151) (300 300)) + ) + net(6 name(A) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-325 -1850) (300 300)) + rect(l4 (-225 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-265 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(7 name(SUBSTRATE)) + net(8 + rect(l6 (975 1660) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.3375) + param(PS 3.85) + param(PD 1.95) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 D$PMOS$1 + location(1550 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.3375) + param(AD 0.6375) + param(PS 1.95) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 D$NMOS + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.21375) + param(PS 2.75) + param(PD 1.4) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 D$NMOS$1 + location(1550 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.21375) + param(AD 0.40375) + param(PS 1.4) + param(PD 2.75) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 400) (2000 7600)) + + # Nets with their geometries + net(1 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-240 -240) (300 1400)) + rect(l11 (-650 300) (1800 800)) + rect(l11 (-1450 -1100) (300 300)) + rect(l11 (299 399) (2 2)) + rect(l2 (-651 -2151) (425 1500)) + ) + net(2 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -1300) (300 1360)) + rect(l11 (-650 -2160) (1800 800)) + rect(l11 (-851 -401) (2 2)) + rect(l6 (-651 859) (425 950)) + ) + net(4 + rect(l3 (-100 4500) (2000 3500)) + ) + net(5 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-525 -1850) (300 300)) + rect(l4 (-25 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-250 -5390) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4) + pin(5 name(IN)) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS$2 + location(850 5800) + param(L 0.25) + param(W 1.5) + param(AS 0.6375) + param(AD 0.6375) + param(PS 3.85) + param(PD 3.85) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 D$NMOS$2 + location(850 2135) + param(L 0.25) + param(W 0.95) + param(AS 0.40375) + param(AD 0.40375) + param(PS 2.75) + param(PD 2.75) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Circuit boundary + rect((-100 400) (2600 7600)) + + # Nets with their geometries + net(1 name(IN) + rect(l4 (725 2860) (250 1940)) + rect(l4 (-225 -1300) (675 450)) + rect(l4 (0 -1100) (250 1950)) + rect(l4 (-1225 -1850) (300 300)) + rect(l4 (675 1550) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (-950 -2000) (250 2000)) + rect(l4 (-250 -2000) (250 2000)) + rect(l4 (450 -5390) (250 1450)) + rect(l4 (-950 -1450) (250 1450)) + rect(l8 (-465 150) (180 180)) + rect(l11 (-91 -91) (2 2)) + rect(l11 (-151 -151) (300 300)) + ) + net(2 name(VDD) + rect(l8 (410 6260) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (1220 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l11 (-1640 -240) (300 1400)) + rect(l11 (-650 300) (2400 800)) + rect(l11 (-2050 -1100) (300 300)) + rect(l11 (1100 -300) (300 300)) + rect(l11 (-1101 399) (2 2)) + rect(l11 (799 -2101) (300 1400)) + rect(l2 (-375 -1450) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + ) + net(3 name(OUT) + rect(l8 (1110 5160) (180 180)) + rect(l8 (-180 920) (180 180)) + rect(l8 (-180 -730) (180 180)) + rect(l8 (-180 -4120) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-240 -790) (300 4790)) + rect(l11 (-151 -2501) (2 2)) + rect(l2 (-226 1049) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(4 name(VSS) + rect(l8 (410 1770) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (1220 -730) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-1640 -1300) (300 1360)) + rect(l11 (-650 -2160) (2400 800)) + rect(l11 (-650 0) (300 1360)) + rect(l11 (-1101 -1761) (2 2)) + rect(l6 (724 859) (425 950)) + rect(l6 (-1800 -950) (425 950)) + ) + net(5 + rect(l3 (-100 4500) (2600 3500)) + ) + net(6 name(SUBSTRATE)) + + # Outgoing pins and their connections to nets + pin(1 name(IN)) + pin(2 name(VDD)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5) + pin(6 name(SUBSTRATE)) + + # Devices and their connections + device(1 D$PMOS + device(D$PMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 5800) + param(L 0.25) + param(W 3) + param(AS 0.975) + param(AD 0.975) + param(PS 5.8) + param(PD 5.8) + terminal(S 2) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS$1 location(700 0)) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + connect(0 B B) + connect(1 B B) + location(850 2135) + param(L 0.25) + param(W 1.9) + param(AS 0.6175) + param(AD 0.6175) + param(PS 4.15) + param(PD 4.15) + terminal(S 4) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Circuit boundary + rect((600 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l8 (4710 3010) (180 180)) + rect(l11 (-850 -240) (610 300)) + rect(l2 (-1175 1800) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l6 (950 -4890) (425 950)) + ) + net(2 + rect(l8 (6510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(3 + rect(l8 (19110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(4 + rect(l8 (20910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(5 name(FB) + rect(l8 (22710 3010) (180 180)) + rect(l8 (-19700 720) (180 180)) + rect(l11 (18380 -1140) (900 300)) + rect(l11 (-19530 590) (320 320)) + rect(l11 (17820 -320) (320 320)) + rect(l12 (-18400 -260) (200 200)) + rect(l12 (17940 -200) (200 200)) + rect(l13 (-18040 -300) (17740 400)) + rect(l13 (-17921 -201) (2 2)) + rect(l13 (-221 -201) (400 400)) + rect(l13 (17740 -400) (400 400)) + rect(l2 (-245 850) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(6 name(VDD) + rect(l3 (1100 4500) (1400 3500)) + rect(l3 (-1900 -3500) (600 3500)) + rect(l3 (23300 -3500) (1400 3500)) + rect(l3 (-100 -3500) (600 3500)) + rect(l8 (-24690 -1240) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l11 (-22341 859) (2 2)) + rect(l11 (-1751 -451) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23400 -800) (1200 800)) + rect(l11 (-750 -1450) (300 1400)) + rect(l11 (-101 -351) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l2 (-23625 -2550) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l2 (1275 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l2 (3175 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (1375 -1500) (425 1500)) + rect(l2 (4550 -1500) (425 1500)) + rect(l2 (-1800 -1500) (425 1500)) + rect(l2 (-2225 -1500) (425 1500)) + rect(l9 (-19575 -450) (500 1500)) + rect(l9 (22900 -1500) (500 1500)) + ) + net(7 name(OUT) + rect(l11 (23440 3840) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + rect(l2 (-625 850) (425 1500)) + rect(l2 (-400 -1500) (425 1500)) + rect(l6 (-450 -4890) (425 950)) + rect(l6 (-400 -950) (425 950)) + ) + net(8 name(ENABLE) + rect(l8 (2510 3010) (180 180)) + rect(l11 (-250 -250) (320 320)) + rect(l12 (-260 -260) (200 200)) + rect(l13 (-101 -101) (2 2)) + rect(l13 (-201 -201) (400 400)) + ) + net(9 name(VSS) + rect(l8 (1710 1610) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l8 (23220 370) (180 180)) + rect(l8 (-180 -1280) (180 180)) + rect(l8 (-180 370) (180 180)) + rect(l11 (-22341 -391) (2 2)) + rect(l11 (-1301 -401) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (-1251 -401) (600 800)) + rect(l11 (23850 -750) (300 1400)) + rect(l11 (-750 -1450) (1200 800)) + rect(l11 (-551 -401) (2 2)) + rect(l11 (549 -401) (600 800)) + rect(l6 (-24300 460) (425 950)) + rect(l6 (1975 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l6 (3175 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (1375 -950) (425 950)) + rect(l6 (4550 -950) (425 950)) + rect(l6 (-1800 -950) (425 950)) + rect(l6 (-2225 -950) (425 950)) + rect(l10 (-19575 -2210) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + net(10 + rect(l8 (8310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(11 + rect(l8 (17310 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(12 + rect(l8 (10110 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(13 + rect(l8 (11910 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(14 + rect(l8 (13710 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + net(15 + rect(l8 (15510 3010) (180 180)) + rect(l11 (-1140 -240) (900 300)) + rect(l2 (-1275 1800) (425 1500)) + rect(l6 (-425 -4890) (425 950)) + ) + + # Outgoing pins and their connections to nets + pin(5 name(FB)) + pin(6 name(VDD)) + pin(7 name(OUT)) + pin(8 name(ENABLE)) + pin(9 name(VSS)) + + # Subcircuits and their connections + circuit(1 ND2X1 location(1800 0) + pin(0 6) + pin(1 1) + pin(2 9) + pin(3 6) + pin(4 5) + pin(5 8) + pin(6 9) + ) + circuit(2 INVX1 location(4200 0) + pin(0 6) + pin(1 2) + pin(2 9) + pin(3 6) + pin(4 1) + pin(5 9) + ) + circuit(3 INVX1 location(6000 0) + pin(0 6) + pin(1 10) + pin(2 9) + pin(3 6) + pin(4 2) + pin(5 9) + ) + circuit(4 INVX1 location(16800 0) + pin(0 6) + pin(1 3) + pin(2 9) + pin(3 6) + pin(4 11) + pin(5 9) + ) + circuit(5 INVX1 location(18600 0) + pin(0 6) + pin(1 4) + pin(2 9) + pin(3 6) + pin(4 3) + pin(5 9) + ) + circuit(6 INVX1 location(20400 0) + pin(0 6) + pin(1 5) + pin(2 9) + pin(3 6) + pin(4 4) + pin(5 9) + ) + circuit(7 INVX2 location(22200 0) + pin(0 5) + pin(1 6) + pin(2 7) + pin(3 9) + pin(4 6) + pin(5 9) + ) + circuit(13 INVX1 location(7800 0) + pin(0 6) + pin(1 12) + pin(2 9) + pin(3 6) + pin(4 10) + pin(5 9) + ) + circuit(14 INVX1 location(9600 0) + pin(0 6) + pin(1 13) + pin(2 9) + pin(3 6) + pin(4 12) + pin(5 9) + ) + circuit(15 INVX1 location(11400 0) + pin(0 6) + pin(1 14) + pin(2 9) + pin(3 6) + pin(4 13) + pin(5 9) + ) + circuit(16 INVX1 location(13200 0) + pin(0 6) + pin(1 15) + pin(2 9) + pin(3 6) + pin(4 14) + pin(5 9) + ) + circuit(17 INVX1 location(15000 0) + pin(0 6) + pin(1 11) + pin(2 9) + pin(3 6) + pin(4 15) + pin(5 9) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(B)) + net(6 name(A)) + net(7 name(BULK)) + net(8 name('1')) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(B)) + pin(6 name(A)) + pin(7 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 2) + terminal(G 6) + terminal(D 1) + terminal(B 4) + ) + device(2 PMOS + name($2) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(3 NMOS + name($3) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 6) + terminal(D 8) + terminal(B 7) + ) + device(4 NMOS + name($4) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 8) + terminal(G 5) + terminal(D 2) + terminal(B 7) + ) + + ) + circuit(INVX1 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 1.5) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 0.95) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(INVX2 + + # Nets + net(1 name(VDD)) + net(2 name(OUT)) + net(3 name(VSS)) + net(4 name(NWELL)) + net(5 name(IN)) + net(6 name(BULK)) + + # Outgoing pins and their connections to nets + pin(1 name(VDD)) + pin(2 name(OUT)) + pin(3 name(VSS)) + pin(4 name(NWELL)) + pin(5 name(IN)) + pin(6 name(BULK)) + + # Devices and their connections + device(1 PMOS + name($1) + param(L 0.25) + param(W 3) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 1) + terminal(G 5) + terminal(D 2) + terminal(B 4) + ) + device(2 NMOS + name($2) + param(L 0.25) + param(W 1.9) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 3) + terminal(G 5) + terminal(D 2) + terminal(B 6) + ) + + ) + circuit(RINGO + + # Nets + net(1 name(VSS)) + net(2 name(VDD)) + net(3 name(FB)) + net(4 name(ENABLE)) + net(5 name(OUT)) + net(6 name('1')) + net(7 name('2')) + net(8 name('3')) + net(9 name('4')) + net(10 name('5')) + net(11 name('6')) + net(12 name('7')) + net(13 name('8')) + net(14 name('9')) + net(15 name('10')) + + # Outgoing pins and their connections to nets + pin(1 name(VSS)) + pin(2 name(VDD)) + pin(3 name(FB)) + pin(4 name(ENABLE)) + pin(5 name(OUT)) + + # Subcircuits and their connections + circuit(1 ND2X1 name($1) + pin(0 2) + pin(1 6) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 4) + pin(6 1) + ) + circuit(2 INVX1 name($2) + pin(0 2) + pin(1 7) + pin(2 1) + pin(3 2) + pin(4 6) + pin(5 1) + ) + circuit(3 INVX1 name($3) + pin(0 2) + pin(1 8) + pin(2 1) + pin(3 2) + pin(4 7) + pin(5 1) + ) + circuit(4 INVX1 name($4) + pin(0 2) + pin(1 9) + pin(2 1) + pin(3 2) + pin(4 8) + pin(5 1) + ) + circuit(5 INVX1 name($5) + pin(0 2) + pin(1 10) + pin(2 1) + pin(3 2) + pin(4 9) + pin(5 1) + ) + circuit(6 INVX1 name($6) + pin(0 2) + pin(1 11) + pin(2 1) + pin(3 2) + pin(4 10) + pin(5 1) + ) + circuit(7 INVX1 name($7) + pin(0 2) + pin(1 12) + pin(2 1) + pin(3 2) + pin(4 11) + pin(5 1) + ) + circuit(8 INVX1 name($8) + pin(0 2) + pin(1 13) + pin(2 1) + pin(3 2) + pin(4 12) + pin(5 1) + ) + circuit(9 INVX1 name($9) + pin(0 2) + pin(1 14) + pin(2 1) + pin(3 2) + pin(4 13) + pin(5 1) + ) + circuit(10 INVX1 name($10) + pin(0 2) + pin(1 15) + pin(2 1) + pin(3 2) + pin(4 14) + pin(5 1) + ) + circuit(11 INVX1 name($11) + pin(0 2) + pin(1 3) + pin(2 1) + pin(3 2) + pin(4 15) + pin(5 1) + ) + circuit(12 INVX2 name($12) + pin(0 2) + pin(1 5) + pin(2 1) + pin(3 2) + pin(4 3) + pin(5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(INVX1 INVX1 match + xref( + net(4 4 match) + net(5 5 match) + net(2 2 match) + net(6 6 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(4 4 match) + pin(1 1 match) + pin(5 5 match) + pin(0 0 match) + pin(2 2 match) + device(2 2 match) + device(1 1 match) + ) + ) + circuit(INVX2 INVX2 match + xref( + net(5 4 match) + net(1 5 match) + net(3 2 match) + net(6 6 match) + net(2 1 match) + net(4 3 match) + pin(4 3 match) + pin(0 4 match) + pin(2 1 match) + pin(5 5 match) + pin(1 0 match) + pin(3 2 match) + device(3 2 match) + device(1 1 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + net(8 8 match) + net(4 4 match) + net(6 6 match) + net(5 5 match) + net(2 2 match) + net(7 7 match) + net(1 1 match) + net(3 3 match) + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(6 6 match) + pin(0 0 match) + pin(2 2 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) + circuit(RINGO RINGO match + xref( + net(1 6 match) + net(4 15 match) + net(2 7 match) + net(10 8 match) + net(12 9 match) + net(13 10 match) + net(14 11 match) + net(15 12 match) + net(11 13 match) + net(3 14 match) + net(8 4 match) + net(5 3 match) + net(7 5 match) + net(6 2 match) + net(9 1 match) + pin(3 3 match) + pin(0 2 match) + pin(2 4 match) + pin(1 1 match) + pin(4 0 match) + circuit(2 2 match) + circuit(3 3 match) + circuit(13 4 match) + circuit(14 5 match) + circuit(15 6 match) + circuit(16 7 match) + circuit(17 8 match) + circuit(4 9 match) + circuit(5 10 match) + circuit(6 11 match) + circuit(7 12 match) + circuit(1 1 match) + ) + ) +) From c8aa926fb06adf61c580c73c9c943d9053d3b054 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 Nov 2019 09:07:00 +0100 Subject: [PATCH 31/31] Another update of testdata for MSVC --- testdata/algo/device_extract_au10.gds.3 | Bin 0 -> 8898 bytes testdata/algo/lvs_test1b_au.lvsdb.2 | 92 ++++++------- testdata/algo/lvs_test2b_au.lvsdb.2 | 163 ++++++++++++++---------- 3 files changed, 143 insertions(+), 112 deletions(-) create mode 100644 testdata/algo/device_extract_au10.gds.3 diff --git a/testdata/algo/device_extract_au10.gds.3 b/testdata/algo/device_extract_au10.gds.3 new file mode 100644 index 0000000000000000000000000000000000000000..f0be9a440641265250e8ab9a107575f61e02cc47 GIT binary patch literal 8898 zcmc&(-HTOK6kqq;d(YgtUT3E3s7+2`af2Sj)KMpi#IX?^v{9N#N)qY8*PePzNV11s z`UhfQA~LAAsEEFh2nh`fdx??|>LGjxd-dz|TYK$w_C6o?-g6Fy1H*4vXaDy4*lX{# z_8tl;2wtS=S}^h_t)V&vG(!{q-_#1i!wdU~ChN_;b8pWcy71wRJ@a2Yx%%$$WtwjG z=S_s+;(_Ip%g@g(E}iVnP@_c@t_|oCg<}B`ZJDS?QS@dM-M+?1RNoBgX+@PYQsV)l z#t4UPZ$m!V_4&n*Z+!*xJ&qh&fu7%i=M`0MutOF{6AoUydG15So06f0ZUv3xQJLT2QQrM0o7h*QTLn9x z5H)eWD5`vPYw2jYQzfy>=(Ncc6D{6l94$eW8}zMBd5iB~vA0;m&)8dsDhCeWW2FvB zv}y+=T8b(M`utS1pntDKtM;8lOHk#Eg`(97!};Fgb4QkXxv|1-If1#b>+YQ37{O0e zI)B&6_k^tjV@<2fhySZQFK4Vl-`7lqW&NU;$6LPPvE1>8RM@uq8lO*|rIpSXj~{yy zTUa2g{x46>svb?Qs&`&gT2+sq_4R(QD*GC*s%L4XRrUB;Pw(TZB7aRcir%43G|~0@ z)9uumsKZ+MF}o=7`JwDEz^4)ie&-!^D{1)rJL*M^0-KbqPj}P5faaP`& z?!6U;=qx1@+g;7eyd2E=+P)!cj0_!^B{Tv^$Kd*C_8lKSa@!4*P zGuv74mXzS%!?%pd_$}kvgL4auctCNt6|aXT+VmFUg`8n*V(&kE%Av}ECTE7+7P30G z#T{lsXBYZ-jTjrZh^D@EsB&N>oqI5q&CP_)vG>GJM)q^!j6?R*ey^nSsXjWJbK)l> z``P);A^T~+SJFA#M`!ID@spALG+ibu0jdOE{#F>%f8(w$Fakk$p**w$7<}s`# z+s4Q?kALJ)<%8n9=8VLdk>fmm#UaPpey?OR!jK#18sfsXF|y6U1&1o{Z!>BD>@sIL zkZlhBaj0_GUd85xMNDOL!#m&5`}`|985_4y!@qaPI^}yIopMvbD{ULM&aT{AO#jSp zjC$Klf9syl{T4n{djkjGbaVfwsE_<(W@_DbqlZ)#u?DZWp2j}24zh22wXjCK1>w$O z>ZYgF-lW=3pg*`KaU5>Z^xwv3v(oWsbK{b3)thNDzSl{`=9M-liCbWqotWjv z71~tlVHG@&U#9EGVI48=T{Rw`BdY9l=sPPGYg}x@iuh7eRFJ|RxpN+rAkL$Uq z>%;1O9=}YFlgBU9*X8lc^s+X4;s3DgC3@slWba{WO@&8ZShm%`^6`dY_~sOw`oYu- pj61fpG+PpM&kvZ7^%fattJzTdcwBlubPA0I{RhVdp@jed literal 0 HcmV?d00001 diff --git a/testdata/algo/lvs_test1b_au.lvsdb.2 b/testdata/algo/lvs_test1b_au.lvsdb.2 index 2853d93ef..bef20e994 100644 --- a/testdata/algo/lvs_test1b_au.lvsdb.2 +++ b/testdata/algo/lvs_test1b_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -1044,16 +1044,16 @@ xref( ) circuit(INV2PAIR INV2PAIR match xref( - net(2 2 match) - net(3 3 match) - net(4 4 match) + net(3 2 match) + net(4 3 match) + net(2 4 match) net(5 5 match) net(6 6 match) net(7 7 match) net(1 1 match) - pin(1 1 match) - pin(2 2 match) - pin(3 3 match) + pin(2 1 match) + pin(3 2 match) + pin(1 3 match) pin(4 4 match) pin(5 5 match) pin(6 6 match) diff --git a/testdata/algo/lvs_test2b_au.lvsdb.2 b/testdata/algo/lvs_test2b_au.lvsdb.2 index 965381b39..92aad1228 100644 --- a/testdata/algo/lvs_test2b_au.lvsdb.2 +++ b/testdata/algo/lvs_test2b_au.lvsdb.2 @@ -268,6 +268,24 @@ layout( # Nets with their geometries net(1 name(BULK)) net(2 + rect(diff_cont (790 890) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (1380 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 -3820) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-1820 3380) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + ) + net(3 rect(diff_cont (4230 3290) (220 220)) rect(diff_cont (-220 180) (220 220)) rect(diff_cont (-220 180) (220 220)) @@ -289,7 +307,7 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(3 + net(4 rect(diff_cont (4230 890) (220 220)) rect(diff_cont (-220 -620) (220 220)) rect(diff_cont (-220 -620) (220 220)) @@ -311,24 +329,6 @@ layout( rect(metal1 (-3000 -1560) (360 1560)) rect(metal1 (-360 -1560) (360 1560)) ) - net(4 - rect(diff_cont (790 890) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (1380 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 -3820) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-220 -620) (220 220)) - rect(diff_cont (-1820 3380) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - rect(diff_cont (-220 180) (220 220)) - ) net(5) net(6 rect(diff_cont (3430 890) (220 220)) @@ -363,17 +363,17 @@ layout( circuit(1 INV2 location(1700 800) pin(0 7) pin(1 5) - pin(2 4) - pin(3 3) - pin(4 2) + pin(2 2) + pin(3 4) + pin(4 3) pin(5 1) ) circuit(2 INV2 location(4340 800) pin(0 7) - pin(1 4) + pin(1 2) pin(2 6) - pin(3 3) - pin(4 2) + pin(3 4) + pin(4 3) pin(5 1) ) @@ -808,45 +808,45 @@ layout( # Subcircuits and their connections circuit(1 INV2PAIR location(19420 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 1) + pin(1 1) + pin(2 3) + pin(3 4) pin(4 10) pin(5 2) pin(6 3) ) circuit(2 INV2PAIR location(-1700 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 8) + pin(1 8) + pin(2 3) + pin(3 4) pin(4 1) pin(5 9) pin(6 3) ) circuit(3 INV2PAIR location(3580 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 7) + pin(1 7) + pin(2 3) + pin(3 4) pin(4 9) pin(5 12) pin(6 3) ) circuit(4 INV2PAIR location(8860 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 6) + pin(1 6) + pin(2 3) + pin(3 4) pin(4 12) pin(5 11) pin(6 3) ) circuit(5 INV2PAIR location(14140 -800) pin(0 4) - pin(1 3) - pin(2 4) - pin(3 5) + pin(1 5) + pin(2 3) + pin(3 4) pin(4 11) pin(5 10) pin(6 3) @@ -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(3 2 mismatch) + net(4 3 mismatch) net(5 4 match) - net(6 5 match) - net(7 6 mismatch) + net(2 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(2 1 match) + pin(3 2 match) pin(4 3 match) + pin(1 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) ) ) )