From 1a9edbf6a9f6760990e45ba3745127c25842ea08 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 21 Jan 2023 15:13:39 +0100 Subject: [PATCH] WIP: refactoring - allow properties constraints modes which do not copy properties. In DRC that is default. --- src/db/db/dbAsIfFlatRegion.cc | 8 ++-- src/db/db/dbDeepRegion.cc | 10 ++--- src/db/db/dbEdgePairsDelegate.h | 6 +++ src/db/db/dbEdgesDelegate.h | 6 +++ src/db/db/dbFlatEdgePairs.cc | 12 ++++-- src/db/db/dbFlatEdges.cc | 12 ++++-- src/db/db/dbFlatRegion.cc | 12 ++++-- src/db/db/dbFlatTexts.cc | 12 ++++-- src/db/db/dbRegionDelegate.h | 6 +++ src/db/db/dbShapeCollection.cc | 11 +++-- src/db/db/dbShapeCollection.h | 7 +++ src/db/db/dbTextsDelegate.h | 6 +++ src/db/unit_tests/dbAsIfFlatRegionTests.cc | 47 +++++++++++++++++++-- src/db/unit_tests/dbDeepRegionTests.cc | 47 +++++++++++++++++++-- src/drc/drc/built-in-macros/_drc_engine.rb | 4 +- testdata/algo/deep_region_au40.gds | Bin 7280 -> 10288 bytes testdata/algo/deep_region_au42.gds | Bin 12132 -> 14832 bytes testdata/algo/deep_region_au43.gds | Bin 5872 -> 7552 bytes testdata/algo/flat_region_au40.gds | Bin 11390 -> 16222 bytes testdata/algo/flat_region_au42.gds | Bin 19094 -> 22118 bytes testdata/algo/flat_region_au43.gds | Bin 8814 -> 11334 bytes testdata/drc/drcSimpleTests_70.drc | 7 +++ testdata/drc/drcSimpleTests_au70.gds | Bin 66238 -> 71406 bytes testdata/drc/drcSimpleTests_au70d.gds | Bin 47702 -> 52278 bytes 24 files changed, 177 insertions(+), 36 deletions(-) diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index b6b3a80b7..aa66e3d1e 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1428,12 +1428,12 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const } else if (other.empty () && ! strict_handling ()) { // Nothing to do - return clone (); + return clone ()->remove_properties (pc_remove (property_constraint)); } else if (! bbox ().overlaps (other.bbox ()) && ! strict_handling ()) { // Nothing to do - return clone (); + return clone ()->remove_properties (pc_remove (property_constraint)); } else { return and_or_not_with (false, other, property_constraint); @@ -1513,12 +1513,12 @@ AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_co } else if (other.empty () && ! strict_handling ()) { // Nothing to do - return std::make_pair (new EmptyRegion (), clone ()); + return std::make_pair (new EmptyRegion (), clone ()->remove_properties (pc_remove (property_constraint))); } else if (! bbox ().overlaps (other.bbox ()) && ! strict_handling ()) { // Nothing to do - return std::make_pair (new EmptyRegion (), clone ()); + return std::make_pair (new EmptyRegion (), clone ()->remove_properties (pc_remove (property_constraint))); } else if (pc_skip (property_constraint)) { diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index c0630158d..0d7d725de 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -783,11 +783,11 @@ DeepRegion::and_with (const Region &other, PropertyConstraint property_constrain if (empty ()) { - return clone (); + return clone ()->remove_properties (pc_remove (property_constraint)); } else if (other.empty ()) { - return other.delegate ()->clone (); + return other.delegate ()->clone ()->remove_properties (pc_remove (property_constraint)); } else if (! other_deep) { @@ -807,7 +807,7 @@ DeepRegion::not_with (const Region &other, PropertyConstraint property_constrain if (empty () || other.empty ()) { - return clone (); + return clone ()->remove_properties (pc_remove (property_constraint)); } else if (! other_deep) { @@ -835,11 +835,11 @@ DeepRegion::andnot_with (const Region &other, PropertyConstraint property_constr if (empty ()) { - return std::make_pair (clone (), clone ()); + return std::make_pair (clone ()->remove_properties (pc_remove (property_constraint)), clone ()->remove_properties (pc_remove (property_constraint))); } else if (other.empty ()) { - return std::make_pair (other.delegate ()->clone (), clone ()); + return std::make_pair (other.delegate ()->clone ()->remove_properties (pc_remove (property_constraint)), clone ()->remove_properties (pc_remove (property_constraint))); } else if (! other_deep) { diff --git a/src/db/db/dbEdgePairsDelegate.h b/src/db/db/dbEdgePairsDelegate.h index 4ea093ede..6cdf92e5c 100644 --- a/src/db/db/dbEdgePairsDelegate.h +++ b/src/db/db/dbEdgePairsDelegate.h @@ -166,6 +166,12 @@ public: virtual EdgePairsDelegate *clone () const = 0; + EdgePairsDelegate *remove_properties (bool remove = true) + { + ShapeCollectionDelegateBase::remove_properties (remove); + return this; + } + void enable_progress (const std::string &progress_desc); void disable_progress (); diff --git a/src/db/db/dbEdgesDelegate.h b/src/db/db/dbEdgesDelegate.h index cba4e40f9..182700bae 100644 --- a/src/db/db/dbEdgesDelegate.h +++ b/src/db/db/dbEdgesDelegate.h @@ -239,6 +239,12 @@ public: virtual EdgesDelegate *clone () const = 0; + EdgesDelegate *remove_properties (bool remove = true) + { + ShapeCollectionDelegateBase::remove_properties (remove); + return this; + } + void set_base_verbosity (int vb); int base_verbosity () const { diff --git a/src/db/db/dbFlatEdgePairs.cc b/src/db/db/dbFlatEdgePairs.cc index 5204387db..eff3816fe 100644 --- a/src/db/db/dbFlatEdgePairs.cc +++ b/src/db/db/dbFlatEdgePairs.cc @@ -192,11 +192,15 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const void FlatEdgePairs::apply_property_translator (const db::PropertiesTranslator &pt) { - db::Shapes new_edge_pairs (mp_edge_pairs->is_editable ()); - new_edge_pairs.assign (*mp_edge_pairs, pt); - mp_edge_pairs->swap (new_edge_pairs); + if ((mp_edge_pairs->type_mask () & db::ShapeIterator::Properties) != 0) { - invalidate_cache (); + db::Shapes new_edge_pairs (mp_edge_pairs->is_editable ()); + new_edge_pairs.assign (*mp_edge_pairs, pt); + mp_edge_pairs->swap (new_edge_pairs); + + invalidate_cache (); + + } } db::PropertiesRepository *FlatEdgePairs::properties_repository () diff --git a/src/db/db/dbFlatEdges.cc b/src/db/db/dbFlatEdges.cc index e185fc5e6..5e386c431 100644 --- a/src/db/db/dbFlatEdges.cc +++ b/src/db/db/dbFlatEdges.cc @@ -390,11 +390,15 @@ const db::RecursiveShapeIterator *FlatEdges::iter () const void FlatEdges::apply_property_translator (const db::PropertiesTranslator &pt) { - db::Shapes new_edges (mp_edges->is_editable ()); - new_edges.assign (*mp_edges, pt); - mp_edges->swap (new_edges); + if ((mp_edges->type_mask () & db::ShapeIterator::Properties) != 0) { - invalidate_cache (); + db::Shapes new_edges (mp_edges->is_editable ()); + new_edges.assign (*mp_edges, pt); + mp_edges->swap (new_edges); + + invalidate_cache (); + + } } db::PropertiesRepository *FlatEdges::properties_repository () diff --git a/src/db/db/dbFlatRegion.cc b/src/db/db/dbFlatRegion.cc index 248b9121a..307984b9d 100644 --- a/src/db/db/dbFlatRegion.cc +++ b/src/db/db/dbFlatRegion.cc @@ -421,11 +421,15 @@ const db::RecursiveShapeIterator *FlatRegion::iter () const void FlatRegion::apply_property_translator (const db::PropertiesTranslator &pt) { - db::Shapes new_polygons (mp_polygons->is_editable ()); - new_polygons.assign (*mp_polygons, pt); - mp_polygons->swap (new_polygons); + if ((mp_polygons->type_mask () & db::ShapeIterator::Properties) != 0) { - invalidate_cache (); + db::Shapes new_polygons (mp_polygons->is_editable ()); + new_polygons.assign (*mp_polygons, pt); + mp_polygons->swap (new_polygons); + + invalidate_cache (); + + } } db::PropertiesRepository *FlatRegion::properties_repository () diff --git a/src/db/db/dbFlatTexts.cc b/src/db/db/dbFlatTexts.cc index 3b00b400a..26a718116 100644 --- a/src/db/db/dbFlatTexts.cc +++ b/src/db/db/dbFlatTexts.cc @@ -190,11 +190,15 @@ const db::RecursiveShapeIterator *FlatTexts::iter () const void FlatTexts::apply_property_translator (const db::PropertiesTranslator &pt) { - db::Shapes new_texts (mp_texts->is_editable ()); - new_texts.assign (*mp_texts, pt); - mp_texts->swap (new_texts); + if ((mp_texts->type_mask () & db::ShapeIterator::Properties) != 0) { - invalidate_cache (); + db::Shapes new_texts (mp_texts->is_editable ()); + new_texts.assign (*mp_texts, pt); + mp_texts->swap (new_texts); + + invalidate_cache (); + + } } db::PropertiesRepository *FlatTexts::properties_repository () diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index d4ccac4a2..1b701f26d 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -196,6 +196,12 @@ public: virtual RegionDelegate *clone () const = 0; + RegionDelegate *remove_properties (bool remove = true) + { + ShapeCollectionDelegateBase::remove_properties (remove); + return this; + } + void set_base_verbosity (int vb); int base_verbosity () const { diff --git a/src/db/db/dbShapeCollection.cc b/src/db/db/dbShapeCollection.cc index 4d5a3a0fc..ba1eb224b 100644 --- a/src/db/db/dbShapeCollection.cc +++ b/src/db/db/dbShapeCollection.cc @@ -55,11 +55,16 @@ DeepShapeCollectionDelegateBase::apply_property_translator (const db::Properties for (auto c = layout.begin (); c != layout.end (); ++c) { db::Shapes &shapes = c->shapes (m_deep_layer.layer ()); + if ((shapes.type_mask () & ShapeIterator::Properties) != 0) { - db::Shapes new_shapes (shapes.is_editable ()); - shapes.swap (new_shapes); + // properties are present - need to translate them - shapes.assign (new_shapes, pt); + db::Shapes new_shapes (shapes.is_editable ()); + shapes.swap (new_shapes); + + shapes.assign (new_shapes, pt); + + } } } diff --git a/src/db/db/dbShapeCollection.h b/src/db/db/dbShapeCollection.h index 4e4824811..a036e0887 100644 --- a/src/db/db/dbShapeCollection.h +++ b/src/db/db/dbShapeCollection.h @@ -83,6 +83,13 @@ public: virtual void apply_property_translator (const db::PropertiesTranslator & /*pt*/) = 0; virtual db::PropertiesRepository *properties_repository () = 0; virtual const db::PropertiesRepository *properties_repository () const = 0; + + void remove_properties (bool remove = true) + { + if (remove) { + apply_property_translator (db::PropertiesTranslator::make_remove_all ()); + } + } }; /** diff --git a/src/db/db/dbTextsDelegate.h b/src/db/db/dbTextsDelegate.h index 367ced7f1..726714dad 100644 --- a/src/db/db/dbTextsDelegate.h +++ b/src/db/db/dbTextsDelegate.h @@ -66,6 +66,12 @@ public: virtual TextsDelegate *clone () const = 0; + TextsDelegate *remove_properties (bool remove = true) + { + ShapeCollectionDelegateBase::remove_properties (remove); + return this; + } + void enable_progress (const std::string &progress_desc); void disable_progress (); diff --git a/src/db/unit_tests/dbAsIfFlatRegionTests.cc b/src/db/unit_tests/dbAsIfFlatRegionTests.cc index 91333e70f..124ac5f15 100644 --- a/src/db/unit_tests/dbAsIfFlatRegionTests.cc +++ b/src/db/unit_tests/dbAsIfFlatRegionTests.cc @@ -1688,6 +1688,12 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 0)), r3.bool_and (r2, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 0)), r1.bool_and (r3, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 0)), r1.bool_and (r3, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 1)), r1.bool_and (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 1)), r1.bool_and (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (24, 1)), r3.bool_and (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 1)), r3.bool_and (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 1)), r1.bool_and (r3, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 1)), r1.bool_and (r3, db::DifferentPropertiesConstraintDrop)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r1 - r2); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.bool_not (r2, db::NoPropertyConstraint)); @@ -1697,6 +1703,12 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (35, 0)), r3.bool_not (r2, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (36, 0)), r1.bool_not (r3, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (37, 0)), r1.bool_not (r3, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r1.bool_not (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (33, 1)), r1.bool_not (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (34, 1)), r3.bool_not (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (35, 1)), r3.bool_not (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (36, 1)), r1.bool_not (r3, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (37, 1)), r1.bool_not (r3, db::DifferentPropertiesConstraintDrop)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.andnot (r2).first); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.andnot (r2).second); @@ -1712,6 +1724,18 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (51, 0)), r1.andnot (r3, db::SamePropertiesConstraint).second); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (52, 0)), r1.andnot (r3, db::DifferentPropertiesConstraint).first); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (53, 0)), r1.andnot (r3, db::DifferentPropertiesConstraint).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r1.andnot (r2, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (43, 1)), r1.andnot (r2, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (44, 1)), r1.andnot (r2, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (45, 1)), r1.andnot (r2, db::DifferentPropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (46, 1)), r3.andnot (r2, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (47, 1)), r3.andnot (r2, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (48, 1)), r3.andnot (r2, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (49, 1)), r3.andnot (r2, db::DifferentPropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (50, 1)), r1.andnot (r3, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (51, 1)), r1.andnot (r3, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (52, 1)), r1.andnot (r3, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (53, 1)), r1.andnot (r3, db::DifferentPropertiesConstraintDrop).second); CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au40.gds"); @@ -1829,12 +1853,24 @@ TEST(42_DRCWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.separation_check (r2, 1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), r2.space_check (1000, opt)); + opt.prop_constraint = db::SamePropertiesConstraintDrop; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 1)), r1.space_check (1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 1)), r1.separation_check (r2, 1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r2.space_check (1000, opt)); + opt.prop_constraint = db::DifferentPropertiesConstraint; target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.space_check (1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.separation_check (r2, 1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 0)), r2.space_check (1000, opt)); + opt.prop_constraint = db::DifferentPropertiesConstraintDrop; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 1)), r1.space_check (1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 1)), r1.separation_check (r2, 1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r2.space_check (1000, opt)); + CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au42.gds"); } @@ -1896,10 +1932,18 @@ TEST(43_ComplexOpsWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.cop_to_region (sep_check2p, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), r1.cop_to_edges (sep_check2e, db::SamePropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 1)), r1.cop_to_edge_pairs (sep_check, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 1)), r1.cop_to_region (sep_check2p, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r1.cop_to_edges (sep_check2e, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.cop_to_edge_pairs (sep_check, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.cop_to_region (sep_check2p, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 0)), r1.cop_to_edges (sep_check2e, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 1)), r1.cop_to_edge_pairs (sep_check, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 1)), r1.cop_to_region (sep_check2p, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r1.cop_to_edges (sep_check2e, db::DifferentPropertiesConstraintDrop)); + CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au43.gds"); } @@ -1932,9 +1976,6 @@ TEST(44_SizeWithProperties) db::Layout target; unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); - db::RegionCheckOptions opt; - opt.metrics = db::Projection; - target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2); diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 6cf0658d5..89117d591 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -2176,6 +2176,12 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 0)), r3.bool_and (r2, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 0)), r1.bool_and (r3, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 0)), r1.bool_and (r3, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 1)), r1.bool_and (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 1)), r1.bool_and (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (24, 1)), r3.bool_and (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 1)), r3.bool_and (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 1)), r1.bool_and (r3, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (27, 1)), r1.bool_and (r3, db::DifferentPropertiesConstraintDrop)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r1 - r2); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.bool_not (r2, db::NoPropertyConstraint)); @@ -2185,6 +2191,12 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (35, 0)), r3.bool_not (r2, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (36, 0)), r1.bool_not (r3, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (37, 0)), r1.bool_not (r3, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r1.bool_not (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (33, 1)), r1.bool_not (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (34, 1)), r3.bool_not (r2, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (35, 1)), r3.bool_not (r2, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (36, 1)), r1.bool_not (r3, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (37, 1)), r1.bool_not (r3, db::DifferentPropertiesConstraintDrop)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.andnot (r2).first); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.andnot (r2).second); @@ -2200,6 +2212,18 @@ TEST(40_BoolWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (51, 0)), r1.andnot (r3, db::SamePropertiesConstraint).second); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (52, 0)), r1.andnot (r3, db::DifferentPropertiesConstraint).first); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (53, 0)), r1.andnot (r3, db::DifferentPropertiesConstraint).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r1.andnot (r2, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (43, 1)), r1.andnot (r2, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (44, 1)), r1.andnot (r2, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (45, 1)), r1.andnot (r2, db::DifferentPropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (46, 1)), r3.andnot (r2, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (47, 1)), r3.andnot (r2, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (48, 1)), r3.andnot (r2, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (49, 1)), r3.andnot (r2, db::DifferentPropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (50, 1)), r1.andnot (r3, db::SamePropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (51, 1)), r1.andnot (r3, db::SamePropertiesConstraintDrop).second); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (52, 1)), r1.andnot (r3, db::DifferentPropertiesConstraintDrop).first); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (53, 1)), r1.andnot (r3, db::DifferentPropertiesConstraintDrop).second); CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au40.gds"); @@ -2321,12 +2345,24 @@ TEST(42_DRCWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.separation_check (r2, 1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), r2.space_check (1000, opt)); + opt.prop_constraint = db::SamePropertiesConstraintDrop; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 1)), r1.space_check (1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 1)), r1.separation_check (r2, 1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r2.space_check (1000, opt)); + opt.prop_constraint = db::DifferentPropertiesConstraint; target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.space_check (1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.separation_check (r2, 1000, opt)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 0)), r2.space_check (1000, opt)); + opt.prop_constraint = db::DifferentPropertiesConstraintDrop; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 1)), r1.space_check (1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 1)), r1.separation_check (r2, 1000, opt)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r2.space_check (1000, opt)); + CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au42.gds"); } @@ -2390,10 +2426,18 @@ TEST(43_ComplexOpsWithProperties) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r1.cop_to_region (sep_check2p, db::SamePropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), r1.cop_to_edges (sep_check2e, db::SamePropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 1)), r1.cop_to_edge_pairs (sep_check, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 1)), r1.cop_to_region (sep_check2p, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 1)), r1.cop_to_edges (sep_check2e, db::SamePropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r1.cop_to_edge_pairs (sep_check, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r1.cop_to_region (sep_check2p, db::DifferentPropertiesConstraint)); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 0)), r1.cop_to_edges (sep_check2e, db::DifferentPropertiesConstraint)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 1)), r1.cop_to_edge_pairs (sep_check, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 1)), r1.cop_to_region (sep_check2p, db::DifferentPropertiesConstraintDrop)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 1)), r1.cop_to_edges (sep_check2e, db::DifferentPropertiesConstraintDrop)); + CHECKPOINT(); db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au43.gds"); } @@ -2428,9 +2472,6 @@ TEST(44_SizeWithProperties) db::Layout target; unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); - db::RegionCheckOptions opt; - opt.metrics = db::Projection; - target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2); diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index a5bd6286d..b3c1c82f4 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -318,13 +318,13 @@ module DRC def props_eq self._context("props_eq") do - DRCPropertiesConstraint::new(RBA::Region::SamePropertiesConstraint) + DRCPropertiesConstraint::new(RBA::Region::SamePropertiesConstraintDrop) end end def props_ne self._context("props_ne") do - DRCPropertiesConstraint::new(RBA::Region::DifferentPropertiesConstraint) + DRCPropertiesConstraint::new(RBA::Region::DifferentPropertiesConstraintDrop) end end diff --git a/testdata/algo/deep_region_au40.gds b/testdata/algo/deep_region_au40.gds index c6764b0b6ded75064a5afbbe372528d39ccf0949..84d6d496957bf87f2865b372111e1077a2450ee3 100644 GIT binary patch delta 856 zcmZ`$Jxc>Y5S_d1-sWOH4B_sgMA4WOY7T`UcxW(!O(b9h3l%IZ1;P9Qe}Y0B(r9aG z5lLgCq!wEX3qe8AD)sY0yAbcOj*y;tLcoAPOrG>&LZp zHZg?0-A^)nU}b#dYk10wSm4_j1Svb-EC;GWx#-Yxya9kLj5 zN7Wj3N6L1;)~b#m*j1YABk#P{7Gh2|^V||1)f|0(s13=wHv0F;$sSJ~HXQRbGG|Mz zr5}lW7kh39N}o%A3c-dw!{Pu;0HpZ8VKs~KLq=!5FziI9CJ3NKRG>STjRMw8)5P($j$9KHl0Xv+B)V3tOkt}KtuipQ2qdJg2>Kr&{8pGj zAVonLS@I|39{^>j#6Tr7u`qxyiO;06nf%@R{C<4jy*odepEf`RLJpv=5cVAuu)%;0 zsQruIG&<&`(C3HmYitKpgMfkq7A82de0+JuOpa)2lES&g@kn!+zf6m0m_Y24D&D6q zK66~05<2#sM+zFcgMat~eBPz_t)k<*LKzRai$lIQ?r;4fIND^ay_%slz716AxwweTyc|9DDjlvRg}dnXVjI^xfN9CRRF31s2c=UnUR$yit&g1TAVy8 z$Y@jvP*cmYj%5e9pPnPi@rjxaGIay|P1D~+%`-~T+SKu0y?Xfq#*gcVI=*VDanpgH znk>>j`mVeHaXx67YYLKk6P$Oes5Z|5Y9DZ$w{hm1;~%Y4w(vIbZ&I@HYsT8;lo?`C((8%PLeq{HY zw)6Gf=w#MhP->(~}?WAiV_IKXN);8;M z?+yS|E&y)7%`RWC@uZU{-^NclTwEGo^s?LbiH%=+*)_#ed>W)%E-W52O?@Gq#gB@@ EU+N>IRR910 delta 152 zcmexR{3K3^fsKKQDS|$ zPLP+KTrVX$IZn!K@;zz($)_b_Cr=PkpKLEJz4@Bd7A84%1_l{coaS%lP>ki?Y^yt$ Loeijvg@pkCNXs6G diff --git a/testdata/algo/deep_region_au43.gds b/testdata/algo/deep_region_au43.gds index c65a1ecc32d916380a8b1df624d8023621f098dd..857661a5bd94658c3b7aecc80b9a172704a06c96 100644 GIT binary patch delta 635 zcmZ{gF;2rU6o#LTYd3Y`q)Nh)s#L8I0jXqSs6c|94jF+%Adb)@r1H!S7>as<9-$|o z8;Ajkfsui@wbME(liz#4_5bgE-^0meA1Gja2OWgj2Ox++fCq=W^|XH+?is&6oN(3! zDlj0Km6qd3zBztK+5n^pKs^jc+QV&KBP7SI;YM{fYEP>HzbI9e zV4}P6 z;;732I*os!&1ddc(>lBG6RUp|+kO%btfLLqUaaReRKH@x47NPl4@~W;GInvP9ZX+& y*U*)_%%|}^lEPtf71Q$kLSz*qWqaQC<)?6&fpq1MEIg%donz1yBBdoZLf{Y3KUMJn delta 127 zcmZp${-CSGz{bGD6u}_F$i)7ffssLofuBL0K^>VrQAt%8i}1!Mb?(W}d8H>`V3MBv lpO0`xqMvQFi3=AwR3;@c$8C3uP diff --git a/testdata/algo/flat_region_au40.gds b/testdata/algo/flat_region_au40.gds index bb410687ac9658fd1a950ae8ce49b2ce5dd7eb7d..682ed0746747a0d18973fd93de5158e0a9ce82f9 100644 GIT binary patch delta 1329 zcmZ`(O-vI(7@b`U+jW1+wsf~epi6%&*kT$Rg^eJ+svF`BG{p2KBu0DlV1nMf7z24H zxq8zCYKSKZc=MpCcQsr!#;7-M!VJu8cN;ux=Y4O#dHZ$V+x@q=znUlgM3xuHup}$r zh(yvPK?rffcs*ZAoj||7bwR^Uu8ae%gr}O1w($rbGy^T8ff~L3=nb^#RUIi~%go@n zLGS5xJTwi=m_FZ|q4iBP6UV$uS0vtGCRfMXf#>)+Qpe?ihGLU`QzjBR=42{n5fY0N z(r?H_@T2<4{H6c&|4==lx!$qSQVWX1AF&bl0{rrH7tdQ=Y+7@YgpI^(WEi0^M8yUE z9QU@LSkp4j4EoqhE#du`k6hZtox!`CTlB=U;Uq{aF!??3>w0^V~ zu;)zEo(BFpE7-{_;K1oaldhk#%h0kr+fzf|WyR(5ZzjC}kJ_`SB=w+vR-8?TkB{#m zGq@qScxRP^&RwUgvP$t7S5Ic62QBzt)>V~bs@6;u@ipV%RZ0)BYgP>{Ny8UQ5A-_O zl>pzSxX7P#W$1WvUaxn&;MTk}c_blPP03R^CRMBz2hoWH5}J8#hT-l(19;=R%2Jd2lGn4lYbvnV!RE3heqRTVBrZB#i9*(2^! zBP0J%@XRWKnT1uZ#zHMHjbwm(BP@DYgazI|%jRRRf?!6=jG>k*lU$$1A`&dl)5$}o zt6eq}kU(R1{61AZKf!*5{qG48E<&G`f;|4@{kykDkc@_nEgcV*ZoYse%|{;$He V*;n=v)8>A)NPaeU1_l-u1^|z#UB&aAdrxd@*fmm8v7hz^1bi9``-6GzuS2w{n(RoL?NNj zJu)eU)SpBmNn#R0oZ$Iot`PeNe7muihI2{A%>@lfyMXOR0w3&L*Oaka=THmns@eZ- z$3pm4PvM1agEs8pw^K6_$+Xa$m-|PVrxR+HC`O1#=uKPLQc`|As9A7gBBn|LTT3RM zQQfcM*c)p5@p09{^TjDi!hu@yQC`)_$uPnJwq=I9;c=#&xL~3MhOhDQ{I6y6oE#%W zju4_mL&Q_wOi!jSekbJoYZ6R5BV)8^;ft11z4$@4FVt0CLhVhH9iumlzj9+weZm$wpZ1g7CAny z%PZqny*ek)@ZKHUoTtn6)@e{r?g;MI8P*%|Vb27v+qS4ztl^5BX1TWgTN+vs!Pt(J z{OWeZ%|}vxJh;tp5~$@a_U~voxxsst7a1O&6-=~}MDdD&^);U5y_|V%><4--j;jn& zP26-eq2W+>9j@{Doi1b;k2TX*q4QEPvXgffp=NKM$1-rRl{sF0J$S>MgwCh zvi}OBWrk0Id(HIJg!@GQS~TCr3d3qT(4}mlJfq=}A+U}itntPCYzXmmj=?lVEjQeA Sm($}P)R;D0aMgVSGWi1$S-Io@ delta 164 zcmaF1hH=_dMkNL|1}3Hm1{p>s_U858_d0ENLyRA)y*w`5uSXdYUdN3#? diff --git a/testdata/algo/flat_region_au43.gds b/testdata/algo/flat_region_au43.gds index 33db39033ff784f7cc35f8cd2f58b7b6af080880..5295c4d6afb5bbe6da36b388952c07e348af127d 100644 GIT binary patch delta 821 zcmZuvJ5Iwu5FJ~NHy{7NL?*TqJBbhnV-}5aSv3GKj=d)QJh|=Q zqNPd_4*db?fNIDfp`~u&gRbDrX{Si2mysLQD`n1n(^fVBlp27l%fML@qmK=um2#7& ziI0WYjO5%$?LM}ud4AH!v8PUdZ4KJ#q08!5v-$y>V&a~p-QO?YPdCErnnpM_-;B_# z=l;1J;aR<6tWdmpQK@XmsE7VB6NX1CoKfA_+eon%jI0am5iaE>bZ^ z2*4Il#JJ!*mI{fN!EU-<52t~Lqek|}j)JeI^D+&-Wc;-V*<+)|-GQ(zwP@2D@dOs? z+c*s9y(C5x|1?)1bc_$HyrX@_J__lMu9ojSjBrt_7;K6ImXZ?RnGWG@CW=?^2f~iK UbS}q-UzYKk?XjYybcN delta 102 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 Bk?Q~e diff --git a/testdata/drc/drcSimpleTests_au70d.gds b/testdata/drc/drcSimpleTests_au70d.gds index 7cac4fb6b72d738c6829972d9ce0bd989a91da5a..a4339e5586c32e4a1fd95473a30e31d18c361456 100644 GIT binary patch delta 1197 zcmZ`&T}V@582-*_&Y$gU3OU`_VktO@gy?|IHJ#>Nj`?ptWV&EmMT8K65RLAIxqJw` zs3~1X5C_5_%*#M=cd-vdx~lFH>Y^*{{l3#VIYu|{_rA~jzRz=bzVCegrM_D`)xn%h zRj;w2qSk+73TtIvLN1=npLIl9YQYpSzLl;t1W3<@%?lwl^VHBb)B^r(!nB(`H`G1q$z-l$vY!9hF-PhZt{6FSsa zB`A=%51YLqcw=I#(5Iu^@5hUH#PCMbjac+LRV9XET$j8tj3<0(h=(vnDlt+ayx+`x zcp3|#EOC=Z;3xS-rDH|T7fE-I=EtbIM685I>(10O7Oea4#T$j;MGs2j<2V}Iz|h1i zG;0p*XA)S~G!!QsIG-K1^XOzsV5_tLpf@uqqkHOyi{8ZjDILr6Zpz%#I(8OB79?zx zurh86OlG?o9WLsY@tUwvnQdojS7t$xrA2owEndOl3{Bq_b#soUW%hwsU2>*G-O;ok z-BS_L3E=&77cu%#$wWxQkKJs9c>P$S{_^~Fbc;GYhj6Y_aABa$13&HTEWBKu?G!?I z(ykHRh&??0a)9$Y)b%4hTa_^eN9J7R><1 zAN9H!lF`dh4P;_{lfbxp?HLnSPpw|gZ)F)8E0ijL!gc)Ayg VIzGxQSrB~>bR-Hc;}(8*{Q-y`cJKfI delta 547 zcmdlsgZbJQCM5s_U8VlYpQPr4&8=r-XF8(XQ zJNdpA_vRBClSMY~wwua1@dPiX(#`9<3iu}HMJ|{u7a1@qnq~62ILFEJd3h)EMJ)nx z72?5M5L2%h#1x$D*Qh+1w@3!0YErc8_N8mPX>2+Tj#1QlMS0J z9-taqX|TnU^J8SdY_10N$?>rewil4SA1EF#%R9NNQGN1%pg4$)Ebi5$KA9gX-UU>@ z9?a&O%-x^{HV330=rOSQ`Ne`j|4#;*0rP+L