From ea28530c556f013a6f37a8f66ff6ddc003e6a9d7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 10 May 2019 00:15:51 +0200 Subject: [PATCH] L2N: combined device persistance (complex concept - needs simplification?) --- src/db/db/dbLayoutToNetlistReader.cc | 89 +- src/db/db/dbLayoutToNetlistReader.h | 4 +- src/db/db/dbNetlist.cc | 4 + .../dbLayoutToNetlistReaderTests.cc | 54 ++ testdata/algo/l2n_reader_4.gds | Bin 0 -> 7294 bytes testdata/algo/l2n_reader_4.l2n | 840 ++++++++++++++++++ testdata/algo/l2n_reader_au_4.gds | Bin 0 -> 35178 bytes testdata/algo/l2n_reader_au_4.l2n | 840 ++++++++++++++++++ 8 files changed, 1805 insertions(+), 26 deletions(-) create mode 100644 testdata/algo/l2n_reader_4.gds create mode 100644 testdata/algo/l2n_reader_4.l2n create mode 100644 testdata/algo/l2n_reader_au_4.gds create mode 100644 testdata/algo/l2n_reader_au_4.l2n diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index 79d056f25..21d895583 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -287,13 +287,9 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n) } else if (test (skeys::pin_key) || test (lkeys::pin_key)) { read_pin (l2n, circuit, id2net); } else if (test (skeys::device_key) || test (lkeys::device_key)) { - std::list conn; - db::CellInstArray ia = read_device (l2n, circuit, conn, id2net); - connections[ia] = conn; + read_device (l2n, circuit, id2net, connections); } else if (test (skeys::circuit_key) || test (lkeys::circuit_key)) { - std::list conn; - db::CellInstArray ia = read_subcircuit (l2n, circuit, conn, id2net); - connections[ia] = conn; + read_subcircuit (l2n, circuit, id2net, connections); } else { throw tl::Exception (tl::to_string (tr ("Invalid keyword inside circuit definition (net, pin, device or circuit expected)"))); } @@ -309,7 +305,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n) std::map >::const_iterator c = connections.find (i->cell_inst ()); if (c != connections.end ()) { for (std::list::const_iterator j = c->second.begin (); j != c->second.end (); ++j) { - l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans () * db::ICplxTrans (j->offset), i->prop_id ())); + l2n->net_clusters ().clusters_per_cell (ci).add_connection (j->from_cluster, db::ClusterInstance (j->to_cluster, i->cell_index (), i->complex_trans (), i->prop_id ())); } } } @@ -511,8 +507,8 @@ device_model_by_name (db::Netlist *netlist, const std::string &dmname) throw tl::Exception (tl::to_string (tr ("Not a valid device abstract name: ")) + dmname); } -db::CellInstArray -LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list &refs, std::map &id2net) +void +LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) { Brace br (this); @@ -534,6 +530,11 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui double dbu = l2n->internal_layout ()->dbu (); db::VCplxTrans dbu_inv (1.0 / dbu); + std::map, size_t> abstracts; + abstracts [std::make_pair (dm, db::Vector ())] = 0; + + size_t max_tid = 0; + while (br) { if (test (skeys::location_key) || test (lkeys::location_key)) { @@ -556,7 +557,10 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui br2.done (); - device->other_abstracts ().push_back (std::make_pair (device_model_by_name (l2n->netlist (), n), db::DVector (dbu * dx, dbu * dy))); + db::DeviceAbstract *da = device_model_by_name (l2n->netlist (), n); + + abstracts [std::make_pair (da, db::Vector (dx, dy))] = device->other_abstracts ().size () + 1; + device->other_abstracts ().push_back (std::make_pair (da, db::DVector (dbu * dx, dbu * dy))); } else if (test (skeys::connect_key) || test (lkeys::connect_key)) { @@ -578,7 +582,8 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui size_t tinner_id = terminal_id (dm->device_class (), tinner); const db::DeviceAbstract *da = device_comp_index > 0 ? device->other_abstracts () [device_comp_index - 1].first : dm; - db::DVector da_offset = device_comp_index > 0 ? device->other_abstracts () [device_comp_index - 1].second : db::DVector (); + db::DVector da_offset = device_comp_index > 0 ? device->other_abstracts () [device_comp_index - 1].second : db::DVector (); + device->reconnected_terminals () [touter_id].push_back (db::Device::OtherTerminalRef (da, da_offset, tinner_id)); } else if (test (skeys::terminal_key) || test (lkeys::terminal_key)) { @@ -590,6 +595,7 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui br2.done (); size_t tid = terminal_id (dm->device_class (), tname); + max_tid = std::max (max_tid, tid + 1); db::Net *net = id2net [netid]; if (!net) { @@ -598,15 +604,6 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui device->connect_terminal (tid, net); - const std::vector *tr = device->reconnected_terminals_for (tid); - if (tr) { - for (std::vector::const_iterator i = tr->begin (); i != tr->end (); ++i) { - refs.push_back (Connections (net->cluster_id (), i->device_abstract->cluster_id_for_terminal (i->other_terminal_id), dbu_inv * i->offset)); - } - } else { - refs.push_back (Connections (net->cluster_id (), dm->cluster_id_for_terminal (tid), db::Vector ())); - } - } else if (test (skeys::param_key) || test (lkeys::param_key)) { Brace br2 (this); @@ -646,25 +643,69 @@ LayoutToNetlistStandardReader::read_device (db::LayoutToNetlist *l2n, db::Circui db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); // make device cell instances + std::vector insts; + db::CellInstArray inst (db::CellInst (dm->cell_index ()), db::Trans (db::Vector (x, y))); ccell.insert (inst); + insts.push_back (inst); const std::vector > &other_devices = device->other_abstracts (); for (std::vector >::const_iterator i = other_devices.begin (); i != other_devices.end (); ++i) { db::CellInstArray other_inst (db::CellInst (i->first->cell_index ()), db::Trans (db::Vector (x, y) + dbu_inv * i->second)); ccell.insert (other_inst); + insts.push_back (other_inst); } - return inst; + // register cluster collections to be made later + + for (size_t tid = 0; tid < max_tid; ++tid) { + + const db::Net *net = device->net_for_terminal (tid); + if (! net) { + continue; + } + + if (! device->reconnected_terminals ().empty ()) { + + const std::vector *tr = device->reconnected_terminals_for (tid); + if (tr) { + + for (std::vector::const_iterator i = tr->begin (); i != tr->end (); ++i) { + + db::Vector offset = dbu_inv * i->offset; + + std::map, size_t>::const_iterator a = abstracts.find (std::make_pair (i->device_abstract, offset)); + if (a != abstracts.end () && a->second < insts.size ()) { + Connections ref (net->cluster_id (), i->device_abstract->cluster_id_for_terminal (i->other_terminal_id), dbu_inv * i->offset); + connections [insts [a->second]].push_back (ref); + } + + } + + } + + } else { + + std::map, size_t>::const_iterator a = abstracts.find (std::make_pair (dm, db::Vector ())); + if (a != abstracts.end () && a->second < insts.size ()) { + Connections ref (net->cluster_id (), dm->cluster_id_for_terminal (tid), db::Vector ()); + connections [insts [a->second]].push_back (ref); + } + + } + + } } -db::CellInstArray -LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list &refs, std::map &id2net) +void +LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections) { Brace br (this); + std::list refs; + std::string name; read_word_or_quoted (name); @@ -767,7 +808,7 @@ LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Ci db::Cell &ccell = l2n->internal_layout ()->cell (circuit->cell_index ()); ccell.insert (inst); - return inst; + connections [inst] = refs; } void diff --git a/src/db/db/dbLayoutToNetlistReader.h b/src/db/db/dbLayoutToNetlistReader.h index 8a4e95efc..4f88c6417 100644 --- a/src/db/db/dbLayoutToNetlistReader.h +++ b/src/db/db/dbLayoutToNetlistReader.h @@ -101,8 +101,8 @@ private: void read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); void read_pin (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net); - db::CellInstArray read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list &refs, std::map &id2net); - db::CellInstArray read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list &refs, std::map &id2net); + void read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); + void read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::map &id2net, std::map > &connections); void read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceAbstract *dm, db::DeviceClass *dc); std::pair read_geometry (db::LayoutToNetlist *l2n); void read_geometries (Brace &br, db::LayoutToNetlist *l2n, db::local_cluster &lc, db::Cell &cell); diff --git a/src/db/db/dbNetlist.cc b/src/db/db/dbNetlist.cc index 81eada167..24a9329ff 100644 --- a/src/db/db/dbNetlist.cc +++ b/src/db/db/dbNetlist.cc @@ -233,6 +233,10 @@ void Netlist::validate_topology () throw tl::Exception (tl::to_string (tr ("Recursive hierarchy detected in netlist"))); } + // doing this reverse will mean we preserve bottom-up order. This is useful for + // netlists where subcircuits have to be defined before they are used. + std::reverse (m_top_down_circuits.begin () + n_top_down_circuits, m_top_down_circuits.end ()); + } // Determine the number of top cells diff --git a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc index 117b66acd..0178c3f6a 100644 --- a/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc +++ b/src/db/unit_tests/dbLayoutToNetlistReaderTests.cc @@ -252,3 +252,57 @@ TEST(3_ReaderAbsoluteCoordinates) } } +TEST(4_ReaderCombinedDevices) +{ + db::LayoutToNetlist l2n; + + // build from: testdata/algo/l2n_reader_4.gds + + std::string in_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_reader_4.l2n"); + tl::InputStream is_in (in_path); + + db::LayoutToNetlistStandardReader reader (is_in); + reader.read (&l2n); + + // verify against the input + + std::string path = tmp_file ("tmp_l2nreader_4.txt"); + { + tl::OutputStream stream (path); + db::LayoutToNetlistStandardWriter writer (stream, false); + writer.write (&l2n); + } + + std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_reader_au_4.l2n"); + + tl::InputStream is (path); + tl::InputStream is_au (au_path); + + if (is.read_all () != is_au.read_all ()) { + _this->raise (tl::sprintf ("Compare failed - see\n actual: %s\n golden: %s", + tl::absolute_file_path (path), + tl::absolute_file_path (au_path))); + } + + // test build_all_nets from read l2n + + { + db::Layout ly2; + ly2.dbu (l2n.internal_layout ()->dbu ()); + db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP")); + + db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/); + + std::map lmap = l2n.create_layermap (ly2, 1000); + + l2n.build_all_nets (cm, ly2, lmap, "NET_", tl::Variant (), db::LayoutToNetlist::BNH_SubcircuitCells, "CIRCUIT_", "DEVICE_"); + + std::string au = tl::testsrc (); + au = tl::combine_path (au, "testdata"); + au = tl::combine_path (au, "algo"); + au = tl::combine_path (au, "l2n_reader_au_4.gds"); + + db::compare_layouts (_this, ly2, au); + } +} + diff --git a/testdata/algo/l2n_reader_4.gds b/testdata/algo/l2n_reader_4.gds new file mode 100644 index 0000000000000000000000000000000000000000..6f16ba1377accf5477774a20cb62e36557e0ef37 GIT binary patch literal 7294 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 bmnjeLe`d;e@)dKgoZqr*E4OGK94!71n1Z(6 literal 0 HcmV?d00001 diff --git a/testdata/algo/l2n_reader_au_4.l2n b/testdata/algo/l2n_reader_au_4.l2n new file mode 100644 index 000000000..d7e39bdf0 --- /dev/null +++ b/testdata/algo/l2n_reader_au_4.l2n @@ -0,0 +1,840 @@ +#%l2n-klayout + +# General section + +top(RINGO) +unit(0.001) + +# Layer section +# This section lists the mask layers (drawing or derived) and their connections. + +# Mask layers +layer($3 '3/0') +layer($9 '3/1') +layer($4 '4/0') +layer($5 '5/0') +layer($6 '6/0') +layer($10 '6/1') +layer($7 '7/0') +layer($8 '8/0') +layer($11 '8/1') +layer($1) +layer($2) + +# Mask layer connectivity +connect($3 $3 $9 $5) +connect($9 $3) +connect($4 $4 $6 $1 $2) +connect($5 $3 $5 $6) +connect($6 $4 $5 $6 $10 $7) +connect($10 $6) +connect($7 $6 $7 $8) +connect($8 $7 $8 $11) +connect($11 $8) +connect($1 $4 $1) +connect($2 $4 $2) + +# Device class section +class(PMOS MOS3) +class(NMOS MOS3) + +# Device abstracts section +# Device abstracts list the pin shapes of the devices. +device(D$PMOS PMOS + terminal(S + rect($1 (-650 -475) (525 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($1 (125 -475) (550 950)) + ) +) +device(D$PMOS$1 PMOS + terminal(S + rect($1 (-675 -475) (550 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($1 (125 -475) (525 950)) + ) +) +device(D$PMOS$2 PMOS + terminal(S + rect($1 (-475 -650) (950 525)) + ) + terminal(G + rect($3 (-475 -125) (950 250)) + ) + terminal(D + rect($1 (-475 125) (950 525)) + ) +) +device(D$PMOS$3 PMOS + terminal(S + rect($1 (-650 -475) (525 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($1 (125 -475) (525 950)) + ) +) +device(D$NMOS NMOS + terminal(S + rect($2 (-650 -475) (525 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($2 (125 -475) (550 950)) + ) +) +device(D$NMOS$1 NMOS + terminal(S + rect($2 (-675 -475) (550 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($2 (125 -475) (525 950)) + ) +) +device(D$NMOS$2 NMOS + terminal(S + rect($2 (-475 -650) (950 525)) + ) + terminal(G + rect($3 (-475 -125) (950 250)) + ) + terminal(D + rect($2 (-475 125) (950 525)) + ) +) +device(D$NMOS$3 NMOS + terminal(S + rect($2 (-650 -475) (525 950)) + ) + terminal(G + rect($3 (-125 -475) (250 950)) + ) + terminal(D + rect($2 (125 -475) (525 950)) + ) +) + +# Circuit section +# Circuits are the hierarchical building blocks of the netlist. +circuit(INV2ALT + + # Nets with their geometries + net(1 + rect($3 (675 600) (250 2300)) + rect($3 (-250 0) (1050 200)) + rect($3 (-1725 -1900) (800 500)) + rect($3 (700 1400) (225 1300)) + rect($3 (-1850 -3700) (250 1500)) + rect($3 (-250 -3000) (250 1600)) + rect($3 (775 -225) (1600 250)) + rect($3 (-2400 3350) (1600 250)) + rect($3 (-1825 -2325) (250 1600)) + ) + net(2 + rect($4 (290 -310) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 2280) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (880 -2220) (220 220)) + rect($4 (180 -220) (220 220)) + rect($4 (-1020 2580) (220 220)) + rect($4 (-620 -220) (220 220)) + rect($6 (-590 -3710) (360 3800)) + rect($6 (-180 -3200) (920 380)) + rect($6 (-1100 -1660) (360 760)) + rect($6 (-360 2140) (360 760)) + rect($6 (740 -2360) (760 360)) + rect($6 (-1560 2440) (760 360)) + rect($1 (-855 -430) (950 525)) + rect($1 (-1250 -1750) (525 950)) + rect($2 (575 -2550) (950 525)) + rect($2 (-2050 -1825) (525 950)) + ) + net(3 + rect($4 (990 4590) (220 220)) + rect($4 (-620 -220) (220 220)) + rect($4 (-1320 -2220) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (810 1310) (760 360)) + rect($6 (-1860 -2360) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($7 (880 1780) (220 220)) + rect($7 (180 -220) (220 220)) + polygon($8 (-5510 -2510) (0 1200) (3100 0) (0 1800) (3800 0) (0 -1800) (2100 0) (0 -1200) (-2900 0) (0 2200) (-2000 0) (0 -2200)) + rect($1 (625 2125) (950 525)) + rect($1 (-2025 -2525) (525 950)) + ) + net(4 + rect($4 (1390 190) (220 220)) + rect($4 (180 -220) (220 220)) + rect($4 (-2520 -720) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (1610 -190) (760 360)) + rect($6 (-2660 -860) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($7 (1680 280) (220 220)) + rect($7 (180 -220) (220 220)) + rect($8 (-6310 -1010) (9000 1200)) + rect($2 (-3475 -550) (950 525)) + rect($2 (-2825 -1050) (525 950)) + ) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + + # Devices and their connections + device($1 D$PMOS$2 + device(D$PMOS$3 -900 -1400) + connect(0 S S) + connect(1 S D) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D S) + location(900 4300) + param(L 0.25) + param(W 1.9) + param(AS 0.9975) + param(AD 0.9975) + param(PS 5.9) + param(PD 5.9) + terminal(S 2) + terminal(G 1) + terminal(D 3) + ) + device($3 D$NMOS$2 + device(D$NMOS$3 -1700 -700) + connect(0 S S) + connect(1 S S) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D D) + location(1700 700) + param(L 0.25) + param(W 1.9) + param(AS 0.9975) + param(AD 0.9975) + param(PS 5.9) + param(PD 5.9) + terminal(S 4) + terminal(G 1) + terminal(D 2) + ) + +) +circuit(NAND1X + + # Nets with their geometries + net(1 + rect($4 (290 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (580 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-290 -310) (360 1500)) + rect($6 (-1160 -400) (1160 400)) + rect($6 (-1160 -400) (360 1500)) + rect($6 (-360 -80) (360 760)) + rect($6 (-360 -760) (360 760)) + rect($6 (440 -3660) (360 760)) + rect($1 (-1255 2045) (550 950)) + rect($2 (250 -3850) (525 950)) + ) + net(2 + rect($4 (1090 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (1310 -690) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($7 (1380 180) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($8 (-2410 -510) (3000 1200)) + rect($1 (-975 -1075) (525 950)) + rect($1 (-2100 -950) (525 950)) + ) + net(3 + rect($4 (-510 -310) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-290 -690) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($8 (-810 -510) (3000 1200)) + rect($2 (-2550 -1075) (525 950)) + ) + net(4 + rect($3 (-125 700) (250 1500)) + rect($3 (-250 -100) (250 1600)) + rect($3 (-250 -4500) (250 1600)) + ) + net(5 + rect($3 (675 700) (250 1500)) + rect($3 (-250 -100) (250 1600)) + rect($3 (-250 -4500) (250 1600)) + ) + net(6 + rect($4 (290 -310) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-290 -690) (360 760)) + rect($6 (-360 -760) (360 760)) + rect($2 (-455 -855) (550 950)) + ) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + pin($4 5) + + # Devices and their connections + device($1 D$PMOS + location(0 2900) + param(L 0.25) + param(W 0.95) + param(AS 0.49875) + param(AD 0.26125) + param(PS 2.95) + param(PD 1.5) + terminal(S 2) + terminal(G 4) + terminal(D 1) + ) + device($2 D$PMOS$1 + location(800 2900) + param(L 0.25) + param(W 0.95) + param(AS 0.26125) + param(AD 0.49875) + param(PS 1.5) + param(PD 2.95) + terminal(S 1) + terminal(G 5) + terminal(D 2) + ) + device($3 D$NMOS + location(0 0) + param(L 0.25) + param(W 0.95) + param(AS 0.49875) + param(AD 0.26125) + param(PS 2.95) + param(PD 1.5) + terminal(S 3) + terminal(G 4) + terminal(D 6) + ) + device($4 D$NMOS$1 + location(800 0) + param(L 0.25) + param(W 0.95) + param(AS 0.26125) + param(AD 0.49875) + param(PS 1.5) + param(PD 2.95) + terminal(S 6) + terminal(G 5) + terminal(D 1) + ) + +) +circuit(INV2X + + # Nets with their geometries + net(1 + rect($3 (-125 700) (250 1500)) + rect($3 (-125 -1000) (800 500)) + rect($3 (-125 -1000) (250 1500)) + rect($3 (-250 -100) (250 1600)) + rect($3 (-1050 -1600) (250 1600)) + rect($3 (550 -4500) (250 1600)) + rect($3 (-1050 -1600) (250 1600)) + ) + net(2 + rect($4 (1090 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (1310 -690) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($7 (1380 180) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($8 (-2410 -510) (3000 1200)) + rect($1 (-975 -1075) (525 950)) + rect($1 (-2100 -950) (525 950)) + ) + net(3 + rect($4 (1090 -310) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (1310 -690) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($7 (-290 -290) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($7 (1380 180) (220 220)) + rect($7 (-220 -620) (220 220)) + rect($8 (-2410 -510) (3000 1200)) + rect($2 (-975 -1075) (525 950)) + rect($2 (-2100 -950) (525 950)) + ) + net(4 + rect($4 (290 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-290 -10) (360 2300)) + rect($6 (-360 -80) (360 760)) + rect($6 (-360 -760) (360 760)) + rect($6 (-360 -3660) (360 760)) + rect($6 (-360 -760) (360 760)) + rect($1 (-455 2045) (550 950)) + rect($2 (-550 -3850) (550 950)) + ) + + # Outgoing pins and their connections to nets + pin($0 1) + pin($1 2) + pin($2 3) + pin($3 4) + + # Devices and their connections + device($1 D$PMOS + device(D$PMOS$1 800 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) + location(0 2900) + param(L 0.25) + param(W 1.9) + param(AS 0.76) + param(AD 0.76) + param(PS 4.45) + param(PD 4.45) + terminal(S 2) + terminal(G 1) + terminal(D 4) + ) + device($3 D$NMOS + device(D$NMOS$1 800 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) + location(0 0) + param(L 0.25) + param(W 1.9) + param(AS 0.76) + param(AD 0.76) + param(PS 4.45) + param(PD 4.45) + terminal(S 3) + terminal(G 1) + terminal(D 4) + ) + +) +circuit(RINGO + + # Nets with their geometries + net(1 + rect($3 (1700 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(2 + rect($3 (4700 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(3 + rect($3 (15000 1100) (1300 400)) + rect($4 (-4910 -1810) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 2280) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (880 -2220) (220 220)) + rect($4 (180 -220) (220 220)) + rect($4 (-1020 2580) (220 220)) + rect($4 (-620 -220) (220 220)) + rect($5 (3190 -2810) (200 200)) + rect($6 (-2400 -300) (2500 400)) + ) + net(4 + rect($3 (18000 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(5 + rect($3 (21000 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(6 + rect($3 (24000 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(7 + rect($3 (27000 1100) (1300 400)) + rect($4 (-2710 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($6 (-1500 -300) (1600 400)) + ) + net(8 name(FB) + rect($3 (30000 1100) (1300 400)) + rect($3 (-33375 100) (1275 400)) + rect($4 (29390 590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (1290 890) (200 200)) + rect($5 (-31400 300) (200 200)) + rect($6 (29700 -800) (1600 400)) + rect($6 (-31600 100) (400 400)) + rect($7 (30900 -800) (200 200)) + rect($7 (-31400 300) (200 200)) + rect($8 (-300 -800) (31600 400)) + rect($8 (-31600 -400) (400 900)) + rect($11 (16399 -701) (2 2)) + ) + net(9 + rect($3 (-1300 900) (1300 400)) + rect($4 (-2710 1290) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (580 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (490 690) (200 200)) + rect($6 (-800 -300) (900 400)) + ) + net(10 name(EN) + rect($3 (-4000 1200) (875 500)) + rect($9 (-476 -201) (2 2)) + ) + net(11 + rect($3 (9800 1100) (1300 400)) + rect($4 (-4810 1090) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($5 (3390 890) (200 200)) + rect($6 (-3600 -300) (3700 400)) + ) + net(12 name(OUT) + rect($4 (31590 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -3520) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($10 (-111 589) (2 2)) + ) + net(13 name(VDD) + rect($4 (4090 2590) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1620 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1620 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (10380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (6380 1380) (220 220)) + rect($4 (-620 -220) (220 220)) + rect($4 (-1320 -2220) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (6580 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-26990 -690) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (-1760 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (-1760 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (10240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (5840 1240) (760 360)) + rect($6 (-1860 -2360) (360 760)) + rect($6 (6440 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($11 (-881 -381) (2 2)) + ) + net(14 name(VSS) + rect($4 (4090 -310) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1620 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-3220 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (10380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (6780 -120) (220 220)) + rect($4 (180 -220) (220 220)) + rect($4 (-2520 -720) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (6580 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (4380 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($4 (-1820 -620) (220 220)) + rect($4 (-220 180) (220 220)) + rect($6 (-26990 -690) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (-1760 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (-3360 -760) (360 760)) + rect($6 (10240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (6640 -260) (760 360)) + rect($6 (-2660 -860) (360 760)) + rect($6 (6440 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($6 (4240 -760) (360 760)) + rect($6 (-1960 -760) (360 760)) + rect($11 (-881 -381) (2 2)) + ) + + # Outgoing pins and their connections to nets + pin(FB 8) + pin(EN 10) + pin(OUT 12) + pin(VDD 13) + pin(VSS 14) + + # Subcircuits and their connections + circuit($1 INV2X location(0 0) + pin($0 9) + pin($1 13) + pin($2 14) + pin($3 1) + ) + circuit($2 INV2X location(3000 0) + pin($0 1) + pin($1 13) + pin($2 14) + pin($3 2) + ) + circuit($3 INV2X location(6000 0) + pin($0 2) + pin($1 13) + pin($2 14) + pin($3 11) + ) + circuit($4 INV2ALT location(11100 0) + pin($0 11) + pin($1 3) + pin($2 13) + pin($3 14) + ) + circuit($5 INV2X location(16300 0) + pin($0 3) + pin($1 13) + pin($2 14) + pin($3 4) + ) + circuit($6 INV2X location(19300 0) + pin($0 4) + pin($1 13) + pin($2 14) + pin($3 5) + ) + circuit($7 INV2X location(22300 0) + pin($0 5) + pin($1 13) + pin($2 14) + pin($3 6) + ) + circuit($8 INV2X location(25300 0) + pin($0 6) + pin($1 13) + pin($2 14) + pin($3 7) + ) + circuit($9 INV2X location(28300 0) + pin($0 7) + pin($1 13) + pin($2 14) + pin($3 8) + ) + circuit($10 NAND1X location(-3000 0) + pin($0 9) + pin($1 13) + pin($2 14) + pin($3 10) + pin($4 8) + ) + circuit($11 INV2X location(31300 0) + pin($0 8) + pin($1 13) + pin($2 14) + pin($3 12) + ) + +)