WIP: diode extraction test.

This commit is contained in:
Matthias Koefferlein 2019-06-15 09:34:04 +02:00
parent c717eb1efa
commit 1b2a611d83
6 changed files with 144 additions and 4 deletions

View File

@ -377,7 +377,7 @@ void NetlistDeviceExtractorCapacitor::extract_devices (const std::vector<db::Reg
modify_device (*p, layer_geometry, device);
// output the device for debugging
device_out (device, db::Region (*p));
device_out (device, *p);
}
}
@ -573,7 +573,7 @@ void NetlistDeviceExtractorDiode::extract_devices (const std::vector<db::Region>
modify_device (*p, layer_geometry, device);
// output the device for debugging
device_out (device, db::Region (*p));
device_out (device, *p);
}
}

View File

@ -193,7 +193,7 @@ protected:
* @brief A callback when the device is produced
* This callback is provided as a debugging port
*/
virtual void device_out (const db::Device * /*device*/, const db::Region & /*cap_area*/)
virtual void device_out (const db::Device * /*device*/, const db::Polygon & /*cap_area*/)
{
// .. no specific implementation ..
}
@ -308,7 +308,7 @@ protected:
* @brief A callback when the device is produced
* This callback is provided as a debugging port
*/
virtual void device_out (const db::Device * /*device*/, const db::Region & /*diode_area*/)
virtual void device_out (const db::Device * /*device*/, const db::Polygon & /*diode_area*/)
{
// .. no specific implementation ..
}

View File

@ -105,6 +105,7 @@ NetlistExtractor::extract_nets (const db::DeepShapeStore &dss, unsigned int layo
db::DeviceAbstract *dm = nl.device_abstract_by_cell_index (*cid);
if (dm) {
// This is a device abstract cell:
// make the terminal to cluster ID connections for the device abstract from the device cells
make_device_abstract_connections (dm, clusters);
continue;
@ -212,6 +213,14 @@ NetlistExtractor::make_device_abstract_connections (db::DeviceAbstract *dm, cons
}
}
// check whether all connections have been made
const std::vector<db::DeviceTerminalDefinition> &td = dm->device_class ()->terminal_definitions ();
for (std::vector<db::DeviceTerminalDefinition>::const_iterator t = td.begin (); t != td.end (); ++t) {
if (! dm->cluster_id_for_terminal (t->id ())) {
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Terminal '%s' of a device of class '%s' isn't connected - maybe the terminal annotation layer of this device type isn't part of the connectivity?")), t->name (), dm->device_class ()->name ()));
}
}
}
void NetlistExtractor::collect_labels (const connected_clusters_type &clusters,

View File

@ -1597,3 +1597,134 @@ TEST(6_BipolarTransistorExtraction)
db::compare_layouts (_this, ly, au);
}
TEST(7_DiodeExtraction)
{
db::Layout ly;
db::LayerMap lmap;
unsigned int nwell = define_layer (ly, lmap, 1);
unsigned int active = define_layer (ly, lmap, 2);
unsigned int diff_cont = define_layer (ly, lmap, 4);
unsigned int metal1 = define_layer (ly, lmap, 6);
unsigned int metal1_lbl = define_layer (ly, lmap, 6, 1);
unsigned int pplus = define_layer (ly, lmap, 9);
unsigned int nplus = define_layer (ly, lmap, 10);
{
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, "diode_devices_test.oas");
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 rdiff_cont (db::RecursiveShapeIterator (ly, tc, diff_cont), dss);
db::Region rmetal1 (db::RecursiveShapeIterator (ly, tc, metal1), dss);
db::Region rmetal1_lbl (db::RecursiveShapeIterator (ly, tc, metal1_lbl), dss);
db::Region rpplus (db::RecursiveShapeIterator (ly, tc, pplus), dss);
db::Region rnplus (db::RecursiveShapeIterator (ly, tc, nplus), dss);
// derived regions
db::Region rn = ractive & rnwell;
db::Region rntie = rnwell & rnplus;
// return the computed layers into the original layout and write it for debugging purposes
unsigned int ln = ly.insert_layer (db::LayerProperties (10, 0)); // 10/0 -> N layer
unsigned int lntie = ly.insert_layer (db::LayerProperties (11, 0)); // 11/0 -> N contact
rn.insert_into (&ly, tc.cell_index (), ln);
rntie.insert_into (&ly, tc.cell_index (), lntie);
// perform the extraction
db::Netlist nl;
db::hier_clusters<db::PolygonRef> cl;
db::NetlistDeviceExtractorDiode diode_ex ("DIODE");
db::NetlistDeviceExtractor::input_layers dl;
dl["N"] = &rn;
dl["P"] = &rpplus;
dl["tC"] = &rnwell;
diode_ex.extract (dss, 0, dl, nl, cl);
// perform the net extraction
db::NetlistExtractor net_ex;
db::Connectivity conn;
// Intra-layer
conn.connect (rnwell);
conn.connect (rntie);
conn.connect (rpplus);
conn.connect (rdiff_cont);
conn.connect (rmetal1);
// Inter-layer
conn.connect (rntie, rnwell);
conn.connect (rntie, rdiff_cont);
conn.connect (rpplus, rdiff_cont);
conn.connect (rdiff_cont, rmetal1);
conn.connect (rmetal1, rmetal1_lbl); // attaches labels
// extract the nets
net_ex.extract_nets (dss, 0, conn, nl, cl, "*");
// cleanup + completion
nl.combine_devices ();
nl.make_top_level_pins ();
nl.purge ();
EXPECT_EQ (all_net_names_unique (nl), true);
// debug layers produced for nets
// 201/0 -> n well
// 204/0 -> Diffusion contacts
// 206/0 -> Metal1
// 210/0 -> N tiedown
std::map<unsigned int, unsigned int> dump_map;
dump_map [layer_of (rntie) ] = ly.insert_layer (db::LayerProperties (210, 0));
dump_map [layer_of (rnwell) ] = ly.insert_layer (db::LayerProperties (201, 0));
dump_map [layer_of (rdiff_cont)] = ly.insert_layer (db::LayerProperties (204, 0));
dump_map [layer_of (rmetal1) ] = ly.insert_layer (db::LayerProperties (206, 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, true /*with device cells*/);
// compare netlist as string
CHECKPOINT ();
db::compare_netlist (_this, nl,
"circuit TOP (A=A,C=C);\n"
" device DIODE $1 (A=A,C=C) (A=9.18,P=21);\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, "diode_devices_nets.gds");
db::compare_layouts (_this, ly, au);
}

BIN
testdata/algo/diode_devices_nets.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/diode_devices_test.oas vendored Normal file

Binary file not shown.