From 1131532e4f5821a53f5ab58865490914323e1a29 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 17 Nov 2019 22:45:36 +0100 Subject: [PATCH 1/2] First implementation, needs testing. --- src/db/db/dbNetlistDeviceExtractor.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/db/db/dbNetlistDeviceExtractor.cc b/src/db/db/dbNetlistDeviceExtractor.cc index aa5b9f84a..7bc0d4caf 100644 --- a/src/db/db/dbNetlistDeviceExtractor.cc +++ b/src/db/db/dbNetlistDeviceExtractor.cc @@ -481,6 +481,10 @@ void NetlistDeviceExtractor::extract_devices (const std::vector & /* void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class) { + std::auto_ptr holder (device_class); + tl_assert (device_class != 0); + tl_assert (m_netlist.get () != 0); + if (mp_device_class != 0) { throw tl::Exception (tl::to_string (tr ("Device class already set"))); } @@ -488,12 +492,22 @@ void NetlistDeviceExtractor::register_device_class (DeviceClass *device_class) throw tl::Exception (tl::to_string (tr ("No device extractor/device class name set"))); } - tl_assert (device_class != 0); - mp_device_class = device_class; - mp_device_class->set_name (m_name); + DeviceClass *existing = m_netlist->device_class_by_name (m_name); + if (existing) { - tl_assert (m_netlist.get () != 0); - m_netlist->add_device_class (device_class); + if (typeid (*existing) != typeid (*device_class)) { + throw tl::Exception (tl::to_string (tr ("Different device class already registered with the same name"))); + } + mp_device_class = existing; + + } else { + + mp_device_class = holder.get (); + mp_device_class->set_name (m_name); + + m_netlist->add_device_class (holder.release ()); + + } } const db::NetlistDeviceExtractorLayerDefinition &NetlistDeviceExtractor::define_layer (const std::string &name, const std::string &description) From 990961e5f44bd0fdb3830382f87df9fb9279515a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 17 Nov 2019 23:12:50 +0100 Subject: [PATCH 2/2] Fixed #411 (multiple device extractors for same class) --- src/db/unit_tests/dbNetlistExtractorTests.cc | 107 +++++++++++++++++++ testdata/algo/device_extract_l11.gds | Bin 0 -> 1130 bytes 2 files changed, 107 insertions(+) create mode 100644 testdata/algo/device_extract_l11.gds diff --git a/src/db/unit_tests/dbNetlistExtractorTests.cc b/src/db/unit_tests/dbNetlistExtractorTests.cc index e04637320..1dbdd0b25 100644 --- a/src/db/unit_tests/dbNetlistExtractorTests.cc +++ b/src/db/unit_tests/dbNetlistExtractorTests.cc @@ -2303,3 +2303,110 @@ TEST(10_DeviceExtractionWithBreakoutCells) db::compare_layouts (_this, ly, au); } + +TEST(11_DeviceExtractionWithSameClass) +{ + db::Layout ly; + db::LayerMap lmap; + + unsigned int rmarker = define_layer (ly, lmap, 1); + unsigned int poly = define_layer (ly, lmap, 2); + unsigned int diff = define_layer (ly, lmap, 3); + unsigned int contact = define_layer (ly, lmap, 4); + unsigned int metal = define_layer (ly, lmap, 5); + + { + db::LoadLayoutOptions options; + options.get_options ().layer_map = lmap; + options.get_options ().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_l11.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 rrmarker (db::RecursiveShapeIterator (ly, tc, rmarker), dss); + db::Region rpoly (db::RecursiveShapeIterator (ly, tc, poly), dss); + db::Region rdiff (db::RecursiveShapeIterator (ly, tc, diff), dss); + db::Region rcontact (db::RecursiveShapeIterator (ly, tc, contact), dss); + db::Region rmetal (db::RecursiveShapeIterator (ly, tc, metal), dss); + + // derived regions + + db::Region rpoly_cap = rpoly - rrmarker; + db::Region rpoly_res = rpoly & rrmarker; + db::Region rdiff_cap = rdiff - rrmarker; + db::Region rdiff_res = rdiff & rrmarker; + + // perform the extraction + + db::Netlist nl; + db::hier_clusters cl; + + db::NetlistDeviceExtractorResistor polyres_ex ("RES", 50.0); + db::NetlistDeviceExtractorResistor diffres_ex ("RES", 150.0); + + db::NetlistDeviceExtractor::input_layers dl; + dl["R"] = &rpoly_res; + dl["C"] = &rpoly_cap; + polyres_ex.extract (dss, 0, dl, nl, cl); + + dl.clear (); + dl["R"] = &rdiff_res; + dl["C"] = &rdiff_cap; + diffres_ex.extract (dss, 0, dl, nl, cl); + + // perform the net extraction + + db::NetlistExtractor net_ex; + + db::Connectivity conn; + // Intra-layer + conn.connect (rpoly_cap); + conn.connect (rdiff_cap); + conn.connect (rcontact); + // Inter-layer + conn.connect (rpoly_cap, rcontact); + conn.connect (rdiff_cap, rcontact); + conn.connect (rmetal, rcontact); + + // extract the nets + + net_ex.extract_nets (dss, 0, conn, nl, cl); + + std::string nl_au_string = + "circuit TOP ();\n" + " device RES $1 (A=$1,B=$2) (R=175,L=2.8,W=0.8,A=0.56,P=3.6);\n" + " device RES $2 (A=$2,B=$3) (R=175,L=2.8,W=0.8,A=0.56,P=3.6);\n" + " device RES $3 (A=$3,B=$4) (R=525,L=2.8,W=0.8,A=0.56,P=3.6);\n" + "end;\n" + ; + + // compare netlist as string + CHECKPOINT (); + db::compare_netlist (_this, nl, nl_au_string); + + nl.combine_devices (); + + std::string nl_au_string_post = + "circuit TOP ();\n" + " device RES $3 (A=$1,B=$4) (R=875,L=8.4,W=0.8,A=1.68,P=10.8);\n" + "end;\n" + ; + + // compare netlist as string + CHECKPOINT (); + db::compare_netlist (_this, nl, nl_au_string_post); +} diff --git a/testdata/algo/device_extract_l11.gds b/testdata/algo/device_extract_l11.gds new file mode 100644 index 0000000000000000000000000000000000000000..23e65f7d82c64656777a136f3dc78aa7d3bfec89 GIT binary patch literal 1130 zcmaKry-EW?6opS_H=At4O$0aOuSmo)U=vV51SO3qXptgVrSJhPQl_*KEbO&Nr;m^# zWssD42b+{BEX6ppmxB`)XPa+1dp>5Eor?fU_0h>nn4lf9L*EfKl2ZC*d41!1jXqP;oI9{)R?hS#=GZ0ru<_Z0s zfBbr1diB0|%>~Ka?R!h37Y)TLo{-Gl zeyuINT3fu@7s=f1hcoGgGw}*fBy+bPkE9om#4C46=5D{$kzT7KUhA7=p7OKy`2+g9 zzCX#M|DU;s=0BQyDS1Ns{5Sk?AU$($jc4Xa$lUG673rC|GoG0vA#=CiTu9H%o$>Z3 MB=bK%r)Sv5FK>+c>;M1& literal 0 HcmV?d00001