From 8e42c7b4e921695190e4a14522b1d005a078d66d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 9 Sep 2023 21:28:46 +0200 Subject: [PATCH 1/4] Fixed issue-1472 (strm2oas: def path with first/last segment length < halfwidth are read wrong) --- .../lefdef/db_plugin/dbDEFImporter.cc | 43 ++++++++++++++++-- .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 8 +++- testdata/lefdef/issue-1472/au.oas | Bin 0 -> 547 bytes testdata/lefdef/issue-1472/tech.lef.gz | Bin 0 -> 129 bytes testdata/lefdef/issue-1472/tech.map | 2 + testdata/lefdef/issue-1472/test.def.gz | Bin 0 -> 218 bytes 6 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 testdata/lefdef/issue-1472/au.oas create mode 100644 testdata/lefdef/issue-1472/tech.lef.gz create mode 100644 testdata/lefdef/issue-1472/tech.map create mode 100644 testdata/lefdef/issue-1472/test.def.gz diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index c36f6a114..873bf8dd1 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -424,17 +424,53 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u } } - if (options ().joined_paths ()) { + auto pt_from = pt0; + auto pt_to = pt + 1; + + // do not split away end segments if they are shorter than half the width + bool dont_join_first = false; + bool dont_join_last = false; + if (pt_to - pt_from >= 3 && (pt_from[1] - pt_from[0]).length() + be < wxy / 2) { + dont_join_first = true; + } + if (pt_to - pt_from >= 3 && (pt_to[-1] - pt_to[-2]).length() + ee < wxy / 2) { + dont_join_last = true; + } + + if (options ().joined_paths () || (dont_join_first && dont_join_last && pt_to - pt_from <= 4)) { + // single path - db::Path p (pt0, pt + 1, wxy, be, ee, false); + db::Path p (pt_from, pt_to, wxy, be, ee, false); if (prop_id != 0) { design.shapes (layer).insert (db::object_with_properties (p, prop_id)); } else { design.shapes (layer).insert (p); } + } else { + + if (dont_join_first) { + db::Path p (pt_from, pt_from + 3, wxy, be, pt_from + 2 != pt ? wxy / 2 : ee, false); + if (prop_id != 0) { + design.shapes (layer).insert (db::object_with_properties (p, prop_id)); + } else { + design.shapes (layer).insert (p); + } + pt_from += 2; + } + + if (dont_join_last) { + db::Path p (pt_to - 3, pt_to, wxy, pt_to - 3 != pt0 ? wxy / 2 : be, ee, false); + if (prop_id != 0) { + design.shapes (layer).insert (db::object_with_properties (p, prop_id)); + } else { + design.shapes (layer).insert (p); + } + pt_to -= 2; + } + // multipart paths - for (std::vector::const_iterator i = pt0; i != pt; ++i) { + for (auto i = pt_from; i + 1 != pt_to; ++i) { db::Path p (i, i + 2, wxy, i == pt0 ? be : wxy / 2, i + 1 != pt ? wxy / 2 : ee, false); if (prop_id != 0) { design.shapes (layer).insert (db::object_with_properties (p, prop_id)); @@ -442,6 +478,7 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u design.shapes (layer).insert (p); } } + } was_path_before = true; diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index a6c99e04d..82aa606f4 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -429,7 +429,7 @@ TEST(def16) // (complete example) db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au_2.oas.gz", opt); + run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au_3.oas.gz", opt); } TEST(100) @@ -1005,3 +1005,9 @@ TEST(208_nets_and_rects) run_test (_this, "issue-1432", "map:test.map+lef:test.lef+def:test.def", "au.oas", default_options (), false); } +// issue-1472 +TEST(209_invalid_split_paths) +{ + run_test (_this, "issue-1472", "map:tech.map+lef:tech.lef.gz+def:test.def.gz", "au.oas", default_options (), false); +} + diff --git a/testdata/lefdef/issue-1472/au.oas b/testdata/lefdef/issue-1472/au.oas new file mode 100644 index 0000000000000000000000000000000000000000..5b7f492968b0ca83033fc60ce0746a2b88c8b28f GIT binary patch literal 547 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKC?n3q!6L)YEF;ds&!EJR>XUoMnybM;fb~F; z;|1o9>4KX(8~>b$4qRRSKbqrK6n{_8gJqfl!9jtCZ5=b5TtyycO>kl0Wf1!p#5k9Uk%3W}v6!)mk&&TcWB~>S E0IWaVwEzGB literal 0 HcmV?d00001 diff --git a/testdata/lefdef/issue-1472/tech.lef.gz b/testdata/lefdef/issue-1472/tech.lef.gz new file mode 100644 index 0000000000000000000000000000000000000000..20f328c3b8470ffdc95f2b866987f61d4eacc20b GIT binary patch literal 129 zcmV-{0Dk`;iwFn_sQF|719W9$XfAAJW&nN6F$#b%3|L4G(3|zOM;)ID{<5^-z&{=B%MnhqNT$%A$NMIvH-`A3soj_t%4r`+= jZT4Us+)L-IjXlA4(fux7_WnIjf>O*0q0dK>xBvhEHvKx^ literal 0 HcmV?d00001 diff --git a/testdata/lefdef/issue-1472/tech.map b/testdata/lefdef/issue-1472/tech.map new file mode 100644 index 000000000..53bfddcd6 --- /dev/null +++ b/testdata/lefdef/issue-1472/tech.map @@ -0,0 +1,2 @@ +METAL3 SPNET 28 0 +METAL5 SPNET 33 0 diff --git a/testdata/lefdef/issue-1472/test.def.gz b/testdata/lefdef/issue-1472/test.def.gz new file mode 100644 index 0000000000000000000000000000000000000000..638a593c5218b12ebbd28e0201f962bfee22b15b GIT binary patch literal 218 zcmV<0044t)iwFq0#{6Ue19W9`bS`9NW&nMWKM#U15XJX?iZ_bJq|iT>I1$>ICRmMy zI6E-PBHurrpav7L)4SLE-CeKNMSlqB+eeQ*Yl5#MtdDgON{6E_FQ*WZa?a_N#j`7Y zQ3Xdyf(&fYwS9NHw+tIxPEGAB!_n16C6F186|~uLNKHDSXbqurHArccqBuct*Egfy zjG_aTW&Ahsg-iK$HDAD`p&XN|Ps^R*qf}ZfGgMB_bxc2V3{(A~vsqkBo-sCOv^W Date: Mon, 11 Sep 2023 21:16:36 +0200 Subject: [PATCH 2/4] Fixed more weird paths in issue-1472 --- .../lefdef/db_plugin/dbDEFImporter.cc | 47 ++++++++++++------ .../lefdef/unit_tests/dbLEFDEFImportTests.cc | 2 +- testdata/lefdef/issue-1472/au.oas | Bin 547 -> 573 bytes testdata/lefdef/issue-1472/test.def.gz | Bin 218 -> 253 bytes 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index cb5782e25..6224bab29 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -428,16 +428,31 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u auto pt_to = pt + 1; // do not split away end segments if they are shorter than half the width - bool dont_join_first = false; - bool dont_join_last = false; - if (pt_to - pt_from >= 3 && (pt_from[1] - pt_from[0]).length() + be < wxy / 2) { - dont_join_first = true; - } - if (pt_to - pt_from >= 3 && (pt_to[-1] - pt_to[-2]).length() + ee < wxy / 2) { - dont_join_last = true; + + auto pt_from_split = pt_from; + if (be < wxy / 2) { + while (pt_from_split + 1 != pt_to && db::Coord ((pt_from_split[1] - pt_from_split[0]).length ()) < wxy / 2) { + ++pt_from_split; + } } - if (options ().joined_paths () || (dont_join_first && dont_join_last && pt_to - pt_from <= 4)) { + auto pt_to_split = pt_to; + if (ee < wxy / 2) { + while (pt_to_split - 1 != pt_from && db::Coord ((pt_to_split[-1] - pt_to_split[-2]).length ()) < wxy / 2) { + --pt_to_split; + } + } + + if (! options ().joined_paths () && (pt_to_split != pt_to || pt_from_split != pt_from)) { + std::string p0 = pt_from->to_string (); + std::string ln = "(unknown)"; + if (design.layout ()) { + ln = design.layout ()->get_properties (layer).to_string (); + } + warn (tl::sprintf (tl::to_string (tr ("Joining path (or parts of it) because of short-edged begin or end segments (layer %s, first point %s)")), ln, p0)); + } + + if (options ().joined_paths () || pt_to_split - 1 <= pt_from_split + 1 || pt_to_split - 1 == pt_from || pt_from_split + 1 == pt_to) { // single path db::Path p (pt_from, pt_to, wxy, be, ee, false); @@ -449,24 +464,24 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u } else { - if (dont_join_first) { - db::Path p (pt_from, pt_from + 3, wxy, be, pt_from + 2 != pt ? wxy / 2 : ee, false); + if (pt_from_split != pt_from) { + db::Path p (pt_from, pt_from_split + 2, wxy, be, wxy / 2, false); if (prop_id != 0) { design.shapes (layer).insert (db::object_with_properties (p, prop_id)); } else { design.shapes (layer).insert (p); } - pt_from += 2; + pt_from = pt_from_split + 1; } - if (dont_join_last) { - db::Path p (pt_to - 3, pt_to, wxy, pt_to - 3 != pt0 ? wxy / 2 : be, ee, false); + if (pt_to_split != pt_to) { + db::Path p (pt_to_split - 2, pt_to, wxy, wxy / 2, ee, false); if (prop_id != 0) { design.shapes (layer).insert (db::object_with_properties (p, prop_id)); } else { design.shapes (layer).insert (p); } - pt_to -= 2; + pt_to = pt_to_split - 1; } // multipart paths @@ -486,7 +501,7 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u } else { if (! is_isotropic) { - warn("Anisotropic wire widths not supported for diagonal wires"); + warn (tl::to_string (tr ("Anisotropic wire widths not supported for diagonal wires"))); } db::Coord s = (w.first + 1) / 2; @@ -839,7 +854,7 @@ DEFImporter::read_nets (db::Layout &layout, db::Cell &design, double scale, bool stored_prop_id = prop_id; in_subnet = true; } else { - warn ("Nested subnets"); + warn (tl::to_string (tr ("Nested subnets"))); } net = stored_netname + "/" + subnetname; diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc index 30333d633..381914855 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImportTests.cc @@ -429,7 +429,7 @@ TEST(def16) // (complete example) db::LEFDEFReaderOptions opt = default_options (); opt.set_macro_resolution_mode (1); - run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au_3.oas.gz", opt); + run_test (_this, "def16", "lef:a.lef+lef:tech.lef+def:a.def", "au_4.oas.gz", opt); } TEST(100) diff --git a/testdata/lefdef/issue-1472/au.oas b/testdata/lefdef/issue-1472/au.oas index 5b7f492968b0ca83033fc60ce0746a2b88c8b28f..6ee5b43f415a19c59cc3b8398340065340f37375 100644 GIT binary patch delta 67 zcmV-J0KEUB1ib{1f(Ho&WOZ$Ad69xG9|Zvemm0k-KUNw*mnG0V4r(0g00@0rY$g5|97@ delta 50 zcmdnXvY2H;)5K0)9!>_v{qk$F?^(*IGfupk#XFaYk%3W}v6!)mk&$6?Amgja35={v G3=9B_{SAx& diff --git a/testdata/lefdef/issue-1472/test.def.gz b/testdata/lefdef/issue-1472/test.def.gz index 638a593c5218b12ebbd28e0201f962bfee22b15b..401f8e37442ad22e9c962e0fb1bee286520b2e6e 100644 GIT binary patch literal 253 zcmVEJ9a*W&xp3Zw)kLG3}u1~smx>HaR|lv7!xwiIo+~! z@X(TA zYvkyWqv=2k!Kc8EuGC{{_zSwSgt0q)m)u%Dl-kJG9C}X8DQ0&cy{k8DF-wiI838uI1$>ICRmMy zI6E-PBHurrpav7L)4SLE-CeKNMSlqB+eeQ*Yl5#MtdDgON{6E_FQ*WZa?a_N#j`7Y zQ3Xdyf(&fYwS9NHw+tIxPEGAB!_n16C6F186|~uLNKHDSXbqurHArccqBuct*Egfy zjG_aTW&Ahsg-iK$HDAD`p&XN|Ps^R*qf}ZfGgMB_bxc2V3{(A~vsqkBo-sCOv^W Date: Mon, 11 Sep 2023 23:34:52 +0200 Subject: [PATCH 3/4] Less verbose warnings on joined paths --- .../lefdef/db_plugin/dbDEFImporter.cc | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 6224bab29..11965e029 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -430,17 +430,22 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u // do not split away end segments if they are shorter than half the width auto pt_from_split = pt_from; - if (be < wxy / 2) { - while (pt_from_split + 1 != pt_to && db::Coord ((pt_from_split[1] - pt_from_split[0]).length ()) < wxy / 2) { - ++pt_from_split; - } - } - auto pt_to_split = pt_to; - if (ee < wxy / 2) { - while (pt_to_split - 1 != pt_from && db::Coord ((pt_to_split[-1] - pt_to_split[-2]).length ()) < wxy / 2) { - --pt_to_split; + + if (pt_to - pt_from > size_t (2)) { + + if (be < wxy / 2) { + while (pt_from_split + 1 != pt_to && db::Coord ((pt_from_split[1] - pt_from_split[0]).length ()) < wxy / 2) { + ++pt_from_split; + } } + + if (ee < wxy / 2) { + while (pt_to_split - 1 != pt_from && db::Coord ((pt_to_split[-1] - pt_to_split[-2]).length ()) < wxy / 2) { + --pt_to_split; + } + } + } if (! options ().joined_paths () && (pt_to_split != pt_to || pt_from_split != pt_from)) { From ddfa64c5172f58cecc5c48e1586f599f14b5c4f1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 12 Sep 2023 00:02:46 +0200 Subject: [PATCH 4/4] Warnings fixed --- src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index 11965e029..87c65c280 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -135,7 +135,7 @@ DEFImporter::get_wire_width_for_rule (const std::string &rulename, const std::st } std::pair -DEFImporter::get_def_ext (const std::string &ln, const std::pair &wxy, double dbu) +DEFImporter::get_def_ext (const std::string & /*ln*/, const std::pair &wxy, double /*dbu*/) { // This implementation assumes the "preferred width" is controlling the default extension and it is // identical to the minimum effective width. This is true if "LEF58_MINWIDTH" with "WRONGDIRECTION" is @@ -432,7 +432,7 @@ DEFImporter::produce_routing_geometry (db::Cell &design, const Polygon *style, u auto pt_from_split = pt_from; auto pt_to_split = pt_to; - if (pt_to - pt_from > size_t (2)) { + if (pt_to - pt_from > 2) { if (be < wxy / 2) { while (pt_from_split + 1 != pt_to && db::Coord ((pt_from_split[1] - pt_from_split[0]).length ()) < wxy / 2) {