From 484ab91850c37ba631db8e045ed2a09eaca6612c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 19 Jul 2026 20:53:27 +0200 Subject: [PATCH] WIP: deep mode implementation of enhanced 2-layer check, tests --- src/db/db/dbAsIfFlatRegion.cc | 1 + src/db/db/dbDeepRegion.cc | 39 +++++++++++++++---------- src/drc/unit_tests/drcSimpleTests.cc | 10 +++++++ testdata/drc/drcSimpleTests_150.drc | 20 +++++++++++++ testdata/drc/drcSimpleTests_150.gds | Bin 0 -> 490 bytes testdata/drc/drcSimpleTests_au150.gds | Bin 0 -> 2218 bytes testdata/drc/drcSimpleTests_au150d.gds | Bin 0 -> 2218 bytes 7 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 testdata/drc/drcSimpleTests_150.drc create mode 100644 testdata/drc/drcSimpleTests_150.gds create mode 100644 testdata/drc/drcSimpleTests_au150.gds create mode 100644 testdata/drc/drcSimpleTests_au150d.gds diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index f253f4768..85111a923 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1185,6 +1185,7 @@ EdgePairsDelegate * AsIfFlatRegion::space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const { // NOTE: we have to use "foreign" to make sure every subject sees neighboring subjects + // @@@ use null ptr instead of foreign_regionptr return run_check (db::SpaceRelation, isolated, foreign_regionptr (), d, options); } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 8a984dfc7..235579f22 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -2368,48 +2368,57 @@ DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyCon EdgePairsDelegate * DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const { - // @@@ if (empty ()) { return new db::DeepEdgePairs (deep_layer ().derived ()); } else if (other && ! is_subject_regionptr (other) && other->empty () && ! options.negative) { return new db::DeepEdgePairs (deep_layer ().derived ()); } + bool has_other = other && other != subject_regionptr () && other != foreign_regionptr (); + // force different polygons in the different properties case to skip intra-polygon checks - if (pc_always_different (options.prop_constraint)) { + if (! has_other && pc_always_different (options.prop_constraint)) { // TODO: this forces merged primaries, so maybe that is not a good optimization? different_polygons = true; } const db::DeepRegion *other_deep = 0; - unsigned int other_layer = 0; bool other_is_merged = true; - bool needs_merged_primary = different_polygons || options.needs_merged (); + bool needs_merged_primary = (! has_other && different_polygons) || options.needs_merged (); bool primary_is_merged = ! merged_semantics () || needs_merged_primary || is_merged (); - if (other == subject_regionptr ()) { - other_layer = subject_idlayer (); - other_is_merged = primary_is_merged; - } else if (other == foreign_regionptr ()) { - other_layer = foreign_idlayer (); + std::vector other_layers; + + if (! has_other) { + + other_layers.push_back (other == foreign_regionptr () ? foreign_idlayer () : subject_idlayer ()); other_is_merged = primary_is_merged; + } else { + other_deep = dynamic_cast (other->delegate ()); if (! other_deep) { return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options); } + if (! other->merged_semantics ()) { - other_layer = other_deep->deep_layer ().layer (); + other_layers.push_back (other_deep->deep_layer ().layer ()); other_is_merged = true; } else if (options.whole_edges) { // NOTE: whole edges needs both inputs merged - other_layer = other_deep->merged_deep_layer ().layer (); + other_layers.push_back (other_deep->merged_deep_layer ().layer ()); other_is_merged = true; } else { - other_layer = other_deep->deep_layer ().layer (); + other_layers.push_back (other_deep->deep_layer ().layer ()); other_is_merged = other->is_merged (); } + + // adds another intruder section to implement subject merging ("primary_intruders") + if (! primary_is_merged) { + other_layers.push_back (foreign_idlayer ()); + } + } const db::DeepLayer &polygons = needs_merged_primary ? merged_deep_layer () : deep_layer (); @@ -2427,7 +2436,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons if (options.prop_constraint == db::IgnoreProperties) { - db::CheckLocalOperation op (check, different_polygons, primary_is_merged, other_deep != 0, other_is_merged, options); + db::CheckLocalOperation op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options); db::local_processor proc (subject_layout, subject_top, intruder_layout, intruder_top, @@ -2436,7 +2445,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons configure_proc (proc); proc.set_threads (polygons.store ()->threads ()); - proc.run (&op, polygons.layer (), other_layer, res->deep_layer ().layer ()); + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); } else { @@ -2449,7 +2458,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons configure_proc (proc); proc.set_threads (polygons.store ()->threads ()); - proc.run (&op, polygons.layer (), other_layer, res->deep_layer ().layer ()); + proc.run (&op, polygons.layer (), other_layers, res->deep_layer ().layer ()); } diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index 40fcf0376..ab6532d72 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -2123,3 +2123,13 @@ TEST(149d_compound_drc_with_mag) { run_test (_this, "149", true); } + +TEST(150_optimized_separation) +{ + run_test (_this, "150", false); +} + +TEST(150d_optimized_separation) +{ + run_test (_this, "150", true); +} diff --git a/testdata/drc/drcSimpleTests_150.drc b/testdata/drc/drcSimpleTests_150.drc new file mode 100644 index 000000000..3bcc8e15c --- /dev/null +++ b/testdata/drc/drcSimpleTests_150.drc @@ -0,0 +1,20 @@ +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep +end + +deep + +l1 = input(1, 0) +l2 = input(2, 0) + +l1.output(1, 0) +l2.output(2, 0) + +l1.space(1.um).output(100, 0) +l1.sep(l2, 1.um).output(101, 0) +(l1 + l2).space(1.um, transparent).output(102, 0) +(l1 + l2).space(1.um).output(103, 0) + diff --git a/testdata/drc/drcSimpleTests_150.gds b/testdata/drc/drcSimpleTests_150.gds new file mode 100644 index 0000000000000000000000000000000000000000..d433eb8bb74e83774b7f52a477d8ff3e6a200803 GIT binary patch literal 490 zcmaKnF$%&k6o&u4wn;=<6&-s7!9@@kL2*zNbm$67v_Te-d_tnFpA^b}ha$0@Pk>GskH-7K;&yrsr)94=ZgXVupH7H; zwFV*uh=dS8qy(Vb4E5=)@B#SSQ&Fp;kMCxR$!+cG$j180zFwN1$$g`6WMh40PZ!fO uxtGe3jrD#{{{4f4zStRHs=of;o#XGjW@WG5re|`W%pAG5{@Y7E8sP)}vM~h! literal 0 HcmV?d00001 diff --git a/testdata/drc/drcSimpleTests_au150.gds b/testdata/drc/drcSimpleTests_au150.gds new file mode 100644 index 0000000000000000000000000000000000000000..9e46df4e89991c6f634da9a5b130ece9b3b2cb13 GIT binary patch literal 2218 zcmbu9KQjYC7{=f1<^IV;7%9_h%qTEMV}?=4U?@@;wLc#LA3;U0iAsq|3|;UgPzRMB z!~5F3+jlRP+~#KPo|}F4m-pS>=K=u;u@1F@2wx$D5valhc>EnA5iHl|0ji!qJ9jX> zbbtCbv(OrE9&a?D=KsM3L1T3dpcnxJWdQ{U1_c0&4SD!vm-h_7Z)O#TExi9IXOR*c z-)bdC`BuKvk~}H#m8Mp5lyBw5jpRv*4&`VjmaS|GrfEEw7XM z79Qt6&^+w(U2^5R)c8)0EB{|!gl7GCr8mBG`Fs7!i5yqHz5b}l4?M{}!dTUpzLgi( za$a`-5?=Y7-|ln&8ISqwtG?6u8TI}A`^We+UtRf==b!qP{nP#D$PcTJe5U`d{C1ze z!8_#7;2pkSgZFnauV=Up)MyItPp!!~D&N1IKJ&+Tr~Dbb!~ciLXU?yO@0amuzVhUc e@lN?O`Aq*k$8@@Mc4`7`)D`3o_sMfe6em`XeV literal 0 HcmV?d00001 diff --git a/testdata/drc/drcSimpleTests_au150d.gds b/testdata/drc/drcSimpleTests_au150d.gds new file mode 100644 index 0000000000000000000000000000000000000000..9e46df4e89991c6f634da9a5b130ece9b3b2cb13 GIT binary patch literal 2218 zcmbu9KQjYC7{=f1<^IV;7%9_h%qTEMV}?=4U?@@;wLc#LA3;U0iAsq|3|;UgPzRMB z!~5F3+jlRP+~#KPo|}F4m-pS>=K=u;u@1F@2wx$D5valhc>EnA5iHl|0ji!qJ9jX> zbbtCbv(OrE9&a?D=KsM3L1T3dpcnxJWdQ{U1_c0&4SD!vm-h_7Z)O#TExi9IXOR*c z-)bdC`BuKvk~}H#m8Mp5lyBw5jpRv*4&`VjmaS|GrfEEw7XM z79Qt6&^+w(U2^5R)c8)0EB{|!gl7GCr8mBG`Fs7!i5yqHz5b}l4?M{}!dTUpzLgi( za$a`-5?=Y7-|ln&8ISqwtG?6u8TI}A`^We+UtRf==b!qP{nP#D$PcTJe5U`d{C1ze z!8_#7;2pkSgZFnauV=Up)MyItPp!!~D&N1IKJ&+Tr~Dbb!~ciLXU?yO@0amuzVhUc e@lN?O`Aq*k$8@@Mc4`7`)D`3o_sMfe6em`XeV literal 0 HcmV?d00001