diff --git a/src/db/db/dbNetlistCompare.cc b/src/db/db/dbNetlistCompare.cc index c3555691e..1d146713d 100644 --- a/src/db/db/dbNetlistCompare.cc +++ b/src/db/db/dbNetlistCompare.cc @@ -776,8 +776,9 @@ public: { if (is_for_subcircuit ()) { const db::SubCircuit *sc = subcircuit_pair ().first; + size_t pin_id = std::numeric_limits::max () - m_id1; const db::Circuit *c = sc->circuit_ref (); - return std::string ("X") + sc->expanded_name () + " " + c->name (); + return std::string ("X") + sc->expanded_name () + " " + c->name () + " " + c->pin_by_id (pin_id)->expanded_name () + " (virtual)"; } else { size_t term_id1 = m_id1; size_t term_id2 = m_id2; @@ -1012,6 +1013,14 @@ public: return j->second; } + /** + * @brief Gets a value indicating whether there is a node for the given net + */ + bool has_node_index_for_net (const db::Net *net) const + { + return m_net_index.find (net) != m_net_index.end (); + } + /** * @brief Gets the node for a given node index */ @@ -2879,9 +2888,16 @@ NetlistComparer::exclude_resistors (double threshold) } void -NetlistComparer::same_nets (const db::Net *na, const db::Net *nb) +NetlistComparer::same_nets (const db::Net *na, const db::Net *nb, bool must_match) { - m_same_nets [std::make_pair (na->circuit (), nb->circuit ())].push_back (std::make_pair (na, nb)); + tl_assert (na && na); + m_same_nets [std::make_pair (na->circuit (), nb->circuit ())].push_back (std::make_pair (std::make_pair (na, nb), must_match)); +} + +void +NetlistComparer::same_nets (const db::Circuit *ca, const db::Circuit *cb, const db::Net *na, const db::Net *nb, bool must_match) +{ + m_same_nets [std::make_pair (ca, cb)].push_back (std::make_pair (std::make_pair (na, nb), must_match)); } void @@ -3113,9 +3129,9 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const tl_assert (i->second.second.size () == size_t (1)); const db::Circuit *cb = i->second.second.front (); - std::vector > empty; - const std::vector > *net_identity = ∅ - std::map, std::vector > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); + std::vector, bool> > empty; + const std::vector, bool> > *net_identity = ∅ + std::map, std::vector, bool> > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb)); if (sn != m_same_nets.end ()) { net_identity = &sn->second; } @@ -3168,14 +3184,16 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const } static -std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper) +std::vector collect_anonymous_empty_pins (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper) { std::vector pins; for (db::Circuit::const_pin_iterator p = c->begin_pins (); p != c->end_pins (); ++p) { - const db::Net *net = c->net_for_pin (p->id ()); - if ((! net || net->is_passive ()) && ! circuit_pin_mapper->is_mapped (c, p->id ())) { - pins.push_back (p->id ()); + if (p->name ().empty () && ! circuit_pin_mapper->is_mapped (c, p->id ())) { + const db::Net *net = c->net_for_pin (p->id ()); + if (! net || net->is_passive ()) { + pins.push_back (p->id ()); + } } } @@ -3185,13 +3203,11 @@ std::vector collect_pins_with_empty_nets (const db::Circuit *c, CircuitP void NetlistComparer::derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper) { - // TODO: All pins with empty nets are treated as equivalent - this as a quick way to - // treat circuits abstracts, although it's not really valid. By doing this, we - // don't capture the case of multiple (abstract) subcircuits wired in different ways. + // NOTE: All unnamed pins with empty nets are treated as equivalent. There is no other criterion to match these pins. std::vector pa, pb; - pa = collect_pins_with_empty_nets (ca, circuit_pin_mapper); - pb = collect_pins_with_empty_nets (cb, circuit_pin_mapper); + pa = collect_anonymous_empty_pins (ca, circuit_pin_mapper); + pb = collect_anonymous_empty_pins (cb, circuit_pin_mapper); circuit_pin_mapper->map_pins (ca, pa); circuit_pin_mapper->map_pins (cb, pb); @@ -3524,7 +3540,7 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, db::CircuitPinMapper &circuit_pin_mapper, - const std::vector > &net_identity, + const std::vector, bool> > &net_identity, bool &pin_mismatch, std::map &c12_circuit_and_pin_mapping, std::map &c22_circuit_and_pin_mapping) const @@ -3537,18 +3553,52 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2, // NOTE: for normalization we map all subcircuits of c1 to c2. // Also, pin swapping will only happen there. + if (options ()->debug_netgraph) { + tl::info << "Netlist graph:"; + } g1.build (c1, device_categorizer, circuit_categorizer, device_filter, &c12_circuit_and_pin_mapping, &circuit_pin_mapper); + if (options ()->debug_netgraph) { + tl::info << "Other netlist graph:"; + } g2.build (c2, device_categorizer, circuit_categorizer, device_filter, &c22_circuit_and_pin_mapping, &circuit_pin_mapper); // Match dummy nodes for null nets g1.identify (0, 0); g2.identify (0, 0); - for (std::vector >::const_iterator p = net_identity.begin (); p != net_identity.end (); ++p) { - size_t ni1 = g1.node_index_for_net (p->first); - size_t ni2 = g2.node_index_for_net (p->second); - g1.identify (ni1, ni2); - g2.identify (ni2, ni1); + for (std::vector, bool> >::const_iterator p = net_identity.begin (); p != net_identity.end (); ++p) { + + // NOTE: nets may vanish, hence there + if (g1.has_node_index_for_net (p->first.first) && g2.has_node_index_for_net (p->first.second)) { + + size_t ni1 = g1.node_index_for_net (p->first.first); + size_t ni2 = g2.node_index_for_net (p->first.second); + g1.identify (ni1, ni2); + g2.identify (ni2, ni1); + + // in must_match mode, check if the nets are identical + if (p->second && ! (g1.node(ni1) == g2.node(ni2))) { + mp_logger->net_mismatch (p->first.first, p->first.second); + } else { + mp_logger->match_nets (p->first.first, p->first.second); + } + + } else if (p->second && g1.has_node_index_for_net (p->first.first)) { + + mp_logger->net_mismatch (p->first.first, 0); + + size_t ni1 = g1.node_index_for_net (p->first.first); + g1.identify (ni1, 0); + + } else if (p->second && g2.has_node_index_for_net (p->first.second)) { + + mp_logger->net_mismatch (0, p->first.second); + + size_t ni2 = g2.node_index_for_net (p->first.second); + g2.identify (ni2, 0); + + } + } int iter = 0; @@ -3851,7 +3901,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g mp_logger->match_pins (p.operator-> (), fp->second); } c12_pin_mapping.map_pin (p->id (), fp->second->id ()); - c22_pin_mapping.map_pin (fp->second->id (), p->id ()); + c22_pin_mapping.map_pin (fp->second->id (), fp->second->id ()); } else if (next_abstract != abstract_pins2.end ()) { @@ -3861,7 +3911,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g mp_logger->match_pins (p.operator-> (), *next_abstract); } c12_pin_mapping.map_pin (p->id (), (*next_abstract)->id ()); - c22_pin_mapping.map_pin ((*next_abstract)->id (), p->id ()); + c22_pin_mapping.map_pin ((*next_abstract)->id (), (*next_abstract)->id ()); ++next_abstract; @@ -4470,7 +4520,9 @@ NetlistComparer::join_symmetric_nets (db::Circuit *circuit) std::map circuit_and_pin_mapping; db::NetGraph graph; - graph.build (circuit, *mp_device_categorizer, *mp_circuit_categorizer, device_filter, &circuit_and_pin_mapping, &circuit_pin_mapper); + db::CircuitCategorizer circuit_categorizer; + db::DeviceCategorizer device_categorizer; + graph.build (circuit, device_categorizer, circuit_categorizer, device_filter, &circuit_and_pin_mapping, &circuit_pin_mapper); // sort the nodes so we can easily identify the identical ones (in terms of topology) // nodes are identical if the attached devices and circuits are of the same kind and with the same parameters diff --git a/src/db/db/dbNetlistCompare.h b/src/db/db/dbNetlistCompare.h index 2d4e81506..197d5ef6c 100644 --- a/src/db/db/dbNetlistCompare.h +++ b/src/db/db/dbNetlistCompare.h @@ -181,7 +181,17 @@ public: * net nb in netlist b. * By default nets are not identical expect through their topology. */ - void same_nets (const db::Net *na, const db::Net *nb); + void same_nets (const db::Net *na, const db::Net *nb, bool must_match = false); + + /** + * @brief Mark two nets as identical + * + * This makes a net na in netlist a identical to the corresponding + * net nb in netlist b. + * By default nets are not identical expect through their topology. + * This version allows mapping one net to a null net because the circuits are explicitly specified. + */ + void same_nets (const db::Circuit *ca, const db::Circuit *cb, const db::Net *na, const db::Net *nb, bool must_match); /** * @brief Mark two pins as equivalent (i.e. can be swapped) @@ -344,7 +354,7 @@ private: NetlistComparer &operator= (const NetlistComparer &); protected: - bool compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, db::CircuitPinMapper &circuit_pin_mapper, const std::vector > &net_identity, bool &pin_mismatch, std::map &c12_circuit_and_pin_mapping, std::map &c22_circuit_and_pin_mapping) const; + bool compare_circuits (const db::Circuit *c1, const db::Circuit *c2, db::DeviceCategorizer &device_categorizer, db::CircuitCategorizer &circuit_categorizer, db::CircuitPinMapper &circuit_pin_mapper, const std::vector, bool> > &net_identity, bool &pin_mismatch, std::map &c12_circuit_and_pin_mapping, std::map &c22_circuit_and_pin_mapping) const; bool all_subcircuits_verified (const db::Circuit *c, const std::set &verified_circuits) const; std::string generate_subcircuits_not_verified_warning (const db::Circuit *ca, const std::set &verified_circuits_a, const db::Circuit *cb, const std::set &verified_circuits_b) const; static void derive_pin_equivalence (const db::Circuit *ca, const db::Circuit *cb, CircuitPinMapper *circuit_pin_mapper); @@ -354,7 +364,7 @@ protected: bool handle_pin_mismatch (const NetGraph &g1, const db::Circuit *c1, const db::Pin *pin1, const NetGraph &g2, const db::Circuit *c2, const db::Pin *p2) const; mutable NetlistCompareLogger *mp_logger; - std::map, std::vector > > m_same_nets; + std::map, std::vector, bool> > > m_same_nets; std::unique_ptr mp_circuit_pin_mapper; std::unique_ptr mp_device_categorizer; std::unique_ptr mp_circuit_categorizer; diff --git a/src/db/db/dbNetlistCrossReference.cc b/src/db/db/dbNetlistCrossReference.cc index 4ebae1072..99ab8c780 100644 --- a/src/db/db/dbNetlistCrossReference.cc +++ b/src/db/db/dbNetlistCrossReference.cc @@ -113,6 +113,10 @@ NetlistCrossReference::other_net_for (const db::Net *net) const const NetlistCrossReference::PerNetData * NetlistCrossReference::per_net_data_for (const std::pair &nets) const { + if (! nets.first && ! nets.second) { + return 0; + } + std::map, PerNetData>::iterator i = m_per_net_data.find (nets); if (i == m_per_net_data.end ()) { i = m_per_net_data.insert (std::make_pair (nets, PerNetData ())).first; @@ -628,11 +632,13 @@ NetlistCrossReference::build_subcircuit_pin_refs (const std::pair &nets, PerNetData &data) const { - if (! nets.second) { + if (! nets.first && ! nets.second) { + // .. nothing .. + } else if (! nets.second) { init_data_from_single (nets.first, data, true); } else if (! nets.first) { init_data_from_single (nets.second, data, false); - } else if (nets.first) { + } else { build_terminal_refs (nets, data); build_pin_refs (nets, data); build_subcircuit_pin_refs (nets, data); diff --git a/src/db/db/gsiDeclDbNetlist.cc b/src/db/db/gsiDeclDbNetlist.cc index be85f137f..19bfd3a5e 100644 --- a/src/db/db/gsiDeclDbNetlist.cc +++ b/src/db/db/gsiDeclDbNetlist.cc @@ -1234,6 +1234,50 @@ static db::Pin *create_pin (db::Circuit *circuit, const std::string &name) return & circuit->add_pin (name); } +static std::vector +nets_by_name (db::Circuit *circuit, const std::string &name_pattern) +{ + std::vector res; + if (! circuit) { + return res; + } + + tl::GlobPattern glob (name_pattern); + if (circuit->netlist ()) { + glob.set_case_sensitive (circuit->netlist ()->is_case_sensitive ()); + } + for (db::Circuit::net_iterator n = circuit->begin_nets (); n != circuit->end_nets (); ++n) { + db::Net *net = n.operator-> (); + if (glob.match (net->name ())) { + res.push_back (net); + } + } + + return res; +} + +static std::vector +nets_by_name_const (const db::Circuit *circuit, const std::string &name_pattern) +{ + std::vector res; + if (! circuit) { + return res; + } + + tl::GlobPattern glob (name_pattern); + if (circuit->netlist ()) { + glob.set_case_sensitive (circuit->netlist ()->is_case_sensitive ()); + } + for (db::Circuit::const_net_iterator n = circuit->begin_nets (); n != circuit->end_nets (); ++n) { + const db::Net *net = n.operator-> (); + if (glob.match (net->name ())) { + res.push_back (net); + } + } + + return res; +} + Class decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit", gsi::method_ext ("create_pin", &create_pin, gsi::arg ("name"), "@brief Creates a new \\Pin object inside the circuit\n" @@ -1347,6 +1391,18 @@ Class decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit", "\n\n" "This constness variant has been introduced in version 0.26.8" ) + + gsi::method_ext ("nets_by_name", &nets_by_name, gsi::arg ("name_pattern"), + "@brief Gets the net objects for a given name filter.\n" + "The name filter is a glob pattern. This method will return all \\Net objects matching the glob pattern.\n" + "\n" + "This method has been introduced in version 0.27.3.\n" + ) + + gsi::method_ext ("nets_by_name", &nets_by_name_const, gsi::arg ("name_pattern"), + "@brief Gets the net objects for a given name filter (const version).\n" + "The name filter is a glob pattern. This method will return all \\Net objects matching the glob pattern.\n" + "\n\n" + "This constness variant has been introduced in version 0.27.3" + ) + gsi::method ("pin_by_id", (db::Pin *(db::Circuit::*) (size_t)) &db::Circuit::pin_by_id, gsi::arg ("id"), "@brief Gets the \\Pin object corresponding to a specific ID\n" "If the ID is not a valid pin ID, nil is returned." @@ -1637,8 +1693,13 @@ static std::vector circuits_by_name (db::Netlist *netlist, const std::string &name_pattern) { std::vector res; + if (! netlist) { + return res; + } tl::GlobPattern glob (name_pattern); + glob.set_case_sensitive (netlist->is_case_sensitive ()); + for (db::Netlist::circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) { db::Circuit *circuit = c.operator-> (); if (glob.match (circuit->name ())) { @@ -1653,8 +1714,13 @@ static std::vector circuits_by_name_const (const db::Netlist *netlist, const std::string &name_pattern) { std::vector res; + if (! netlist) { + return res; + } tl::GlobPattern glob (name_pattern); + glob.set_case_sensitive (netlist->is_case_sensitive ()); + for (db::Netlist::const_circuit_iterator c = netlist->begin_circuits (); c != netlist->end_circuits (); ++c) { const db::Circuit *circuit = c.operator-> (); if (glob.match (circuit->name ())) { @@ -1666,6 +1732,14 @@ circuits_by_name_const (const db::Netlist *netlist, const std::string &name_patt } Class decl_dbNetlist ("db", "Netlist", + gsi::method ("is_case_sensitive?", &db::Netlist::is_case_sensitive, + "@brief Returns a value indicating whether the netlist names are case sensitive\n" + "This method has been added in version 0.27.3.\n" + ) + + gsi::method ("case_sensitive=", &db::Netlist::set_case_sensitive, gsi::arg ("cs"), + "@brief Sets a value indicating whether the netlist names are case sensitive\n" + "This method has been added in version 0.27.3.\n" + ) + gsi::method_ext ("add", &gsi::add_circuit, gsi::arg ("circuit"), "@brief Adds the circuit to the netlist\n" "This method will add the given circuit object to the netlist. " @@ -1709,7 +1783,7 @@ Class decl_dbNetlist ("db", "Netlist", "This method will erase everything from inside the circuits matching the given pattern. It will only leave pins which are " "not connected to any net. Hence, this method forms 'abstract' or black-box circuits which can be instantiated through " "subcircuits like the former ones, but are empty shells.\n" - "The name pattern is a glob expression. For example, 'flatten_circuit(\"np*\")' will blank out all circuits with names " + "The name pattern is a glob expression. For example, 'blank_circuit(\"np*\")' will blank out all circuits with names " "starting with 'np'.\n" "\n" "For more details see \\Circuit#blank which is the corresponding method on the actual object." diff --git a/src/db/db/gsiDeclDbNetlistCompare.cc b/src/db/db/gsiDeclDbNetlistCompare.cc index 815790559..5a0696ee6 100644 --- a/src/db/db/gsiDeclDbNetlistCompare.cc +++ b/src/db/db/gsiDeclDbNetlistCompare.cc @@ -476,13 +476,32 @@ Class decl_dbNetlistComparer ("db", "NetlistComparer", "The logger is a delegate or event receiver which the comparer will send compare events to. " "See the class description for more details." ) + - gsi::method ("same_nets", &db::NetlistComparer::same_nets, gsi::arg ("net_a"), gsi::arg ("net_b"), + gsi::method ("same_nets", (void (db::NetlistComparer::*) (const db::Net *, const db::Net *, bool)) &db::NetlistComparer::same_nets, gsi::arg ("net_a"), gsi::arg ("net_b"), gsi::arg ("must_match", false), "@brief Marks two nets as identical.\n" "This makes a net net_a in netlist a identical to the corresponding\n" "net net_b in netlist b (see \\compare).\n" "Otherwise, the algorithm will try to identify nets according to their topology. " "This method can be used to supply hints to the compare algorithm. It will use " - "these hints to derive further identities." + "these hints to derive further identities.\n" + "\n" + "If 'must_match' is true, the nets are required to match. If they don't, an error is reported.\n" + "\n" + "The 'must_match' optional argument has been added in version 0.27.3.\n" + ) + + gsi::method ("same_nets", (void (db::NetlistComparer::*) (const db::Circuit *, const db::Circuit *, const db::Net *, const db::Net *, bool)) &db::NetlistComparer::same_nets, gsi::arg ("circuit_a"), gsi::arg ("circuit_b"), gsi::arg ("net_a"), gsi::arg ("net_b"), gsi::arg ("must_match", false), + "@brief Marks two nets as identical.\n" + "This makes a net net_a in netlist a identical to the corresponding\n" + "net net_b in netlist b (see \\compare).\n" + "Otherwise, the algorithm will try to identify nets according to their topology. " + "This method can be used to supply hints to the compare algorithm. It will use " + "these hints to derive further identities.\n" + "\n" + "If 'must_match' is true, the nets are required to match. If they don't, an error is reported.\n" + "\n" + "This variant allows specifying nil for the nets indicating the nets are mismatched by definition. " + "with 'must_match' this will render a net mismatch error.\n" + "\n" + "This variant has been added in version 0.27.3.\n" ) + gsi::method ("equivalent_pins", (void (db::NetlistComparer::*) (const db::Circuit *, size_t, size_t)) &db::NetlistComparer::equivalent_pins, gsi::arg ("circuit_b"), gsi::arg ("pin_id1"), gsi::arg ("pin_id2"), "@brief Marks two pins of the given circuit as equivalent (i.e. they can be swapped).\n" diff --git a/src/db/unit_tests/dbNetlistCompareTests.cc b/src/db/unit_tests/dbNetlistCompareTests.cc index 17f102883..12106ac5e 100644 --- a/src/db/unit_tests/dbNetlistCompareTests.cc +++ b/src/db/unit_tests/dbNetlistCompareTests.cc @@ -766,16 +766,18 @@ TEST(2_SimpleInverterWithForcedNetAssignment) bool good = comp.compare (&nl1, &nl2); EXPECT_EQ (logger.text (), - "begin_circuit INV INV\n" - "match_nets OUT OUT\n" - "match_nets IN IN\n" - "match_pins $0 $1\n" - "match_pins $1 $3\n" - "match_pins $2 $0\n" - "match_pins $3 $2\n" - "match_devices $2 $1\n" - "match_devices $1 $2\n" - "end_circuit INV INV MATCH" + "begin_circuit INV INV\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" + "match_nets OUT OUT\n" + "match_nets IN IN\n" + "match_pins $0 $1\n" + "match_pins $1 $3\n" + "match_pins $2 $0\n" + "match_pins $3 $2\n" + "match_devices $2 $1\n" + "match_devices $1 $2\n" + "end_circuit INV INV MATCH" ); EXPECT_EQ (good, true); } @@ -933,6 +935,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets INT $10\n" "net_mismatch IN IN\n" @@ -959,6 +963,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets IN IN\n" "match_ambiguous_nets INT $10\n" @@ -985,6 +991,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets INT $10\n" "net_mismatch IN IN\n" @@ -1011,6 +1019,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets INT $10\n" "net_mismatch IN IN\n" @@ -1037,6 +1047,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets IN IN\n" "match_ambiguous_nets INT $10\n" @@ -1064,6 +1076,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets IN IN\n" "match_ambiguous_nets INT $10\n" @@ -1091,6 +1105,8 @@ TEST(5_BufferTwoPathsDifferentParameters) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets OUT OUT\n" "match_nets INT $10\n" "net_mismatch IN IN\n" @@ -1156,6 +1172,8 @@ TEST(5_BufferTwoPathsDifferentDeviceClasses) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "match_nets INT $10\n" "match_nets IN IN\n" "net_mismatch INT2 $11\n" @@ -1222,6 +1240,8 @@ TEST(6_BufferTwoPathsAdditionalResistor) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "net_mismatch INT $10\n" "match_nets IN IN\n" "net_mismatch INT2 $11\n" @@ -1249,6 +1269,8 @@ TEST(6_BufferTwoPathsAdditionalResistor) EXPECT_EQ (logger.text (), "begin_circuit BUF BUF\n" + "match_nets VDD VDD\n" + "match_nets VSS VSS\n" "net_mismatch INT $10\n" "match_nets OUT OUT\n" "net_mismatch INT2 $11\n" @@ -2704,6 +2726,7 @@ TEST(17_InherentlyAmbiguousDecoder) "match_devices $4 $4\n" "end_circuit NAND NAND MATCH\n" "begin_circuit DECODER DECODER\n" + "match_nets A A\n" "match_nets VSS VSS\n" "match_nets VDD VDD\n" "match_nets B B\n" @@ -2755,6 +2778,7 @@ TEST(17_InherentlyAmbiguousDecoder) "match_devices $4 $4\n" "end_circuit NAND NAND MATCH\n" "begin_circuit DECODER DECODER\n" + "match_nets A A\n" "match_nets VSS VSS\n" "match_nets VDD VDD\n" "match_nets NA NA\n" @@ -3822,24 +3846,24 @@ TEST(21_BusLikeAmbiguousConnections) "match_pins VSS VSS\n" "end_circuit INV8 INV8 MATCH\n" "begin_circuit INV8_WRAP INV8_WRAP\n" - "match_ambiguous_nets VDD VDD\n" - "match_ambiguous_nets VSS VSS\n" - "match_ambiguous_nets IN1 A1\n" - "match_ambiguous_nets IN2 A2\n" - "match_ambiguous_nets IN3 A3\n" - "match_ambiguous_nets IN4 A4\n" - "match_ambiguous_nets IN5 A5\n" - "match_ambiguous_nets IN6 A6\n" - "match_ambiguous_nets IN7 A7\n" - "match_ambiguous_nets IN8 A8\n" - "match_ambiguous_nets OUT1 Q1\n" - "match_ambiguous_nets OUT2 Q2\n" - "match_ambiguous_nets OUT3 Q3\n" - "match_ambiguous_nets OUT4 Q4\n" - "match_ambiguous_nets OUT5 Q5\n" - "match_ambiguous_nets OUT6 Q6\n" - "match_ambiguous_nets OUT7 Q7\n" - "match_ambiguous_nets OUT8 Q8\n" + "match_nets VSS VSS\n" + "match_nets VDD VDD\n" + "match_nets OUT8 Q8\n" + "match_nets IN8 A8\n" + "match_nets OUT7 Q7\n" + "match_nets IN7 A7\n" + "match_nets OUT6 Q6\n" + "match_nets IN6 A6\n" + "match_nets OUT5 Q5\n" + "match_nets IN5 A5\n" + "match_nets OUT4 Q4\n" + "match_nets IN4 A4\n" + "match_nets OUT3 Q3\n" + "match_nets IN3 A3\n" + "match_nets OUT2 Q2\n" + "match_nets IN2 A2\n" + "match_nets OUT1 Q1\n" + "match_nets IN1 A1\n" "match_pins IN1 A1\n" "match_pins OUT1 Q1\n" "match_pins IN2 A2\n" diff --git a/src/drc/drc/built-in-macros/_drc_netter.rb b/src/drc/drc/built-in-macros/_drc_netter.rb index 978e6c723..1fa342e52 100644 --- a/src/drc/drc/built-in-macros/_drc_netter.rb +++ b/src/drc/drc/built-in-macros/_drc_netter.rb @@ -64,10 +64,8 @@ module DRC def initialize(engine) @engine = engine - @connect_implicit = [] - @connect_implicit_per_cell = {} - @connect_explicit = [] - @connect_explicit_per_cell = {} + @pre_extract_config = [] + @post_extract_config = [] @l2n = nil @lnum = 0 @device_scaling = 1.0 @@ -239,10 +237,8 @@ module DRC # See \connect for more details. def clear_connections - @connect_implicit = [] - @connect_implicit_per_cell = {} - @connect_explicit = [] - @connect_explicit_per_cell = {} + @pre_extract_config = [] + @post_extract_config = [] _clear_data end @@ -277,11 +273,10 @@ module DRC if arg2 (arg2.is_a?(String) && arg2 != "") || raise("The second argument has to be a non-empty string") arg1.is_a?(String) || raise("The first argument has to be a string") - @connect_implicit_per_cell[arg1] ||= [] - @connect_implicit_per_cell[arg1] << arg2 + @pre_extract_config << lambda { |l2n| l2n.join_net_names(arg1, arg2) } else arg1.is_a?(String) || raise("The argument has to be a string") - @connect_implicit << arg1 + @pre_extract_config << lambda { |l2n| l2n.join_net_names(arg1) } end end @@ -338,11 +333,10 @@ module DRC arg2.is_a?(Array) || raise("The second argument has to be an array of strings") arg2.find { |a| !a.is_a?(String) } && raise("The second argument has to be an array of strings") arg1.is_a?(String) || raise("The first argument has to be a string") - @connect_explicit_per_cell[arg1] ||= [] - @connect_explicit_per_cell[arg1] << arg2 + @pre_extract_config << lambda { |l2n| l2n.join_nets(arg1, arg2) } else arg1.is_a?(String) || raise("The argument has to be a string") - @connect_explicit << arg1 + @pre_extract_config << lambda { |l2n| l2n.join_nets(arg1) } end end @@ -563,30 +557,21 @@ module DRC # run extraction in a timed environment if ! @l2n.is_extracted? - # configure implicit net connections @l2n.clear_join_net_names - @connect_implicit.each do |label_pattern| - @l2n.join_net_names(label_pattern) - end - @connect_implicit_per_cell.each do |cell_pattern,label_pattern| - label_pattern.each do |lp| - @l2n.join_net_names(cell_pattern, lp) - end - end - - # configure explicit net connections @l2n.clear_join_nets - @connect_explicit.each do |names| - @l2n.join_nets(names) - end - @connect_explicit_per_cell.each do |cell_pattern,name_lists| - name_lists.each do |names| - @l2n.join_nets(cell_pattern, names) - end + + # configure the netter + @pre_extract_config.each do |cfg| + cfg.call(@l2n) end @engine._cmd(@l2n, :extract_netlist) + # configure the netter, post-extraction + @post_extract_config.each do |cfg| + cfg.call(@l2n) + end + end @l2n diff --git a/src/lay/lay/doc/about/lvs_ref_global.xml b/src/lay/lay/doc/about/lvs_ref_global.xml index f854e06e6..ab05ff346 100644 --- a/src/lay/lay/doc/about/lvs_ref_global.xml +++ b/src/lay/lay/doc/about/lvs_ref_global.xml @@ -28,6 +28,15 @@ For more details about the DRC functions see See Netter#align for a description of that function.

+

"blank_circuit" - Removes the content from the given circuits (blackboxing)

+ +

Usage:

+
    +
  • blank_circuit(circuit_filter)
  • +
+

+See Netter#blank_circuit for a description of that function. +

"compare" - Compares the extracted netlist vs. the schematic

Usage:

@@ -152,12 +161,24 @@ See
Netter#same_device_c

Usage:

    -
  • same_nets(circuit, net_a, net_b)
  • +
  • same_nets(circuit_pattern, net_pattern)
  • +
  • same_nets(circuit_pattern, net_a, net_b)
  • same_nets(circuit_a, net_a, circuit_b, net_b)

See Netter#same_nets for a description of that function.

+

"same_nets!" - Establishes an equivalence between the nets (must match)

+ +

Usage:

+
    +
  • same_nets!(circuit_pattern, net_pattern)
  • +
  • same_nets!(circuit_pattern, net_a, net_b)
  • +
  • same_nets!(circuit_a, net_a, circuit_b, net_b)
  • +
+

+See Netter#same_nets! for a description of that function. +

"schematic" - Reads the reference netlist

Usage:

diff --git a/src/lay/lay/doc/about/lvs_ref_netter.xml b/src/lay/lay/doc/about/lvs_ref_netter.xml index 04244ff71..4b33f3fe5 100644 --- a/src/lay/lay/doc/about/lvs_ref_netter.xml +++ b/src/lay/lay/doc/about/lvs_ref_netter.xml @@ -68,6 +68,36 @@ are other (explicit) ways to flatten circuits. Please note that flattening circuits has some side effects such as loss of details in the cross reference and net layout.

+

"blank_circuit" - Removes the content from the given circuits (blackboxing)

+ +

Usage:

+
    +
  • blank_circuit(circuit_filter)
  • +
+

+This method will erase all content from the circuits matching the filter. +The filter is a glob expression. +

+This has the following effects: +

+

    +
  • The circuits are no longer compared (netlist vs. schematic)
  • +
  • Named pins are required to match (use labels on the nets to name pins in the layout)
  • +
  • Unnamed pins are treated as equivalent and can be swapped
  • +
  • The selected circuits will not be purged on netlist simplification
  • +
+

+Using this method can be useful to reduce the verification overhead for +blocks which are already verifified by other ways or for which no schematic +is available - e.g. hard macros. +

+Example: +

+

+# skips all MEMORY* circuits from compare
+blank_circuit("MEMORY*")
+
+

"compare" - Compares the extracted netlist vs. the schematic

Usage:

@@ -289,7 +319,8 @@ Use this method andwhere in the script before the
compare

Usage:

    -
  • same_nets(circuit, net_a, net_b)
  • +
  • same_nets(circuit_pattern, net_pattern)
  • +
  • same_nets(circuit_pattern, net_a, net_b)
  • same_nets(circuit_a, net_a, circuit_b, net_b)

@@ -297,8 +328,17 @@ This method will force an equivalence between the net_a and net_b from circuit_a and circuit_b (circuit in the three-argument form is for both circuit_a and circuit_b).

In the four-argument form, the circuits can be either given by name or as Circuit -objects. In the three-argument form, the circuit has to be given by name. +objects. In the three-argument form, the circuits have to be given by name pattern. Nets can be either given by name or as Net objects. +In the two-argument form, the circuits and nets have to be given as name pattern. +

+"name pattern" are glob-style pattern - e.g. the following will identify the +all nets starting with "A" from the extracted netlist with the same net from +the schematic netlist for all circuits starting with "INV": +

+

+same_nets("INV*", "A*")
+

After using this function, the compare algorithm will consider these nets equivalent. Use this method to provide hints for the comparer in cases which are difficult to @@ -309,6 +349,18 @@ Names are case sensitive for layout-derived netlists and case-insensitive for SP

Use this method andwhere in the script before the compare call.

+

"same_nets!" - Establishes an equivalence between the nets with matching requirement

+ +

Usage:

+
    +
  • same_nets!(circuit_pattern, net_pattern)
  • +
  • same_nets!(circuit_pattern, net_a, net_b)
  • +
  • same_nets!(circuit_a, net_a, circuit_b, net_b)
  • +
+

+This method is equivalent to same_nets, but requires identity of the given nets. +If the specified nets do not match, an error is reported. +

"schematic" - Gets, sets or reads the reference netlist

Usage:

diff --git a/src/lay/lay/doc/manual/lvs_compare.xml b/src/lay/lay/doc/manual/lvs_compare.xml index d5de64f78..5b3fe3073 100644 --- a/src/lay/lay/doc/manual/lvs_compare.xml +++ b/src/lay/lay/doc/manual/lvs_compare.xml @@ -52,7 +52,44 @@

- For more information about "same_nets" see same_nets. + "same_nets" can also be used to require a matching between specific nets. + This is useful on top level to check for matching nets assigned to specific pads. + This allows checking correct pad assignment. For example to check whether the + same net is attached to the "VDD" pad, label the net "VDD" in the layout and + specify: +

+ +
same_nets!("CHIP", "VDD", "VDD")
+ +

+ The exclamation-mark version will report a net mismatch if either there is no + "VDD" net in either layout or schematic or if these nets to not match. + The above specification can be abbreviated as layout and schematic net name are identical: +

+ +
same_nets!("CHIP", "VDD")
+ +

+ It's also possible to specify pattern for circuit names or net names. + This example requires all nets starting with "PAD" to have a counterpart + in layout and schematic for circuit "TOP" and each of these pairs has to match: +

+ +
same_nets!("TOP", "PAD*")
+ +

+ So it is an error if there is a PAD1 net in layout but none in the schematic. + It is also an error if a net called PAD2 is there is layout and schematic but they + do not match. +

+ +

+ "same_nets" and "same_nets!" can appear anywhere in the LVS script. +

+ +

+ For more information about "same_nets" see same_nets and + same_nets!.

Circuit equivalence hint

diff --git a/src/lay/lay/doc/manual/lvs_tweaks.xml b/src/lay/lay/doc/manual/lvs_tweaks.xml index 12e4b0bf5..6a8d505f9 100644 --- a/src/lay/lay/doc/manual/lvs_tweaks.xml +++ b/src/lay/lay/doc/manual/lvs_tweaks.xml @@ -153,10 +153,11 @@

A useful method in this context is the "blank_circuit" method. It clears - a circuit's innards and leaves only the pins. You can use this method to - ensure abstracts in both the layout netlist and the schematic. After this, + a circuit's innards from a netlist. After this, the compare algorithm will identify both circuits as identical, provided - they feature the same number of pins. + they feature the same number of pins. Named pins are required to match exactly + unless declared equivalent. Unnamed pins are treated as equivalent. To name + pins use labels on the pin's nets inside the circuit's layout.

@@ -166,14 +167,20 @@

netlist.blank_circuit("CIRCUIT_NAME")
 schematic.blank_circuit("CIRCUIT_NAME")
+

NOTE: In this version, use "blank_circuit" before "purge" or "simplify" (see below). "blank_circuit" + sets a flag () which prevents purging of abstract circuits.

+

- The argument to "blank_circuit" is a glob pattern (shell-like). - For example, "MEMORY*" will blank out all circuits starting with "MEMORY". + There is a short form for this too (blank_circuit). + In contrast to netlist-based "blank_circuit", this method can be used anywhere in the LVS script:

-

NOTE: Use "blank_circuit" before "purge" or "simplify" (see below). This method - sets a flag () which prevents purging of abstract - circuits.

+
blank_circuit("CIRCUIT_NAME")
+ +

+ The argument to "blank_circuit" in both cases is a glob pattern (shell-like). + For example, "MEMORY*" will blank out all circuits starting with the word "MEMORY". +

Joining of symmetric nodes

@@ -201,8 +208,8 @@ schematic.blank_circuit("CIRCUIT_NAME")

- KLayout provides a feature which will add such connections after extraction - of the netlist: + KLayout provides a feature (join_symmetric_nets) + which will add such connections after extraction of the netlist:

join_symmetric_nets("NAND2")
@@ -221,6 +228,10 @@ schematic.blank_circuit("CIRCUIT_NAME") need it.

+

+ "join_symmetric_nets" can be used anywhere in the LVS script. +

+

Purging (elimination of redundancy)

diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.cc b/src/laybasic/laybasic/layNetlistBrowserModel.cc index b160ac73a..5def404a6 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.cc +++ b/src/laybasic/laybasic/layNetlistBrowserModel.cc @@ -233,11 +233,11 @@ static QString escaped (const std::string &s) } template -static std::string str_from_expanded_name (const Obj *obj, bool dash_for_empty = false) +static std::string str_from_expanded_name (const Obj *obj, bool indicate_empty = false) { if (obj) { return obj->expanded_name (); - } else if (dash_for_empty) { + } else if (indicate_empty) { return std::string ("-"); } else { return std::string (); @@ -245,11 +245,11 @@ static std::string str_from_expanded_name (const Obj *obj, bool dash_for_empty = } template -static std::string str_from_name (const Obj *obj, bool dash_for_empty = false) +static std::string str_from_name (const Obj *obj, bool indicate_empty = false) { if (obj) { return obj->name (); - } else if (dash_for_empty) { + } else if (indicate_empty) { return std::string ("-"); } else { return std::string (); @@ -264,7 +264,7 @@ static std::string str_from_expanded_names (const std::pair &ob std::string s = str_from_name (objs.first, ! is_single); if (! is_single) { std::string t = str_from_name (objs.second, ! is_single); - if (t != s) { + if (t != s || ! objs.first || ! objs.second) { s += var_sep; s += t; } diff --git a/src/lvs/lvs/built-in-macros/_lvs_engine.rb b/src/lvs/lvs/built-in-macros/_lvs_engine.rb index f53bfcc72..3a0506516 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_engine.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_engine.rb @@ -100,6 +100,12 @@ module LVS # @synopsis join_symmetric_nets(circuit_filter) # See \Netter#join_symmetric_nets for a description of that function. + # %LVS% + # @name blank_circuit + # @brief Removes the content from the given circuits (blackboxing) + # @synopsis blank_circuit(circuit_filter) + # See \Netter#blank_circuit for a description of that function. + # %LVS% # @name align # @brief Aligns the extracted netlist vs. the schematic by flattening circuits where required @@ -109,10 +115,19 @@ module LVS # %LVS% # @name same_nets # @brief Establishes an equivalence between the nets - # @synopsis same_nets(circuit, net_a, net_b) + # @synopsis same_nets(circuit_pattern, net_pattern) + # @synopsis same_nets(circuit_pattern, net_a, net_b) # @synopsis same_nets(circuit_a, net_a, circuit_b, net_b) # See \Netter#same_nets for a description of that function. + # %LVS% + # @name same_nets! + # @brief Establishes an equivalence between the nets (must match) + # @synopsis same_nets!(circuit_pattern, net_pattern) + # @synopsis same_nets!(circuit_pattern, net_a, net_b) + # @synopsis same_nets!(circuit_a, net_a, circuit_b, net_b) + # See \Netter#same_nets! for a description of that function. + # %LVS% # @name same_circuits # @brief Establishes an equivalence between the circuits @@ -168,7 +183,7 @@ module LVS # @synopsis tolerance(device_class_name, parameter_name [, :absolute => absolute_tolerance] [, :relative => relative_tolerance]) # See \Netter#tolerance for a description of that function. - %w(schematic compare join_symmetric_nets tolerance align same_nets same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity consider_net_names).each do |f| + %w(schematic compare join_symmetric_nets tolerance blank_circuit align same_nets same_nets! same_circuits same_device_classes equivalent_pins min_caps max_res max_depth max_branch_complexity consider_net_names).each do |f| eval <<"CODE" def #{f}(*args) _netter.#{f}(*args) diff --git a/src/lvs/lvs/built-in-macros/_lvs_netter.rb b/src/lvs/lvs/built-in-macros/_lvs_netter.rb index ca20ae82f..5c34685a3 100644 --- a/src/lvs/lvs/built-in-macros/_lvs_netter.rb +++ b/src/lvs/lvs/built-in-macros/_lvs_netter.rb @@ -49,6 +49,7 @@ module LVS def initialize(engine) super @comparer_config = [] + @comparer_miniconfig = [] end def _make_data @@ -140,7 +141,18 @@ module LVS abs_tol ||= 0.0 rel_tol ||= 0.0 - dc = netlist.device_class_by_name(device_class_name) + if self._l2n_data + # already extracted + self._tolerance(self._l2n_data, device_class_name, parameter_name, abs_tol, rel_tol) + else + @post_extract_config << lambda { |l2n| self._tolerance(l2n, device_class_name, parameter_name, abs_tol, rel_tol) } + end + + end + + def _tolerance(l2n, device_class_name, parameter_name, abs_tol, rel_tol) + + dc = l2n.netlist.device_class_by_name(device_class_name) if dc && dc.has_parameter?(parameter_name) ep = RBA::EqualDeviceParameters::new(dc.parameter_id(parameter_name), abs_tol, rel_tol) if dc.equal_parameters == nil @@ -250,13 +262,74 @@ module LVS circuit_pattern.is_a?(String) || raise("Circuit pattern argument of 'join_symmetric_nets' must be a string") - comparer = self._comparer + if self._l2n_data + # already extracted + self._join_symmetric_nets(self._l2n_data, circuit_pattern) + else + @post_extract_config << lambda { |l2n| self._join_symmetric_nets(l2n, circuit_pattern) } + end - netlist || raise("No netlist present (not extracted?)") - netlist.circuits_by_name(circuit_pattern).each do |c| + end + + def _join_symmetric_nets(l2n, circuit_pattern) + + comparer = self._comparer_mini + + l2n.netlist.circuits_by_name(circuit_pattern).each do |c| comparer.join_symmetric_nets(c) end + comparer._destroy + + end + + # %LVS% + # @name blank_circuit + # @brief Removes the content from the given circuits (blackboxing) + # @synopsis blank_circuit(circuit_filter) + # This method will erase all content from the circuits matching the filter. + # The filter is a glob expression. + # + # This has the following effects: + # + # @ul + # @li The circuits are no longer compared (netlist vs. schematic) @/li + # @li Named pins are required to match (use labels on the nets to name pins in the layout) @/li + # @li Unnamed pins are treated as equivalent and can be swapped @/li + # @li The selected circuits will not be purged on netlist simplification @/li + # @/ul + # + # Using this method can be useful to reduce the verification overhead for + # blocks which are already verifified by other ways or for which no schematic + # is available - e.g. hard macros. + # + # Example: + # + # @code + # # skips all MEMORY* circuits from compare + # blank_circuit("MEMORY*") + # @/code + + def blank_circuit(circuit_pattern) + + circuit_pattern.is_a?(String) || raise("Circuit pattern argument of 'blank_circuit' must be a string") + + if self._l2n_data + # already extracted + self._blank_circuit(self._l2n_data, circuit_pattern) + else + @post_extract_config << lambda { |l2n| self._blank_circuit(l2n, circuit_pattern) } + end + + end + + def _blank_circuit(l2n, circuit_pattern) + + (n, s) = _ensure_two_netlists + + n.blank_circuit(circuit_pattern) + s.blank_circuit(circuit_pattern) + end def _comparer @@ -272,6 +345,19 @@ module LVS end + def _comparer_mini + + comparer = RBA::NetlistComparer::new + + # execute the configuration commands + @comparer_miniconfig.each do |cc| + cc.call(comparer) + end + + return comparer + + end + def _ensure_two_netlists netlist || raise("No netlist present (not extracted?)") @@ -284,14 +370,24 @@ module LVS # %LVS% # @name same_nets # @brief Establishes an equivalence between the nets - # @synopsis same_nets(circuit, net_a, net_b) + # @synopsis same_nets(circuit_pattern, net_pattern) + # @synopsis same_nets(circuit_pattern, net_a, net_b) # @synopsis same_nets(circuit_a, net_a, circuit_b, net_b) # This method will force an equivalence between the net_a and net_b from circuit_a # and circuit_b (circuit in the three-argument form is for both circuit_a and circuit_b). - # + # # In the four-argument form, the circuits can be either given by name or as Circuit - # objects. In the three-argument form, the circuit has to be given by name. + # objects. In the three-argument form, the circuits have to be given by name pattern. # Nets can be either given by name or as Net objects. + # In the two-argument form, the circuits and nets have to be given as name pattern. + # + # "name pattern" are glob-style pattern - e.g. the following will identify the + # all nets starting with "A" from the extracted netlist with the same net from + # the schematic netlist for all circuits starting with "INV": + # + # @code + # same_nets("INV*", "A*") + # @/code # # After using this function, the compare algorithm will consider these nets equivalent. # Use this method to provide hints for the comparer in cases which are difficult to @@ -303,65 +399,127 @@ module LVS # Use this method andwhere in the script before the \compare call. def same_nets(*args) + _same_nets_impl(false, *args) + end - if args.size < 3 - raise("Too few arguments to 'same_nets' (need at least 3)") + # %LVS% + # @name same_nets! + # @brief Establishes an equivalence between the nets with matching requirement + # @synopsis same_nets!(circuit_pattern, net_pattern) + # @synopsis same_nets!(circuit_pattern, net_a, net_b) + # @synopsis same_nets!(circuit_a, net_a, circuit_b, net_b) + # This method is equivalent to \same_nets, but requires identity of the given nets. + # If the specified nets do not match, an error is reported. + + def same_nets!(*args) + _same_nets_impl(true, *args) + end + + def _same_nets_impl(force, *args) + + if args.size < 2 + raise("Too few arguments to 'same_nets' (need at least 2)") end if args.size > 4 raise("Too many arguments to 'same_nets' (need max 4)") end if args.size == 3 - ( ca, a, b ) = args - cb = ca + ( ca, a ) = args + cb = nil ca.is_a?(String) || raise("Circuit argument of 'same_nets' must be a string") + b = nil + a.is_a?(String) || raise("Net argument of 'same_nets' must be a string") + elsif args.size == 3 + ( ca, a, b ) = args + cb = nil + ca.is_a?(String) || raise("Circuit argument of 'same_nets' must be a string") + [ a, b ].each do |n| + n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") + end else ( ca, a, cb, b ) = args [ ca, cb ].each do |n| - n.is_a?(String) || n.is_a?(RBA::Net) || raise("Circuit arguments of 'same_nets' must be strings or Net objects") + n.is_a?(String) || n.is_a?(RBA::Circuit) || raise("Circuit arguments of 'same_nets' must be strings or Circuit objects") + end + [ a, b ].each do |n| + n.is_a?(String) || n.is_a?(RBA::Net) || raise("Net arguments of 'same_nets' must be strings or Net objects") end end - [ a, b ].each do |n| - 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 { |comparer| self._same_nets(comparer, ca, a, cb, b) } + @comparer_config << lambda { |comparer| self._same_nets(comparer, ca, a, cb, b, force) } end - def _same_nets(comparer, ca, a, cb, b) + def _same_nets(comparer, ca, a, cb, b, force) ( nl_a, nl_b ) = _ensure_two_netlists - if ca.is_a?(String) - circuit_a = nl_a.circuit_by_name(ca) + cs = !(nl_a.is_case_sensitive? && nl_b.is_case_sensitive?) + + if ca.is_a?(String) && !cb + + n2c = {} + nl_a.circuits_by_name(ca).each { |c| name = cs ? c.name.upcase : c.name; n2c[name] ||= [ nil, nil ]; n2c[name][0] = c } + nl_b.circuits_by_name(ca).each { |c| name = cs ? c.name.upcase : c.name; n2c[name] ||= [ nil, nil ]; n2c[name][1] = c } + + circuits = [] + n2c.keys.sort.each do |n| + if n2c[n][0] && n2c[n][1] + circuits << n2c[n] + end + end + else - circuit_a = ca - end - if cb.is_a?(String) - circuit_b = nl_b.circuit_by_name(cb) - else - circuit_b = cb - end + circuit_a = ca.is_a?(String) ? nl_a.circuit_by_name(ca) : ca + circuit_b = cb.is_a?(String) ? nl_b.circuit_by_name(cb) : cb - 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 in 'same_nets': #{a} (for circuit #{circuit_a})") - else - net_a = a + circuits = [] + if circuit_a && circuit_b + circuits << [ circuit_a, circuit_b ] end - if b.is_a?(String) - 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})") + end + + circuits.each do |circuit_a, circuit_b| + + if a.is_a?(String) && !b + + n2n = {} + circuit_a.nets_by_name(a).each { |n| name = cs ? n.name.upcase : n.name; n2n[name] ||= [ nil, nil ]; n2n[name][0] = n } + circuit_b.nets_by_name(a).each { |n| name = cs ? n.name.upcase : n.name; n2n[name] ||= [ nil, nil ]; n2n[name][1] = n } + + nets = [] + n2n.keys.sort.each do |n| + if force || (n2n[n][0] && n2n[n][1]) + nets << n2n[n] + end + end + else - net_b = b + + if a.is_a?(String) + 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 in 'same_nets': #{b} (for circuit #{circuit_b})") + else + net_b = b + end + + nets = [] + if net_a && net_b + nets << [ net_a, net_b ] + end + end - if net_a && net_b - comparer.same_nets(net_a, net_b) + nets.each do |net_a, net_b| + comparer.same_nets(circuit_a, circuit_b, net_a, net_b, force) end end @@ -589,6 +747,7 @@ module LVS def min_caps(value) v = value.to_f @comparer_config << lambda { |comparer| comparer.min_capacitance = v } + @comparer_miniconfig << lambda { |comparer| comparer.min_capacitance = v } end # %LVS% @@ -601,6 +760,7 @@ module LVS def max_res(value) v = value.to_f @comparer_config << lambda { |comparer| comparer.max_resistance = v } + @comparer_miniconfig << lambda { |comparer| comparer.max_resistance = v } end # %LVS% diff --git a/src/lvs/unit_tests/lvsSimpleTests.cc b/src/lvs/unit_tests/lvsSimpleTests.cc index 6d054e461..d6fdec334 100644 --- a/src/lvs/unit_tests/lvsSimpleTests.cc +++ b/src/lvs/unit_tests/lvsSimpleTests.cc @@ -86,6 +86,11 @@ TEST(1b_simple_with_tolerance) run_test (_this, "ringo_simple_with_tol", "ringo.gds"); } +TEST(1c_simple_with_tolerance_early) +{ + run_test (_this, "ringo_simple_with_tol_early", "ringo.gds"); +} + TEST(2_simple_io) { run_test (_this, "ringo_simple_io", "ringo.gds"); @@ -130,6 +135,11 @@ TEST(9_blackboxing) run_test (_this, "ringo_simple_blackboxing", "ringo_for_blackboxing.gds"); } +TEST(9b_blackboxing_netter) +{ + run_test (_this, "ringo_simple_blackboxing_netter", "ringo_for_blackboxing.gds"); +} + TEST(10_simplification_with_align) { run_test (_this, "ringo_simple_simplification_with_align", "ringo_for_simplification.gds"); @@ -200,6 +210,11 @@ TEST(22_split_gate) run_test (_this, "nand2_split_gate", "nand2_split_gate.oas"); } +TEST(22b_split_gate_early) +{ + run_test (_this, "nand2_split_gate_early", "nand2_split_gate.oas"); +} + // empty gds TEST(23_issue709) { @@ -211,3 +226,12 @@ TEST(24_issue806) { run_test (_this, "custom_compare", "custom_compare.gds"); } + +TEST(25_blackbox) +{ + run_test (_this, "blackbox1", "blackbox.gds"); + run_test (_this, "blackbox2", "blackbox_swapped.gds"); + run_test (_this, "blackbox3", "blackbox_open.gds"); + run_test (_this, "blackbox4", "blackbox_short.gds"); + run_test (_this, "blackbox5", "blackbox_short_and_open.gds"); +} diff --git a/testdata/drc/drcSimpleTests_au9a.cir b/testdata/drc/drcSimpleTests_au9a.cir index 8d0e86af5..b106c0428 100644 --- a/testdata/drc/drcSimpleTests_au9a.cir +++ b/testdata/drc/drcSimpleTests_au9a.cir @@ -119,9 +119,9 @@ M$2 3 5 2 7 LVNMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U * cell TIE * pin VDD * pin BULK,VSS -.SUBCKT TIE 2 3 -* net 2 VDD -* net 3 BULK,VSS +.SUBCKT TIE 1 2 +* net 1 VDD +* net 2 BULK,VSS .ENDS TIE * cell EMPTY diff --git a/testdata/lvs/blackbox.gds b/testdata/lvs/blackbox.gds new file mode 100644 index 000000000..27ad3ab86 Binary files /dev/null and b/testdata/lvs/blackbox.gds differ diff --git a/testdata/lvs/blackbox1.cir b/testdata/lvs/blackbox1.cir new file mode 100644 index 000000000..f8fb8eeb8 --- /dev/null +++ b/testdata/lvs/blackbox1.cir @@ -0,0 +1,27 @@ +* Extracted by KLayout + +* cell TOP +.SUBCKT TOP +* net 1 3 +* net 2 4 +* net 3 2 +* net 4 1 +* net 5 8 +* net 6 7 +* net 7 5 +* net 8 6 +* cell instance $1 r0 *1 0,0 +X$1 1 2 7 3 4 5 8 6 CHIP +.ENDS TOP + +* cell CHIP +* pin pad3 +* pin pad4 +* pin pad5 +* pin pad2 +* pin pad1 +* pin pad8 +* pin pad6 +* pin pad7 +.SUBCKT CHIP 1 2 3 4 5 6 7 8 +.ENDS CHIP diff --git a/testdata/lvs/blackbox1.lvs b/testdata/lvs/blackbox1.lvs new file mode 100644 index 000000000..9b20bc4d6 --- /dev/null +++ b/testdata/lvs/blackbox1.lvs @@ -0,0 +1,22 @@ +source($lvs_test_source) +report_lvs($lvs_test_target_lvsdb, true) +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("blackbox_schematic.cir") + +deep + +same_nets!("TOP", "*", "*") + +m1 = input(1, 0) +via = input(2, 0) +m2 = input(3, 0) +pad = input(10, 0) + +connect(m1, pad) +connect(m1, via) +connect(via, m2) + +blank_circuit("CHIP") + +compare diff --git a/testdata/lvs/blackbox1.lvsdb b/testdata/lvs/blackbox1.lvsdb new file mode 100644 index 000000000..a9012c999 --- /dev/null +++ b/testdata/lvs/blackbox1.lvsdb @@ -0,0 +1,196 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l1 '1/0') + layer(l3 '2/0') + layer(l4 '3/0') + layer(l2 '10/0') + + # Mask layer connectivity + connect(l1 l1 l3 l2) + connect(l3 l1 l3 l4) + connect(l4 l3 l4) + connect(l2 l1 l2) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Circuit boundary + rect((-4000 -6000) (11000 9000)) + + # Outgoing pins and their connections to nets + pin(name(pad3)) + pin(name(pad4)) + pin(name(pad5)) + pin(name(pad2)) + pin(name(pad1)) + pin(name(pad8)) + pin(name(pad6)) + pin(name(pad7)) + + ) + circuit(TOP + + # Circuit boundary + rect((-18500 -14000) (44500 28000)) + + # Nets with their geometries + net(1 name('3') + rect(l1 (-10500 2000) (7500 1000)) + rect(l1 (-7500 0) (1000 4000)) + rect(l1 (-6000 0) (6000 1000)) + rect(l1 (-9000 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -5501) (1000 1000)) + ) + net(2 name('4') + rect(l1 (1000 2000) (1000 10000)) + rect(l1 (-17500 0) (17500 1000)) + rect(l1 (-20500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (17499 -10501) (1000 1000)) + ) + net(3 name('2') + rect(l1 (-15500 -2000) (12500 1000)) + rect(l1 (-15500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -501) (1000 1000)) + ) + net(4 name('1') + rect(l1 (-15500 -13000) (6000 1000)) + rect(l1 (-1000 0) (1000 6000)) + rect(l1 (-9000 -8000) (3500 3000)) + rect(l1 (4500 5000) (7500 1000)) + rect(l1 (-13501 -7501) (2 2)) + rect(l2 (12499 6499) (1000 1000)) + ) + net(5 name('8') + rect(l1 (1000 -13000) (22000 1000)) + rect(l1 (-22000 0) (1000 7000)) + rect(l1 (20500 -9000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-23501 6499) (1000 1000)) + ) + net(6 name('7') + rect(l1 (6000 -6000) (7000 1000)) + rect(l1 (-1000 0) (1000 12000)) + rect(l1 (-1000 0) (11000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-18501 -13501) (1000 1000)) + ) + net(7 name('5') + rect(l1 (6000 2000) (1000 10000)) + rect(l1 (-1000 0) (17000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-18501 -10501) (1000 1000)) + ) + net(8 name('6') + rect(l1 (16000 -2000) (7000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-18501 -501) (3500 1000)) + rect(l3 (6500 -1000) (1000 1000)) + rect(l3 (-8500 -1000) (1000 1000)) + rect(l4 (-1000 -1000) (8500 1000)) + rect(l2 (-11000 -1000) (1000 1000)) + ) + + # Subcircuits and their connections + circuit(1 CHIP location(0 0) + pin(0 1) + pin(1 2) + pin(2 7) + pin(3 3) + pin(4 4) + pin(5 5) + pin(6 8) + pin(7 6) + ) + + ) +) + +# Reference netlist +reference( + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Outgoing pins and their connections to nets + pin(name(PAD1)) + pin(name(PAD2)) + pin(name(PAD3)) + pin(name(PAD4)) + pin(name(PAD5)) + pin(name(PAD6)) + pin(name(PAD7)) + pin(name(PAD8)) + + ) + circuit(TOP + + # 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')) + net(7 name('7')) + net(8 name('8')) + + # Subcircuits and their connections + circuit(1 CHIP name('1') + pin(0 1) + pin(1 2) + pin(2 3) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 7) + pin(7 8) + ) + + ) +) + +# Cross reference +xref( + circuit(CHIP CHIP match + xref( + pin(4 0 match) + pin(3 1 match) + pin(0 2 match) + pin(1 3 match) + pin(2 4 match) + pin(6 5 match) + pin(7 6 match) + pin(5 7 match) + ) + ) + circuit(TOP TOP match + xref( + net(4 1 match) + net(3 2 match) + net(1 3 match) + net(2 4 match) + net(7 5 match) + net(8 6 match) + net(6 7 match) + net(5 8 match) + circuit(1 1 match) + ) + ) +) diff --git a/testdata/lvs/blackbox2.cir b/testdata/lvs/blackbox2.cir new file mode 100644 index 000000000..6b3a67d15 --- /dev/null +++ b/testdata/lvs/blackbox2.cir @@ -0,0 +1,27 @@ +* Extracted by KLayout + +* cell TOP +.SUBCKT TOP +* net 1 4 +* net 2 3 +* net 3 2 +* net 4 1 +* net 5 8 +* net 6 7 +* net 7 5 +* net 8 6 +* cell instance $1 r0 *1 0,0 +X$1 1 2 7 3 4 5 8 6 CHIP +.ENDS TOP + +* cell CHIP +* pin pad3 +* pin pad4 +* pin pad5 +* pin pad2 +* pin pad1 +* pin pad8 +* pin pad6 +* pin pad7 +.SUBCKT CHIP 1 2 3 4 5 6 7 8 +.ENDS CHIP diff --git a/testdata/lvs/blackbox2.lvs b/testdata/lvs/blackbox2.lvs new file mode 100644 index 000000000..9b20bc4d6 --- /dev/null +++ b/testdata/lvs/blackbox2.lvs @@ -0,0 +1,22 @@ +source($lvs_test_source) +report_lvs($lvs_test_target_lvsdb, true) +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("blackbox_schematic.cir") + +deep + +same_nets!("TOP", "*", "*") + +m1 = input(1, 0) +via = input(2, 0) +m2 = input(3, 0) +pad = input(10, 0) + +connect(m1, pad) +connect(m1, via) +connect(via, m2) + +blank_circuit("CHIP") + +compare diff --git a/testdata/lvs/blackbox2.lvsdb b/testdata/lvs/blackbox2.lvsdb new file mode 100644 index 000000000..4fa169913 --- /dev/null +++ b/testdata/lvs/blackbox2.lvsdb @@ -0,0 +1,196 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l1 '1/0') + layer(l3 '2/0') + layer(l4 '3/0') + layer(l2 '10/0') + + # Mask layer connectivity + connect(l1 l1 l3 l2) + connect(l3 l1 l3 l4) + connect(l4 l3 l4) + connect(l2 l1 l2) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Circuit boundary + rect((-4000 -6000) (11000 9000)) + + # Outgoing pins and their connections to nets + pin(name(pad3)) + pin(name(pad4)) + pin(name(pad5)) + pin(name(pad2)) + pin(name(pad1)) + pin(name(pad8)) + pin(name(pad6)) + pin(name(pad7)) + + ) + circuit(TOP + + # Circuit boundary + rect((-18500 -14000) (44500 28000)) + + # Nets with their geometries + net(1 name('4') + rect(l1 (-10500 2000) (7500 1000)) + rect(l1 (-7500 0) (1000 4000)) + rect(l1 (-6000 0) (6000 1000)) + rect(l1 (-9000 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -5501) (1000 1000)) + ) + net(2 name('3') + rect(l1 (1000 2000) (1000 10000)) + rect(l1 (-17500 0) (17500 1000)) + rect(l1 (-20500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (17499 -10501) (1000 1000)) + ) + net(3 name('2') + rect(l1 (-15500 -2000) (12500 1000)) + rect(l1 (-15500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -501) (1000 1000)) + ) + net(4 name('1') + rect(l1 (-15500 -13000) (6000 1000)) + rect(l1 (-1000 0) (1000 6000)) + rect(l1 (-9000 -8000) (3500 3000)) + rect(l1 (4500 5000) (7500 1000)) + rect(l1 (-13501 -7501) (2 2)) + rect(l2 (12499 6499) (1000 1000)) + ) + net(5 name('8') + rect(l1 (1000 -13000) (22000 1000)) + rect(l1 (-22000 0) (1000 7000)) + rect(l1 (20500 -9000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-23501 6499) (1000 1000)) + ) + net(6 name('7') + rect(l1 (6000 -6000) (7000 1000)) + rect(l1 (-1000 0) (1000 12000)) + rect(l1 (-1000 0) (11000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-18501 -13501) (1000 1000)) + ) + net(7 name('5') + rect(l1 (6000 2000) (1000 10000)) + rect(l1 (-1000 0) (17000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-18501 -10501) (1000 1000)) + ) + net(8 name('6') + rect(l1 (16000 -2000) (7000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-18501 -501) (3500 1000)) + rect(l3 (6500 -1000) (1000 1000)) + rect(l3 (-8500 -1000) (1000 1000)) + rect(l4 (-1000 -1000) (8500 1000)) + rect(l2 (-11000 -1000) (1000 1000)) + ) + + # Subcircuits and their connections + circuit(1 CHIP location(0 0) + pin(0 1) + pin(1 2) + pin(2 7) + pin(3 3) + pin(4 4) + pin(5 5) + pin(6 8) + pin(7 6) + ) + + ) +) + +# Reference netlist +reference( + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Outgoing pins and their connections to nets + pin(name(PAD1)) + pin(name(PAD2)) + pin(name(PAD3)) + pin(name(PAD4)) + pin(name(PAD5)) + pin(name(PAD6)) + pin(name(PAD7)) + pin(name(PAD8)) + + ) + circuit(TOP + + # 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')) + net(7 name('7')) + net(8 name('8')) + + # Subcircuits and their connections + circuit(1 CHIP name('1') + pin(0 1) + pin(1 2) + pin(2 3) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 7) + pin(7 8) + ) + + ) +) + +# Cross reference +xref( + circuit(CHIP CHIP match + xref( + pin(4 0 match) + pin(3 1 match) + pin(0 2 match) + pin(1 3 match) + pin(2 4 match) + pin(6 5 match) + pin(7 6 match) + pin(5 7 match) + ) + ) + circuit(TOP TOP nomatch + xref( + net(4 1 match) + net(3 2 match) + net(2 3 mismatch) + net(1 4 mismatch) + net(7 5 match) + net(8 6 match) + net(6 7 match) + net(5 8 match) + circuit(1 1 mismatch) + ) + ) +) diff --git a/testdata/lvs/blackbox3.cir b/testdata/lvs/blackbox3.cir new file mode 100644 index 000000000..40adb3c28 --- /dev/null +++ b/testdata/lvs/blackbox3.cir @@ -0,0 +1,27 @@ +* Extracted by KLayout + +* cell TOP +.SUBCKT TOP +* net 2 3 +* net 3 4 +* net 4 2 +* net 5 1 +* net 6 8 +* net 7 5 +* net 8 6 +* net 9 7 +* cell instance $1 r0 *1 0,0 +X$1 2 3 7 4 5 6 8 1 CHIP +.ENDS TOP + +* cell CHIP +* pin pad3 +* pin pad4 +* pin pad5 +* pin pad2 +* pin pad1 +* pin pad8 +* pin pad6 +* pin pad7 +.SUBCKT CHIP 1 2 3 4 5 6 7 8 +.ENDS CHIP diff --git a/testdata/lvs/blackbox3.lvs b/testdata/lvs/blackbox3.lvs new file mode 100644 index 000000000..9b20bc4d6 --- /dev/null +++ b/testdata/lvs/blackbox3.lvs @@ -0,0 +1,22 @@ +source($lvs_test_source) +report_lvs($lvs_test_target_lvsdb, true) +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("blackbox_schematic.cir") + +deep + +same_nets!("TOP", "*", "*") + +m1 = input(1, 0) +via = input(2, 0) +m2 = input(3, 0) +pad = input(10, 0) + +connect(m1, pad) +connect(m1, via) +connect(via, m2) + +blank_circuit("CHIP") + +compare diff --git a/testdata/lvs/blackbox3.lvsdb b/testdata/lvs/blackbox3.lvsdb new file mode 100644 index 000000000..1dd6f3942 --- /dev/null +++ b/testdata/lvs/blackbox3.lvsdb @@ -0,0 +1,200 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l1 '1/0') + layer(l3 '2/0') + layer(l4 '3/0') + layer(l2 '10/0') + + # Mask layer connectivity + connect(l1 l1 l3 l2) + connect(l3 l1 l3 l4) + connect(l4 l3 l4) + connect(l2 l1 l2) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Circuit boundary + rect((-4000 -6000) (11000 9000)) + + # Outgoing pins and their connections to nets + pin(name(pad3)) + pin(name(pad4)) + pin(name(pad5)) + pin(name(pad2)) + pin(name(pad1)) + pin(name(pad8)) + pin(name(pad6)) + pin(name(pad7)) + + ) + circuit(TOP + + # Circuit boundary + rect((-18500 -14000) (44500 28000)) + + # Nets with their geometries + net(1 + rect(l1 (6000 -6000) (7000 1000)) + rect(l1 (-1000 0) (1000 12000)) + rect(l1 (-1000 0) (5160 1000)) + rect(l2 (-11160 -14000) (1000 1000)) + ) + net(2 name('3') + rect(l1 (-10500 2000) (7500 1000)) + rect(l1 (-7500 0) (1000 4000)) + rect(l1 (-6000 0) (6000 1000)) + rect(l1 (-9000 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -5501) (1000 1000)) + ) + net(3 name('4') + rect(l1 (1000 2000) (1000 10000)) + rect(l1 (-17500 0) (17500 1000)) + rect(l1 (-20500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (17499 -10501) (1000 1000)) + ) + net(4 name('2') + rect(l1 (-15500 -2000) (12500 1000)) + rect(l1 (-15500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -501) (1000 1000)) + ) + net(5 name('1') + rect(l1 (-15500 -13000) (6000 1000)) + rect(l1 (-1000 0) (1000 6000)) + rect(l1 (-9000 -8000) (3500 3000)) + rect(l1 (4500 5000) (7500 1000)) + rect(l1 (-13501 -7501) (2 2)) + rect(l2 (12499 6499) (1000 1000)) + ) + net(6 name('8') + rect(l1 (1000 -13000) (22000 1000)) + rect(l1 (-22000 0) (1000 7000)) + rect(l1 (20500 -9000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-23501 6499) (1000 1000)) + ) + net(7 name('5') + rect(l1 (6000 2000) (1000 10000)) + rect(l1 (-1000 0) (17000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-18501 -10501) (1000 1000)) + ) + net(8 name('6') + rect(l1 (16000 -2000) (7000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-18501 -501) (3500 1000)) + rect(l3 (6500 -1000) (1000 1000)) + rect(l3 (-8500 -1000) (1000 1000)) + rect(l4 (-1000 -1000) (8500 1000)) + rect(l2 (-11000 -1000) (1000 1000)) + ) + net(9 name('7') + rect(l1 (18080 7000) (4920 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + ) + + # Subcircuits and their connections + circuit(1 CHIP location(0 0) + pin(0 2) + pin(1 3) + pin(2 7) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 8) + pin(7 1) + ) + + ) +) + +# Reference netlist +reference( + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Outgoing pins and their connections to nets + pin(name(PAD1)) + pin(name(PAD2)) + pin(name(PAD3)) + pin(name(PAD4)) + pin(name(PAD5)) + pin(name(PAD6)) + pin(name(PAD7)) + pin(name(PAD8)) + + ) + circuit(TOP + + # 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')) + net(7 name('7')) + net(8 name('8')) + + # Subcircuits and their connections + circuit(1 CHIP name('1') + pin(0 1) + pin(1 2) + pin(2 3) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 7) + pin(7 8) + ) + + ) +) + +# Cross reference +xref( + circuit(CHIP CHIP match + xref( + pin(4 0 match) + pin(3 1 match) + pin(0 2 match) + pin(1 3 match) + pin(2 4 match) + pin(6 5 match) + pin(7 6 match) + pin(5 7 match) + ) + ) + circuit(TOP TOP nomatch + xref( + net(() 7 mismatch) + net(1 () mismatch) + net(5 1 match) + net(4 2 match) + net(2 3 match) + net(3 4 match) + net(7 5 match) + net(8 6 match) + net(6 8 match) + circuit(1 1 mismatch) + ) + ) +) diff --git a/testdata/lvs/blackbox4.cir b/testdata/lvs/blackbox4.cir new file mode 100644 index 000000000..84da4c047 --- /dev/null +++ b/testdata/lvs/blackbox4.cir @@ -0,0 +1,26 @@ +* Extracted by KLayout + +* cell TOP +.SUBCKT TOP +* net 1 3 +* net 2 4 +* net 3 2 +* net 4 1 +* net 5 8 +* net 6 5,7 +* net 7 6 +* cell instance $1 r0 *1 0,0 +X$1 1 2 6 3 4 5 7 6 CHIP +.ENDS TOP + +* cell CHIP +* pin pad3 +* pin pad4 +* pin pad5 +* pin pad2 +* pin pad1 +* pin pad8 +* pin pad6 +* pin pad7 +.SUBCKT CHIP 1 2 3 4 5 6 7 8 +.ENDS CHIP diff --git a/testdata/lvs/blackbox4.lvs b/testdata/lvs/blackbox4.lvs new file mode 100644 index 000000000..9b20bc4d6 --- /dev/null +++ b/testdata/lvs/blackbox4.lvs @@ -0,0 +1,22 @@ +source($lvs_test_source) +report_lvs($lvs_test_target_lvsdb, true) +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("blackbox_schematic.cir") + +deep + +same_nets!("TOP", "*", "*") + +m1 = input(1, 0) +via = input(2, 0) +m2 = input(3, 0) +pad = input(10, 0) + +connect(m1, pad) +connect(m1, via) +connect(via, m2) + +blank_circuit("CHIP") + +compare diff --git a/testdata/lvs/blackbox4.lvsdb b/testdata/lvs/blackbox4.lvsdb new file mode 100644 index 000000000..fb865f98d --- /dev/null +++ b/testdata/lvs/blackbox4.lvsdb @@ -0,0 +1,196 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l1 '1/0') + layer(l3 '2/0') + layer(l4 '3/0') + layer(l2 '10/0') + + # Mask layer connectivity + connect(l1 l1 l3 l2) + connect(l3 l1 l3 l4) + connect(l4 l3 l4) + connect(l2 l1 l2) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Circuit boundary + rect((-4000 -6000) (11000 9000)) + + # Outgoing pins and their connections to nets + pin(name(pad3)) + pin(name(pad4)) + pin(name(pad5)) + pin(name(pad2)) + pin(name(pad1)) + pin(name(pad8)) + pin(name(pad6)) + pin(name(pad7)) + + ) + circuit(TOP + + # Circuit boundary + rect((-18500 -14000) (44500 28000)) + + # Nets with their geometries + net(1 name('3') + rect(l1 (-10500 2000) (7500 1000)) + rect(l1 (-7500 0) (1000 4000)) + rect(l1 (-6000 0) (6000 1000)) + rect(l1 (-9000 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -5501) (1000 1000)) + ) + net(2 name('4') + rect(l1 (1000 2000) (1000 10000)) + rect(l1 (-17500 0) (17500 1000)) + rect(l1 (-20500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (17499 -10501) (1000 1000)) + ) + net(3 name('2') + rect(l1 (-15500 -2000) (12500 1000)) + rect(l1 (-15500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -501) (1000 1000)) + ) + net(4 name('1') + rect(l1 (-15500 -13000) (6000 1000)) + rect(l1 (-1000 0) (1000 6000)) + rect(l1 (-9000 -8000) (3500 3000)) + rect(l1 (4500 5000) (7500 1000)) + rect(l1 (-13501 -7501) (2 2)) + rect(l2 (12499 6499) (1000 1000)) + ) + net(5 name('8') + rect(l1 (1000 -13000) (22000 1000)) + rect(l1 (-22000 0) (1000 7000)) + rect(l1 (20500 -9000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-23501 6499) (1000 1000)) + ) + net(6 name('5,7') + rect(l1 (6000 -6000) (7000 1000)) + rect(l1 (-1000 0) (1000 12000)) + rect(l1 (-1000 0) (11000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-12200 -1500) (790 4500)) + rect(l1 (-8590 -10000) (1000 10000)) + rect(l1 (-1000 0) (17000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -6501) (2 2)) + rect(l1 (-2 4998) (2 2)) + rect(l2 (-18501 -18501) (1000 1000)) + rect(l2 (-1000 7000) (1000 1000)) + ) + net(7 name('6') + rect(l1 (16000 -2000) (7000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-18501 -501) (3500 1000)) + rect(l3 (6500 -1000) (1000 1000)) + rect(l3 (-8500 -1000) (1000 1000)) + rect(l4 (-1000 -1000) (8500 1000)) + rect(l2 (-11000 -1000) (1000 1000)) + ) + + # Subcircuits and their connections + circuit(1 CHIP location(0 0) + pin(0 1) + pin(1 2) + pin(2 6) + pin(3 3) + pin(4 4) + pin(5 5) + pin(6 7) + pin(7 6) + ) + + ) +) + +# Reference netlist +reference( + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Outgoing pins and their connections to nets + pin(name(PAD1)) + pin(name(PAD2)) + pin(name(PAD3)) + pin(name(PAD4)) + pin(name(PAD5)) + pin(name(PAD6)) + pin(name(PAD7)) + pin(name(PAD8)) + + ) + circuit(TOP + + # 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')) + net(7 name('7')) + net(8 name('8')) + + # Subcircuits and their connections + circuit(1 CHIP name('1') + pin(0 1) + pin(1 2) + pin(2 3) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 7) + pin(7 8) + ) + + ) +) + +# Cross reference +xref( + circuit(CHIP CHIP match + xref( + pin(4 0 match) + pin(3 1 match) + pin(0 2 match) + pin(1 3 match) + pin(2 4 match) + pin(6 5 match) + pin(7 6 match) + pin(5 7 match) + ) + ) + circuit(TOP TOP nomatch + xref( + net(() 5 mismatch) + net(() 7 mismatch) + net(4 1 match) + net(3 2 match) + net(1 3 match) + net(2 4 match) + net(6 () mismatch) + net(7 6 match) + net(5 8 match) + circuit(1 1 mismatch) + ) + ) +) diff --git a/testdata/lvs/blackbox5.cir b/testdata/lvs/blackbox5.cir new file mode 100644 index 000000000..4e2b43ed7 --- /dev/null +++ b/testdata/lvs/blackbox5.cir @@ -0,0 +1,26 @@ +* Extracted by KLayout + +* cell TOP +.SUBCKT TOP +* net 2 3 +* net 3 4 +* net 4 2 +* net 5 1 +* net 6 8 +* net 7 5,7 +* net 8 6 +* cell instance $1 r0 *1 0,0 +X$1 2 3 7 4 5 6 8 1 CHIP +.ENDS TOP + +* cell CHIP +* pin pad3 +* pin pad4 +* pin pad5 +* pin pad2 +* pin pad1 +* pin pad8 +* pin pad6 +* pin pad7 +.SUBCKT CHIP 1 2 3 4 5 6 7 8 +.ENDS CHIP diff --git a/testdata/lvs/blackbox5.lvs b/testdata/lvs/blackbox5.lvs new file mode 100644 index 000000000..9b20bc4d6 --- /dev/null +++ b/testdata/lvs/blackbox5.lvs @@ -0,0 +1,22 @@ +source($lvs_test_source) +report_lvs($lvs_test_target_lvsdb, true) +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("blackbox_schematic.cir") + +deep + +same_nets!("TOP", "*", "*") + +m1 = input(1, 0) +via = input(2, 0) +m2 = input(3, 0) +pad = input(10, 0) + +connect(m1, pad) +connect(m1, via) +connect(via, m2) + +blank_circuit("CHIP") + +compare diff --git a/testdata/lvs/blackbox5.lvsdb b/testdata/lvs/blackbox5.lvsdb new file mode 100644 index 000000000..3c2726f5a --- /dev/null +++ b/testdata/lvs/blackbox5.lvsdb @@ -0,0 +1,200 @@ +#%lvsdb-klayout + +# Layout +layout( + top(TOP) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l1 '1/0') + layer(l3 '2/0') + layer(l4 '3/0') + layer(l2 '10/0') + + # Mask layer connectivity + connect(l1 l1 l3 l2) + connect(l3 l1 l3 l4) + connect(l4 l3 l4) + connect(l2 l1 l2) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Circuit boundary + rect((-4000 -6000) (11000 9000)) + + # Outgoing pins and their connections to nets + pin(name(pad3)) + pin(name(pad4)) + pin(name(pad5)) + pin(name(pad2)) + pin(name(pad1)) + pin(name(pad8)) + pin(name(pad6)) + pin(name(pad7)) + + ) + circuit(TOP + + # Circuit boundary + rect((-18500 -14000) (44500 28000)) + + # Nets with their geometries + net(1 + rect(l1 (6000 -6000) (7000 1000)) + rect(l1 (-1000 0) (1000 12000)) + rect(l1 (-1000 0) (4550 1000)) + rect(l2 (-10550 -14000) (1000 1000)) + ) + net(2 name('3') + rect(l1 (-10500 2000) (7500 1000)) + rect(l1 (-7500 0) (1000 4000)) + rect(l1 (-6000 0) (6000 1000)) + rect(l1 (-9000 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -5501) (1000 1000)) + ) + net(3 name('4') + rect(l1 (1000 2000) (1000 10000)) + rect(l1 (-17500 0) (17500 1000)) + rect(l1 (-20500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (17499 -10501) (1000 1000)) + ) + net(4 name('2') + rect(l1 (-15500 -2000) (12500 1000)) + rect(l1 (-15500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (12499 -501) (1000 1000)) + ) + net(5 name('1') + rect(l1 (-15500 -13000) (6000 1000)) + rect(l1 (-1000 0) (1000 6000)) + rect(l1 (-9000 -8000) (3500 3000)) + rect(l1 (4500 5000) (7500 1000)) + rect(l1 (-13501 -7501) (2 2)) + rect(l2 (12499 6499) (1000 1000)) + ) + net(6 name('8') + rect(l1 (1000 -13000) (22000 1000)) + rect(l1 (-22000 0) (1000 7000)) + rect(l1 (20500 -9000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l2 (-23501 6499) (1000 1000)) + ) + net(7 name('5,7') + rect(l1 (6000 2000) (1000 10000)) + rect(l1 (-1000 0) (17000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-6960 -6450) (700 4950)) + rect(l1 (-2270 -5500) (5530 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-2 4998) (2 2)) + rect(l2 (-18501 -10501) (1000 1000)) + ) + net(8 name('6') + rect(l1 (16000 -2000) (7000 1000)) + rect(l1 (-500 -2000) (3500 3000)) + rect(l1 (-1501 -1501) (2 2)) + rect(l1 (-18501 -501) (3500 1000)) + rect(l3 (6500 -1000) (1000 1000)) + rect(l3 (-8500 -1000) (1000 1000)) + rect(l4 (-1000 -1000) (8500 1000)) + rect(l2 (-11000 -1000) (1000 1000)) + ) + + # Subcircuits and their connections + circuit(1 CHIP location(0 0) + pin(0 2) + pin(1 3) + pin(2 7) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 8) + pin(7 1) + ) + + ) +) + +# Reference netlist +reference( + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(CHIP + + # Outgoing pins and their connections to nets + pin(name(PAD1)) + pin(name(PAD2)) + pin(name(PAD3)) + pin(name(PAD4)) + pin(name(PAD5)) + pin(name(PAD6)) + pin(name(PAD7)) + pin(name(PAD8)) + + ) + circuit(TOP + + # 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')) + net(7 name('7')) + net(8 name('8')) + + # Subcircuits and their connections + circuit(1 CHIP name('1') + pin(0 1) + pin(1 2) + pin(2 3) + pin(3 4) + pin(4 5) + pin(5 6) + pin(6 7) + pin(7 8) + ) + + ) +) + +# Cross reference +xref( + circuit(CHIP CHIP match + xref( + pin(4 0 match) + pin(3 1 match) + pin(0 2 match) + pin(1 3 match) + pin(2 4 match) + pin(6 5 match) + pin(7 6 match) + pin(5 7 match) + ) + ) + circuit(TOP TOP nomatch + xref( + net(() 5 mismatch) + net(() 7 mismatch) + net(1 () mismatch) + net(5 1 match) + net(4 2 match) + net(2 3 match) + net(3 4 match) + net(7 () mismatch) + net(8 6 match) + net(6 8 match) + circuit(1 1 mismatch) + ) + ) +) diff --git a/testdata/lvs/blackbox_open.gds b/testdata/lvs/blackbox_open.gds new file mode 100644 index 000000000..3123ac4da Binary files /dev/null and b/testdata/lvs/blackbox_open.gds differ diff --git a/testdata/lvs/blackbox_schematic.cir b/testdata/lvs/blackbox_schematic.cir new file mode 100644 index 000000000..3dcf769b4 --- /dev/null +++ b/testdata/lvs/blackbox_schematic.cir @@ -0,0 +1,9 @@ + +.subckt chip pad1 pad2 pad3 pad4 pad5 pad6 pad7 pad8 +* This chip is an abstract +.ends + +.subckt TOP +X1 1 2 3 4 5 6 7 8 chip +.ends + diff --git a/testdata/lvs/blackbox_short.gds b/testdata/lvs/blackbox_short.gds new file mode 100644 index 000000000..ec78d962b Binary files /dev/null and b/testdata/lvs/blackbox_short.gds differ diff --git a/testdata/lvs/blackbox_short_and_open.gds b/testdata/lvs/blackbox_short_and_open.gds new file mode 100644 index 000000000..49e96056c Binary files /dev/null and b/testdata/lvs/blackbox_short_and_open.gds differ diff --git a/testdata/lvs/blackbox_swapped.gds b/testdata/lvs/blackbox_swapped.gds new file mode 100644 index 000000000..555ca2c8d Binary files /dev/null and b/testdata/lvs/blackbox_swapped.gds differ diff --git a/testdata/lvs/empty_subcells.lvsdb b/testdata/lvs/empty_subcells.lvsdb index 81138e85d..5a0306ccb 100644 --- a/testdata/lvs/empty_subcells.lvsdb +++ b/testdata/lvs/empty_subcells.lvsdb @@ -158,8 +158,8 @@ xref( ) circuit(empty_subcells EMPTY_SUBCELLS match xref( - net(1 1 warning) - net(2 2 warning) + net(1 1 match) + net(2 2 match) circuit(2 1 match) circuit(1 2 match) ) diff --git a/testdata/lvs/nand2_split_gate_early.cir.1 b/testdata/lvs/nand2_split_gate_early.cir.1 new file mode 100644 index 000000000..5c739a1a4 --- /dev/null +++ b/testdata/lvs/nand2_split_gate_early.cir.1 @@ -0,0 +1,23 @@ +* Extracted by KLayout + +* cell NAND2_WITH_DIODES +* pin B +* pin A +* pin OUT +* pin VDD +* pin VSS +.SUBCKT NAND2_WITH_DIODES 1 2 4 5 6 +* net 1 B +* net 2 A +* net 4 OUT +* net 5 VDD +* net 6 VSS +* device instance $1 r0 *1 1.025,4.95 PMOS +M$1 5 1 4 5 PMOS L=0.25U W=1.5U AS=0.675P AD=0.375P PS=3.9U PD=2U +* device instance $2 r0 *1 1.775,4.95 PMOS +M$2 4 2 5 5 PMOS L=0.25U W=1.5U AS=0.375P AD=0.675P PS=2U PD=3.9U +* device instance $3 r0 *1 1.025,2 NMOS +M$3 6 1 3 6 NMOS L=0.25U W=1.8U AS=0.81P AD=0.45P PS=5.4U PD=2.8U +* device instance $4 r0 *1 1.775,2 NMOS +M$4 3 2 4 6 NMOS L=0.25U W=1.8U AS=0.45P AD=0.81P PS=2.8U PD=5.4U +.ENDS NAND2_WITH_DIODES diff --git a/testdata/lvs/nand2_split_gate_early.cir.2 b/testdata/lvs/nand2_split_gate_early.cir.2 new file mode 100644 index 000000000..6bceb7353 --- /dev/null +++ b/testdata/lvs/nand2_split_gate_early.cir.2 @@ -0,0 +1,23 @@ +* Extracted by KLayout + +* cell NAND2_WITH_DIODES +* pin B +* pin A +* pin OUT +* pin VDD +* pin VSS +.SUBCKT NAND2_WITH_DIODES 1 2 4 5 6 +* net 1 B +* net 2 A +* net 4 OUT +* net 5 VDD +* net 6 VSS +* device instance $1 r0 *1 1.025,4.95 PMOS +M$1 5 1 4 5 PMOS L=0.25U W=1.5U AS=0.675P AD=0.375P PS=3.9U PD=2U +* device instance $2 r0 *1 1.775,4.95 PMOS +M$2 4 2 5 5 PMOS L=0.25U W=1.5U AS=0.375P AD=0.675P PS=2U PD=3.9U +* device instance $3 r0 *1 1.025,0.65 NMOS +M$3 6 1 3 6 NMOS L=0.25U W=1.8U AS=0.81P AD=0.45P PS=5.4U PD=2.8U +* device instance $4 r0 *1 1.775,0.65 NMOS +M$4 3 2 4 6 NMOS L=0.25U W=1.8U AS=0.45P AD=0.81P PS=2.8U PD=5.4U +.ENDS NAND2_WITH_DIODES diff --git a/testdata/lvs/nand2_split_gate_early.lvs b/testdata/lvs/nand2_split_gate_early.lvs new file mode 100644 index 000000000..bf48ae960 --- /dev/null +++ b/testdata/lvs/nand2_split_gate_early.lvs @@ -0,0 +1,85 @@ + +source($lvs_test_source, "NAND2_WITH_DIODES") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("nand2_split_gate_schematic.cir") + +join_symmetric_nets("*") + +deep + +# Reports generated + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(6, 0) +metal1 = input(7, 0) +metal1_lbl = labels(7, 1) +via1 = input(8, 0) +metal2 = input(9, 0) +metal2_lbl = labels(9, 1) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell & pplus +pgate = pactive & poly +psd = pactive - pgate +ntie = active_in_nwell & nplus + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate +ptie = active_outside_nwell & pplus + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos4("PMOS"), { "SD" => 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, metal1_lbl) # attaches labels +connect(metal1, via1) +connect(via1, metal2) +connect(metal2, metal2_lbl) # attaches labels + +# Global +connect_global(bulk, "SUBSTRATE") +connect_global(ptie, "SUBSTRATE") + +# Extract, simplify + +netlist +netlist.simplify + +# Compare section + +compare + diff --git a/testdata/lvs/nand2_split_gate_early.lvsdb.1 b/testdata/lvs/nand2_split_gate_early.lvsdb.1 new file mode 100644 index 000000000..e0d758a88 --- /dev/null +++ b/testdata/lvs/nand2_split_gate_early.lvsdb.1 @@ -0,0 +1,407 @@ +#%lvsdb-klayout + +# Layout +layout( + top(NAND2_WITH_DIODES) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 'NWELL (1/0)') + layer(l4 'POLY (5/0)') + layer(l8 'CONTACT (6/0)') + layer(l11 'METAL1 (7/0)') + layer(l12 'METAL1_LABEL (7/1)') + layer(l13 'VIA1 (8/0)') + layer(l14 'METAL2 (9/0)') + layer(l15 'METAL2_LABEL (9/1)') + 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 l13) + connect(l12 l11) + connect(l13 l11 l13 l14) + connect(l14 l13 l14 l15) + connect(l15 l14) + 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 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (500 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-625 -750) (500 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$NMOS NMOS + terminal(S + rect(l6 (-575 -450) (450 900)) + ) + terminal(G + rect(l4 (-125 -450) (250 900)) + ) + terminal(D + rect(l6 (125 -450) (500 900)) + ) + terminal(B + rect(l7 (-125 -450) (250 900)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-625 -450) (500 900)) + ) + terminal(G + rect(l4 (-125 -450) (250 900)) + ) + terminal(D + rect(l6 (125 -450) (450 900)) + ) + terminal(B + rect(l7 (-125 -450) (250 900)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(NAND2_WITH_DIODES + + # Circuit boundary + rect((0 0) (3750 6150)) + + # Nets with their geometries + net(1 name(B) + rect(l4 (350 2750) (550 400)) + rect(l4 (0 -2050) (250 3100)) + rect(l4 (-250 0) (250 1650)) + rect(l4 (-250 -5800) (250 1050)) + rect(l4 (-250 300) (250 1050)) + rect(l8 (-700 400) (200 200)) + rect(l11 (-300 -300) (400 400)) + text(l12 B (-200 -200)) + ) + net(2 name(A) + rect(l4 (1900 3400) (550 400)) + rect(l4 (-800 -2700) (250 3100)) + rect(l4 (-250 0) (250 1650)) + rect(l4 (-250 -5800) (250 1050)) + rect(l4 (-250 300) (250 1050)) + rect(l8 (250 1050) (200 200)) + rect(l11 (-300 -300) (400 400)) + text(l12 A (-200 -200)) + ) + net(3 + rect(l8 (1300 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 650) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l11 (-250 -2150) (300 900)) + rect(l11 (-300 -900) (300 850)) + rect(l11 (-300 500) (300 900)) + rect(l11 (-300 -900) (300 850)) + rect(l6 (-400 -2200) (500 900)) + rect(l6 (-500 450) (500 900)) + ) + net(4 name(OUT) + rect(l8 (2050 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 650) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-950 2000) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l11 (500 -5350) (300 850)) + rect(l11 (-300 -50) (300 1950)) + rect(l11 (-300 -1400) (300 850)) + rect(l11 (-300 300) (450 400)) + rect(l11 (-1200 -300) (1050 300)) + rect(l11 (-1050 1150) (300 1400)) + rect(l11 (-300 -2700) (300 1950)) + text(l12 OUT (700 -2000)) + rect(l2 (-1100 1300) (500 1500)) + rect(l6 (250 -5500) (450 900)) + rect(l6 (-450 450) (450 900)) + ) + net(5 name(VDD) + rect(l3 (0 2950) (3750 3200)) + rect(l8 (-3200 -1800) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (1300 -1200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (700 -800) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l11 (-2650 -1200) (300 1600)) + rect(l11 (1200 -1600) (300 1600)) + rect(l11 (600 -1200) (300 1200)) + rect(l13 (-2650 -800) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (1300 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (700 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l14 (-3150 -850) (3750 1000)) + text(l15 VDD (-100 -850)) + rect(l2 (-3200 -850) (450 1500)) + rect(l2 (1000 -1500) (450 1500)) + rect(l9 (400 -1200) (600 1200)) + ) + net(6 name(VSS) + rect(l8 (550 1650) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -2050) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (2200 -550) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l11 (-2650 -50) (300 1350)) + rect(l11 (-300 -2400) (300 1050)) + rect(l11 (2100 -1050) (300 1200)) + rect(l13 (-2650 -1100) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (2200 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l14 (-3150 -850) (3750 1000)) + text(l15 VSS (-100 -850)) + rect(l6 (-3200 1400) (450 900)) + rect(l6 (-450 -2250) (450 900)) + rect(l10 (1850 -900) (600 1200)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(B)) + pin(2 name(A)) + pin(4 name(OUT)) + pin(5 name(VDD)) + pin(6 name(VSS)) + + # Devices and their connections + device(1 D$PMOS + location(1025 4950) + param(L 0.25) + param(W 1.5) + param(AS 0.675) + param(AD 0.375) + param(PS 3.9) + param(PD 2) + terminal(S 5) + terminal(G 1) + terminal(D 4) + terminal(B 5) + ) + device(2 D$PMOS$1 + location(1775 4950) + param(L 0.25) + param(W 1.5) + param(AS 0.375) + param(AD 0.675) + param(PS 2) + param(PD 3.9) + terminal(S 4) + terminal(G 2) + terminal(D 5) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS location(0 -1350)) + connect(0 S S) + connect(1 S S) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D D) + connect(0 B B) + connect(1 B B) + location(1025 2000) + param(L 0.25) + param(W 1.8) + param(AS 0.81) + param(AD 0.45) + param(PS 5.4) + param(PD 2.8) + terminal(S 6) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + device(4 D$NMOS$1 + device(D$NMOS$1 location(0 -1350)) + connect(0 S S) + connect(1 S S) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D D) + connect(0 B B) + connect(1 B B) + location(1775 2000) + param(L 0.25) + param(W 1.8) + param(AS 0.45) + param(AD 0.81) + param(PS 2.8) + param(PD 5.4) + terminal(S 3) + terminal(G 2) + terminal(D 4) + terminal(B 6) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(NAND2_WITH_DIODES + + # Nets + net(1 name(A)) + net(2 name(B)) + net(3 name(OUT)) + net(4 name(VSS)) + net(5 name(VDD)) + net(6 name($1)) + + # Outgoing pins and their connections to nets + pin(1 name(A)) + pin(2 name(B)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5 name(VDD)) + + # 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 5) + terminal(G 2) + terminal(D 3) + terminal(B 5) + ) + 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 5) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 NMOS + name('3') + param(L 0.25) + param(W 1.8) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 4) + terminal(G 2) + terminal(D 6) + terminal(B 4) + ) + device(4 NMOS + name('4') + param(L 0.25) + param(W 1.8) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 6) + terminal(G 1) + terminal(D 3) + terminal(B 4) + ) + + ) +) + +# Cross reference +xref( + circuit(NAND2_WITH_DIODES NAND2_WITH_DIODES match + xref( + net(3 6 match) + net(2 1 match) + net(1 2 match) + net(4 3 match) + net(5 5 match) + net(6 4 match) + pin(1 0 match) + pin(0 1 match) + pin(2 2 match) + pin(3 4 match) + pin(4 3 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) +) diff --git a/testdata/lvs/nand2_split_gate_early.lvsdb.2 b/testdata/lvs/nand2_split_gate_early.lvsdb.2 new file mode 100644 index 000000000..4742977a2 --- /dev/null +++ b/testdata/lvs/nand2_split_gate_early.lvsdb.2 @@ -0,0 +1,407 @@ +#%lvsdb-klayout + +# Layout +layout( + top(NAND2_WITH_DIODES) + unit(0.001) + + # Layer section + # This section lists the mask layers (drawing or derived) and their connections. + + # Mask layers + layer(l3 'NWELL (1/0)') + layer(l4 'POLY (5/0)') + layer(l8 'CONTACT (6/0)') + layer(l11 'METAL1 (7/0)') + layer(l12 'METAL1_LABEL (7/1)') + layer(l13 'VIA1 (8/0)') + layer(l14 'METAL2 (9/0)') + layer(l15 'METAL2_LABEL (9/1)') + 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 l13) + connect(l12 l11) + connect(l13 l11 l13 l14) + connect(l14 l13 l14 l15) + connect(l15 l14) + 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 (-575 -750) (450 1500)) + ) + terminal(G + rect(l4 (-125 -750) (250 1500)) + ) + terminal(D + rect(l2 (125 -750) (500 1500)) + ) + terminal(B + rect(l3 (-125 -750) (250 1500)) + ) + ) + device(D$PMOS$1 PMOS + terminal(S + rect(l2 (-625 -750) (500 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$NMOS NMOS + terminal(S + rect(l6 (-575 -450) (450 900)) + ) + terminal(G + rect(l4 (-125 -450) (250 900)) + ) + terminal(D + rect(l6 (125 -450) (500 900)) + ) + terminal(B + rect(l7 (-125 -450) (250 900)) + ) + ) + device(D$NMOS$1 NMOS + terminal(S + rect(l6 (-625 -450) (500 900)) + ) + terminal(G + rect(l4 (-125 -450) (250 900)) + ) + terminal(D + rect(l6 (125 -450) (450 900)) + ) + terminal(B + rect(l7 (-125 -450) (250 900)) + ) + ) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(NAND2_WITH_DIODES + + # Circuit boundary + rect((0 0) (3750 6150)) + + # Nets with their geometries + net(1 name(B) + rect(l4 (350 2750) (550 400)) + rect(l4 (0 -2050) (250 3100)) + rect(l4 (-250 0) (250 1650)) + rect(l4 (-250 -5800) (250 1050)) + rect(l4 (-250 300) (250 1050)) + rect(l8 (-700 400) (200 200)) + rect(l11 (-300 -300) (400 400)) + text(l12 B (-200 -200)) + ) + net(2 name(A) + rect(l4 (1900 3400) (550 400)) + rect(l4 (-800 -2700) (250 3100)) + rect(l4 (-250 0) (250 1650)) + rect(l4 (-250 -5800) (250 1050)) + rect(l4 (-250 300) (250 1050)) + rect(l8 (250 1050) (200 200)) + rect(l11 (-300 -300) (400 400)) + text(l12 A (-200 -200)) + ) + net(3 + rect(l8 (1300 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 650) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l11 (-250 -2150) (300 900)) + rect(l11 (-300 -900) (300 850)) + rect(l11 (-300 500) (300 900)) + rect(l11 (-300 -900) (300 850)) + rect(l6 (-400 -2200) (500 900)) + rect(l6 (-500 450) (500 900)) + ) + net(4 name(OUT) + rect(l8 (2050 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 650) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-950 2000) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -200) (200 200)) + rect(l11 (500 -5350) (300 850)) + rect(l11 (-300 -50) (300 1950)) + rect(l11 (-300 -1400) (300 850)) + rect(l11 (-300 300) (450 400)) + rect(l11 (-1200 -300) (1050 300)) + rect(l11 (-1050 1150) (300 1400)) + rect(l11 (-300 -2700) (300 1950)) + text(l12 OUT (700 -2000)) + rect(l2 (-1100 1300) (500 1500)) + rect(l6 (250 -5500) (450 900)) + rect(l6 (-450 450) (450 900)) + ) + net(5 name(VDD) + rect(l3 (0 2950) (3750 3200)) + rect(l8 (-3200 -1800) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (1300 -1200) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (700 -800) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l11 (-2650 -1200) (300 1600)) + rect(l11 (1200 -1600) (300 1600)) + rect(l11 (600 -1200) (300 1200)) + rect(l13 (-2650 -800) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (1300 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (700 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l14 (-3150 -850) (3750 1000)) + text(l15 VDD (-100 -850)) + rect(l2 (-3200 -850) (450 1500)) + rect(l2 (1000 -1500) (450 1500)) + rect(l9 (400 -1200) (600 1200)) + ) + net(6 name(VSS) + rect(l8 (550 1650) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (-200 -2050) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l8 (2200 -550) (200 200)) + rect(l8 (-200 300) (200 200)) + rect(l11 (-2650 -50) (300 1350)) + rect(l11 (-300 -2400) (300 1050)) + rect(l11 (2100 -1050) (300 1200)) + rect(l13 (-2650 -1100) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l13 (2200 -700) (200 200)) + rect(l13 (-200 300) (200 200)) + rect(l14 (-3150 -850) (3750 1000)) + text(l15 VSS (-100 -850)) + rect(l6 (-3200 1400) (450 900)) + rect(l6 (-450 -2250) (450 900)) + rect(l10 (1850 -900) (600 1200)) + ) + + # Outgoing pins and their connections to nets + pin(1 name(B)) + pin(2 name(A)) + pin(4 name(OUT)) + pin(5 name(VDD)) + pin(6 name(VSS)) + + # Devices and their connections + device(1 D$PMOS + location(1025 4950) + param(L 0.25) + param(W 1.5) + param(AS 0.675) + param(AD 0.375) + param(PS 3.9) + param(PD 2) + terminal(S 5) + terminal(G 1) + terminal(D 4) + terminal(B 5) + ) + device(2 D$PMOS$1 + location(1775 4950) + param(L 0.25) + param(W 1.5) + param(AS 0.375) + param(AD 0.675) + param(PS 2) + param(PD 3.9) + terminal(S 4) + terminal(G 2) + terminal(D 5) + terminal(B 5) + ) + device(3 D$NMOS + device(D$NMOS location(0 1350)) + connect(0 S S) + connect(1 S S) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D D) + connect(0 B B) + connect(1 B B) + location(1025 650) + param(L 0.25) + param(W 1.8) + param(AS 0.81) + param(AD 0.45) + param(PS 5.4) + param(PD 2.8) + terminal(S 6) + terminal(G 1) + terminal(D 3) + terminal(B 6) + ) + device(4 D$NMOS$1 + device(D$NMOS$1 location(0 1350)) + connect(0 S S) + connect(1 S S) + connect(0 G G) + connect(1 G G) + connect(0 D D) + connect(1 D D) + connect(0 B B) + connect(1 B B) + location(1775 650) + param(L 0.25) + param(W 1.8) + param(AS 0.45) + param(AD 0.81) + param(PS 2.8) + param(PD 5.4) + terminal(S 3) + terminal(G 2) + terminal(D 4) + terminal(B 6) + ) + + ) +) + +# Reference netlist +reference( + + # Device class section + class(PMOS MOS4) + class(NMOS MOS4) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(NAND2_WITH_DIODES + + # Nets + net(1 name(A)) + net(2 name(B)) + net(3 name(OUT)) + net(4 name(VSS)) + net(5 name(VDD)) + net(6 name($1)) + + # Outgoing pins and their connections to nets + pin(1 name(A)) + pin(2 name(B)) + pin(3 name(OUT)) + pin(4 name(VSS)) + pin(5 name(VDD)) + + # 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 5) + terminal(G 2) + terminal(D 3) + terminal(B 5) + ) + 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 5) + terminal(G 1) + terminal(D 3) + terminal(B 5) + ) + device(3 NMOS + name('3') + param(L 0.25) + param(W 1.8) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 4) + terminal(G 2) + terminal(D 6) + terminal(B 4) + ) + device(4 NMOS + name('4') + param(L 0.25) + param(W 1.8) + param(AS 0) + param(AD 0) + param(PS 0) + param(PD 0) + terminal(S 6) + terminal(G 1) + terminal(D 3) + terminal(B 4) + ) + + ) +) + +# Cross reference +xref( + circuit(NAND2_WITH_DIODES NAND2_WITH_DIODES match + xref( + net(3 6 match) + net(2 1 match) + net(1 2 match) + net(4 3 match) + net(5 5 match) + net(6 4 match) + pin(1 0 match) + pin(0 1 match) + pin(2 2 match) + pin(3 4 match) + pin(4 3 match) + device(3 3 match) + device(4 4 match) + device(1 1 match) + device(2 2 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_blackboxing.lvsdb b/testdata/lvs/ringo_simple_blackboxing.lvsdb index 31b71eaba..ac20fdda6 100644 --- a/testdata/lvs/ringo_simple_blackboxing.lvsdb +++ b/testdata/lvs/ringo_simple_blackboxing.lvsdb @@ -516,8 +516,8 @@ xref( net(8 4 match) net(5 3 match) net(7 5 match) - net(6 2 warning) - net(9 1 warning) + net(6 2 match) + net(9 1 match) pin(3 3 match) pin(0 2 match) pin(2 4 match) diff --git a/testdata/lvs/ringo_simple_blackboxing_netter.cir b/testdata/lvs/ringo_simple_blackboxing_netter.cir new file mode 100644 index 000000000..e6a7e5bcc --- /dev/null +++ b/testdata/lvs/ringo_simple_blackboxing_netter.cir @@ -0,0 +1,70 @@ +* Extracted by KLayout + +* cell RINGO +* pin FB +* pin VDD +* pin OUT +* pin ENABLE +* pin VSS +.SUBCKT RINGO 5 6 7 8 9 +* net 5 FB +* net 6 VDD +* net 7 OUT +* net 8 ENABLE +* net 9 VSS +* cell instance $1 r0 *1 1.8,0 +X$1 6 1 9 6 5 8 9 ND2X1 +* cell instance $2 r0 *1 4.2,0 +X$2 6 2 9 6 1 9 INVX1 +* cell instance $3 r0 *1 6,0 +X$3 6 10 9 6 2 9 INVX1 +* cell instance $4 r0 *1 16.8,0 +X$4 6 3 9 6 11 9 INVX1 +* cell instance $5 r0 *1 18.6,0 +X$5 6 4 9 6 3 9 INVX1 +* cell instance $6 r0 *1 20.4,0 +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 +.ENDS RINGO + +* cell INVX2 +* pin IN +* pin VDD +* pin OUT +* pin VSS +* pin +* pin BULK +.SUBCKT INVX2 1 2 3 4 5 6 +.ENDS INVX2 + +* cell INVX1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin IN +* pin BULK +.SUBCKT INVX1 1 2 3 4 5 6 +.ENDS INVX1 + +* cell ND2X1 +* pin VDD +* pin OUT +* pin VSS +* pin +* pin B +* pin A +* pin BULK +.SUBCKT ND2X1 1 2 3 4 5 6 7 +.ENDS ND2X1 diff --git a/testdata/lvs/ringo_simple_blackboxing_netter.lvs b/testdata/lvs/ringo_simple_blackboxing_netter.lvs new file mode 100644 index 000000000..4cbbc0591 --- /dev/null +++ b/testdata/lvs/ringo_simple_blackboxing_netter.lvs @@ -0,0 +1,87 @@ + +source($lvs_test_source, "RINGO") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("ringo_for_blackboxing.cir") + +blank_circuit("INVX1") +blank_circuit("INVX2") +blank_circuit("ND2X1") + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(8, 0) +metal1 = input(9, 0) +via1 = input(10, 0) +metal2 = input(11, 0) + +# Bulk layer for terminal provisioning +# and to provide the BULK labels for +# the abstracts + +bulk = labels(13, 0) + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell & pplus +pgate = pactive & poly +psd = pactive - pgate +ntie = active_in_nwell & nplus + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate +ptie = active_outside_nwell & pplus + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos4("PMOS"), { "SD" => 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.flatten_circuit("INVCHAIN") + +netlist.make_top_level_pins +netlist.purge +netlist.combine_devices +netlist.purge_nets + +consider_net_names(false) + +compare + diff --git a/testdata/lvs/ringo_simple_blackboxing_netter.lvsdb b/testdata/lvs/ringo_simple_blackboxing_netter.lvsdb new file mode 100644 index 000000000..ac20fdda6 --- /dev/null +++ b/testdata/lvs/ringo_simple_blackboxing_netter.lvsdb @@ -0,0 +1,540 @@ +#%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 '13/0') + 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(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) + + # Circuit section + # Circuits are the hierarchical building blocks of the netlist. + circuit(ND2X1 + + # Circuit boundary + rect((-100 250) (2600 7750)) + + # Outgoing pins and their connections to nets + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin() + pin(name(B)) + pin(name(A)) + pin(name(BULK)) + + ) + circuit(INVX1 + + # Circuit boundary + rect((-100 250) (2000 7750)) + + # Outgoing pins and their connections to nets + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin() + pin(name(IN)) + pin(name(BULK)) + + ) + circuit(INVX2 + + # Circuit boundary + rect((-100 250) (2600 7750)) + + # Outgoing pins and their connections to nets + pin(name(IN)) + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin() + pin(name(BULK)) + + ) + circuit(RINGO + + # Circuit boundary + rect((600 250) (25800 7750)) + + # Nets with their geometries + net(1 + rect(l11 (4040 2950) (610 300)) + ) + net(2 + rect(l11 (5550 2950) (900 300)) + ) + net(3 + rect(l11 (18150 2950) (900 300)) + ) + net(4 + rect(l11 (19950 2950) (900 300)) + ) + net(5 name(FB) + rect(l11 (21750 2950) (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)) + ) + 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(l9 (-24850 -1500) (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)) + ) + net(8 name(ENABLE) + rect(l11 (2440 2940) (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(l10 (-24850 -800) (500 1500)) + rect(l10 (22900 -1500) (500 1500)) + ) + net(10 + rect(l11 (7350 2950) (900 300)) + ) + net(11 + rect(l11 (16350 2950) (900 300)) + ) + net(12 + rect(l11 (9150 2950) (900 300)) + ) + net(13 + rect(l11 (10950 2950) (900 300)) + ) + net(14 + rect(l11 (12750 2950) (900 300)) + ) + net(15 + rect(l11 (14550 2950) (900 300)) + ) + + # 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 + + # Outgoing pins and their connections to nets + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin(name(NWELL)) + pin(name(B)) + pin(name(A)) + pin(name(BULK)) + + ) + circuit(INVX1 + + # Outgoing pins and their connections to nets + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin(name(NWELL)) + pin(name(IN)) + pin(name(BULK)) + + ) + circuit(INVX2 + + # Outgoing pins and their connections to nets + pin(name(VDD)) + pin(name(OUT)) + pin(name(VSS)) + pin(name(NWELL)) + pin(name(IN)) + pin(name(BULK)) + + ) + 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( + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(1 1 match) + pin(0 0 match) + pin(2 2 match) + ) + ) + circuit(INVX2 INVX2 match + xref( + pin(4 3 match) + pin(5 5 match) + pin(0 4 match) + pin(2 1 match) + pin(1 0 match) + pin(3 2 match) + ) + ) + circuit(ND2X1 ND2X1 match + xref( + pin(3 3 match) + pin(5 5 match) + pin(4 4 match) + pin(6 6 match) + pin(1 1 match) + pin(0 0 match) + pin(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_net_and_circuit_equivalence.lvsdb.1 b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 index a43d6f458..638555d57 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.1 @@ -881,6 +881,7 @@ xref( 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) diff --git a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 index 04e80f7d8..a2b8e370d 100644 --- a/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 +++ b/testdata/lvs/ringo_simple_net_and_circuit_equivalence.lvsdb.2 @@ -881,6 +881,7 @@ xref( 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) diff --git a/testdata/lvs/ringo_simple_with_tol_early.cir b/testdata/lvs/ringo_simple_with_tol_early.cir new file mode 100644 index 000000000..761afb771 --- /dev/null +++ b/testdata/lvs/ringo_simple_with_tol_early.cir @@ -0,0 +1,83 @@ +* 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 INVX1 +* 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 INVX1 +* 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 INVX1 +* 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 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_simple_with_tol_early.lvs b/testdata/lvs/ringo_simple_with_tol_early.lvs new file mode 100644 index 000000000..7f8fcef72 --- /dev/null +++ b/testdata/lvs/ringo_simple_with_tol_early.lvs @@ -0,0 +1,79 @@ + +source($lvs_test_source, "RINGO") + +report_lvs($lvs_test_target_lvsdb, true) + +target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout") + +schematic("ringo_off_target.cir") + +tolerance("PMOS", "L", 0.001) # absolute +tolerance("PMOS", "W", 0.01, 0.1) # relative + absolute +tolerance("NMOS", "L", :absolute => 0.01) +tolerance("NMOS", "W", :relative => 0.07) + +deep + +# Drawing layers + +nwell = input(1, 0) +active = input(2, 0) +pplus = input(3, 0) +nplus = input(4, 0) +poly = input(5, 0) +contact = input(8, 0) +metal1 = input(9, 0) +via1 = input(10, 0) +metal2 = input(11, 0) + +# Bulk layer for terminal provisioning + +bulk = polygon_layer + +# Computed layers + +active_in_nwell = active & nwell +pactive = active_in_nwell & pplus +pgate = pactive & poly +psd = pactive - pgate +ntie = active_in_nwell & nplus + +active_outside_nwell = active - nwell +nactive = active_outside_nwell & nplus +ngate = nactive & poly +nsd = nactive - ngate +ptie = active_outside_nwell & pplus + +# Device extraction + +# PMOS transistor device extraction +extract_devices(mos4("PMOS"), { "SD" => 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 + +compare + diff --git a/testdata/lvs/ringo_simple_with_tol_early.lvsdb.1 b/testdata/lvs/ringo_simple_with_tol_early.lvsdb.1 new file mode 100644 index 000000000..51c6fe9e2 --- /dev/null +++ b/testdata/lvs/ringo_simple_with_tol_early.lvsdb.1 @@ -0,0 +1,908 @@ +#%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(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l11 (4040 2950) (610 300)) + ) + net(2 + rect(l11 (5550 2950) (900 300)) + ) + net(3 + rect(l11 (7350 2950) (900 300)) + ) + net(4 + rect(l11 (9150 2950) (900 300)) + ) + net(5 + rect(l11 (10950 2950) (900 300)) + ) + net(6 + rect(l11 (12750 2950) (900 300)) + ) + net(7 + rect(l11 (14550 2950) (900 300)) + ) + net(8 + rect(l11 (16350 2950) (900 300)) + ) + net(9 + rect(l11 (18150 2950) (900 300)) + ) + net(10 + rect(l11 (19950 2950) (900 300)) + ) + net(11 name(FB) + rect(l11 (21750 2950) (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)) + ) + 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(l9 (-24850 -1500) (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)) + ) + net(14 name(ENABLE) + rect(l11 (2440 2940) (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(l10 (-24850 -800) (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 INVX1 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 INVX1 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 INVX1 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.251) + param(W 1.6) + 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.26) + param(W 1) + 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(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(2 2 match) + circuit(3 3 match) + circuit(4 4 match) + circuit(5 5 match) + circuit(6 6 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(1 1 match) + ) + ) +) diff --git a/testdata/lvs/ringo_simple_with_tol_early.lvsdb.2 b/testdata/lvs/ringo_simple_with_tol_early.lvsdb.2 new file mode 100644 index 000000000..372bf323d --- /dev/null +++ b/testdata/lvs/ringo_simple_with_tol_early.lvsdb.2 @@ -0,0 +1,908 @@ +#%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(RINGO + + # Circuit boundary + rect((0 350) (25800 7650)) + + # Nets with their geometries + net(1 + rect(l11 (4040 2950) (610 300)) + ) + net(2 + rect(l11 (5550 2950) (900 300)) + ) + net(3 + rect(l11 (7350 2950) (900 300)) + ) + net(4 + rect(l11 (9150 2950) (900 300)) + ) + net(5 + rect(l11 (10950 2950) (900 300)) + ) + net(6 + rect(l11 (12750 2950) (900 300)) + ) + net(7 + rect(l11 (14550 2950) (900 300)) + ) + net(8 + rect(l11 (16350 2950) (900 300)) + ) + net(9 + rect(l11 (18150 2950) (900 300)) + ) + net(10 + rect(l11 (19950 2950) (900 300)) + ) + net(11 name(FB) + rect(l11 (21750 2950) (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)) + ) + 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(l9 (-24850 -1500) (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)) + ) + net(14 name(ENABLE) + rect(l11 (2440 2940) (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(l10 (-24850 -800) (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 INVX1 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 INVX1 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 INVX1 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.251) + param(W 1.6) + 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.26) + param(W 1) + 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(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(2 2 match) + circuit(3 3 match) + circuit(4 4 match) + circuit(5 5 match) + circuit(6 6 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(1 1 match) + ) + ) +) diff --git a/testdata/ruby/dbNetlist.rb b/testdata/ruby/dbNetlist.rb index bb1d34570..392c9a3e8 100644 --- a/testdata/ruby/dbNetlist.rb +++ b/testdata/ruby/dbNetlist.rb @@ -63,6 +63,13 @@ class DBNetlist_TestClass < TestBase assert_equal(nl.circuit_by_cell_index(17).inspect, "nil") assert_equal(nl.circuit_by_name("DOESNOTEXIST").inspect, "nil") + assert_equal(nl.is_case_sensitive?, true) + assert_equal(nl.circuit_by_name("xyz").inspect, "nil") + nl.case_sensitive = false + assert_equal(nl.is_case_sensitive?, false) + assert_equal(nl.circuit_by_name("xyz").name, "XYZ") + nl.case_sensitive = true + cc = RBA::Circuit::new assert_equal(cc.dont_purge, false) cc.dont_purge = true @@ -103,6 +110,11 @@ class DBNetlist_TestClass < TestBase assert_equal(names, [ c.name, cc.name ]) assert_equal(nl.circuits_by_name("X*").collect { |x| x.name }, [ "XYZ" ]) + assert_equal(nl.circuits_by_name("x*").collect { |x| x.name }, []) + nl.case_sensitive = false + assert_equal(nl.circuits_by_name("X*").collect { |x| x.name }, [ "XYZ" ]) + assert_equal(nl.circuits_by_name("x*").collect { |x| x.name }, [ "XYZ" ]) + nl.case_sensitive = true assert_equal(nl.circuits_by_name("???").collect { |x| x.name }, [ "XYZ", "UVW" ]) assert_equal(nl.circuits_by_name("*").collect { |x| x.name }, [ "XYZ", "UVW" ]) assert_equal(nl.circuits_by_name("P*").collect { |x| x.name }, []) @@ -698,7 +710,14 @@ class DBNetlist_TestClass < TestBase assert_equal(c.net_by_cluster_id(17).name, "NET1") assert_equal(c.net_by_cluster_id(42).inspect, "nil") assert_equal(c.net_by_name("NET1").name, "NET1") + assert_equal(c.nets_by_name("NET*").collect(&:name), ["NET1"]) assert_equal(c.net_by_name("DOESNOTEXIST").inspect, "nil") + assert_equal(c.nets_by_name("DOESNOTEXIST").collect(&:name), []) + + assert_equal(c.net_by_name("net1").inspect, "nil") + nl.case_sensitive = false + assert_equal(c.net_by_name("net1").name, "NET1") + nl.case_sensitive = true net2 = c.create_net net2.name = "NET2" @@ -706,6 +725,12 @@ class DBNetlist_TestClass < TestBase names = [] c.each_net { |n| names << n.name } assert_equal(names, [ "NET1", "NET2" ]) + assert_equal(c.nets_by_name("NET*").collect(&:name), ["NET1", "NET2"]) + assert_equal(c.nets_by_name("net*").collect(&:name), []) + nl.case_sensitive = false + assert_equal(c.nets_by_name("NET*").collect(&:name), ["NET1", "NET2"]) + assert_equal(c.nets_by_name("net*").collect(&:name), ["NET1", "NET2"]) + nl.case_sensitive = true assert_equal(net1.pin_count, 0) c.connect_pin(pina1, net1) diff --git a/testdata/ruby/dbNetlistCompare.rb b/testdata/ruby/dbNetlistCompare.rb index 58b3339ca..9fe3b704d 100644 --- a/testdata/ruby/dbNetlistCompare.rb +++ b/testdata/ruby/dbNetlistCompare.rb @@ -333,6 +333,8 @@ END assert_equal(logger.text(), <<"END") begin_circuit INV INV +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_pins $0 $1 @@ -459,6 +461,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets INT $10 net_mismatch IN IN @@ -487,6 +491,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -515,6 +521,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets INT $10 net_mismatch IN IN @@ -545,6 +553,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -574,6 +584,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS match_nets OUT OUT match_nets IN IN match_ambiguous_nets INT $10 @@ -636,17 +648,20 @@ END # NOTE: adding this power hint makes the device class error harder to detect ca = nl1.circuit_by_name("BUF") cb = nl2.circuit_by_name("BUF") - comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD")) - comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS")) + comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD"), false) + comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS"), false) + comp.same_nets(ca.net_by_name("OUT"), cb.net_by_name("OUT"), false) good = comp.compare(nl1, nl2) assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS +match_nets OUT OUT match_nets INT $10 match_nets IN IN net_mismatch INT2 $11 -net_mismatch OUT OUT match_pins $0 $1 match_pins $1 $3 match_pins $2 $0 @@ -666,6 +681,157 @@ END end + def test_6b + + nls1 = <<"END" +circuit BUF ($1=IN,$2=OUT,$3=VDD,$4=VSS); + device PMOS $1 (S=VDD,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $2 (S=VSS,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $4 (S=VSS,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $5 (S=VDD,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=VSS,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOSB $7 (S=VDD,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=VSS,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nls2 = <<"END" +circuit BUF ($1=VDD,$2=IN,$3=VSS,$4=OUT); + device PMOS $1 (S=VDD,G=IN,D=$10) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $2 (S=VDD,G=$10,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=IN,D=$11) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $4 (S=VDD,G=$11,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $5 (S=$10,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=OUT,G=$10,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $7 (S=$11,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=OUT,G=$11,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nl1 = RBA::Netlist::new + nl2 = RBA::Netlist::new + prep_nl(nl1, nls1) + prep_nl(nl2, nls2) + + logger = NetlistCompareTestLogger::new + comp = RBA::NetlistComparer::new(logger) + + # NOTE: adding this power hint makes the device class error harder to detect + ca = nl1.circuit_by_name("BUF") + cb = nl2.circuit_by_name("BUF") + comp.same_nets(ca.net_by_name("VDD"), cb.net_by_name("VDD"), true) + comp.same_nets(ca.net_by_name("VSS"), cb.net_by_name("VSS"), true) + comp.same_nets(ca.net_by_name("OUT"), cb.net_by_name("OUT"), true) + + good = comp.compare(nl1, nl2) + + assert_equal(logger.text, <<"END") +begin_circuit BUF BUF +net_mismatch VDD VDD +match_nets VSS VSS +net_mismatch OUT OUT +match_nets INT $10 +match_nets IN IN +net_mismatch INT2 $11 +match_pins $0 $1 +match_pins $1 $3 +match_pins $2 $0 +match_pins $3 $2 +match_devices $1 $1 +match_devices $3 $2 +match_devices $5 $3 +match_devices_with_different_device_classes $7 $4 +match_devices $2 $5 +match_devices $4 $6 +match_devices $6 $7 +match_devices $8 $8 +end_circuit BUF BUF NOMATCH +END + + assert_equal(good, false) + + end + + def test_6c + + nls1 = <<"END" +circuit BUF ($1=IN,$2=OUT,$3=VDD,$4=VSS); + device PMOS $1 (S=VDD,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $2 (S=VSS,G=IN,D=INT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $4 (S=VSS,G=INT,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $5 (S=VDD,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=VSS,G=IN,D=INT2) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOSB $7 (S=VDD,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=VSS,G=INT2,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nls2 = <<"END" +circuit BUF ($1=VDD,$2=IN,$3=VSS,$4=OUT); + device PMOS $1 (S=VDD,G=IN,D=$10) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $2 (S=VDD,G=$10,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $3 (S=VDD,G=IN,D=$11) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device PMOS $4 (S=VDD,G=$11,D=OUT) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $5 (S=$10,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $6 (S=OUT,G=$10,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOS $7 (S=$11,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); + device NMOSB $8 (S=OUT,G=$11,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5); +end; +END + + nl1 = RBA::Netlist::new + nl2 = RBA::Netlist::new + prep_nl(nl1, nls1) + prep_nl(nl2, nls2) + + logger = NetlistCompareTestLogger::new + comp = RBA::NetlistComparer::new(logger) + + # NOTE: adding this power hint makes the device class error harder to detect + ca = nl1.circuit_by_name("BUF") + cb = nl2.circuit_by_name("BUF") + comp.same_nets(ca, cb, ca.net_by_name("VDD"), cb.net_by_name("VDD"), true) + comp.same_nets(ca, cb, ca.net_by_name("VSS"), nil, false) + comp.same_nets(ca, cb, ca.net_by_name("OUT"), nil, true) + + good = comp.compare(nl1, nl2) + + assert_equal(logger.text, <<"END") +begin_circuit BUF BUF +net_mismatch VDD VDD +match_nets VSS (null) +net_mismatch OUT (null) +match_nets INT $10 +match_nets IN IN +net_mismatch INT2 (null) +net_mismatch (null) VSS +net_mismatch (null) OUT +net_mismatch (null) $11 +match_pins $0 $1 +match_pins $2 $0 +match_pins $1 (null) +match_pins $3 (null) +match_pins (null) $2 +match_pins (null) $3 +match_devices $1 $1 +device_mismatch $3 $2 +device_mismatch $5 $3 +device_mismatch (null) $4 +device_mismatch $6 $5 +device_mismatch $4 $6 +device_mismatch $2 $7 +device_mismatch (null) $8 +device_mismatch $7 (null) +device_mismatch $8 (null) +end_circuit BUF BUF NOMATCH +END + + assert_equal(good, false) + + end + def test_7 nls1 = <<"END" @@ -713,6 +879,8 @@ END assert_equal(logger.text, <<"END") begin_circuit BUF BUF +match_nets VDD VDD +match_nets VSS VSS net_mismatch INT $10 match_nets IN IN net_mismatch INT2 $11