diff --git a/src/db/db/gsiDeclDbCompoundOperation.cc b/src/db/db/gsiDeclDbCompoundOperation.cc index f12ac1944..dde1c2a51 100644 --- a/src/db/db/gsiDeclDbCompoundOperation.cc +++ b/src/db/db/gsiDeclDbCompoundOperation.cc @@ -862,7 +862,7 @@ gsi::EnumIn decl_dbRegionRatioFilter_ParameterType ("db", "ParameterType", +gsi::EnumIn decl_dbRegionRatioFilter_ParameterType ("db", "RatioParameterType", gsi::enum_const ("AreaRatio", db::RegionRatioFilter::AreaRatio, "@brief Measures the area ratio (bounding box area / polygon area)\n" ) + diff --git a/src/drc/drc/built-in-macros/_drc_complex_ops.rb b/src/drc/drc/built-in-macros/_drc_complex_ops.rb index c3df1adf3..3ae166c66 100644 --- a/src/drc/drc/built-in-macros/_drc_complex_ops.rb +++ b/src/drc/drc/built-in-macros/_drc_complex_ops.rb @@ -399,7 +399,7 @@ CODE # The plain function is equivalent to "primary.bbox_aspect_ratio". def bbox_aspect_ratio - DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AspectRatio, self) + DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::AspectRatio, self) end # %DRC% @@ -430,7 +430,7 @@ CODE # The plain function is equivalent to "primary.bbox_aspect_ratio". def relative_height - DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::RelativeHeight, self) + DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::RelativeHeight, self) end # %DRC% @@ -459,7 +459,7 @@ CODE # The plain function is equivalent to "primary.area_ratio". def area_ratio - DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AreaRatio, self) + DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::AreaRatio, self) end # %DRC% @@ -1240,7 +1240,7 @@ class DRCOpNodeWithCompare < DRCOpNode attr_accessor :reverse attr_accessor :original attr_accessor :lt, :le, :gt, :ge, :arg - attr_accessor :ne_allowed + attr_accessor :mode_or_supported attr_accessor :mode_or def initialize(engine, original = nil, reverse = false) @@ -1249,7 +1249,7 @@ class DRCOpNodeWithCompare < DRCOpNode self.original = original self.description = original ? original.description : "BasicWithCompare" self.mode_or = false - self.ne_allowed = false + self.mode_or_supported = false end def _description_for_dump @@ -1313,17 +1313,21 @@ class DRCOpNodeWithCompare < DRCOpNode end def !=(other) - if !self.ne_allowed - raise("!= operator is not allowed for '" + self.description + "'") + if self.respond_to?(:inverted) + res = self.==(other).inverted + else + if !self.mode_or_supported + raise("!= operator is not allowed for '" + self.description + "'") + end + if !(other.is_a?(Float) || other.is_a?(Integer)) + raise("!= operator needs a numerical argument for '" + self.description + "' argument") + end + res = self._self_or_original + res.mode_or = true + res.set_lt(other) + res.set_gt(other) end - if !(other.is_a?(Float) || other.is_a?(Integer)) - raise("!= operator needs a numerical argument for '" + self.description + "' argument") - end - res = self._self_or_original - res.mode_or = true - res.set_lt(other) - res.set_gt(other) - return res + res end def ==(other) @@ -1680,7 +1684,7 @@ class DRCOpNodeCheck < DRCOpNodeWithCompare self.other = other self.args = args self.description = check.to_s - self.ne_allowed = true + self.mode_or_supported = true end def _description_for_dump @@ -1772,6 +1776,39 @@ class DRCOpNodeBBoxParameterFilter < DRCOpNodeWithCompare end +class DRCOpNodeRatioParameterFilter < DRCOpNodeWithCompare + + attr_accessor :input + attr_accessor :parameter + attr_accessor :inverse + + def initialize(engine, parameter, input) + super(engine) + self.parameter = parameter + self.input = input + self.inverse = false + self.description = parameter.to_s + end + + def do_create_node(cache) + args = [ self.input.create_node(cache), self.parameter, self.inverse ] + args << (self.gt ? self.gt : (self.ge ? self.ge : 0.0)) + args << (self.gt ? false : true) + if self.lt || self.le + args << (self.lt ? self.lt : self.le) + args << (self.lt ? false : true) + end + RBA::CompoundRegionOperationNode::new_ratio_filter(*args) + end + + def inverted + res = self.dup + res.inverse = !res.inverse + return res + end + +end + class DRCOpNodeCornersFilter < DRCOpNodeWithCompare attr_accessor :input diff --git a/src/drc/drc/built-in-macros/_drc_cop_integration.rb b/src/drc/drc/built-in-macros/_drc_cop_integration.rb index 768eb211f..5ce9df8c7 100644 --- a/src/drc/drc/built-in-macros/_drc_cop_integration.rb +++ b/src/drc/drc/built-in-macros/_drc_cop_integration.rb @@ -652,16 +652,16 @@ CODE # the operation acts similar to \Layer#with_angle. %w( + angle area holes hulls + length odd_polygons perimeter rectangles - squares rectilinear - length - angle + squares ).each do |f| # NOTE: these methods are fallback for the respective global ones which route to DRCLayer or here. eval <<"CODE" diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index b3fd5e93e..5dbe50541 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1603,6 +1603,7 @@ CODE moved non_rectangles non_rectilinear + non_squares non_strict not notch @@ -1646,6 +1647,7 @@ CODE snap snapped space + squares start_segments strict texts @@ -1656,7 +1658,9 @@ CODE width with_angle with_area + with_area_ratio with_bbox_area + with_bbox_area_ratio with_bbox_height with_bbox_max with_bbox_min @@ -1664,13 +1668,17 @@ CODE with_length without_angle without_area + without_area_ratio without_bbox + without_bbox_area_ratio without_bbox_height without_bbox_max without_bbox_min without_length without_perimeter + without_relative_height with_perimeter + with_relative_height xor ).each do |f| eval <<"CODE" diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 5ef059555..bccc40bdc 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -600,12 +600,12 @@ CODE if args.size == 1 a = args[0] if a.is_a?(Range) - DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a.first), @engine._make_numeric_value(a.last), #{inv.inspect})) + DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a.first), @engine._make_numeric_value(a.last), #{inv.inspect})) else - DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a), #{inv.inspect})) + DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a), #{inv.inspect})) end elsif args.size == 2 - DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(args[0]), @engine._make_numeric_value(args[1]), #{inv.inspect})) + DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(args[0]), @engine._make_numeric_value(args[1]), #{inv.inspect})) else raise("Invalid number of arguments (1 or 2 expected)") end diff --git a/src/drc/unit_tests/drcGenericTests.cc b/src/drc/unit_tests/drcGenericTests.cc index ecd5e7caa..538925c36 100644 --- a/src/drc/unit_tests/drcGenericTests.cc +++ b/src/drc/unit_tests/drcGenericTests.cc @@ -198,3 +198,13 @@ TEST(13d) { run_test (_this, "13", true); } + +TEST(14) +{ + run_test (_this, "14", false); +} + +TEST(14d) +{ + run_test (_this, "14", true); +} diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index 4306e99b7..81a76a140 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -1127,3 +1127,13 @@ TEST(25d_spaceWithOptions) { run_test (_this, "25", true); } + +TEST(26_attributes) +{ + run_test (_this, "26", false); +} + +TEST(26d_attributes) +{ + run_test (_this, "26", true); +} diff --git a/testdata/drc/drcGenericTests_14.drc b/testdata/drc/drcGenericTests_14.drc new file mode 100644 index 000000000..c762a3108 --- /dev/null +++ b/testdata/drc/drcGenericTests_14.drc @@ -0,0 +1,36 @@ + +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep +end + +l1 = input(1, 0) +l2 = input(2, 0) +l3 = input(3, 0) + +l1.output(1, 0) +l2.output(2, 0) +l3.output(3, 0) + +ar = 4.0/3.0 # "L" shape +l1.drc(area_ratio == ar).output(100, 0) +l1.drc(primary.area_ratio != ar).output(101, 0) +l1.drc(primary.area_ratio > ar).output(102, 0) +l1.drc(primary.area_ratio < ar).output(103, 0) + +l1.drc(squares).output(110, 0) +l1.drc(! primary.squares).output(111, 0) + +l2.drc(bbox_aspect_ratio == 2).output(120, 0) +l2.drc(bbox_aspect_ratio == 1).output(121, 0) +l2.drc(bbox_aspect_ratio <= 1).output(122, 0) +l2.drc(bbox_aspect_ratio > 2).output(123, 0) + +l2.drc(relative_height == 2).output(130, 0) +l2.drc(relative_height == 1).output(131, 0) +l2.drc(relative_height <= 1).output(132, 0) +l2.drc(relative_height > 2).output(133, 0) + + diff --git a/testdata/drc/drcGenericTests_14.gds b/testdata/drc/drcGenericTests_14.gds new file mode 100644 index 000000000..5ef6b30e3 Binary files /dev/null and b/testdata/drc/drcGenericTests_14.gds differ diff --git a/testdata/drc/drcGenericTests_au14.gds b/testdata/drc/drcGenericTests_au14.gds new file mode 100644 index 000000000..d1f255073 Binary files /dev/null and b/testdata/drc/drcGenericTests_au14.gds differ diff --git a/testdata/drc/drcGenericTests_au14d.gds b/testdata/drc/drcGenericTests_au14d.gds new file mode 100644 index 000000000..1b0f1b8ed Binary files /dev/null and b/testdata/drc/drcGenericTests_au14d.gds differ diff --git a/testdata/drc/drcSimpleTests_26.drc b/testdata/drc/drcSimpleTests_26.drc new file mode 100644 index 000000000..e9ddf0e79 --- /dev/null +++ b/testdata/drc/drcSimpleTests_26.drc @@ -0,0 +1,36 @@ + +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep +end + +l1 = input(1, 0) +l2 = input(2, 0) +l3 = input(3, 0) + +l1.output(1, 0) +l2.output(2, 0) +l3.output(3, 0) + +ar = 4.0/3.0 # "L" shape +l1.with_area_ratio(ar).output(100, 0) +l1.without_area_ratio(ar).output(101, 0) +l1.without_area_ratio(0..ar).output(102, 0) +l1.with_area_ratio(0.0, ar-1e-6).output(103, 0) + +l1.squares.output(110, 0) +l1.non_squares.output(111, 0) + +l2.with_bbox_aspect_ratio(2).output(120, 0) +l2.with_bbox_aspect_ratio(1).output(121, 0) +l2.with_bbox_aspect_ratio(0..1).output(122, 0) +l2.without_bbox_aspect_ratio(0..2).output(123, 0) + +l2.with_relative_height(2).output(130, 0) +l2.with_relative_height(1).output(131, 0) +l2.with_relative_height(0..1).output(132, 0) +l2.without_relative_height(0..2).output(133, 0) + + diff --git a/testdata/drc/drcSimpleTests_26.gds b/testdata/drc/drcSimpleTests_26.gds new file mode 100644 index 000000000..5ef6b30e3 Binary files /dev/null and b/testdata/drc/drcSimpleTests_26.gds differ diff --git a/testdata/drc/drcSimpleTests_au26.gds b/testdata/drc/drcSimpleTests_au26.gds new file mode 100644 index 000000000..d1f255073 Binary files /dev/null and b/testdata/drc/drcSimpleTests_au26.gds differ diff --git a/testdata/drc/drcSimpleTests_au26d.gds b/testdata/drc/drcSimpleTests_au26d.gds new file mode 100644 index 000000000..5e03be23d Binary files /dev/null and b/testdata/drc/drcSimpleTests_au26d.gds differ