Tests for texts as net names, fixed Shapes test (order of texts)

This commit is contained in:
Matthias Koefferlein 2020-05-20 01:05:19 +02:00
parent cd0b86b1dc
commit e9af72ee28
6 changed files with 277 additions and 16 deletions

View File

@ -25,7 +25,13 @@
#include "dbCellMapping.h"
#include "dbLayoutUtils.h"
#include "dbRegion.h"
#include "dbEdges.h"
#include "dbEdgePairs.h"
#include "dbTexts.h"
#include "dbDeepRegion.h"
#include "dbDeepEdges.h"
#include "dbDeepEdgePairs.h"
#include "dbDeepTexts.h"
#include "tlTimer.h"
@ -48,6 +54,30 @@ DeepLayer::DeepLayer (const Region &region)
*this = dr->deep_layer ();
}
DeepLayer::DeepLayer (const Texts &texts)
: mp_store (), m_layout (0), m_layer (0)
{
const db::DeepTexts *dr = dynamic_cast<db::DeepTexts *> (texts.delegate ());
tl_assert (dr != 0);
*this = dr->deep_layer ();
}
DeepLayer::DeepLayer (const Edges &edges)
: mp_store (), m_layout (0), m_layer (0)
{
const db::DeepEdges *dr = dynamic_cast<db::DeepEdges *> (edges.delegate ());
tl_assert (dr != 0);
*this = dr->deep_layer ();
}
DeepLayer::DeepLayer (const EdgePairs &edge_pairs)
: mp_store (), m_layout (0), m_layer (0)
{
const db::DeepEdgePairs *dr = dynamic_cast<db::DeepEdgePairs *> (edge_pairs.delegate ());
tl_assert (dr != 0);
*this = dr->deep_layer ();
}
DeepLayer::DeepLayer (const DeepLayer &x)
: mp_store (x.mp_store), m_layout (x.m_layout), m_layer (x.m_layer)
{

View File

@ -43,6 +43,8 @@ class DeepShapeStore;
class DeepShapeStoreState;
class Region;
class Edges;
class EdgePairs;
class Texts;
/**
* @brief Represents a shape collection from the deep shape store
@ -75,6 +77,24 @@ public:
*/
DeepLayer (const Region &region);
/**
* @brief Conversion operator from texts collection to DeepLayer
* This requires the texts to be a DeepTexts. Otherwise, this constructor will assert
*/
DeepLayer (const Texts &region);
/**
* @brief Conversion operator from edges collection to DeepLayer
* This requires the edges to be a DeepEdges. Otherwise, this constructor will assert
*/
DeepLayer (const Edges &region);
/**
* @brief Conversion operator from edge pairs collection to DeepLayer
* This requires the edge pairs to be a DeepEdgePairs. Otherwise, this constructor will assert
*/
DeepLayer (const EdgePairs &region);
/**
* @brief Copy constructor
*/

View File

@ -25,10 +25,11 @@
#include "dbNetlistExtractor.h"
#include "dbNetlistDeviceClasses.h"
#include "dbLayout.h"
#include "dbDeepShapeStore.h"
#include "dbRegion.h"
#include "dbTexts.h"
#include "dbStream.h"
#include "dbDeepRegion.h"
#include "dbDeepTexts.h"
#include "dbDeepShapeStore.h"
#include "dbReader.h"
#include "dbWriter.h"
@ -52,6 +53,13 @@ static unsigned int layer_of (const db::Region &region)
return dr->deep_layer ().layer ();
}
static unsigned int layer_of (const db::Texts &region)
{
const db::DeepTexts *dr = dynamic_cast<const db::DeepTexts *> (region.delegate ());
tl_assert (dr != 0);
return dr->deep_layer ().layer ();
}
static unsigned int define_layer (db::Layout &ly, db::LayerMap &lmap, int gds_layer, int gds_datatype = 0)
{
unsigned int lid = ly.insert_layer (db::LayerProperties (gds_layer, gds_datatype));
@ -291,14 +299,17 @@ TEST(1_DeviceAndNetExtraction)
// 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));
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 (rpoly_lbl) ] = ly.insert_layer (db::LayerProperties (203, 1));
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 (rmetal1_lbl) ] = ly.insert_layer (db::LayerProperties (206, 1));
dump_map [layer_of (rvia1) ] = ly.insert_layer (db::LayerProperties (207, 0));
dump_map [layer_of (rmetal2) ] = ly.insert_layer (db::LayerProperties (208, 0));
dump_map [layer_of (rmetal2_lbl) ] = ly.insert_layer (db::LayerProperties (208, 1));
// write nets to layout
db::CellMapping cm = dss.cell_mapping_to_original (0, &ly, tc.cell_index ());
@ -371,6 +382,206 @@ TEST(1_DeviceAndNetExtraction)
" device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
"end;\n"
);
// 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.gds");
db::compare_layouts (_this, ly, au);
}
TEST(1a_DeviceAndNetExtractionWithTextsAsLabels)
{
db::Layout ly;
db::LayerMap lmap;
unsigned int nwell = define_layer (ly, lmap, 1);
unsigned int active = define_layer (ly, lmap, 2);
unsigned int poly = define_layer (ly, lmap, 3);
unsigned int poly_lbl = define_layer (ly, lmap, 3, 1);
unsigned int diff_cont = define_layer (ly, lmap, 4);
unsigned int poly_cont = define_layer (ly, lmap, 5);
unsigned int metal1 = define_layer (ly, lmap, 6);
unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1);
unsigned int via1 = define_layer (ly, lmap, 7);
unsigned int metal2 = define_layer (ly, lmap, 8);
unsigned int metal2_lbl = define_layer (ly, lmap, 8, 1);
{
db::LoadLayoutOptions options;
options.get_options<db::CommonReaderOptions> ().layer_map = lmap;
options.get_options<db::CommonReaderOptions> ().create_other_layers = false;
std::string fn (tl::testsrc ());
fn = tl::combine_path (fn, "testdata");
fn = tl::combine_path (fn, "algo");
fn = tl::combine_path (fn, "device_extract_l1.gds");
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly, options);
}
db::Cell &tc = ly.cell (*ly.begin_top_down ());
db::DeepShapeStore dss;
dss.set_text_enlargement (1);
dss.set_text_property_name (tl::Variant ("LABEL"));
// original layers
db::Region rnwell (db::RecursiveShapeIterator (ly, tc, nwell), dss);
db::Region ractive (db::RecursiveShapeIterator (ly, tc, active), dss);
db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss);
db::Texts 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::Texts 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::Texts 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::NetShape> cl;
db::NetlistDeviceExtractorMOS3Transistor pmos_ex ("PMOS");
db::NetlistDeviceExtractorMOS3Transistor nmos_ex ("NMOS");
db::NetlistDeviceExtractor::input_layers dl;
dl["SD"] = &rpsd;
dl["G"] = &rpgate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
pmos_ex.extract (dss, 0, dl, nl, cl);
dl["SD"] = &rnsd;
dl["G"] = &rngate;
dl["P"] = &rpoly; // not needed for extraction but to return terminal shapes
nmos_ex.extract (dss, 0, dl, nl, cl);
// perform the net extraction
db::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, 0, 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 (rpoly_lbl) ] = ly.insert_layer (db::LayerProperties (203, 1));
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 (rmetal1_lbl) ] = ly.insert_layer (db::LayerProperties (206, 1));
dump_map [layer_of (rvia1) ] = ly.insert_layer (db::LayerProperties (207, 0));
dump_map [layer_of (rmetal2) ] = ly.insert_layer (db::LayerProperties (208, 0));
dump_map [layer_of (rmetal2_lbl) ] = ly.insert_layer (db::LayerProperties (208, 1));
// 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
CHECKPOINT ();
db::compare_netlist (_this, nl,
"circuit RINGO ();\n"
" subcircuit INV2 $1 (IN=$I8,$2=FB,OUT=OSC,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $2 (IN=FB,$2=$I38,OUT=$I19,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $3 (IN=$I19,$2=$I39,OUT=$I1,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $4 (IN=$I1,$2=$I40,OUT=$I2,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $5 (IN=$I2,$2=$I41,OUT=$I3,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $6 (IN=$I3,$2=$I42,OUT=$I4,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $7 (IN=$I4,$2=$I43,OUT=$I5,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $8 (IN=$I5,$2=$I44,OUT=$I6,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $9 (IN=$I6,$2=$I45,OUT=$I7,$4=VSS,$5=VDD);\n"
" subcircuit INV2 $10 (IN=$I7,$2=$I46,OUT=$I8,$4=VSS,$5=VDD);\n"
"end;\n"
"circuit INV2 (IN=IN,$2=$2,OUT=OUT,$4=$4,$5=$5);\n"
" device PMOS $1 (S=$2,G=IN,D=$5) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device PMOS $2 (S=$5,G=$2,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
" device NMOS $3 (S=$2,G=IN,D=$4) (L=0.25,W=0.95,AS=0.49875,AD=0.26125,PS=2.95,PD=1.5);\n"
" device NMOS $4 (S=$4,G=$2,D=OUT) (L=0.25,W=0.95,AS=0.26125,AD=0.49875,PS=1.5,PD=2.95);\n"
" subcircuit TRANS $1 ($1=$2,$2=$4,$3=IN);\n"
" subcircuit TRANS $2 ($1=$2,$2=$5,$3=IN);\n"
" subcircuit TRANS $3 ($1=$5,$2=OUT,$3=$2);\n"
" subcircuit TRANS $4 ($1=$4,$2=OUT,$3=$2);\n"
"end;\n"
"circuit TRANS ($1=$1,$2=$2,$3=$3);\n"
"end;\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_au1a.gds");
db::compare_layouts (_this, ly, au);
}
TEST(2_DeviceAndNetExtractionFlat)

View File

@ -1318,6 +1318,9 @@ TEST(5)
"text ('A',r0 10,35) #0\n"
"text ('B',r90 20,25) #0\n"
"text ('C',m90 30,15) #0\n"
"text ('A',r0 10,35) #1\n"
"text ('B',r90 20,25) #2\n"
"text ('C',m90 30,15) #3\n"
"text ('A',r0 0,50) #0\n"
"text ('B',r90 -90,140) #0\n"
"text ('C',m90 -180,230) #0\n"
@ -1333,9 +1336,6 @@ TEST(5)
"text ('A',r0 33010,40) #0\n"
"text ('A',r0 33010,10040) #0\n"
"text ('A',r0 33010,20040) #0\n"
"text ('A',r0 10,35) #1\n"
"text ('B',r90 20,25) #2\n"
"text ('C',m90 30,15) #3\n"
"text ('A',r0 0,50) #5\n"
"text ('B',r90 -90,140) #6\n"
"text ('C',m90 -180,230) #7\n"
@ -1357,10 +1357,13 @@ TEST(5)
for (db::Shapes::shape_iterator shape = topcell.shapes (lindex).begin (db::Shapes::shape_iterator::All); ! shape.at_end (); ++shape) {
sa_copy.insert (*shape);
}
EXPECT_EQ (shapes_to_string (_this, sa_copy),
EXPECT_EQ (shapes_to_string (_this, sa_copy),
"text ('A',r0 10,35) #0\n"
"text ('B',r90 20,25) #0\n"
"text ('C',m90 30,15) #0\n"
"text ('A',r0 10,35) #1\n"
"text ('B',r90 20,25) #2\n"
"text ('C',m90 30,15) #3\n"
"text ('A',r0 0,50) #0\n"
"text ('B',r90 -90,140) #0\n"
"text ('C',m90 -180,230) #0\n"
@ -1376,9 +1379,6 @@ TEST(5)
"text ('A',r0 33010,40) #0\n"
"text ('A',r0 33010,10040) #0\n"
"text ('A',r0 33010,20040) #0\n"
"text ('A',r0 10,35) #1\n"
"text ('B',r90 20,25) #2\n"
"text ('C',m90 30,15) #3\n"
"text ('A',r0 0,50) #5\n"
"text ('B',r90 -90,140) #6\n"
"text ('C',m90 -180,230) #7\n"

Binary file not shown.

BIN
testdata/algo/device_extract_au1a.gds vendored Normal file

Binary file not shown.