diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 6c6b6186a..6776eacb6 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1494,6 +1494,61 @@ CODE end + # used for two-element array output methods (e.g. andnot) + def _tcmd_a2(obj, border, result_cls1, result_cls2, method, *args) + + if @tx && @ty + + tp = RBA::TilingProcessor::new + tp.dbu = self.dbu + tp.scale_to_dbu = false + tp.tile_size(@tx, @ty) + bx = [ @bx || 0.0, border * self.dbu ].max + by = [ @by || 0.0, border * self.dbu ].max + tp.tile_border(bx, by) + + res1 = result_cls1.new + tp.output("res1", res1) + res2 = result_cls2.new + tp.output("res2", res2) + res = [ res1, res2 ] + tp.input("self", obj) + tp.threads = (@tt || 1) + args.each_with_index do |a,i| + if a.is_a?(RBA::Edges) || a.is_a?(RBA::Region) || a.is_a?(RBA::EdgePairs) || a.is_a?(RBA::Texts) + tp.input("a#{i}", a) + else + tp.var("a#{i}", a) + end + end + av = args.size.times.collect { |i| "a#{i}" }.join(", ") + tp.queue("var rr = self.#{method}(#{av}); _output(res1, rr[0]); _output(res2, rr[1])") + run_timed("\"#{method}\" in: #{src_line}", obj) do + tp.execute("Tiled \"#{method}\" in: #{src_line}") + end + + else + + if @dss + @dss.threads = (@tt || 1) + end + + res = nil + run_timed("\"#{method}\" in: #{src_line}", obj) do + res = obj.send(method, *args) + end + + end + + # enable progress + if obj.is_a?(RBA::Region) + obj.disable_progress + end + + res + + end + # used for area and perimeter only def _tdcmd(obj, border, method) diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 64033a89a..070c18ce0 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -1308,6 +1308,35 @@ CODE self + other end + # %DRC% + # @name andnot + # @brief Computes Boolean AND and NOT results at the same time + # @synopsis layer.andnot(other) + # This method returns a two-element array containing one layer for the + # AND result and one for the NOT result. + # + # This method is available for polygon layers. + # + # It can be used to initialize two variables with the AND and NOT results: + # + # @code + # (and_result, not_result) = l1.andnot(l2) + # @/code + # + # As the AND and NOT results are computed in the same sweep, calling this + # method is faster than calling AND and NOT separately. + + def andnot(other) + + requires_region("andnot") + other.requires_region("andnot") + + res = @engine._tcmd_a2(@data, 0, @data.class, @data.class, :andnot, other.data) + + [ DRCLayer::new(@engine, res[0]), DRCLayer::new(@engine, res[1]) ] + + end + # %DRC% # @name & # @brief Boolean AND operation diff --git a/testdata/drc/drcSuiteTests.drc b/testdata/drc/drcSuiteTests.drc index 55cbbedd2..26e7d5e01 100644 --- a/testdata/drc/drcSuiteTests.drc +++ b/testdata/drc/drcSuiteTests.drc @@ -31,16 +31,21 @@ def run_testsuite(dm, ic, tiled = false, hier = false) message "--- general #{lb}" - l1 = a&b + l1 = a & b l1.output(lb, dm) expect_eq(l1.is_empty?, false) + (an1, an2) = a.andnot(b) + an1.output(lb, dm + 1) + expect_eq(an1.is_empty?, false) + a.and(b).xor(l1).is_empty? || raise("xor not empty") tiled || hier || expect_eq(a.and(b).is_merged?, true) a.xor(b).output(RBA::LayerInfo::new(lb + 1, dm)) a.xor(b).xor(a ^ b).is_empty? || raise("xor not empty") a.not(b).output(lb + 2, dm) + an2.output(lb + 2, dm + 1) a.not(b).xor(a - b).is_empty? || raise("xor not empty") a.or(b).output(lb + 3, dm) a.or(b).xor(a | b).is_empty? || raise("xor not empty") diff --git a/testdata/drc/drcSuiteTests_au1.oas b/testdata/drc/drcSuiteTests_au1.oas index 47716726f..f8915df92 100644 Binary files a/testdata/drc/drcSuiteTests_au1.oas and b/testdata/drc/drcSuiteTests_au1.oas differ diff --git a/testdata/drc/drcSuiteTests_au2.oas b/testdata/drc/drcSuiteTests_au2.oas index 17b7942ef..6c57f6f21 100644 Binary files a/testdata/drc/drcSuiteTests_au2.oas and b/testdata/drc/drcSuiteTests_au2.oas differ diff --git a/testdata/drc/drcSuiteTests_au3.oas b/testdata/drc/drcSuiteTests_au3.oas index eb87b64f1..003fd6382 100644 Binary files a/testdata/drc/drcSuiteTests_au3.oas and b/testdata/drc/drcSuiteTests_au3.oas differ diff --git a/testdata/drc/drcSuiteTests_au4.oas b/testdata/drc/drcSuiteTests_au4.oas index 969c76839..0e4551375 100644 Binary files a/testdata/drc/drcSuiteTests_au4.oas and b/testdata/drc/drcSuiteTests_au4.oas differ diff --git a/testdata/drc/drcSuiteTests_au5.oas b/testdata/drc/drcSuiteTests_au5.oas index f7bda7376..53a0b9fb3 100644 Binary files a/testdata/drc/drcSuiteTests_au5.oas and b/testdata/drc/drcSuiteTests_au5.oas differ diff --git a/testdata/drc/drcSuiteTests_au6.oas b/testdata/drc/drcSuiteTests_au6.oas index ae57f6a90..51f01d3a1 100644 Binary files a/testdata/drc/drcSuiteTests_au6.oas and b/testdata/drc/drcSuiteTests_au6.oas differ