diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index 0e5a4ae46..fdc344763 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -495,19 +495,25 @@ void LayoutToNetlistStandardReader::read_pin (db::Netlist * /*netlist*/, db::LayoutToNetlist * /*l2n*/, db::Circuit *circuit, std::map &id2net) { Brace br (this); + std::string name; read_word_or_quoted (name); - unsigned int netid = (unsigned int) read_int (); - br.done (); - const db::Pin &pin = circuit->add_pin (name); - db::Net *net = id2net [netid]; - if (!net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); + if (br) { + + unsigned int netid = (unsigned int) read_int (); + db::Net *net = id2net [netid]; + if (!net) { + throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); + } + + circuit->connect_pin (pin.id (), net); + } - circuit->connect_pin (pin.id (), net); + br.done (); + } size_t @@ -616,18 +622,23 @@ LayoutToNetlistStandardReader::read_device (db::Netlist *netlist, db::LayoutToNe Brace br2 (this); std::string tname; read_word_or_quoted (tname); - unsigned int netid = (unsigned int) read_int (); - br2.done (); size_t tid = terminal_id (dm.second, tname); max_tid = std::max (max_tid, tid + 1); - db::Net *net = id2net [netid]; - if (!net) { - throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); + if (br2) { + + unsigned int netid = (unsigned int) read_int (); + db::Net *net = id2net [netid]; + if (!net) { + throw tl::Exception (tl::to_string (tr ("Not a valid net ID: ")) + tl::to_string (netid)); + } + + device->connect_terminal (tid, net); + } - device->connect_terminal (tid, net); + br2.done (); } else if (test (skeys::param_key) || test (lkeys::param_key)) { diff --git a/src/db/db/dbLayoutToNetlistWriter.cc b/src/db/db/dbLayoutToNetlistWriter.cc index 487c41409..34c214c14 100644 --- a/src/db/db/dbLayoutToNetlistWriter.cc +++ b/src/db/db/dbLayoutToNetlistWriter.cc @@ -226,6 +226,8 @@ void std_writer_impl::write (const db::Netlist *netlist, const db::LayoutT const db::Net *net = circuit.net_for_pin (p->id ()); if (net) { *mp_stream << indent << indent1 << Keys::pin_key << "(" << tl::to_word_or_quoted_string (p->expanded_name ()) << " " << (*net2id) [net] << ")" << endl; + } else { + *mp_stream << indent << indent1 << Keys::pin_key << "(" << tl::to_word_or_quoted_string (p->expanded_name ()) << ")" << endl; } } } @@ -530,6 +532,8 @@ void std_writer_impl::write (const db::LayoutToNetlist * /*l2n*/, const db const db::Net *net = device.net_for_terminal (i->id ()); if (net) { *mp_stream << indent << indent2 << Keys::terminal_key << "(" << tl::to_word_or_quoted_string (i->name ()) << " " << net2id [net] << ")" << endl; + } else { + *mp_stream << indent << indent2 << Keys::terminal_key << "(" << tl::to_word_or_quoted_string (i->name ()) << ")" << endl; } } diff --git a/src/db/db/dbLayoutVsSchematicReader.cc b/src/db/db/dbLayoutVsSchematicReader.cc index 9eadfbed1..e146b7088 100644 --- a/src/db/db/dbLayoutVsSchematicReader.cc +++ b/src/db/db/dbLayoutVsSchematicReader.cc @@ -162,18 +162,24 @@ void LayoutVsSchematicStandardReader::read_xref (db::NetlistCrossReference *xref Brace br (this); - std::string name_a, name_b; - read_word_or_quoted (name_a); - read_word_or_quoted (name_b); + std::pair non_a, non_b; + non_a = read_non_string (); + non_b = read_non_string (); - const db::Circuit *circuit_a = xref->netlist_a ()->circuit_by_name (name_a); - if (! circuit_a) { - throw tl::Exception (tl::to_string (tr ("Not a valid circuit name: ")) + name_a); + const db::Circuit *circuit_a = 0; + if (non_a.second) { + circuit_a = xref->netlist_a ()->circuit_by_name (non_a.first); + if (! circuit_a) { + throw tl::Exception (tl::to_string (tr ("Not a valid circuit name: ")) + non_a.first); + } } - const db::Circuit *circuit_b = xref->netlist_b ()->circuit_by_name (name_b); - if (! circuit_b) { - throw tl::Exception (tl::to_string (tr ("Not a valid circuit name: ")) + name_b); + const db::Circuit *circuit_b = 0; + if (non_b.second) { + circuit_b = xref->netlist_b ()->circuit_by_name (non_b.first); + if (! circuit_b) { + throw tl::Exception (tl::to_string (tr ("Not a valid circuit name: ")) + non_b.first); + } } xref->gen_begin_circuit (circuit_a, circuit_b); diff --git a/src/db/unit_tests/dbLayoutVsSchematicTests.cc b/src/db/unit_tests/dbLayoutVsSchematicTests.cc index 49e07711f..e9d184efe 100644 --- a/src/db/unit_tests/dbLayoutVsSchematicTests.cc +++ b/src/db/unit_tests/dbLayoutVsSchematicTests.cc @@ -257,3 +257,199 @@ TEST(1_BasicFlow) compare_lvsdbs (_this, path2, au_path); } + +TEST(2_FlowWithErrors) +{ + db::Layout ly; + db::LayerMap lmap; + + unsigned int nwell = define_layer (ly, lmap, 1); + unsigned int active = define_layer (ly, lmap, 2); + unsigned int pplus = define_layer (ly, lmap, 10); + unsigned int nplus = define_layer (ly, lmap, 11); + 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, "lvs_test_1.gds"); + + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly, options); + } + + db::Cell &tc = ly.cell (*ly.begin_top_down ()); + db::LayoutVsSchematic lvs (db::RecursiveShapeIterator (ly, tc, std::set ())); + + std::auto_ptr rbulk (lvs.make_layer ("bulk")); + std::auto_ptr rnwell (lvs.make_layer (nwell, "nwell")); + std::auto_ptr ractive (lvs.make_layer (active, "active")); + std::auto_ptr rpplus (lvs.make_layer (pplus, "pplus")); + std::auto_ptr rnplus (lvs.make_layer (nplus, "nplus")); + std::auto_ptr rpoly (lvs.make_polygon_layer (poly, "poly")); + std::auto_ptr rpoly_lbl (lvs.make_text_layer (poly_lbl, "poly_lbl")); + std::auto_ptr rdiff_cont (lvs.make_polygon_layer (diff_cont, "diff_cont")); + std::auto_ptr rpoly_cont (lvs.make_polygon_layer (poly_cont, "poly_cont")); + std::auto_ptr rmetal1 (lvs.make_polygon_layer (metal1, "metal1")); + std::auto_ptr rmetal1_lbl (lvs.make_text_layer (metal1_lbl, "metal1_lbl")); + std::auto_ptr rvia1 (lvs.make_polygon_layer (via1, "via1")); + std::auto_ptr rmetal2 (lvs.make_polygon_layer (metal2, "metal2")); + std::auto_ptr rmetal2_lbl (lvs.make_text_layer (metal2_lbl, "metal2_lbl")); + + // derived regions + + db::Region ractive_in_nwell = *ractive & *rnwell; + db::Region rpactive = ractive_in_nwell & *rpplus; + db::Region rntie = ractive_in_nwell & *rnplus; + db::Region rpgate = rpactive & *rpoly; + db::Region rpsd = rpactive - rpgate; + + db::Region ractive_outside_nwell = *ractive - *rnwell; + db::Region rnactive = ractive_outside_nwell & *rnplus; + db::Region rptie = ractive_outside_nwell & *rpplus; + 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 lgate = ly.insert_layer (db::LayerProperties (20, 0)); // 20/0 -> Gate + unsigned int lsd = ly.insert_layer (db::LayerProperties (21, 0)); // 21/0 -> Source/Drain + 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 + unsigned int lptie = ly.insert_layer (db::LayerProperties (24, 0)); // 24/0 -> P Tie + unsigned int lntie = ly.insert_layer (db::LayerProperties (25, 0)); // 25/0 -> N Tie + + rpgate.insert_into (&ly, tc.cell_index (), lgate); + rngate.insert_into (&ly, tc.cell_index (), lgate); + rpsd.insert_into (&ly, tc.cell_index (), lsd); + rnsd.insert_into (&ly, tc.cell_index (), lsd); + rpsd.insert_into (&ly, tc.cell_index (), lpdiff); + rnsd.insert_into (&ly, tc.cell_index (), lndiff); + rpsd.insert_into (&ly, tc.cell_index (), lptie); + rnsd.insert_into (&ly, tc.cell_index (), lntie); + + db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS"); + db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS"); + + // device extraction + + db::NetlistDeviceExtractor::input_layers dl; + + dl["SD"] = &rpsd; + dl["G"] = &rpgate; + dl["P"] = rpoly.get (); // not needed for extraction but to return terminal shapes + dl["W"] = rnwell.get (); + lvs.extract_devices (pmos_ex, dl); + + dl["SD"] = &rnsd; + dl["G"] = &rngate; + dl["P"] = rpoly.get (); // not needed for extraction but to return terminal shapes + dl["W"] = rbulk.get (); + lvs.extract_devices (nmos_ex, dl); + + // net extraction + + lvs.register_layer (rpsd, "psd"); + lvs.register_layer (rnsd, "nsd"); + lvs.register_layer (rptie, "ptie"); + lvs.register_layer (rntie, "ntie"); + + // Intra-layer + lvs.connect (rpsd); + lvs.connect (rnsd); + lvs.connect (*rnwell); + lvs.connect (*rpoly); + lvs.connect (*rdiff_cont); + lvs.connect (*rpoly_cont); + lvs.connect (*rmetal1); + lvs.connect (*rvia1); + lvs.connect (*rmetal2); + lvs.connect (rptie); + lvs.connect (rntie); + // Inter-layer + lvs.connect (rpsd, *rdiff_cont); + lvs.connect (rnsd, *rdiff_cont); + lvs.connect (*rpoly, *rpoly_cont); + lvs.connect (*rpoly_cont, *rmetal1); + lvs.connect (*rdiff_cont, *rmetal1); + lvs.connect (*rdiff_cont, rptie); + lvs.connect (*rdiff_cont, rntie); + lvs.connect (*rnwell, rntie); + lvs.connect (*rmetal1, *rvia1); + lvs.connect (*rvia1, *rmetal2); + lvs.connect (*rpoly, *rpoly_lbl); // attaches labels + lvs.connect (*rmetal1, *rmetal1_lbl); // attaches labels + lvs.connect (*rmetal2, *rmetal2_lbl); // attaches labels + // Global + lvs.connect_global (rptie, "BULK"); + lvs.connect_global (*rbulk, "BULK"); + + // create some mess - we have to keep references to the layers to make them not disappear + rmetal1_lbl.reset (0); + rmetal2_lbl.reset (0); + rpoly_lbl.reset (0); + + lvs.extract_netlist (); + + // doesn't do anything here, but we test that this does not destroy anything: + lvs.netlist ()->combine_devices (); + + // make pins for named nets of top-level circuits - this way they are not purged + lvs.netlist ()->make_top_level_pins (); + lvs.netlist ()->purge (); + + // read the reference netlist + { + db::NetlistSpiceReader reader; + + std::string fn (tl::testsrc ()); + fn = tl::combine_path (fn, "testdata"); + fn = tl::combine_path (fn, "algo"); + fn = tl::combine_path (fn, "lvs_test_2.spi"); + + std::auto_ptr netlist (new db::Netlist ()); + tl::InputStream stream (fn); + reader.read (stream, *netlist); + lvs.set_reference_netlist (netlist.release ()); + } + + // perform the compare + { + db::NetlistComparer comparer; + lvs.compare_netlists (&comparer); + } + + // save and compare + + std::string path = tmp_file ("tmp_lvstest2.lvsdb"); + lvs.save (path, false); + + std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "lvs_test2_au.lvsdb"); + + compare_lvsdbs (_this, path, au_path); + + // load, save and compare + + db::LayoutVsSchematic lvs2; + + std::string path2 = tmp_file ("tmp_lvstest2b.lvsdb"); + lvs2.load (path); + lvs2.save (path2, false); + + compare_lvsdbs (_this, path2, au_path); +} + diff --git a/testdata/algo/lvs_test2_au.lvsdb b/testdata/algo/lvs_test2_au.lvsdb new file mode 100644 index 000000000..a6e4a5e99 --- /dev/null +++ b/testdata/algo/lvs_test2_au.lvsdb @@ -0,0 +1,1001 @@ +#%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(bulk '1/0') + layer(nwell '1/0') + layer(poly '3/0') + layer(poly_lbl '3/1') + layer(diff_cont '4/0') + layer(poly_cont '5/0') + layer(metal1 '6/0') + layer(metal1_lbl '6/1') + layer(via1 '7/0') + layer(metal2 '8/0') + layer(metal2_lbl '8/1') + layer(ntie) + layer(psd) + layer(ptie) + layer(nsd) + + # Mask layer connectivity + connect(nwell nwell ntie) + connect(poly poly poly_lbl poly_cont) + connect(poly_lbl poly) + connect(diff_cont diff_cont metal1 ntie psd ptie nsd) + connect(poly_cont poly poly_cont metal1) + connect(metal1 diff_cont poly_cont metal1 metal1_lbl via1) + connect(metal1_lbl metal1) + connect(via1 metal1 via1 metal2) + connect(metal2 via1 metal2 metal2_lbl) + connect(metal2_lbl metal2) + connect(ntie nwell diff_cont ntie) + connect(psd diff_cont psd) + connect(ptie diff_cont ptie) + connect(nsd diff_cont nsd) + + # Global nets and connectivity + global(bulk BULK) + global(ptie BULK) + + # 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(psd (-650 -875) (525 1750)) + ) + terminal(G + rect(poly (-125 -875) (250 1750)) + ) + terminal(D + rect(psd (125 -875) (550 1750)) + ) + terminal(B + rect(nwell (-125 -875) (250 1750)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(psd (-675 -875) (550 1750)) + ) + terminal(G + rect(poly (-125 -875) (250 1750)) + ) + terminal(D + rect(psd (125 -875) (525 1750)) + ) + terminal(B + rect(nwell (-125 -875) (250 1750)) + ) + ) + device(D$NMOS NMOS + terminal(S + rect(nsd (-650 -875) (525 1750)) + ) + terminal(G + rect(poly (-125 -875) (250 1750)) + ) + terminal(D + rect(nsd (125 -875) (550 1750)) + ) + terminal(B + rect(bulk (-125 -875) (250 1750)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(nsd (-675 -875) (550 1750)) + ) + terminal(G + rect(poly (-125 -875) (250 1750)) + ) + terminal(D + rect(nsd (125 -875) (525 1750)) + ) + terminal(B + rect(bulk (-125 -875) (250 1750)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(INV2 + + # Nets with their geometries + net(1 + rect(nwell (-1400 1800) (2800 3580)) + rect(diff_cont (-1510 -650) (220 220)) + rect(ntie (-510 -450) (800 680)) + ) + net(2 name(IN) + rect(poly (-525 -250) (250 2500)) + rect(poly (-1425 -630) (2100 360)) + rect(poly (-125 -2230) (250 2500)) + rect(poly (-1050 -3850) (250 2400)) + rect(poly (550 1200) (250 2400)) + rect(poly (-250 -6000) (250 2400)) + rect(poly (-1050 1200) (250 2400)) + rect(poly_lbl (-526 -2601) (2 2)) + rect(poly_cont (-831 -111) (220 220)) + ) + net(3 name(OUT) + rect(diff_cont (-910 90) (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)) + rect(metal1 (1310 -3710) (360 2220)) + rect(metal1 (-1900 -800) (2220 360)) + rect(metal1 (-2280 -2400) (360 2840)) + rect(metal1 (-360 -3600) (360 1560)) + rect(metal1 (1240 2040) (360 1560)) + rect(metal1 (-360 -5160) (360 1560)) + rect(metal1 (-1960 2040) (360 1560)) + rect(metal1_lbl (1419 -2181) (2 2)) + rect(psd (-276 524) (525 1750)) + rect(psd (-2100 -1750) (525 1750)) + rect(nsd (1050 -5350) (525 1750)) + rect(nsd (-2100 -1750) (525 1750)) + ) + net(4 name(VSS) + rect(diff_cont (-110 90) (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 (-220 980) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(metal1 (-290 -290) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(via1 (-305 -705) (250 250)) + rect(via1 (-250 150) (250 250)) + rect(via1 (-250 -1450) (250 250)) + rect(via1 (-250 150) (250 250)) + rect(metal2 (-1525 -775) (2800 1700)) + rect(metal2_lbl (-161 -541) (2 2)) + rect(nsd (-1516 -1186) (550 1750)) + ) + net(5 name(VDD) + rect(diff_cont (-110 2490) (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 -1420) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(metal1 (-290 -1490) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(via1 (-305 -1505) (250 250)) + rect(via1 (-250 150) (250 250)) + rect(via1 (-250 150) (250 250)) + rect(via1 (-250 150) (250 250)) + rect(metal2 (-1525 -1575) (2800 1700)) + rect(metal2_lbl (-151 -1251) (2 2)) + rect(psd (-1526 -476) (550 1750)) + ) + net(6 name(BULK) + rect(diff_cont (-110 -2160) (220 220)) + rect(ptie (-510 -450) (800 680)) + ) + + # Outgoing pins and their connections to nets + pin($0 1) + pin(IN 2) + pin(OUT 3) + pin(VSS 4) + pin(VDD 5) + pin(BULK 6) + + # Devices and their connections + device($1 D$PMOS + device(D$PMOS$1 800 0) + connect(0 S S) + connect(0 S D) + connect(0 G G) + connect(0 G G) + connect(0 D D) + connect(0 D S) + connect(0 B B) + connect(0 B B) + location(-400 3200) + param(L 0.25) + param(W 3.5) + param(AS 1.4) + param(AD 1.4) + param(PS 6.85) + param(PD 6.85) + terminal(S 3) + terminal(G 2) + terminal(D 5) + terminal(B 1) + ) + device($3 D$NMOS + device(D$NMOS$1 800 0) + connect(0 S S) + connect(0 S D) + connect(0 G G) + connect(0 G G) + connect(0 D D) + connect(0 D S) + connect(0 B B) + connect(0 B B) + location(-400 -400) + param(L 0.25) + param(W 3.5) + param(AS 1.4) + param(AD 1.4) + param(PS 6.85) + param(PD 6.85) + terminal(S 3) + terminal(G 2) + terminal(D 4) + terminal(B 6) + ) + + ) + circuit(INV2PAIR + + # Nets with their geometries + net(1 name(BULK)) + net(2 + rect(diff_cont (4230 3290) (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 -1420) (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 (-2860 -1420) (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 -1420) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(metal1 (2350 -1490) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + ) + net(3 + rect(diff_cont (4230 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 (-220 980) (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 (-2860 980) (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 (-220 980) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(metal1 (2350 -290) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + 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)) + 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(7) + + # Outgoing pins and their connections to nets + pin(BULK 1) + pin($1 2) + pin($2 3) + pin($3 4) + pin($4 5) + pin($5 6) + pin($6 7) + + # Subcircuits and their connections + circuit($1 INV2 location(1700 800) + pin($0 7) + pin(IN 5) + pin(OUT 4) + pin(VSS 3) + pin(VDD 2) + pin(BULK 1) + ) + circuit($2 INV2 location(4340 800) + pin($0 7) + pin(IN 4) + pin(OUT 6) + pin(VSS 3) + pin(VDD 2) + pin(BULK 1) + ) + + ) + circuit(RINGO + + # Nets with their geometries + net(1 name(FB) + rect(diff_cont (20210 90) (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)) + rect(metal1 (-22130 -2290) (360 360)) + rect(via1 (-305 -305) (250 250)) + rect(via1 (23190 -250) (250 250)) + rect(metal2 (-23765 -325) (23840 400)) + rect(metal2_lbl (-22121 -201) (2 2)) + ) + net(2 name(OSC) + rect(diff_cont (22850 90) (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)) + rect(via1 (1365 -2235) (250 250)) + rect(metal2 (-325 -325) (400 400)) + rect(metal2_lbl (-201 -201) (2 2)) + ) + net(3 name(VDD) + rect(diff_cont (7810 2490) (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 -1420) (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 (-2860 -1420) (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 -1420) (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 (-2860 -1420) (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 -1420) (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 (-2860 -1420) (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 -1420) (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 (12980 -1420) (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 -1420) (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 (-2860 -1420) (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 -1420) (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 (7700 -1420) (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 -1420) (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 (-2860 -1420) (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 -1420) (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 (7700 -1420) (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 -1420) (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 (-2860 -1420) (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 -1420) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(diff_cont (-220 180) (220 220)) + rect(metal1 (-21410 -10) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (-16200 -2600) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (12840 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (7560 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (7560 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal2_lbl (-21301 -1181) (2 2)) + ) + net(4 name('BULK,VSS') + rect(diff_cont (7810 90) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (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 (12980 980) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (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 (7700 980) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (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 (7700 980) (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 (-220 980) (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 (-2860 980) (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 (-220 980) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(diff_cont (-220 -620) (220 220)) + rect(metal1 (-21410 -1330) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (2280 -1120) (360 1120)) + rect(metal1 (-16200 -80) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (12840 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (7560 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (7560 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal1 (-3000 -1560) (360 1560)) + rect(metal1 (-360 -1560) (360 1560)) + rect(metal2_lbl (-21301 -381) (2 2)) + ) + net(5 + rect(diff_cont (1730 90) (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(6 + rect(diff_cont (17570 90) (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(7 + rect(diff_cont (12290 90) (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(8 + rect(diff_cont (7010 90) (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)) + ) + + # Outgoing pins and their connections to nets + pin(FB 1) + pin(OSC 2) + pin(VDD 3) + pin('BULK,VSS' 4) + + # Subcircuits and their connections + circuit($1 INV2PAIR location(19420 -800) + pin(BULK 4) + pin($1 3) + pin($2 4) + pin($3 1) + pin($4 6) + pin($5 2) + pin($6 3) + ) + circuit($2 INV2PAIR location(-1700 -800) + pin(BULK 4) + pin($1 3) + pin($2 4) + pin($4 1) + pin($5 5) + pin($6 3) + ) + circuit($3 INV2PAIR location(3580 -800) + pin(BULK 4) + pin($1 3) + pin($2 4) + pin($4 5) + pin($5 8) + pin($6 3) + ) + circuit($4 INV2PAIR location(8860 -800) + pin(BULK 4) + pin($1 3) + pin($2 4) + pin($4 8) + pin($5 7) + pin($6 3) + ) + circuit($5 INV2PAIR location(14140 -800) + pin(BULK 4) + pin($1 3) + pin($2 4) + pin($4 7) + pin($5 6) + pin($6 3) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(INV2 + + # Nets + net(1 name('1')) + net(2 name('2')) + net(3 name('3')) + net(4 name('4')) + net(5 name('5')) + net(6 name('6')) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + pin($4 5) + pin($5 6) + + # Devices and their connections + device($1 PMOS + param(L 0.25) + param(W 3.5) + param(AS 1.4) + param(AD 1.4) + param(PS 6.85) + param(PD 6.85) + terminal(S 3) + terminal(G 2) + terminal(D 5) + terminal(B 1) + ) + device($3 NMOS + param(L 0.25) + param(W 3.5) + param(AS 1.4) + param(AD 1.4) + param(PS 6.85) + param(PD 6.85) + terminal(S 3) + terminal(G 2) + terminal(D 4) + terminal(B 6) + ) + + ) + circuit(INV2PAIR + + # Nets + net(1 name('1')) + net(2 name('2')) + net(3 name('3')) + net(4 name('4')) + net(5 name('6')) + net(6 name('7')) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + pin($4) + pin($5 5) + pin($6 6) + + # Subcircuits and their connections + circuit($2 INV2 + pin($0 6) + pin($1 4) + pin($2 5) + pin($3 3) + pin($4 2) + pin($5 1) + ) + + ) + circuit(RINGO + + # Nets + net(1 name('1')) + net(2 name('2')) + net(3 name('3')) + net(4 name('4')) + net(5 name('6')) + net(6 name('5')) + net(7 name('8')) + net(8 name('7')) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + + # Subcircuits and their connections + circuit($1 INV2PAIR + pin($0 4) + pin($1 3) + pin($2 4) + pin($3 1) + pin($4 5) + pin($5 2) + pin($6 3) + ) + circuit($2 INV2PAIR + pin($0 4) + pin($1 3) + pin($2 4) + pin($3 1) + pin($4 1) + pin($5 6) + pin($6 3) + ) + circuit($3 INV2PAIR + pin($0 4) + pin($1 3) + pin($2 4) + pin($4 6) + pin($5 7) + pin($6 3) + ) + circuit($4 INV2PAIR + pin($0 4) + pin($1 3) + pin($2 4) + pin($4 7) + pin($5 8) + pin($6 3) + ) + circuit($5 INV2PAIR + pin($0 4) + pin($1 3) + pin($2 4) + pin($4 8) + pin($5 5) + pin($6 3) + ) + + ) + circuit(INV2PAIRX + + # Nets + net(1 name('1')) + net(2 name('2')) + net(3 name('3')) + net(4 name('4')) + net(5 name('6')) + net(6 name('7')) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + pin($4) + pin($5 5) + pin($6 6) + + # Subcircuits and their connections + circuit($2 INV2 + pin($0 6) + pin($1 4) + pin($2 5) + pin($3 3) + pin($4 2) + pin($5 1) + ) + + ) +) + +# Cross reference +xref( + circuit(() INV2PAIRX mismatch + xref( + ) + ) + circuit(INV2 INV2 match + xref( + net(1 1 match) + net(6 6 match) + net(2 2 match) + net(3 3 match) + net(5 5 match) + net(4 4 match) + pin($0 $0 match) + pin(BULK $5 match) + pin(IN $1 match) + pin(OUT $2 match) + pin(VDD $4 match) + pin(VSS $3 match) + device($1 $1 match) + device($3 $3 match) + ) + ) + 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(1 1 mismatch) + pin($3 () mismatch) + pin($1 $1 match) + pin($2 $2 match) + pin($4 $3 match) + pin($5 $5 match) + pin($6 $6 match) + pin(BULK $0 match) + circuit(() $2 mismatch) + circuit($1 () mismatch) + circuit($2 () mismatch) + ) + ) + circuit(RINGO RINGO skipped + xref( + ) + ) +) diff --git a/testdata/algo/lvs_test_2.spi b/testdata/algo/lvs_test_2.spi new file mode 100644 index 000000000..3d030f040 --- /dev/null +++ b/testdata/algo/lvs_test_2.spi @@ -0,0 +1,70 @@ +* Test netlist + +* cell RINGO +* pin FB +* pin OSC +* pin VDD +* pin BULK,VSS +.SUBCKT RINGO 1 2 3 4 +* net 1 FB +* net 2 OSC +* net 3 VDD +* net 4 BULK,VSS +* cell instance $1 r0 *1 19.42,-0.8 +X$1 4 3 4 1 6 2 3 INV2PAIR +* cell instance $2 r0 *1 -1.7,-0.8 +X$2 4 3 4 1 1 5 3 INV2PAIR +* cell instance $3 r0 *1 3.58,-0.8 +X$3 4 3 4 101 5 8 3 INV2PAIR +* cell instance $4 r0 *1 8.86,-0.8 +X$4 4 3 4 102 8 7 3 INV2PAIR +* cell instance $5 r0 *1 14.14,-0.8 +X$5 4 3 4 103 7 6 3 INV2PAIR +.ENDS RINGO + +* cell INV2PAIR +* pin BULK +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV2PAIR 1 2 3 4 5 6 7 +* net 1 BULK +* cell instance $2 r0 *1 4.34,0.8 +X$2 7 4 6 3 2 1 INV2 +.ENDS INV2PAIR + +* cell INV2PAIRX +* pin BULK +* pin +* pin +* pin +* pin +* pin +* pin +.SUBCKT INV2PAIRX 1 2 3 4 5 6 7 +* net 1 BULK +* cell instance $2 r0 *1 4.34,0.8 +X$2 7 4 6 3 2 1 INV2 +.ENDS INV2PAIR + +* cell INV2 +* pin +* pin IN +* pin OUT +* pin VSS +* pin VDD +* pin BULK +.SUBCKT INV2 1 2 3 4 5 6 +* net 2 IN +* net 3 OUT +* net 4 VSS +* net 5 VDD +* net 6 BULK +* device instance $1 -0.4,3.2 PMOS +M$1 3 2 5 1 PMOS L=0.25U W=3.5U AS=1.4P AD=1.4P PS=6.85U PD=6.85U +* device instance $3 -0.4,-0.4 NMOS +M$3 3 2 4 6 NMOS L=0.25U W=3.5U AS=1.4P AD=1.4P PS=6.85U PD=6.85U +.ENDS INV2