Date: Tue, 25 Jun 2024 22:20:48 +0200
Subject: [PATCH] Added documentation for new DRC feature
---
scripts/drc_lvs_doc/create_drc_samples.rb | 30 ++++++++++
src/doc/doc/about/drc_ref_layer.xml | 54 +++++++++++++++--
src/doc/doc/images/drc_sized_inside1.png | Bin 0 -> 6696 bytes
src/doc/doc/images/drc_sized_inside2.png | Bin 0 -> 6900 bytes
src/doc/doc/images/drc_sized_inside3.png | Bin 0 -> 7080 bytes
src/doc/doc/images/drc_sized_inside4.png | Bin 0 -> 6697 bytes
src/doc/docDRCLVSResources.qrc | 4 ++
src/drc/drc/built-in-macros/_drc_layer.rb | 67 +++++++++++++---------
8 files changed, 125 insertions(+), 30 deletions(-)
create mode 100644 src/doc/doc/images/drc_sized_inside1.png
create mode 100644 src/doc/doc/images/drc_sized_inside2.png
create mode 100644 src/doc/doc/images/drc_sized_inside3.png
create mode 100644 src/doc/doc/images/drc_sized_inside4.png
diff --git a/scripts/drc_lvs_doc/create_drc_samples.rb b/scripts/drc_lvs_doc/create_drc_samples.rb
index 2799b88e1..5a9c1c332 100644
--- a/scripts/drc_lvs_doc/create_drc_samples.rb
+++ b/scripts/drc_lvs_doc/create_drc_samples.rb
@@ -914,6 +914,36 @@ run_demo gen, "input.sized(1.um, octagon_limit)", "drc_sized4.png"
run_demo gen, "input.sized(1.um, square_limit)", "drc_sized5.png"
run_demo gen, "input.sized(1.um, acute_limit)", "drc_sized6.png"
+class Gen
+ def produce(s1, s2)
+ pts = [
+ RBA::Point::new(1000, 1000),
+ RBA::Point::new(1000, 2000),
+ RBA::Point::new(2000, 2000),
+ RBA::Point::new(2000, 1000)
+ ];
+ s1.insert(RBA::Polygon::new(pts))
+ pts = [
+ RBA::Point::new(1000, 1000),
+ RBA::Point::new(1000, 7000),
+ RBA::Point::new(6000, 7000),
+ RBA::Point::new(6000, 1000),
+ RBA::Point::new(5000, 1000),
+ RBA::Point::new(5000, 6000),
+ RBA::Point::new(2000, 6000),
+ RBA::Point::new(2000, 1000)
+ ];
+ s2.insert(RBA::Polygon::new(pts))
+ end
+end
+
+gen = Gen::new
+
+run_demo gen, "input1.sized(1.um, steps(1), inside(input2))", "drc_sized_inside1.png"
+run_demo gen, "input1.sized(2.um, steps(2), inside(input2))", "drc_sized_inside2.png"
+run_demo gen, "input1.sized(3.um, steps(3), inside(input2))", "drc_sized_inside3.png"
+run_demo gen, "input1.sized(10.um, steps(10), inside(input2))", "drc_sized_inside4.png"
+
class Gen
def produce(s1, s2)
pts = [
diff --git a/src/doc/doc/about/drc_ref_layer.xml b/src/doc/doc/about/drc_ref_layer.xml
index 9dd40b6ca..7b03a95e1 100644
--- a/src/doc/doc/about/drc_ref_layer.xml
+++ b/src/doc/doc/about/drc_ref_layer.xml
@@ -3056,18 +3056,27 @@ The following images shows the effect of some rectangle filter modes:
Usage:
- layer.size(d [, mode])
-- layer.size(dx, dy [, mode]))
+- layer.size(d, inside(l) [, steps(n)] [, mode])
+- layer.size(d, outside(l) [, steps(n)] [, mode])
+- layer.size(dx, dy [, mode])
+- layer.size(dx, dy, inside(l) [, steps(n)] [, mode])
+- layer.size(dx, dy, outside(l) [, steps(n)] [, mode])
-See sized. The size method basically does the same but modifies the layer
+See sized for a description of the options.
+The size method basically does the same but modifies the layer
it is called on. The input layer is returned and available for further processing.
"sized" - Polygon sizing (per-edge biasing)
Usage:
-- layer.sized(d [, mode])
-- layer.sized(dx, dy [, mode]))
+- layer.sized(d [, mode] [, inside(l) [, steps(n)]])
+- layer.sized(d, inside(l) [, steps(n)] [, mode])
+- layer.sized(d, outside(l) [, steps(n)] [, mode])
+- layer.sized(dx, dy [, mode])
+- layer.sized(dx, dy, inside(l) [, steps(n)] [, mode])
+- layer.sized(dx, dy, outside(l) [, steps(n)] [, mode])
This method requires a polygon layer. It will apply a bias per edge of the polygons
@@ -3100,6 +3109,30 @@ layer.sized(300.nm).raw.merged(2)
Bias 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 "inside" option and the "steps" option implement incremental size. Incremental
+size means that the sizing value is applied in n steps. Between the steps, the sized
+shape is confined to the "inside" layer by means of a boolean "AND" operation.
+
+This scheme is used to implement latch-up rules where a device active region has to
+be close to a well tap. By using the well layer as the "inside" layer, the size function
+follows the well contours. The steps have to selected such that the per-step size value
+is smaller than the minimum space of the well shapes. With that, the sized shapes will
+not cross over to neighbor well regions. Specifically, the per-step size has to be less
+than about 70% of the minimum space to account for the minimum corner-to-corner case
+with Euclidian space measurements.
+
+"inside" and "steps" can be used with positive sizing values only.
+
+"outside" acts like "inside", but instead of confining the sized region to the
+inside of the given layer, it is confined to be outside of that layer. Technically,
+a boolean "NOT" is performed instead of a boolean "AND".
+
+An example for the "inside" option is this:
+
+
+ntap.sized(30.um, inside(nwell), steps(100))
+
+