mirror of https://github.com/KLayout/klayout.git
l2n dump format is leaner (device terminal shapes dropped from nets as they are contained in the device abstracts). Some refactoring.
This commit is contained in:
parent
8213e71a79
commit
a5e2cf58c3
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "dbDeviceModel.h"
|
||||
#include "dbCircuit.h"
|
||||
#include "dbNetlist.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -71,11 +72,17 @@ void DeviceModel::set_netlist (Netlist *netlist)
|
|||
void DeviceModel::set_name (const std::string &n)
|
||||
{
|
||||
m_name = n;
|
||||
if (mp_netlist) {
|
||||
mp_netlist->m_device_model_by_name.invalidate ();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceModel::set_cell_index (db::cell_index_type ci)
|
||||
{
|
||||
m_cell_index = ci;
|
||||
if (mp_netlist) {
|
||||
mp_netlist->m_device_model_by_cell_index.invalidate ();
|
||||
}
|
||||
}
|
||||
|
||||
size_t DeviceModel::cluster_id_for_terminal (size_t terminal_id) const
|
||||
|
|
|
|||
|
|
@ -260,13 +260,9 @@ db::CellMapping LayoutToNetlist::cell_mapping_into (db::Layout &layout, db::Cell
|
|||
unsigned int layout_index = 0;
|
||||
|
||||
std::set<db::cell_index_type> device_cells;
|
||||
|
||||
if (! with_device_cells) {
|
||||
const db::Layout &src_layout = m_dss.layout (layout_index);
|
||||
for (db::Layout::const_iterator c = src_layout.begin (); c != src_layout.end (); ++c) {
|
||||
if (db::NetlistDeviceExtractor::is_device_cell (src_layout, c->cell_index ())) {
|
||||
device_cells.insert (c->cell_index ());
|
||||
}
|
||||
if (! with_device_cells && mp_netlist.get ()) {
|
||||
for (db::Netlist::device_model_iterator i = mp_netlist->begin_device_models (); i != mp_netlist->end_device_models (); ++i) {
|
||||
device_cells.insert (i->cell_index ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -404,7 +400,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
if (cm == cmap.end ()) {
|
||||
|
||||
const char *name_prefix = 0;
|
||||
if (db::NetlistDeviceExtractor::is_device_cell (*internal_layout (), subci)) {
|
||||
if (mp_netlist->device_model_by_cell_index (subci)) {
|
||||
name_prefix = device_cell_name_prefix;
|
||||
} else {
|
||||
name_prefix = cell_name_prefix;
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
*mp_stream << "# Circuits are the hierarchical building blocks of the netlist." << endl;
|
||||
for (db::Netlist::const_bottom_up_circuit_iterator i = nl->begin_bottom_up (); i != nl->end_bottom_up (); ++i) {
|
||||
const db::Circuit *x = *i;
|
||||
*mp_stream << endl << "# Circuit " << x->name () << endl;
|
||||
*mp_stream << Keys::circuit_key << "(" << tl::to_word_or_quoted_string (x->name ()) << endl;
|
||||
write (l2n, *x);
|
||||
*mp_stream << ")" << endl;
|
||||
|
|
@ -233,6 +232,10 @@ void std_writer_impl<Keys>::write (const db::PolygonRef *s, const db::ICplxTrans
|
|||
template <class Keys>
|
||||
void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n, const db::Net &net)
|
||||
{
|
||||
if (! l2n->netlist ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Can't write annotated netlist before extraction has been done")));
|
||||
}
|
||||
|
||||
const db::Layout *ly = l2n->internal_layout ();
|
||||
const db::hier_clusters<db::PolygonRef> &clusters = l2n->net_clusters ();
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
|
|
@ -251,7 +254,7 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n, const db::Net
|
|||
// vanish in "purge" but the clusters will still be there we need to recursive into clusters from
|
||||
// unknown cells.
|
||||
db::cell_index_type ci = si.cell_index ();
|
||||
if (ci != prev_ci && ci != cci && l2n->netlist ()->circuit_by_cell_index (ci)) {
|
||||
if (ci != prev_ci && ci != cci && (l2n->netlist ()->circuit_by_cell_index (ci) || l2n->netlist ()->device_model_by_cell_index (ci))) {
|
||||
|
||||
si.skip_cell ();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,26 +33,33 @@ namespace db
|
|||
Netlist::Netlist ()
|
||||
: m_valid_topology (false), m_lock_count (0),
|
||||
m_circuit_by_name (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits)
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_device_model_by_name (this, &Netlist::begin_device_models, &Netlist::end_device_models),
|
||||
m_device_model_by_cell_index (this, &Netlist::begin_device_models, &Netlist::end_device_models)
|
||||
{
|
||||
m_circuits.changed ().add (this, &Netlist::invalidate_topology);
|
||||
m_circuits.changed ().add (this, &Netlist::circuits_changed);
|
||||
m_device_models.changed ().add (this, &Netlist::device_models_changed);
|
||||
}
|
||||
|
||||
Netlist::Netlist (const Netlist &other)
|
||||
: gsi::ObjectBase (other), tl::Object (other), m_valid_topology (false), m_lock_count (0),
|
||||
m_circuit_by_name (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits)
|
||||
m_circuit_by_cell_index (this, &Netlist::begin_circuits, &Netlist::end_circuits),
|
||||
m_device_model_by_name (this, &Netlist::begin_device_models, &Netlist::end_device_models),
|
||||
m_device_model_by_cell_index (this, &Netlist::begin_device_models, &Netlist::end_device_models)
|
||||
{
|
||||
operator= (other);
|
||||
m_circuits.changed ().add (this, &Netlist::invalidate_topology);
|
||||
m_circuits.changed ().add (this, &Netlist::circuits_changed);
|
||||
m_device_models.changed ().add (this, &Netlist::device_models_changed);
|
||||
}
|
||||
|
||||
Netlist::~Netlist ()
|
||||
{
|
||||
m_circuits.changed ().remove (this, &Netlist::invalidate_topology);
|
||||
m_circuits.changed ().remove (this, &Netlist::circuits_changed);
|
||||
m_device_models.changed ().remove (this, &Netlist::device_models_changed);
|
||||
}
|
||||
|
||||
Netlist &Netlist::operator= (const Netlist &other)
|
||||
|
|
@ -98,6 +105,12 @@ void Netlist::circuits_changed ()
|
|||
m_circuit_by_name.invalidate ();
|
||||
}
|
||||
|
||||
void Netlist::device_models_changed ()
|
||||
{
|
||||
m_device_model_by_cell_index.invalidate ();
|
||||
m_device_model_by_name.invalidate ();
|
||||
}
|
||||
|
||||
void Netlist::invalidate_topology ()
|
||||
{
|
||||
if (m_valid_topology) {
|
||||
|
|
|
|||
|
|
@ -349,6 +349,46 @@ public:
|
|||
return m_device_models.end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the device model with the given name
|
||||
*
|
||||
* If no device model with that name exists, null is returned.
|
||||
*/
|
||||
DeviceModel *device_model_by_name (const std::string &name)
|
||||
{
|
||||
return m_device_model_by_name.object_by (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the device model with the given name (const version)
|
||||
*
|
||||
* If no device model with that name exists, null is returned.
|
||||
*/
|
||||
const DeviceModel *device_model_by_name (const std::string &name) const
|
||||
{
|
||||
return m_device_model_by_name.object_by (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the device model with the given cell index
|
||||
*
|
||||
* If no device model with that cell index exists, null is returned.
|
||||
*/
|
||||
DeviceModel *device_model_by_cell_index (db::cell_index_type cell_index)
|
||||
{
|
||||
return m_device_model_by_cell_index.object_by (cell_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the device model with the given cell index (const version)
|
||||
*
|
||||
* If no device model with that cell index exists, null is returned.
|
||||
*/
|
||||
const DeviceModel *device_model_by_cell_index (db::cell_index_type cell_index) const
|
||||
{
|
||||
return m_device_model_by_cell_index.object_by (cell_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Purge unused nets
|
||||
*
|
||||
|
|
@ -383,6 +423,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class Circuit;
|
||||
friend class DeviceModel;
|
||||
|
||||
circuit_list m_circuits;
|
||||
device_class_list m_device_classes;
|
||||
|
|
@ -395,10 +436,13 @@ private:
|
|||
size_t m_top_circuits;
|
||||
object_by_attr<Netlist, Netlist::circuit_iterator, name_attribute<Circuit> > m_circuit_by_name;
|
||||
object_by_attr<Netlist, Netlist::circuit_iterator, cell_index_attribute<Circuit> > m_circuit_by_cell_index;
|
||||
object_by_attr<Netlist, Netlist::device_model_iterator, name_attribute<DeviceModel> > m_device_model_by_name;
|
||||
object_by_attr<Netlist, Netlist::device_model_iterator, cell_index_attribute<DeviceModel> > m_device_model_by_cell_index;
|
||||
|
||||
void invalidate_topology ();
|
||||
void validate_topology ();
|
||||
void circuits_changed ();
|
||||
void device_models_changed ();
|
||||
|
||||
const tl::vector<Circuit *> &child_circuits (Circuit *circuit);
|
||||
const tl::vector<Circuit *> &parent_circuits (Circuit *circuit);
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
for (std::set<db::cell_index_type>::const_iterator ci = called_cells.begin (); ci != called_cells.end (); ++ci) {
|
||||
|
||||
// skip device cells from previous extractions
|
||||
if (is_device_cell (*ci)) {
|
||||
if (m_netlist->device_model_by_cell_index (*ci)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -223,33 +223,6 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
}
|
||||
}
|
||||
|
||||
bool NetlistDeviceExtractor::is_device_cell (const db::Layout &layout, db::cell_index_type ci)
|
||||
{
|
||||
db::properties_id_type pi = layout.cell (ci).prop_id ();
|
||||
if (pi == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<bool, db::property_names_id_type> pn = layout.properties_repository ().get_id_of_name (db::NetlistDeviceExtractor::device_class_property_name ());
|
||||
if (! pn.first) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = layout.properties_repository ().properties (pi);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
if (j->first == pn.second) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetlistDeviceExtractor::is_device_cell (db::cell_index_type ci) const
|
||||
{
|
||||
return is_device_cell (*mp_layout, ci);
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::push_new_devices ()
|
||||
{
|
||||
db::VCplxTrans dbu_inv = db::CplxTrans (mp_layout->dbu ()).inverted ();
|
||||
|
|
@ -298,8 +271,6 @@ void NetlistDeviceExtractor::push_new_devices ()
|
|||
ps.insert (std::make_pair (m_device_class_propname_id, tl::Variant (mp_device_class->name ())));
|
||||
device_cell.prop_id (mp_layout->properties_repository ().properties_id (ps));
|
||||
|
||||
db::connected_clusters<db::PolygonRef> &cc = mp_clusters->clusters_per_cell (device_cell.cell_index ());
|
||||
|
||||
for (geometry_per_terminal_type::const_iterator t = d->second.begin (); t != d->second.end (); ++t) {
|
||||
|
||||
// Build a property set for the device terminal ID
|
||||
|
|
|
|||
|
|
@ -234,11 +234,6 @@ public:
|
|||
*/
|
||||
static const tl::Variant &device_class_property_name ();
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the given cell is a device cell
|
||||
*/
|
||||
static bool is_device_cell (const db::Layout &layout, db::cell_index_type ci);
|
||||
|
||||
/**
|
||||
* @brief Performs the extraction
|
||||
*
|
||||
|
|
@ -527,7 +522,6 @@ private:
|
|||
|
||||
void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers);
|
||||
void push_new_devices ();
|
||||
bool is_device_cell (db::cell_index_type ci) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,12 +63,6 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
|
|||
circuits.insert (std::make_pair (c->cell_index (), c.operator-> ()));
|
||||
}
|
||||
|
||||
// reverse lookup for DeviceModel vs. cell index
|
||||
std::map<db::cell_index_type, db::DeviceModel *> device_models;
|
||||
for (db::Netlist::device_model_iterator dm = nl.begin_device_models (); dm != nl.end_device_models (); ++dm) {
|
||||
device_models.insert (std::make_pair (dm->cell_index (), dm.operator-> ()));
|
||||
}
|
||||
|
||||
std::map<db::cell_index_type, std::map<size_t, size_t> > pins_per_cluster_per_cell;
|
||||
for (db::Layout::bottom_up_const_iterator cid = mp_layout->begin_bottom_up (); cid != mp_layout->end_bottom_up (); ++cid) {
|
||||
|
||||
|
|
@ -77,28 +71,11 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
|
|||
continue;
|
||||
}
|
||||
|
||||
std::map<db::cell_index_type, db::DeviceModel *>::const_iterator dmc = device_models.find (*cid);
|
||||
if (dmc != device_models.end ()) {
|
||||
|
||||
db::DeviceModel *dm = nl.device_model_by_cell_index (*cid);
|
||||
if (dm) {
|
||||
// make the terminal to cluster ID connections for the device model from the device cells
|
||||
|
||||
if (m_terminal_annot_name_id.first) {
|
||||
|
||||
for (connected_clusters_type::const_iterator dc = clusters.begin (); dc != clusters.end (); ++dc) {
|
||||
for (local_cluster_type::attr_iterator a = dc->begin_attr (); a != dc->end_attr (); ++a) {
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
if (j->first == m_terminal_annot_name_id.second) {
|
||||
dmc->second->set_cluster_id_for_terminal (j->second.to<size_t> (), dc->id ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
make_device_model_connections (dm, clusters);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// a cell makes a new circuit (or uses an existing one)
|
||||
|
|
@ -151,6 +128,31 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, const db::Connect
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
NetlistExtractor::make_device_model_connections (db::DeviceModel *dm, const connected_clusters_type &clusters)
|
||||
{
|
||||
// make the terminal to cluster ID connections for the device model from the device cells
|
||||
|
||||
if (m_terminal_annot_name_id.first) {
|
||||
|
||||
for (connected_clusters_type::const_iterator dc = clusters.begin (); dc != clusters.end (); ++dc) {
|
||||
|
||||
for (local_cluster_type::attr_iterator a = dc->begin_attr (); a != dc->end_attr (); ++a) {
|
||||
|
||||
const db::PropertiesRepository::properties_set &ps = mp_layout->properties_repository ().properties (*a);
|
||||
for (db::PropertiesRepository::properties_set::const_iterator j = ps.begin (); j != ps.end (); ++j) {
|
||||
if (j->first == m_terminal_annot_name_id.second) {
|
||||
dm->set_cluster_id_for_terminal (j->second.to<size_t> (), dc->id ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,
|
||||
size_t cid,
|
||||
db::Net *net)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ class Circuit;
|
|||
class SubCircuit;
|
||||
class Net;
|
||||
class Device;
|
||||
class DeviceModel;
|
||||
|
||||
/**
|
||||
* @brief The Netlist Extractor
|
||||
|
|
@ -151,6 +152,12 @@ private:
|
|||
void collect_labels (const connected_clusters_type &clusters,
|
||||
size_t cid,
|
||||
db::Net *net);
|
||||
|
||||
/**
|
||||
* @brief Makes the terminal to cluster ID connections of the device model
|
||||
*/
|
||||
void make_device_model_connections (db::DeviceModel *dm, const connected_clusters_type &clusters);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,4 +63,27 @@ TEST(1_ReaderBasic)
|
|||
tl::absolute_file_path (path),
|
||||
tl::absolute_file_path (au_path)));
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
std::string path = tmp_file ("tmp_l2nwriter_1.txt");
|
||||
{
|
||||
tl::OutputStream stream (path);
|
||||
db::LayoutToNetlistStandardWriter writer (stream, false);
|
||||
writer.write (&l2n);
|
||||
}
|
||||
|
||||
std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au.txt");
|
||||
|
||||
tl::InputStream is (path);
|
||||
tl::InputStream is_au (au_path);
|
||||
|
||||
if (is.read_all () != is_au.read_all ()) {
|
||||
_this->raise (tl::sprintf ("Compare failed - see\n actual: %s\n golden: %s",
|
||||
tl::absolute_file_path (path),
|
||||
tl::absolute_file_path (au_path)));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1047,10 +1047,19 @@ TEST(13_DeviceModel)
|
|||
db::Netlist nl;
|
||||
|
||||
db::DeviceModel *dm = new db::DeviceModel (0, "name");
|
||||
nl.add_device_model (dm);
|
||||
EXPECT_EQ (dm->netlist () == &nl, true);
|
||||
|
||||
EXPECT_EQ (dm->device_class () == 0, true);
|
||||
EXPECT_EQ (dm->name (), "name");
|
||||
EXPECT_EQ (nl.device_model_by_name ("name") == dm, true);
|
||||
EXPECT_EQ (nl.device_model_by_name ("name2") == 0, true);
|
||||
EXPECT_EQ (nl.device_model_by_name ("does_not_exist") == 0, true);
|
||||
dm->set_name ("name2");
|
||||
EXPECT_EQ (dm->name (), "name2");
|
||||
EXPECT_EQ (nl.device_model_by_name ("name") == 0, true);
|
||||
EXPECT_EQ (nl.device_model_by_name ("name2") == dm, true);
|
||||
EXPECT_EQ (nl.device_model_by_name ("does_not_exist") == 0, true);
|
||||
|
||||
dm->set_cluster_id_for_terminal (1, 17);
|
||||
dm->set_cluster_id_for_terminal (0, 42);
|
||||
|
|
@ -1058,10 +1067,10 @@ TEST(13_DeviceModel)
|
|||
EXPECT_EQ (dm->cluster_id_for_terminal (1), size_t (17));
|
||||
|
||||
dm->set_cell_index (5);
|
||||
EXPECT_EQ (nl.device_model_by_cell_index (5) == dm, true);
|
||||
EXPECT_EQ (nl.device_model_by_cell_index (17) == 0, true);
|
||||
EXPECT_EQ (dm->cell_index (), db::cell_index_type (5));
|
||||
|
||||
nl.add_device_model (dm);
|
||||
EXPECT_EQ (dm->netlist () == &nl, true);
|
||||
EXPECT_EQ (nl.begin_device_models () == nl.end_device_models (), false);
|
||||
EXPECT_EQ (nl.begin_device_models ()->name (), "name2");
|
||||
|
||||
|
|
|
|||
|
|
@ -82,8 +82,6 @@ device(D$NMOS$1 NMOS
|
|||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
|
||||
# Circuit INV2
|
||||
circuit(INV2
|
||||
|
||||
# Nets with their geometries
|
||||
|
|
@ -91,9 +89,7 @@ circuit(INV2
|
|||
rect(poly -525 -250 -275 2250)
|
||||
rect(poly -1700 1620 -400 1980)
|
||||
rect(poly -525 -800 -275 800)
|
||||
rect(poly -525 -475 -275 475)
|
||||
rect(poly -525 2000 -275 3600)
|
||||
rect(poly -525 2325 -275 3275)
|
||||
rect(poly_lbl -801 1799 -799 1801)
|
||||
rect(poly_cont -1630 1690 -1410 1910)
|
||||
)
|
||||
|
|
@ -101,9 +97,7 @@ circuit(INV2
|
|||
rect(poly 275 -250 525 2250)
|
||||
rect(poly 220 820 580 1180)
|
||||
rect(poly 275 2000 525 3600)
|
||||
rect(poly 275 2325 525 3275)
|
||||
rect(poly 275 -800 525 800)
|
||||
rect(poly 275 -475 525 475)
|
||||
rect(diff_cont -910 2490 -690 2710)
|
||||
rect(diff_cont -910 2890 -690 3110)
|
||||
rect(diff_cont -910 -310 -690 -90)
|
||||
|
|
@ -114,8 +108,6 @@ circuit(INV2
|
|||
rect(metal1 -980 2420 -620 3180)
|
||||
rect(metal1 -980 -380 -620 380)
|
||||
rect(psd -1050 2325 -525 3275)
|
||||
rect(psd -1050 2325 -525 3275)
|
||||
rect(nsd -1050 -475 -525 475)
|
||||
rect(nsd -1050 -475 -525 475)
|
||||
)
|
||||
net(OUT
|
||||
|
|
@ -128,8 +120,6 @@ circuit(INV2
|
|||
rect(metal1 620 -380 980 380)
|
||||
rect(metal1_lbl 799 1799 801 1801)
|
||||
rect(psd 525 2325 1050 3275)
|
||||
rect(psd 525 2325 1050 3275)
|
||||
rect(nsd 525 -475 1050 475)
|
||||
rect(nsd 525 -475 1050 475)
|
||||
)
|
||||
net($4
|
||||
|
|
@ -143,8 +133,6 @@ circuit(INV2
|
|||
rect(via1 -125 75 125 325)
|
||||
rect(metal2 -1400 -450 1400 450)
|
||||
rect(nsd -275 -475 275 475)
|
||||
rect(nsd -275 -475 275 475)
|
||||
rect(nsd -275 -475 275 475)
|
||||
)
|
||||
net($5
|
||||
rect(diff_cont -110 2490 110 2710)
|
||||
|
|
@ -157,8 +145,6 @@ circuit(INV2
|
|||
rect(via1 -125 2875 125 3125)
|
||||
rect(metal2 -1400 2350 1400 3250)
|
||||
rect(psd -275 2325 275 3275)
|
||||
rect(psd -275 2325 275 3275)
|
||||
rect(psd -275 2325 275 3275)
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
|
|
@ -211,8 +197,6 @@ circuit(INV2
|
|||
)
|
||||
|
||||
)
|
||||
|
||||
# Circuit RINGO
|
||||
circuit(RINGO
|
||||
|
||||
# Nets with their geometries
|
||||
|
|
|
|||
Loading…
Reference in New Issue