mirror of https://github.com/KLayout/klayout.git
commit
8f8c393309
|
|
@ -105,6 +105,14 @@ Circuit &Circuit::operator= (const Circuit &other)
|
|||
m_cell_index = other.m_cell_index;
|
||||
m_pins = other.m_pins;
|
||||
|
||||
m_pin_by_id.clear ();
|
||||
for (pin_list::iterator p = m_pins.begin (); p != m_pins.end (); ++p) {
|
||||
if (m_pin_by_id.size () <= p->id ()) {
|
||||
m_pin_by_id.resize (p->id () + 1, pin_list::iterator ());
|
||||
}
|
||||
m_pin_by_id [p->id ()] = p;
|
||||
}
|
||||
|
||||
std::map<const Device *, Device *> device_table;
|
||||
for (const_device_iterator i = other.begin_devices (); i != other.end_devices (); ++i) {
|
||||
Device *d = new Device (*i);
|
||||
|
|
@ -157,17 +165,22 @@ void Circuit::set_netlist (Netlist *netlist)
|
|||
|
||||
const Pin *Circuit::pin_by_id (size_t id) const
|
||||
{
|
||||
if (id >= m_pins.size ()) {
|
||||
if (id >= m_pin_by_id.size ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return &m_pins [id];
|
||||
pin_list::iterator pi = m_pin_by_id [id];
|
||||
if (pi == pin_list::iterator ()) {
|
||||
return 0;
|
||||
} else {
|
||||
return pi.operator-> ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::rename_pin (size_t id, const std::string &name)
|
||||
{
|
||||
if (id < m_pins.size ()) {
|
||||
m_pins [id].set_name (name);
|
||||
if (id < m_pin_by_id.size () && m_pin_by_id [id] != pin_list::iterator ()) {
|
||||
m_pin_by_id [id]->set_name (name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,6 +220,7 @@ void Circuit::clear ()
|
|||
{
|
||||
m_name.clear ();
|
||||
m_pins.clear ();
|
||||
m_pin_by_id.clear ();
|
||||
m_devices.clear ();
|
||||
m_nets.clear ();
|
||||
m_subcircuits.clear ();
|
||||
|
|
@ -290,22 +304,33 @@ Circuit::const_child_circuit_iterator Circuit::end_parents () const
|
|||
void Circuit::clear_pins ()
|
||||
{
|
||||
m_pins.clear ();
|
||||
m_pin_by_id.clear ();
|
||||
}
|
||||
|
||||
const Pin &Circuit::add_pin (const Pin &pin)
|
||||
{
|
||||
m_pins.push_back (pin);
|
||||
m_pins.back ().set_id (m_pins.size () - 1);
|
||||
m_pins.back ().set_id (m_pin_by_id.size ());
|
||||
m_pin_by_id.push_back (--m_pins.end ());
|
||||
return m_pins.back ();
|
||||
}
|
||||
|
||||
const Pin &Circuit::add_pin (const std::string &name)
|
||||
{
|
||||
m_pins.push_back (Pin (name));
|
||||
m_pins.back ().set_id (m_pins.size () - 1);
|
||||
m_pins.back ().set_id (m_pin_by_id.size ());
|
||||
m_pin_by_id.push_back (--m_pins.end ());
|
||||
return m_pins.back ();
|
||||
}
|
||||
|
||||
void Circuit::remove_pin (size_t id)
|
||||
{
|
||||
if (id < m_pin_by_id.size () && m_pin_by_id [id] != pin_list::iterator ()) {
|
||||
m_pins.erase (m_pin_by_id [id]);
|
||||
m_pin_by_id [id] = pin_list::iterator ();
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::add_net (Net *net)
|
||||
{
|
||||
m_nets.push_back (net);
|
||||
|
|
@ -550,17 +575,58 @@ void Circuit::connect_pin (size_t pin_id, Net *net)
|
|||
}
|
||||
}
|
||||
|
||||
void Circuit::purge_nets_keep_pins ()
|
||||
{
|
||||
do_purge_nets (true);
|
||||
}
|
||||
|
||||
void Circuit::purge_nets ()
|
||||
{
|
||||
do_purge_nets (false);
|
||||
}
|
||||
|
||||
void Circuit::do_purge_nets (bool keep_pins)
|
||||
{
|
||||
std::vector<db::Net *> nets_to_be_purged;
|
||||
for (net_iterator n = begin_nets (); n != end_nets (); ++n) {
|
||||
if (n->is_floating ()) {
|
||||
if (n->is_passive ()) {
|
||||
nets_to_be_purged.push_back (n.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
std::set<size_t> pins_to_delete;
|
||||
|
||||
for (std::vector<db::Net *>::const_iterator n = nets_to_be_purged.begin (); n != nets_to_be_purged.end (); ++n) {
|
||||
if (! keep_pins) {
|
||||
for (db::Net::pin_iterator p = (*n)->begin_pins (); p != (*n)->end_pins (); ++p) {
|
||||
pins_to_delete.insert (p->pin_id ());
|
||||
}
|
||||
}
|
||||
delete *n;
|
||||
}
|
||||
|
||||
if (! pins_to_delete.empty ()) {
|
||||
|
||||
// remove the pin references of the pins we're going to delete
|
||||
for (refs_iterator r = begin_refs (); r != end_refs (); ++r) {
|
||||
db::SubCircuit *subcircuit = r.operator-> ();
|
||||
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
|
||||
db::Net *net = subcircuit->net_for_pin (*p);
|
||||
for (db::Net::subcircuit_pin_iterator sp = net->begin_subcircuit_pins (); sp != net->end_subcircuit_pins (); ++sp) {
|
||||
if (sp->pin_id () == *p && sp->subcircuit () == subcircuit) {
|
||||
net->erase_subcircuit_pin (sp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and actually remove those pins
|
||||
for (std::set<size_t>::const_iterator p = pins_to_delete.begin (); p != pins_to_delete.end (); ++p) {
|
||||
remove_pin (*p);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ class DB_PUBLIC Circuit
|
|||
: public db::NetlistObject, public gsi::ObjectBase
|
||||
{
|
||||
public:
|
||||
typedef tl::vector<Pin> pin_list;
|
||||
typedef std::list<Pin> pin_list;
|
||||
typedef pin_list::const_iterator const_pin_iterator;
|
||||
typedef pin_list::iterator pin_iterator;
|
||||
typedef tl::shared_collection<Device> device_list;
|
||||
|
|
@ -330,6 +330,11 @@ public:
|
|||
*/
|
||||
const Pin &add_pin (const Pin &pin);
|
||||
|
||||
/**
|
||||
* @brief Removes the pin with the given ID
|
||||
*/
|
||||
void remove_pin (size_t id);
|
||||
|
||||
/**
|
||||
* @brief Begin iterator for the pins of the circuit (non-const version)
|
||||
*/
|
||||
|
|
@ -708,10 +713,19 @@ public:
|
|||
/**
|
||||
* @brief Purge unused nets
|
||||
*
|
||||
* This method will purge all nets which return "floating".
|
||||
* This method will purge all nets which return "is_passive".
|
||||
* Pins on these nets will also be removed.
|
||||
*/
|
||||
void purge_nets ();
|
||||
|
||||
/**
|
||||
* @brief Purge unused nets but
|
||||
*
|
||||
* This method will purge all nets which return "is_passive".
|
||||
* Pins on these nets will be kept but their net will be 0.
|
||||
*/
|
||||
void purge_nets_keep_pins ();
|
||||
|
||||
/**
|
||||
* @brief Combine devices
|
||||
*
|
||||
|
|
@ -751,6 +765,7 @@ private:
|
|||
db::cell_index_type m_cell_index;
|
||||
net_list m_nets;
|
||||
pin_list m_pins;
|
||||
std::vector<pin_list::iterator> m_pin_by_id;
|
||||
device_list m_devices;
|
||||
subcircuit_list m_subcircuits;
|
||||
Netlist *mp_netlist;
|
||||
|
|
@ -780,6 +795,7 @@ private:
|
|||
void set_netlist (Netlist *netlist);
|
||||
bool combine_parallel_devices (const db::DeviceClass &cls);
|
||||
bool combine_serial_devices (const db::DeviceClass &cls);
|
||||
void do_purge_nets (bool keep_pins);
|
||||
|
||||
void devices_changed ();
|
||||
void subcircuits_changed ();
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ void Netlist::remove_device_abstract (DeviceAbstract *device_abstract)
|
|||
|
||||
void Netlist::purge_nets ()
|
||||
{
|
||||
for (circuit_iterator c = begin_circuits (); c != end_circuits (); ++c) {
|
||||
for (bottom_up_circuit_iterator c = begin_bottom_up (); c != end_bottom_up (); ++c) {
|
||||
c->purge_nets ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2951,14 +2951,34 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
// Report missing net assignment
|
||||
|
||||
for (db::NetGraph::node_iterator i = g1.begin (); i != g1.end (); ++i) {
|
||||
if (! i->has_other () && mp_logger) {
|
||||
mp_logger->net_mismatch (i->net (), 0);
|
||||
if (! i->has_other ()) {
|
||||
if (mp_logger) {
|
||||
if (good) {
|
||||
mp_logger->match_nets (i->net (), 0);
|
||||
} else {
|
||||
mp_logger->net_mismatch (i->net (), 0);
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
// in the "good" case, match the nets against 0
|
||||
g1.identify (g1.node_index_for_net (i->net ()), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (db::NetGraph::node_iterator i = g2.begin (); i != g2.end (); ++i) {
|
||||
if (! i->has_other () && mp_logger) {
|
||||
mp_logger->net_mismatch (0, i->net ());
|
||||
if (! i->has_other ()) {
|
||||
if (mp_logger) {
|
||||
if (good) {
|
||||
mp_logger->match_nets (0, i->net ());
|
||||
} else {
|
||||
mp_logger->net_mismatch (0, i->net ());
|
||||
}
|
||||
}
|
||||
if (good) {
|
||||
// in the "good" case, match the nets against 0
|
||||
g2.identify (g2.node_index_for_net (i->net ()), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2969,22 +2989,34 @@ NetlistComparer::compare_circuits (const db::Circuit *c1, const db::Circuit *c2,
|
|||
return good;
|
||||
}
|
||||
|
||||
void
|
||||
NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *pin2, bool &good, bool &pin_mismatch) const
|
||||
bool
|
||||
NetlistComparer::handle_pin_mismatch (const db::NetGraph &g1, const db::Circuit *c1, const db::Pin *pin1, const db::NetGraph &g2, const db::Circuit *c2, const db::Pin *pin2) const
|
||||
{
|
||||
const db::Circuit *c = pin1 ? c1 : c2;
|
||||
const db::Pin *pin = pin1 ? pin1 : pin2;
|
||||
const db::NetGraph *graph = pin1 ? &g1 : &g2;
|
||||
const db::Net *net = c->net_for_pin (pin->id ());
|
||||
|
||||
// If the pin isn't connected internally inside the circuit we can ignore it
|
||||
if (c->net_for_pin (pin->id ()) && c->net_for_pin (pin->id ())->is_passive ()) {
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
// Nets which are paired with "null" are "safely to be ignored" and
|
||||
// pin matching against "null" is valid.
|
||||
if (net) {
|
||||
const db::NetGraphNode &n = graph->node (graph->node_index_for_net (net));
|
||||
if (n.has_other () && n.other_net_index () == 0) {
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine whether the pin in question is used - only in this case we will report an error.
|
||||
// Otherwise, the report will be "match" against 0.
|
||||
// "used" follows a heuristic criterion derived from the subcircuits which make use of this circuit:
|
||||
// if one of these connects the pin to a net with either connections upwards, other subcircuits or
|
||||
// devices, the pin is regarded "used".
|
||||
// TODO: it would be better probably to have a global concept of "used pins" which considers all
|
||||
// devices and propagates their presence as "used" property upwards, then downwards to the subcircuit
|
||||
// pins.
|
||||
|
||||
bool is_not_connected = true;
|
||||
for (db::Circuit::const_refs_iterator r = c->begin_refs (); r != c->end_refs () && is_not_connected; ++r) {
|
||||
|
|
@ -2999,12 +3031,12 @@ NetlistComparer::handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1
|
|||
if (mp_logger) {
|
||||
mp_logger->match_pins (pin1, pin2);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (mp_logger) {
|
||||
mp_logger->pin_mismatch (pin1, pin2);
|
||||
}
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3042,18 +3074,21 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<const db::Pin *> abstract_pins;
|
||||
std::multimap<size_t, const db::Pin *> net2pin;
|
||||
std::vector<const db::Pin *> abstract_pins2;
|
||||
std::multimap<size_t, const db::Pin *> net2pin2;
|
||||
for (db::Circuit::const_pin_iterator p = c2->begin_pins (); p != c2->end_pins (); ++p) {
|
||||
const db::Net *net = c2->net_for_pin (p->id ());
|
||||
if (net) {
|
||||
net2pin.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
|
||||
net2pin2.insert (std::make_pair (g2.node_index_for_net (net), p.operator-> ()));
|
||||
} else if (abstract_pin_name_mapping.find (p.operator-> ()) == abstract_pin_name_mapping.end ()) {
|
||||
abstract_pins.push_back (p.operator-> ());
|
||||
abstract_pins2.push_back (p.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const db::Pin *>::iterator next_abstract = abstract_pins.begin ();
|
||||
// collect missing assignment for circuit 1
|
||||
std::multimap<size_t, const db::Pin *> net2pin1;
|
||||
|
||||
std::vector<const db::Pin *>::iterator next_abstract = abstract_pins2.begin ();
|
||||
|
||||
CircuitMapper &c12_pin_mapping = c12_circuit_and_pin_mapping [c1];
|
||||
c12_pin_mapping.set_other (c2);
|
||||
|
|
@ -3078,7 +3113,7 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
c12_pin_mapping.map_pin (p->id (), fp->second->id ());
|
||||
c22_pin_mapping.map_pin (fp->second->id (), p->id ());
|
||||
|
||||
} else if (next_abstract != abstract_pins.end ()) {
|
||||
} else if (next_abstract != abstract_pins2.end ()) {
|
||||
|
||||
// assign an abstract pin - this is a dummy assignment which is mitigated
|
||||
// by declaring the pins equivalent in derive_pin_equivalence
|
||||
|
|
@ -3093,7 +3128,10 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
} else {
|
||||
|
||||
// otherwise this is an error for subcircuits or worth a report for top-level circuits
|
||||
handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch);
|
||||
if (! handle_pin_mismatch (g1, c1, p.operator-> (), g2, c2, 0)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -3104,14 +3142,15 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
const db::NetGraphNode &n = *(g1.begin () + g1.node_index_for_net (net));
|
||||
|
||||
if (! n.has_other ()) {
|
||||
handle_pin_mismatch (c1, p.operator-> (), c2, 0, good, pin_mismatch);
|
||||
// remember and handle later when we know which pins are not mapped
|
||||
net2pin1.insert (std::make_pair (g1.node_index_for_net (net), p.operator-> ()));
|
||||
continue;
|
||||
}
|
||||
|
||||
std::multimap<size_t, const db::Pin *>::iterator np = net2pin.find (n.other_net_index ());
|
||||
std::multimap<size_t, const db::Pin *>::iterator np = net2pin2.find (n.other_net_index ());
|
||||
for (db::Net::const_pin_iterator pi = net->begin_pins (); pi != net->end_pins (); ++pi) {
|
||||
|
||||
if (np != net2pin.end () && np->first == n.other_net_index ()) {
|
||||
if (np != net2pin2.end () && np->first == n.other_net_index ()) {
|
||||
|
||||
if (mp_logger) {
|
||||
mp_logger->match_pins (pi->pin (), np->second);
|
||||
|
|
@ -3122,11 +3161,12 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
|
||||
std::multimap<size_t, const db::Pin *>::iterator np_delete = np;
|
||||
++np;
|
||||
net2pin.erase (np_delete);
|
||||
net2pin2.erase (np_delete);
|
||||
|
||||
} else {
|
||||
|
||||
handle_pin_mismatch (c1, pi->pin (), c2, 0, good, pin_mismatch);
|
||||
// remember and handle later when we know which pins are not mapped
|
||||
net2pin1.insert (std::make_pair (g1.node_index_for_net (net), p.operator-> ()));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -3134,16 +3174,28 @@ NetlistComparer::do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g
|
|||
|
||||
}
|
||||
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin.begin (); np != net2pin.end (); ++np) {
|
||||
handle_pin_mismatch (c1, 0, c2, np->second, good, pin_mismatch);
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin1.begin (); np != net2pin1.end (); ++np) {
|
||||
if (! handle_pin_mismatch (g1, c1, np->second, g2, c2, 0)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::multimap<size_t, const db::Pin *>::iterator np = net2pin2.begin (); np != net2pin2.end (); ++np) {
|
||||
if (! handle_pin_mismatch (g1, c1, 0, g2, c2, np->second)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
// abstract pins must match.
|
||||
while (next_abstract != abstract_pins.end ()) {
|
||||
handle_pin_mismatch (c1, 0, c2, *next_abstract, good, pin_mismatch);
|
||||
while (next_abstract != abstract_pins2.end ()) {
|
||||
if (! handle_pin_mismatch (g1, c1, 0, g2, c2, *next_abstract)) {
|
||||
good = false;
|
||||
pin_mismatch = true;
|
||||
}
|
||||
++next_abstract;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3384,7 +3436,7 @@ NetlistComparer::do_subcircuit_assignment (const db::Circuit *c1, const db::NetG
|
|||
|
||||
bool mapped = true;
|
||||
for (std::vector<std::pair<size_t, size_t> >::iterator i = k.begin (); i != k.end (); ++i) {
|
||||
if (! g1.begin () [i->second].has_other ()) {
|
||||
if (! g2.begin () [i->second].has_other ()) {
|
||||
mapped = false;
|
||||
} else {
|
||||
i->second = g2.begin () [i->second].other_net_index ();
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ protected:
|
|||
void do_pin_assignment (const db::Circuit *c1, const db::NetGraph &g1, const db::Circuit *c2, const db::NetGraph &g2, std::map<const db::Circuit *, CircuitMapper> &c12_circuit_and_pin_mapping, std::map<const db::Circuit *, CircuitMapper> &c22_circuit_and_pin_mapping, bool &pin_mismatch, bool &good) const;
|
||||
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, 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::CircuitPinMapper &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, bool &good) const;
|
||||
void handle_pin_mismatch (const db::Circuit *c1, const db::Pin *pin1, const db::Circuit *c2, const db::Pin *p2, bool &good, bool &pin_mismatch) 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;
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -508,8 +508,7 @@ NetlistCrossReference::build_pin_refs (const std::pair<const db::Net *, const db
|
|||
std::map<const db::Pin *, const db::Pin *>::const_iterator ipb = m_other_pin.find (pa);
|
||||
if (ipb != m_other_pin.end () && ipb->second) {
|
||||
|
||||
const db::Pin *pb = ipb->second;
|
||||
std::map<const Pin *, const db::NetPinRef *>::iterator b = p2r_b.find (pb);
|
||||
std::map<const Pin *, const db::NetPinRef *>::iterator b = p2r_b.find (ipb->second);
|
||||
if (b != p2r_b.end ()) {
|
||||
prb = b->second;
|
||||
// remove the entry so we won't find it again
|
||||
|
|
@ -558,7 +557,7 @@ NetlistCrossReference::build_subcircuit_pin_refs (const std::pair<const db::Net
|
|||
|
||||
const db::Pin *pa = sa->circuit_ref ()->pin_by_id (a->first.second);
|
||||
std::map<const db::Pin *, const db::Pin *>::const_iterator ipb = m_other_pin.find (pa);
|
||||
if (ipb != m_other_pin.end ()) {
|
||||
if (ipb != m_other_pin.end () && ipb->second) {
|
||||
|
||||
std::map<std::pair<const db::SubCircuit *, size_t>, const db::NetSubcircuitPinRef *>::iterator b = s2t_b.find (std::make_pair (sb, ipb->second->id ()));
|
||||
if (b != s2t_b.end ()) {
|
||||
|
|
|
|||
|
|
@ -288,11 +288,6 @@ void NetlistSpiceReader::finish ()
|
|||
pop_stream ();
|
||||
}
|
||||
|
||||
// purge nets with single connections (this way unconnected pins can be realized)
|
||||
if (mp_netlist) {
|
||||
mp_netlist->purge_nets ();
|
||||
}
|
||||
|
||||
mp_stream.reset (0);
|
||||
mp_netlist = 0;
|
||||
mp_circuit = 0;
|
||||
|
|
|
|||
|
|
@ -1131,6 +1131,11 @@ Class<db::Circuit> decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit",
|
|||
"to the outside through such a pin. The pin is added after all existing "
|
||||
"pins. For more details see the \\Pin class."
|
||||
) +
|
||||
gsi::method ("remove_pin", &db::Circuit::remove_pin, gsi::arg ("id"),
|
||||
"@brief Removes the pin with the given ID from the circuit\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2.\n"
|
||||
) +
|
||||
gsi::iterator ("each_child", (db::Circuit::child_circuit_iterator (db::Circuit::*) ()) &db::Circuit::begin_children, (db::Circuit::child_circuit_iterator (db::Circuit::*) ()) &db::Circuit::end_children,
|
||||
"@brief Iterates over the child circuits of this circuit\n"
|
||||
"Child circuits are the ones that are referenced from this circuit via subcircuits."
|
||||
|
|
@ -1311,8 +1316,16 @@ Class<db::Circuit> decl_dbCircuit (decl_dbNetlistObject, "db", "Circuit",
|
|||
) +
|
||||
gsi::method ("purge_nets", &db::Circuit::purge_nets,
|
||||
"@brief Purges floating nets.\n"
|
||||
"Floating nets can be created as effect of reconnections of devices or pins. "
|
||||
"This method will eliminate all nets that make less than two connections."
|
||||
"Floating nets are nets with no device or subcircuit attached to. Such floating "
|
||||
"nets are removed in this step. If these nets are connected outward to a circuit pin, this "
|
||||
"circuit pin is also removed."
|
||||
) +
|
||||
gsi::method ("purge_nets_keep_pins", &db::Circuit::purge_nets_keep_pins,
|
||||
"@brief Purges floating nets but keep pins.\n"
|
||||
"This method will remove floating nets like \\purge_nets, but if these nets are attached "
|
||||
"to a pin, the pin will be left disconnected from any net.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2.\n"
|
||||
),
|
||||
"@brief Circuits are the basic building blocks of the netlist\n"
|
||||
"A circuit has pins by which it can connect to the outside. Pins are "
|
||||
|
|
|
|||
|
|
@ -2055,11 +2055,11 @@ TEST(14_Subcircuit2NandMismatchNoSwap)
|
|||
"net_mismatch INT IN1\n"
|
||||
"net_mismatch IN1 INT\n"
|
||||
"net_mismatch IN2 IN2\n"
|
||||
"match_pins $0 (null)\n"
|
||||
"match_pins $1 $1\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins $3 $3\n"
|
||||
"match_pins $4 $4\n"
|
||||
"match_pins $0 (null)\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_subcircuits $2 $1\n"
|
||||
"subcircuit_mismatch $1 $2\n"
|
||||
|
|
@ -3366,3 +3366,340 @@ TEST(21_BusLikeAmbiguousConnections)
|
|||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
||||
TEST(22_NodesRemoved)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
" subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
" subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) $1\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_nets (null) $I1\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_pins (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR MATCH\n"
|
||||
"begin_circuit RINGO RINGO\n"
|
||||
"match_nets OSC OSC\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I6 $I6\n"
|
||||
"match_nets $I5 $I5\n"
|
||||
"match_nets $I21 $I13\n"
|
||||
"match_nets FB FB\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets $I22 $I22\n"
|
||||
"match_nets $I23 $I23\n"
|
||||
"match_nets $I24 $I24\n"
|
||||
"match_nets $I25 $I25\n"
|
||||
"match_pins FB FB\n"
|
||||
"match_pins OSC OSC\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $3 $3\n"
|
||||
"match_subcircuits $4 $4\n"
|
||||
"match_subcircuits $5 $5\n"
|
||||
"end_circuit RINGO RINGO MATCH"
|
||||
);
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
||||
TEST(23_NodesRemovedWithError)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
// NOTE: $1 pin should not be connected to different nets, although it's not functional
|
||||
" subcircuit INV2 $1 ($1=$3,IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 ($1=$6,IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
" subcircuit INV2 $2 ($1=$I1,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=BULK);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets $1 $1\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins $0 $0\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $2 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"net_mismatch $3 $I1\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"net_mismatch $6 BULK\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"pin_mismatch (null) BULK\n"
|
||||
"pin_mismatch (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"subcircuit_mismatch $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR NOMATCH\n"
|
||||
"circuit_skipped RINGO RINGO"
|
||||
);
|
||||
EXPECT_EQ (good, false);
|
||||
}
|
||||
|
||||
TEST(24_NodesRemovedButConnectedInOther)
|
||||
{
|
||||
const char *nls1 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 ($2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC);\n"
|
||||
" subcircuit INV2PAIR $2 ($2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I21);\n"
|
||||
" subcircuit INV2PAIR $3 ($2=$I23,$3=VDD,$4=VSS,$5=$I21,$6=$I5);\n"
|
||||
" subcircuit INV2PAIR $4 ($2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6);\n"
|
||||
" subcircuit INV2PAIR $5 ($2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7);\n"
|
||||
"end;\n"
|
||||
"circuit INV2PAIR ($2=$I8,$3=$I5,$4=$I4,$5=$I3,$6=$I2);\n"
|
||||
" subcircuit INV2 $1 (IN=$I3,$3=$I7,OUT=$I6,VSS=$I4,VDD=$I5);\n"
|
||||
" subcircuit INV2 $2 (IN=$I6,$3=$I8,OUT=$I2,VSS=$I4,VDD=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
const char *nls2 =
|
||||
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
|
||||
" subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
|
||||
" subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);\n"
|
||||
"end;\n"
|
||||
// rewired here: BULK->VSS (pin $4), $1->$I3/$I4 (both rewired pins are deleted in the first netlist)
|
||||
// This proves that we can basically do everything with the dropped pins.
|
||||
"circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);\n"
|
||||
" subcircuit INV2 $1 ($1=$I3,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=$I5);\n"
|
||||
" subcircuit INV2 $2 ($1=$I4,IN=$I4,$3=$I8,OUT=$I2,VSS=$I5,VDD=$I6,BULK=$I5);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 ($1=$1,IN=IN,$3=$3,OUT=OUT,VSS=VSS,VDD=VDD,BULK=BULK);\n"
|
||||
" device PMOS $1 (S=$3,G=IN,D=VDD) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=VDD,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$3,G=IN,D=VSS) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=VSS,G=$3,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n";
|
||||
|
||||
db::Netlist nl1, nl2;
|
||||
prep_nl (nl1, nls1);
|
||||
prep_nl (nl2, nls2);
|
||||
|
||||
NetlistCompareTestLogger logger;
|
||||
db::NetlistComparer comp (&logger);
|
||||
|
||||
bool good = comp.compare (&nl1, &nl2);
|
||||
|
||||
std::string txt = logger.text ();
|
||||
|
||||
EXPECT_EQ (txt,
|
||||
"begin_circuit INV2 INV2\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets OUT OUT\n"
|
||||
"match_nets $3 $3\n"
|
||||
"match_nets IN IN\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets (null) $1\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_pins IN IN\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins OUT OUT\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins (null) $0\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_devices $1 $1\n"
|
||||
"match_devices $2 $2\n"
|
||||
"match_devices $3 $3\n"
|
||||
"match_devices $4 $4\n"
|
||||
"end_circuit INV2 INV2 MATCH\n"
|
||||
"begin_circuit INV2PAIR INV2PAIR\n"
|
||||
"match_nets $I2 $I2\n"
|
||||
"match_nets $I5 $I6\n"
|
||||
"match_nets $I4 $I5\n"
|
||||
"match_nets $I6 $I4\n"
|
||||
"match_nets $I3 $I3\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I8 $I8\n"
|
||||
"match_nets (null) BULK\n"
|
||||
"match_nets (null) $I1\n"
|
||||
"match_pins $0 $1\n"
|
||||
"match_pins $1 $2\n"
|
||||
"match_pins $2 $3\n"
|
||||
"match_pins $3 $4\n"
|
||||
"match_pins $4 $5\n"
|
||||
"match_pins (null) BULK\n"
|
||||
"match_pins (null) $6\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"end_circuit INV2PAIR INV2PAIR MATCH\n"
|
||||
"begin_circuit RINGO RINGO\n"
|
||||
"match_nets OSC OSC\n"
|
||||
"match_nets $I7 $I7\n"
|
||||
"match_nets $I6 $I6\n"
|
||||
"match_nets $I5 $I5\n"
|
||||
"match_nets $I21 $I13\n"
|
||||
"match_nets FB FB\n"
|
||||
"match_nets VSS VSS\n"
|
||||
"match_nets VDD VDD\n"
|
||||
"match_nets $I22 $I22\n"
|
||||
"match_nets $I23 $I23\n"
|
||||
"match_nets $I24 $I24\n"
|
||||
"match_nets $I25 $I25\n"
|
||||
"match_pins FB FB\n"
|
||||
"match_pins OSC OSC\n"
|
||||
"match_pins VDD VDD\n"
|
||||
"match_pins VSS VSS\n"
|
||||
"match_subcircuits $1 $1\n"
|
||||
"match_subcircuits $2 $2\n"
|
||||
"match_subcircuits $3 $3\n"
|
||||
"match_subcircuits $4 $4\n"
|
||||
"match_subcircuits $5 $5\n"
|
||||
"end_circuit RINGO RINGO MATCH"
|
||||
);
|
||||
EXPECT_EQ (good, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2573,3 +2573,134 @@ TEST(12_FloatingSubcircuitExtraction)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(13_RemoveDummyPins)
|
||||
{
|
||||
db::Layout ly;
|
||||
db::LayerMap lmap;
|
||||
|
||||
unsigned int nwell = define_layer (ly, lmap, 1);
|
||||
unsigned int active = define_layer (ly, lmap, 2);
|
||||
unsigned int poly = define_layer (ly, lmap, 3);
|
||||
unsigned int poly_lbl = define_layer (ly, lmap, 3, 1);
|
||||
unsigned int diff_cont = define_layer (ly, lmap, 4);
|
||||
unsigned int poly_cont = define_layer (ly, lmap, 5);
|
||||
unsigned int metal1 = define_layer (ly, lmap, 6);
|
||||
unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1);
|
||||
unsigned int via1 = define_layer (ly, lmap, 7);
|
||||
unsigned int metal2 = define_layer (ly, lmap, 8);
|
||||
unsigned int metal2_lbl = define_layer (ly, lmap, 8, 1);
|
||||
|
||||
{
|
||||
db::LoadLayoutOptions options;
|
||||
options.get_options<db::CommonReaderOptions> ().layer_map = lmap;
|
||||
options.get_options<db::CommonReaderOptions> ().create_other_layers = false;
|
||||
|
||||
std::string fn (tl::testsrc ());
|
||||
fn = tl::combine_path (fn, "testdata");
|
||||
fn = tl::combine_path (fn, "algo");
|
||||
fn = tl::combine_path (fn, "issue-425.gds");
|
||||
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (ly, options);
|
||||
}
|
||||
|
||||
db::Cell &tc = ly.cell (*ly.begin_top_down ());
|
||||
|
||||
db::DeepShapeStore dss;
|
||||
dss.set_text_enlargement (1);
|
||||
dss.set_text_property_name (tl::Variant ("LABEL"));
|
||||
|
||||
// original layers
|
||||
db::Region rnwell (db::RecursiveShapeIterator (ly, tc, nwell), dss);
|
||||
db::Region ractive (db::RecursiveShapeIterator (ly, tc, active), dss);
|
||||
db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss);
|
||||
db::Region rpoly_lbl (db::RecursiveShapeIterator (ly, tc, poly_lbl), dss);
|
||||
db::Region rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss);
|
||||
db::Region rpoly_cont (db::RecursiveShapeIterator (ly, tc, poly_cont), dss);
|
||||
db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss);
|
||||
db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss);
|
||||
db::Region rvia1 (db::RecursiveShapeIterator (ly, tc, via1), dss);
|
||||
db::Region rmetal2 (db::RecursiveShapeIterator (ly, tc, metal2), dss);
|
||||
db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss);
|
||||
|
||||
// derived regions
|
||||
|
||||
db::Region rpactive = ractive & rnwell;
|
||||
db::Region rpgate = rpactive & rpoly;
|
||||
db::Region rpsd = rpactive - rpgate;
|
||||
|
||||
db::Region rnactive = ractive - rnwell;
|
||||
db::Region rngate = rnactive & rpoly;
|
||||
db::Region rnsd = rnactive - rngate;
|
||||
|
||||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
||||
db::NetlistDeviceExtractor::input_layers dl;
|
||||
|
||||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, 0, dl, nl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
db::Connectivity conn;
|
||||
// Intra-layer
|
||||
conn.connect (rpsd);
|
||||
conn.connect (rnsd);
|
||||
conn.connect (rpoly);
|
||||
conn.connect (rdiff_cont);
|
||||
conn.connect (rpoly_cont);
|
||||
conn.connect (rmetal1);
|
||||
conn.connect (rvia1);
|
||||
conn.connect (rmetal2);
|
||||
// Inter-layer
|
||||
conn.connect (rpsd, rdiff_cont);
|
||||
conn.connect (rnsd, rdiff_cont);
|
||||
conn.connect (rpoly, rpoly_cont);
|
||||
conn.connect (rpoly_cont, rmetal1);
|
||||
conn.connect (rdiff_cont, rmetal1);
|
||||
conn.connect (rmetal1, rvia1);
|
||||
conn.connect (rvia1, rmetal2);
|
||||
conn.connect (rpoly, rpoly_lbl); // attaches labels
|
||||
conn.connect (rmetal1, rmetal1_lbl); // attaches labels
|
||||
conn.connect (rmetal2, rmetal2_lbl); // attaches labels
|
||||
|
||||
// extract the nets
|
||||
|
||||
db::NetlistExtractor net_ex;
|
||||
net_ex.set_include_floating_subcircuits (true);
|
||||
net_ex.extract_nets (dss, 0, conn, nl, cl);
|
||||
|
||||
nl.simplify ();
|
||||
|
||||
// compare netlist as string
|
||||
CHECKPOINT ();
|
||||
db::compare_netlist (_this, nl,
|
||||
"circuit RINGO (FB=FB,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 $1 (IN=FB,OUT=$I25,$3=VSS,$4=VDD);\n"
|
||||
" subcircuit INV2 $2 (IN=$I25,OUT=$I1,$3=VSS,$4=VDD);\n"
|
||||
" subcircuit INV2 $3 (IN=$I1,OUT=$I2,$3=VSS,$4=VDD);\n"
|
||||
" subcircuit INV2 $4 (IN=$I2,OUT=$I3,$3=VSS,$4=VDD);\n"
|
||||
"end;\n"
|
||||
"circuit INV2 (IN=IN,OUT=OUT,$3=$4,$4=$5);\n"
|
||||
" device PMOS $1 (S=$2,G=IN,D=$5) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device PMOS $2 (S=$5,G=$2,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
" device NMOS $3 (S=$2,G=IN,D=$4) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
|
||||
" device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
|
||||
"end;\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,6 +360,17 @@ TEST(3_CircuitBasic)
|
|||
EXPECT_EQ (c2.pin_by_id (0)->name (), "p1");
|
||||
EXPECT_EQ (c2.pin_by_id (1)->name (), "p2");
|
||||
EXPECT_EQ (c2.pin_by_id (2), 0);
|
||||
|
||||
c2.remove_pin (1);
|
||||
EXPECT_EQ (c2.pin_by_id (0)->name (), "p1");
|
||||
EXPECT_EQ (c2.pin_by_id (1), 0);
|
||||
EXPECT_EQ (c2.pin_by_id (2), 0);
|
||||
|
||||
db::Pin p3 = c2.add_pin ("p3");
|
||||
EXPECT_EQ (c2.pin_by_id (0)->name (), "p1");
|
||||
EXPECT_EQ (c2.pin_by_id (1), 0);
|
||||
EXPECT_EQ (c2.pin_by_id (2)->name (), "p3");
|
||||
EXPECT_EQ (c2.pin_by_id (3), 0);
|
||||
}
|
||||
|
||||
TEST(4_CircuitDevices)
|
||||
|
|
@ -1393,7 +1404,7 @@ TEST(22_BlankCircuit)
|
|||
nl2.purge ();
|
||||
|
||||
EXPECT_EQ (nl2.to_string (),
|
||||
"circuit RINGO (IN=IN,OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
"circuit RINGO (OSC=OSC,VSS=VSS,VDD=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
|
||||
" subcircuit INV2 INV2_SC2 (IN=FB,$2=(null),OUT=$I8,$4=VSS,$5=VDD);\n"
|
||||
"end;\n"
|
||||
|
|
|
|||
|
|
@ -30,22 +30,14 @@
|
|||
#include "lymMacro.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
void run_test (tl::TestBase *_this, const std::string &lvs_rs, const std::string &suffix, const std::string &layout)
|
||||
void run_test (tl::TestBase *_this, const std::string &lvs_rs, const std::string &au_netlist, const std::string &layout, bool priv = false)
|
||||
{
|
||||
std::string rs = tl::testsrc ();
|
||||
rs += "/testdata/lvs/" + lvs_rs;
|
||||
std::string testsrc = priv ? tl::testsrc_private () : tl::testsrc ();
|
||||
testsrc = tl::combine_path (tl::combine_path (testsrc, "testdata"), "lvs");
|
||||
|
||||
std::string src = tl::testsrc ();
|
||||
src += "/testdata/lvs/" + layout;
|
||||
|
||||
std::string au_lvsdb = tl::testsrc ();
|
||||
au_lvsdb += "/testdata/lvs/" + suffix + ".lvsdb.gz";
|
||||
|
||||
std::string au_cir = tl::testsrc ();
|
||||
au_cir += "/testdata/lvs/" + suffix + ".cir.gz";
|
||||
|
||||
std::string au_l2n = tl::testsrc ();
|
||||
au_l2n += "/testdata/lvs/" + suffix + ".l2n.gz";
|
||||
std::string rs = tl::combine_path (testsrc, lvs_rs);
|
||||
std::string ly = tl::combine_path (testsrc, layout);
|
||||
std::string au_cir = tl::combine_path (testsrc, au_netlist);
|
||||
|
||||
std::string output_lvsdb = _this->tmp_file ("tmp.lvsdb");
|
||||
std::string output_cir = _this->tmp_file ("tmp.cir");
|
||||
|
|
@ -59,7 +51,7 @@ void run_test (tl::TestBase *_this, const std::string &lvs_rs, const std::string
|
|||
"$lvs_test_target_lvsdb = '%s'\n"
|
||||
"$lvs_test_target_cir = '%s'\n"
|
||||
"$lvs_test_target_l2n = '%s'\n"
|
||||
, src, output_lvsdb, output_cir, output_l2n)
|
||||
, ly, output_lvsdb, output_cir, output_l2n)
|
||||
);
|
||||
config.set_interpreter (lym::Macro::Ruby);
|
||||
EXPECT_EQ (config.run (), 0);
|
||||
|
|
@ -101,11 +93,53 @@ void run_test (tl::TestBase *_this, const std::string &lvs_rs, const std::string
|
|||
TEST(1_full)
|
||||
{
|
||||
test_is_long_runner ();
|
||||
run_test (_this, "vexriscv.lvs", "vexriscv", "vexriscv.oas.gz");
|
||||
run_test (_this, "vexriscv.lvs", "vexriscv.cir.gz", "vexriscv.oas.gz");
|
||||
}
|
||||
|
||||
TEST(2_fullWithAlign)
|
||||
{
|
||||
test_is_long_runner ();
|
||||
run_test (_this, "vexriscv_align.lvs", "vexriscv", "vexriscv.oas.gz");
|
||||
run_test (_this, "vexriscv_align.lvs", "vexriscv.cir.gz", "vexriscv.oas.gz");
|
||||
}
|
||||
|
||||
TEST(10_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_10.lvs", "test_10.cir.gz", "test_10.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(11_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_11.lvs", "test_11.cir.gz", "test_11.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(12_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_12.lvs", "test_12.cir.gz", "test_12.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(13_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_13.lvs", "test_13.cir.gz", "test_13.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(14_private)
|
||||
{
|
||||
test_is_long_runner ();
|
||||
run_test (_this, "test_14.lvs", "test_14.cir.gz", "test_14.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(15_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_15.lvs", "test_15.cir.gz", "test_15.gds.gz", true);
|
||||
}
|
||||
|
||||
TEST(16_private)
|
||||
{
|
||||
// test_is_long_runner ();
|
||||
run_test (_this, "test_16.lvs", "test_16.cir.gz", "test_16.gds.gz", true);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1120,7 +1120,7 @@ xref(
|
|||
circuit(3 () mismatch)
|
||||
circuit(4 () mismatch)
|
||||
circuit(5 () mismatch)
|
||||
circuit(1 1 mismatch)
|
||||
circuit(1 1 match)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1120,7 +1120,7 @@ xref(
|
|||
circuit(3 () mismatch)
|
||||
circuit(4 () mismatch)
|
||||
circuit(5 () mismatch)
|
||||
circuit(1 1 mismatch)
|
||||
circuit(1 1 match)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,30 +1,25 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT INVCHAIN
|
||||
X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3
|
||||
X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2
|
||||
X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV
|
||||
.SUBCKT INVCHAIN IN OUT VSS VDD
|
||||
X$1 IN \$2 \$3 \$2 \$3 \$4 VDD VSS INV3
|
||||
X$2 \$5 \$6 \$4 \$5 VDD VSS INV2
|
||||
X$3 VSS VDD \$6 OUT INV
|
||||
.ENDS INVCHAIN
|
||||
|
||||
.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV
|
||||
X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV
|
||||
X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV
|
||||
.SUBCKT INV3 3 5 7 4 6 8 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 3 4 INV
|
||||
X$2 \$I2 \$I4 5 6 INV
|
||||
X$3 \$I2 \$I4 7 8 INV
|
||||
.ENDS INV3
|
||||
|
||||
.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5
|
||||
+ \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV
|
||||
X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV
|
||||
.SUBCKT INV2 \$I8 \$I7 \$I6 \$I5 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I6 \$I8 INV
|
||||
X$2 \$I2 \$I4 \$I5 \$I7 INV
|
||||
.ENDS INV2
|
||||
|
||||
.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$9 \$I8 \$I7
|
||||
M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$4 \$1 \$I7 \$9 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
.SUBCKT INV \$1 \$2 \$3 \$4
|
||||
M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U
|
||||
+ PD=3.45U
|
||||
M$2 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.73625P AD=0.73625P PS=3.45U
|
||||
+ PD=3.45U
|
||||
.ENDS INV
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT INVCHAIN
|
||||
X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3
|
||||
X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2
|
||||
X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV
|
||||
.ENDS INVCHAIN
|
||||
|
||||
.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV
|
||||
X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV
|
||||
X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV
|
||||
.ENDS INV3
|
||||
|
||||
.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5
|
||||
+ \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV
|
||||
X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV
|
||||
.ENDS INV2
|
||||
|
||||
.SUBCKT INV \$1 \$2 \$3 \$4 \$5 \$8 \$I8 \$I7
|
||||
M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$2 \$2 \$I8 \$5 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$4 \$1 \$I7 \$8 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
.ENDS INV
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT INVCHAIN
|
||||
X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3
|
||||
X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2
|
||||
X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV
|
||||
.ENDS INVCHAIN
|
||||
|
||||
.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV
|
||||
X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV
|
||||
X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV
|
||||
.ENDS INV3
|
||||
|
||||
.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5
|
||||
+ \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV
|
||||
X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV
|
||||
.ENDS INV2
|
||||
|
||||
.SUBCKT INV \$1 \$2 \$3 \$4 \$7 \$10 \$I8 \$I7
|
||||
M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$2 \$2 \$I8 \$7 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$4 \$1 \$I7 \$10 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
.ENDS INV
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
* Extracted by KLayout
|
||||
|
||||
.SUBCKT INVCHAIN
|
||||
X$1 \$7 \$1 \$9 \$8 \$6 \$9 \$5 \$5 \$3 \$2 \$I2 \$I1 INV3
|
||||
X$2 \$8 \$11 \$9 \$10 \$8 \$11 \$2 \$I3 \$2 \$I3 \$5 \$4 \$I2 \$I1 INV2
|
||||
X$3 \$I1 \$I2 \$11 \$I3 \$4 \$4 \$10 \$10 INV
|
||||
.ENDS INVCHAIN
|
||||
|
||||
.SUBCKT INV3 \$I18 \$I17 \$I15 \$I14 \$I13 \$I11 \$I10 \$I8 \$I7 \$I5 \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I13 \$I17 \$I7 \$I7 \$I18 \$I18 INV
|
||||
X$2 \$I2 \$I4 \$I18 \$I7 \$I17 \$I17 \$I13 \$I13 INV
|
||||
X$3 \$I2 \$I4 \$I14 \$I5 \$I8 \$I10 \$I15 \$I11 INV
|
||||
.ENDS INV3
|
||||
|
||||
.SUBCKT INV2 \$I16 \$I15 \$I14 \$I13 \$I12 \$I11 \$I10 \$I9 \$I8 \$I7 \$I6 \$I5
|
||||
+ \$I4 \$I2
|
||||
X$1 \$I2 \$I4 \$I14 \$I6 \$I8 \$I10 \$I16 \$I12 INV
|
||||
X$2 \$I2 \$I4 \$I13 \$I5 \$I7 \$I9 \$I15 \$I11 INV
|
||||
.ENDS INV2
|
||||
|
||||
.SUBCKT INV \$1 \$2 \$3 \$4 \$6 \$9 \$I8 \$I7
|
||||
M$1 \$4 \$3 \$2 \$4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$2 \$2 \$I8 \$6 \$2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
M$3 \$4 \$3 \$1 \$4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U
|
||||
+ PD=1.5U
|
||||
M$4 \$1 \$I7 \$9 \$1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U
|
||||
+ PD=1.97U
|
||||
.ENDS INV
|
||||
|
|
@ -6,7 +6,52 @@ report_lvs($lvs_test_target_lvsdb)
|
|||
writer = write_spice(true, false)
|
||||
target_netlist($lvs_test_target_cir, writer, "Extracted by KLayout")
|
||||
|
||||
schematic("invchain_for_cheat.cir")
|
||||
# needs this delegate because we use MOS3 which is not available in Spice
|
||||
class SpiceReaderDelegate < RBA::NetlistSpiceReaderDelegate
|
||||
|
||||
# says we want to catch these subcircuits as devices
|
||||
def wants_subcircuit(name)
|
||||
name == "HVNMOS" || name == "HVPMOS"
|
||||
end
|
||||
|
||||
# translate the element
|
||||
def element(circuit, el, name, model, value, nets, params)
|
||||
|
||||
if el != "M"
|
||||
# all other elements are left to the standard implementation
|
||||
return super
|
||||
end
|
||||
|
||||
if nets.size != 4
|
||||
error("Device #{model} needs four nodes")
|
||||
end
|
||||
|
||||
# provide a device class
|
||||
cls = circuit.netlist.device_class_by_name(model)
|
||||
if ! cls
|
||||
cls = RBA::DeviceClassMOS3Transistor::new
|
||||
cls.name = model
|
||||
circuit.netlist.add(cls)
|
||||
end
|
||||
|
||||
# create a device
|
||||
device = circuit.create_device(cls, name)
|
||||
|
||||
# and configure the device
|
||||
[ "S", "G", "D" ].each_with_index do |t,index|
|
||||
device.connect_terminal(t, nets[index])
|
||||
end
|
||||
device.set_parameter("W", params["W"] * 1e6)
|
||||
device.set_parameter("L", params["L"] * 1e6)
|
||||
|
||||
device
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
reader = RBA::NetlistSpiceReader::new(SpiceReaderDelegate::new)
|
||||
schematic("invchain_for_cheat.cir", reader)
|
||||
|
||||
deep
|
||||
|
||||
|
|
@ -15,32 +60,38 @@ deep
|
|||
nwell = input(1, 0)
|
||||
active = input(2, 0)
|
||||
poly = input(3, 0)
|
||||
poly_lbl = input(3, 1)
|
||||
diff_cont = input(4, 0)
|
||||
poly_cont = input(5, 0)
|
||||
metal1 = input(6, 0)
|
||||
metal1_lbl = input(6, 1)
|
||||
via1 = input(7, 0)
|
||||
metal2 = input(8, 0)
|
||||
metal2_lbl = input(8, 1)
|
||||
|
||||
# Bulk layer for terminal provisioning
|
||||
|
||||
bulk = polygon_layer
|
||||
|
||||
# Computed layers
|
||||
|
||||
active_in_nwell = active & nwell
|
||||
pactive = active_in_nwell
|
||||
pgate = pactive & poly
|
||||
psd = pactive - pgate
|
||||
|
||||
active_outside_nwell = active - nwell
|
||||
nactive = active_outside_nwell
|
||||
ngate = nactive & poly
|
||||
nsd = nactive - ngate
|
||||
|
||||
# Device extraction
|
||||
psd = nil
|
||||
nsd = nil
|
||||
|
||||
cheat("INV") do
|
||||
|
||||
# Computed layers
|
||||
|
||||
active_in_nwell = active & nwell
|
||||
pactive = active_in_nwell
|
||||
pgate = pactive & poly
|
||||
psd = pactive - pgate
|
||||
|
||||
active_outside_nwell = active - nwell
|
||||
nactive = active_outside_nwell
|
||||
ngate = nactive & poly
|
||||
nsd = nactive - ngate
|
||||
|
||||
# Device extraction
|
||||
|
||||
# PMOS transistor device extraction
|
||||
extract_devices(mos3("PMOS"), { "SD" => psd, "G" => pgate,
|
||||
"tS" => psd, "tD" => psd, "tG" => poly })
|
||||
|
|
@ -62,12 +113,18 @@ connect(poly_cont, metal1)
|
|||
connect(metal1, via1)
|
||||
connect(via1, metal2)
|
||||
|
||||
# attach labels
|
||||
connect(poly, poly_lbl)
|
||||
connect(metal1, metal1_lbl)
|
||||
connect(metal2, metal2_lbl)
|
||||
|
||||
# Global
|
||||
connect_global(bulk, "SUBSTRATE")
|
||||
|
||||
# Compare section
|
||||
|
||||
netlist.simplify
|
||||
align
|
||||
|
||||
compare
|
||||
|
||||
|
|
|
|||
|
|
@ -3,66 +3,50 @@ J(
|
|||
W(INVCHAIN)
|
||||
U(0.001)
|
||||
L(l3 '3/0')
|
||||
L(l11 '3/1')
|
||||
L(l6 '4/0')
|
||||
L(l7 '2/0')
|
||||
L(l7 '5/0')
|
||||
L(l8 '6/0')
|
||||
L(l12 '6/1')
|
||||
L(l9 '7/0')
|
||||
L(l10 '8/0')
|
||||
L(l11)
|
||||
L(l13 '8/1')
|
||||
L(l14)
|
||||
L(l2)
|
||||
L(l5)
|
||||
C(l3 l3 l7)
|
||||
C(l3 l3 l11 l7)
|
||||
C(l11 l3 l11)
|
||||
C(l6 l6 l8 l2 l5)
|
||||
C(l7 l3 l7 l8)
|
||||
C(l8 l6 l7 l8 l9)
|
||||
C(l8 l6 l7 l8 l12 l9)
|
||||
C(l12 l8 l12)
|
||||
C(l9 l8 l9 l10)
|
||||
C(l10 l9 l10)
|
||||
C(l11 l11)
|
||||
C(l10 l9 l10 l13)
|
||||
C(l13 l10 l13)
|
||||
C(l14 l14)
|
||||
C(l2 l6 l2)
|
||||
C(l5 l6 l5)
|
||||
G(l11 SUBSTRATE)
|
||||
G(l14 SUBSTRATE)
|
||||
D(D$PMOS PMOS
|
||||
T(S
|
||||
R(l2 (-960 -475) (835 950))
|
||||
R(l2 (-900 -475) (775 950))
|
||||
)
|
||||
T(G
|
||||
R(l3 (-125 -475) (250 950))
|
||||
)
|
||||
T(D
|
||||
R(l2 (125 -475) (550 950))
|
||||
)
|
||||
)
|
||||
D(D$PMOS$1 PMOS
|
||||
T(S
|
||||
R(l2 (-675 -475) (550 950))
|
||||
)
|
||||
T(G
|
||||
R(l3 (-125 -475) (250 950))
|
||||
)
|
||||
T(D
|
||||
R(l2 (125 -475) (35 950))
|
||||
R(l2 (125 -475) (775 950))
|
||||
)
|
||||
)
|
||||
D(D$NMOS NMOS
|
||||
T(S
|
||||
R(l5 (-960 -475) (835 950))
|
||||
R(l5 (-900 -475) (775 950))
|
||||
)
|
||||
T(G
|
||||
R(l3 (-125 -475) (250 950))
|
||||
)
|
||||
T(D
|
||||
R(l5 (125 -475) (550 950))
|
||||
)
|
||||
)
|
||||
D(D$NMOS$1 NMOS
|
||||
T(S
|
||||
R(l5 (-675 -475) (550 950))
|
||||
)
|
||||
T(G
|
||||
R(l3 (-125 -475) (250 950))
|
||||
)
|
||||
T(D
|
||||
R(l5 (125 -475) (35 950))
|
||||
R(l5 (125 -475) (775 950))
|
||||
)
|
||||
)
|
||||
X(INV
|
||||
|
|
@ -74,7 +58,7 @@ J(
|
|||
R(l9 (-305 -705) (250 250))
|
||||
R(l9 (-250 150) (250 250))
|
||||
R(l10 (-2025 -775) (3000 900))
|
||||
R(l5 (-1375 -925) (550 950))
|
||||
R(l5 (-1375 -925) (775 950))
|
||||
)
|
||||
N(2
|
||||
R(l6 (290 2490) (220 220))
|
||||
|
|
@ -83,7 +67,7 @@ J(
|
|||
R(l9 (-305 -705) (250 250))
|
||||
R(l9 (-250 150) (250 250))
|
||||
R(l10 (-2025 -775) (3000 900))
|
||||
R(l2 (-1375 -925) (550 950))
|
||||
R(l2 (-1375 -925) (775 950))
|
||||
)
|
||||
N(3
|
||||
R(l3 (-125 -250) (250 2500))
|
||||
|
|
@ -98,99 +82,55 @@ J(
|
|||
R(l8 (-290 -3530) (360 2840))
|
||||
R(l8 (-360 -2800) (360 760))
|
||||
R(l8 (-360 2040) (360 760))
|
||||
R(l2 (-740 -855) (835 950))
|
||||
R(l5 (-835 -3750) (835 950))
|
||||
R(l2 (-680 -855) (775 950))
|
||||
R(l5 (-775 -3750) (775 950))
|
||||
)
|
||||
N(5
|
||||
R(l2 (925 2325) (35 950))
|
||||
)
|
||||
N(6
|
||||
R(l5 (925 -475) (35 950))
|
||||
)
|
||||
N(7)
|
||||
N(8)
|
||||
P(1)
|
||||
P(2)
|
||||
P(3)
|
||||
P(4)
|
||||
P(5)
|
||||
P(6)
|
||||
P(7)
|
||||
P(8)
|
||||
D(1 D$PMOS
|
||||
Y(0 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.79325)
|
||||
E(AD 0.26125)
|
||||
E(PS 3.57)
|
||||
E(PD 1.5)
|
||||
E(AS 0.73625)
|
||||
E(AD 0.73625)
|
||||
E(PS 3.45)
|
||||
E(PD 3.45)
|
||||
T(S 4)
|
||||
T(G 3)
|
||||
T(D 2)
|
||||
)
|
||||
D(2 D$PMOS$1
|
||||
Y(800 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.03325)
|
||||
E(PS 1.5)
|
||||
E(PD 1.97)
|
||||
T(S 2)
|
||||
T(G 7)
|
||||
T(D 5)
|
||||
)
|
||||
D(3 D$NMOS
|
||||
D(2 D$NMOS
|
||||
Y(0 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.79325)
|
||||
E(AD 0.26125)
|
||||
E(PS 3.57)
|
||||
E(PD 1.5)
|
||||
E(AS 0.73625)
|
||||
E(AD 0.73625)
|
||||
E(PS 3.45)
|
||||
E(PD 3.45)
|
||||
T(S 4)
|
||||
T(G 3)
|
||||
T(D 1)
|
||||
)
|
||||
D(4 D$NMOS$1
|
||||
Y(800 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.03325)
|
||||
E(PS 1.5)
|
||||
E(PD 1.97)
|
||||
T(S 1)
|
||||
T(G 8)
|
||||
T(D 6)
|
||||
)
|
||||
)
|
||||
X(INV2
|
||||
R((0 0) (5500 4600))
|
||||
N(1)
|
||||
N(2)
|
||||
N(3)
|
||||
N(4)
|
||||
N(5)
|
||||
N(6)
|
||||
N(7)
|
||||
N(8)
|
||||
N(9)
|
||||
N(10)
|
||||
N(11
|
||||
N(1
|
||||
R(l6 (1790 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
)
|
||||
N(12
|
||||
N(2
|
||||
R(l6 (3490 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
)
|
||||
N(13
|
||||
N(3)
|
||||
N(4)
|
||||
N(5
|
||||
R(l6 (990 3290) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
|
|
@ -198,7 +138,7 @@ J(
|
|||
R(l8 (-3590 -690) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
)
|
||||
N(14
|
||||
N(6
|
||||
R(l6 (990 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
|
|
@ -212,63 +152,52 @@ J(
|
|||
P(4)
|
||||
P(5)
|
||||
P(6)
|
||||
P(7)
|
||||
P(8)
|
||||
P(9)
|
||||
P(10)
|
||||
P(11)
|
||||
P(12)
|
||||
P(13)
|
||||
P(14)
|
||||
X(1 INV M O(180) Y(1500 800)
|
||||
P(0 14)
|
||||
P(1 13)
|
||||
P(0 6)
|
||||
P(1 5)
|
||||
P(2 3)
|
||||
P(3 11)
|
||||
P(4 9)
|
||||
P(5 7)
|
||||
P(6 1)
|
||||
P(7 5)
|
||||
P(3 1)
|
||||
)
|
||||
X(2 INV Y(4000 800)
|
||||
P(0 14)
|
||||
P(1 13)
|
||||
P(0 6)
|
||||
P(1 5)
|
||||
P(2 4)
|
||||
P(3 12)
|
||||
P(4 10)
|
||||
P(5 8)
|
||||
P(6 2)
|
||||
P(7 6)
|
||||
P(3 2)
|
||||
)
|
||||
)
|
||||
X(INV3
|
||||
R((0 0) (6300 4600))
|
||||
N(1)
|
||||
N(2
|
||||
N(1 I('3')
|
||||
R(l11 (1509 1929) (2 2))
|
||||
)
|
||||
N(2 I('5')
|
||||
R(l11 (2319 1909) (2 2))
|
||||
)
|
||||
N(3 I('7')
|
||||
R(l11 (4829 1889) (2 2))
|
||||
)
|
||||
N(4 I('4')
|
||||
R(l6 (990 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l12 (-121 -1941) (2 2))
|
||||
)
|
||||
N(3)
|
||||
N(4)
|
||||
N(5)
|
||||
N(6)
|
||||
N(7)
|
||||
N(8)
|
||||
N(9
|
||||
N(5 I('6')
|
||||
R(l6 (2590 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l12 (-131 -1971) (2 2))
|
||||
)
|
||||
N(10
|
||||
N(6 I('8')
|
||||
R(l6 (4290 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l12 (-101 -1991) (2 2))
|
||||
)
|
||||
N(11
|
||||
N(7
|
||||
R(l6 (1790 3290) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 -620) (220 220))
|
||||
|
|
@ -279,7 +208,7 @@ J(
|
|||
R(l8 (-360 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
)
|
||||
N(12
|
||||
N(8
|
||||
R(l6 (1790 490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 -620) (220 220))
|
||||
|
|
@ -290,136 +219,92 @@ J(
|
|||
R(l8 (-360 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
)
|
||||
P(1)
|
||||
P(2)
|
||||
P(3)
|
||||
P(4)
|
||||
P(5)
|
||||
P(6)
|
||||
P(1 I('3'))
|
||||
P(2 I('5'))
|
||||
P(3 I('7'))
|
||||
P(4 I('4'))
|
||||
P(5 I('6'))
|
||||
P(6 I('8'))
|
||||
P(7)
|
||||
P(8)
|
||||
P(9)
|
||||
P(10)
|
||||
P(11)
|
||||
P(12)
|
||||
X(1 INV Y(1500 800)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(2 5)
|
||||
P(3 2)
|
||||
P(4 9)
|
||||
P(5 9)
|
||||
P(6 1)
|
||||
P(7 1)
|
||||
P(0 8)
|
||||
P(1 7)
|
||||
P(2 1)
|
||||
P(3 4)
|
||||
)
|
||||
X(2 INV M O(180) Y(2300 800)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(2 1)
|
||||
P(3 9)
|
||||
P(4 2)
|
||||
P(5 2)
|
||||
P(6 5)
|
||||
P(7 5)
|
||||
P(0 8)
|
||||
P(1 7)
|
||||
P(2 2)
|
||||
P(3 5)
|
||||
)
|
||||
X(3 INV Y(4800 800)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(2 4)
|
||||
P(3 10)
|
||||
P(4 8)
|
||||
P(5 7)
|
||||
P(6 3)
|
||||
P(7 6)
|
||||
P(0 8)
|
||||
P(1 7)
|
||||
P(2 3)
|
||||
P(3 6)
|
||||
)
|
||||
)
|
||||
X(INVCHAIN
|
||||
R((-1500 -800) (10400 4600))
|
||||
N(1
|
||||
R(l6 (490 990) (220 220))
|
||||
R(l6 (-1220 -1520) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (-65 -2185) (1105 350))
|
||||
N(1 I(IN)
|
||||
R(l3 (-1295 925) (1235 350))
|
||||
R(l11 (-911 -151) (2 2))
|
||||
)
|
||||
N(2
|
||||
R(l6 (3790 990) (220 220))
|
||||
R(l6 (-1220 -1520) (220 220))
|
||||
R(l3 (445 805) (480 550))
|
||||
R(l6 (-1435 -1665) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (-65 -2185) (1105 350))
|
||||
R(l7 (780 -2120) (220 220))
|
||||
R(l8 (-1065 -285) (1105 350))
|
||||
)
|
||||
N(3
|
||||
R(l6 (1405 990) (220 220))
|
||||
R(l6 (-535 -1520) (220 220))
|
||||
R(l3 (1345 925) (1945 350))
|
||||
R(l6 (-2200 -1585) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (20 -2270) (440 520))
|
||||
R(l7 (95 -2120) (220 220))
|
||||
R(l8 (-295 -370) (440 520))
|
||||
)
|
||||
N(4
|
||||
R(l6 (7090 990) (220 220))
|
||||
R(l6 (-1220 -1520) (220 220))
|
||||
R(l3 (3745 805) (480 550))
|
||||
R(l6 (-1435 -1665) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (-65 -2185) (1105 350))
|
||||
R(l7 (780 -2120) (220 220))
|
||||
R(l8 (-1065 -285) (1105 350))
|
||||
)
|
||||
N(5
|
||||
R(l6 (4705 990) (220 220))
|
||||
R(l6 (-535 -1520) (220 220))
|
||||
R(l3 (4645 925) (1945 350))
|
||||
R(l6 (-2200 -1585) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (20 -2270) (440 520))
|
||||
R(l7 (95 -2120) (220 220))
|
||||
R(l8 (-295 -370) (440 520))
|
||||
)
|
||||
N(6
|
||||
R(l3 (-1295 925) (1235 350))
|
||||
)
|
||||
N(7
|
||||
R(l3 (445 805) (480 550))
|
||||
)
|
||||
N(8
|
||||
R(l3 (1345 925) (1945 350))
|
||||
)
|
||||
N(9
|
||||
R(l3 (3745 805) (480 550))
|
||||
)
|
||||
N(10
|
||||
R(l3 (4645 925) (1945 350))
|
||||
)
|
||||
N(11
|
||||
R(l3 (7045 805) (480 550))
|
||||
R(l6 (-1435 -1665) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l7 (780 -2120) (220 220))
|
||||
R(l8 (-1065 -285) (1105 350))
|
||||
)
|
||||
N(12
|
||||
N(7 I(OUT)
|
||||
R(l6 (7690 -310) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 2180) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l12 (-121 -2011) (2 2))
|
||||
)
|
||||
N(13
|
||||
R(l6 (6890 2490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-3520 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-6820 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (3010 -690) (360 760))
|
||||
R(l8 (-3660 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
R(l8 (-6960 -760) (360 760))
|
||||
R(l8 (-360 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
)
|
||||
N(14
|
||||
N(8 I(VSS)
|
||||
R(l6 (6890 -310) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-3520 -620) (220 220))
|
||||
|
|
@ -438,136 +323,96 @@ J(
|
|||
R(l8 (-6960 -760) (360 760))
|
||||
R(l8 (-360 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
R(l13 (2719 -381) (2 2))
|
||||
R(l13 (-3302 -2) (2 2))
|
||||
R(l13 (-3302 -2) (2 2))
|
||||
)
|
||||
N(9 I(VDD)
|
||||
R(l6 (6890 2490) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-3520 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-6820 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (-220 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l6 (3080 -620) (220 220))
|
||||
R(l6 (-220 180) (220 220))
|
||||
R(l8 (3010 -690) (360 760))
|
||||
R(l8 (-3660 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
R(l8 (-6960 -760) (360 760))
|
||||
R(l8 (-360 -760) (360 760))
|
||||
R(l8 (2940 -760) (360 760))
|
||||
R(l13 (-581 -381) (2 2))
|
||||
R(l13 (3298 -2) (2 2))
|
||||
R(l13 (-6602 -2) (2 2))
|
||||
)
|
||||
P(1 I(IN))
|
||||
P(7 I(OUT))
|
||||
P(8 I(VSS))
|
||||
P(9 I(VDD))
|
||||
X(1 INV3 Y(-1500 -800)
|
||||
P(0 7)
|
||||
P(1 1)
|
||||
P(2 9)
|
||||
P(3 8)
|
||||
P(4 6)
|
||||
P(5 9)
|
||||
P(6 5)
|
||||
P(7 5)
|
||||
P(8 3)
|
||||
P(9 2)
|
||||
P(10 13)
|
||||
P(11 14)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 3)
|
||||
P(3 2)
|
||||
P(4 3)
|
||||
P(5 4)
|
||||
P(6 9)
|
||||
P(7 8)
|
||||
)
|
||||
X(2 INV2 Y(2600 -800)
|
||||
P(0 8)
|
||||
P(1 11)
|
||||
P(2 9)
|
||||
P(3 10)
|
||||
P(4 8)
|
||||
P(5 11)
|
||||
P(6 2)
|
||||
P(7 12)
|
||||
P(8 2)
|
||||
P(9 12)
|
||||
P(10 5)
|
||||
P(11 4)
|
||||
P(12 13)
|
||||
P(13 14)
|
||||
P(0 5)
|
||||
P(1 6)
|
||||
P(2 4)
|
||||
P(3 5)
|
||||
P(4 9)
|
||||
P(5 8)
|
||||
)
|
||||
X(3 INV M O(180) Y(7400 0)
|
||||
P(0 14)
|
||||
P(1 13)
|
||||
P(2 11)
|
||||
P(3 12)
|
||||
P(4 4)
|
||||
P(5 4)
|
||||
P(6 10)
|
||||
P(7 10)
|
||||
P(0 8)
|
||||
P(1 9)
|
||||
P(2 6)
|
||||
P(3 7)
|
||||
)
|
||||
)
|
||||
)
|
||||
H(
|
||||
X(TRANS
|
||||
N(1 I('1'))
|
||||
N(2 I('2'))
|
||||
N(3 I('3'))
|
||||
P(1 I('1'))
|
||||
P(2 I('2'))
|
||||
P(3 I('3'))
|
||||
)
|
||||
X(INV
|
||||
N(1 I('1'))
|
||||
N(2 I('2'))
|
||||
N(3 I('3'))
|
||||
N(4 I('4'))
|
||||
N(5 I('5'))
|
||||
N(6 I('6'))
|
||||
N(7 I('7'))
|
||||
N(8 I('8'))
|
||||
P(1 I('1'))
|
||||
P(2 I('2'))
|
||||
P(3 I('3'))
|
||||
P(4 I('4'))
|
||||
P(5 I('5'))
|
||||
P(6 I('6'))
|
||||
P(7 I('7'))
|
||||
P(8 I('8'))
|
||||
D(1 PMOS
|
||||
I($1)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.79325)
|
||||
E(AD 0.26125)
|
||||
E(PS 3.57)
|
||||
E(PD 1.5)
|
||||
T(S 4)
|
||||
E(AS 0)
|
||||
E(AD 0)
|
||||
E(PS 0)
|
||||
E(PD 0)
|
||||
T(S 1)
|
||||
T(G 3)
|
||||
T(D 2)
|
||||
T(B 4)
|
||||
T(D 4)
|
||||
)
|
||||
D(2 PMOS
|
||||
I($2)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.03325)
|
||||
E(PS 1.5)
|
||||
E(PD 1.97)
|
||||
T(S 2)
|
||||
T(G 7)
|
||||
T(D 5)
|
||||
T(B 2)
|
||||
)
|
||||
D(3 NMOS
|
||||
D(2 NMOS
|
||||
I($3)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.79325)
|
||||
E(AD 0.26125)
|
||||
E(PS 3.57)
|
||||
E(PD 1.5)
|
||||
T(S 4)
|
||||
E(AS 0)
|
||||
E(AD 0)
|
||||
E(PS 0)
|
||||
E(PD 0)
|
||||
T(S 2)
|
||||
T(G 3)
|
||||
T(D 1)
|
||||
T(B 4)
|
||||
)
|
||||
D(4 NMOS
|
||||
I($4)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.03325)
|
||||
E(PS 1.5)
|
||||
E(PD 1.97)
|
||||
T(S 1)
|
||||
T(G 8)
|
||||
T(D 6)
|
||||
T(B 1)
|
||||
)
|
||||
X(1 TRANS I($1)
|
||||
P(0 4)
|
||||
P(1 1)
|
||||
P(2 3)
|
||||
)
|
||||
X(2 TRANS I($2)
|
||||
P(0 4)
|
||||
P(1 2)
|
||||
P(2 3)
|
||||
T(D 4)
|
||||
)
|
||||
)
|
||||
X(INV3
|
||||
|
|
@ -579,10 +424,6 @@ H(
|
|||
N(6 I('6'))
|
||||
N(7 I('7'))
|
||||
N(8 I('8'))
|
||||
N(9 I('9'))
|
||||
N(10 I('10'))
|
||||
N(11 I('11'))
|
||||
N(12 I('12'))
|
||||
P(1 I('1'))
|
||||
P(2 I('2'))
|
||||
P(3 I('3'))
|
||||
|
|
@ -591,39 +432,23 @@ H(
|
|||
P(6 I('6'))
|
||||
P(7 I('7'))
|
||||
P(8 I('8'))
|
||||
P(9 I('9'))
|
||||
P(10 I('10'))
|
||||
P(11 I('11'))
|
||||
P(12 I('12'))
|
||||
X(1 INV I($1)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 3)
|
||||
P(3 10)
|
||||
P(4 8)
|
||||
P(5 6)
|
||||
P(6 1)
|
||||
P(7 5)
|
||||
P(3 4)
|
||||
)
|
||||
X(2 INV I($2)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(2 4)
|
||||
P(3 7)
|
||||
P(4 9)
|
||||
P(5 9)
|
||||
P(6 2)
|
||||
P(7 2)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 5)
|
||||
P(3 6)
|
||||
)
|
||||
X(3 INV I($3)
|
||||
P(0 12)
|
||||
P(1 11)
|
||||
P(2 2)
|
||||
P(3 9)
|
||||
P(4 7)
|
||||
P(5 7)
|
||||
P(6 4)
|
||||
P(7 4)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 7)
|
||||
P(3 8)
|
||||
)
|
||||
)
|
||||
X(INV2
|
||||
|
|
@ -633,125 +458,135 @@ H(
|
|||
N(4 I('4'))
|
||||
N(5 I('5'))
|
||||
N(6 I('6'))
|
||||
N(7 I('7'))
|
||||
N(8 I('8'))
|
||||
N(9 I('9'))
|
||||
N(10 I('10'))
|
||||
N(11 I('11'))
|
||||
N(12 I('12'))
|
||||
N(13 I('13'))
|
||||
N(14 I('14'))
|
||||
P(1 I('1'))
|
||||
P(2 I('2'))
|
||||
P(3 I('3'))
|
||||
P(4 I('4'))
|
||||
P(5 I('5'))
|
||||
P(6 I('6'))
|
||||
P(7 I('7'))
|
||||
P(8 I('8'))
|
||||
P(9 I('9'))
|
||||
P(10 I('10'))
|
||||
P(11 I('11'))
|
||||
P(12 I('12'))
|
||||
P(13 I('13'))
|
||||
P(14 I('14'))
|
||||
X(1 INV I($1)
|
||||
P(0 14)
|
||||
P(1 13)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 3)
|
||||
P(3 11)
|
||||
P(4 9)
|
||||
P(5 7)
|
||||
P(6 1)
|
||||
P(7 5)
|
||||
P(3 4)
|
||||
)
|
||||
X(2 INV I($2)
|
||||
P(0 14)
|
||||
P(1 13)
|
||||
P(2 4)
|
||||
P(3 12)
|
||||
P(4 10)
|
||||
P(5 8)
|
||||
P(6 2)
|
||||
P(7 6)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 5)
|
||||
P(3 6)
|
||||
)
|
||||
)
|
||||
X(INVCHAIN
|
||||
N(1 I('9'))
|
||||
N(2 I('7'))
|
||||
N(3 I('8'))
|
||||
N(4 I('6'))
|
||||
N(1 I('1'))
|
||||
N(2 I('2'))
|
||||
N(3 I('3'))
|
||||
N(4 I('4'))
|
||||
N(5 I('5'))
|
||||
N(6 I('1'))
|
||||
N(7 I('3'))
|
||||
N(8 I('2'))
|
||||
N(9 I('13'))
|
||||
N(10 I('14'))
|
||||
N(11 I('11'))
|
||||
N(12 I('10'))
|
||||
N(13 I('12'))
|
||||
N(14 I('4'))
|
||||
N(6 I('6'))
|
||||
N(7 I('7'))
|
||||
N(8 I('8'))
|
||||
N(9 I('9'))
|
||||
X(1 INV3 I($1)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 3)
|
||||
P(3 4)
|
||||
P(4 1)
|
||||
P(4 4)
|
||||
P(5 5)
|
||||
P(6 6)
|
||||
P(7 5)
|
||||
P(8 7)
|
||||
P(9 8)
|
||||
P(10 9)
|
||||
P(11 10)
|
||||
P(6 5)
|
||||
P(7 6)
|
||||
)
|
||||
X(2 INV2 I($2)
|
||||
P(0 3)
|
||||
P(1 11)
|
||||
P(2 1)
|
||||
P(3 12)
|
||||
P(4 3)
|
||||
P(5 11)
|
||||
P(6 8)
|
||||
P(7 13)
|
||||
P(8 8)
|
||||
P(9 13)
|
||||
P(10 5)
|
||||
P(11 14)
|
||||
P(12 9)
|
||||
P(13 10)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 6)
|
||||
P(3 7)
|
||||
P(4 7)
|
||||
P(5 8)
|
||||
)
|
||||
X(3 INV I($3)
|
||||
P(0 10)
|
||||
P(1 9)
|
||||
P(2 11)
|
||||
P(3 13)
|
||||
P(4 14)
|
||||
P(5 14)
|
||||
P(6 12)
|
||||
P(7 12)
|
||||
P(0 1)
|
||||
P(1 2)
|
||||
P(2 8)
|
||||
P(3 9)
|
||||
)
|
||||
)
|
||||
)
|
||||
Z(
|
||||
X(() TRANS 0
|
||||
X(INV INV 1
|
||||
Z(
|
||||
N(2 1 1)
|
||||
N(1 2 1)
|
||||
N(3 3 1)
|
||||
N(4 4 1)
|
||||
P(1 0 1)
|
||||
P(0 1 1)
|
||||
P(2 2 1)
|
||||
P(3 3 1)
|
||||
D(2 2 1)
|
||||
D(1 1 1)
|
||||
)
|
||||
)
|
||||
X(INV INV S
|
||||
X(INV2 INV2 1
|
||||
Z(
|
||||
N(5 1 1)
|
||||
N(6 2 1)
|
||||
N(3 3 1)
|
||||
N(1 4 W)
|
||||
N(4 5 1)
|
||||
N(2 6 W)
|
||||
P(4 0 1)
|
||||
P(5 1 1)
|
||||
P(2 2 1)
|
||||
P(0 3 1)
|
||||
P(3 4 1)
|
||||
P(1 5 1)
|
||||
X(1 1 1)
|
||||
X(2 2 1)
|
||||
)
|
||||
)
|
||||
X(INV2 INV2 S
|
||||
X(INV3 INV3 1
|
||||
Z(
|
||||
N(7 1 1)
|
||||
N(8 2 1)
|
||||
N(1 3 1)
|
||||
N(4 4 W)
|
||||
N(2 5 1)
|
||||
N(5 6 W)
|
||||
N(3 7 1)
|
||||
N(6 8 W)
|
||||
P(6 0 1)
|
||||
P(7 1 1)
|
||||
P(0 2 1)
|
||||
P(3 3 1)
|
||||
P(1 4 1)
|
||||
P(4 5 1)
|
||||
P(2 6 1)
|
||||
P(5 7 1)
|
||||
X(1 1 1)
|
||||
X(2 2 1)
|
||||
X(3 3 1)
|
||||
)
|
||||
)
|
||||
X(INV3 INV3 S
|
||||
Z(
|
||||
)
|
||||
)
|
||||
X(INVCHAIN INVCHAIN S
|
||||
X(INVCHAIN INVCHAIN 1
|
||||
Z(
|
||||
N(2 4 1)
|
||||
N(3 5 1)
|
||||
N(4 6 1)
|
||||
N(5 7 1)
|
||||
N(6 8 1)
|
||||
N(1 3 1)
|
||||
N(7 9 1)
|
||||
N(9 1 1)
|
||||
N(8 2 1)
|
||||
P(0 () 1)
|
||||
P(1 () 1)
|
||||
P(3 () 1)
|
||||
P(2 () 1)
|
||||
X(3 3 1)
|
||||
X(2 2 1)
|
||||
X(1 1 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,85 +1,27 @@
|
|||
|
||||
* cell INVCHAIN
|
||||
.SUBCKT INVCHAIN
|
||||
* cell instance $1 r0 *1 -1.5,-0.8
|
||||
X$1 9 7 8 6 9 5 1 5 3 2 13 14 INV3
|
||||
* cell instance $2 r0 *1 2.6,-0.8
|
||||
X$2 8 11 9 10 8 11 2 12 2 12 5 4 13 14 INV2
|
||||
* cell instance $3 m90 *1 7.4,0
|
||||
X$3 14 13 11 12 4 4 10 10 INV
|
||||
X$1 1 2 3 4 4 5 5 6 INV3
|
||||
X$2 1 2 6 7 7 8 INV2
|
||||
X$3 1 2 8 9 INV
|
||||
.ENDS INVCHAIN
|
||||
|
||||
* cell INV3
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
.SUBCKT INV3 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
* cell instance $1 r0 *1 4.8,0.8
|
||||
X$1 12 11 3 10 8 6 1 5 INV
|
||||
* cell instance $2 r0 *1 1.5,0.8
|
||||
X$2 12 11 4 7 9 9 2 2 INV
|
||||
* cell instance $3 m90 *1 2.3,0.8
|
||||
X$3 12 11 2 9 7 7 4 4 INV
|
||||
.SUBCKT INV3 1 2 3 4 5 6 7 8
|
||||
X$1 1 2 3 4 INV
|
||||
X$2 1 2 5 6 INV
|
||||
X$3 1 2 7 8 INV
|
||||
.ENDS INV3
|
||||
|
||||
* cell INV2
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
.SUBCKT INV2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
* cell instance $1 m90 *1 1.5,0.8
|
||||
X$1 14 13 3 11 9 7 1 5 INV
|
||||
* cell instance $2 r0 *1 4,0.8
|
||||
X$2 14 13 4 12 10 8 2 6 INV
|
||||
.SUBCKT INV2 1 2 3 4 5 6
|
||||
X$1 1 2 3 4 INV
|
||||
X$2 1 2 5 6 INV
|
||||
.ENDS INV2
|
||||
|
||||
* cell INV
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
.SUBCKT INV 1 2 3 4 5 6 7 8
|
||||
* cell instance $1 r0 *1 0,0
|
||||
X$1 4 1 3 TRANS
|
||||
* cell instance $2 r0 *1 0,2.8
|
||||
X$2 4 2 3 TRANS
|
||||
* device instance $1 r0 *1 0,2.8 PMOS
|
||||
M$1 4 3 2 4 PMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U
|
||||
* device instance $2 r0 *1 0.8,2.8 PMOS
|
||||
M$2 2 7 5 2 PMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U
|
||||
* device instance $3 r0 *1 0,0 NMOS
|
||||
M$3 4 3 1 4 NMOS L=0.25U W=0.95U AS=0.79325P AD=0.26125P PS=3.57U PD=1.5U
|
||||
* device instance $4 r0 *1 0.8,0 NMOS
|
||||
M$4 1 8 6 1 NMOS L=0.25U W=0.95U AS=0.26125P AD=0.03325P PS=1.5U PD=1.97U
|
||||
.SUBCKT INV 1 2 3 4
|
||||
M$1 1 3 4 1 PMOS L=0.25U W=0.95U
|
||||
M$3 2 3 4 2 NMOS L=0.25U W=0.95U
|
||||
.ENDS INV
|
||||
|
||||
* cell TRANS
|
||||
* pin
|
||||
* pin
|
||||
* pin
|
||||
.SUBCKT TRANS 1 2 3
|
||||
.ENDS TRANS
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -170,6 +170,21 @@ class DBNetlist_TestClass < TestBase
|
|||
c.each_pin { |p| names << p.name }
|
||||
assert_equal(names, [ "A", "B" ])
|
||||
|
||||
assert_equal(c.pin_by_id(0) == nil, false)
|
||||
assert_equal(c.pin_by_id(1) == nil, false)
|
||||
assert_equal(c.pin_by_id(0).name, "A")
|
||||
assert_equal(c.pin_by_id(1).name, "B")
|
||||
|
||||
c.remove_pin(0)
|
||||
|
||||
names = []
|
||||
c.each_pin { |p| names << p.name }
|
||||
assert_equal(names, [ "B" ])
|
||||
|
||||
assert_equal(c.pin_by_id(0) == nil, true)
|
||||
assert_equal(c.pin_by_id(1) == nil, false)
|
||||
assert_equal(c.pin_by_id(1).name, "B")
|
||||
|
||||
end
|
||||
|
||||
def test_4_Device
|
||||
|
|
|
|||
Loading…
Reference in New Issue