From 716aa3c87b818de0cfb86ec601d8f7083842e326 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 1 Sep 2024 21:18:49 +0200 Subject: [PATCH 1/3] Fixing issue #1835 (saving a PCell as cell renders a layout that cannot be read) --- src/db/db/dbCommonReader.cc | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index 108a62851..2c1a876df 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -23,6 +23,7 @@ #include "dbCommonReader.h" +#include "dbColdProxy.h" #include "dbStream.h" #include "tlXMLParser.h" @@ -475,7 +476,7 @@ CommonReaderBase::finish (db::Layout &layout) } if (name) { - // need to rename: add a new madding to m_layer_map_out and adjust the layout's layer properties + // need to rename: add a new mapping to m_layer_map_out and adjust the layout's layer properties db::LayerProperties lpp = lp; join_layer_names (lpp.name, *name); layout.set_properties (*i, lpp); @@ -580,9 +581,32 @@ CommonReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) } // A cleanup may be necessary because of the following scenario: if library proxies contain subcells - // which are proxies itself, the proxy update may make them orphans (the proxies are regenerated). + // which are proxies themselves, the proxy update may make them orphans (the proxies are regenerated). // The cleanup will removed these. - layout.cleanup (); + + // Adressing issue #1835 (reading proxy-only GDS file renders empty layout) we do not delete + // the first (non-cold) proxy if there are only proxy top cells. + // We never clean up the top cell if there is a single one. This catches the case of having + // defunct proxies for top cells. + + std::set keep; + if (layout.end_top_cells () - layout.begin_top_down () == 1) { + keep.insert (*layout.begin_top_down ()); + } else { + for (auto c = layout.begin_top_down (); c != layout.end_top_cells (); ++c) { + const db::Cell *cptr = &layout.cell (*c); + if (cptr->is_proxy ()) { + if (! dynamic_cast (cptr) && keep.empty ()) { + keep.insert (*c); + } + } else { + keep.clear (); + break; + } + } + } + + layout.cleanup (keep); return layer_map_out (); } From bc78f4a0e9b039c3be31845ceecb7cbe0f64fa3f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 1 Sep 2024 21:26:25 +0200 Subject: [PATCH 2/3] Added test. --- .../gds2/unit_tests/dbGDS2ReaderTests.cc | 21 ++++++++++++++++++ testdata/gds/issue_1835.gds | Bin 0 -> 910 bytes testdata/gds/issue_1835_au.gds | Bin 0 -> 660 bytes 3 files changed, 21 insertions(+) create mode 100644 testdata/gds/issue_1835.gds create mode 100644 testdata/gds/issue_1835_au.gds diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc index c503bab0a..f9fca1052 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2ReaderTests.cc @@ -704,3 +704,24 @@ TEST(5_issue893) db::compare_layouts (_this, layout, fn_au, db::WriteGDS2, 1); } +// PCell saved as top cell +TEST(6_issue1835) +{ + db::Manager m (false); + db::Layout layout (&m); + + db::LoadLayoutOptions options; + + { + tl::InputStream file (tl::testdata () + "/gds/issue_1835.gds"); + db::Reader reader (file); + reader.read (layout, options); + } + + tl_assert (layout.begin_top_down () != layout.end_top_cells ()); + layout.convert_cell_to_static (*layout.begin_top_down ()); + + std::string fn_au (tl::testdata () + "/gds/issue_1835_au.gds"); + db::compare_layouts (_this, layout, fn_au, db::WriteGDS2, 1); +} + diff --git a/testdata/gds/issue_1835.gds b/testdata/gds/issue_1835.gds new file mode 100644 index 0000000000000000000000000000000000000000..ecd49c3f1379add9c7f09267d12e2f9e623561cf GIT binary patch literal 910 zcmaJ(F9m;t z7jI%OUInibdh|zl@aRRU*7P~^C5k=h!eickZ{9cG%q~2fTSqZ+>1P~4gk#9V|GmeE z^Nr;Tz*L+&cmBoc%e~iM&Rl#q|LWz9CW^U#-<$TnR4UchR-5(p=I!OxOKW^ZG71zX z{YtB|vhk$W>fUW{B43E{`|-yeJf_S3O0C{#R1fiVmb0_jhjZ1N_a5ADbsl9W7Rr@d z&{=|U-ka?{o~zExEWm0p@>Uy^#Bzg5hn2-s#)&W`PMba38&5a8*~$4~M_{rn_rp0F ztvf(6!Ik2_-V6S)!(@ch9Cggsk2}B(9fz=22_c*%W+5CrBVG%k|DL!_jETD;{Ja{% z_hJb9Z-`sOG2*unevq%Fz14Ik4!OFcyVgU!)RVnUgIcCpQRu8^gbz9gB69b(Ibof+ zOYEy35WgjE(fD=g5x+_s$dSK4MsuUmCO(%o@sqTHbV=Go&Urw7x+863Z}7p>kJ28z zN7PMsq)jB(^@&T;RzGR0zqE<`jdJ8`X>T>1i9@dL=&topFZE<^(~!0_rOhYp4QJwP zHX~=XnKe5-$cuTRH}fd3^epenKv`HO%7z(PR?JMagNmFijL=whvUetdc|Gmkh6BqJdy$!G|K!($QnnYD{% zwnQzP^)9JmKrwC%v6P zmNSck9?I0F?ty@{?K(T$(0giEen9j$v8gZoY4-mI^wtd$zDBM SX6#v)Mdo=C@i;9~t{A_8&<-~M literal 0 HcmV?d00001 From a4467cfd3e5766fe5cf2529f5b79bbb1d104a1d3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 1 Sep 2024 21:27:25 +0200 Subject: [PATCH 3/3] Fixed a small bug: when deleting the only top cell, you could not create new cells as an error was issued saying 'no layout present' --- src/layui/layui/layLayoutViewFunctions.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/layui/layui/layLayoutViewFunctions.cc b/src/layui/layui/layLayoutViewFunctions.cc index 7cbe98685..da5bdafad 100644 --- a/src/layui/layui/layLayoutViewFunctions.cc +++ b/src/layui/layui/layLayoutViewFunctions.cc @@ -1230,11 +1230,12 @@ LayoutViewFunctions::do_cm_paste (bool interactive) void LayoutViewFunctions::cm_new_cell () { - lay::CellView cv = view ()->cellview (view ()->active_cellview_index ()); - if (! cv.is_valid ()) { + if (view ()->active_cellview_index () < 0) { throw tl::Exception (tl::to_string (tr ("No layout present to add a cell to"))); } + lay::CellView cv = view ()->cellview (view ()->active_cellview_index ()); + static double s_new_cell_window_size = 2.0; static std::string s_new_cell_cell_name;