Enabling 'enclosed' as a (sometimes) more efficient way of implementing an enclosing check.

This commit is contained in:
Matthias Koefferlein 2021-11-08 23:18:01 +01:00
parent 2fd9401013
commit 4a44329e38
15 changed files with 275 additions and 11 deletions

View File

@ -452,6 +452,22 @@ run_demo gen, "input1.drc(enclosing(input2) < 2.0.um)", "drc_enc1u.png"
run_demo gen, "input1.drc(enclosing(input2,\n"+
" projection) < 2.0.um)", "drc_enc2u.png"
class Gen
def produce(s1, s2)
s1.insert(RBA::Box::new(3000, 0, 6000, 6000))
s2.insert(RBA::Box::new(0, 1000, 6000, 7000))
end
end
gen = Gen::new
run_demo gen, "input1.enclosed(input2, 2.0.um)", "drc_encd1.png"
run_demo gen, "input1.enclosed(input2, 2.0.um, projection)", "drc_encd2.png"
run_demo gen, "input1.drc(enclosed(input2) < 2.0.um)", "drc_encd1u.png"
run_demo gen, "input1.drc(enclosed(input2,\n"+
" projection) < 2.0.um)", "drc_encd2u.png"
class Gen
def produce(s1, s2)

View File

@ -460,6 +460,11 @@ static db::CompoundRegionOperationNode *new_enclosing_check (db::CompoundRegionO
return new_check_node (other, db::OverlapRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative);
}
static db::CompoundRegionOperationNode *new_enclosed_check (db::CompoundRegionOperationNode *other, db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative)
{
return new_check_node (other, db::InsideRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative);
}
static db::CompoundRegionOperationNode *new_perimeter_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits<db::Coord>::perimeter_type pmin, db::coord_traits<db::Coord>::perimeter_type pmax)
{
check_non_null (input, "input");
@ -673,6 +678,11 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
gsi::constructor ("new_enclosing_check", &new_enclosing_check, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false),
"@brief Creates a node providing an inside (enclosure) check.\n"
) +
gsi::constructor ("new_enclosed_check", &new_enclosed_check, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false),
"@brief Creates a node providing an enclosed (secondary enclosing primary) check.\n"
"\n"
"This method has been added in version 0.27.5.\n"
) +
gsi::constructor ("new_perimeter_filter", &new_perimeter_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::perimeter_type>::max (), "max"),
"@brief Creates a node filtering the input by perimeter.\n"
"This node renders the input if the perimeter is between pmin and pmax (exclusively). If 'inverse' is set to true, the "

View File

@ -1160,7 +1160,7 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("inside_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"),
method_ext ("inside_check|enclosed_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"),
"@brief Performs an inside check with options\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
@ -1186,6 +1186,8 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
"It is sufficient if the projection of one edge on the other matches the specified condition. "
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
"\n"
"The 'enclosed_check' alias was introduced in version 0.27.5.\n"
) +
method_ext ("enclosing_check", &enclosing2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"),
"@brief Performs an enclosing check with options\n"

View File

@ -2591,7 +2591,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
"\n"
"The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27."
) +
method_ext ("inside_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false),
method_ext ("inside_check|enclosed_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false),
"@brief Performs an inside check with options\n"
"@param d The minimum distance for which the polygons are checked\n"
"@param other The other region against which to check\n"
@ -2639,6 +2639,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
"\n"
"The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. "
"The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n"
"The 'enclosed_check' alias was introduced in version 0.27.5.\n"
) +
method_ext ("overlap_check", &overlap2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false),
"@brief Performs an overlap check with options\n"

View File

@ -1888,7 +1888,7 @@ class DRCOpNodeCheck < DRCOpNodeWithCompare
factory = { :width => :new_width_check, :space => :new_space_check,
:notch => :new_notch_check, :separation => :new_separation_check,
:isolated => :new_isolated_check, :overlap => :new_overlap_check,
:enclosing => :new_enclosing_check }[self.check]
:enclosing => :new_enclosing_check, :enclosed => :new_enclosed_check }[self.check]
oargs = []
if self.other

View File

@ -1042,6 +1042,84 @@ CODE
# actual edges from the first input (see \separation for an example).
#
# %DRC%
# @name enclosed
# @brief Performs an enclosing check (other enclosing layer)
# @synopsis enclosed(other [, options ]) (in conditions)
# @synopsis enclosed(layer, other [, options ])
#
# This check verifies if the polygons of the input layer are enclosed by shapes
# of the other input layer by a certain distance.
# It has manifold options. See \Layer#width for the basic options such
# as metrics, projection and angle constraints etc. This check also features
# opposite and rectangle filtering. See \Layer#separation for details about opposite and
# rectangle error filtering.
#
# This function is essentially the reverse of \enclosing. In case of
# "enclosed", the other layer must be bigger than the primary layer.
#
# @h3 Classic mode @/h3
#
# This function can be used in classic mode with a layer argument. In this case it
# is equivalent to "layer.enclosed" (see \Layer#enclosed).
#
# @code
# # classic "enclosed" check for < 0.2 um
# in = layer(1, 0)
# other = layer(2, 0)
# errors = enclosed(in, other, 0.2.um)
# @/code
#
# @h3 Universal DRC @/h3
#
# The version without a first layer is intended for use within \DRC# expressions
# together with the "universal DRC" method \Layer#drc. In this case, this function needs to be
# put into a condition to specify the check constraints. The other options
# of \Layer#enclosed (e.g. metrics, projection constraints, angle limits etc.)
# apply to this version too:
#
# @code
# # universal DRC "enclosed" check for < 0.2 um
# in = layer(1, 0)
# other = layer(2, 0)
# errors = in.drc(enclosed(other) < 0.2.um)
# @/code
#
# The conditions may involve an upper and lower limit. The following examples
# illustrate the use of this function with conditions:
#
# @code
# out = in.drc(enclosed(other) < 0.2.um)
# out = in.drc(enclosed(other) <= 0.2.um)
# out = in.drc(enclosed(other) > 0.2.um)
# out = in.drc(enclosed(other) >= 0.2.um)
# out = in.drc(enclosed(other) == 0.2.um)
# out = in.drc(enclosed(other) != 0.2.um)
# out = in.drc(0.1.um <= enclosed(other) < 0.2.um)
# @/code
#
# The result of the enclosed check are edges or edge pairs forming the markers.
# These markers indicate the presence of the specified condition.
#
# With a lower and upper limit, the results are edges marking the positions on the
# primary shape where the condition is met.
# With a lower limit alone, the results are edge pairs which are formed by two identical, but opposite edges attached to
# the primary shape. Without an upper limit only, the first edge of the marker is attached to the
# primary shape while the second edge is attached to the shape of the "other" layer.
#
# @table
# @tr
# @td @img(/images/drc_encd1u.png) @/td
# @td @img(/images/drc_encd2u.png) @/td
# @/tr
# @/table
#
# When "larger than" constraints are used, this function will produce the edges from the
# first layer only. The result will still be edge pairs for consistency, but each edge pair holds one edge from
# the original polygon plus a reverse copy of that edge in the second member. Use "first_edges" to extract the
# actual edges from the first input (see \separation for an example).
#
# %DRC%
# @name separation
# @brief Performs a separation check
@ -1367,6 +1445,7 @@ CODE
%w(
enclosing
enclosed
isolated
notch
overlap

View File

@ -1751,6 +1751,7 @@ CODE
%w(
enc
enclosing
enclosed
overlap
sep
separation

View File

@ -3756,7 +3756,7 @@ CODE
# %DRC%
# @name enclosing
# @brief An enclosing check
# @brief An enclosing check (layer enclosing other_layer)
# @synopsis layer.enclosing(other_layer, value [, options])
# @synopsis layer.enc(other_layer, value [, options])
#
@ -3764,8 +3764,8 @@ CODE
# the \DRC framework. These variants have more options and are more intuitive to use.
# See \global#enclosing for more details.
#
# This method checks whether layer encloses (is bigger than) other_layer by the
# given dimension. Locations, where this is not the case will be reported in form
# This method checks whether layer encloses (is bigger than) other_layer by not less than the
# given distance value. Locations, where the distance is less will be reported in form
# of edge pair error markers.
# Locations, where both edges coincide will be reported as errors as well. Formally
# such locations form an enclosure with a distance of 0. Locations, where other_layer
@ -3794,13 +3794,48 @@ CODE
# @/tr
# @/table
%w(width space overlap enclosing separation isolated notch).each do |f|
# %DRC%
# @name enclosed
# @brief An enclosing check (other_layer enclosing layer)
# @synopsis layer.enclosed(other_layer, value [, options])
#
# @b Note: @/b "enclosed" is available as operators for the "universal DRC" function \drc within
# the \DRC framework. These variants have more options and are more intuitive to use.
# See \global#enclosed for more details.
#
# This method checks whether layer is enclosed by (is inside of) other_layer by not less than the
# given distance value. Locations, where the distance is less will be reported in form
# of edge pair error markers.
# Locations, where both edges coincide will be reported as errors as well. Formally
# such locations form an enclosure with a distance of 0. Locations, where other_layer
# is inside layer will not be reported as errors. Such regions can be detected
# by \inside or a boolean "not" operation.
#
# The options are the same as for \separation.
#
# This method is available for edge and polygon layers.
#
# As for the other DRC methods, merged semantics applies.
#
# Distance values can be given as floating-point values (in micron) or integer values (in
# database units). To explicitly specify the unit, use the unit denominators.
#
# The following images show the effect of two enclosed checks (red: input1, blue: input2):
#
# @table
# @tr
# @td @img(/images/drc_encd1.png) @/td
# @td @img(/images/drc_encd2.png) @/td
# @/tr
# @/table
%w(width space overlap enclosing enclosed separation isolated notch).each do |f|
eval <<"CODE"
def #{f}(*args)
@engine._context("#{f}") do
if :#{f} == :width || :#{f} == :space || :#{f} == :overlap || :#{f} == :enclosing || :#{f} == :separation
if :#{f} == :width || :#{f} == :space || :#{f} == :overlap || :#{f} == :enclosed || :#{f} == :enclosing || :#{f} == :separation
requires_edges_or_region
else
requires_region

View File

@ -536,6 +536,85 @@ See <a href="/about/drc_ref_source.xml#edges">Source#edges</a> for a description
<p>
"enc" is the short form for <a href="#enclosing">enclosing</a>.
</p>
<a name="enclosed"/><h2>"enclosed" - Performs an enclosing check (other enclosing layer)</h2>
<keyword name="enclosed"/>
<p>Usage:</p>
<ul>
<li><tt>enclosed(other [, options ]) (in conditions)</tt></li>
<li><tt>enclosed(layer, other [, options ])</tt></li>
</ul>
<p>
This check verifies if the polygons of the input layer are enclosed by shapes
of the other input layer by a certain distance.
It has manifold options. See <a href="/about/drc_ref_layer.xml#width">Layer#width</a> for the basic options such
as metrics, projection and angle constraints etc. This check also features
opposite and rectangle filtering. See <a href="/about/drc_ref_layer.xml#separation">Layer#separation</a> for details about opposite and
rectangle error filtering.
</p><p>
This function is essentially the reverse of <a href="#enclosing">enclosing</a>. In case of
"enclosed", the other layer must be bigger than the primary layer.
</p><p>
<h3>Classic mode </h3>
</p><p>
This function can be used in classic mode with a layer argument. In this case it
is equivalent to "layer.enclosed" (see <a href="/about/drc_ref_layer.xml#enclosed">Layer#enclosed</a>).
</p><p>
<pre>
# classic "enclosed" check for &lt; 0.2 um
in = layer(1, 0)
other = layer(2, 0)
errors = enclosed(in, other, 0.2.um)
</pre>
</p><p>
<h3>Universal DRC </h3>
</p><p>
The version without a first layer is intended for use within <a href="/about/drc_ref_drc.xml">DRC</a> expressions
together with the "universal DRC" method <a href="/about/drc_ref_layer.xml#drc">Layer#drc</a>. In this case, this function needs to be
put into a condition to specify the check constraints. The other options
of <a href="/about/drc_ref_layer.xml#enclosed">Layer#enclosed</a> (e.g. metrics, projection constraints, angle limits etc.)
apply to this version too:
</p><p>
<pre>
# universal DRC "enclosed" check for &lt; 0.2 um
in = layer(1, 0)
other = layer(2, 0)
errors = in.drc(enclosed(other) &lt; 0.2.um)
</pre>
</p><p>
The conditions may involve an upper and lower limit. The following examples
illustrate the use of this function with conditions:
</p><p>
<pre>
out = in.drc(enclosed(other) &lt; 0.2.um)
out = in.drc(enclosed(other) &lt;= 0.2.um)
out = in.drc(enclosed(other) &gt; 0.2.um)
out = in.drc(enclosed(other) &gt;= 0.2.um)
out = in.drc(enclosed(other) == 0.2.um)
out = in.drc(enclosed(other) != 0.2.um)
out = in.drc(0.1.um &lt;= enclosed(other) &lt; 0.2.um)
</pre>
</p><p>
The result of the enclosed check are edges or edge pairs forming the markers.
These markers indicate the presence of the specified condition.
</p><p>
With a lower and upper limit, the results are edges marking the positions on the
primary shape where the condition is met.
With a lower limit alone, the results are edge pairs which are formed by two identical, but opposite edges attached to
the primary shape. Without an upper limit only, the first edge of the marker is attached to the
primary shape while the second edge is attached to the shape of the "other" layer.
</p><p>
<table>
<tr>
<td><img src="/images/drc_encd1u.png"/></td>
<td><img src="/images/drc_encd2u.png"/></td>
</tr>
</table>
</p><p>
When "larger than" constraints are used, this function will produce the edges from the
first layer only. The result will still be edge pairs for consistency, but each edge pair holds one edge from
the original polygon plus a reverse copy of that edge in the second member. Use "first_edges" to extract the
actual edges from the first input (see <a href="#separation">separation</a> for an example).
</p>
<a name="enclosing"/><h2>"enclosing" - Performs an enclosing check</h2>
<keyword name="enclosing"/>
<p>Usage:</p>

View File

@ -778,7 +778,44 @@ individual ones unless raw mode is chosen.
<p>
See <a href="#enclosing">enclosing</a> for a description of that method
</p>
<a name="enclosing"/><h2>"enclosing" - An enclosing check</h2>
<a name="enclosed"/><h2>"enclosed" - An enclosing check (other_layer enclosing layer)</h2>
<keyword name="enclosed"/>
<p>Usage:</p>
<ul>
<li><tt>layer.enclosed(other_layer, value [, options])</tt></li>
</ul>
<p>
<b>Note: </b>"enclosed" is available as operators for the "universal DRC" function <a href="#drc">drc</a> within
the <a href="#DRC">DRC</a> framework. These variants have more options and are more intuitive to use.
See <a href="/about/drc_ref_global.xml#enclosed">enclosed</a> for more details.
</p><p>
This method checks whether layer is enclosed by (is inside of) other_layer by not less than the
given distance value. Locations, where the distance is less will be reported in form
of edge pair error markers.
Locations, where both edges coincide will be reported as errors as well. Formally
such locations form an enclosure with a distance of 0. Locations, where other_layer
is inside layer will not be reported as errors. Such regions can be detected
by <a href="#inside">inside</a> or a boolean "not" operation.
</p><p>
The options are the same as for <a href="#separation">separation</a>.
</p><p>
This method is available for edge and polygon layers.
</p><p>
As for the other DRC methods, merged semantics applies.
</p><p>
Distance values can be given as floating-point values (in micron) or integer values (in
database units). To explicitly specify the unit, use the unit denominators.
</p><p>
The following images show the effect of two enclosed checks (red: input1, blue: input2):
</p><p>
<table>
<tr>
<td><img src="/images/drc_encd1.png"/></td>
<td><img src="/images/drc_encd2.png"/></td>
</tr>
</table>
</p>
<a name="enclosing"/><h2>"enclosing" - An enclosing check (layer enclosing other_layer)</h2>
<keyword name="enclosing"/>
<p>Usage:</p>
<ul>
@ -790,8 +827,8 @@ See <a href="#enclosing">enclosing</a> for a description of that method
the <a href="#DRC">DRC</a> framework. These variants have more options and are more intuitive to use.
See <a href="/about/drc_ref_global.xml#enclosing">enclosing</a> for more details.
</p><p>
This method checks whether layer encloses (is bigger than) other_layer by the
given dimension. Locations, where this is not the case will be reported in form
This method checks whether layer encloses (is bigger than) other_layer by not less than the
given distance value. Locations, where the distance is less will be reported in form
of edge pair error markers.
Locations, where both edges coincide will be reported as errors as well. Formally
such locations form an enclosure with a distance of 0. Locations, where other_layer

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -36,6 +36,10 @@
<file alias="drc_enc2.png">doc/images/drc_enc2.png</file>
<file alias="drc_enc1u.png">doc/images/drc_enc1u.png</file>
<file alias="drc_enc2u.png">doc/images/drc_enc2u.png</file>
<file alias="drc_encd1.png">doc/images/drc_encd1.png</file>
<file alias="drc_encd2.png">doc/images/drc_encd2.png</file>
<file alias="drc_encd1u.png">doc/images/drc_encd1u.png</file>
<file alias="drc_encd2u.png">doc/images/drc_encd2u.png</file>
<file alias="drc_overlap1.png">doc/images/drc_overlap1.png</file>
<file alias="drc_overlap2.png">doc/images/drc_overlap2.png</file>
<file alias="drc_overlap1u.png">doc/images/drc_overlap1u.png</file>