mirror of https://github.com/KLayout/klayout.git
WIP: Enabled layout generation from read l2n data.
This commit is contained in:
parent
a5e2cf58c3
commit
dd39168dc8
|
|
@ -217,6 +217,11 @@ void LayoutToNetlist::extract_netlist ()
|
|||
m_netlist_extracted = true;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::set_netlist_extracted ()
|
||||
{
|
||||
m_netlist_extracted = true;
|
||||
}
|
||||
|
||||
const db::Layout *LayoutToNetlist::internal_layout () const
|
||||
{
|
||||
return &m_dss.const_layout ();
|
||||
|
|
@ -293,19 +298,30 @@ db::Netlist *LayoutToNetlist::make_netlist ()
|
|||
return mp_netlist.get ();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct StopOnFirst { };
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static void deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr)
|
||||
static bool deliver_shape (const db::PolygonRef &, StopOnFirst, const Tr &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
} else {
|
||||
region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class Tr>
|
||||
static void deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr)
|
||||
static bool deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const Tr &tr)
|
||||
{
|
||||
if (pr.obj ().is_box ()) {
|
||||
shapes.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr));
|
||||
|
|
@ -317,25 +333,51 @@ static void deliver_shape (const db::PolygonRef &pr, db::Shapes &shapes, const T
|
|||
shapes.insert (pr.obj ().transformed (pr.trans ()).transformed (tr));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static void deliver_shapes_of_net_recursive (const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, To &to)
|
||||
static bool deliver_shapes_of_net_recursive (const db::Netlist * /*nl*/, const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to)
|
||||
{
|
||||
// deliver the net shapes
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (clusters, layer_id, ci, cid); !rci.at_end (); ++rci) {
|
||||
deliver_shape (*rci, to, rci.trans ());
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class To>
|
||||
static void deliver_shapes_of_net_nonrecursive (const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, To &to)
|
||||
static bool deliver_shapes_of_net_nonrecursive (const db::Netlist *nl, const db::hier_clusters<db::PolygonRef> &clusters, db::cell_index_type ci, size_t cid, unsigned int layer_id, const db::ICplxTrans &tr, To &to)
|
||||
{
|
||||
const db::local_cluster<db::PolygonRef> &lc = clusters.clusters_per_cell (ci).cluster_by_id (cid);
|
||||
// NOTE: this scheme will deliver the shapes from the cell, including (!)
|
||||
// subcells that are purged
|
||||
|
||||
db::cell_index_type prev_ci = ci;
|
||||
|
||||
// deliver the net shapes
|
||||
for (db::recursive_cluster_shape_iterator<db::PolygonRef> rci (clusters, layer_id, ci, cid); !rci.at_end (); ) {
|
||||
|
||||
db::cell_index_type cci = rci.cell_index ();
|
||||
if (cci != prev_ci && cci != ci && (! nl || nl->circuit_by_cell_index (cci) || nl->device_model_by_cell_index (cci))) {
|
||||
|
||||
rci.skip_cell ();
|
||||
|
||||
} else {
|
||||
|
||||
if (! deliver_shape (*rci, to, tr * rci.trans ())) {
|
||||
return false;
|
||||
}
|
||||
prev_ci = cci;
|
||||
|
||||
++rci;
|
||||
|
||||
}
|
||||
|
||||
for (db::local_cluster<db::PolygonRef>::shape_iterator s = lc.begin (layer_id); !s.at_end (); ++s) {
|
||||
deliver_shape (*s, to, db::UnitTrans ());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive, db::Shapes &to) const
|
||||
|
|
@ -345,9 +387,9 @@ void LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_la
|
|||
tl_assert (circuit != 0);
|
||||
|
||||
if (! recursive) {
|
||||
deliver_shapes_of_net_nonrecursive (m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, to);
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to);
|
||||
} else {
|
||||
deliver_shapes_of_net_recursive (m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, to);
|
||||
deliver_shapes_of_net_recursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), to);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,31 +402,60 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region
|
|||
std::auto_ptr<db::Region> res (new db::Region ());
|
||||
|
||||
if (! recursive) {
|
||||
deliver_shapes_of_net_nonrecursive (m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, *res);
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res);
|
||||
} else {
|
||||
deliver_shapes_of_net_recursive (m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, *res);
|
||||
deliver_shapes_of_net_recursive (mp_netlist.get (), m_net_clusters, circuit->cell_index (), net.cluster_id (), lid, db::ICplxTrans (), *res);
|
||||
}
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap) const
|
||||
LayoutToNetlist::build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
{
|
||||
const db::Circuit *circuit = net.circuit ();
|
||||
tl_assert (circuit != 0);
|
||||
|
||||
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, cell_name_prefix, device_cell_name_prefix, cmap);
|
||||
build_net_rec (circuit->cell_index (), net.cluster_id (), target, target_cell, lmap, &net, net_cell_name_prefix, cell_name_prefix, device_cell_name_prefix, cmap, tr);
|
||||
}
|
||||
|
||||
void
|
||||
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap) const
|
||||
LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &tc, const std::map<unsigned int, const db::Region *> &lmap, const db::Net *net, const char *net_cell_name_prefix, const char *circuit_cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const db::ICplxTrans &tr) const
|
||||
{
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
deliver_shapes_of_net_nonrecursive (m_net_clusters, ci, cid, layer_of (*l->second), target_cell.shapes (l->first));
|
||||
db::Cell *target_cell = &tc;
|
||||
|
||||
if (net_cell_name_prefix) {
|
||||
|
||||
const db::connected_clusters<db::PolygonRef> &ccl = m_net_clusters.clusters_per_cell (ci);
|
||||
|
||||
bool any_connections = circuit_cell_name_prefix && ! ccl.connections_for_cluster (cid).empty ();
|
||||
if (! any_connections) {
|
||||
|
||||
bool consider_cell = any_connections;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end () && !consider_cell; ++l) {
|
||||
StopOnFirst sof;
|
||||
consider_cell = deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, sof);
|
||||
}
|
||||
|
||||
if (! consider_cell) {
|
||||
// shortcut if cell is empty -> no net cell will be produced
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make a specific cell for the net if requested
|
||||
|
||||
target_cell = &target.cell (target.add_cell ((std::string (net_cell_name_prefix) + net->expanded_name ()).c_str ()));
|
||||
tc.insert (db::CellInstArray (db::CellInst (target_cell->cell_index ()), db::Trans ()));
|
||||
|
||||
}
|
||||
|
||||
if (! cell_name_prefix && ! device_cell_name_prefix) {
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator l = lmap.begin (); l != lmap.end (); ++l) {
|
||||
deliver_shapes_of_net_nonrecursive (mp_netlist.get (), m_net_clusters, ci, cid, layer_of (*l->second), tr, target_cell->shapes (l->first));
|
||||
}
|
||||
|
||||
if (! circuit_cell_name_prefix && ! device_cell_name_prefix) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +474,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
if (mp_netlist->device_model_by_cell_index (subci)) {
|
||||
name_prefix = device_cell_name_prefix;
|
||||
} else {
|
||||
name_prefix = cell_name_prefix;
|
||||
name_prefix = circuit_cell_name_prefix;
|
||||
}
|
||||
|
||||
if (name_prefix) {
|
||||
|
|
@ -413,7 +484,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
db::cell_index_type target_ci = target.add_cell ((std::string (name_prefix) + cell_name).c_str ());
|
||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), target_ci)).first;
|
||||
|
||||
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, cell_name_prefix, device_cell_name_prefix, cmap);
|
||||
build_net_rec (subci, subcid, target, target.cell (target_ci), lmap, 0, 0, circuit_cell_name_prefix, device_cell_name_prefix, cmap, db::ICplxTrans ());
|
||||
|
||||
} else {
|
||||
cm = cmap.insert (std::make_pair (std::make_pair (subci, subcid), std::numeric_limits<db::cell_index_type>::max ())).first;
|
||||
|
|
@ -422,7 +493,7 @@ LayoutToNetlist::build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &
|
|||
}
|
||||
|
||||
if (cm->second != std::numeric_limits<db::cell_index_type>::max ()) {
|
||||
target_cell.insert (db::CellInstArray (db::CellInst (cm->second), c->inst ().complex_trans ()));
|
||||
target_cell->insert (db::CellInstArray (db::CellInst (cm->second), tr * c->inst ().complex_trans ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -437,7 +508,7 @@ LayoutToNetlist::build_net (const db::Net &net, db::Layout &target, db::Cell &ta
|
|||
|
||||
std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> cell_map;
|
||||
|
||||
build_net_rec (net, target, target_cell, lmap, cell_name_prefix, device_cell_name_prefix, cell_map);
|
||||
build_net_rec (net, target, target_cell, lmap, 0, cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -456,39 +527,55 @@ LayoutToNetlist::build_all_nets (const db::CellMapping &cmap, db::Layout &target
|
|||
continue;
|
||||
}
|
||||
|
||||
bool is_top_circuit = c->begin_parents () == c->end_parents ();
|
||||
|
||||
db::cell_index_type target_ci = cmap.cell_mapping (c->cell_index ());
|
||||
|
||||
for (db::Circuit::const_net_iterator n = c->begin_nets (); n != c->end_nets (); ++n) {
|
||||
|
||||
// exlude local nets in recursive mode
|
||||
if (circuit_cell_name_prefix && n->pin_count () > 0) {
|
||||
if (circuit_cell_name_prefix && ! is_top_circuit && n->pin_count () > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const db::connected_clusters<db::PolygonRef> &ccl = m_net_clusters.clusters_per_cell (c->cell_index ());
|
||||
const db::local_cluster<db::PolygonRef> &cl = ccl.cluster_by_id (n->cluster_id ());
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, db::ICplxTrans ());
|
||||
|
||||
bool any_connections = ! ccl.connections_for_cluster (n->cluster_id ()).empty ();
|
||||
}
|
||||
|
||||
bool any_shapes = false;
|
||||
for (std::map<unsigned int, const db::Region *>::const_iterator m = lmap.begin (); m != lmap.end () && !any_shapes; ++m) {
|
||||
any_shapes = ! cl.begin (layer_of (*m->second)).at_end ();
|
||||
}
|
||||
if (circuit_cell_name_prefix) {
|
||||
|
||||
if (any_shapes || (circuit_cell_name_prefix && any_connections)) {
|
||||
// with recursive nets we skip nets in subcircuits which are connected upwards. This means, nets will
|
||||
// get lost if there is no connection to this pin from the outside. Hence we need to deliver nets from
|
||||
// subcircuits as part of the circuit which calls the subcircuit - but NOT in a subcircuit cell, because
|
||||
// this will just apply to nets from certain instances. But the net cell name will be formed as "subcircuit:net"
|
||||
|
||||
db::cell_index_type net_ci = target_ci;
|
||||
const db::Circuit &circuit = *c;
|
||||
for (db::Circuit::const_subcircuit_iterator sc = circuit.begin_subcircuits (); sc != circuit.end_subcircuits (); ++sc) {
|
||||
|
||||
if (net_cell_name_prefix) {
|
||||
const db::SubCircuit &subcircuit = *sc;
|
||||
for (db::Circuit::const_pin_iterator p = subcircuit.circuit_ref ()->begin_pins (); p != subcircuit.circuit_ref ()->end_pins (); ++p) {
|
||||
|
||||
db::Cell &tc = target.cell (target_ci);
|
||||
net_ci = target.add_cell ((std::string (net_cell_name_prefix) + n->expanded_name ()).c_str ());
|
||||
tc.insert (db::CellInstArray (db::CellInst (net_ci), db::Trans ()));
|
||||
if (! subcircuit.net_for_pin (p->id ())) {
|
||||
|
||||
const db::Net *n = subcircuit.circuit_ref ()->net_for_pin (p->id ());
|
||||
if (n) {
|
||||
|
||||
double dbu = target.dbu ();
|
||||
db::ICplxTrans tr = db::CplxTrans (dbu).inverted () * subcircuit.trans () * db::CplxTrans (dbu);
|
||||
|
||||
if (net_cell_name_prefix) {
|
||||
std::string ncn = std::string (net_cell_name_prefix) + subcircuit.expanded_name () + ":";
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, ncn.c_str (), circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
||||
} else {
|
||||
build_net_rec (*n, target, target.cell (target_ci), lmap, net_cell_name_prefix, circuit_cell_name_prefix, device_cell_name_prefix, cell_map, tr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
build_net_rec (*n, target, target.cell (net_ci), lmap, circuit_cell_name_prefix, device_cell_name_prefix, cell_map);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ public:
|
|||
/**
|
||||
* @brief Creates a new region representing an original layer
|
||||
* "layer_index" is the layer index of the desired layer in the original layout.
|
||||
* The Region object returned is a new object and must be deleted by the caller.
|
||||
* This variant produces polygons and takes texts for net name annotation.
|
||||
* A variant not taking texts is "make_polygon_layer". A Variant only taking
|
||||
* texts is "make_text_layer".
|
||||
|
|
@ -211,6 +210,13 @@ public:
|
|||
*/
|
||||
void extract_netlist ();
|
||||
|
||||
/**
|
||||
* @brief Marks the netlist as extracted
|
||||
* NOTE: this method is provided for special cases such as netlist readers. Don't
|
||||
* use it.
|
||||
*/
|
||||
void set_netlist_extracted ();
|
||||
|
||||
/**
|
||||
* @brief Gets the internal layout
|
||||
*/
|
||||
|
|
@ -268,6 +274,8 @@ public:
|
|||
|
||||
/**
|
||||
* @brief gets the netlist extracted or make on if none exists yet.
|
||||
* NOTE: this method is provided for special cases like readers of persisted
|
||||
* layout to netlist data.
|
||||
*/
|
||||
db::Netlist *make_netlist ();
|
||||
|
||||
|
|
@ -401,8 +409,8 @@ private:
|
|||
bool m_netlist_extracted;
|
||||
|
||||
size_t search_net (const db::ICplxTrans &trans, const db::Cell *cell, const db::local_cluster<db::PolygonRef> &test_cluster, std::vector<db::InstElement> &rev_inst_path);
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap) const;
|
||||
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap) const;
|
||||
void build_net_rec (const db::Net &net, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
|
||||
void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map<unsigned int, const db::Region *> &lmap, const Net *net, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map<std::pair<db::cell_index_type, size_t>, db::cell_index_type> &cmap, const ICplxTrans &tr) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ namespace l2n_std_format
|
|||
param_key, location_key, rotation_key,
|
||||
mirror_key, scale_key, pin_key,
|
||||
indent1, indent2;
|
||||
|
||||
inline static bool is_short () { return Short; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ public:
|
|||
m_layers.insert (std::make_pair (name, region));
|
||||
}
|
||||
|
||||
bool has_layer (const std::string &name) const
|
||||
{
|
||||
return m_layers.find (name) != m_layers.end ();
|
||||
}
|
||||
|
||||
db::Region &layer (const std::string &name)
|
||||
{
|
||||
std::map<std::string, db::Region *>::const_iterator l = m_layers.find (name);
|
||||
|
|
@ -180,6 +185,11 @@ void LayoutToNetlistStandardReader::read (db::LayoutToNetlist *l2n)
|
|||
}
|
||||
}
|
||||
|
||||
const db::Region *LayoutToNetlistStandardReader::layer_by_name (const std::string &name)
|
||||
{
|
||||
return mp_layers->has_layer (name) ? &mp_layers->layer (name) : 0;
|
||||
}
|
||||
|
||||
void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
int version = 0;
|
||||
|
|
@ -191,7 +201,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
|
||||
l2n->make_netlist ();
|
||||
|
||||
Layers layers;
|
||||
mp_layers.reset (new Layers ());
|
||||
|
||||
while (! at_end ()) {
|
||||
|
||||
|
|
@ -227,7 +237,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
Brace br (this);
|
||||
std::string layer;
|
||||
read_word_or_quoted (layer);
|
||||
layers.add (layer, l2n->make_layer (layer));
|
||||
mp_layers->add (layer, l2n->make_layer (layer));
|
||||
br.done ();
|
||||
|
||||
} else if (test (skeys::connect_key) || test (lkeys::connect_key)) {
|
||||
|
|
@ -238,7 +248,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
while (br) {
|
||||
std::string l2;
|
||||
read_word_or_quoted (l2);
|
||||
l2n->connect (layers.layer (l1), layers.layer (l2));
|
||||
l2n->connect (mp_layers->layer (l1), mp_layers->layer (l2));
|
||||
}
|
||||
br.done ();
|
||||
|
||||
|
|
@ -250,7 +260,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
while (br) {
|
||||
std::string g;
|
||||
read_word_or_quoted (g);
|
||||
l2n->connect_global (layers.layer (l1), g);
|
||||
l2n->connect_global (mp_layers->layer (l1), g);
|
||||
}
|
||||
br.done ();
|
||||
|
||||
|
|
@ -265,7 +275,8 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
l2n->netlist ()->add_circuit (circuit);
|
||||
|
||||
db::Layout *ly = l2n->internal_layout ();
|
||||
db::cell_index_type ci = ly->add_cell (name.c_str ());
|
||||
std::pair<bool, db::cell_index_type> ci_old = ly->cell_by_name (name.c_str ());
|
||||
db::cell_index_type ci = ci_old.first ? ci_old.second : ly->add_cell (name.c_str ());
|
||||
circuit->set_cell_index (ci);
|
||||
|
||||
std::map<db::CellInstArray, std::list<Connections> > connections;
|
||||
|
|
@ -273,7 +284,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
while (br) {
|
||||
|
||||
if (test (skeys::net_key) || test (lkeys::net_key)) {
|
||||
read_net (l2n, circuit, layers);
|
||||
read_net (l2n, circuit);
|
||||
} else if (test (skeys::pin_key) || test (lkeys::pin_key)) {
|
||||
read_pin (l2n, circuit);
|
||||
} else if (test (skeys::device_key) || test (lkeys::device_key)) {
|
||||
|
|
@ -340,7 +351,7 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
while (br) {
|
||||
|
||||
if (test (skeys::terminal_key) || test (lkeys::terminal_key)) {
|
||||
read_abstract_terminal (l2n, dm, gen_dc ? dc : 0, layers);
|
||||
read_abstract_terminal (l2n, dm, gen_dc ? dc : 0);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid keyword inside device abstract definition (terminal expected)")));
|
||||
}
|
||||
|
|
@ -352,10 +363,12 @@ void LayoutToNetlistStandardReader::do_read (db::LayoutToNetlist *l2n)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
l2n->set_netlist_extracted ();
|
||||
}
|
||||
|
||||
std::pair<unsigned int, db::PolygonRef>
|
||||
LayoutToNetlistStandardReader::read_geometry (db::LayoutToNetlist *l2n, Layers &layers)
|
||||
LayoutToNetlistStandardReader::read_geometry (db::LayoutToNetlist *l2n)
|
||||
{
|
||||
std::string lname;
|
||||
|
||||
|
|
@ -364,7 +377,7 @@ LayoutToNetlistStandardReader::read_geometry (db::LayoutToNetlist *l2n, Layers &
|
|||
Brace br (this);
|
||||
|
||||
read_word_or_quoted (lname);
|
||||
unsigned int lid = l2n->layer_of (layers.layer (lname));
|
||||
unsigned int lid = l2n->layer_of (mp_layers->layer (lname));
|
||||
|
||||
db::Coord l = read_coord ();
|
||||
db::Coord b = read_coord ();
|
||||
|
|
@ -381,7 +394,7 @@ LayoutToNetlistStandardReader::read_geometry (db::LayoutToNetlist *l2n, Layers &
|
|||
Brace br (this);
|
||||
|
||||
read_word_or_quoted (lname);
|
||||
unsigned int lid = l2n->layer_of (layers.layer (lname));
|
||||
unsigned int lid = l2n->layer_of (mp_layers->layer (lname));
|
||||
|
||||
std::vector<db::Point> pt;
|
||||
|
||||
|
|
@ -403,7 +416,7 @@ LayoutToNetlistStandardReader::read_geometry (db::LayoutToNetlist *l2n, Layers &
|
|||
}
|
||||
|
||||
void
|
||||
LayoutToNetlistStandardReader::read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit, Layers &layers)
|
||||
LayoutToNetlistStandardReader::read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit)
|
||||
{
|
||||
Brace br (this);
|
||||
|
||||
|
|
@ -421,7 +434,7 @@ LayoutToNetlistStandardReader::read_net (db::LayoutToNetlist *l2n, db::Circuit *
|
|||
db::Cell &cell = l2n->internal_layout ()->cell (circuit->cell_index ());
|
||||
|
||||
while (br) {
|
||||
std::pair<unsigned int, db::PolygonRef> pr = read_geometry (l2n, layers);
|
||||
std::pair<unsigned int, db::PolygonRef> pr = read_geometry (l2n);
|
||||
lc.add (pr.second, pr.first);
|
||||
cell.shapes (pr.first).insert (pr.second);
|
||||
}
|
||||
|
|
@ -675,7 +688,7 @@ LayoutToNetlistStandardReader::read_subcircuit (db::LayoutToNetlist *l2n, db::Ci
|
|||
}
|
||||
|
||||
void
|
||||
LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceModel *dm, db::DeviceClass *dc, Layers &layers)
|
||||
LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceModel *dm, db::DeviceClass *dc)
|
||||
{
|
||||
Brace br (this);
|
||||
|
||||
|
|
@ -707,7 +720,7 @@ LayoutToNetlistStandardReader::read_abstract_terminal (db::LayoutToNetlist *l2n,
|
|||
db::Cell &cell = l2n->internal_layout ()->cell (dm->cell_index ());
|
||||
|
||||
while (br) {
|
||||
std::pair<unsigned int, db::PolygonRef> pr = read_geometry (l2n, layers);
|
||||
std::pair<unsigned int, db::PolygonRef> pr = read_geometry (l2n);
|
||||
lc.add (pr.second, pr.first);
|
||||
cell.shapes (pr.first).insert (pr.second);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class Circuit;
|
|||
class Cell;
|
||||
class DeviceModel;
|
||||
class DeviceClass;
|
||||
class Region;
|
||||
|
||||
/**
|
||||
* @brief The base class for a LayoutToNetlist writer
|
||||
|
|
@ -64,6 +65,8 @@ public:
|
|||
|
||||
void read (db::LayoutToNetlist *l2n);
|
||||
|
||||
const db::Region *layer_by_name (const std::string &name);
|
||||
|
||||
private:
|
||||
friend class l2n_std_reader::Brace;
|
||||
typedef l2n_std_reader::Brace Brace;
|
||||
|
|
@ -82,6 +85,7 @@ private:
|
|||
std::string m_path;
|
||||
std::string m_line;
|
||||
tl::Extractor m_ex;
|
||||
std::auto_ptr<Layers> mp_layers;
|
||||
|
||||
void do_read (db::LayoutToNetlist *l2n);
|
||||
|
||||
|
|
@ -94,12 +98,12 @@ private:
|
|||
bool at_end ();
|
||||
void skip ();
|
||||
|
||||
void read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit, Layers &layers);
|
||||
void read_net (db::LayoutToNetlist *l2n, db::Circuit *circuit);
|
||||
void read_pin (db::LayoutToNetlist *l2n, db::Circuit *circuit);
|
||||
db::CellInstArray read_device (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list<Connections> &refs);
|
||||
db::CellInstArray read_subcircuit (db::LayoutToNetlist *l2n, db::Circuit *circuit, std::list<Connections> &refs);
|
||||
void read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceModel *dm, db::DeviceClass *dc, Layers &layers);
|
||||
std::pair<unsigned int, db::PolygonRef> read_geometry (db::LayoutToNetlist *l2n, Layers &layers);
|
||||
void read_abstract_terminal (db::LayoutToNetlist *l2n, db::DeviceModel *dm, db::DeviceClass *dc);
|
||||
std::pair<unsigned int, db::PolygonRef> read_geometry (db::LayoutToNetlist *l2n);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,23 +83,33 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
const db::Layout *ly = l2n->internal_layout ();
|
||||
const db::Netlist *nl = l2n->netlist ();
|
||||
|
||||
*mp_stream << "# General section" << endl;
|
||||
*mp_stream << "# Lists general definitions." << endl << endl;
|
||||
*mp_stream << "#%l2n-klayout" << endl;
|
||||
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# General section" << endl << endl;
|
||||
}
|
||||
|
||||
if (version > 0) {
|
||||
*mp_stream << Keys::version_key << "(" << version << ")" << endl;
|
||||
}
|
||||
*mp_stream << Keys::top_key << "(" << tl::to_word_or_quoted_string (ly->cell_name (l2n->internal_top_cell ()->cell_index ())) << ")" << endl;
|
||||
*mp_stream << Keys::unit_key << "(" << ly->dbu () << ")" << endl;
|
||||
|
||||
*mp_stream << endl << "# Layer section" << endl;
|
||||
*mp_stream << "# This section lists the mask layers (drawing or derived) and their connections." << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Layer section" << endl;
|
||||
*mp_stream << "# This section lists the mask layers (drawing or derived) and their connections." << endl;
|
||||
}
|
||||
|
||||
*mp_stream << endl << "# Mask layers" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Mask layers" << endl;
|
||||
}
|
||||
for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) {
|
||||
*mp_stream << Keys::layer_key << "(" << name_for_layer (ly, *l) << ")" << endl;
|
||||
}
|
||||
|
||||
*mp_stream << endl << "# Mask layer connectivity" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Mask layer connectivity" << endl;
|
||||
}
|
||||
for (db::Connectivity::layer_iterator l = l2n->connectivity ().begin_layers (); l != l2n->connectivity ().end_layers (); ++l) {
|
||||
|
||||
db::Connectivity::layer_iterator ce = l2n->connectivity ().end_connected (*l);
|
||||
|
|
@ -121,7 +131,9 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
db::Connectivity::global_nets_iterator gb = l2n->connectivity ().begin_global_connections (*l);
|
||||
if (gb != ge) {
|
||||
if (! any) {
|
||||
*mp_stream << endl << "# Global nets and connectivity" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Global nets and connectivity" << endl;
|
||||
}
|
||||
any = true;
|
||||
}
|
||||
*mp_stream << Keys::global_key << "(" << name_for_layer (ly, *l);
|
||||
|
|
@ -133,7 +145,7 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
|
||||
}
|
||||
|
||||
if (nl->begin_device_models () != nl->end_device_models ()) {
|
||||
if (nl->begin_device_models () != nl->end_device_models () && ! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Device abstracts section" << endl;
|
||||
*mp_stream << "# Device abstracts list the pin shapes of the devices." << endl;
|
||||
}
|
||||
|
|
@ -145,8 +157,10 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n)
|
|||
}
|
||||
}
|
||||
|
||||
*mp_stream << endl << "# Circuit section" << endl;
|
||||
*mp_stream << "# Circuits are the hierarchical building blocks of the netlist." << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << "# Circuit section" << endl;
|
||||
*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 << Keys::circuit_key << "(" << tl::to_word_or_quoted_string (x->name ()) << endl;
|
||||
|
|
@ -159,14 +173,18 @@ template <class Keys>
|
|||
void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n, const db::Circuit &circuit)
|
||||
{
|
||||
if (circuit.begin_nets () != circuit.end_nets ()) {
|
||||
*mp_stream << endl << indent1 << "# Nets with their geometries" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << indent1 << "# Nets with their geometries" << endl;
|
||||
}
|
||||
for (db::Circuit::const_net_iterator n = circuit.begin_nets (); n != circuit.end_nets (); ++n) {
|
||||
write (l2n, *n);
|
||||
}
|
||||
}
|
||||
|
||||
if (circuit.begin_pins () != circuit.end_pins ()) {
|
||||
*mp_stream << endl << indent1 << "# Outgoing pins and their connections to nets" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << indent1 << "# Outgoing pins and their connections to nets" << endl;
|
||||
}
|
||||
for (db::Circuit::const_pin_iterator p = circuit.begin_pins (); p != circuit.end_pins (); ++p) {
|
||||
const db::Net *net = circuit.net_for_pin (p->id ());
|
||||
if (net) {
|
||||
|
|
@ -176,20 +194,26 @@ void std_writer_impl<Keys>::write (const db::LayoutToNetlist *l2n, const db::Cir
|
|||
}
|
||||
|
||||
if (circuit.begin_devices () != circuit.end_devices ()) {
|
||||
*mp_stream << endl << indent1 << "# Devices and their connections" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << indent1 << "# Devices and their connections" << endl;
|
||||
}
|
||||
for (db::Circuit::const_device_iterator d = circuit.begin_devices (); d != circuit.end_devices (); ++d) {
|
||||
write (l2n, *d);
|
||||
}
|
||||
}
|
||||
|
||||
if (circuit.begin_subcircuits () != circuit.end_subcircuits ()) {
|
||||
*mp_stream << endl << indent1 << "# Subcircuits and their connections" << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl << indent1 << "# Subcircuits and their connections" << endl;
|
||||
}
|
||||
for (db::Circuit::const_subcircuit_iterator x = circuit.begin_subcircuits (); x != circuit.end_subcircuits (); ++x) {
|
||||
write (l2n, *x);
|
||||
}
|
||||
}
|
||||
|
||||
*mp_stream << endl;
|
||||
if (! Keys::is_short ()) {
|
||||
*mp_stream << endl;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Tr>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbStream.h"
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbNetlistDeviceExtractorClasses.h"
|
||||
#include "dbTestSupport.h"
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlStream.h"
|
||||
|
|
@ -64,17 +65,59 @@ TEST(1_ReaderBasic)
|
|||
tl::absolute_file_path (au_path)));
|
||||
}
|
||||
|
||||
// test build_all_nets from read l2n
|
||||
|
||||
#if 0
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (ly.dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
std::string path = tmp_file ("tmp_l2nwriter_1.txt");
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/);
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = reader.layer_by_name ("psd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = reader.layer_by_name ("nsd");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = reader.layer_by_name ("poly");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = reader.layer_by_name ("diff_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = reader.layer_by_name ("poly_cont");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = reader.layer_by_name ("metal1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = reader.layer_by_name ("via1");
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = reader.layer_by_name ("metal2");
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_writer_au.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(2_ReaderBasicShort)
|
||||
{
|
||||
db::Layout ly;
|
||||
|
||||
db::Cell &tc = ly.cell (ly.add_cell ("TOP"));
|
||||
db::LayoutToNetlist l2n (db::RecursiveShapeIterator (ly, tc, std::set<unsigned int> ()));
|
||||
|
||||
std::string in_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au_s.txt");
|
||||
tl::InputStream is_in (in_path);
|
||||
|
||||
db::LayoutToNetlistStandardReader reader (is_in);
|
||||
reader.read (&l2n);
|
||||
|
||||
// verify against the input
|
||||
|
||||
std::string path = tmp_file ("tmp_l2nreader_2.txt");
|
||||
{
|
||||
tl::OutputStream stream (path);
|
||||
db::LayoutToNetlistStandardWriter writer (stream, false);
|
||||
db::LayoutToNetlistStandardWriter writer (stream, true);
|
||||
writer.write (&l2n);
|
||||
}
|
||||
|
||||
std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au.txt");
|
||||
std::string au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au_s.txt");
|
||||
|
||||
tl::InputStream is (path);
|
||||
tl::InputStream is_au (au_path);
|
||||
|
|
@ -85,5 +128,4 @@ TEST(1_ReaderBasic)
|
|||
tl::absolute_file_path (au_path)));
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "dbStream.h"
|
||||
#include "dbCommonReader.h"
|
||||
#include "dbNetlistDeviceExtractorClasses.h"
|
||||
#include "dbTestSupport.h"
|
||||
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlStream.h"
|
||||
|
|
@ -163,6 +164,7 @@ TEST(1_WriterBasic)
|
|||
rpoly_lbl.reset (0);
|
||||
|
||||
l2n.extract_netlist ();
|
||||
l2n.netlist ()->make_top_level_pins ();
|
||||
l2n.netlist ()->purge ();
|
||||
|
||||
std::string path = tmp_file ("tmp_l2nwriter_1.txt");
|
||||
|
|
@ -174,12 +176,289 @@ TEST(1_WriterBasic)
|
|||
|
||||
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);
|
||||
{
|
||||
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)));
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
path = tmp_file ("tmp_l2nwriter_1s.txt");
|
||||
{
|
||||
tl::OutputStream stream (path);
|
||||
db::LayoutToNetlistStandardWriter writer (stream, true);
|
||||
writer.write (&l2n);
|
||||
}
|
||||
|
||||
au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au_s.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)));
|
||||
}
|
||||
}
|
||||
|
||||
// test build_all_nets (verify reference for reader)
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (ly.dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/);
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = &rpsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = &rnsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = rpoly.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = rdiff_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = rpoly_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = rmetal1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", 0, "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_writer_au.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(2_WriterWithGlobalNets)
|
||||
{
|
||||
db::Layout ly;
|
||||
db::LayerMap lmap;
|
||||
|
||||
unsigned int nwell = define_layer (ly, lmap, 1);
|
||||
unsigned int active = define_layer (ly, lmap, 2);
|
||||
unsigned int pplus = define_layer (ly, lmap, 10);
|
||||
unsigned int nplus = define_layer (ly, lmap, 11);
|
||||
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, "device_extract_l3.gds");
|
||||
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (ly, options);
|
||||
}
|
||||
|
||||
db::Cell &tc = ly.cell (*ly.begin_top_down ());
|
||||
db::LayoutToNetlist l2n (db::RecursiveShapeIterator (ly, tc, std::set<unsigned int> ()));
|
||||
|
||||
std::auto_ptr<db::Region> rbulk (l2n.make_layer (ly.insert_layer (), "rbulk"));
|
||||
std::auto_ptr<db::Region> rnwell (l2n.make_layer (nwell, "nwell"));
|
||||
std::auto_ptr<db::Region> ractive (l2n.make_layer (active, "active"));
|
||||
std::auto_ptr<db::Region> rpplus (l2n.make_layer (pplus, "pplus"));
|
||||
std::auto_ptr<db::Region> rnplus (l2n.make_layer (nplus, "nplus"));
|
||||
std::auto_ptr<db::Region> rpoly (l2n.make_polygon_layer (poly, "poly"));
|
||||
std::auto_ptr<db::Region> rpoly_lbl (l2n.make_text_layer (poly_lbl, "poly_lbl"));
|
||||
std::auto_ptr<db::Region> rdiff_cont (l2n.make_polygon_layer (diff_cont, "diff_cont"));
|
||||
std::auto_ptr<db::Region> rpoly_cont (l2n.make_polygon_layer (poly_cont, "poly_cont"));
|
||||
std::auto_ptr<db::Region> rmetal1 (l2n.make_polygon_layer (metal1, "metal1"));
|
||||
std::auto_ptr<db::Region> rmetal1_lbl (l2n.make_text_layer (metal1_lbl, "metal1_lbl"));
|
||||
std::auto_ptr<db::Region> rvia1 (l2n.make_polygon_layer (via1, "via1"));
|
||||
std::auto_ptr<db::Region> rmetal2 (l2n.make_polygon_layer (metal2, "metal2"));
|
||||
std::auto_ptr<db::Region> rmetal2_lbl (l2n.make_text_layer (metal2_lbl, "metal2_lbl"));
|
||||
|
||||
// derived regions
|
||||
|
||||
db::Region ractive_in_nwell = *ractive & *rnwell;
|
||||
db::Region rpactive = ractive_in_nwell & *rpplus;
|
||||
db::Region rntie = ractive_in_nwell & *rnplus;
|
||||
db::Region rpgate = rpactive & *rpoly;
|
||||
db::Region rpsd = rpactive - rpgate;
|
||||
l2n.name (rpactive, "pactive");
|
||||
l2n.name (rntie, "ntie");
|
||||
l2n.name (rpgate, "pgate");
|
||||
l2n.name (rpsd, "psd");
|
||||
|
||||
db::Region ractive_outside_nwell = *ractive - *rnwell;
|
||||
db::Region rnactive = ractive_outside_nwell & *rnplus;
|
||||
db::Region rptie = ractive_outside_nwell & *rpplus;
|
||||
db::Region rngate = rnactive & *rpoly;
|
||||
db::Region rnsd = rnactive - rngate;
|
||||
l2n.name (rnactive, "nactive");
|
||||
l2n.name (rptie, "ptie");
|
||||
l2n.name (rngate, "ngate");
|
||||
l2n.name (rnsd, "nsd");
|
||||
|
||||
// return the computed layers into the original layout and write it for debugging purposes
|
||||
|
||||
unsigned int lgate = ly.insert_layer (db::LayerProperties (20, 0)); // 20/0 -> Gate
|
||||
unsigned int lsd = ly.insert_layer (db::LayerProperties (21, 0)); // 21/0 -> Source/Drain
|
||||
unsigned int lpdiff = ly.insert_layer (db::LayerProperties (22, 0)); // 22/0 -> P Diffusion
|
||||
unsigned int lndiff = ly.insert_layer (db::LayerProperties (23, 0)); // 23/0 -> N Diffusion
|
||||
unsigned int lptie = ly.insert_layer (db::LayerProperties (24, 0)); // 24/0 -> P Tie
|
||||
unsigned int lntie = ly.insert_layer (db::LayerProperties (25, 0)); // 25/0 -> N Tie
|
||||
|
||||
rpgate.insert_into (&ly, tc.cell_index (), lgate);
|
||||
rngate.insert_into (&ly, tc.cell_index (), lgate);
|
||||
rpsd.insert_into (&ly, tc.cell_index (), lsd);
|
||||
rnsd.insert_into (&ly, tc.cell_index (), lsd);
|
||||
rpsd.insert_into (&ly, tc.cell_index (), lpdiff);
|
||||
rnsd.insert_into (&ly, tc.cell_index (), lndiff);
|
||||
rpsd.insert_into (&ly, tc.cell_index (), lptie);
|
||||
rnsd.insert_into (&ly, tc.cell_index (), lntie);
|
||||
|
||||
db::NetlistDeviceExtractorMOS4Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS4Transistor nmos_ex ("NMOS");
|
||||
|
||||
// device extraction
|
||||
|
||||
db::NetlistDeviceExtractor::input_layers dl;
|
||||
|
||||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = rpoly.get (); // not needed for extraction but to return terminal shapes
|
||||
dl["W"] = rnwell.get ();
|
||||
l2n.extract_devices (pmos_ex, dl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = rpoly.get (); // not needed for extraction but to return terminal shapes
|
||||
dl["W"] = rbulk.get ();
|
||||
l2n.extract_devices (nmos_ex, dl);
|
||||
|
||||
// net extraction
|
||||
|
||||
// Intra-layer
|
||||
l2n.connect (rpsd);
|
||||
l2n.connect (rnsd);
|
||||
l2n.connect (*rnwell);
|
||||
l2n.connect (*rpoly);
|
||||
l2n.connect (*rdiff_cont);
|
||||
l2n.connect (*rpoly_cont);
|
||||
l2n.connect (*rmetal1);
|
||||
l2n.connect (*rvia1);
|
||||
l2n.connect (*rmetal2);
|
||||
l2n.connect (rptie);
|
||||
l2n.connect (rntie);
|
||||
// Inter-layer
|
||||
l2n.connect (rpsd, *rdiff_cont);
|
||||
l2n.connect (rnsd, *rdiff_cont);
|
||||
l2n.connect (*rpoly, *rpoly_cont);
|
||||
l2n.connect (*rpoly_cont, *rmetal1);
|
||||
l2n.connect (*rdiff_cont, *rmetal1);
|
||||
l2n.connect (*rdiff_cont, rptie);
|
||||
l2n.connect (*rdiff_cont, rntie);
|
||||
l2n.connect (*rnwell, rntie);
|
||||
l2n.connect (*rmetal1, *rvia1);
|
||||
l2n.connect (*rvia1, *rmetal2);
|
||||
l2n.connect (*rpoly, *rpoly_lbl); // attaches labels
|
||||
l2n.connect (*rmetal1, *rmetal1_lbl); // attaches labels
|
||||
l2n.connect (*rmetal2, *rmetal2_lbl); // attaches labels
|
||||
// Global
|
||||
l2n.connect_global (rptie, "BULK");
|
||||
l2n.connect_global (*rbulk, "BULK");
|
||||
|
||||
// create some mess - we have to keep references to the layers to make them not disappear
|
||||
rmetal1_lbl.reset (0);
|
||||
rmetal2_lbl.reset (0);
|
||||
rpoly_lbl.reset (0);
|
||||
|
||||
l2n.extract_netlist ();
|
||||
l2n.netlist ()->make_top_level_pins ();
|
||||
l2n.netlist ()->purge ();
|
||||
|
||||
std::string path = tmp_file ("tmp_l2nwriter_2.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_2.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)));
|
||||
}
|
||||
}
|
||||
|
||||
path = tmp_file ("tmp_l2nwriter_2s.txt");
|
||||
{
|
||||
tl::OutputStream stream (path);
|
||||
db::LayoutToNetlistStandardWriter writer (stream, true);
|
||||
writer.write (&l2n);
|
||||
}
|
||||
|
||||
au_path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "l2n_writer_au_2s.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)));
|
||||
}
|
||||
}
|
||||
|
||||
// test build_all_nets
|
||||
|
||||
{
|
||||
db::Layout ly2;
|
||||
ly2.dbu (ly.dbu ());
|
||||
db::Cell &top2 = ly2.cell (ly2.add_cell ("TOP"));
|
||||
|
||||
db::CellMapping cm = l2n.cell_mapping_into (ly2, top2, true /*with device cells*/);
|
||||
|
||||
std::map<unsigned int, const db::Region *> lmap;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (10, 0))] = &rpsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (11, 0))] = &rnsd;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (12, 0))] = rbulk.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (13, 0))] = &rptie;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (14, 0))] = &rntie;
|
||||
lmap [ly2.insert_layer (db::LayerProperties (1, 0)) ] = rnwell.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (3, 0)) ] = rpoly.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (4, 0)) ] = rdiff_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (5, 0)) ] = rpoly_cont.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (6, 0)) ] = rmetal1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (7, 0)) ] = rvia1.get ();
|
||||
lmap [ly2.insert_layer (db::LayerProperties (8, 0)) ] = rmetal2.get ();
|
||||
|
||||
l2n.build_all_nets (cm, ly2, lmap, "NET_", "CIRCUIT_", "DEVICE_");
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "l2n_writer_au_2.gds");
|
||||
|
||||
db::compare_layouts (_this, ly2, au);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,5 +1,6 @@
|
|||
#%l2n-klayout
|
||||
|
||||
# General section
|
||||
# Lists general definitions.
|
||||
|
||||
top(RINGO)
|
||||
unit(0.001)
|
||||
|
|
@ -211,6 +212,15 @@ circuit(RINGO
|
|||
rect(metal2 -1720 1600 23160 2000)
|
||||
rect(metal2_lbl -1 1799 1 1801)
|
||||
)
|
||||
net(OSC
|
||||
rect(diff_cont 24450 2890 24670 3110)
|
||||
rect(diff_cont 24450 2490 24670 2710)
|
||||
rect(diff_cont 24450 90 24670 310)
|
||||
rect(diff_cont 24450 -310 24670 -90)
|
||||
rect(via1 24435 1675 24685 1925)
|
||||
rect(metal2 24360 1600 24760 2000)
|
||||
rect(metal2_lbl 24559 1799 24561 1801)
|
||||
)
|
||||
net(VSS
|
||||
rect(diff_cont 2530 -310 2750 -90)
|
||||
rect(diff_cont 2530 90 2750 310)
|
||||
|
|
@ -392,10 +402,17 @@ circuit(RINGO
|
|||
rect(diff_cont 3330 -310 3550 -90)
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(FB FB)
|
||||
pin(OSC OSC)
|
||||
pin(VSS VSS)
|
||||
pin(VDD VDD)
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit($1 INV2 location(23760 0)
|
||||
pin(IN $I8)
|
||||
pin($1 FB)
|
||||
pin(OUT OSC)
|
||||
pin($3 VSS)
|
||||
pin($4 VDD)
|
||||
)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,566 @@
|
|||
#%l2n-klayout
|
||||
|
||||
# General section
|
||||
|
||||
top(RINGO)
|
||||
unit(0.001)
|
||||
|
||||
# Layer section
|
||||
# This section lists the mask layers (drawing or derived) and their connections.
|
||||
|
||||
# Mask layers
|
||||
layer(rbulk)
|
||||
layer(nwell)
|
||||
layer(poly)
|
||||
layer(poly_lbl)
|
||||
layer(diff_cont)
|
||||
layer(poly_cont)
|
||||
layer(metal1)
|
||||
layer(metal1_lbl)
|
||||
layer(via1)
|
||||
layer(metal2)
|
||||
layer(metal2_lbl)
|
||||
layer(ntie)
|
||||
layer(psd)
|
||||
layer(ptie)
|
||||
layer(nsd)
|
||||
|
||||
# Mask layer connectivity
|
||||
connect(nwell nwell ntie)
|
||||
connect(poly poly poly_lbl poly_cont)
|
||||
connect(poly_lbl poly)
|
||||
connect(diff_cont diff_cont metal1 ntie psd ptie nsd)
|
||||
connect(poly_cont poly poly_cont metal1)
|
||||
connect(metal1 diff_cont poly_cont metal1 metal1_lbl via1)
|
||||
connect(metal1_lbl metal1)
|
||||
connect(via1 metal1 via1 metal2)
|
||||
connect(metal2 via1 metal2 metal2_lbl)
|
||||
connect(metal2_lbl metal2)
|
||||
connect(ntie nwell diff_cont ntie)
|
||||
connect(psd diff_cont psd)
|
||||
connect(ptie diff_cont ptie)
|
||||
connect(nsd diff_cont nsd)
|
||||
|
||||
# Global nets and connectivity
|
||||
global(rbulk BULK)
|
||||
global(ptie BULK)
|
||||
|
||||
# Device abstracts section
|
||||
# Device abstracts list the pin shapes of the devices.
|
||||
device(D$PMOS PMOS
|
||||
terminal(S
|
||||
rect(psd -650 -475 -125 475)
|
||||
)
|
||||
terminal(G
|
||||
rect(poly -125 -475 125 475)
|
||||
)
|
||||
terminal(D
|
||||
rect(psd 125 -475 675 475)
|
||||
)
|
||||
terminal(B
|
||||
rect(nwell -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
device(D$PMOS$1 PMOS
|
||||
terminal(S
|
||||
rect(psd -675 -475 -125 475)
|
||||
)
|
||||
terminal(G
|
||||
rect(poly -125 -475 125 475)
|
||||
)
|
||||
terminal(D
|
||||
rect(psd 125 -475 650 475)
|
||||
)
|
||||
terminal(B
|
||||
rect(nwell -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
device(D$NMOS NMOS
|
||||
terminal(S
|
||||
rect(nsd -650 -475 -125 475)
|
||||
)
|
||||
terminal(G
|
||||
rect(poly -125 -475 125 475)
|
||||
)
|
||||
terminal(D
|
||||
rect(nsd 125 -475 675 475)
|
||||
)
|
||||
terminal(B
|
||||
rect(rbulk -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
device(D$NMOS$1 NMOS
|
||||
terminal(S
|
||||
rect(nsd -675 -475 -125 475)
|
||||
)
|
||||
terminal(G
|
||||
rect(poly -125 -475 125 475)
|
||||
)
|
||||
terminal(D
|
||||
rect(nsd 125 -475 650 475)
|
||||
)
|
||||
terminal(B
|
||||
rect(rbulk -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
|
||||
# Circuit section
|
||||
# Circuits are the hierarchical building blocks of the netlist.
|
||||
circuit(INV2
|
||||
|
||||
# Nets with their geometries
|
||||
net($1
|
||||
rect(nwell -1400 1800 1400 4580)
|
||||
rect(diff_cont -110 3930 110 4150)
|
||||
rect(ntie -400 3700 400 4380)
|
||||
)
|
||||
net(IN
|
||||
rect(poly -525 -250 -275 2250)
|
||||
rect(poly -1700 1620 -400 1980)
|
||||
rect(poly -525 -800 -275 800)
|
||||
rect(poly -525 2000 -275 3600)
|
||||
rect(poly_lbl -801 1799 -799 1801)
|
||||
rect(poly_cont -1630 1690 -1410 1910)
|
||||
)
|
||||
net($3
|
||||
rect(poly 275 -250 525 2250)
|
||||
rect(poly 220 820 580 1180)
|
||||
rect(poly 275 2000 525 3600)
|
||||
rect(poly 275 -800 525 800)
|
||||
rect(diff_cont -910 2490 -690 2710)
|
||||
rect(diff_cont -910 2890 -690 3110)
|
||||
rect(diff_cont -910 -310 -690 -90)
|
||||
rect(diff_cont -910 90 -690 310)
|
||||
rect(poly_cont 290 890 510 1110)
|
||||
rect(metal1 -800 820 580 1180)
|
||||
rect(metal1 -980 -420 -620 2420)
|
||||
rect(metal1 -980 2420 -620 3180)
|
||||
rect(metal1 -980 -380 -620 380)
|
||||
rect(psd -1050 2325 -525 3275)
|
||||
rect(nsd -1050 -475 -525 475)
|
||||
)
|
||||
net(OUT
|
||||
rect(diff_cont 690 2890 910 3110)
|
||||
rect(diff_cont 690 2490 910 2710)
|
||||
rect(diff_cont 690 90 910 310)
|
||||
rect(diff_cont 690 -310 910 -90)
|
||||
polygon(metal1 800 20 800 380 940 380 940 1620 620 1620 620 2420 980 2420 980 1980 1300 1980 1300 20)
|
||||
rect(metal1 620 2420 980 3180)
|
||||
rect(metal1 620 -380 980 380)
|
||||
rect(metal1_lbl 799 1799 801 1801)
|
||||
rect(psd 525 2325 1050 3275)
|
||||
rect(nsd 525 -475 1050 475)
|
||||
)
|
||||
net(VSS
|
||||
rect(diff_cont -110 -310 110 -90)
|
||||
rect(diff_cont -110 90 110 310)
|
||||
rect(diff_cont -110 90 110 310)
|
||||
rect(diff_cont -110 -310 110 -90)
|
||||
rect(metal1 -180 -380 180 380)
|
||||
rect(metal1 -180 -380 180 380)
|
||||
rect(via1 -125 -325 125 -75)
|
||||
rect(via1 -125 75 125 325)
|
||||
rect(metal2 -1400 -450 1400 450)
|
||||
rect(metal2_lbl 1239 -91 1241 -89)
|
||||
rect(nsd -275 -475 275 475)
|
||||
)
|
||||
net(VDD
|
||||
rect(diff_cont -110 2490 110 2710)
|
||||
rect(diff_cont -110 2890 110 3110)
|
||||
rect(diff_cont -110 2890 110 3110)
|
||||
rect(diff_cont -110 2490 110 2710)
|
||||
rect(metal1 -180 2420 180 3180)
|
||||
rect(metal1 -180 2420 180 3180)
|
||||
rect(via1 -125 2475 125 2725)
|
||||
rect(via1 -125 2875 125 3125)
|
||||
rect(metal2 -1400 2350 1400 3250)
|
||||
rect(metal2_lbl 1249 2799 1251 2801)
|
||||
rect(psd -275 2325 275 3275)
|
||||
)
|
||||
net(BULK
|
||||
rect(diff_cont -110 -1360 110 -1140)
|
||||
rect(ptie -400 -1590 400 -910)
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin($0 $1)
|
||||
pin(IN IN)
|
||||
pin($2 $3)
|
||||
pin(OUT OUT)
|
||||
pin(VSS VSS)
|
||||
pin(VDD VDD)
|
||||
pin(BULK BULK)
|
||||
|
||||
# Devices and their connections
|
||||
device($1 D$PMOS
|
||||
location(-400 2800)
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0.49875)
|
||||
param(AD 0.26125)
|
||||
terminal(S $3)
|
||||
terminal(G IN)
|
||||
terminal(D VDD)
|
||||
terminal(B $1)
|
||||
)
|
||||
device($2 D$PMOS$1
|
||||
location(400 2800)
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0.26125)
|
||||
param(AD 0.49875)
|
||||
terminal(S VDD)
|
||||
terminal(G $3)
|
||||
terminal(D OUT)
|
||||
terminal(B $1)
|
||||
)
|
||||
device($3 D$NMOS
|
||||
location(-400 0)
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0.49875)
|
||||
param(AD 0.26125)
|
||||
terminal(S $3)
|
||||
terminal(G IN)
|
||||
terminal(D VSS)
|
||||
terminal(B BULK)
|
||||
)
|
||||
device($4 D$NMOS$1
|
||||
location(400 0)
|
||||
param(L 0.25)
|
||||
param(W 0.95)
|
||||
param(AS 0.26125)
|
||||
param(AD 0.49875)
|
||||
terminal(S VSS)
|
||||
terminal(G $3)
|
||||
terminal(D OUT)
|
||||
terminal(B BULK)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(INV2PAIR
|
||||
|
||||
# Nets with their geometries
|
||||
net(BULK)
|
||||
net($I8
|
||||
rect(diff_cont 3430 3290 3650 3510)
|
||||
rect(diff_cont 3430 3690 3650 3910)
|
||||
rect(diff_cont 3430 490 3650 710)
|
||||
rect(diff_cont 3430 890 3650 1110)
|
||||
)
|
||||
net($I6
|
||||
rect(diff_cont 4230 3290 4450 3510)
|
||||
rect(diff_cont 4230 3690 4450 3910)
|
||||
rect(diff_cont 4230 3690 4450 3910)
|
||||
rect(diff_cont 4230 3290 4450 3510)
|
||||
rect(diff_cont 1590 3290 1810 3510)
|
||||
rect(diff_cont 1590 3690 1810 3910)
|
||||
rect(diff_cont 1590 3690 1810 3910)
|
||||
rect(diff_cont 1590 3290 1810 3510)
|
||||
rect(metal1 4160 3220 4520 3980)
|
||||
rect(metal1 4160 3220 4520 3980)
|
||||
rect(metal1 1520 3220 1880 3980)
|
||||
rect(metal1 1520 3220 1880 3980)
|
||||
)
|
||||
net($I5
|
||||
rect(diff_cont 4230 490 4450 710)
|
||||
rect(diff_cont 4230 890 4450 1110)
|
||||
rect(diff_cont 4230 890 4450 1110)
|
||||
rect(diff_cont 4230 490 4450 710)
|
||||
rect(diff_cont 1590 490 1810 710)
|
||||
rect(diff_cont 1590 890 1810 1110)
|
||||
rect(diff_cont 1590 890 1810 1110)
|
||||
rect(diff_cont 1590 490 1810 710)
|
||||
rect(metal1 4160 420 4520 1180)
|
||||
rect(metal1 4160 420 4520 1180)
|
||||
rect(metal1 1520 420 1880 1180)
|
||||
rect(metal1 1520 420 1880 1180)
|
||||
)
|
||||
net($I4
|
||||
rect(diff_cont 2390 3690 2610 3910)
|
||||
rect(diff_cont 2390 3290 2610 3510)
|
||||
rect(diff_cont 2390 890 2610 1110)
|
||||
rect(diff_cont 2390 490 2610 710)
|
||||
)
|
||||
net($I3)
|
||||
net($I2
|
||||
rect(diff_cont 5030 3690 5250 3910)
|
||||
rect(diff_cont 5030 3290 5250 3510)
|
||||
rect(diff_cont 5030 890 5250 1110)
|
||||
rect(diff_cont 5030 490 5250 710)
|
||||
)
|
||||
net($I1)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(BULK BULK)
|
||||
pin($1 $I8)
|
||||
pin($2 $I6)
|
||||
pin($3 $I5)
|
||||
pin($4 $I3)
|
||||
pin($5 $I2)
|
||||
pin($6 $I1)
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit($1 INV2 location(1700 800)
|
||||
pin($0 $I1)
|
||||
pin(IN $I3)
|
||||
pin(OUT $I4)
|
||||
pin(VSS $I5)
|
||||
pin(VDD $I6)
|
||||
pin(BULK BULK)
|
||||
)
|
||||
circuit($2 INV2 location(4340 800)
|
||||
pin($0 $I1)
|
||||
pin(IN $I4)
|
||||
pin($2 $I8)
|
||||
pin(OUT $I2)
|
||||
pin(VSS $I5)
|
||||
pin(VDD $I6)
|
||||
pin(BULK BULK)
|
||||
)
|
||||
|
||||
)
|
||||
circuit(RINGO
|
||||
|
||||
# Nets with their geometries
|
||||
net(FB
|
||||
rect(diff_cont 22850 2490 23070 2710)
|
||||
rect(diff_cont 22850 2890 23070 3110)
|
||||
rect(diff_cont 22850 -310 23070 -90)
|
||||
rect(diff_cont 22850 90 23070 310)
|
||||
rect(metal1 -1700 1620 -1340 1980)
|
||||
rect(via1 -1645 1675 -1395 1925)
|
||||
rect(via1 22835 1675 23085 1925)
|
||||
rect(metal2 -1720 1600 23160 2000)
|
||||
rect(metal2_lbl -1 1799 1 1801)
|
||||
)
|
||||
net(OSC
|
||||
rect(diff_cont 24450 2890 24670 3110)
|
||||
rect(diff_cont 24450 2490 24670 2710)
|
||||
rect(diff_cont 24450 90 24670 310)
|
||||
rect(diff_cont 24450 -310 24670 -90)
|
||||
rect(via1 24435 1675 24685 1925)
|
||||
rect(metal2 24360 1600 24760 2000)
|
||||
rect(metal2_lbl 24559 1799 24561 1801)
|
||||
)
|
||||
net(VDD
|
||||
rect(diff_cont 7810 2490 8030 2710)
|
||||
rect(diff_cont 7810 2890 8030 3110)
|
||||
rect(diff_cont 7810 2890 8030 3110)
|
||||
rect(diff_cont 7810 2490 8030 2710)
|
||||
rect(diff_cont 5170 2490 5390 2710)
|
||||
rect(diff_cont 5170 2890 5390 3110)
|
||||
rect(diff_cont 5170 2890 5390 3110)
|
||||
rect(diff_cont 5170 2490 5390 2710)
|
||||
rect(diff_cont 2530 2490 2750 2710)
|
||||
rect(diff_cont 2530 2890 2750 3110)
|
||||
rect(diff_cont 2530 2890 2750 3110)
|
||||
rect(diff_cont 2530 2490 2750 2710)
|
||||
rect(diff_cont -110 2490 110 2710)
|
||||
rect(diff_cont -110 2890 110 3110)
|
||||
rect(diff_cont -110 2890 110 3110)
|
||||
rect(diff_cont -110 2490 110 2710)
|
||||
rect(diff_cont 13090 2490 13310 2710)
|
||||
rect(diff_cont 13090 2890 13310 3110)
|
||||
rect(diff_cont 13090 2890 13310 3110)
|
||||
rect(diff_cont 13090 2490 13310 2710)
|
||||
rect(diff_cont 10450 2490 10670 2710)
|
||||
rect(diff_cont 10450 2890 10670 3110)
|
||||
rect(diff_cont 10450 2890 10670 3110)
|
||||
rect(diff_cont 10450 2490 10670 2710)
|
||||
rect(diff_cont 18370 2490 18590 2710)
|
||||
rect(diff_cont 18370 2890 18590 3110)
|
||||
rect(diff_cont 18370 2890 18590 3110)
|
||||
rect(diff_cont 18370 2490 18590 2710)
|
||||
rect(diff_cont 15730 2490 15950 2710)
|
||||
rect(diff_cont 15730 2890 15950 3110)
|
||||
rect(diff_cont 15730 2890 15950 3110)
|
||||
rect(diff_cont 15730 2490 15950 2710)
|
||||
rect(diff_cont 23650 2490 23870 2710)
|
||||
rect(diff_cont 23650 2890 23870 3110)
|
||||
rect(diff_cont 23650 2890 23870 3110)
|
||||
rect(diff_cont 23650 2490 23870 2710)
|
||||
rect(diff_cont 21010 2490 21230 2710)
|
||||
rect(diff_cont 21010 2890 21230 3110)
|
||||
rect(diff_cont 21010 2890 21230 3110)
|
||||
rect(diff_cont 21010 2490 21230 2710)
|
||||
rect(metal1 -180 3100 180 4220)
|
||||
rect(metal1 2460 3100 2820 4220)
|
||||
rect(metal1 5100 3100 5460 4220)
|
||||
rect(metal1 7740 3100 8100 4220)
|
||||
rect(metal1 10380 3100 10740 4220)
|
||||
rect(metal1 13020 3100 13380 4220)
|
||||
rect(metal1 15660 3100 16020 4220)
|
||||
rect(metal1 18300 3100 18660 4220)
|
||||
rect(metal1 20940 3100 21300 4220)
|
||||
rect(metal1 23580 3100 23940 4220)
|
||||
rect(metal1 7740 2420 8100 3180)
|
||||
rect(metal1 7740 2420 8100 3180)
|
||||
rect(metal1 5100 2420 5460 3180)
|
||||
rect(metal1 5100 2420 5460 3180)
|
||||
rect(metal1 2460 2420 2820 3180)
|
||||
rect(metal1 2460 2420 2820 3180)
|
||||
rect(metal1 -180 2420 180 3180)
|
||||
rect(metal1 -180 2420 180 3180)
|
||||
rect(metal1 13020 2420 13380 3180)
|
||||
rect(metal1 13020 2420 13380 3180)
|
||||
rect(metal1 10380 2420 10740 3180)
|
||||
rect(metal1 10380 2420 10740 3180)
|
||||
rect(metal1 18300 2420 18660 3180)
|
||||
rect(metal1 18300 2420 18660 3180)
|
||||
rect(metal1 15660 2420 16020 3180)
|
||||
rect(metal1 15660 2420 16020 3180)
|
||||
rect(metal1 23580 2420 23940 3180)
|
||||
rect(metal1 23580 2420 23940 3180)
|
||||
rect(metal1 20940 2420 21300 3180)
|
||||
rect(metal1 20940 2420 21300 3180)
|
||||
rect(metal2_lbl -1 2799 1 2801)
|
||||
)
|
||||
net('BULK,VSS'
|
||||
rect(diff_cont 7810 -310 8030 -90)
|
||||
rect(diff_cont 7810 90 8030 310)
|
||||
rect(diff_cont 7810 90 8030 310)
|
||||
rect(diff_cont 7810 -310 8030 -90)
|
||||
rect(diff_cont 5170 -310 5390 -90)
|
||||
rect(diff_cont 5170 90 5390 310)
|
||||
rect(diff_cont 5170 90 5390 310)
|
||||
rect(diff_cont 5170 -310 5390 -90)
|
||||
rect(diff_cont 2530 -310 2750 -90)
|
||||
rect(diff_cont 2530 90 2750 310)
|
||||
rect(diff_cont 2530 90 2750 310)
|
||||
rect(diff_cont 2530 -310 2750 -90)
|
||||
rect(diff_cont -110 -310 110 -90)
|
||||
rect(diff_cont -110 90 110 310)
|
||||
rect(diff_cont -110 90 110 310)
|
||||
rect(diff_cont -110 -310 110 -90)
|
||||
rect(diff_cont 13090 -310 13310 -90)
|
||||
rect(diff_cont 13090 90 13310 310)
|
||||
rect(diff_cont 13090 90 13310 310)
|
||||
rect(diff_cont 13090 -310 13310 -90)
|
||||
rect(diff_cont 10450 -310 10670 -90)
|
||||
rect(diff_cont 10450 90 10670 310)
|
||||
rect(diff_cont 10450 90 10670 310)
|
||||
rect(diff_cont 10450 -310 10670 -90)
|
||||
rect(diff_cont 18370 -310 18590 -90)
|
||||
rect(diff_cont 18370 90 18590 310)
|
||||
rect(diff_cont 18370 90 18590 310)
|
||||
rect(diff_cont 18370 -310 18590 -90)
|
||||
rect(diff_cont 15730 -310 15950 -90)
|
||||
rect(diff_cont 15730 90 15950 310)
|
||||
rect(diff_cont 15730 90 15950 310)
|
||||
rect(diff_cont 15730 -310 15950 -90)
|
||||
rect(diff_cont 23650 -310 23870 -90)
|
||||
rect(diff_cont 23650 90 23870 310)
|
||||
rect(diff_cont 23650 90 23870 310)
|
||||
rect(diff_cont 23650 -310 23870 -90)
|
||||
rect(diff_cont 21010 -310 21230 -90)
|
||||
rect(diff_cont 21010 90 21230 310)
|
||||
rect(diff_cont 21010 90 21230 310)
|
||||
rect(diff_cont 21010 -310 21230 -90)
|
||||
rect(metal1 -180 -1420 180 -300)
|
||||
rect(metal1 2460 -1420 2820 -300)
|
||||
rect(metal1 5100 -1420 5460 -300)
|
||||
rect(metal1 7740 -1420 8100 -300)
|
||||
rect(metal1 10380 -1420 10740 -300)
|
||||
rect(metal1 13020 -1420 13380 -300)
|
||||
rect(metal1 15660 -1420 16020 -300)
|
||||
rect(metal1 18300 -1420 18660 -300)
|
||||
rect(metal1 20940 -1420 21300 -300)
|
||||
rect(metal1 23580 -1420 23940 -300)
|
||||
rect(metal1 7740 -380 8100 380)
|
||||
rect(metal1 7740 -380 8100 380)
|
||||
rect(metal1 5100 -380 5460 380)
|
||||
rect(metal1 5100 -380 5460 380)
|
||||
rect(metal1 2460 -380 2820 380)
|
||||
rect(metal1 2460 -380 2820 380)
|
||||
rect(metal1 -180 -380 180 380)
|
||||
rect(metal1 -180 -380 180 380)
|
||||
rect(metal1 13020 -380 13380 380)
|
||||
rect(metal1 13020 -380 13380 380)
|
||||
rect(metal1 10380 -380 10740 380)
|
||||
rect(metal1 10380 -380 10740 380)
|
||||
rect(metal1 18300 -380 18660 380)
|
||||
rect(metal1 18300 -380 18660 380)
|
||||
rect(metal1 15660 -380 16020 380)
|
||||
rect(metal1 15660 -380 16020 380)
|
||||
rect(metal1 23580 -380 23940 380)
|
||||
rect(metal1 23580 -380 23940 380)
|
||||
rect(metal1 20940 -380 21300 380)
|
||||
rect(metal1 20940 -380 21300 380)
|
||||
rect(metal2_lbl -1 -1 1 1)
|
||||
)
|
||||
net($I13
|
||||
rect(diff_cont 3330 2890 3550 3110)
|
||||
rect(diff_cont 3330 2490 3550 2710)
|
||||
rect(diff_cont 3330 90 3550 310)
|
||||
rect(diff_cont 3330 -310 3550 -90)
|
||||
)
|
||||
net($I7
|
||||
rect(diff_cont 19170 2890 19390 3110)
|
||||
rect(diff_cont 19170 2490 19390 2710)
|
||||
rect(diff_cont 19170 90 19390 310)
|
||||
rect(diff_cont 19170 -310 19390 -90)
|
||||
)
|
||||
net($I6
|
||||
rect(diff_cont 13890 2890 14110 3110)
|
||||
rect(diff_cont 13890 2490 14110 2710)
|
||||
rect(diff_cont 13890 90 14110 310)
|
||||
rect(diff_cont 13890 -310 14110 -90)
|
||||
)
|
||||
net($I5
|
||||
rect(diff_cont 8610 2890 8830 3110)
|
||||
rect(diff_cont 8610 2490 8830 2710)
|
||||
rect(diff_cont 8610 90 8830 310)
|
||||
rect(diff_cont 8610 -310 8830 -90)
|
||||
)
|
||||
|
||||
# Outgoing pins and their connections to nets
|
||||
pin(FB FB)
|
||||
pin(OSC OSC)
|
||||
pin(VDD VDD)
|
||||
pin('BULK,VSS' 'BULK,VSS')
|
||||
|
||||
# Subcircuits and their connections
|
||||
circuit($1 INV2PAIR location(19420 -800)
|
||||
pin(BULK 'BULK,VSS')
|
||||
pin($1 FB)
|
||||
pin($2 VDD)
|
||||
pin($3 'BULK,VSS')
|
||||
pin($4 $I7)
|
||||
pin($5 OSC)
|
||||
pin($6 VDD)
|
||||
)
|
||||
circuit($2 INV2PAIR location(-1700 -800)
|
||||
pin(BULK 'BULK,VSS')
|
||||
pin($2 VDD)
|
||||
pin($3 'BULK,VSS')
|
||||
pin($4 FB)
|
||||
pin($5 $I13)
|
||||
pin($6 VDD)
|
||||
)
|
||||
circuit($3 INV2PAIR location(3580 -800)
|
||||
pin(BULK 'BULK,VSS')
|
||||
pin($2 VDD)
|
||||
pin($3 'BULK,VSS')
|
||||
pin($4 $I13)
|
||||
pin($5 $I5)
|
||||
pin($6 VDD)
|
||||
)
|
||||
circuit($4 INV2PAIR location(8860 -800)
|
||||
pin(BULK 'BULK,VSS')
|
||||
pin($2 VDD)
|
||||
pin($3 'BULK,VSS')
|
||||
pin($4 $I5)
|
||||
pin($5 $I6)
|
||||
pin($6 VDD)
|
||||
)
|
||||
circuit($5 INV2PAIR location(14140 -800)
|
||||
pin(BULK 'BULK,VSS')
|
||||
pin($2 VDD)
|
||||
pin($3 'BULK,VSS')
|
||||
pin($4 $I6)
|
||||
pin($5 $I7)
|
||||
pin($6 VDD)
|
||||
)
|
||||
|
||||
)
|
||||
|
|
@ -0,0 +1,527 @@
|
|||
#%l2n-klayout
|
||||
W(RINGO)
|
||||
U(0.001)
|
||||
L(rbulk)
|
||||
L(nwell)
|
||||
L(poly)
|
||||
L(poly_lbl)
|
||||
L(diff_cont)
|
||||
L(poly_cont)
|
||||
L(metal1)
|
||||
L(metal1_lbl)
|
||||
L(via1)
|
||||
L(metal2)
|
||||
L(metal2_lbl)
|
||||
L(ntie)
|
||||
L(psd)
|
||||
L(ptie)
|
||||
L(nsd)
|
||||
C(nwell nwell ntie)
|
||||
C(poly poly poly_lbl poly_cont)
|
||||
C(poly_lbl poly)
|
||||
C(diff_cont diff_cont metal1 ntie psd ptie nsd)
|
||||
C(poly_cont poly poly_cont metal1)
|
||||
C(metal1 diff_cont poly_cont metal1 metal1_lbl via1)
|
||||
C(metal1_lbl metal1)
|
||||
C(via1 metal1 via1 metal2)
|
||||
C(metal2 via1 metal2 metal2_lbl)
|
||||
C(metal2_lbl metal2)
|
||||
C(ntie nwell diff_cont ntie)
|
||||
C(psd diff_cont psd)
|
||||
C(ptie diff_cont ptie)
|
||||
C(nsd diff_cont nsd)
|
||||
G(rbulk BULK)
|
||||
G(ptie BULK)
|
||||
D(D$PMOS PMOS
|
||||
T(S
|
||||
R(psd -650 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(psd 125 -475 675 475)
|
||||
)
|
||||
T(B
|
||||
R(nwell -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
D(D$PMOS$1 PMOS
|
||||
T(S
|
||||
R(psd -675 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(psd 125 -475 650 475)
|
||||
)
|
||||
T(B
|
||||
R(nwell -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
D(D$NMOS NMOS
|
||||
T(S
|
||||
R(nsd -650 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(nsd 125 -475 675 475)
|
||||
)
|
||||
T(B
|
||||
R(rbulk -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
D(D$NMOS$1 NMOS
|
||||
T(S
|
||||
R(nsd -675 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(nsd 125 -475 650 475)
|
||||
)
|
||||
T(B
|
||||
R(rbulk -125 -475 125 475)
|
||||
)
|
||||
)
|
||||
X(INV2
|
||||
N($1
|
||||
R(nwell -1400 1800 1400 4580)
|
||||
R(diff_cont -110 3930 110 4150)
|
||||
R(ntie -400 3700 400 4380)
|
||||
)
|
||||
N(IN
|
||||
R(poly -525 -250 -275 2250)
|
||||
R(poly -1700 1620 -400 1980)
|
||||
R(poly -525 -800 -275 800)
|
||||
R(poly -525 2000 -275 3600)
|
||||
R(poly_lbl -801 1799 -799 1801)
|
||||
R(poly_cont -1630 1690 -1410 1910)
|
||||
)
|
||||
N($3
|
||||
R(poly 275 -250 525 2250)
|
||||
R(poly 220 820 580 1180)
|
||||
R(poly 275 2000 525 3600)
|
||||
R(poly 275 -800 525 800)
|
||||
R(diff_cont -910 2490 -690 2710)
|
||||
R(diff_cont -910 2890 -690 3110)
|
||||
R(diff_cont -910 -310 -690 -90)
|
||||
R(diff_cont -910 90 -690 310)
|
||||
R(poly_cont 290 890 510 1110)
|
||||
R(metal1 -800 820 580 1180)
|
||||
R(metal1 -980 -420 -620 2420)
|
||||
R(metal1 -980 2420 -620 3180)
|
||||
R(metal1 -980 -380 -620 380)
|
||||
R(psd -1050 2325 -525 3275)
|
||||
R(nsd -1050 -475 -525 475)
|
||||
)
|
||||
N(OUT
|
||||
R(diff_cont 690 2890 910 3110)
|
||||
R(diff_cont 690 2490 910 2710)
|
||||
R(diff_cont 690 90 910 310)
|
||||
R(diff_cont 690 -310 910 -90)
|
||||
Q(metal1 800 20 800 380 940 380 940 1620 620 1620 620 2420 980 2420 980 1980 1300 1980 1300 20)
|
||||
R(metal1 620 2420 980 3180)
|
||||
R(metal1 620 -380 980 380)
|
||||
R(metal1_lbl 799 1799 801 1801)
|
||||
R(psd 525 2325 1050 3275)
|
||||
R(nsd 525 -475 1050 475)
|
||||
)
|
||||
N(VSS
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(via1 -125 -325 125 -75)
|
||||
R(via1 -125 75 125 325)
|
||||
R(metal2 -1400 -450 1400 450)
|
||||
R(metal2_lbl 1239 -91 1241 -89)
|
||||
R(nsd -275 -475 275 475)
|
||||
)
|
||||
N(VDD
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(via1 -125 2475 125 2725)
|
||||
R(via1 -125 2875 125 3125)
|
||||
R(metal2 -1400 2350 1400 3250)
|
||||
R(metal2_lbl 1249 2799 1251 2801)
|
||||
R(psd -275 2325 275 3275)
|
||||
)
|
||||
N(BULK
|
||||
R(diff_cont -110 -1360 110 -1140)
|
||||
R(ptie -400 -1590 400 -910)
|
||||
)
|
||||
P($0 $1)
|
||||
P(IN IN)
|
||||
P($2 $3)
|
||||
P(OUT OUT)
|
||||
P(VSS VSS)
|
||||
P(VDD VDD)
|
||||
P(BULK BULK)
|
||||
D($1 D$PMOS
|
||||
Y(-400 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.49875)
|
||||
E(AD 0.26125)
|
||||
T(S $3)
|
||||
T(G IN)
|
||||
T(D VDD)
|
||||
T(B $1)
|
||||
)
|
||||
D($2 D$PMOS$1
|
||||
Y(400 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.49875)
|
||||
T(S VDD)
|
||||
T(G $3)
|
||||
T(D OUT)
|
||||
T(B $1)
|
||||
)
|
||||
D($3 D$NMOS
|
||||
Y(-400 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.49875)
|
||||
E(AD 0.26125)
|
||||
T(S $3)
|
||||
T(G IN)
|
||||
T(D VSS)
|
||||
T(B BULK)
|
||||
)
|
||||
D($4 D$NMOS$1
|
||||
Y(400 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.49875)
|
||||
T(S VSS)
|
||||
T(G $3)
|
||||
T(D OUT)
|
||||
T(B BULK)
|
||||
)
|
||||
)
|
||||
X(INV2PAIR
|
||||
N(BULK)
|
||||
N($I8
|
||||
R(diff_cont 3430 3290 3650 3510)
|
||||
R(diff_cont 3430 3690 3650 3910)
|
||||
R(diff_cont 3430 490 3650 710)
|
||||
R(diff_cont 3430 890 3650 1110)
|
||||
)
|
||||
N($I6
|
||||
R(diff_cont 4230 3290 4450 3510)
|
||||
R(diff_cont 4230 3690 4450 3910)
|
||||
R(diff_cont 4230 3690 4450 3910)
|
||||
R(diff_cont 4230 3290 4450 3510)
|
||||
R(diff_cont 1590 3290 1810 3510)
|
||||
R(diff_cont 1590 3690 1810 3910)
|
||||
R(diff_cont 1590 3690 1810 3910)
|
||||
R(diff_cont 1590 3290 1810 3510)
|
||||
R(metal1 4160 3220 4520 3980)
|
||||
R(metal1 4160 3220 4520 3980)
|
||||
R(metal1 1520 3220 1880 3980)
|
||||
R(metal1 1520 3220 1880 3980)
|
||||
)
|
||||
N($I5
|
||||
R(diff_cont 4230 490 4450 710)
|
||||
R(diff_cont 4230 890 4450 1110)
|
||||
R(diff_cont 4230 890 4450 1110)
|
||||
R(diff_cont 4230 490 4450 710)
|
||||
R(diff_cont 1590 490 1810 710)
|
||||
R(diff_cont 1590 890 1810 1110)
|
||||
R(diff_cont 1590 890 1810 1110)
|
||||
R(diff_cont 1590 490 1810 710)
|
||||
R(metal1 4160 420 4520 1180)
|
||||
R(metal1 4160 420 4520 1180)
|
||||
R(metal1 1520 420 1880 1180)
|
||||
R(metal1 1520 420 1880 1180)
|
||||
)
|
||||
N($I4
|
||||
R(diff_cont 2390 3690 2610 3910)
|
||||
R(diff_cont 2390 3290 2610 3510)
|
||||
R(diff_cont 2390 890 2610 1110)
|
||||
R(diff_cont 2390 490 2610 710)
|
||||
)
|
||||
N($I3)
|
||||
N($I2
|
||||
R(diff_cont 5030 3690 5250 3910)
|
||||
R(diff_cont 5030 3290 5250 3510)
|
||||
R(diff_cont 5030 890 5250 1110)
|
||||
R(diff_cont 5030 490 5250 710)
|
||||
)
|
||||
N($I1)
|
||||
P(BULK BULK)
|
||||
P($1 $I8)
|
||||
P($2 $I6)
|
||||
P($3 $I5)
|
||||
P($4 $I3)
|
||||
P($5 $I2)
|
||||
P($6 $I1)
|
||||
X($1 INV2 Y(1700 800)
|
||||
P($0 $I1)
|
||||
P(IN $I3)
|
||||
P(OUT $I4)
|
||||
P(VSS $I5)
|
||||
P(VDD $I6)
|
||||
P(BULK BULK)
|
||||
)
|
||||
X($2 INV2 Y(4340 800)
|
||||
P($0 $I1)
|
||||
P(IN $I4)
|
||||
P($2 $I8)
|
||||
P(OUT $I2)
|
||||
P(VSS $I5)
|
||||
P(VDD $I6)
|
||||
P(BULK BULK)
|
||||
)
|
||||
)
|
||||
X(RINGO
|
||||
N(FB
|
||||
R(diff_cont 22850 2490 23070 2710)
|
||||
R(diff_cont 22850 2890 23070 3110)
|
||||
R(diff_cont 22850 -310 23070 -90)
|
||||
R(diff_cont 22850 90 23070 310)
|
||||
R(metal1 -1700 1620 -1340 1980)
|
||||
R(via1 -1645 1675 -1395 1925)
|
||||
R(via1 22835 1675 23085 1925)
|
||||
R(metal2 -1720 1600 23160 2000)
|
||||
R(metal2_lbl -1 1799 1 1801)
|
||||
)
|
||||
N(OSC
|
||||
R(diff_cont 24450 2890 24670 3110)
|
||||
R(diff_cont 24450 2490 24670 2710)
|
||||
R(diff_cont 24450 90 24670 310)
|
||||
R(diff_cont 24450 -310 24670 -90)
|
||||
R(via1 24435 1675 24685 1925)
|
||||
R(metal2 24360 1600 24760 2000)
|
||||
R(metal2_lbl 24559 1799 24561 1801)
|
||||
)
|
||||
N(VDD
|
||||
R(diff_cont 7810 2490 8030 2710)
|
||||
R(diff_cont 7810 2890 8030 3110)
|
||||
R(diff_cont 7810 2890 8030 3110)
|
||||
R(diff_cont 7810 2490 8030 2710)
|
||||
R(diff_cont 5170 2490 5390 2710)
|
||||
R(diff_cont 5170 2890 5390 3110)
|
||||
R(diff_cont 5170 2890 5390 3110)
|
||||
R(diff_cont 5170 2490 5390 2710)
|
||||
R(diff_cont 2530 2490 2750 2710)
|
||||
R(diff_cont 2530 2890 2750 3110)
|
||||
R(diff_cont 2530 2890 2750 3110)
|
||||
R(diff_cont 2530 2490 2750 2710)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont 13090 2490 13310 2710)
|
||||
R(diff_cont 13090 2890 13310 3110)
|
||||
R(diff_cont 13090 2890 13310 3110)
|
||||
R(diff_cont 13090 2490 13310 2710)
|
||||
R(diff_cont 10450 2490 10670 2710)
|
||||
R(diff_cont 10450 2890 10670 3110)
|
||||
R(diff_cont 10450 2890 10670 3110)
|
||||
R(diff_cont 10450 2490 10670 2710)
|
||||
R(diff_cont 18370 2490 18590 2710)
|
||||
R(diff_cont 18370 2890 18590 3110)
|
||||
R(diff_cont 18370 2890 18590 3110)
|
||||
R(diff_cont 18370 2490 18590 2710)
|
||||
R(diff_cont 15730 2490 15950 2710)
|
||||
R(diff_cont 15730 2890 15950 3110)
|
||||
R(diff_cont 15730 2890 15950 3110)
|
||||
R(diff_cont 15730 2490 15950 2710)
|
||||
R(diff_cont 23650 2490 23870 2710)
|
||||
R(diff_cont 23650 2890 23870 3110)
|
||||
R(diff_cont 23650 2890 23870 3110)
|
||||
R(diff_cont 23650 2490 23870 2710)
|
||||
R(diff_cont 21010 2490 21230 2710)
|
||||
R(diff_cont 21010 2890 21230 3110)
|
||||
R(diff_cont 21010 2890 21230 3110)
|
||||
R(diff_cont 21010 2490 21230 2710)
|
||||
R(metal1 -180 3100 180 4220)
|
||||
R(metal1 2460 3100 2820 4220)
|
||||
R(metal1 5100 3100 5460 4220)
|
||||
R(metal1 7740 3100 8100 4220)
|
||||
R(metal1 10380 3100 10740 4220)
|
||||
R(metal1 13020 3100 13380 4220)
|
||||
R(metal1 15660 3100 16020 4220)
|
||||
R(metal1 18300 3100 18660 4220)
|
||||
R(metal1 20940 3100 21300 4220)
|
||||
R(metal1 23580 3100 23940 4220)
|
||||
R(metal1 7740 2420 8100 3180)
|
||||
R(metal1 7740 2420 8100 3180)
|
||||
R(metal1 5100 2420 5460 3180)
|
||||
R(metal1 5100 2420 5460 3180)
|
||||
R(metal1 2460 2420 2820 3180)
|
||||
R(metal1 2460 2420 2820 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 13020 2420 13380 3180)
|
||||
R(metal1 13020 2420 13380 3180)
|
||||
R(metal1 10380 2420 10740 3180)
|
||||
R(metal1 10380 2420 10740 3180)
|
||||
R(metal1 18300 2420 18660 3180)
|
||||
R(metal1 18300 2420 18660 3180)
|
||||
R(metal1 15660 2420 16020 3180)
|
||||
R(metal1 15660 2420 16020 3180)
|
||||
R(metal1 23580 2420 23940 3180)
|
||||
R(metal1 23580 2420 23940 3180)
|
||||
R(metal1 20940 2420 21300 3180)
|
||||
R(metal1 20940 2420 21300 3180)
|
||||
R(metal2_lbl -1 2799 1 2801)
|
||||
)
|
||||
N('BULK,VSS'
|
||||
R(diff_cont 7810 -310 8030 -90)
|
||||
R(diff_cont 7810 90 8030 310)
|
||||
R(diff_cont 7810 90 8030 310)
|
||||
R(diff_cont 7810 -310 8030 -90)
|
||||
R(diff_cont 5170 -310 5390 -90)
|
||||
R(diff_cont 5170 90 5390 310)
|
||||
R(diff_cont 5170 90 5390 310)
|
||||
R(diff_cont 5170 -310 5390 -90)
|
||||
R(diff_cont 2530 -310 2750 -90)
|
||||
R(diff_cont 2530 90 2750 310)
|
||||
R(diff_cont 2530 90 2750 310)
|
||||
R(diff_cont 2530 -310 2750 -90)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont 13090 -310 13310 -90)
|
||||
R(diff_cont 13090 90 13310 310)
|
||||
R(diff_cont 13090 90 13310 310)
|
||||
R(diff_cont 13090 -310 13310 -90)
|
||||
R(diff_cont 10450 -310 10670 -90)
|
||||
R(diff_cont 10450 90 10670 310)
|
||||
R(diff_cont 10450 90 10670 310)
|
||||
R(diff_cont 10450 -310 10670 -90)
|
||||
R(diff_cont 18370 -310 18590 -90)
|
||||
R(diff_cont 18370 90 18590 310)
|
||||
R(diff_cont 18370 90 18590 310)
|
||||
R(diff_cont 18370 -310 18590 -90)
|
||||
R(diff_cont 15730 -310 15950 -90)
|
||||
R(diff_cont 15730 90 15950 310)
|
||||
R(diff_cont 15730 90 15950 310)
|
||||
R(diff_cont 15730 -310 15950 -90)
|
||||
R(diff_cont 23650 -310 23870 -90)
|
||||
R(diff_cont 23650 90 23870 310)
|
||||
R(diff_cont 23650 90 23870 310)
|
||||
R(diff_cont 23650 -310 23870 -90)
|
||||
R(diff_cont 21010 -310 21230 -90)
|
||||
R(diff_cont 21010 90 21230 310)
|
||||
R(diff_cont 21010 90 21230 310)
|
||||
R(diff_cont 21010 -310 21230 -90)
|
||||
R(metal1 -180 -1420 180 -300)
|
||||
R(metal1 2460 -1420 2820 -300)
|
||||
R(metal1 5100 -1420 5460 -300)
|
||||
R(metal1 7740 -1420 8100 -300)
|
||||
R(metal1 10380 -1420 10740 -300)
|
||||
R(metal1 13020 -1420 13380 -300)
|
||||
R(metal1 15660 -1420 16020 -300)
|
||||
R(metal1 18300 -1420 18660 -300)
|
||||
R(metal1 20940 -1420 21300 -300)
|
||||
R(metal1 23580 -1420 23940 -300)
|
||||
R(metal1 7740 -380 8100 380)
|
||||
R(metal1 7740 -380 8100 380)
|
||||
R(metal1 5100 -380 5460 380)
|
||||
R(metal1 5100 -380 5460 380)
|
||||
R(metal1 2460 -380 2820 380)
|
||||
R(metal1 2460 -380 2820 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 13020 -380 13380 380)
|
||||
R(metal1 13020 -380 13380 380)
|
||||
R(metal1 10380 -380 10740 380)
|
||||
R(metal1 10380 -380 10740 380)
|
||||
R(metal1 18300 -380 18660 380)
|
||||
R(metal1 18300 -380 18660 380)
|
||||
R(metal1 15660 -380 16020 380)
|
||||
R(metal1 15660 -380 16020 380)
|
||||
R(metal1 23580 -380 23940 380)
|
||||
R(metal1 23580 -380 23940 380)
|
||||
R(metal1 20940 -380 21300 380)
|
||||
R(metal1 20940 -380 21300 380)
|
||||
R(metal2_lbl -1 -1 1 1)
|
||||
)
|
||||
N($I13
|
||||
R(diff_cont 3330 2890 3550 3110)
|
||||
R(diff_cont 3330 2490 3550 2710)
|
||||
R(diff_cont 3330 90 3550 310)
|
||||
R(diff_cont 3330 -310 3550 -90)
|
||||
)
|
||||
N($I7
|
||||
R(diff_cont 19170 2890 19390 3110)
|
||||
R(diff_cont 19170 2490 19390 2710)
|
||||
R(diff_cont 19170 90 19390 310)
|
||||
R(diff_cont 19170 -310 19390 -90)
|
||||
)
|
||||
N($I6
|
||||
R(diff_cont 13890 2890 14110 3110)
|
||||
R(diff_cont 13890 2490 14110 2710)
|
||||
R(diff_cont 13890 90 14110 310)
|
||||
R(diff_cont 13890 -310 14110 -90)
|
||||
)
|
||||
N($I5
|
||||
R(diff_cont 8610 2890 8830 3110)
|
||||
R(diff_cont 8610 2490 8830 2710)
|
||||
R(diff_cont 8610 90 8830 310)
|
||||
R(diff_cont 8610 -310 8830 -90)
|
||||
)
|
||||
P(FB FB)
|
||||
P(OSC OSC)
|
||||
P(VDD VDD)
|
||||
P('BULK,VSS' 'BULK,VSS')
|
||||
X($1 INV2PAIR Y(19420 -800)
|
||||
P(BULK 'BULK,VSS')
|
||||
P($1 FB)
|
||||
P($2 VDD)
|
||||
P($3 'BULK,VSS')
|
||||
P($4 $I7)
|
||||
P($5 OSC)
|
||||
P($6 VDD)
|
||||
)
|
||||
X($2 INV2PAIR Y(-1700 -800)
|
||||
P(BULK 'BULK,VSS')
|
||||
P($2 VDD)
|
||||
P($3 'BULK,VSS')
|
||||
P($4 FB)
|
||||
P($5 $I13)
|
||||
P($6 VDD)
|
||||
)
|
||||
X($3 INV2PAIR Y(3580 -800)
|
||||
P(BULK 'BULK,VSS')
|
||||
P($2 VDD)
|
||||
P($3 'BULK,VSS')
|
||||
P($4 $I13)
|
||||
P($5 $I5)
|
||||
P($6 VDD)
|
||||
)
|
||||
X($4 INV2PAIR Y(8860 -800)
|
||||
P(BULK 'BULK,VSS')
|
||||
P($2 VDD)
|
||||
P($3 'BULK,VSS')
|
||||
P($4 $I5)
|
||||
P($5 $I6)
|
||||
P($6 VDD)
|
||||
)
|
||||
X($5 INV2PAIR Y(14140 -800)
|
||||
P(BULK 'BULK,VSS')
|
||||
P($2 VDD)
|
||||
P($3 'BULK,VSS')
|
||||
P($4 $I6)
|
||||
P($5 $I7)
|
||||
P($6 VDD)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,444 @@
|
|||
#%l2n-klayout
|
||||
W(RINGO)
|
||||
U(0.001)
|
||||
L(poly)
|
||||
L(poly_lbl)
|
||||
L(diff_cont)
|
||||
L(poly_cont)
|
||||
L(metal1)
|
||||
L(metal1_lbl)
|
||||
L(via1)
|
||||
L(metal2)
|
||||
L(metal2_lbl)
|
||||
L(psd)
|
||||
L(nsd)
|
||||
C(poly poly poly_lbl poly_cont)
|
||||
C(poly_lbl poly)
|
||||
C(diff_cont diff_cont metal1 psd nsd)
|
||||
C(poly_cont poly poly_cont metal1)
|
||||
C(metal1 diff_cont poly_cont metal1 metal1_lbl via1)
|
||||
C(metal1_lbl metal1)
|
||||
C(via1 metal1 via1 metal2)
|
||||
C(metal2 via1 metal2 metal2_lbl)
|
||||
C(metal2_lbl metal2)
|
||||
C(psd diff_cont psd)
|
||||
C(nsd diff_cont nsd)
|
||||
D(D$PMOS PMOS
|
||||
T(S
|
||||
R(psd -650 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(psd 125 -475 675 475)
|
||||
)
|
||||
)
|
||||
D(D$PMOS$1 PMOS
|
||||
T(S
|
||||
R(psd -675 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(psd 125 -475 650 475)
|
||||
)
|
||||
)
|
||||
D(D$NMOS NMOS
|
||||
T(S
|
||||
R(nsd -650 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(nsd 125 -475 675 475)
|
||||
)
|
||||
)
|
||||
D(D$NMOS$1 NMOS
|
||||
T(S
|
||||
R(nsd -675 -475 -125 475)
|
||||
)
|
||||
T(G
|
||||
R(poly -125 -475 125 475)
|
||||
)
|
||||
T(D
|
||||
R(nsd 125 -475 650 475)
|
||||
)
|
||||
)
|
||||
X(INV2
|
||||
N(IN
|
||||
R(poly -525 -250 -275 2250)
|
||||
R(poly -1700 1620 -400 1980)
|
||||
R(poly -525 -800 -275 800)
|
||||
R(poly -525 2000 -275 3600)
|
||||
R(poly_lbl -801 1799 -799 1801)
|
||||
R(poly_cont -1630 1690 -1410 1910)
|
||||
)
|
||||
N($2
|
||||
R(poly 275 -250 525 2250)
|
||||
R(poly 220 820 580 1180)
|
||||
R(poly 275 2000 525 3600)
|
||||
R(poly 275 -800 525 800)
|
||||
R(diff_cont -910 2490 -690 2710)
|
||||
R(diff_cont -910 2890 -690 3110)
|
||||
R(diff_cont -910 -310 -690 -90)
|
||||
R(diff_cont -910 90 -690 310)
|
||||
R(poly_cont 290 890 510 1110)
|
||||
R(metal1 -800 820 580 1180)
|
||||
R(metal1 -980 -420 -620 2420)
|
||||
R(metal1 -980 2420 -620 3180)
|
||||
R(metal1 -980 -380 -620 380)
|
||||
R(psd -1050 2325 -525 3275)
|
||||
R(nsd -1050 -475 -525 475)
|
||||
)
|
||||
N(OUT
|
||||
R(diff_cont 690 2890 910 3110)
|
||||
R(diff_cont 690 2490 910 2710)
|
||||
R(diff_cont 690 90 910 310)
|
||||
R(diff_cont 690 -310 910 -90)
|
||||
Q(metal1 800 20 800 380 940 380 940 1620 620 1620 620 2420 980 2420 980 1980 1300 1980 1300 20)
|
||||
R(metal1 620 2420 980 3180)
|
||||
R(metal1 620 -380 980 380)
|
||||
R(metal1_lbl 799 1799 801 1801)
|
||||
R(psd 525 2325 1050 3275)
|
||||
R(nsd 525 -475 1050 475)
|
||||
)
|
||||
N($4
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(via1 -125 -325 125 -75)
|
||||
R(via1 -125 75 125 325)
|
||||
R(metal2 -1400 -450 1400 450)
|
||||
R(nsd -275 -475 275 475)
|
||||
)
|
||||
N($5
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(via1 -125 2475 125 2725)
|
||||
R(via1 -125 2875 125 3125)
|
||||
R(metal2 -1400 2350 1400 3250)
|
||||
R(psd -275 2325 275 3275)
|
||||
)
|
||||
P(IN IN)
|
||||
P($1 $2)
|
||||
P(OUT OUT)
|
||||
P($3 $4)
|
||||
P($4 $5)
|
||||
D($1 D$PMOS
|
||||
Y(-400 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.49875)
|
||||
E(AD 0.26125)
|
||||
T(S $2)
|
||||
T(G IN)
|
||||
T(D $5)
|
||||
)
|
||||
D($2 D$PMOS$1
|
||||
Y(400 2800)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.49875)
|
||||
T(S $5)
|
||||
T(G $2)
|
||||
T(D OUT)
|
||||
)
|
||||
D($3 D$NMOS
|
||||
Y(-400 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.49875)
|
||||
E(AD 0.26125)
|
||||
T(S $2)
|
||||
T(G IN)
|
||||
T(D $4)
|
||||
)
|
||||
D($4 D$NMOS$1
|
||||
Y(400 0)
|
||||
E(L 0.25)
|
||||
E(W 0.95)
|
||||
E(AS 0.26125)
|
||||
E(AD 0.49875)
|
||||
T(S $4)
|
||||
T(G $2)
|
||||
T(D OUT)
|
||||
)
|
||||
)
|
||||
X(RINGO
|
||||
N(FB
|
||||
R(diff_cont 22850 2490 23070 2710)
|
||||
R(diff_cont 22850 2890 23070 3110)
|
||||
R(diff_cont 22850 -310 23070 -90)
|
||||
R(diff_cont 22850 90 23070 310)
|
||||
R(metal1 -1700 1620 -1340 1980)
|
||||
R(via1 -1645 1675 -1395 1925)
|
||||
R(via1 22835 1675 23085 1925)
|
||||
R(metal2 -1720 1600 23160 2000)
|
||||
R(metal2_lbl -1 1799 1 1801)
|
||||
)
|
||||
N(OSC
|
||||
R(diff_cont 24450 2890 24670 3110)
|
||||
R(diff_cont 24450 2490 24670 2710)
|
||||
R(diff_cont 24450 90 24670 310)
|
||||
R(diff_cont 24450 -310 24670 -90)
|
||||
R(via1 24435 1675 24685 1925)
|
||||
R(metal2 24360 1600 24760 2000)
|
||||
R(metal2_lbl 24559 1799 24561 1801)
|
||||
)
|
||||
N(VSS
|
||||
R(diff_cont 2530 -310 2750 -90)
|
||||
R(diff_cont 2530 90 2750 310)
|
||||
R(diff_cont 2530 90 2750 310)
|
||||
R(diff_cont 2530 -310 2750 -90)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 90 110 310)
|
||||
R(diff_cont -110 -310 110 -90)
|
||||
R(diff_cont 5170 -310 5390 -90)
|
||||
R(diff_cont 5170 90 5390 310)
|
||||
R(diff_cont 5170 90 5390 310)
|
||||
R(diff_cont 5170 -310 5390 -90)
|
||||
R(diff_cont 7810 -310 8030 -90)
|
||||
R(diff_cont 7810 90 8030 310)
|
||||
R(diff_cont 7810 90 8030 310)
|
||||
R(diff_cont 7810 -310 8030 -90)
|
||||
R(diff_cont 10450 -310 10670 -90)
|
||||
R(diff_cont 10450 90 10670 310)
|
||||
R(diff_cont 10450 90 10670 310)
|
||||
R(diff_cont 10450 -310 10670 -90)
|
||||
R(diff_cont 13090 -310 13310 -90)
|
||||
R(diff_cont 13090 90 13310 310)
|
||||
R(diff_cont 13090 90 13310 310)
|
||||
R(diff_cont 13090 -310 13310 -90)
|
||||
R(diff_cont 15730 -310 15950 -90)
|
||||
R(diff_cont 15730 90 15950 310)
|
||||
R(diff_cont 15730 90 15950 310)
|
||||
R(diff_cont 15730 -310 15950 -90)
|
||||
R(diff_cont 18370 -310 18590 -90)
|
||||
R(diff_cont 18370 90 18590 310)
|
||||
R(diff_cont 18370 90 18590 310)
|
||||
R(diff_cont 18370 -310 18590 -90)
|
||||
R(diff_cont 21010 -310 21230 -90)
|
||||
R(diff_cont 21010 90 21230 310)
|
||||
R(diff_cont 21010 90 21230 310)
|
||||
R(diff_cont 21010 -310 21230 -90)
|
||||
R(diff_cont 23650 -310 23870 -90)
|
||||
R(diff_cont 23650 90 23870 310)
|
||||
R(diff_cont 23650 90 23870 310)
|
||||
R(diff_cont 23650 -310 23870 -90)
|
||||
R(metal1 2460 -380 2820 380)
|
||||
R(metal1 2460 -380 2820 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 -180 -380 180 380)
|
||||
R(metal1 5100 -380 5460 380)
|
||||
R(metal1 5100 -380 5460 380)
|
||||
R(metal1 7740 -380 8100 380)
|
||||
R(metal1 7740 -380 8100 380)
|
||||
R(metal1 10380 -380 10740 380)
|
||||
R(metal1 10380 -380 10740 380)
|
||||
R(metal1 13020 -380 13380 380)
|
||||
R(metal1 13020 -380 13380 380)
|
||||
R(metal1 15660 -380 16020 380)
|
||||
R(metal1 15660 -380 16020 380)
|
||||
R(metal1 18300 -380 18660 380)
|
||||
R(metal1 18300 -380 18660 380)
|
||||
R(metal1 20940 -380 21300 380)
|
||||
R(metal1 20940 -380 21300 380)
|
||||
R(metal1 23580 -380 23940 380)
|
||||
R(metal1 23580 -380 23940 380)
|
||||
R(metal2_lbl -1 -1 1 1)
|
||||
)
|
||||
N(VDD
|
||||
R(diff_cont 2530 2490 2750 2710)
|
||||
R(diff_cont 2530 2890 2750 3110)
|
||||
R(diff_cont 2530 2890 2750 3110)
|
||||
R(diff_cont 2530 2490 2750 2710)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2890 110 3110)
|
||||
R(diff_cont -110 2490 110 2710)
|
||||
R(diff_cont 5170 2490 5390 2710)
|
||||
R(diff_cont 5170 2890 5390 3110)
|
||||
R(diff_cont 5170 2890 5390 3110)
|
||||
R(diff_cont 5170 2490 5390 2710)
|
||||
R(diff_cont 7810 2490 8030 2710)
|
||||
R(diff_cont 7810 2890 8030 3110)
|
||||
R(diff_cont 7810 2890 8030 3110)
|
||||
R(diff_cont 7810 2490 8030 2710)
|
||||
R(diff_cont 10450 2490 10670 2710)
|
||||
R(diff_cont 10450 2890 10670 3110)
|
||||
R(diff_cont 10450 2890 10670 3110)
|
||||
R(diff_cont 10450 2490 10670 2710)
|
||||
R(diff_cont 13090 2490 13310 2710)
|
||||
R(diff_cont 13090 2890 13310 3110)
|
||||
R(diff_cont 13090 2890 13310 3110)
|
||||
R(diff_cont 13090 2490 13310 2710)
|
||||
R(diff_cont 15730 2490 15950 2710)
|
||||
R(diff_cont 15730 2890 15950 3110)
|
||||
R(diff_cont 15730 2890 15950 3110)
|
||||
R(diff_cont 15730 2490 15950 2710)
|
||||
R(diff_cont 18370 2490 18590 2710)
|
||||
R(diff_cont 18370 2890 18590 3110)
|
||||
R(diff_cont 18370 2890 18590 3110)
|
||||
R(diff_cont 18370 2490 18590 2710)
|
||||
R(diff_cont 21010 2490 21230 2710)
|
||||
R(diff_cont 21010 2890 21230 3110)
|
||||
R(diff_cont 21010 2890 21230 3110)
|
||||
R(diff_cont 21010 2490 21230 2710)
|
||||
R(diff_cont 23650 2490 23870 2710)
|
||||
R(diff_cont 23650 2890 23870 3110)
|
||||
R(diff_cont 23650 2890 23870 3110)
|
||||
R(diff_cont 23650 2490 23870 2710)
|
||||
R(metal1 2460 2420 2820 3180)
|
||||
R(metal1 2460 2420 2820 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 -180 2420 180 3180)
|
||||
R(metal1 5100 2420 5460 3180)
|
||||
R(metal1 5100 2420 5460 3180)
|
||||
R(metal1 7740 2420 8100 3180)
|
||||
R(metal1 7740 2420 8100 3180)
|
||||
R(metal1 10380 2420 10740 3180)
|
||||
R(metal1 10380 2420 10740 3180)
|
||||
R(metal1 13020 2420 13380 3180)
|
||||
R(metal1 13020 2420 13380 3180)
|
||||
R(metal1 15660 2420 16020 3180)
|
||||
R(metal1 15660 2420 16020 3180)
|
||||
R(metal1 18300 2420 18660 3180)
|
||||
R(metal1 18300 2420 18660 3180)
|
||||
R(metal1 20940 2420 21300 3180)
|
||||
R(metal1 20940 2420 21300 3180)
|
||||
R(metal1 23580 2420 23940 3180)
|
||||
R(metal1 23580 2420 23940 3180)
|
||||
R(metal2_lbl -1 2799 1 2801)
|
||||
)
|
||||
N($I19
|
||||
R(diff_cont 690 2890 910 3110)
|
||||
R(diff_cont 690 2490 910 2710)
|
||||
R(diff_cont 690 90 910 310)
|
||||
R(diff_cont 690 -310 910 -90)
|
||||
)
|
||||
N($I8
|
||||
R(diff_cont 21810 2890 22030 3110)
|
||||
R(diff_cont 21810 2490 22030 2710)
|
||||
R(diff_cont 21810 90 22030 310)
|
||||
R(diff_cont 21810 -310 22030 -90)
|
||||
)
|
||||
N($I7
|
||||
R(diff_cont 19170 2890 19390 3110)
|
||||
R(diff_cont 19170 2490 19390 2710)
|
||||
R(diff_cont 19170 90 19390 310)
|
||||
R(diff_cont 19170 -310 19390 -90)
|
||||
)
|
||||
N($I6
|
||||
R(diff_cont 16530 2890 16750 3110)
|
||||
R(diff_cont 16530 2490 16750 2710)
|
||||
R(diff_cont 16530 90 16750 310)
|
||||
R(diff_cont 16530 -310 16750 -90)
|
||||
)
|
||||
N($I5
|
||||
R(diff_cont 13890 2890 14110 3110)
|
||||
R(diff_cont 13890 2490 14110 2710)
|
||||
R(diff_cont 13890 90 14110 310)
|
||||
R(diff_cont 13890 -310 14110 -90)
|
||||
)
|
||||
N($I4
|
||||
R(diff_cont 11250 2890 11470 3110)
|
||||
R(diff_cont 11250 2490 11470 2710)
|
||||
R(diff_cont 11250 90 11470 310)
|
||||
R(diff_cont 11250 -310 11470 -90)
|
||||
)
|
||||
N($I3
|
||||
R(diff_cont 8610 2890 8830 3110)
|
||||
R(diff_cont 8610 2490 8830 2710)
|
||||
R(diff_cont 8610 90 8830 310)
|
||||
R(diff_cont 8610 -310 8830 -90)
|
||||
)
|
||||
N($I2
|
||||
R(diff_cont 5970 2890 6190 3110)
|
||||
R(diff_cont 5970 2490 6190 2710)
|
||||
R(diff_cont 5970 90 6190 310)
|
||||
R(diff_cont 5970 -310 6190 -90)
|
||||
)
|
||||
N($I1
|
||||
R(diff_cont 3330 2890 3550 3110)
|
||||
R(diff_cont 3330 2490 3550 2710)
|
||||
R(diff_cont 3330 90 3550 310)
|
||||
R(diff_cont 3330 -310 3550 -90)
|
||||
)
|
||||
P(FB FB)
|
||||
P(OSC OSC)
|
||||
P(VSS VSS)
|
||||
P(VDD VDD)
|
||||
X($1 INV2 Y(23760 0)
|
||||
P(IN $I8)
|
||||
P($1 FB)
|
||||
P(OUT OSC)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($2 INV2 Y(0 0)
|
||||
P(IN FB)
|
||||
P(OUT $I19)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($3 INV2 Y(2640 0)
|
||||
P(IN $I19)
|
||||
P(OUT $I1)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($4 INV2 Y(5280 0)
|
||||
P(IN $I1)
|
||||
P(OUT $I2)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($5 INV2 Y(7920 0)
|
||||
P(IN $I2)
|
||||
P(OUT $I3)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($6 INV2 Y(10560 0)
|
||||
P(IN $I3)
|
||||
P(OUT $I4)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($7 INV2 Y(13200 0)
|
||||
P(IN $I4)
|
||||
P(OUT $I5)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($8 INV2 Y(15840 0)
|
||||
P(IN $I5)
|
||||
P(OUT $I6)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($9 INV2 Y(18480 0)
|
||||
P(IN $I6)
|
||||
P(OUT $I7)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
X($10 INV2 Y(21120 0)
|
||||
P(IN $I7)
|
||||
P(OUT $I8)
|
||||
P($3 VSS)
|
||||
P($4 VDD)
|
||||
)
|
||||
)
|
||||
Loading…
Reference in New Issue