mirror of https://github.com/KLayout/klayout.git
Merge pull request #1720 from KLayout/bugfix/issue-1719
Bugfix/issue 1719
This commit is contained in:
commit
7b2a248484
|
|
@ -2817,6 +2817,18 @@ private:
|
|||
std::map<size_t, entry_list::iterator> m_global_net_to_entries;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_for_nets
|
||||
{
|
||||
static bool value () { return false; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_for_nets<db::NetShape>
|
||||
{
|
||||
static bool value () { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
|
@ -2903,11 +2915,34 @@ hier_clusters<T>::build_hier_connections (cell_clusters_box_converter<T> &cbc, c
|
|||
}
|
||||
|
||||
bs2.process (*rec, 1 /*touching*/, local_cluster_box_convert<T> (), cibc);
|
||||
|
||||
}
|
||||
|
||||
// join local clusters which got connected by child clusters
|
||||
rec->finish_cluster_to_instance_interactions ();
|
||||
|
||||
if (is_for_nets<T>::value ()) {
|
||||
|
||||
// remove empty or point-like clusters which do not make a downward connection - i.e. from stray texts.
|
||||
// This implies, we cannot connect from upward down to such nets too. In other words: to force a pin,
|
||||
// inside a cell we need more than a text.
|
||||
// (issue #1719, part 2)
|
||||
std::vector<typename local_cluster<T>::id_type> to_delete;
|
||||
for (typename connected_clusters<T>::const_iterator c = local.begin (); c != local.end (); ++c) {
|
||||
box_type bbox = c->bbox ();
|
||||
if ((bbox.empty () || (bbox.width () == 0 && bbox.height () == 0)) && c->get_global_nets ().empty () && local.connections_for_cluster (c->id ()).empty ()) {
|
||||
to_delete.push_back (c->id ());
|
||||
}
|
||||
}
|
||||
for (auto i = to_delete.begin (); i != to_delete.end (); ++i) {
|
||||
local.remove_cluster (*i);
|
||||
}
|
||||
if (tl::verbosity () >= m_base_verbosity + 20) {
|
||||
tl::info << "Removed " << to_delete.size () << " clusters because they are point-like or empty and do not have connections downward (stray texts)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (tl::verbosity () >= m_base_verbosity + 20) {
|
||||
tl::info << "Cluster build cache statistics (instance to shape cache): size=" << rec->cluster_cache_size () << ", hits=" << rec->cluster_cache_hits () << ", misses=" << rec->cluster_cache_misses ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -508,12 +508,37 @@ void LayoutToNetlist::do_join_nets (db::Circuit &c, const std::vector<db::Net *>
|
|||
return;
|
||||
}
|
||||
|
||||
check_must_connect (c, nets);
|
||||
|
||||
for (auto n = nets.begin () + 1; n != nets.end (); ++n) {
|
||||
check_must_connect (c, *nets [0], **n);
|
||||
c.join_nets (nets [0], *n);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutToNetlist::check_must_connect (const db::Circuit &c, const std::vector<db::Net *> &nets)
|
||||
{
|
||||
std::vector<const db::Net *> unique_nets;
|
||||
unique_nets.reserve (nets.size ());
|
||||
std::set<const db::Net *> seen;
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
if (seen.find (*n) == seen.end ()) {
|
||||
seen.insert (*n);
|
||||
unique_nets.push_back (*n);
|
||||
}
|
||||
}
|
||||
if (unique_nets.size () < size_t (2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool same_names = true;
|
||||
for (auto n = unique_nets.begin () + 1; n != unique_nets.end () && same_names; ++n) {
|
||||
same_names = (unique_nets.front ()->expanded_name () == (*n)->expanded_name ());
|
||||
}
|
||||
|
||||
std::vector<const db::SubCircuit *> path;
|
||||
check_must_connect_impl (c, unique_nets, c, unique_nets, path, same_names);
|
||||
}
|
||||
|
||||
static std::string subcircuit_to_string (const db::SubCircuit &sc)
|
||||
{
|
||||
if (! sc.name ().empty ()) {
|
||||
|
|
@ -533,14 +558,31 @@ static db::DPolygon subcircuit_geometry (const db::SubCircuit &sc, const db::Lay
|
|||
return db::DPolygon (sc.trans () * dbox);
|
||||
}
|
||||
|
||||
void LayoutToNetlist::check_must_connect (const db::Circuit &c, const db::Net &a, const db::Net &b)
|
||||
static db::DBox net_geometry_box (const db::Circuit &c, const db::Net *net, const db::Layout *layout, const db::hier_clusters<db::NetShape> &net_clusters)
|
||||
{
|
||||
if (&a == &b) {
|
||||
return;
|
||||
if (! layout || ! net) {
|
||||
return db::DBox ();
|
||||
}
|
||||
|
||||
std::vector<const db::SubCircuit *> path;
|
||||
check_must_connect_impl (c, a, b, c, a, b, path);
|
||||
auto nc = net_clusters.clusters_per_cell (c.cell_index ());
|
||||
auto lc = nc.cluster_by_id (net->cluster_id ());
|
||||
|
||||
return db::CplxTrans (layout->dbu ()) * lc.bbox ();
|
||||
}
|
||||
|
||||
static db::DPolygon net_geometry (const db::Circuit &c, const db::Net *net, const db::Layout *layout, const db::hier_clusters<db::NetShape> &net_clusters)
|
||||
{
|
||||
auto box = net_geometry_box (c, net, layout, net_clusters);
|
||||
return box.empty () ? db::DPolygon () : db::DPolygon (box);
|
||||
}
|
||||
|
||||
static db::DPolygon net_geometry (const db::Circuit &c, const std::vector<const db::Net *> &nets, const db::Layout *layout, const db::hier_clusters<db::NetShape> &net_clusters)
|
||||
{
|
||||
db::DBox box;
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
box += net_geometry_box (c, *n, layout, net_clusters);
|
||||
}
|
||||
return box.empty () ? db::DPolygon () : db::DPolygon (box);
|
||||
}
|
||||
|
||||
static std::string path_msg (const std::vector<const db::SubCircuit *> &path)
|
||||
|
|
@ -562,46 +604,98 @@ static std::string path_msg (const std::vector<const db::SubCircuit *> &path)
|
|||
return msg;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::check_must_connect_impl (const db::Circuit &c, const db::Net &a, const db::Net &b, const db::Circuit &c_org, const db::Net &a_org, const db::Net &b_org, std::vector<const db::SubCircuit *> &path)
|
||||
static bool all_nets_are_same (const std::vector<const db::Net *> &nets)
|
||||
{
|
||||
for (auto n = nets.begin () + 1; n != nets.end (); ++n) {
|
||||
if (*n != nets.front ()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool no_pins_on_any_net (const std::vector<const db::Net *> &nets)
|
||||
{
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
if ((*n)->begin_pins () == (*n)->end_pins ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string net_names_msg (const std::vector<const db::Net *> &nets)
|
||||
{
|
||||
std::set<std::string> names;
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
names.insert ((*n)->expanded_name ());
|
||||
}
|
||||
|
||||
std::string msg;
|
||||
size_t num = names.size ();
|
||||
size_t i = 0;
|
||||
for (auto n = names.begin (); n != names.end (); ++n, ++i) {
|
||||
if (i > 0) {
|
||||
if (i + 1 < num) {
|
||||
msg += ", ";
|
||||
} else {
|
||||
msg += tl::to_string (tr (" and "));
|
||||
}
|
||||
}
|
||||
msg += *n;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::check_must_connect_impl (const db::Circuit &c, const std::vector<const db::Net *> &nets, const db::Circuit &c_org, const std::vector<const db::Net *> &nets_org, std::vector<const db::SubCircuit *> &path, bool same_names)
|
||||
{
|
||||
if (c.begin_refs () != c.end_refs () && path.empty ()) {
|
||||
|
||||
if (a.begin_pins () == a.end_pins ()) {
|
||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a_org.expanded_name ()));
|
||||
error.set_cell_name (c.name ());
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
}
|
||||
if (b.begin_pins () == b.end_pins ()) {
|
||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s is not connected to outside")), a_org.expanded_name ()));
|
||||
error.set_cell_name (c.name ());
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n) {
|
||||
|
||||
if ((*n)->begin_pins () == (*n)->end_pins ()) {
|
||||
std::string msg;
|
||||
if (same_names) {
|
||||
msg = tl::sprintf (tl::to_string (tr ("Must-connect subnet of %s does not have any pin at all")), (*n)->expanded_name ());
|
||||
} else {
|
||||
msg = tl::sprintf (tl::to_string (tr ("Must-connect net %s does not have any pin at all")), (*n)->expanded_name ());
|
||||
}
|
||||
db::LogEntryData error (db::Error, msg);
|
||||
error.set_cell_name (c.name ());
|
||||
error.set_geometry (net_geometry (c, *n, internal_layout (), net_clusters ()));
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (c.begin_refs () == c.end_refs () || a.begin_pins () == a.end_pins () || b.begin_pins () == b.end_pins ()) {
|
||||
} else if (c.begin_refs () == c.end_refs () || no_pins_on_any_net (nets)) {
|
||||
|
||||
if (a_org.expanded_name () == b_org.expanded_name ()) {
|
||||
if (same_names) {
|
||||
if (path.empty ()) {
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name ()) + path_msg (path));
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect subnets of %s must be connected further up in the hierarchy - this is an error at chip top level")), nets_org.front ()->expanded_name ()) + path_msg (path));
|
||||
warn.set_cell_name (c.name ());
|
||||
warn.set_geometry (net_geometry (c, nets, internal_layout (), net_clusters ()));
|
||||
warn.set_category_name ("must-connect");
|
||||
log_entry (warn);
|
||||
} else {
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), c_org.name ()) + path_msg (path));
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect subnets of %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), nets_org.front ()->expanded_name (), c_org.name ()) + path_msg (path));
|
||||
warn.set_cell_name (c.name ());
|
||||
warn.set_geometry (subcircuit_geometry (*path.back (), internal_layout ()));
|
||||
warn.set_category_name ("must-connect");
|
||||
log_entry (warn);
|
||||
}
|
||||
} else {
|
||||
std::string net_names = net_names_msg (nets_org);
|
||||
if (path.empty ()) {
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), b_org.expanded_name ()) + path_msg (path));
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s must be connected further up in the hierarchy - this is an error at chip top level")), net_names) + path_msg (path));
|
||||
warn.set_cell_name (c.name ());
|
||||
warn.set_geometry (net_geometry (c, nets, internal_layout (), net_clusters ()));
|
||||
warn.set_category_name ("must-connect");
|
||||
log_entry (warn);
|
||||
} else {
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s and %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), a_org.expanded_name (), b_org.expanded_name (), c_org.name ()) + path_msg (path));
|
||||
db::LogEntryData warn (m_top_level_mode ? db::Error : db::Warning, tl::sprintf (tl::to_string (tr ("Must-connect nets %s of circuit %s must be connected further up in the hierarchy - this is an error at chip top level")), net_names, c_org.name ()) + path_msg (path));
|
||||
warn.set_cell_name (c.name ());
|
||||
warn.set_geometry (subcircuit_geometry (*path.back (), internal_layout ()));
|
||||
warn.set_category_name ("must-connect");
|
||||
|
|
@ -611,35 +705,49 @@ void LayoutToNetlist::check_must_connect_impl (const db::Circuit &c, const db::N
|
|||
|
||||
}
|
||||
|
||||
if (a.begin_pins () != a.end_pins () && b.begin_pins () != b.end_pins ()) {
|
||||
if (! no_pins_on_any_net (nets)) {
|
||||
|
||||
for (auto ref = c.begin_refs (); ref != c.end_refs (); ++ref) {
|
||||
|
||||
const db::SubCircuit &sc = *ref;
|
||||
|
||||
// TODO: consider the case of multiple pins on a net (rare)
|
||||
const db::Net *net_a = sc.net_for_pin (a.begin_pins ()->pin_id ());
|
||||
const db::Net *net_b = sc.net_for_pin (b.begin_pins ()->pin_id ());
|
||||
std::vector<const db::Net *> new_nets;
|
||||
new_nets.reserve (nets.size ());
|
||||
|
||||
bool failed = false;
|
||||
std::set<const db::Net *> seen;
|
||||
size_t i = 0;
|
||||
for (auto n = nets.begin (); n != nets.end (); ++n, ++i) {
|
||||
|
||||
if (seen.find (*n) != seen.end ()) {
|
||||
continue;
|
||||
}
|
||||
seen.insert (*n);
|
||||
|
||||
const db::Net *new_net = sc.net_for_pin ((*n)->begin_pins ()->pin_id ());
|
||||
new_nets.push_back (new_net);
|
||||
|
||||
if (new_net == 0) {
|
||||
failed = true;
|
||||
std::string msg;
|
||||
if (same_names) {
|
||||
msg = tl::sprintf (tl::to_string (tr ("Must-connect subnet of %s of circuit %s has no outside connection at all%s")), nets_org[i]->expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path);
|
||||
} else {
|
||||
msg = tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s has no outside connection at all%s")), nets_org[i]->expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path);
|
||||
}
|
||||
db::LogEntryData error (db::Error, msg);
|
||||
error.set_cell_name (sc.circuit ()->name ());
|
||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
}
|
||||
|
||||
if (net_a == 0) {
|
||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), a_org.expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path));
|
||||
error.set_cell_name (sc.circuit ()->name ());
|
||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
}
|
||||
|
||||
if (net_b == 0) {
|
||||
db::LogEntryData error (db::Error, tl::sprintf (tl::to_string (tr ("Must-connect net %s of circuit %s is not connected at all%s")), b_org.expanded_name (), c_org.name (), subcircuit_to_string (sc)) + path_msg (path));
|
||||
error.set_cell_name (sc.circuit ()->name ());
|
||||
error.set_geometry (subcircuit_geometry (sc, internal_layout ()));
|
||||
error.set_category_name ("must-connect");
|
||||
log_entry (error);
|
||||
}
|
||||
|
||||
if (net_a && net_b && net_a != net_b) {
|
||||
if (! failed && ! all_nets_are_same (new_nets)) {
|
||||
path.push_back (&sc);
|
||||
check_must_connect_impl (*sc.circuit (), *net_a, *net_b, c_org, a_org, b_org, path);
|
||||
check_must_connect_impl (*sc.circuit (), new_nets, c_org, nets_org, path, same_names);
|
||||
path.pop_back ();
|
||||
}
|
||||
|
||||
|
|
@ -910,7 +1018,7 @@ void LayoutToNetlist::register_layer (const ShapeCollection &collection, const s
|
|||
throw tl::Exception (tl::to_string (tr ("Layer name is already used: ")) + n_in);
|
||||
}
|
||||
|
||||
// Caution: this make create names which clash with future explicit names. Hopefully, the generated names are unique enough.
|
||||
// Caution: this may create names which clash with future explicit names. Hopefully, the generated names are unique enough.
|
||||
std::string n = n_in.empty () ? make_new_name () : n_in;
|
||||
|
||||
db::DeepLayer dl;
|
||||
|
|
|
|||
|
|
@ -1109,8 +1109,8 @@ private:
|
|||
void do_soft_connections ();
|
||||
void join_nets_from_pattern (db::Circuit &c, const tl::GlobPattern &p);
|
||||
void join_nets_from_pattern (db::Circuit &c, const std::set<std::string> &p);
|
||||
void check_must_connect (const db::Circuit &c, const db::Net &a, const db::Net &b);
|
||||
void check_must_connect_impl (const db::Circuit &c, const db::Net &a, const db::Net &b, const db::Circuit &c_org, const db::Net &a_org, const db::Net &b_org, std::vector<const db::SubCircuit *> &path);
|
||||
void check_must_connect (const db::Circuit &c, const std::vector<Net *> &nets);
|
||||
void check_must_connect_impl (const db::Circuit &c, const std::vector<const Net *> &nets, const db::Circuit &c_org, const std::vector<const Net *> &nets_org, std::vector<const db::SubCircuit *> &path, bool same_names);
|
||||
|
||||
// for debugging and testing
|
||||
void place_soft_connection_diodes ();
|
||||
|
|
|
|||
|
|
@ -86,14 +86,17 @@ NetlistComparer::exclude_resistors (double threshold)
|
|||
void
|
||||
NetlistComparer::same_nets (const db::Net *na, const db::Net *nb, bool must_match)
|
||||
{
|
||||
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));
|
||||
if (na || nb) {
|
||||
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));
|
||||
if (na || nb) {
|
||||
m_same_nets [std::make_pair (ca, cb)].push_back (std::make_pair (std::make_pair (na, nb), must_match));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -207,6 +210,49 @@ NetlistComparer::compare (const db::Netlist *a, const db::Netlist *b) const
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a consolidated list of identical nets for a circuit pair (aka "same_nets")
|
||||
*
|
||||
* The list is reduced by duplicates of the first net such, that the
|
||||
* last "same_nets" entry wins.
|
||||
*
|
||||
* The return value is a list of net pairs and a flag indicating "must_match" mode.
|
||||
* The second net can be null if "must_match" is true, indicating that no schematic
|
||||
* net with the same name was found - hence a mismatch exists.
|
||||
*/
|
||||
std::vector<std::pair<std::pair<const Net *, const Net *>, bool> >
|
||||
NetlistComparer::get_net_identity (const db::Circuit *ca, const db::Circuit *cb) const
|
||||
{
|
||||
std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > net_identity;
|
||||
|
||||
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 ()) {
|
||||
|
||||
const std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > &ni = sn->second;
|
||||
|
||||
// take last definition for a given first net
|
||||
net_identity.reserve (ni.size ());
|
||||
std::set<const Net *> seen;
|
||||
for (auto i = ni.end (); i != ni.begin (); ) {
|
||||
--i;
|
||||
const Net *main_net = i->first.first ? i->first.first : i->first.second;
|
||||
const Net *other_net = i->first.first ? i->first.second : i->first.first;
|
||||
if (seen.find (main_net) == seen.end () && (! other_net || seen.find (other_net) == seen.end ())) {
|
||||
net_identity.push_back (*i);
|
||||
seen.insert (main_net);
|
||||
if (other_net) {
|
||||
seen.insert (other_net);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse (net_identity.begin (), net_identity.end ());
|
||||
|
||||
}
|
||||
|
||||
return net_identity;
|
||||
}
|
||||
|
||||
bool
|
||||
NetlistComparer::compare_impl (const db::Netlist *a, const db::Netlist *b) const
|
||||
{
|
||||
|
|
@ -344,13 +390,6 @@ NetlistComparer::compare_impl (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<std::pair<const Net *, const Net *>, bool> > empty;
|
||||
const std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > *net_identity = ∅
|
||||
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;
|
||||
}
|
||||
|
||||
if (all_subcircuits_verified (ca, verified_circuits_a) && all_subcircuits_verified (cb, verified_circuits_b)) {
|
||||
|
||||
if (db::NetlistCompareGlobalOptions::options ()->debug_netcompare) {
|
||||
|
|
@ -362,7 +401,7 @@ NetlistComparer::compare_impl (const db::Netlist *a, const db::Netlist *b) const
|
|||
}
|
||||
|
||||
bool pin_mismatch = false;
|
||||
bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, *net_identity, pin_mismatch, c12_pin_mapping, c22_pin_mapping);
|
||||
bool g = compare_circuits (ca, cb, device_categorizer, circuit_categorizer, circuit_pin_mapper, get_net_identity (ca, cb), pin_mismatch, c12_pin_mapping, c22_pin_mapping);
|
||||
if (! g) {
|
||||
good = false;
|
||||
}
|
||||
|
|
@ -899,8 +938,16 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
if (mp_logger) {
|
||||
if (p->second && ! exact_match) {
|
||||
if (m_with_log) {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Nets %s are paired explicitly, but are not identical topologically")), nets2string (p->first)));
|
||||
if (! p->first.first) {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Right-side net %s is paired explicitly with a left-side one, but no net is present there")), expanded_name (p->first.second)));
|
||||
} else if (! p->first.second) {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Left-side net %s is paired explicitly with a right-side one, but no net is present there")), expanded_name (p->first.first)));
|
||||
} else {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Nets %s are paired explicitly, but are not identical topologically")), nets2string (p->first)));
|
||||
}
|
||||
}
|
||||
mp_logger->net_mismatch (p->first.first, p->first.second);
|
||||
} else {
|
||||
|
|
@ -911,7 +958,11 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
} else if (p->second && g1.has_node_index_for_net (p->first.first)) {
|
||||
|
||||
if (mp_logger) {
|
||||
mp_logger->net_mismatch (p->first.first, 0);
|
||||
mp_logger->net_mismatch (p->first.first, p->first.second);
|
||||
if (m_with_log && p->first.second) {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Nets %s are paired explicitly, but are not identical topologically")), nets2string (p->first)));
|
||||
}
|
||||
}
|
||||
|
||||
size_t ni1 = g1.node_index_for_net (p->first.first);
|
||||
|
|
@ -920,7 +971,11 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
} else if (p->second && g2.has_node_index_for_net (p->first.second)) {
|
||||
|
||||
if (mp_logger) {
|
||||
mp_logger->net_mismatch (0, p->first.second);
|
||||
mp_logger->net_mismatch (p->first.first, p->first.second);
|
||||
if (m_with_log && p->first.first) {
|
||||
mp_logger->log_entry (db::Error,
|
||||
tl::sprintf (tl::to_string (tr ("Nets %s are paired explicitly, but are not identical topologically")), nets2string (p->first)));
|
||||
}
|
||||
}
|
||||
|
||||
size_t ni2 = g2.node_index_for_net (p->first.second);
|
||||
|
|
|
|||
|
|
@ -387,6 +387,7 @@ protected:
|
|||
void do_device_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, const db::DeviceFilter &device_filter, DeviceCategorizer &device_categorizer, db::DeviceEquivalenceTracker &device_eq, bool &good) const;
|
||||
void do_subcircuit_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, CircuitCategorizer &circuit_categorizer, const db::CircuitPinCategorizer &circuit_pin_mapper, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping, db::SubCircuitEquivalenceTracker &subcircuit_eq, bool &good) const;
|
||||
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;
|
||||
std::vector<std::pair<std::pair<const Net *, const Net *>, bool> > get_net_identity (const db::Circuit *ca, const db::Circuit *cb) const;
|
||||
|
||||
mutable NetlistCompareLogger *mp_logger;
|
||||
bool m_with_log;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ nl_compare_debug_indent (size_t depth)
|
|||
|
||||
const std::string var_sep = tl::to_string (tr (" vs. "));
|
||||
|
||||
static std::string
|
||||
std::string
|
||||
expanded_name (const db::Net *a)
|
||||
{
|
||||
if (a == 0) {
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ const size_t unknown_id = std::numeric_limits<size_t>::max () - 1;
|
|||
// Some utilities
|
||||
|
||||
std::string nl_compare_debug_indent (size_t depth);
|
||||
std::string expanded_name (const db::Net *a);
|
||||
std::string nets2string (const db::Net *a, const db::Net *b);
|
||||
std::string nets2string (const std::pair<const db::Net *, const db::Net *> &np);
|
||||
|
||||
|
|
|
|||
|
|
@ -1451,7 +1451,7 @@ nets_by_name_const (const db::Circuit *circuit, const std::string &name_pattern)
|
|||
}
|
||||
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 ())) {
|
||||
if (!net->name ().empty () && glob.match (net->name ())) {
|
||||
res.push_back (net);
|
||||
}
|
||||
}
|
||||
|
|
@ -1480,7 +1480,7 @@ nets_by_name_const_from_netlist (const db::Netlist *netlist, const std::string &
|
|||
for (auto n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
const db::Net *net = n.operator-> ();
|
||||
// NOTE: we only pick root nets (pin_count == 0 or in top cell)
|
||||
if ((is_top || net->pin_count () == 0) && glob.match (net->name ())) {
|
||||
if ((is_top || net->pin_count () == 0) && !net->name ().empty () && glob.match (net->name ())) {
|
||||
res.push_back (net);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1175,6 +1175,24 @@ four-terminal MOS transistor.
|
|||
See <class_doc href="DeviceExtractorMOS4Transistor">DeviceExtractorMOS4Transistor</class_doc> for more details
|
||||
about this extractor (non-strict mode applies for 'mos4').
|
||||
</p>
|
||||
<a name="name"/><h2>"name" - Assigns a name to a layer for reference in the LVS database</h2>
|
||||
<keyword name="name"/>
|
||||
<p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>name(layer, name)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
See <a href="/about/drc_ref_netter.xml#name">Netter#name</a> for a description of that function.
|
||||
</p>
|
||||
<a name="name_prefix"/><h2>"name_prefix" - Specifies the layer name prefix for auto-generated layer names</h2>
|
||||
<keyword name="name_prefix"/>
|
||||
<p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>name_prefix(prefix)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
See <a href="/about/drc_ref_netter.xml#name_prefix">Netter#name_prefix</a> for a description of that function.
|
||||
</p>
|
||||
<a name="netlist"/><h2>"netlist" - Obtains the extracted netlist from the default <a href="/about/drc_ref_netter.xml">Netter</a></h2>
|
||||
<keyword name="netlist"/>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -422,6 +422,49 @@ but no error is raised.
|
|||
The <class_doc href="LayoutToNetlist">LayoutToNetlist</class_doc> object provides access to the internal details of
|
||||
the netter object.
|
||||
</p>
|
||||
<a name="name"/><h2>"name" - Assigns a name to a layer</h2>
|
||||
<keyword name="name"/>
|
||||
<p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>name(layer, name)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
Layer names are listed in the LayoutToNetlist (L2N) or LVS database. They
|
||||
are used to identify the layers, the net or device terminal geometries are
|
||||
on. It is usual to have computed layers, so it is necessary to indicate the
|
||||
purpose of the layer for later reuse of the geometries.
|
||||
</p><p>
|
||||
It is a good practice to assign names to computed and original layers,
|
||||
for example:
|
||||
</p><p>
|
||||
<pre>
|
||||
poly = input(...)
|
||||
poly_resistor = input(...)
|
||||
|
||||
poly_wiring = poly - poly_resistor
|
||||
name(poly_wiring, "poly_wiring")
|
||||
</pre>
|
||||
</p><p>
|
||||
Names must be assigned before the layers are used for the first time
|
||||
in <a href="#connect">connect</a>, <a href="#soft_connect">soft_connect</a>, <a href="#connect_global">connect_global</a>, <a href="#soft_connect_global">soft_connect_global</a> and
|
||||
<a href="#extract_devices">extract_devices</a> statements.
|
||||
</p><p>
|
||||
If layers are not named, they will be given a name made from the
|
||||
<a href="#name_prefix">name_prefix</a> and an incremental number when the layer is used for the
|
||||
first time.
|
||||
</p><p>
|
||||
<a href="#name">name</a> can only be used once on a layer and the layer names must be
|
||||
unique (not taken by another layer).
|
||||
</p>
|
||||
<a name="name_prefix"/><h2>"name_prefix" - Specifies the name prefix for auto-generated layer names</h2>
|
||||
<keyword name="name_prefix"/>
|
||||
<p>Usage:</p>
|
||||
<ul>
|
||||
<li><tt>name_prefix(prefix)</tt></li>
|
||||
</ul>
|
||||
<p>
|
||||
See <link href="#name"/> for details. The default prefix is "l".
|
||||
</p>
|
||||
<a name="netlist"/><h2>"netlist" - Gets the extracted netlist or triggers extraction if not done yet</h2>
|
||||
<keyword name="netlist"/>
|
||||
<p>Usage:</p>
|
||||
|
|
|
|||
|
|
@ -396,6 +396,9 @@ the schematic netlist for all circuits starting with "INV":
|
|||
same_nets("INV*", "A*")
|
||||
</pre>
|
||||
</p><p>
|
||||
A plain "*" for the net pattern forces all (named) nets to be equivalent between layout and schematic.
|
||||
Unnamed nets from the extracted netlist are not considered - i.e. nets without a label.
|
||||
</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
|
||||
resolve otherwise.
|
||||
|
|
@ -404,6 +407,16 @@ circuit_a and net_a are for the layout netlist, circuit_b and net_b for the sche
|
|||
Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
</p><p>
|
||||
Use this method andwhere in the script before the <a href="#compare">compare</a> call.
|
||||
</p><p>
|
||||
Multiple calls of "same_nets" can be used. The calls are effective in the order
|
||||
the are given. For example, the following sequence specifies equivalence of all
|
||||
equally named nets, with the exception of "A" and "B" which are equivalent to each other
|
||||
inside cell "ND2", despite their different name:
|
||||
</p><p>
|
||||
<pre>
|
||||
same_nets("*", "*")
|
||||
same_nets("ND2", "A", "B")
|
||||
</pre>
|
||||
</p>
|
||||
<a name="same_nets!"/><h2>"same_nets!" - Establishes an equivalence between the nets with matching requirement</h2>
|
||||
<keyword name="same_nets!"/>
|
||||
|
|
@ -416,6 +429,22 @@ Use this method andwhere in the script before the <a href="#compare">compare</a>
|
|||
<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><p>
|
||||
For example, this global specification requires all named nets from the
|
||||
layout to have an equivalent net in the schematic and those nets need to be
|
||||
identical for all circuits:
|
||||
</p><p>
|
||||
<pre>
|
||||
same_nets!("*", "*")
|
||||
</pre>
|
||||
</p><p>
|
||||
The following specification requires "A" and "B" to be identical in
|
||||
circuit "ND2". It is not an error if either "A" does not exist in the
|
||||
layout or "B" does not exist in the schematic:
|
||||
</p><p>
|
||||
<pre>
|
||||
same_nets!("ND2", "A", "B")
|
||||
</pre>
|
||||
</p>
|
||||
<a name="schematic"/><h2>"schematic" - Gets, sets or reads the reference netlist</h2>
|
||||
<keyword name="schematic"/>
|
||||
|
|
|
|||
|
|
@ -2394,6 +2394,18 @@ CODE
|
|||
# @synopsis extract_devices(extractor_class, name, layer_hash)
|
||||
# See \Netter#extract_devices for a description of that function.
|
||||
|
||||
# %DRC%
|
||||
# @name name
|
||||
# @brief Assigns a name to a layer for reference in the LVS database
|
||||
# @synopsis name(layer, name)
|
||||
# See \Netter#name for a description of that function.
|
||||
|
||||
# %DRC%
|
||||
# @name name_prefix
|
||||
# @brief Specifies the layer name prefix for auto-generated layer names
|
||||
# @synopsis name_prefix(prefix)
|
||||
# See \Netter#name_prefix for a description of that function.
|
||||
|
||||
# %DRC%
|
||||
# @name netlist
|
||||
# @brief Obtains the extracted netlist from the default \Netter
|
||||
|
|
@ -2408,6 +2420,8 @@ CODE
|
|||
connect_global
|
||||
soft_connect
|
||||
soft_connect_global
|
||||
name_prefix
|
||||
name
|
||||
connect_implicit
|
||||
connect_explicit
|
||||
device_scaling
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ module DRC
|
|||
@post_extract_config = []
|
||||
@l2n = nil
|
||||
@lnum = 0
|
||||
@name_prefix = "l"
|
||||
@device_scaling = 1.0
|
||||
@ignore_extraction_errors = false
|
||||
@top_level = false
|
||||
|
|
@ -106,8 +107,8 @@ module DRC
|
|||
a.requires_texts_or_region
|
||||
b.requires_texts_or_region
|
||||
|
||||
register_layer(a.data)
|
||||
register_layer(b.data)
|
||||
_register_layer(a.data, "connect")
|
||||
_register_layer(b.data, "connect")
|
||||
a.data.is_a?(RBA::Region) && @l2n.connect(a.data)
|
||||
b.data.is_a?(RBA::Region) && @l2n.connect(b.data)
|
||||
@l2n.connect(a.data, b.data)
|
||||
|
|
@ -150,8 +151,8 @@ module DRC
|
|||
a.requires_texts_or_region
|
||||
b.requires_texts_or_region
|
||||
|
||||
register_layer(a.data)
|
||||
register_layer(b.data)
|
||||
_register_layer(a.data, "soft_connect")
|
||||
_register_layer(b.data, "soft_connect")
|
||||
# soft connections imply hard intra-layer connections
|
||||
a.data.is_a?(RBA::Region) && @l2n.connect(a.data)
|
||||
b.data.is_a?(RBA::Region) && @l2n.connect(b.data)
|
||||
|
|
@ -177,7 +178,7 @@ module DRC
|
|||
l.is_a?(DRC::DRCLayer) || raise("Layer argument must be a layer")
|
||||
l.requires_texts_or_region
|
||||
|
||||
register_layer(l.data)
|
||||
_register_layer(l.data, "connect_global")
|
||||
l.data.is_a?(RBA::Region) && @l2n.connect(l.data)
|
||||
@l2n.connect_global(l.data, name)
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ module DRC
|
|||
l.is_a?(DRC::DRCLayer) || raise("Layer argument must be a layer")
|
||||
l.requires_texts_or_region
|
||||
|
||||
register_layer(l.data)
|
||||
_register_layer(l.data, "soft_connect_global")
|
||||
l.data.is_a?(RBA::Region) && @l2n.connect(l.data)
|
||||
@l2n.soft_connect_global(l.data, name)
|
||||
|
||||
|
|
@ -282,7 +283,7 @@ module DRC
|
|||
layer_selection.keys.sort.each do |n|
|
||||
l = layer_selection[n]
|
||||
l.requires_texts_or_region
|
||||
register_layer(l.data)
|
||||
_register_layer(l.data, "extract_devices")
|
||||
ls[n.to_s] = l.data
|
||||
end
|
||||
|
||||
|
|
@ -294,6 +295,70 @@ module DRC
|
|||
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name name
|
||||
# @brief Assigns a name to a layer
|
||||
# @synopsis name(layer, name)
|
||||
# Layer names are listed in the LayoutToNetlist (L2N) or LVS database. They
|
||||
# are used to identify the layers, the net or device terminal geometries are
|
||||
# on. It is usual to have computed layers, so it is necessary to indicate the
|
||||
# purpose of the layer for later reuse of the geometries.
|
||||
#
|
||||
# It is a good practice to assign names to computed and original layers,
|
||||
# for example:
|
||||
#
|
||||
# @code
|
||||
# poly = input(...)
|
||||
# poly_resistor = input(...)
|
||||
#
|
||||
# poly_wiring = poly - poly_resistor
|
||||
# name(poly_wiring, "poly_wiring")
|
||||
# @/code
|
||||
#
|
||||
# Names must be assigned before the layers are used for the first time
|
||||
# in \connect, \soft_connect, \connect_global, \soft_connect_global and
|
||||
# \extract_devices statements.
|
||||
#
|
||||
# If layers are not named, they will be given a name made from the
|
||||
# \name_prefix and an incremental number when the layer is used for the
|
||||
# first time.
|
||||
#
|
||||
# \name can only be used once on a layer and the layer names must be
|
||||
# unique (not taken by another layer).
|
||||
|
||||
# %DRC%
|
||||
# @name name_prefix
|
||||
# @brief Specifies the name prefix for auto-generated layer names
|
||||
# @synopsis name_prefix(prefix)
|
||||
# See \\name for details. The default prefix is "l".
|
||||
|
||||
def name(l, name)
|
||||
|
||||
@engine._context("name") do
|
||||
|
||||
l.is_a?(DRC::DRCLayer) || raise("First argument must be a layer")
|
||||
(name.is_a?(String) && name != "") || raise("Second argument must be a non-empty string")
|
||||
|
||||
id = l.data.data_id
|
||||
|
||||
if @layers && @layers[id]
|
||||
# already registered
|
||||
if @layers[id][1] != name
|
||||
raise("Layer already registered with name #{@layers[id][1]} in context: #{@layers[id][2]}")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
self._register_layer(l.data, "name", name)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def name_prefix(prefix)
|
||||
@name_prefix = prefix.to_s
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name device_scaling
|
||||
# @brief Specifies a dimension scale factor for the geometrical device properties
|
||||
|
|
@ -761,21 +826,30 @@ module DRC
|
|||
@l2n.make_soft_connection_diodes = f
|
||||
end
|
||||
|
||||
private
|
||||
protected
|
||||
|
||||
def _register_layer(data, context, name = nil)
|
||||
|
||||
id = data.data_id
|
||||
ensure_data
|
||||
|
||||
if @layers && @layers[id]
|
||||
# already registered
|
||||
return
|
||||
end
|
||||
|
||||
if !name
|
||||
@lnum += 1
|
||||
name = @name_prefix + @lnum.to_s
|
||||
end
|
||||
|
||||
@layers[id] = [ data, name, context ]
|
||||
|
||||
# every layer gets registered and intra-layer connections are made
|
||||
@l2n.register(data, name)
|
||||
|
||||
def cleanup
|
||||
@l2n && @l2n.is_extracted? && clear_connections
|
||||
end
|
||||
|
||||
def ensure_data
|
||||
if !@l2n
|
||||
@layers = {}
|
||||
_make_data
|
||||
@l2n.device_scaling = @device_scaling
|
||||
@l2n.top_level_mode = @top_level
|
||||
end
|
||||
end
|
||||
|
||||
def _make_data
|
||||
|
||||
if @engine._dss
|
||||
|
|
@ -792,24 +866,21 @@ module DRC
|
|||
|
||||
end
|
||||
|
||||
def register_layer(data)
|
||||
|
||||
id = data.data_id
|
||||
ensure_data
|
||||
|
||||
if @layers && @layers[id]
|
||||
# already registered
|
||||
return
|
||||
end
|
||||
|
||||
@layers[id] = data
|
||||
@lnum += 1
|
||||
|
||||
# every layer gets registered and intra-layer connections are made
|
||||
@l2n.register(data, "l" + @lnum.to_s)
|
||||
private
|
||||
|
||||
def cleanup
|
||||
@l2n && @l2n.is_extracted? && clear_connections
|
||||
end
|
||||
|
||||
def ensure_data
|
||||
if !@l2n
|
||||
@layers = {}
|
||||
_make_data
|
||||
@l2n.device_scaling = @device_scaling
|
||||
@l2n.top_level_mode = @top_level
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -552,6 +552,9 @@ CODE
|
|||
# same_nets("INV*", "A*")
|
||||
# @/code
|
||||
#
|
||||
# A plain "*" for the net pattern forces all (named) nets to be equivalent between layout and schematic.
|
||||
# Unnamed nets from the extracted netlist are not considered - i.e. nets without a label.
|
||||
#
|
||||
# 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
|
||||
# resolve otherwise.
|
||||
|
|
@ -560,6 +563,16 @@ CODE
|
|||
# Names are case sensitive for layout-derived netlists and case-insensitive for SPICE schematic netlists.
|
||||
#
|
||||
# Use this method andwhere in the script before the \compare call.
|
||||
#
|
||||
# Multiple calls of "same_nets" can be used. The calls are effective in the order
|
||||
# the are given. For example, the following sequence specifies equivalence of all
|
||||
# equally named nets, with the exception of "A" and "B" which are equivalent to each other
|
||||
# inside cell "ND2", despite their different name:
|
||||
#
|
||||
# @code
|
||||
# same_nets("*", "*")
|
||||
# same_nets("ND2", "A", "B")
|
||||
# @/code
|
||||
|
||||
def same_nets(*args)
|
||||
_same_nets_impl(false, *args)
|
||||
|
|
@ -573,6 +586,22 @@ CODE
|
|||
# @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.
|
||||
#
|
||||
# For example, this global specification requires all named nets from the
|
||||
# layout to have an equivalent net in the schematic and those nets need to be
|
||||
# identical for all circuits:
|
||||
#
|
||||
# @code
|
||||
# same_nets!("*", "*")
|
||||
# @/code
|
||||
#
|
||||
# The following specification requires "A" and "B" to be identical in
|
||||
# circuit "ND2". It is not an error if either "A" does not exist in the
|
||||
# layout or "B" does not exist in the schematic:
|
||||
#
|
||||
# @code
|
||||
# same_nets!("ND2", "A", "B")
|
||||
# @/code
|
||||
|
||||
def same_nets!(*args)
|
||||
_same_nets_impl(true, *args)
|
||||
|
|
@ -655,7 +684,7 @@ CODE
|
|||
|
||||
nets = []
|
||||
n2n.keys.sort.each do |n|
|
||||
if force || (n2n[n][0] && n2n[n][1])
|
||||
if n2n[n][0] && (force || n2n[n][1])
|
||||
nets << n2n[n]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -338,3 +338,22 @@ TEST(55_SoftConnectionSecondLevel)
|
|||
{
|
||||
run_test (_this, "soft_connect6", "soft_connect6.gds", true, false /*no LVS*/);
|
||||
}
|
||||
|
||||
// Issue #1719, part 2 (ignore stray texts)
|
||||
TEST(60_StrayTextsDoNotMakeNets)
|
||||
{
|
||||
run_test (_this, "stray_texts1", "stray_texts.gds", true, false /*no LVS*/);
|
||||
}
|
||||
|
||||
// Issue #1719, part 2 (ignore stray texts)
|
||||
TEST(61_StrayTextsDoNotMakeNets)
|
||||
{
|
||||
run_test (_this, "stray_texts2", "stray_texts.gds", true, false /*no LVS*/);
|
||||
}
|
||||
|
||||
// Issue #1719, part 3 (layer naming)
|
||||
TEST(62_LayerNames)
|
||||
{
|
||||
run_test (_this, "layer_names", "layer_names.gds", false, true, "TOP");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ TEST(20_private)
|
|||
|
||||
TEST(21_private)
|
||||
{
|
||||
run_test (_this, "test_21.lylvs", "test_21.cir.gz", "test_21.gds.gz", true, "test_21_4.lvsdb");
|
||||
run_test (_this, "test_21.lylvs", "test_21.cir.gz", "test_21.gds.gz", true, "test_21_5.lvsdb");
|
||||
}
|
||||
|
||||
// issue #1021
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT BBGATEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -55,7 +54,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT FBGATEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -63,7 +61,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT FWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
||||
* cell BWBTEST
|
||||
|
|
@ -71,5 +68,4 @@ X$14 4 BBGATEST
|
|||
.SUBCKT BWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l15 (576500 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (754500 -114000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -82,9 +79,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -104,9 +98,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -126,9 +117,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ X$14 7 6 BBGATEST
|
|||
.SUBCKT BBGATEST 1 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -57,7 +56,6 @@ X$14 7 6 BBGATEST
|
|||
.SUBCKT FBGATEST 1 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -66,7 +64,6 @@ X$14 7 6 BBGATEST
|
|||
.SUBCKT FWBTEST 1 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
||||
* cell BWBTEST
|
||||
|
|
@ -75,5 +72,4 @@ X$14 7 6 BBGATEST
|
|||
.SUBCKT BWBTEST 1 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l15 (576500 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (754500 -114000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -83,9 +80,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -106,9 +100,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -129,9 +120,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT BBGATEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -55,7 +54,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT FBGATEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -63,7 +61,6 @@ X$14 4 BBGATEST
|
|||
.SUBCKT FWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
||||
* cell BWBTEST
|
||||
|
|
@ -71,5 +68,4 @@ X$14 4 BBGATEST
|
|||
.SUBCKT BWBTEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l15 (830000 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (757500 -114000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -82,9 +79,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -104,9 +98,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -126,9 +117,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ X$13 4 BBGATEST
|
|||
.SUBCKT BWBTEST
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
||||
* cell FDPTEST
|
||||
|
|
@ -52,7 +51,6 @@ X$13 4 BBGATEST
|
|||
.SUBCKT BBGATEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -60,7 +58,6 @@ X$13 4 BBGATEST
|
|||
.SUBCKT FBGATEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -68,5 +65,4 @@ X$13 4 BBGATEST
|
|||
.SUBCKT FWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -82,9 +79,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -104,9 +98,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -186,9 +177,6 @@ layout(
|
|||
rect(l15 (576500 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (754500 -114000) (0 0))
|
||||
)
|
||||
|
||||
)
|
||||
circuit(testall
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ X$14 5 BWBTEST
|
|||
.SUBCKT BBGATEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -55,7 +54,6 @@ X$14 5 BWBTEST
|
|||
.SUBCKT FBGATEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -63,7 +61,6 @@ X$14 5 BWBTEST
|
|||
.SUBCKT FWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
||||
* cell BWBTEST
|
||||
|
|
@ -71,5 +68,4 @@ X$14 5 BWBTEST
|
|||
.SUBCKT BWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l15 (576500 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (754500 -114000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -82,9 +79,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -104,9 +98,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -126,9 +117,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ X$14 3 FBGATEST
|
|||
.SUBCKT BBGATEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BBGATEST
|
||||
.ENDS BBGATEST
|
||||
|
||||
* cell FBGATEST
|
||||
|
|
@ -55,7 +54,6 @@ X$14 3 FBGATEST
|
|||
.SUBCKT FBGATEST 1
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FBGATEST
|
||||
.ENDS FBGATEST
|
||||
|
||||
* cell FWBTEST
|
||||
|
|
@ -63,7 +61,6 @@ X$14 3 FBGATEST
|
|||
.SUBCKT FWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 FWBTEST
|
||||
.ENDS FWBTEST
|
||||
|
||||
* cell BWBTEST
|
||||
|
|
@ -71,5 +68,4 @@ X$14 3 FBGATEST
|
|||
.SUBCKT BWBTEST 2
|
||||
* net 1 B
|
||||
* net 2 A
|
||||
* net 3 BWBTEST
|
||||
.ENDS BWBTEST
|
||||
|
|
|
|||
|
|
@ -60,9 +60,6 @@ layout(
|
|||
rect(l15 (576500 -249000) (105500 81500))
|
||||
rect(l15 (-52750 -40750) (0 0))
|
||||
)
|
||||
net(3 name(BWBTEST)
|
||||
rect(l15 (754500 -114000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -82,9 +79,6 @@ layout(
|
|||
rect(l3 (572500 432500) (74500 73500))
|
||||
rect(l3 (-37250 -36750) (0 0))
|
||||
)
|
||||
net(3 name(FWBTEST)
|
||||
rect(l3 (798000 565500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
@ -104,9 +98,6 @@ layout(
|
|||
rect(l3 (-449500 422500) (146000 144500))
|
||||
rect(l3 (-71000 -71250) (0 0))
|
||||
)
|
||||
net(3 name(FBGATEST)
|
||||
rect(l3 (-417000 610500) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(B))
|
||||
|
|
@ -126,9 +117,6 @@ layout(
|
|||
rect(l15 (-218500 -290000) (193000 203000))
|
||||
rect(l15 (-94000 -101500) (0 0))
|
||||
)
|
||||
net(3 name(BBGATEST)
|
||||
rect(l15 (-422000 -313000) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
|
|
|
|||
|
|
@ -185,10 +185,9 @@ xref(
|
|||
)
|
||||
circuit(TOP TOP nomatch
|
||||
log(
|
||||
entry(error description('Nets $1 vs. (not connected) are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets 7 are paired explicitly, but are not identical topologically'))
|
||||
)
|
||||
xref(
|
||||
net(() 7 mismatch)
|
||||
net(1 () mismatch)
|
||||
net(5 1 match)
|
||||
net(4 2 match)
|
||||
|
|
@ -196,8 +195,10 @@ xref(
|
|||
net(3 4 match)
|
||||
net(7 5 match)
|
||||
net(8 6 match)
|
||||
net(9 7 mismatch)
|
||||
net(6 8 match)
|
||||
circuit(1 1 mismatch)
|
||||
circuit(() 1 mismatch)
|
||||
circuit(1 () mismatch)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -181,9 +181,8 @@ xref(
|
|||
)
|
||||
circuit(TOP TOP nomatch
|
||||
log(
|
||||
entry(error description('Nets (not connected) vs. 5 are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets 5,7 vs. (not connected) are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets (not connected) vs. 7 are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Left-side net 5,7 is paired explicitly with a right-side one, but no net is present there'))
|
||||
entry(error description('Net 5,7 is not matching any net from reference netlist'))
|
||||
)
|
||||
xref(
|
||||
net(() 5 mismatch)
|
||||
|
|
|
|||
|
|
@ -184,15 +184,11 @@ xref(
|
|||
)
|
||||
circuit(TOP TOP nomatch
|
||||
log(
|
||||
entry(error description('Nets $1 vs. (not connected) are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets (not connected) vs. 5 are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets 5,7 vs. (not connected) are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Nets (not connected) vs. 7 are paired explicitly, but are not identical topologically'))
|
||||
entry(error description('Left-side net 5,7 is paired explicitly with a right-side one, but no net is present there'))
|
||||
)
|
||||
xref(
|
||||
net(() 5 mismatch)
|
||||
net(() 7 mismatch)
|
||||
net(1 () mismatch)
|
||||
net(1 7 match)
|
||||
net(5 1 match)
|
||||
net(4 2 match)
|
||||
net(2 3 match)
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||
H(W B('Must-connect nets R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$1') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
H(W B('Must-connect subnets of GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect') Q('(0.27,0.8;0.27,8.4;0.32,8.4;0.32,0.8)'))
|
||||
H(W B('Must-connect subnets of R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect') Q('(1.48,2.37;1.48,7.46;2.61,7.46;2.61,2.37)'))
|
||||
H(W B('Must-connect subnets of R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$1') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
D(D$PMOS PMOS
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||
H(W B('Must-connect nets R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect'))
|
||||
H(W B('Must-connect nets R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$1') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
H(W B('Must-connect subnets of GND must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect') Q('(0.27,0.8;0.27,8.4;0.32,8.4;0.32,0.8)'))
|
||||
H(W B('Must-connect subnets of R must be connected further up in the hierarchy - this is an error at chip top level') C(INVCHAIN) X('must-connect') Q('(1.48,2.37;1.48,7.46;2.61,7.46;2.61,2.37)'))
|
||||
H(W B('Must-connect subnets of R of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$1') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
D(D$PMOS PMOS
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
* cell TOP
|
||||
* pin A
|
||||
* pin C
|
||||
* pin SUBSTRATE
|
||||
.SUBCKT TOP 2 3 4
|
||||
* net 2 A
|
||||
* net 3 C
|
||||
* net 4 SUBSTRATE
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 2 3 1 6 4 DINV
|
||||
* cell instance $2 r0 *1 3.6,0
|
||||
X$2 5 6 1 4 INVX1
|
||||
.ENDS TOP
|
||||
|
||||
* cell DINV
|
||||
* pin A<1>
|
||||
* pin A<2>
|
||||
* pin B<2>
|
||||
* pin VDD
|
||||
* pin VSS
|
||||
.SUBCKT DINV 1 2 3 5 6
|
||||
* net 1 A<1>
|
||||
* net 2 A<2>
|
||||
* net 3 B<2>
|
||||
* net 4 B<1>
|
||||
* net 5 VDD
|
||||
* net 6 VSS
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 4 5 1 6 INVX1
|
||||
* cell instance $2 r0 *1 1.8,0
|
||||
X$2 3 5 2 6 INVX1
|
||||
.ENDS DINV
|
||||
|
||||
* cell INVX1
|
||||
* pin OUT
|
||||
* pin VDD
|
||||
* pin IN
|
||||
* pin VSS
|
||||
.SUBCKT INVX1 1 2 3 4
|
||||
* net 1 OUT
|
||||
* net 2 VDD
|
||||
* net 3 IN
|
||||
* net 4 VSS
|
||||
* device instance $1 r0 *1 0.85,5.8 PMOS
|
||||
M$1 1 3 2 2 PMOS L=0.25U W=1.5U AS=0.6375P AD=0.6375P PS=3.85U PD=3.85U
|
||||
* device instance $2 r0 *1 0.85,2.135 NMOS
|
||||
M$2 1 3 4 4 NMOS L=0.25U W=0.95U AS=0.40375P AD=0.40375P PS=2.75U PD=2.75U
|
||||
.ENDS INVX1
|
||||
Binary file not shown.
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
source($lvs_test_source, $lvs_test_top)
|
||||
|
||||
report_lvs($lvs_test_target_lvsdb, true)
|
||||
|
||||
target_netlist($lvs_test_target_cir, write_spice, "Extracted by KLayout")
|
||||
|
||||
schematic("floating_ref.cir")
|
||||
|
||||
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)
|
||||
|
||||
# try layer names with nwell
|
||||
name(nwell, "nwell")
|
||||
|
||||
# same name - not an error
|
||||
name(nwell, "nwell")
|
||||
|
||||
ok = true
|
||||
begin
|
||||
name(nwell, "nwell2")
|
||||
ok = false
|
||||
rescue => ex
|
||||
end
|
||||
ok || raise("nwell layer is already named - this is an error")
|
||||
|
||||
# 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
|
||||
|
||||
# Layer names for all other layers
|
||||
|
||||
%w(bulk pactive pgate psd ntie nactive ngate nsd poly contact metal1 via1 metal2).each do |v|
|
||||
name(eval(v), v)
|
||||
end
|
||||
|
||||
# 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")
|
||||
|
||||
ok = true
|
||||
begin
|
||||
name(ptie, "ptie")
|
||||
ok = false
|
||||
rescue => ex
|
||||
end
|
||||
ok || raise("ptie layer already used - this is an error")
|
||||
|
||||
# Compare section
|
||||
|
||||
netlist.simplify
|
||||
align
|
||||
|
||||
consider_net_names(false)
|
||||
|
||||
compare
|
||||
|
||||
|
|
@ -0,0 +1,434 @@
|
|||
#%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(nwell '1/0')
|
||||
layer(poly '5/0')
|
||||
layer(contact '8/0')
|
||||
layer(metal1 '9/0')
|
||||
layer(via1)
|
||||
layer(metal2)
|
||||
layer(bulk)
|
||||
layer(psd)
|
||||
layer(ntie)
|
||||
layer(nsd)
|
||||
layer(l1)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(nwell nwell ntie)
|
||||
connect(poly poly contact)
|
||||
connect(contact poly contact metal1 psd ntie nsd l1)
|
||||
connect(metal1 contact metal1 via1)
|
||||
connect(via1 metal1 via1 metal2)
|
||||
connect(metal2 via1 metal2)
|
||||
connect(bulk bulk)
|
||||
connect(psd contact psd)
|
||||
connect(ntie nwell contact ntie)
|
||||
connect(nsd contact nsd)
|
||||
connect(l1 contact l1)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(bulk SUBSTRATE)
|
||||
global(l1 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(psd (-550 -750) (425 1500))
|
||||
)
|
||||
terminal(G
|
||||
rect(poly (-125 -750) (250 1500))
|
||||
)
|
||||
terminal(D
|
||||
rect(psd (125 -750) (425 1500))
|
||||
)
|
||||
terminal(B
|
||||
rect(nwell (-125 -750) (250 1500))
|
||||
)
|
||||
)
|
||||
device(D$NMOS NMOS
|
||||
terminal(S
|
||||
rect(nsd (-550 -475) (425 950))
|
||||
)
|
||||
terminal(G
|
||||
rect(poly (-125 -475) (250 950))
|
||||
)
|
||||
terminal(D
|
||||
rect(nsd (125 -475) (425 950))
|
||||
)
|
||||
terminal(B
|
||||
rect(bulk (-125 -475) (250 950))
|
||||
)
|
||||
)
|
||||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
circuit(INVX1
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (2000 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1 name(OUT)
|
||||
rect(contact (1110 5160) (180 180))
|
||||
rect(contact (-180 920) (180 180))
|
||||
rect(contact (-180 -730) (180 180))
|
||||
rect(contact (-180 -4120) (180 180))
|
||||
rect(contact (-180 370) (180 180))
|
||||
rect(metal1 (-240 -790) (300 4790))
|
||||
rect(metal1 (-150 -2500) (0 0))
|
||||
rect(psd (-225 1050) (425 1500))
|
||||
rect(nsd (-425 -4890) (425 950))
|
||||
)
|
||||
net(2 name(VDD)
|
||||
rect(nwell (-100 4500) (2000 3500))
|
||||
rect(contact (-1090 -890) (180 180))
|
||||
rect(contact (-580 -1030) (180 180))
|
||||
rect(contact (-180 -730) (180 180))
|
||||
rect(contact (-180 -730) (180 180))
|
||||
rect(metal1 (-590 1460) (1800 800))
|
||||
rect(metal1 (-1050 -550) (300 300))
|
||||
rect(metal1 (-700 -850) (300 300))
|
||||
rect(metal1 (300 500) (0 0))
|
||||
rect(metal1 (-600 -2200) (300 1400))
|
||||
rect(psd (-350 -1450) (425 1500))
|
||||
rect(ntie (-75 450) (500 500))
|
||||
)
|
||||
net(3 name(IN)
|
||||
rect(poly (725 2860) (250 1940))
|
||||
rect(poly (-525 -1850) (300 300))
|
||||
rect(poly (-25 -1840) (250 1450))
|
||||
rect(poly (-250 1940) (250 2000))
|
||||
rect(poly (-250 -2000) (250 2000))
|
||||
rect(contact (-465 -3790) (180 180))
|
||||
rect(metal1 (-90 -90) (0 0))
|
||||
rect(metal1 (-150 -150) (300 300))
|
||||
)
|
||||
net(4 name(VSS)
|
||||
rect(contact (810 710) (180 180))
|
||||
rect(contact (-580 880) (180 180))
|
||||
rect(contact (-180 370) (180 180))
|
||||
rect(metal1 (-590 -2100) (1800 800))
|
||||
rect(metal1 (-1050 -550) (300 300))
|
||||
rect(metal1 (-100 -150) (0 0))
|
||||
rect(metal1 (-600 400) (300 1360))
|
||||
rect(nsd (-350 -900) (425 950))
|
||||
rect(l1 (-75 -2010) (500 400))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(OUT))
|
||||
pin(2 name(VDD))
|
||||
pin(3 name(IN))
|
||||
pin(4 name(VSS))
|
||||
|
||||
# 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.6375)
|
||||
param(PS 3.85)
|
||||
param(PD 3.85)
|
||||
terminal(S 2)
|
||||
terminal(G 3)
|
||||
terminal(D 1)
|
||||
terminal(B 2)
|
||||
)
|
||||
device(2 D$NMOS
|
||||
location(850 2135)
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0.40375)
|
||||
param(AD 0.40375)
|
||||
param(PS 2.75)
|
||||
param(PD 2.75)
|
||||
terminal(S 4)
|
||||
terminal(G 3)
|
||||
terminal(D 1)
|
||||
terminal(B 4)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(DINV
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (3800 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1 name('A<1>')
|
||||
rect(metal1 (600 3100) (0 0))
|
||||
)
|
||||
net(2 name('A<2>')
|
||||
rect(metal1 (2400 3100) (0 0))
|
||||
)
|
||||
net(3 name('B<2>')
|
||||
rect(metal1 (3000 4000) (0 0))
|
||||
)
|
||||
net(4 name('B<1>')
|
||||
rect(metal1 (1200 4000) (0 0))
|
||||
)
|
||||
net(5 name(VDD)
|
||||
rect(metal1 (1800 7200) (0 0))
|
||||
)
|
||||
net(6 name(VSS)
|
||||
rect(metal1 (1800 800) (0 0))
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name('A<1>'))
|
||||
pin(2 name('A<2>'))
|
||||
pin(3 name('B<2>'))
|
||||
pin(5 name(VDD))
|
||||
pin(6 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 INVX1 location(0 0)
|
||||
pin(0 4)
|
||||
pin(1 5)
|
||||
pin(2 1)
|
||||
pin(3 6)
|
||||
)
|
||||
circuit(2 INVX1 location(1800 0)
|
||||
pin(0 3)
|
||||
pin(1 5)
|
||||
pin(2 2)
|
||||
pin(3 6)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(TOP
|
||||
|
||||
# Circuit boundary
|
||||
rect((-100 400) (5600 7600))
|
||||
|
||||
# Nets with their geometries
|
||||
net(1
|
||||
rect(metal1 (3100 2950) (950 300))
|
||||
)
|
||||
net(2 name(A)
|
||||
rect(metal1 (600 3100) (0 0))
|
||||
)
|
||||
net(3 name(C)
|
||||
rect(metal1 (2400 3100) (0 0))
|
||||
)
|
||||
net(4 name(SUBSTRATE))
|
||||
net(5)
|
||||
net(6)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(2 name(A))
|
||||
pin(3 name(C))
|
||||
pin(4 name(SUBSTRATE))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 DINV location(0 0)
|
||||
pin(0 2)
|
||||
pin(1 3)
|
||||
pin(2 1)
|
||||
pin(3 6)
|
||||
pin(4 4)
|
||||
)
|
||||
circuit(2 INVX1 location(3600 0)
|
||||
pin(0 5)
|
||||
pin(1 6)
|
||||
pin(2 1)
|
||||
pin(3 4)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
# Reference netlist
|
||||
reference(
|
||||
|
||||
# Device class section
|
||||
class(NMOS MOS4)
|
||||
class(PMOS MOS4)
|
||||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
circuit(INVX1
|
||||
|
||||
# Nets
|
||||
net(1 name(A))
|
||||
net(2 name(Z))
|
||||
net(3 name(VSS))
|
||||
net(4 name(VDD))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(A))
|
||||
pin(2 name(Z))
|
||||
pin(4 name(VDD))
|
||||
pin(3 name(VSS))
|
||||
|
||||
# Devices and their connections
|
||||
device(1 NMOS
|
||||
name('0')
|
||||
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 1)
|
||||
terminal(D 2)
|
||||
terminal(B 3)
|
||||
)
|
||||
device(2 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 4)
|
||||
terminal(G 1)
|
||||
terminal(D 2)
|
||||
terminal(B 4)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(DINV
|
||||
|
||||
# Nets
|
||||
net(1 name('A<1>'))
|
||||
net(2 name('A<2>'))
|
||||
net(3 name('B<1>'))
|
||||
net(4 name('B<2>'))
|
||||
net(5 name(VDD))
|
||||
net(6 name(VSS))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name('A<1>'))
|
||||
pin(2 name('A<2>'))
|
||||
pin(3 name('B<1>'))
|
||||
pin(4 name('B<2>'))
|
||||
pin(5 name(VDD))
|
||||
pin(6 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 INVX1 name(A)
|
||||
pin(0 1)
|
||||
pin(1 3)
|
||||
pin(2 5)
|
||||
pin(3 6)
|
||||
)
|
||||
circuit(2 INVX1 name(B)
|
||||
pin(0 2)
|
||||
pin(1 4)
|
||||
pin(2 5)
|
||||
pin(3 6)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(TOP
|
||||
|
||||
# Nets
|
||||
net(1 name(A))
|
||||
net(2 name(C))
|
||||
net(3 name(D))
|
||||
net(4 name(B))
|
||||
net(5 name(E))
|
||||
net(6 name(VDD))
|
||||
net(7 name(VSS))
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(1 name(A))
|
||||
pin(2 name(C))
|
||||
pin(3 name(D))
|
||||
pin(6 name(VDD))
|
||||
pin(7 name(VSS))
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit(1 DINV name('0')
|
||||
pin(0 1)
|
||||
pin(1 2)
|
||||
pin(2 4)
|
||||
pin(3 5)
|
||||
pin(4 6)
|
||||
pin(5 7)
|
||||
)
|
||||
circuit(2 INVX1 name('1')
|
||||
pin(0 5)
|
||||
pin(1 3)
|
||||
pin(2 6)
|
||||
pin(3 7)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
# Cross reference
|
||||
xref(
|
||||
circuit(DINV DINV match
|
||||
log(
|
||||
entry(warning description('Matching nets B<1> from an ambiguous group of nets'))
|
||||
entry(warning description('Matching nets B<2> from an ambiguous group of nets'))
|
||||
entry(info description('Matching nets A<1> following an ambiguous match'))
|
||||
entry(info description('Matching nets A<2> following an ambiguous match'))
|
||||
)
|
||||
xref(
|
||||
net(1 1 match)
|
||||
net(2 2 match)
|
||||
net(4 3 warning)
|
||||
net(3 4 warning)
|
||||
net(5 5 match)
|
||||
net(6 6 match)
|
||||
pin(() 2 match)
|
||||
pin(0 0 match)
|
||||
pin(1 1 match)
|
||||
pin(2 3 match)
|
||||
pin(3 4 match)
|
||||
pin(4 5 match)
|
||||
circuit(1 1 match)
|
||||
circuit(2 2 match)
|
||||
)
|
||||
)
|
||||
circuit(INVX1 INVX1 match
|
||||
xref(
|
||||
net(3 1 match)
|
||||
net(1 2 match)
|
||||
net(2 4 match)
|
||||
net(4 3 match)
|
||||
pin(2 0 match)
|
||||
pin(0 1 match)
|
||||
pin(1 2 match)
|
||||
pin(3 3 match)
|
||||
device(2 1 match)
|
||||
device(1 2 match)
|
||||
)
|
||||
)
|
||||
circuit(TOP TOP match
|
||||
xref(
|
||||
net(5 3 match)
|
||||
net(1 5 match)
|
||||
net(6 6 match)
|
||||
net(2 1 match)
|
||||
net(3 2 match)
|
||||
net(4 7 match)
|
||||
pin(() 2 match)
|
||||
pin(() 3 match)
|
||||
pin(0 0 match)
|
||||
pin(1 1 match)
|
||||
pin(2 4 match)
|
||||
circuit(1 1 match)
|
||||
circuit(2 2 match)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -27,7 +27,7 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||
H(W B('Must-connect subnets of VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect') Q('(3.61,0.7;3.61,8.89;11.365,8.89;11.365,0.7)'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
D(D$PMOS PMOS
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(E B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||
H(E B('Must-connect subnets of VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect') Q('(3.61,0.7;3.61,8.89;11.365,8.89;11.365,0.7)'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
D(D$PMOS PMOS
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ J(
|
|||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l14 SUBSTRATE)
|
||||
H(W B('Must-connect nets VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||
H(W B('Must-connect nets VDD must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect'))
|
||||
H(W B('Must-connect nets VSS of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$2') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
H(W B('Must-connect subnets of VSSTOP must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect') Q('(3.61,0.7;3.61,8.89;11.365,8.89;11.365,0.7)'))
|
||||
H(W B('Must-connect subnets of VDD must be connected further up in the hierarchy - this is an error at chip top level') C(TOP) X('must-connect') Q('(2.595,4.725;2.595,4.805;11.865,4.805;11.865,4.725)'))
|
||||
H(W B('Must-connect subnets of VSS of circuit INV2 must be connected further up in the hierarchy - this is an error at chip top level.\nInstance path: INVCHAIN/INV2[r0 0,0]:$2') C(INVCHAIN) X('must-connect') Q('(0,0;0,9.2;3,9.2;3,0)'))
|
||||
K(PMOS MOS3)
|
||||
K(NMOS MOS3)
|
||||
D(D$PMOS PMOS
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ layout(
|
|||
global(l10 SUBSTRATE)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets VDD must be connected further up in the hierarchy - this is an error at chip top level') cell(RINGO) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of VDD must be connected further up in the hierarchy - this is an error at chip top level') cell(RINGO) cat('must-connect') polygon('(2.95,7.25;2.95,7.4;25.1,7.4;25.1,7.25)'))
|
||||
|
||||
# Device class section
|
||||
class(PMOS MOS4)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ layout(
|
|||
global(l10 SUBSTRATE)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets VDD must be connected further up in the hierarchy - this is an error at chip top level') cell(RINGO) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of VDD must be connected further up in the hierarchy - this is an error at chip top level') cell(RINGO) cat('must-connect') polygon('(2.95,7.25;2.95,7.4;25.1,7.4;25.1,7.25)'))
|
||||
|
||||
# Device class section
|
||||
class(PMOS MOS4)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,12 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT TOP
|
||||
X$1 \$2 \$5 \$4 E \$1 MIDDLE
|
||||
.ENDS TOP
|
||||
|
||||
.SUBCKT MIDDLE B \$I4 \$I3 \$I2 \$I1
|
||||
X$1 \$I1 B \$I3 \$I4 \$I2 F CHILD
|
||||
.ENDS MIDDLE
|
||||
|
||||
.SUBCKT CHILD A B C D \$8 \$9
|
||||
.ENDS CHILD
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#%l2n-klayout
|
||||
W(TOP)
|
||||
U(0.001)
|
||||
L(l1 '1/0')
|
||||
L(l2 '1/0')
|
||||
L(l3 '2/0')
|
||||
C(l1 l2 l3)
|
||||
C(l2 l1 l2 l3)
|
||||
C(l3 l1 l2 l3)
|
||||
X(CHILD
|
||||
R((-1230 410) (4330 220))
|
||||
N(1 I(A)
|
||||
J(l1 A (-560 550))
|
||||
R(l2 (-80 -80) (170 160))
|
||||
)
|
||||
N(2 I(B)
|
||||
J(l1 B (660 510))
|
||||
J(l1 B (560 10))
|
||||
R(l2 (-650 -90) (160 150))
|
||||
R(l2 (410 -140) (140 160))
|
||||
)
|
||||
N(3 I(C)
|
||||
J(l1 C (-1160 530))
|
||||
R(l2 (-70 -90) (160 170))
|
||||
)
|
||||
N(4 I(D)
|
||||
J(l1 D (1820 510))
|
||||
R(l2 (-70 -90) (160 160))
|
||||
)
|
||||
N(5
|
||||
R(l2 (2370 410) (170 200))
|
||||
)
|
||||
N(6
|
||||
R(l2 (2910 430) (190 200))
|
||||
)
|
||||
P(1 I(A))
|
||||
P(2 I(B))
|
||||
P(3 I(C))
|
||||
P(4 I(D))
|
||||
P(5)
|
||||
P(6)
|
||||
)
|
||||
X(MIDDLE
|
||||
R((-1230 410) (4330 220))
|
||||
N(1 I(B)
|
||||
J(l1 B (640 520))
|
||||
J(l1 B (550 0))
|
||||
)
|
||||
N(2 I(F)
|
||||
J(l1 F (3000 510))
|
||||
)
|
||||
N(3)
|
||||
N(4)
|
||||
N(5)
|
||||
N(6)
|
||||
P(1 I(B))
|
||||
P(3)
|
||||
P(4)
|
||||
P(5)
|
||||
P(6)
|
||||
X(1 CHILD Y(0 0)
|
||||
P(0 6)
|
||||
P(1 1)
|
||||
P(2 4)
|
||||
P(3 3)
|
||||
P(4 5)
|
||||
P(5 2)
|
||||
)
|
||||
)
|
||||
X(TOP
|
||||
R((-1280 -190) (4350 840))
|
||||
N(1
|
||||
R(l3 (-680 -160) (170 760))
|
||||
R(l3 (-170 -790) (860 270))
|
||||
R(l3 (-200 -270) (220 780))
|
||||
)
|
||||
N(2
|
||||
R(l3 (530 -180) (220 790))
|
||||
R(l3 (-220 -790) (790 180))
|
||||
R(l3 (-260 -180) (260 810))
|
||||
)
|
||||
N(3 I(E)
|
||||
J(l1 E (2400 460))
|
||||
)
|
||||
N(4
|
||||
R(l3 (-1280 -150) (210 750))
|
||||
)
|
||||
N(5
|
||||
R(l3 (1660 -190) (240 840))
|
||||
)
|
||||
X(1 MIDDLE Y(-30 -40)
|
||||
P(0 2)
|
||||
P(1 5)
|
||||
P(2 4)
|
||||
P(3 3)
|
||||
P(4 1)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
$lvs_test_source && source($lvs_test_source)
|
||||
|
||||
if $lvs_test_target_l2n
|
||||
report_netlist($lvs_test_target_l2n)
|
||||
else
|
||||
report_netlist
|
||||
end
|
||||
|
||||
writer = write_spice(true, false)
|
||||
$lvs_test_target_cir && target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||
|
||||
deep
|
||||
|
||||
# separate labels and polygons
|
||||
|
||||
l1l = labels(1, 0)
|
||||
l1 = polygons(1, 0)
|
||||
l2 = input(2, 0)
|
||||
|
||||
connect(l1l, l1)
|
||||
connect(l1l, l2)
|
||||
connect(l1, l2)
|
||||
|
||||
connect_implicit("*", "*")
|
||||
|
||||
netlist
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT TOP
|
||||
X$1 \$2 \$5 \$4 E \$1 MIDDLE
|
||||
.ENDS TOP
|
||||
|
||||
.SUBCKT MIDDLE B \$I4 \$I3 \$I2 \$I1
|
||||
X$1 \$I1 B \$I3 \$I4 \$I2 F CHILD
|
||||
.ENDS MIDDLE
|
||||
|
||||
.SUBCKT CHILD A B C D \$6 \$7
|
||||
.ENDS CHILD
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
#%l2n-klayout
|
||||
W(TOP)
|
||||
U(0.001)
|
||||
L(l1 '1/0')
|
||||
L(l2 '2/0')
|
||||
C(l1 l1 l2)
|
||||
C(l2 l1 l2)
|
||||
X(CHILD
|
||||
R((-1230 410) (4330 220))
|
||||
N(1 I(A)
|
||||
R(l1 (-640 470) (170 160))
|
||||
R(l1 (-90 -80) (0 0))
|
||||
)
|
||||
N(2 I(B)
|
||||
R(l1 (570 430) (160 150))
|
||||
R(l1 (-70 -70) (0 0))
|
||||
R(l1 (480 -70) (140 160))
|
||||
R(l1 (-60 -80) (0 0))
|
||||
)
|
||||
N(3 I(C)
|
||||
R(l1 (-1230 440) (160 170))
|
||||
R(l1 (-90 -80) (0 0))
|
||||
)
|
||||
N(4 I(D)
|
||||
R(l1 (1750 420) (160 160))
|
||||
R(l1 (-90 -70) (0 0))
|
||||
)
|
||||
N(5
|
||||
R(l1 (2370 410) (170 200))
|
||||
)
|
||||
N(6
|
||||
R(l1 (2910 430) (190 200))
|
||||
)
|
||||
P(1 I(A))
|
||||
P(2 I(B))
|
||||
P(3 I(C))
|
||||
P(4 I(D))
|
||||
P(5)
|
||||
P(6)
|
||||
)
|
||||
X(MIDDLE
|
||||
R((-1230 410) (4330 220))
|
||||
N(1 I(B)
|
||||
R(l1 (640 520) (0 0))
|
||||
R(l1 (550 0) (0 0))
|
||||
)
|
||||
N(2 I(F)
|
||||
R(l1 (3000 510) (0 0))
|
||||
)
|
||||
N(3)
|
||||
N(4)
|
||||
N(5)
|
||||
N(6)
|
||||
P(1 I(B))
|
||||
P(3)
|
||||
P(4)
|
||||
P(5)
|
||||
P(6)
|
||||
X(1 CHILD Y(0 0)
|
||||
P(0 6)
|
||||
P(1 1)
|
||||
P(2 4)
|
||||
P(3 3)
|
||||
P(4 5)
|
||||
P(5 2)
|
||||
)
|
||||
)
|
||||
X(TOP
|
||||
R((-1280 -190) (4350 840))
|
||||
N(1
|
||||
R(l2 (-680 -160) (170 760))
|
||||
R(l2 (-170 -790) (860 270))
|
||||
R(l2 (-200 -270) (220 780))
|
||||
)
|
||||
N(2
|
||||
R(l2 (530 -180) (220 790))
|
||||
R(l2 (-220 -790) (790 180))
|
||||
R(l2 (-260 -180) (260 810))
|
||||
)
|
||||
N(3 I(E)
|
||||
R(l1 (2400 460) (0 0))
|
||||
)
|
||||
N(4
|
||||
R(l2 (-1280 -150) (210 750))
|
||||
)
|
||||
N(5
|
||||
R(l2 (1660 -190) (240 840))
|
||||
)
|
||||
X(1 MIDDLE Y(-30 -40)
|
||||
P(0 2)
|
||||
P(1 5)
|
||||
P(2 4)
|
||||
P(3 3)
|
||||
P(4 1)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
$lvs_test_source && source($lvs_test_source)
|
||||
|
||||
if $lvs_test_target_l2n
|
||||
report_netlist($lvs_test_target_l2n)
|
||||
else
|
||||
report_netlist
|
||||
end
|
||||
|
||||
writer = write_spice(true, false)
|
||||
$lvs_test_target_cir && target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||
|
||||
deep
|
||||
|
||||
# polygons and labels on same layer
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
|
||||
connect(l1, l2)
|
||||
|
||||
connect_implicit("*", "*")
|
||||
|
||||
netlist
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.385,-0.305;-0.385,5.855;9.105,5.855;9.105,-0.305)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.385,-0.305;-0.385,5.855;9.105,5.855;9.105,-0.305)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.385,-0.305;-0.385,5.855;9.105,5.855;9.105,-0.305)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l6 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.385,-0.305;-0.385,5.855;9.105,5.855;9.105,-0.305)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ layout(
|
|||
global(l1 vss)
|
||||
|
||||
# Log entries
|
||||
message(warning description('Must-connect nets vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect'))
|
||||
message(warning description('Must-connect subnets of vdd must be connected further up in the hierarchy - this is an error at chip top level') cell(SP6TArray_2X4) cat('must-connect') polygon('(-0.16,-0.13;-0.16,5.68;8.88,5.68;8.88,-0.13)'))
|
||||
|
||||
# Device class section
|
||||
class(active_res RES)
|
||||
|
|
|
|||
Loading…
Reference in New Issue