Some enhancements for netlist extraction and writer

* Spice writer can now be configure to skip the debug
  comments
* < and > are allowed chars in spice names now
* global net names have second prio over labels now
This commit is contained in:
Matthias Koefferlein 2019-05-31 00:11:28 +02:00
parent 98207cb454
commit c684633dd6
22 changed files with 131 additions and 95 deletions

View File

@ -142,11 +142,6 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
net->set_cluster_id (*c);
circuit->add_net (net);
const db::local_cluster<db::PolygonRef>::global_nets &gn = lc.get_global_nets ();
for (db::local_cluster<db::PolygonRef>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
assign_net_name (conn.global_net_name (*g), net);
}
// make subcircuit connections (also make the subcircuits if required) from the connections of the clusters
make_and_connect_subcircuits (circuit, clusters, *c, net, subcircuits, circuits, pins_per_cluster_per_cell);
@ -154,7 +149,18 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
connect_devices (circuit, clusters, *c, net);
// collect labels to net names
collect_labels (clusters, *c, net);
std::set<std::string> net_names;
collect_labels (clusters, *c, net_names);
// add the global names as second priority
if (net_names.empty ()) {
const db::local_cluster<db::PolygonRef>::global_nets &gn = lc.get_global_nets ();
for (db::local_cluster<db::PolygonRef>::global_nets::const_iterator g = gn.begin (); g != gn.end (); ++g) {
net_names.insert (conn.global_net_name (*g));
}
}
assign_net_names (net, net_names);
if (! clusters.is_root (*c)) {
// a non-root cluster makes a pin
@ -167,6 +173,22 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
}
}
void
NetlistExtractor::assign_net_names (db::Net *net, const std::set<std::string> &net_names)
{
std::string nn;
for (std::set<std::string>::const_iterator n = net_names.begin (); n != net_names.end (); ++n) {
if (! n->empty ()) {
if (! nn.empty ()) {
nn += ",";
}
nn += *n;
}
}
net->set_name (nn);
}
void
NetlistExtractor::make_device_abstract_connections (db::DeviceAbstract *dm, const connected_clusters_type &clusters)
{
@ -194,7 +216,7 @@ NetlistExtractor::make_device_abstract_connections (db::DeviceAbstract *dm, cons
void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,
size_t cid,
db::Net *net)
std::set<std::string> &net_names)
{
// collect the properties - we know that the cluster attributes are property ID's because the
// cluster processor converts shape property IDs to attributes
@ -206,7 +228,7 @@ void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
if (m_text_annot_name_id.first && j->first == m_text_annot_name_id.second) {
assign_net_name (j->second.to_string (), net);
net_names.insert (j->second.to_string ());
}
}
@ -348,15 +370,4 @@ size_t NetlistExtractor::make_pin (db::Circuit *circuit, db::Net *net)
return pin_id;
}
void NetlistExtractor::assign_net_name (const std::string &n, db::Net *net)
{
std::string nn = n;
if (! nn.empty ()) {
if (! net->name ().empty ()) {
nn = net->name () + "," + nn;
}
net->set_name (nn);
}
}
}

View File

@ -27,6 +27,8 @@
#include "dbHierNetworkProcessor.h"
#include <map>
#include <set>
#include <string>
namespace db
{
@ -92,9 +94,9 @@ private:
std::pair<bool, db::property_names_id_type> m_device_annot_name_id;
std::pair<bool, db::property_names_id_type> m_terminal_annot_name_id;
void assign_net_name (const std::string &n, db::Net *net);
bool instance_is_device (db::properties_id_type prop_id) const;
db::Device *device_from_instance (db::properties_id_type prop_id, db::Circuit *circuit) const;
void assign_net_names (db::Net *net, const std::set<std::string> &net_names);
/**
* @brief Make a pin connection from clusters
@ -151,7 +153,7 @@ private:
*/
void collect_labels (const connected_clusters_type &clusters,
size_t cid,
db::Net *net);
std::set<std::string> &net_names);
/**
* @brief Makes the terminal to cluster ID connections of the device abstract

View File

@ -31,7 +31,7 @@
namespace db
{
static const char *allowed_name_chars = "_.:,!+$/&\\#[]";
static const char *allowed_name_chars = "_.:,!+$/&\\#[]<>";
static const char *not_connect_prefix = "nc_";
// --------------------------------------------------------------------------------
@ -197,7 +197,7 @@ std::string NetlistSpiceWriterDelegate::format_params (const db::Device &dev) co
// --------------------------------------------------------------------------------
NetlistSpiceWriter::NetlistSpiceWriter (NetlistSpiceWriterDelegate *delegate)
: mp_netlist (0), mp_stream (0), mp_delegate (delegate), m_next_net_id (0), m_use_net_names (false)
: mp_netlist (0), mp_stream (0), mp_delegate (delegate), m_next_net_id (0), m_use_net_names (false), m_with_comments (true)
{
static NetlistSpiceWriterDelegate std_delegate;
if (! delegate) {
@ -215,6 +215,11 @@ void NetlistSpiceWriter::set_use_net_names (bool use_net_names)
m_use_net_names = use_net_names;
}
void NetlistSpiceWriter::set_with_comments (bool with_comments)
{
m_with_comments = with_comments;
}
void NetlistSpiceWriter::write (tl::OutputStream &stream, const db::Netlist &netlist, const std::string &description)
{
mp_stream = &stream;
@ -395,9 +400,10 @@ void NetlistSpiceWriter::do_write (const std::string &description)
for (db::Circuit::const_device_iterator i = circuit.begin_devices (); i != circuit.end_devices (); ++i) {
// TODO: make this configurable?
std::string comment = "device instance " + i->expanded_name () + " " + i->trans ().to_string () + " " + i->device_class ()->name ();
emit_comment (comment);
if (m_with_comments) {
std::string comment = "device instance " + i->expanded_name () + " " + i->trans ().to_string () + " " + i->device_class ()->name ();
emit_comment (comment);
}
mp_delegate->write_device (*i);
@ -410,9 +416,10 @@ void NetlistSpiceWriter::do_write (const std::string &description)
void NetlistSpiceWriter::write_subcircuit_call (const db::SubCircuit &subcircuit) const
{
// TODO: make this configurable?
std::string comment = "cell instance " + subcircuit.expanded_name() + " " + subcircuit.trans ().to_string ();
emit_comment (comment);
if (m_with_comments) {
std::string comment = "cell instance " + subcircuit.expanded_name() + " " + subcircuit.trans ().to_string ();
emit_comment (comment);
}
std::ostringstream os;
os << "X";
@ -433,9 +440,11 @@ void NetlistSpiceWriter::write_circuit_header (const db::Circuit &circuit) const
{
emit_line ("");
emit_comment ("cell " + circuit.name ());
for (db::Circuit::const_pin_iterator p = circuit.begin_pins (); p != circuit.end_pins (); ++p) {
emit_comment ("pin " + p->name ());
if (m_with_comments) {
emit_comment ("cell " + circuit.name ());
for (db::Circuit::const_pin_iterator p = circuit.begin_pins (); p != circuit.end_pins (); ++p) {
emit_comment ("pin " + p->name ());
}
}
std::ostringstream os;
@ -450,7 +459,7 @@ void NetlistSpiceWriter::write_circuit_header (const db::Circuit &circuit) const
emit_line (os.str ());
if (! m_use_net_names) {
if (! m_use_net_names && m_with_comments) {
for (db::Circuit::const_net_iterator n = circuit.begin_nets (); n != circuit.end_nets (); ++n) {
if (! n->name ().empty ()) {
emit_comment ("net " + net_to_string (n.operator-> ()) + " " + n->name ());

View File

@ -92,6 +92,12 @@ public:
return m_use_net_names;
}
void set_with_comments (bool f);
bool with_comments () const
{
return m_with_comments;
}
private:
friend class NetlistSpiceWriterDelegate;
@ -101,6 +107,7 @@ private:
std::map<const db::Net *, size_t> m_net_to_spice_id;
mutable size_t m_next_net_id;
bool m_use_net_names;
bool m_with_comments;
void do_write (const std::string &description);

View File

@ -1544,8 +1544,15 @@ Class<db::NetlistSpiceWriter> db_NetlistSpiceWriter (db_NetlistWriter, "db", "Ne
"@brief Sets a value indicating whether to use net names (true) or net numbers (false).\n"
"The default is to use net numbers."
) +
gsi::method ("use_net_names", &db::NetlistSpiceWriter::use_net_names,
gsi::method ("use_net_names?", &db::NetlistSpiceWriter::use_net_names,
"@brief Gets a value indicating whether to use net names (true) or net numbers (false).\n"
) +
gsi::method ("with_comments=", &db::NetlistSpiceWriter::set_with_comments, gsi::arg ("f"),
"@brief Sets a value indicating whether to embed comments for position etc. (true) or not (false).\n"
"The default is to embed comments."
) +
gsi::method ("with_comments?", &db::NetlistSpiceWriter::with_comments,
"@brief Gets a value indicating whether to embed comments for position etc. (true) or not (false).\n"
),
"@brief Implements a netlist writer for the SPICE format.\n"
"Provide a delegate for customizing the way devices are written.\n"

View File

@ -1070,7 +1070,7 @@ TEST(3_GlobalNetConnections)
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal2, db::DPoint (-2.0, 1.8))), "(null)");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (-1.5, 1.8))), "RINGO:FB");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (24.5, 1.8))), "RINGO:OSC");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:BULK,VSS");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4");
@ -1085,12 +1085,12 @@ TEST(3_GlobalNetConnections)
// compare netlist as string
CHECKPOINT ();
db::compare_netlist (_this, *l2n.netlist (),
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS');\n"
" subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);\n"
"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=(null),$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK=VSS,$2=(null),$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=(null),OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
@ -1357,7 +1357,7 @@ TEST(4_GlobalNetDeviceExtraction)
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal2, db::DPoint (-2.0, 1.8))), "(null)");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (-1.5, 1.8))), "RINGO:FB");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (24.5, 1.8))), "RINGO:OSC");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:BULK,VSS");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (2.6, 1.0))), "RINGO:$I22");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (6.4, 1.0))), "INV2PAIR:$I4");
@ -1372,12 +1372,12 @@ TEST(4_GlobalNetDeviceExtraction)
// compare netlist as string
CHECKPOINT ();
db::compare_netlist (_this, *l2n.netlist (),
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS');\n"
" subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);\n"
"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=(null),$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK=VSS,$2=(null),$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=(null),OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"
@ -1644,7 +1644,7 @@ TEST(5_DeviceExtractionWithDeviceCombination)
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal2, db::DPoint (-2.0, 1.8))), "(null)");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (-1.5, 1.8))), "RINGO:FB");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (24.5, 1.8))), "RINGO:OSC");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:BULK,VSS");
EXPECT_EQ (qnet_name (l2n.probe_net (*rmetal1, db::DPoint (5.3, 0.0))), "RINGO:VSS");
// doesn't do anything here, but we test that this does not destroy anything:
l2n.netlist ()->combine_devices ();
@ -1656,12 +1656,12 @@ TEST(5_DeviceExtractionWithDeviceCombination)
// compare netlist as string
CHECKPOINT ();
db::compare_netlist (_this, *l2n.netlist (),
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS');\n"
" subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=VDD,$3='BULK,VSS',$4=FB,$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=VDD,$3='BULK,VSS',$4=(null),$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=VDD,$3='BULK,VSS',$4=(null),$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=VDD,$3='BULK,VSS',$4=(null),$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=VDD,$3='BULK,VSS',$4=(null),$5=$I6,$6=$I7,$7=VDD);\n"
"circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);\n"
" subcircuit INV2PAIR $1 (BULK=VSS,$2=VDD,$3=VSS,$4=FB,$5=$I7,$6=OSC,$7=VDD);\n"
" subcircuit INV2PAIR $2 (BULK=VSS,$2=VDD,$3=VSS,$4=(null),$5=FB,$6=$I13,$7=VDD);\n"
" subcircuit INV2PAIR $3 (BULK=VSS,$2=VDD,$3=VSS,$4=(null),$5=$I13,$6=$I5,$7=VDD);\n"
" subcircuit INV2PAIR $4 (BULK=VSS,$2=VDD,$3=VSS,$4=(null),$5=$I5,$6=$I6,$7=VDD);\n"
" subcircuit INV2PAIR $5 (BULK=VSS,$2=VDD,$3=VSS,$4=(null),$5=$I6,$6=$I7,$7=VDD);\n"
"end;\n"
"circuit INV2PAIR (BULK=BULK,$2=$I6,$3=$I5,$4=$I4,$5=$I3,$6=$I2,$7=$I1);\n"
" subcircuit INV2 $1 ($1=$I1,IN=$I3,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);\n"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -425,7 +425,7 @@ circuit(RINGO
rect(metal1 (-360 -760) (360 760))
rect(metal2_lbl (-21301 -381) (2 2))
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont (7810 -310) (220 220))
rect(diff_cont (-220 180) (220 220))
rect(diff_cont (-220 -220) (220 220))
@ -527,7 +527,7 @@ circuit(RINGO
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)

View File

@ -428,7 +428,7 @@ circuit(RINGO
rect(metal1 20940 2420 21300 3180)
rect(metal2_lbl -1 2799 1 2801)
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont 7810 -310 8030 -90)
rect(diff_cont 7810 90 8030 310)
rect(diff_cont 7810 90 8030 310)
@ -530,7 +530,7 @@ circuit(RINGO
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)

View File

@ -390,7 +390,7 @@ X(RINGO
R(metal1 (-360 -760) (360 760))
R(metal2_lbl (-21301 -381) (2 2))
)
N(4 I('BULK,VSS')
N(4 I(VSS)
R(diff_cont (7810 -310) (220 220))
R(diff_cont (-220 180) (220 220))
R(diff_cont (-220 -220) (220 220))
@ -490,7 +490,7 @@ X(RINGO
P(1 I(FB))
P(2 I(OSC))
P(3 I(VDD))
P(4 I('BULK,VSS'))
P(4 I(VSS))
X(1 INV2PAIR Y(19420 -800)
P(0 4)
P(1 1)

View File

@ -532,7 +532,7 @@ layout(
rect(metal1 (-360 -1560) (360 1560))
rect(metal2_lbl (-21301 -1181) (2 2))
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont (7810 90) (220 220))
rect(diff_cont (-220 -620) (220 220))
rect(diff_cont (-220 -620) (220 220))
@ -722,7 +722,7 @@ layout(
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)
@ -973,14 +973,14 @@ xref(
net(6 5 match)
net(7 8 match)
net(8 7 match)
net(4 4 match)
net(1 1 match)
net(2 2 match)
net(3 3 match)
pin(3 3 match)
net(4 4 match)
pin(0 0 match)
pin(1 1 match)
pin(2 2 match)
pin(3 3 match)
circuit(1 1 match)
circuit(2 2 match)
circuit(3 3 match)

View File

@ -532,7 +532,7 @@ layout(
rect(metal1 (-360 -1560) (360 1560))
rect(metal2_lbl (-21301 -1181) (2 2))
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont (7810 90) (220 220))
rect(diff_cont (-220 -620) (220 220))
rect(diff_cont (-220 -620) (220 220))
@ -722,7 +722,7 @@ layout(
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)
@ -973,14 +973,14 @@ xref(
net(6 5 match)
net(7 8 match)
net(8 7 match)
net(4 4 match)
net(1 1 match)
net(2 2 match)
net(3 3 match)
pin(3 3 match)
net(4 4 match)
pin(0 0 match)
pin(1 1 match)
pin(2 2 match)
pin(3 3 match)
circuit(1 1 match)
circuit(2 2 match)
circuit(3 3 match)

View File

@ -532,7 +532,7 @@ layout(
rect(metal1 (-360 -1560) (360 1560))
rect(metal2_lbl (-21301 -1181) (2 2))
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont (7810 90) (220 220))
rect(diff_cont (-220 -620) (220 220))
rect(diff_cont (-220 -620) (220 220))
@ -722,7 +722,7 @@ layout(
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)

View File

@ -532,7 +532,7 @@ layout(
rect(metal1 (-360 -1560) (360 1560))
rect(metal2_lbl (-21301 -1181) (2 2))
)
net(4 name('BULK,VSS')
net(4 name(VSS)
rect(diff_cont (7810 90) (220 220))
rect(diff_cont (-220 -620) (220 220))
rect(diff_cont (-220 -620) (220 220))
@ -722,7 +722,7 @@ layout(
pin(1 name(FB))
pin(2 name(OSC))
pin(3 name(VDD))
pin(4 name('BULK,VSS'))
pin(4 name(VSS))
# Subcircuits and their connections
circuit(1 INV2PAIR location(19420 -800)

View File

@ -386,11 +386,11 @@ end;
l2n.extract_netlist()
self.assertEqual(str(l2n.netlist()), """circuit RINGO ();
subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=$I22,$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=$I23,$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=$I24,$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=$I25,$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);
subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);
end;
circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);
subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);
@ -414,12 +414,12 @@ end;
l2n.netlist().make_top_level_pins()
l2n.netlist().purge()
self.assertEqual(str(l2n.netlist()), """circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS');
subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);
self.assertEqual(str(l2n.netlist()), """circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);
subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);
end;
circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);
subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=(null),OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);

View File

@ -390,11 +390,11 @@ END
assert_equal(l2n.netlist.to_s, <<END)
circuit RINGO ();
subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=$I22,$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=$I23,$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=$I24,$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=$I25,$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);
subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK=VSS,$2=$I22,$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK=VSS,$2=$I23,$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK=VSS,$2=$I24,$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK=VSS,$2=$I25,$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);
end;
circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);
subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=$I7,OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);
@ -419,12 +419,12 @@ END
l2n.netlist.purge
assert_equal(l2n.netlist.to_s, <<END)
circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,'BULK,VSS'='BULK,VSS');
subcircuit INV2PAIR $1 (BULK='BULK,VSS',$2=FB,$3=VDD,$4='BULK,VSS',$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK='BULK,VSS',$2=(null),$3=VDD,$4='BULK,VSS',$5=$I6,$6=$I7,$7=VDD);
circuit RINGO (FB=FB,OSC=OSC,VDD=VDD,VSS=VSS);
subcircuit INV2PAIR $1 (BULK=VSS,$2=FB,$3=VDD,$4=VSS,$5=$I7,$6=OSC,$7=VDD);
subcircuit INV2PAIR $2 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=FB,$6=$I13,$7=VDD);
subcircuit INV2PAIR $3 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I13,$6=$I5,$7=VDD);
subcircuit INV2PAIR $4 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I5,$6=$I6,$7=VDD);
subcircuit INV2PAIR $5 (BULK=VSS,$2=(null),$3=VDD,$4=VSS,$5=$I6,$6=$I7,$7=VDD);
end;
circuit INV2PAIR (BULK=BULK,$2=$I8,$3=$I6,$4=$I5,$5=$I3,$6=$I2,$7=$I1);
subcircuit INV2 $1 ($1=$I1,IN=$I3,$3=(null),OUT=$I4,VSS=$I5,VDD=$I6,BULK=BULK);