Provide a solution for #809 (density goes outside the area)

This commit is contained in:
Matthias Koefferlein 2021-05-29 10:16:30 +02:00
parent e57d573a42
commit fd1e206c56
7 changed files with 79 additions and 8 deletions

View File

@ -102,6 +102,14 @@ module DRC
DRCJoinFlag::new(true)
end
def padding_zero
DRCDensityPadding::new(:zero)
end
def padding_ignore
DRCDensityPadding::new(:ignore)
end
def diamond_limit
DRCSizingMode::new(0)
end

View File

@ -3897,6 +3897,20 @@ CODE
# # (100 and 150 tiles of 20 um each are used in horizontal and vertical direction):
# low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150))
# @/code
#
# The "padding mode" indicates how the area outside the layout's bounding box is considered.
# There are two modes:
#
# @ul
# @li @b padding_zero @/b: the outside area is considered zero density. This is the default mode. @/li
# @li @b padding_ignore @/b: the outside area is ignored for the density computation. @/li
# @/ul
#
# Example:
#
# @code
# low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), padding_ignore)
# @/code
#
# The complementary version of "with_density" is \without_density.
@ -3920,6 +3934,7 @@ CODE
tile_origin = nil
tile_count = nil
tile_boundary = nil
padding_mode = :zero
n = 1
args.each do |a|
@ -3933,6 +3948,8 @@ CODE
tile_count = a.get
elsif a.is_a?(DRCTileBoundary)
tile_boundary = a.get
elsif a.is_a?(DRCDensityPadding)
padding_mode = a.value
elsif a.is_a?(Float) || a.is_a?(1.class) || a == nil
nlimits < 2 || raise("Too many values specified")
limits[nlimits] = @engine._make_numeric_value_with_nil(a)
@ -3977,18 +3994,34 @@ CODE
tp.threads = (@engine.threads || 1)
if tile_boundary
tp.input("boundary", tile_boundary.data)
else
tp.input("boundary", RBA::Region::new(self.data.bbox))
end
tp.var("vmin", limits[0] || 0.0)
tp.var("vmax", limits[1] || 1.0)
tp.var("inverse", inverse)
tp.queue(<<"TP_SCRIPT")
_tile && (
var bx = _tile.bbox.enlarged(xoverlap, yoverlap);
var d = to_f(input.area(bx)) / to_f(bx.area);
((d > vmin - 1e-10 && d < vmax + 1e-10) != inverse) && _output(res, bx, false)
)
if padding_mode == :zero
tp.queue(<<"TP_SCRIPT")
_tile && (
var bx = _tile.bbox.enlarged(xoverlap, yoverlap);
var d = to_f(input.area(bx)) / to_f(bx.area);
((d > vmin - 1e-10 && d < vmax + 1e-10) != inverse) && _output(res, bx, false)
)
TP_SCRIPT
elsif padding_mode == :ignore
tp.queue(<<"TP_SCRIPT")
_tile && (
var bx = _tile.bbox.enlarged(xoverlap, yoverlap);
var ba = boundary.area(bx);
ba > 0 && (
var d = to_f(input.area(bx)) / to_f(ba);
((d > vmin - 1e-10 && d < vmax + 1e-10) != inverse) && _output(res, bx, false)
)
)
TP_SCRIPT
end
@engine.run_timed("\"#{method}\" in: #{@engine.src_line}", self.data) do
tp.execute("Tiled \"#{method}\" in: #{@engine.src_line}")

View File

@ -20,6 +20,14 @@ module DRC
class DRCBothEdges
end
# A wrapper for the padding modes of with_density
class DRCDensityPadding
attr_accessor :value
def initialize(v)
self.value = v
end
end
# A wrapper for the sizing mode value
class DRCSizingMode
attr_accessor :value

View File

@ -3382,6 +3382,20 @@ direction. With the "tile_origin" option this allows full control over the area
low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150))
</pre>
</p><p>
The "padding mode" indicates how the area outside the layout's bounding box is considered.
There are two modes:
</p><p>
<ul>
<li><b>padding_zero </b>: the outside area is considered zero density. This is the default mode. </li>
<li><b>padding_ignore </b>: the outside area is ignored for the density computation. </li>
</ul>
</p><p>
Example:
</p><p>
<pre>
low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), padding_ignore)
</pre>
</p><p>
The complementary version of "with_density" is <a href="#without_density">without_density</a>.
</p>
<a name="with_distance"/><h2>"with_distance" - Selects edge pairs by the distance of the edges</h2>

View File

@ -9,10 +9,18 @@ b.output(0, 0)
a.output(1, 0)
a.with_density(0..0.1, tile_size(10.um), tile_boundary(b)).output(100, 0)
a.without_density(0..0.1, tile_size(10.um)).output(101, 0)
a.without_density(0..0.1, tile_size(10.um), padding_zero).output(101, 0)
a.with_density(0.1, nil, tile_size(10.um), tile_origin(25.um, 10.um)).output(102, 0)
a.with_density(0.1, nil, tile_size(10.um, 20.um)).output(103, 0)
a.with_density(0.1, 1.0, tile_size(10.um), tile_step(10.um, 20.um)).output(104, 0)
a.with_density(0.1, nil, tile_size(10.um), tile_origin(25.um, 10.um), tile_count(10, 15)).output(105, 0)
a.with_density(0..0.1, tile_size(100.um), tile_step(10.um)).output(110, 0)
a.with_density(0..0.1, tile_size(100.um), tile_step(10.um), padding_zero).output(110, 0)
a.with_density(0..0.1, tile_size(10.um), tile_boundary(b), padding_ignore).output(200, 0)
a.without_density(0..0.1, tile_size(10.um), padding_ignore).output(201, 0)
a.with_density(0.1, nil, tile_size(10.um), tile_origin(25.um, 10.um), padding_ignore).output(202, 0)
a.with_density(0.1, nil, tile_size(10.um, 20.um), padding_ignore).output(203, 0)
a.with_density(0.1, 1.0, tile_size(10.um), tile_step(10.um, 20.um), padding_ignore).output(204, 0)
a.with_density(0.1, nil, tile_size(10.um), tile_origin(25.um, 10.um), tile_count(10, 15), padding_ignore).output(205, 0)
a.with_density(0..0.1, tile_size(100.um), tile_step(10.um), padding_ignore).output(210, 0)

Binary file not shown.

Binary file not shown.