Merge branch 'master' into issue-859

This commit is contained in:
Matthias Koefferlein 2021-07-06 23:45:08 +02:00
commit 9b18571d86
69 changed files with 5942 additions and 227 deletions

View File

@ -112,7 +112,17 @@ InternalAngleEdgePairFilter::InternalAngleEdgePairFilter (double amin, bool incl
bool
InternalAngleEdgePairFilter::selected (const db::EdgePair &edge_pair) const
{
return m_checker (edge_pair.first ().d (), -edge_pair.second ().d ()) != m_inverted;
db::Vector d1 = edge_pair.first ().d ();
db::Vector d2 = edge_pair.second ().d ();
if (db::sprod_sign (d1, d2) < 0) {
d1 = -d1;
}
if (db::vprod_sign (d1, d2) < 0) {
std::swap (d1, d2);
}
return m_checker (d1, d2) != m_inverted;
}
}

View File

@ -776,8 +776,9 @@ public:
{
if (is_for_subcircuit ()) {
const db::SubCircuit *sc = subcircuit_pair ().first;
size_t pin_id = std::numeric_limits<size_t>::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<std::pair<const Net *, const Net *> > empty;
const std::vector<std::pair<const Net *, const Net *> > *net_identity = &empty;
std::map<std::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<const Net *, const Net *> > >::const_iterator sn = m_same_nets.find (std::make_pair (ca, cb));
std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > empty;
const std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > *net_identity = &empty;
std::map<std::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<std::pair<const Net *, const Net *>, 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<size_t> collect_pins_with_empty_nets (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper)
std::vector<size_t> collect_anonymous_empty_pins (const db::Circuit *c, CircuitPinMapper *circuit_pin_mapper)
{
std::vector<size_t> 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<size_t> 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<size_t> 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<std::pair<const Net *, const Net *> > &net_identity,
const std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > &net_identity,
bool &pin_mismatch,
std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping,
std::map<const db::Circuit *, CircuitMapper> &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<std::pair<const Net *, const Net *> >::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<std::pair<std::pair<const Net *, const Net *>, 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<const db::Circuit *, CircuitMapper> 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

View File

@ -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<std::pair<const Net *, const Net *> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &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<std::pair<std::pair<const Net *, const Net *>, bool> > &net_identity, bool &pin_mismatch, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping) const;
bool all_subcircuits_verified (const db::Circuit *c, const std::set<const db::Circuit *> &verified_circuits) const;
std::string generate_subcircuits_not_verified_warning (const db::Circuit *ca, const std::set<const db::Circuit *> &verified_circuits_a, const db::Circuit *cb, const std::set<const db::Circuit *> &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::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<const Net *, const Net *> > > m_same_nets;
std::map<std::pair<const db::Circuit *, const db::Circuit *>, std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > > m_same_nets;
std::unique_ptr<CircuitPinMapper> mp_circuit_pin_mapper;
std::unique_ptr<DeviceCategorizer> mp_device_categorizer;
std::unique_ptr<CircuitCategorizer> mp_circuit_categorizer;

View File

@ -113,6 +113,10 @@ NetlistCrossReference::other_net_for (const db::Net *net) const
const NetlistCrossReference::PerNetData *
NetlistCrossReference::per_net_data_for (const std::pair<const db::Net *, const db::Net *> &nets) const
{
if (! nets.first && ! nets.second) {
return 0;
}
std::map<std::pair<const db::Net *, const db::Net *>, 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<const db::Net
void
NetlistCrossReference::build_per_net_info (const std::pair<const db::Net *, const db::Net *> &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);

View File

@ -724,10 +724,7 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"edge pairs with the given angle are returned. If \"inverse\" is true, "
"edge pairs not with the given angle are returned.\n"
"\n"
"The angle is measured between the two edges. Antiparallel edges have an angle of 0, parallel ones an angle of 180 or -180 degree (whichever fits). "
"For other configurations, the angle is determined by thinking of the edges as emerging from the same point: if the second edge is rotated clockwise "
"against the first one, the angle is positive. If the second edge is rotated counterclockwise, the angle is negative. This way, the same angle "
"definition applies to edges at a corner of a polygon and the same edges appearing in an edge pair.\n"
"The angle is measured between the two edges. It is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).\n"
"\n"
"This method has been added in version 0.27.2.\n"
) +
@ -737,10 +734,7 @@ Class<db::EdgePairs> decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"edge pairs with an angle between min_angle and max_angle (max_angle itself is excluded) are returned. If \"inverse\" is true, "
"edge pairs not fulfilling this criterion are returned.\n"
"\n"
"The angle is measured between the two edges. Antiparallel edges have an angle of 0, parallel ones an angle of 180 or -180 degree (whichever fits). "
"For other configurations, the angle is determined by thinking of the edges as emerging from the same point: if the second edge is rotated clockwise "
"against the first one, the angle is positive. If the second edge is rotated counterclockwise, the angle is negative. This way, the same angle "
"definition applies to edges at a corner of a polygon and the same edges appearing in an edge pair.\n"
"The angle is measured between the two edges. It is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).\n"
"\n"
"With \"include_min_angle\" set to true (the default), the minimum angle is included in the criterion while with false, the "
"minimum angle itself is not included. Same for \"include_max_angle\" where the default is false, meaning the maximum angle is not included in the range.\n"

View File

@ -1391,6 +1391,50 @@ static db::Pin *create_pin (db::Circuit *circuit, const std::string &name)
return & circuit->add_pin (name);
}
static std::vector<db::Net *>
nets_by_name (db::Circuit *circuit, const std::string &name_pattern)
{
std::vector<db::Net *> 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<const db::Net *>
nets_by_name_const (const db::Circuit *circuit, const std::string &name_pattern)
{
std::vector<const db::Net *> 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<db::Circuit> 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"
@ -1504,6 +1548,18 @@ Class<db::Circuit> 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."
@ -1794,8 +1850,13 @@ static std::vector<db::Circuit *>
circuits_by_name (db::Netlist *netlist, const std::string &name_pattern)
{
std::vector<db::Circuit *> 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 ())) {
@ -1810,8 +1871,13 @@ static std::vector<const db::Circuit *>
circuits_by_name_const (const db::Netlist *netlist, const std::string &name_pattern)
{
std::vector<const db::Circuit *> 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 ())) {
@ -1823,6 +1889,14 @@ circuits_by_name_const (const db::Netlist *netlist, const std::string &name_patt
}
Class<db::Netlist> 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. "
@ -1866,7 +1940,7 @@ Class<db::Netlist> 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."

View File

@ -476,13 +476,32 @@ Class<db::NetlistComparer> 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"

View File

@ -24,6 +24,7 @@
#include "tlUnitTest.h"
#include "dbEdgePairs.h"
#include "dbEdgePairFilters.h"
#include "dbEdges.h"
#include "dbRegion.h"
#include "dbTestSupport.h"
@ -160,3 +161,42 @@ TEST(4)
db::Region r (db::RecursiveShapeIterator (ly, ly.cell (top_cell), l1));
EXPECT_EQ (db::compare (r, "(-10,-21;9,20;50,51;91,80);(-10,-21;9,20;110,121;91,80)"), true);
}
TEST(5_InternalAngleFilter)
{
db::EdgePair ep0 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (0, 0)));
db::EdgePair ep45 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, 100)));
db::EdgePair ep180 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, 0)));
db::EdgePair ep90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (0, 100)));
db::EdgePair epm90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 100), db::Point (0, 0)));
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep0), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep180), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (epm90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep45), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep0), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep180), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep90), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (epm90), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep45), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep0), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep180), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (epm90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep0), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep180), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep90), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (epm90), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep45), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep0), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep180), true);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (epm90), false);
EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45), true);
}

View File

@ -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"

View File

@ -330,28 +330,30 @@ module DRC
# %DRC%
# @name with_area
# @brief Selects polygons by area
# @brief Selects polygons or edge pairs by area
# @synopsis layer.with_area(min .. max)
# @synopsis layer.with_area(value)
# @synopsis layer.with_area(min, max)
# The first form will select all polygons with an area larger or
# The first form will select all polygons or edge pairs with an area larger or
# equal to min and less (but not equal to) max. The second form
# will select the polygons with exactly the given area.
# will select the polygons or edge pairs with exactly the given area.
# The third form basically is equivalent to the first form, but
# allows specification of nil for min or max indicating no lower or
# upper limit.
#
# This method is available for polygon or edge pair layers.
# %DRC%
# @name without_area
# @brief Selects polygons by area
# @brief Selects polygons or edge pairs by area
# @synopsis layer.without_area(min .. max)
# @synopsis layer.without_area(value)
# @synopsis layer.without_area(min, max)
# This method is the inverse of "with_area". It will select
# polygons without an area equal to the given one or outside
# polygons or edge pairs without an area equal to the given one or outside
# the given interval.
#
# This method is available for polygon layers only.
# This method is available for polygon or edge pair layers.
%w(area).each do |f|
[true, false].each do |inv|
@ -361,7 +363,8 @@ module DRC
@engine._context("#{mn}") do
requires_region
self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::EdgePairs) || raise("Requires an edge pair or polygon layer")
if args.size == 1
a = args[0]
if a.is_a?(Range)
@ -857,7 +860,7 @@ CODE
# @synopsis layer.with_angle(min .. max)
# @synopsis layer.with_angle(value)
# @synopsis layer.with_angle(min, max)
# @synopsis edge_pairlayer.with_angle(min, max [, both])
# @synopsis edge_pair_layer.with_angle(min, max [, both])
#
# When called on an edge layer, the method selects edges by their angle,
# measured against the horizontal axis in the mathematical sense.
@ -871,10 +874,6 @@ CODE
# The second version selects edges with exactly the given angle. The third
# version is identical to the first one.
#
# When called on a polygon layer, this method selects corners which match the
# given angle or is within the given angle interval. The angle is measured between the edges forming the corner.
# For each corner, an edge pair containing the edges forming in the angle is returned.
#
# When called on an edge pair layer, this method selects edge pairs with one or both edges
# meeting the angle criterion. In this case an additional argument is accepted which can be
# either "both" (plain word) to indicate that both edges have to be within the given interval.
@ -903,6 +902,9 @@ CODE
# @td @img(/images/drc_with_angle4.png) @/td
# @/tr
# @/table
#
# Note that in former versions, with_angle could be used on polygon layers selecting corners with specific angles.
# This feature has been deprecated. Use \corners instead.
# %DRC%
# @name without_angle
@ -910,11 +912,12 @@ CODE
# @synopsis layer.without_angle(min .. max)
# @synopsis layer.without_angle(value)
# @synopsis layer.without_angle(min, max)
# @synopsis edge_pairlayer.without_angle(min, max [, both])
# @synopsis edge_pair_layer.without_angle(min, max [, both])
#
# The method basically is the inverse of \with_angle. It selects all edges
# of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle
# is not inside the given interval (first and third form).
# is not inside the given interval (first and third form). When called on edge pairs, it selects
# edge pairs by the angles of their edges.
#
# A note on the "both" modifier (without_angle called on edge pairs): "both" means that
# both edges need to be "without_angle". For example
@ -925,8 +928,41 @@ CODE
# ep = edge_pairs.without_angle(0, both)
# @/code
#
# See \with_internal_angle and \without_internal_angle to select edge pairs by the
# angle between the edges.
%w(angle).each do |f|
# %DRC%
# @name with_internal_angle
# @brief Selects edge pairs by their internal angle
# @synopsis edge_pair_layer.with_internal_angle(min .. max)
# @synopsis edge_pair_layer.with_internal_angle(value)
# @synopsis edge_pair_layer.with_internal_angle(min, max)
#
# This method selects edge pairs by the angle enclosed by their edges.
# The angle is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).
# If an interval or two values are given, the angle is checked to be within the given
# range.
#
# Here are examples for "with_internal_angle" on edge pair layers:
#
# @code
# # selects edge pairs with parallel edges
# ep1 = edge_pairs.with_internal_angle(0)
# # selects edge pairs with perpendicular edges
# ep2 = edge_pairs.with_internal_angle(90)
# @/code
# %DRC%
# @name without_internal_angle
# @brief Selects edge pairs by their internal angle
# @synopsis edge_pair_layer.without_internal_angle(min .. max)
# @synopsis edge_pair_layer.without_internal_angle(value)
# @synopsis edge_pair_layer.without_internal_angle(min, max)
#
# The method basically is the inverse of \with_internal_angle. It selects all
# edge pairs by the angle enclosed by their edges, applying the opposite criterion than \with_internal_angle.
%w(angle internal_angle).each do |f|
[true, false].each do |inv|
mn = (inv ? "without" : "with") + "_" + f
eval <<"CODE"
@ -935,16 +971,22 @@ CODE
@engine._context("#{mn}") do
f = :with_#{f}
args = args.select do |a|
if a.is_a?(DRCBothEdges)
if !self.data.is_a?(RBA::EdgePairs)
raise("'both' keyword only available for edge pair layers")
if "#{f}" == "angle"
self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::Edges) || self.data.is_a?(RBA::EdgePairs) || raise("Requires an edge, edge pair or polygon layer")
args = args.select do |a|
if a.is_a?(DRCBothEdges)
if !self.data.is_a?(RBA::EdgePairs)
raise("'both' keyword only available for edge pair layers")
end
f = :with_#{f}_both
false
else
true
end
f = :with_#{f}_both
false
else
true
end
else
requires_edge_pairs
end
result_class = self.data.is_a?(RBA::Edges) ? RBA::Edges : RBA::EdgePairs

View File

@ -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
@ -244,10 +242,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
@ -282,11 +278,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
@ -343,11 +338,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
@ -568,30 +562,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

View File

@ -1283,12 +1283,12 @@ TEST(48d_drcWithFragments)
run_test (_this, "48", true);
}
TEST(49_drcWithFragments)
TEST(49_epAngle)
{
run_test (_this, "49", false);
}
TEST(49d_drcWithFragments)
TEST(49d_epAngle)
{
run_test (_this, "49", true);
}
@ -1298,3 +1298,8 @@ TEST(50_issue826)
run_test (_this, "50", false);
}
TEST(51_epInternalAngle)
{
run_test (_this, "51", false);
}

View File

@ -156,6 +156,7 @@ msvc {
win32 {
QMAKE_LFLAGS += -Wl,--exclude-all-symbols
QMAKE_CXXFLAGS += -fdeclspec
} else {
QMAKE_CXXFLAGS += -fvisibility=hidden
}

View File

@ -3157,7 +3157,7 @@ Shielding is enabled by default, but can be switched off with the "transparent"
<li><tt>layer.with_angle(min .. max)</tt></li>
<li><tt>layer.with_angle(value)</tt></li>
<li><tt>layer.with_angle(min, max)</tt></li>
<li><tt>edge_pairlayer.with_angle(min, max [, both])</tt></li>
<li><tt>edge_pair_layer.with_angle(min, max [, both])</tt></li>
</ul>
<p>
When called on an edge layer, the method selects edges by their angle,
@ -3172,10 +3172,6 @@ edges with a angle larger or equal to min and less than max (but not equal).
The second version selects edges with exactly the given angle. The third
version is identical to the first one.
</p><p>
When called on a polygon layer, this method selects corners which match the
given angle or is within the given angle interval. The angle is measured between the edges forming the corner.
For each corner, an edge pair containing the edges forming in the angle is returned.
</p><p>
When called on an edge pair layer, this method selects edge pairs with one or both edges
meeting the angle criterion. In this case an additional argument is accepted which can be
either "both" (plain word) to indicate that both edges have to be within the given interval.
@ -3204,8 +3200,11 @@ The following images demonstrate some use cases of <a href="#with_angle">with_an
<td><img src="/images/drc_with_angle4.png"/></td>
</tr>
</table>
</p><p>
Note that in former versions, with_angle could be used on polygon layers selecting corners with specific angles.
This feature has been deprecated. Use <a href="#corners">corners</a> instead.
</p>
<a name="with_area"/><h2>"with_area" - Selects polygons by area</h2>
<a name="with_area"/><h2>"with_area" - Selects polygons or edge pairs by area</h2>
<keyword name="with_area"/>
<p>Usage:</p>
<ul>
@ -3214,12 +3213,14 @@ The following images demonstrate some use cases of <a href="#with_angle">with_an
<li><tt>layer.with_area(min, max)</tt></li>
</ul>
<p>
The first form will select all polygons with an area larger or
The first form will select all polygons or edge pairs with an area larger or
equal to min and less (but not equal to) max. The second form
will select the polygons with exactly the given area.
will select the polygons or edge pairs with exactly the given area.
The third form basically is equivalent to the first form, but
allows specification of nil for min or max indicating no lower or
upper limit.
</p><p>
This method is available for polygon or edge pair layers.
</p>
<a name="with_area_ratio"/><h2>"with_area_ratio" - Selects polygons by the ratio of the bounding box area vs. polygon area</h2>
<keyword name="with_area_ratio"/>
@ -3430,6 +3431,29 @@ This method is available for edge pair layers only.
This method is available for polygon layers. It will select all polygons from the input layer
which have the specified number of holes.
</p>
<a name="with_internal_angle"/><h2>"with_internal_angle" - Selects edge pairs by their internal angle</h2>
<keyword name="with_internal_angle"/>
<p>Usage:</p>
<ul>
<li><tt>edge_pair_layer.with_internal_angle(min .. max)</tt></li>
<li><tt>edge_pair_layer.with_internal_angle(value)</tt></li>
<li><tt>edge_pair_layer.with_internal_angle(min, max)</tt></li>
</ul>
<p>
This method selects edge pairs by the angle enclosed by their edges.
The angle is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).
If an interval or two values are given, the angle is checked to be within the given
range.
</p><p>
Here are examples for "with_internal_angle" on edge pair layers:
</p><p>
<pre>
# selects edge pairs with parallel edges
ep1 = edge_pairs.with_internal_angle(0)
# selects edge pairs with perpendicular edges
ep2 = edge_pairs.with_internal_angle(90)
</pre>
</p>
<a name="with_length"/><h2>"with_length" - Selects edges by their length</h2>
<keyword name="with_length"/>
<p>Usage:</p>
@ -3505,12 +3529,13 @@ This method is available for polygon layers only.
<li><tt>layer.without_angle(min .. max)</tt></li>
<li><tt>layer.without_angle(value)</tt></li>
<li><tt>layer.without_angle(min, max)</tt></li>
<li><tt>edge_pairlayer.without_angle(min, max [, both])</tt></li>
<li><tt>edge_pair_layer.without_angle(min, max [, both])</tt></li>
</ul>
<p>
The method basically is the inverse of <a href="#with_angle">with_angle</a>. It selects all edges
of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle
is not inside the given interval (first and third form).
is not inside the given interval (first and third form). When called on edge pairs, it selects
edge pairs by the angles of their edges.
</p><p>
A note on the "both" modifier (without_angle called on edge pairs): "both" means that
both edges need to be "without_angle". For example
@ -3520,8 +3545,11 @@ both edges need to be "without_angle". For example
# the edge pair is skipped if one edge is horizontal
ep = edge_pairs.without_angle(0, both)
</pre>
</p><p>
See <a href="#with_internal_angle">with_internal_angle</a> and <a href="#without_internal_angle">without_internal_angle</a> to select edge pairs by the
angle between the edges.
</p>
<a name="without_area"/><h2>"without_area" - Selects polygons by area</h2>
<a name="without_area"/><h2>"without_area" - Selects polygons or edge pairs by area</h2>
<keyword name="without_area"/>
<p>Usage:</p>
<ul>
@ -3531,10 +3559,10 @@ ep = edge_pairs.without_angle(0, both)
</ul>
<p>
This method is the inverse of "with_area". It will select
polygons without an area equal to the given one or outside
polygons or edge pairs without an area equal to the given one or outside
the given interval.
</p><p>
This method is available for polygon layers only.
This method is available for polygon or edge pair layers.
</p>
<a name="without_area_ratio"/><h2>"without_area_ratio" - Selects polygons by the aspect ratio of their bounding box</h2>
<keyword name="without_area_ratio"/>
@ -3647,6 +3675,18 @@ This method is available for edge pair layers only.
This method is available for polygon layers. It will select all polygons from the input layer
which do not have the specified number of holes.
</p>
<a name="without_internal_angle"/><h2>"without_internal_angle" - Selects edge pairs by their internal angle</h2>
<keyword name="without_internal_angle"/>
<p>Usage:</p>
<ul>
<li><tt>edge_pair_layer.without_internal_angle(min .. max)</tt></li>
<li><tt>edge_pair_layer.without_internal_angle(value)</tt></li>
<li><tt>edge_pair_layer.without_internal_angle(min, max)</tt></li>
</ul>
<p>
The method basically is the inverse of <a href="#with_internal_angle">with_internal_angle</a>. It selects all
edge pairs by the angle enclosed by their edges, applying the opposite criterion than <a href="#with_internal_angle">with_internal_angle</a>.
</p>
<a name="without_length"/><h2>"without_length" - Selects edges by the their length</h2>
<keyword name="without_length"/>
<p>Usage:</p>

View File

@ -28,6 +28,15 @@ For more details about the DRC functions see <a href="/about/drc_ref_global.xml"
<p>
See <a href="/about/lvs_ref_netter.xml#align">Netter#align</a> for a description of that function.
</p>
<a name="blank_circuit"/><h2>"blank_circuit" - Removes the content from the given circuits (blackboxing)</h2>
<keyword name="blank_circuit"/>
<p>Usage:</p>
<ul>
<li><tt>blank_circuit(circuit_filter)</tt></li>
</ul>
<p>
See <a href="/about/lvs_ref_netter.xml#blank_circuit">Netter#blank_circuit</a> for a description of that function.
</p>
<a name="compare"/><h2>"compare" - Compares the extracted netlist vs. the schematic</h2>
<keyword name="compare"/>
<p>Usage:</p>
@ -152,12 +161,24 @@ See <a href="/about/lvs_ref_netter.xml#same_device_classes">Netter#same_device_c
<keyword name="same_nets"/>
<p>Usage:</p>
<ul>
<li><tt>same_nets(circuit, net_a, net_b)</tt></li>
<li><tt>same_nets(circuit_pattern, net_pattern)</tt></li>
<li><tt>same_nets(circuit_pattern, net_a, net_b)</tt></li>
<li><tt>same_nets(circuit_a, net_a, circuit_b, net_b)</tt></li>
</ul>
<p>
See <a href="/about/lvs_ref_netter.xml#same_nets">Netter#same_nets</a> for a description of that function.
</p>
<a name="same_nets!"/><h2>"same_nets!" - Establishes an equivalence between the nets (must match)</h2>
<keyword name="same_nets!"/>
<p>Usage:</p>
<ul>
<li><tt>same_nets!(circuit_pattern, net_pattern)</tt></li>
<li><tt>same_nets!(circuit_pattern, net_a, net_b)</tt></li>
<li><tt>same_nets!(circuit_a, net_a, circuit_b, net_b)</tt></li>
</ul>
<p>
See <a href="/about/lvs_ref_netter.xml#same_nets">Netter#same_nets</a>! for a description of that function.
</p>
<a name="schematic"/><h2>"schematic" - Reads the reference netlist</h2>
<keyword name="schematic"/>
<p>Usage:</p>

View File

@ -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.
</p>
<a name="blank_circuit"/><h2>"blank_circuit" - Removes the content from the given circuits (blackboxing)</h2>
<keyword name="blank_circuit"/>
<p>Usage:</p>
<ul>
<li><tt>blank_circuit(circuit_filter)</tt></li>
</ul>
<p>
This method will erase all content from the circuits matching the filter.
The filter is a glob expression.
</p><p>
This has the following effects:
</p><p>
<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>
</p><p>
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.
</p><p>
Example:
</p><p>
<pre>
# skips all MEMORY* circuits from compare
blank_circuit("MEMORY*")
</pre>
</p>
<a name="compare"/><h2>"compare" - Compares the extracted netlist vs. the schematic</h2>
<keyword name="compare"/>
<p>Usage:</p>
@ -289,7 +319,8 @@ Use this method andwhere in the script before the <a href="#compare">compare</a>
<keyword name="same_nets"/>
<p>Usage:</p>
<ul>
<li><tt>same_nets(circuit, net_a, net_b)</tt></li>
<li><tt>same_nets(circuit_pattern, net_pattern)</tt></li>
<li><tt>same_nets(circuit_pattern, net_a, net_b)</tt></li>
<li><tt>same_nets(circuit_a, net_a, circuit_b, net_b)</tt></li>
</ul>
<p>
@ -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).
</p><p>
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.
</p><p>
"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":
</p><p>
<pre>
same_nets("INV*", "A*")
</pre>
</p><p>
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
</p><p>
Use this method andwhere in the script before the <a href="#compare">compare</a> call.
</p>
<a name="same_nets!"/><h2>"same_nets!" - Establishes an equivalence between the nets with matching requirement</h2>
<keyword name="same_nets!"/>
<p>Usage:</p>
<ul>
<li><tt>same_nets!(circuit_pattern, net_pattern)</tt></li>
<li><tt>same_nets!(circuit_pattern, net_a, net_b)</tt></li>
<li><tt>same_nets!(circuit_a, net_a, circuit_b, net_b)</tt></li>
</ul>
<p>
This method is equivalent to <a href="#same_nets">same_nets</a>, but requires identity of the given nets.
If the specified nets do not match, an error is reported.
</p>
<a name="schematic"/><h2>"schematic" - Gets, sets or reads the reference netlist</h2>
<keyword name="schematic"/>
<p>Usage:</p>

View File

@ -52,7 +52,44 @@
</p>
<p>
For more information about "same_nets" see <a href="/about/lvs_ref_global.xml#same_nets">same_nets</a>.
"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:
</p>
<pre>same_nets!("CHIP", "VDD", "VDD")</pre>
<p>
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:
</p>
<pre>same_nets!("CHIP", "VDD")</pre>
<p>
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:
</p>
<pre>same_nets!("TOP", "PAD*")</pre>
<p>
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.
</p>
<p>
"same_nets" and "same_nets!" can appear anywhere in the LVS script.
</p>
<p>
For more information about "same_nets" see <a href="/about/lvs_ref_global.xml#same_nets">same_nets</a> and
<a href="/about/lvs_ref_global.xml#same_nets!">same_nets!</a>.
</p>
<h2>Circuit equivalence hint</h2>

View File

@ -153,10 +153,11 @@
<p>
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.
</p>
<p>
@ -166,14 +167,20 @@
<pre>netlist.blank_circuit("CIRCUIT_NAME")
schematic.blank_circuit("CIRCUIT_NAME")</pre>
<p><b>NOTE:</b> In this version, use "blank_circuit" before "purge" or "simplify" (see below). "blank_circuit"
sets a flag (<class_doc href="Circuit#dont_purge"/>) which prevents purging of abstract circuits.</p>
<p>
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 (<a href="/about/lvs_ref_netter.xml#blank_circuit">blank_circuit</a>).
In contrast to netlist-based "blank_circuit", this method can be used anywhere in the LVS script:
</p>
<p><b>NOTE:</b> Use "blank_circuit" before "purge" or "simplify" (see below). This method
sets a flag (<class_doc href="Circuit#dont_purge"/>) which prevents purging of abstract
circuits.</p>
<pre>blank_circuit("CIRCUIT_NAME")</pre>
<p>
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".
</p>
<h2>Joining of symmetric nodes</h2>
@ -201,8 +208,8 @@ schematic.blank_circuit("CIRCUIT_NAME")</pre>
</p>
<p>
KLayout provides a feature which will add such connections after extraction
of the netlist:
KLayout provides a feature (<a href="/about/lvs_ref_netter.xml#join_symmetric_nets">join_symmetric_nets</a>)
which will add such connections after extraction of the netlist:
</p>
<pre>join_symmetric_nets("NAND2")</pre>
@ -221,6 +228,10 @@ schematic.blank_circuit("CIRCUIT_NAME")</pre>
need it.
</p>
<p>
"join_symmetric_nets" can be used anywhere in the LVS script.
</p>
<h2>Purging (elimination of redundancy)</h2>
<p>

View File

@ -234,11 +234,11 @@ static QString escaped (const std::string &s)
}
template <class Obj>
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 ();
@ -246,11 +246,11 @@ static std::string str_from_expanded_name (const Obj *obj, bool dash_for_empty =
}
template <class Obj>
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 ();
@ -265,7 +265,7 @@ static std::string str_from_expanded_names (const std::pair<const Obj *, const O
std::string s = str_from_expanded_name (objs.first, ! is_single);
if (! is_single) {
std::string t = str_from_expanded_name (objs.second, ! is_single);
if (t != s) {
if (t != s || ! objs.first || ! objs.second) {
s += var_sep;
s += t;
}
@ -279,7 +279,7 @@ static std::string str_from_names (const std::pair<const Obj *, const Obj *> &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;
}

View File

@ -1192,6 +1192,7 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma
while (! shapes.at_end ()) {
if (shapes->type () != db::NetShape::Polygon) {
++shapes;
continue;
}

View File

@ -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)

View File

@ -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%

View File

@ -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,7 +226,15 @@ TEST(24_issue806)
run_test (_this, "custom_compare", "custom_compare.gds");
}
TEST(25_enableWandL)
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");
TEST(26_enableWandL)
{
run_test (_this, "enable_wl1", "resistor.gds");
run_test (_this, "enable_wl2", "resistor.gds");

View File

@ -224,7 +224,7 @@ object_to_ruby (void *obj, Proxy *self, const gsi::ClassBase *cls, bool pass_obj
// a Ruby object. If it already has, we simply return a reference to this.
ret = rba_data->self ();
#if HAVE_RUBY_VERSION_CODE >= 20200
#if HAVE_RUBY_VERSION_CODE >= 20200 && HAVE_RUBY_VERSION_CODE < 30000
// Mark the returned object - the original one may have been already
// scheduled for sweeping. This happens at least for Ruby 2.3 which
// has a two-phase GC (mark and sweep in separate steps). If by chance

26
testdata/drc/drcSimpleTests_51.drc vendored Normal file
View File

@ -0,0 +1,26 @@
source $drc_test_source
target $drc_test_target
if $drc_test_deep
deep
end
ep = input(1, 0).drc(sep(input(2, 0), angle_limit(91)) < 0.5)
input(1, 0).output(1, 0)
input(2, 0).output(2, 0)
ep.polygons(0).output(100, 0)
ep.with_internal_angle(45.0).polygons(0).output(200, 0)
ep.with_internal_angle(0.0).polygons(0).output(201, 0)
ep.with_internal_angle(45.0..91.0).polygons(0).output(202, 0)
ep.without_internal_angle(45.0).polygons(0).output(220, 0)
ep.without_internal_angle(0.0).polygons(0).output(221, 0)
ep.without_internal_angle(45.0..91.0).polygons(0).output(222, 0)
ep.with_area(0 .. 0.1).polygons(0).output(300, 0)
ep.without_area(0 .. 0.1).polygons(0).output(301, 0)

BIN
testdata/drc/drcSimpleTests_51.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au51.gds vendored Normal file

Binary file not shown.

View File

@ -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

BIN
testdata/lvs/blackbox.gds vendored Normal file

Binary file not shown.

27
testdata/lvs/blackbox1.cir vendored Normal file
View File

@ -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

22
testdata/lvs/blackbox1.lvs vendored Normal file
View File

@ -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

196
testdata/lvs/blackbox1.lvsdb vendored Normal file
View File

@ -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)
)
)
)

27
testdata/lvs/blackbox2.cir vendored Normal file
View File

@ -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

22
testdata/lvs/blackbox2.lvs vendored Normal file
View File

@ -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

196
testdata/lvs/blackbox2.lvsdb vendored Normal file
View File

@ -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)
)
)
)

27
testdata/lvs/blackbox3.cir vendored Normal file
View File

@ -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

22
testdata/lvs/blackbox3.lvs vendored Normal file
View File

@ -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

200
testdata/lvs/blackbox3.lvsdb vendored Normal file
View File

@ -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)
)
)
)

26
testdata/lvs/blackbox4.cir vendored Normal file
View File

@ -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

22
testdata/lvs/blackbox4.lvs vendored Normal file
View File

@ -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

196
testdata/lvs/blackbox4.lvsdb vendored Normal file
View File

@ -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)
)
)
)

26
testdata/lvs/blackbox5.cir vendored Normal file
View File

@ -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

22
testdata/lvs/blackbox5.lvs vendored Normal file
View File

@ -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

200
testdata/lvs/blackbox5.lvsdb vendored Normal file
View File

@ -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)
)
)
)

BIN
testdata/lvs/blackbox_open.gds vendored Normal file

Binary file not shown.

9
testdata/lvs/blackbox_schematic.cir vendored Normal file
View File

@ -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

BIN
testdata/lvs/blackbox_short.gds vendored Normal file

Binary file not shown.

BIN
testdata/lvs/blackbox_short_and_open.gds vendored Normal file

Binary file not shown.

BIN
testdata/lvs/blackbox_swapped.gds vendored Normal file

Binary file not shown.

View File

@ -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)
)

View File

@ -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

View File

@ -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

85
testdata/lvs/nand2_split_gate_early.lvs vendored Normal file
View File

@ -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

View File

@ -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)
)
)
)

View File

@ -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)
)
)
)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)
)
)
)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)
)
)
)

View File

@ -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)
)
)
)

View File

@ -894,8 +894,10 @@ class Basic_TestClass < TestBase
end
# TODO: this class is going to be deprecated
class X < Data
if RUBY_VERSION < "3.0.0"
# TODO: this class is going to be deprecated
class X < Data
end
end
class Y < Object
end
@ -907,12 +909,14 @@ class Basic_TestClass < TestBase
end
# Test, if this throws an error (object of class X passed to A argument):
begin
b = RBA::B.new
assert_equal( b.b4( X.new ), "b4_result: -6" )
assert_equal( false, true ) # this must never hit
rescue
assert_equal( $!.to_s(), "allocator undefined for Basic_TestClass::X" );
if RUBY_VERSION < "3.0.0"
begin
b = RBA::B.new
assert_equal( b.b4( X.new ), "b4_result: -6" )
assert_equal( false, true ) # this must never hit
rescue
assert_equal( $!.to_s(), "allocator undefined for Basic_TestClass::X" );
end
end
# Test, if this throws an error (object of class X passed to A argument):

View File

@ -268,13 +268,9 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_area(150, 150, false).to_s, "")
assert_equal(r1.with_area(150, 151, true).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,20)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(0, 0, false).to_s, "")
assert_equal(r1.with_internal_angle(0, 180, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,20)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(0, 180, false, true, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(180, false).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(-180, false).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(0, true).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(0, true).to_s, "")
ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 20, 10, 0))
ep2 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(20, 0, 30, 0))
@ -286,8 +282,8 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_distance(20, true).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(90, false).to_s, "(0,0;0,10)/(20,0;30,0)")
assert_equal(r1.with_internal_angle(-90, false).to_s, "(0,0;0,10)/(-20,0;-30,0)")
assert_equal(r1.with_internal_angle(90, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
assert_equal(r1.with_internal_angle(-90, false).to_s, "")
assert_equal(r1.with_angle(90, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
assert_equal(r1.with_angle(0, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
@ -295,6 +291,18 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_angle_both(90, false).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_angle_both(0, false).to_s, "")
ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 20, 10, 0))
ep2 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(20, 10, 30, 0))
r1 = RBA::EdgePairs::new([ ep1, ep2 ])
assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(90, false).to_s, "")
assert_equal(r1.with_internal_angle(90, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,10;30,0)")
assert_equal(r1.with_internal_angle(45, false).to_s, "(0,0;0,10)/(20,10;30,0)")
assert_equal(r1.with_internal_angle(0, 45, false, true, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,10;30,0)")
assert_equal(r1.with_internal_angle(0, 45, true, true, true).to_s, "")
end
end

View File

@ -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 }, [])
@ -700,7 +712,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"
@ -708,6 +727,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)

View File

@ -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