diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 31780d0eb..b6b3a80b7 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1017,7 +1017,7 @@ EdgePairsDelegate * AsIfFlatRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) { std::unique_ptr output (new FlatEdgePairs ()); - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { region_cop_impl (this, &output->raw_edge_pairs (), node); } else { region_cop_with_properties_impl (this, &output->raw_edge_pairs (), output->properties_repository (), node, prop_constraint); @@ -1029,7 +1029,7 @@ RegionDelegate * AsIfFlatRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) { std::unique_ptr output (new FlatRegion ()); - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { region_cop_impl (this, &output->raw_polygons (), node); } else { region_cop_with_properties_impl (this, &output->raw_polygons (), output->properties_repository (), node, prop_constraint); @@ -1041,7 +1041,7 @@ EdgesDelegate * AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node, PropertyConstraint prop_constraint) { std::unique_ptr output (new FlatEdges ()); - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { region_cop_impl (this, &output->raw_edges (), node); } else { region_cop_with_properties_impl (this, &output->raw_edges (), output->properties_repository (), node, prop_constraint); @@ -1113,7 +1113,7 @@ EdgePairsDelegate * AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const { // force different polygons in the different properties case to skip intra-polygon checks - if (options.prop_constraint == DifferentPropertiesConstraint) { + if (pc_always_different (options.prop_constraint)) { different_polygons = true; } @@ -1159,7 +1159,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, std::vector results; results.push_back (&output->raw_edge_pairs ()); - if (options.prop_constraint == db::IgnoreProperties) { + if (pc_skip (options.prop_constraint)) { db::check_local_operation op (check, different_polygons, primary_is_merged, has_other, other_is_merged, options); @@ -1209,7 +1209,7 @@ AsIfFlatRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) { - edge2edge_check_negative_or_positive edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : pm (p.prop_id ())); + edge2edge_check_negative_or_positive edge_check (check, result->raw_edge_pairs (), options.negative, false /*=same polygons*/, false /*=same layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : pm (p.prop_id ())); poly2poly_check poly_check (edge_check); do { @@ -1364,7 +1364,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const // Nothing to do return new EmptyRegion (); - } else if (property_constraint == db::IgnoreProperties && is_box () && other.is_box ()) { + } else if (pc_skip (property_constraint) && is_box () && other.is_box ()) { // @@@ TODO: implement this with property constraints as that is important for the clip implementation! @@ -1373,7 +1373,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const b &= other.bbox (); return region_from_box (b); - } else if (property_constraint == db::IgnoreProperties && is_box () && ! other.strict_handling ()) { + } else if (pc_skip (property_constraint) && is_box () && ! other.strict_handling ()) { // @@@ TODO: implement this with property constraints as that is important for the clip implementation! @@ -1390,7 +1390,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const return new_region.release (); - } else if (property_constraint == db::IgnoreProperties && other.is_box () && ! strict_handling ()) { + } else if (pc_skip (property_constraint) && other.is_box () && ! strict_handling ()) { // @@@ TODO: implement this with property constraints as that is important for the clip implementation! @@ -1443,7 +1443,7 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const RegionDelegate * AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const { - if (property_constraint == db::IgnoreProperties) { + if (pc_skip (property_constraint)) { // Generic case db::EdgeProcessor ep (report_progress (), progress_desc ()); @@ -1520,7 +1520,7 @@ AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_co // Nothing to do return std::make_pair (new EmptyRegion (), clone ()); - } else if (property_constraint == db::IgnoreProperties) { + } else if (pc_skip (property_constraint)) { // Generic case db::EdgeProcessor ep (report_progress (), progress_desc ()); diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 45b9879f2..f63ca361d 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -1549,7 +1549,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi set_description ("check"); // force different polygons in the different properties case to skip intra-polygon checks - if (m_options.prop_constraint == DifferentPropertiesConstraint) { + if (pc_always_different (m_options.prop_constraint)) { m_different_polygons = true; } diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index b48e6cdaf..5c3c63c9d 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -1658,7 +1658,7 @@ protected: for (size_t n = 0; n < results.size (); ++n) { for (auto i = results_wo_props [n].begin (); i != results_wo_props [n].end (); ++i) { - results [n].insert (db::object_with_properties (*i, s2p->first)); + results [n].insert (db::object_with_properties (*i, pc_norm (m_prop_constraint, s2p->first))); } } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 1becfa40e..c0630158d 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -858,7 +858,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op, db::PropertyC { DeepLayer dl_out (deep_layer ().derived ()); - if (property_constraint == db::IgnoreProperties) { + if (pc_skip (property_constraint)) { db::BoolAndOrNotLocalOperation op (and_op); @@ -893,7 +893,7 @@ DeepRegion::and_and_not_with (const DeepRegion *other, PropertyConstraint proper DeepLayer dl_out1 (deep_layer ().derived ()); DeepLayer dl_out2 (deep_layer ().derived ()); - if (property_constraint == db::IgnoreProperties) { + if (pc_skip (property_constraint)) { db::TwoBoolAndNotLocalOperation op; @@ -1840,7 +1840,7 @@ EdgePairsDelegate * DeepRegion::cop_to_edge_pairs (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) { DeepEdgePairs *output = 0; - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { output = region_cop_impl (this, node); } else { output = region_cop_with_properties_impl (this, node, prop_constraint); @@ -1856,7 +1856,7 @@ RegionDelegate * DeepRegion::cop_to_region (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) { DeepRegion *output = 0; - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { output = region_cop_impl (this, node); } else { output = region_cop_with_properties_impl (this, node, prop_constraint); @@ -1872,7 +1872,7 @@ EdgesDelegate * DeepRegion::cop_to_edges (db::CompoundRegionOperationNode &node, db::PropertyConstraint prop_constraint) { DeepEdges *output = 0; - if (prop_constraint == db::IgnoreProperties) { + if (pc_skip (prop_constraint)) { output = region_cop_impl (this, node); } else { output = region_cop_with_properties_impl (this, node, prop_constraint); @@ -1894,7 +1894,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons } // force different polygons in the different properties case to skip intra-polygon checks - if (options.prop_constraint == DifferentPropertiesConstraint) { + if (pc_always_different (options.prop_constraint)) { different_polygons = true; } @@ -2004,7 +2004,7 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c for (db::Shapes::shape_iterator s = shapes.begin (db::ShapeIterator::Polygons); ! s.at_end (); ++s) { - edge2edge_check_negative_or_positive edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, options.prop_constraint == db::IgnoreProperties ? 0 : s->prop_id ()); + edge2edge_check_negative_or_positive edge_check (check, result, options.negative, false /*does not require different polygons*/, false /*does not require different layers*/, options.shielded, true /*symmetric edge pairs*/, pc_remove (options.prop_constraint) ? 0 : s->prop_id ()); poly2poly_check poly_check (edge_check); db::Polygon poly; diff --git a/src/db/db/dbLocalOperationUtils.h b/src/db/db/dbLocalOperationUtils.h index e18d975f8..77a813f2a 100644 --- a/src/db/db/dbLocalOperationUtils.h +++ b/src/db/db/dbLocalOperationUtils.h @@ -341,9 +341,8 @@ separate_interactions_by_properties (const shape_interactionssecond.begin (); ii != i->second.end (); ++ii) { const std::pair > &intruder = interactions.intruder_shape (*ii); - db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmi (intruder.second.properties_id ())); - if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) { + if (pc_match (property_constraint, prop_id, pmi (intruder.second.properties_id ()))) { s2p.second.insert (&intruder.second); } @@ -382,9 +381,8 @@ separate_interactions_to_interactions_by_properties (const shape_interactions > &intruder = interactions.intruder_shape (*ii); tl_assert (intruder.first < (unsigned int) pmis.size ()); - db::properties_id_type intruder_prop_id = (property_constraint == db::NoPropertyConstraint ? prop_id : pmis[intruder.first] (intruder.second.properties_id ())); - if ((property_constraint == db::DifferentPropertiesConstraint) == (prop_id != intruder_prop_id)) { + if (pc_match (property_constraint, prop_id, pmis[intruder.first] (intruder.second.properties_id ()))) { s2p.add_interaction (i->first, *ii); intruder_ids.insert (*ii); } diff --git a/src/db/db/dbPropertyConstraint.h b/src/db/db/dbPropertyConstraint.h index c4a19cc0a..b59a4f7a8 100644 --- a/src/db/db/dbPropertyConstraint.h +++ b/src/db/db/dbPropertyConstraint.h @@ -26,6 +26,7 @@ #define HDR_dbPropertyConstraint #include "dbCommon.h" +#include "dbTypes.h" namespace db { @@ -56,14 +57,74 @@ enum PropertyConstraint */ SamePropertiesConstraint = 2, + /** + * @brief Shapes are processed if their properties are the same + * + * No properties are attached to the output. + */ + SamePropertiesConstraintDrop = 3, + /** * @brief Shapes are processed if their properties are different * * Properties are attached to the outputs where applicable. */ - DifferentPropertiesConstraint = 3 + DifferentPropertiesConstraint = 4, + + /** + * @brief Shapes are processed if their properties are different + * + * No properties are attached to the output. + */ + DifferentPropertiesConstraintDrop = 5 }; +/** + * @brief Returns a predicate indicating whether properties need to be considered + */ +bool inline pc_skip (PropertyConstraint pc) +{ + return pc == IgnoreProperties; +} + +/** + * @brief Returns a predicate indicating whether properties are always different + */ +bool inline pc_always_different (PropertyConstraint pc) +{ + return pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop; +} + +/** + * @brief Returns a value indicating whether two properties satisfy the condition + */ +bool inline pc_match (PropertyConstraint pc, db::properties_id_type a, db::properties_id_type b) +{ + if (pc == SamePropertiesConstraint || pc == SamePropertiesConstraintDrop) { + return a == b; + } else if (pc == DifferentPropertiesConstraint || pc == DifferentPropertiesConstraintDrop) { + return a != b; + } else { + return true; + } +} + +/** + * @brief Returns a value indicating whether the property can be removed on output + */ +bool inline pc_remove (PropertyConstraint pc) +{ + return pc == IgnoreProperties || pc == SamePropertiesConstraintDrop || pc == DifferentPropertiesConstraintDrop; +} + +/** + * @brief Returns a normalized property for output + */ +db::properties_id_type inline pc_norm (PropertyConstraint pc, db::properties_id_type prop_id) +{ + return pc_remove (pc) ? 0 : prop_id; +} + } #endif diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index 13a5ce031..aaaa73cf3 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -782,7 +782,7 @@ check_local_operation_with_properties::do_compute_local (db::Layout *lay } for (auto r = result.begin (); r != result.end (); ++r) { - results.front ().insert (db::EdgePairWithProperties (*r, s2p->first)); + results.front ().insert (db::EdgePairWithProperties (*r, pc_norm (check_local_operation_base::m_options.prop_constraint, s2p->first))); } } @@ -1668,8 +1668,7 @@ bool_and_or_not_local_operation_with_properties::do_compute_local (d for (auto j = i->second.begin (); j != i->second.end (); ++j) { const db::object_with_properties &intruder = interactions.intruder_shape (*j).second; - db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s); - if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) { + if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) { shapes_by_prop.second.insert (intruder); } } @@ -1684,7 +1683,7 @@ bool_and_or_not_local_operation_with_properties::do_compute_local (d size_t p1 = 0, p2 = 1; const std::set &others = p2s->second.second; - db::properties_id_type prop_id = p2s->first; + db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first); for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) { @@ -1857,8 +1856,7 @@ two_bool_and_not_local_operation_with_properties::do_compute_local ( for (auto j = i->second.begin (); j != i->second.end (); ++j) { const db::object_with_properties &intruder = interactions.intruder_shape (*j).second; - db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? m_pmi (intruder.properties_id ()) : prop_id_s); - if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) { + if (pc_match (m_property_constraint, prop_id_s, m_pmi (intruder.properties_id ()))) { shapes_by_prop.second.insert (intruder); } } @@ -1873,7 +1871,7 @@ two_bool_and_not_local_operation_with_properties::do_compute_local ( size_t p1 = 0, p2 = 1; const std::set &others = p2s->second.second; - db::properties_id_type prop_id = p2s->first; + db::properties_id_type prop_id = pc_norm (m_property_constraint, p2s->first); for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) { diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 04ad9ae04..6170da161 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -3172,10 +3172,20 @@ gsi::EnumIn decl_Region_PropertyConstraint ( "When using this constraint - for example on a boolean operation - shapes are considered " "only if their user properties are the same. Properties are generated on the output shapes where applicable." ) + + gsi::enum_const ("SamePropertiesConstraintDrop", db::SamePropertiesConstraintDrop, + "@brief Specifies to consider shapes only if their user properties are the same\n" + "When using this constraint - for example on a boolean operation - shapes are considered " + "only if their user properties are the same. No properties are generated on the output shapes." + ) + gsi::enum_const ("DifferentPropertiesConstraint", db::DifferentPropertiesConstraint, "@brief Specifies to consider shapes only if their user properties are different\n" "When using this constraint - for example on a boolean operation - shapes are considered " "only if their user properties are different. Properties are generated on the output shapes where applicable." + ) + + gsi::enum_const ("DifferentPropertiesConstraintDrop", db::DifferentPropertiesConstraintDrop, + "@brief Specifies to consider shapes only if their user properties are different\n" + "When using this constraint - for example on a boolean operation - shapes are considered " + "only if their user properties are the same. No properties are generated on the output shapes." ), "@brief This class represents the property constraint for boolean and check functions.\n" "\n" diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 2c166ee4f..a5bd6286d 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -267,6 +267,13 @@ module DRC # # m1m2_overlap_connected = metal1.nets.and(metal2, props_eq) # @/code + # + # "props_eq" can be combined with \props_copy. In this case, properties + # are transferred to the output shapes and can be used in further processing: + # + # @code + # m1m2_overlap_connected = metal1.nets.and(metal2, props_eq + props_copy) + # @/code # # See also \props_ne. @@ -291,6 +298,13 @@ module DRC # m1m2_overlap_not_connected = metal1.nets.and(metal2, props_ne) # @/code # + # "props_ne" can be combined with \props_copy. In this case, properties + # are transferred to the output shapes and can be used in further processing: + # + # @code + # m1m2_overlap_connected = metal1.nets.and(metal2, props_ne + props_copy) + # @/code + # # See also \props_eq. # %DRC% diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 2ff441a03..0747afedf 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -3781,10 +3781,17 @@ CODE # @code # # \props_copy is a special properties constraint that does not alter the behaviour of - # the checks, but copies the primary shape's properties to the output markers - # (a behaviour that is implied by \props_eq and \props_ne, but not there by default). + # the checks, but copies the primary shape's properties to the output markers. # This constraint is applicable to \width and \notch checks too. The effect is that # the original polygon's properties are copied to the error markers. + # \props_copy can be combined with \props_eq and \props_ne to copy the original + # shape's properties to the output too: + # + # @code + # space_not_connected = metal1_nets.space(0.4.um, props_ne + props_copy) + # space_connected = metal1_nets.space(0.4.um, props_eq + props_copy) + # @code + # # %DRC% # @name space diff --git a/src/drc/drc/built-in-macros/_drc_tags.rb b/src/drc/drc/built-in-macros/_drc_tags.rb index aabb84c52..495f458d1 100644 --- a/src/drc/drc/built-in-macros/_drc_tags.rb +++ b/src/drc/drc/built-in-macros/_drc_tags.rb @@ -151,6 +151,30 @@ module DRC def initialize(v) self.value = v end + def is_eq? + self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::SamePropertiesConstraintDrop + end + def is_ne? + self.value == RBA::Region::DifferentPropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraintDrop + end + def is_copy? + self.value == RBA::Region::NoPropertyConstraint || self.value == RBA::Region::SamePropertiesConstraint || self.value == RBA::Region::DifferentPropertiesConstraint + end + def +(other) + other.is_a?(DRCPropertiesConstraint) || raise("'+' needs to be applied to two properties constraints (got #{other.inspect} for the second one)") + is_eq = self.is_eq? || other.is_eq? + is_ne = self.is_ne? || other.is_ne? + is_copy = self.is_copy? || other.is_copy? + if is_eq == is_ne + DRCPropertiesConstraint::new(is_copy ? RBA::Region::NoPropertyConstraint : RBA::Region::IgnoreProperties) + elsif is_eq + DRCPropertiesConstraint::new(is_copy ? RBA::Region::SamePropertiesConstraint : RBA::Region::SamePropertiesConstraintDrop) + elsif is_ne + DRCPropertiesConstraint::new(is_copy ? RBA::Region::DifferentPropertiesConstraint : RBA::Region::DifferentPropertiesConstraintDrop) + else + nil + end + end end # Negative output on checks diff --git a/testdata/drc/drcSimpleTests_70.drc b/testdata/drc/drcSimpleTests_70.drc index 28c67a740..860fe612c 100644 --- a/testdata/drc/drcSimpleTests_70.drc +++ b/testdata/drc/drcSimpleTests_70.drc @@ -40,15 +40,15 @@ l4_wp.output(16, 0) # booleans with properties constraints -l3_wp.and(l4_wp, props_eq).output(20, 0) -l3_wp1.and(l4_wp, props_eq).output(21, 0) -l3_wp2as1.and(l4_wp, props_eq).output(22, 0) -l3_nowp.and(l4_wp, props_eq).output(23, 0) +l3_wp.and(l4_wp, props_eq + props_copy).output(20, 0) +l3_wp1.and(l4_wp, props_eq + props_copy).output(21, 0) +l3_wp2as1.and(l4_wp, props_eq + props_copy).output(22, 0) +l3_nowp.and(l4_wp, props_eq + props_copy).output(23, 0) -l3_wp.and(l4_wp, props_ne).output(30, 0) -l3_wp1.and(l4_wp, props_ne).output(31, 0) -l3_wp2as1.and(l4_wp, props_ne).output(32, 0) -l3_nowp.and(l4_wp, props_ne).output(33, 0) +l3_wp.and(l4_wp, props_ne + props_copy).output(30, 0) +l3_wp1.and(l4_wp, props_ne + props_copy).output(31, 0) +l3_wp2as1.and(l4_wp, props_ne + props_copy).output(32, 0) +l3_nowp.and(l4_wp, props_ne + props_copy).output(33, 0) l3_wp.and(l4_wp, props_copy).output(40, 0) l3_wp1.and(l4_wp, props_copy).output(41, 0) @@ -79,15 +79,15 @@ l1.nets("NOTEXIST", "NOTEXIST").output(113, 0) l1_nets = l1.nets l1_nets.space(1.0.um, projection).polygons.output(200, 0) -l1_nets.space(1.0.um, projection, props_eq).polygons.output(201, 0) -l1_nets.space(1.0.um, projection, props_ne).polygons.output(202, 0) +l1_nets.space(1.0.um, projection, props_eq + props_copy).polygons.output(201, 0) +l1_nets.space(1.0.um, projection, props_ne + props_copy).polygons.output(202, 0) l1_nets.space(1.0.um, projection, props_copy).polygons.output(203, 0) l1_nets.width(1.0.um, projection).polygons.output(204, 0) l1_nets.width(1.0.um, projection, props_copy).polygons.output(205, 0) l1_nets.drc(space(projection) < 1.0.um).polygons.output(210, 0) -l1_nets.drc(space(projection) < 1.0.um, props_eq).polygons.output(211, 0) -l1_nets.drc(space(projection) < 1.0.um, props_ne).polygons.output(212, 0) +l1_nets.drc(space(projection) < 1.0.um, props_eq + props_copy).polygons.output(211, 0) +l1_nets.drc(space(projection) < 1.0.um, props_ne + props_copy).polygons.output(212, 0) l1_nets.drc(space(projection) < 1.0.um, props_copy).polygons.output(213, 0) l1_nets.drc(width(projection) < 1.0.um).polygons.output(214, 0) l1_nets.drc(width(projection) < 1.0.um, props_copy).polygons.output(215, 0) @@ -103,10 +103,10 @@ l1_nets.space(1.0.um, projection, props_copy).edges.extended_in(10.nm).output(22 # sizing with properties l1_nets_sized = l1_nets.sized(0.2.um) -l1_nets_sized.and(l1_nets_sized, props_ne).output(300, 0) # overlap of different nets, same layer +l1_nets_sized.and(l1_nets_sized, props_ne + props_copy).output(300, 0) # overlap of different nets, same layer l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um)).output(310, 0) -l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne).output(311, 0) -l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq).output(312, 0) +l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_ne + props_copy).output(311, 0) +l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_eq + props_copy).output(312, 0) l1_nets.drc(primary.sized(0.2.um) & foreign.sized(0.2.um), props_copy).output(313, 0)