mirror of https://github.com/KLayout/klayout.git
WIP: performance improvement.
This commit is contained in:
parent
81bf47688e
commit
68fe668567
|
|
@ -433,7 +433,7 @@ DeepShapeStore::cell_mapping_to_original (size_t layout_index, db::Layout *into_
|
|||
}
|
||||
|
||||
if (! skip) {
|
||||
cm->second.map (m->first.first, m->second);
|
||||
cm->second.map (m->second, m->first.first);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@
|
|||
#include "dbHierNetworkProcessor.h"
|
||||
#include "dbDeepRegion.h"
|
||||
|
||||
#include "tlProgress.h"
|
||||
#include "tlTimer.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
|
|
@ -156,23 +159,53 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
}
|
||||
|
||||
// collect the cells below the top cell
|
||||
std::set<db::cell_index_type> all_called_cells;
|
||||
all_called_cells.insert (cell.cell_index ());
|
||||
cell.collect_called_cells (all_called_cells);
|
||||
|
||||
// ignore device cells from previous extractions
|
||||
std::set<db::cell_index_type> called_cells;
|
||||
called_cells.insert (cell.cell_index ());
|
||||
cell.collect_called_cells (called_cells);
|
||||
for (std::set<db::cell_index_type>::const_iterator ci = all_called_cells.begin (); ci != all_called_cells.end (); ++ci) {
|
||||
if (! m_netlist->device_abstract_by_cell_index (*ci)) {
|
||||
called_cells.insert (*ci);
|
||||
}
|
||||
}
|
||||
all_called_cells.clear ();
|
||||
|
||||
// build the device clusters
|
||||
db::Connectivity device_conn = get_connectivity (layout, layers);
|
||||
db::hier_clusters<shape_type> device_clusters;
|
||||
device_clusters.build (layout, cell, shape_iter_flags, device_conn);
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Extracting devices")));
|
||||
|
||||
// count effort and make a progress reporter
|
||||
|
||||
size_t n = 0;
|
||||
for (std::set<db::cell_index_type>::const_iterator ci = called_cells.begin (); ci != called_cells.end (); ++ci) {
|
||||
db::connected_clusters<shape_type> cc = device_clusters.clusters_per_cell (*ci);
|
||||
for (db::connected_clusters<shape_type>::all_iterator c = cc.begin_all (); !c.at_end(); ++c) {
|
||||
if (cc.is_root (*c)) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl::RelativeProgress progress (tl::to_string (tr ("Extracting devices")), n, 1);
|
||||
|
||||
struct ExtractorCacheValueType {
|
||||
ExtractorCacheValueType () : circuit (0) { }
|
||||
db::Circuit *circuit;
|
||||
db::Vector disp;
|
||||
std::map<size_t, geometry_per_terminal_type> geometry;
|
||||
};
|
||||
|
||||
typedef std::map<std::vector<db::Region>, ExtractorCacheValueType> extractor_cache_type;
|
||||
extractor_cache_type extractor_cache;
|
||||
|
||||
// for each cell investigate the clusters
|
||||
for (std::set<db::cell_index_type>::const_iterator ci = called_cells.begin (); ci != called_cells.end (); ++ci) {
|
||||
|
||||
// skip device cells from previous extractions
|
||||
if (m_netlist->device_abstract_by_cell_index (*ci)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_cell_index = *ci;
|
||||
|
||||
std::map<db::cell_index_type, db::Circuit *>::const_iterator c2c = circuits_by_cell.find (*ci);
|
||||
|
|
@ -200,6 +233,8 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
continue;
|
||||
}
|
||||
|
||||
++progress;
|
||||
|
||||
// build layer geometry from the cluster found
|
||||
|
||||
std::vector<db::Region> layer_geometry;
|
||||
|
|
@ -210,28 +245,55 @@ void NetlistDeviceExtractor::extract_without_initialize (db::Layout &layout, db:
|
|||
for (db::recursive_cluster_shape_iterator<shape_type> si (device_clusters, *l, *ci, *c); ! si.at_end(); ++si) {
|
||||
insert_into_region (*si, si.trans (), r);
|
||||
}
|
||||
// r.merge ()???
|
||||
}
|
||||
|
||||
// do the actual device extraction
|
||||
extract_devices (layer_geometry);
|
||||
db::Box box;
|
||||
for (std::vector<db::Region>::const_iterator g = layer_geometry.begin (); g != layer_geometry.end (); ++g) {
|
||||
box += g->bbox ();
|
||||
}
|
||||
|
||||
// push the new devices to the layout
|
||||
push_new_devices ();
|
||||
db::Vector disp = box.p1 () - db::Point ();
|
||||
for (std::vector<db::Region>::iterator g = layer_geometry.begin (); g != layer_geometry.end (); ++g) {
|
||||
g->transform (db::Disp (-disp));
|
||||
}
|
||||
|
||||
extractor_cache_type::const_iterator ec = extractor_cache.find (layer_geometry);
|
||||
if (ec == extractor_cache.end ()) {
|
||||
|
||||
// do the actual device extraction
|
||||
extract_devices (layer_geometry);
|
||||
|
||||
// push the new devices to the layout
|
||||
push_new_devices (disp);
|
||||
|
||||
ExtractorCacheValueType &ecv = extractor_cache [layer_geometry];
|
||||
ecv.disp = disp;
|
||||
ecv.circuit = mp_circuit;
|
||||
ecv.geometry.swap (m_new_devices);
|
||||
|
||||
} else {
|
||||
|
||||
push_cached_devices (ec->second.circuit, ec->second.geometry, ec->second.disp, disp);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::push_new_devices ()
|
||||
void NetlistDeviceExtractor::push_new_devices (const db::Vector &disp_cache)
|
||||
{
|
||||
db::VCplxTrans dbu_inv = db::CplxTrans (mp_layout->dbu ()).inverted ();
|
||||
db::CplxTrans dbu = db::CplxTrans (mp_layout->dbu ());
|
||||
db::VCplxTrans dbu_inv = dbu.inverted ();
|
||||
|
||||
for (std::map<size_t, geometry_per_terminal_type>::const_iterator d = m_new_devices.begin (); d != m_new_devices.end (); ++d) {
|
||||
|
||||
db::Device *device = mp_circuit->device_by_id (d->first);
|
||||
|
||||
db::Vector disp = dbu_inv * device->position () - db::Point ();
|
||||
device->set_position (device->position () + dbu * disp_cache);
|
||||
|
||||
DeviceCellKey key;
|
||||
|
||||
|
|
@ -302,12 +364,36 @@ void NetlistDeviceExtractor::push_new_devices ()
|
|||
ps.insert (std::make_pair (m_device_id_propname_id, tl::Variant (d->first)));
|
||||
db::properties_id_type pi = mp_layout->properties_repository ().properties_id (ps);
|
||||
|
||||
db::CellInstArrayWithProperties inst (db::CellInstArray (db::CellInst (c->second.first), db::Trans (disp)), pi);
|
||||
db::CellInstArrayWithProperties inst (db::CellInstArray (db::CellInst (c->second.first), db::Trans (disp_cache + disp)), pi);
|
||||
mp_layout->cell (m_cell_index).insert (inst);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_new_devices.clear ();
|
||||
void NetlistDeviceExtractor::push_cached_devices (db::Circuit *circuit, const std::map<size_t, geometry_per_terminal_type> &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp)
|
||||
{
|
||||
db::CplxTrans dbu = db::CplxTrans (mp_layout->dbu ());
|
||||
db::VCplxTrans dbu_inv = dbu.inverted ();
|
||||
db::PropertiesRepository::properties_set ps;
|
||||
|
||||
for (std::map<size_t, geometry_per_terminal_type>::const_iterator d = cached_devices.begin (); d != cached_devices.end (); ++d) {
|
||||
|
||||
db::Device *cached_device = circuit->device_by_id (d->first);
|
||||
db::Vector disp = dbu_inv * cached_device->position () - disp_cache - db::Point ();
|
||||
|
||||
db::Device *device = new db::Device (*cached_device);
|
||||
mp_circuit->add_device (device);
|
||||
device->set_position (device->position () + dbu * (new_disp - disp_cache));
|
||||
|
||||
// Build a property set for the device ID
|
||||
ps.clear ();
|
||||
ps.insert (std::make_pair (m_device_id_propname_id, tl::Variant (device->id ())));
|
||||
db::properties_id_type pi = mp_layout->properties_repository ().properties_id (ps);
|
||||
|
||||
db::CellInstArrayWithProperties inst (db::CellInstArray (db::CellInst (device->device_abstract ()->cell_index ()), db::Trans (new_disp + disp)), pi);
|
||||
mp_layout->cell (m_cell_index).insert (inst);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NetlistDeviceExtractor::setup ()
|
||||
|
|
|
|||
|
|
@ -521,7 +521,8 @@ private:
|
|||
void initialize (db::Netlist *nl);
|
||||
|
||||
void extract_without_initialize (db::Layout &layout, db::Cell &cell, hier_clusters_type &clusters, const std::vector<unsigned int> &layers);
|
||||
void push_new_devices ();
|
||||
void push_new_devices (const Vector &disp_cache);
|
||||
void push_cached_devices (db::Circuit *circuit, const std::map<size_t, geometry_per_terminal_type> &cached_devices, const db::Vector &disp_cache, const db::Vector &new_disp);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,3 +340,210 @@ TEST(1_DeviceAndNetExtraction)
|
|||
|
||||
db::compare_layouts (_this, ly, au);
|
||||
}
|
||||
|
||||
TEST(2_DeviceAndNetExtractionFlat)
|
||||
{
|
||||
db::Layout ly (true);
|
||||
db::LayerMap lmap;
|
||||
|
||||
unsigned int nwell = define_layer (ly, lmap, 1);
|
||||
unsigned int active = define_layer (ly, lmap, 2);
|
||||
unsigned int poly = define_layer (ly, lmap, 3);
|
||||
unsigned int poly_lbl = define_layer (ly, lmap, 3, 1);
|
||||
unsigned int diff_cont = define_layer (ly, lmap, 4);
|
||||
unsigned int poly_cont = define_layer (ly, lmap, 5);
|
||||
unsigned int metal1 = define_layer (ly, lmap, 6);
|
||||
unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1);
|
||||
unsigned int via1 = define_layer (ly, lmap, 7);
|
||||
unsigned int metal2 = define_layer (ly, lmap, 8);
|
||||
unsigned int metal2_lbl = define_layer (ly, lmap, 8, 1);
|
||||
|
||||
{
|
||||
db::LoadLayoutOptions options;
|
||||
options.get_options<db::CommonReaderOptions> ().layer_map = lmap;
|
||||
options.get_options<db::CommonReaderOptions> ().create_other_layers = false;
|
||||
|
||||
std::string fn (tl::testsrc ());
|
||||
fn = tl::combine_path (fn, "testdata");
|
||||
fn = tl::combine_path (fn, "algo");
|
||||
fn = tl::combine_path (fn, "device_extract_l1.gds");
|
||||
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (ly, options);
|
||||
ly.flatten (ly.cell (*ly.begin_top_down ()), -1, true);
|
||||
}
|
||||
|
||||
db::Cell &tc = ly.cell (*ly.begin_top_down ());
|
||||
|
||||
db::DeepShapeStore dss;
|
||||
dss.set_text_enlargement (1);
|
||||
dss.set_text_property_name (tl::Variant ("LABEL"));
|
||||
|
||||
// original layers
|
||||
db::Region rnwell (db::RecursiveShapeIterator (ly, tc, nwell), dss);
|
||||
db::Region ractive (db::RecursiveShapeIterator (ly, tc, active), dss);
|
||||
db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss);
|
||||
db::Region rpoly_lbl (db::RecursiveShapeIterator (ly, tc, poly_lbl), dss);
|
||||
db::Region rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss);
|
||||
db::Region rpoly_cont (db::RecursiveShapeIterator (ly, tc, poly_cont), dss);
|
||||
db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss);
|
||||
db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss);
|
||||
db::Region rvia1 (db::RecursiveShapeIterator (ly, tc, via1), dss);
|
||||
db::Region rmetal2 (db::RecursiveShapeIterator (ly, tc, metal2), dss);
|
||||
db::Region rmetal2_lbl (db::RecursiveShapeIterator (ly, tc, metal2_lbl), dss);
|
||||
|
||||
// derived regions
|
||||
|
||||
db::Region rpactive = ractive & rnwell;
|
||||
db::Region rpgate = rpactive & rpoly;
|
||||
db::Region rpsd = rpactive - rpgate;
|
||||
|
||||
db::Region rnactive = ractive - rnwell;
|
||||
db::Region rngate = rnactive & rpoly;
|
||||
db::Region rnsd = rnactive - rngate;
|
||||
|
||||
// return the computed layers into the original layout and write it for debugging purposes
|
||||
|
||||
unsigned int lgate = ly.insert_layer (db::LayerProperties (10, 0)); // 10/0 -> Gate
|
||||
unsigned int lsd = ly.insert_layer (db::LayerProperties (11, 0)); // 11/0 -> Source/Drain
|
||||
unsigned int lpdiff = ly.insert_layer (db::LayerProperties (12, 0)); // 12/0 -> P Diffusion
|
||||
unsigned int lndiff = ly.insert_layer (db::LayerProperties (13, 0)); // 13/0 -> N Diffusion
|
||||
|
||||
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);
|
||||
|
||||
// perform the extraction
|
||||
|
||||
db::Netlist nl;
|
||||
db::hier_clusters<db::PolygonRef> cl;
|
||||
|
||||
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
|
||||
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
|
||||
|
||||
db::NetlistDeviceExtractor::input_layers dl;
|
||||
|
||||
dl["SD"] = &rpsd;
|
||||
dl["G"] = &rpgate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
pmos_ex.extract (dss, dl, nl, cl);
|
||||
|
||||
dl["SD"] = &rnsd;
|
||||
dl["G"] = &rngate;
|
||||
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
|
||||
nmos_ex.extract (dss, dl, nl, cl);
|
||||
|
||||
// perform the net extraction
|
||||
|
||||
db::NetlistExtractor net_ex;
|
||||
|
||||
db::Connectivity conn;
|
||||
// Intra-layer
|
||||
conn.connect (rpsd);
|
||||
conn.connect (rnsd);
|
||||
conn.connect (rpoly);
|
||||
conn.connect (rdiff_cont);
|
||||
conn.connect (rpoly_cont);
|
||||
conn.connect (rmetal1);
|
||||
conn.connect (rvia1);
|
||||
conn.connect (rmetal2);
|
||||
// Inter-layer
|
||||
conn.connect (rpsd, rdiff_cont);
|
||||
conn.connect (rnsd, rdiff_cont);
|
||||
conn.connect (rpoly, rpoly_cont);
|
||||
conn.connect (rpoly_cont, rmetal1);
|
||||
conn.connect (rdiff_cont, rmetal1);
|
||||
conn.connect (rmetal1, rvia1);
|
||||
conn.connect (rvia1, rmetal2);
|
||||
conn.connect (rpoly, rpoly_lbl); // attaches labels
|
||||
conn.connect (rmetal1, rmetal1_lbl); // attaches labels
|
||||
conn.connect (rmetal2, rmetal2_lbl); // attaches labels
|
||||
|
||||
// extract the nets
|
||||
|
||||
net_ex.extract_nets (dss, conn, nl, cl);
|
||||
|
||||
// debug layers produced for nets
|
||||
// 202/0 -> Active
|
||||
// 203/0 -> Poly
|
||||
// 204/0 -> Diffusion contacts
|
||||
// 205/0 -> Poly contacts
|
||||
// 206/0 -> Metal1
|
||||
// 207/0 -> Via1
|
||||
// 208/0 -> Metal2
|
||||
// 210/0 -> N source/drain
|
||||
// 211/0 -> P source/drain
|
||||
std::map<unsigned int, unsigned int> dump_map;
|
||||
dump_map [layer_of (rpsd) ] = ly.insert_layer (db::LayerProperties (210, 0));
|
||||
dump_map [layer_of (rnsd) ] = ly.insert_layer (db::LayerProperties (211, 0));
|
||||
dump_map [layer_of (rpoly) ] = ly.insert_layer (db::LayerProperties (203, 0));
|
||||
dump_map [layer_of (rdiff_cont)] = ly.insert_layer (db::LayerProperties (204, 0));
|
||||
dump_map [layer_of (rpoly_cont)] = ly.insert_layer (db::LayerProperties (205, 0));
|
||||
dump_map [layer_of (rmetal1) ] = ly.insert_layer (db::LayerProperties (206, 0));
|
||||
dump_map [layer_of (rvia1) ] = ly.insert_layer (db::LayerProperties (207, 0));
|
||||
dump_map [layer_of (rmetal2) ] = ly.insert_layer (db::LayerProperties (208, 0));
|
||||
|
||||
// write nets to layout
|
||||
db::CellMapping cm = dss.cell_mapping_to_original (0, &ly, tc.cell_index ());
|
||||
dump_nets_to_layout (nl, cl, ly, dump_map, cm);
|
||||
|
||||
// compare netlist as string
|
||||
// NOTE: some of the nets are called IN,OUT but are different ones. They
|
||||
// happen to be the same because they share the same label.
|
||||
EXPECT_EQ (nl.to_string (),
|
||||
"Circuit RINGO ():\n"
|
||||
" DPMOS $1 (S='IN,FB',G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $2 (S=VDD,G='IN,FB',D='OUT,OSC') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $3 (S=$18,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $4 (S=VDD,G=$18,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $5 (S=$16,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $6 (S=VDD,G=$16,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $7 (S=$14,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $8 (S=VDD,G=$14,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $9 (S=$12,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $10 (S=VDD,G=$12,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $11 (S=$4,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $12 (S=VDD,G=$4,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $13 (S=$8,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $14 (S=VDD,G=$8,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $15 (S=$6,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $16 (S=VDD,G=$6,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $17 (S=$2,G='IN,FB',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $18 (S=VDD,G=$2,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DPMOS $19 (S=$10,G='IN,OUT',D=VDD) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DPMOS $20 (S=VDD,G=$10,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $21 (S='IN,FB',G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $22 (S=VSS,G='IN,FB',D='OUT,OSC') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $23 (S=$16,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $24 (S=VSS,G=$16,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $25 (S=$14,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $26 (S=VSS,G=$14,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $27 (S=$12,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $28 (S=VSS,G=$12,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $29 (S=$4,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $30 (S=VSS,G=$4,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $31 (S=$18,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $32 (S=VSS,G=$18,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $33 (S=$2,G='IN,FB',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $34 (S=VSS,G=$2,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $35 (S=$10,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $36 (S=VSS,G=$10,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $37 (S=$6,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $38 (S=VSS,G=$6,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
" DNMOS $39 (S=$8,G='IN,OUT',D=VSS) [L=0.25,W=0.95,AS=0.49875,AD=0.26125]\n"
|
||||
" DNMOS $40 (S=VSS,G=$8,D='IN,OUT') [L=0.25,W=0.95,AS=0.26125,AD=0.49875]\n"
|
||||
);
|
||||
|
||||
// compare the collected test data
|
||||
|
||||
std::string au = tl::testsrc ();
|
||||
au = tl::combine_path (au, "testdata");
|
||||
au = tl::combine_path (au, "algo");
|
||||
au = tl::combine_path (au, "device_extract_au1_flat.gds");
|
||||
|
||||
db::compare_layouts (_this, ly, au);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue