min_enclosure

Every shape on the enclosed layer (layers[1]) must sit inside an enclosing region (layers[0]) with at least value µm of margin on all sides.

Semantics

For each enclosed shape, the engine finds the enclosing region(s) that fully contain it and measures the margin as a facing-edge-pair scan: each inner edge is paired with parallel outer edges that have positive projected overlap onto it (KLayout’s projection metric, not a raw closest-point distance), and the worst (smallest) margin among those pairs is the shape’s measured enclosure. A shape not contained by any enclosing region is itself a violation (“not enclosed at all”) unless interacting_only says otherwise.

An inner edge that lies exactly on the enclosing contour — a coincident segment, offset ~0 — is geometrically ambiguous: it’s either a genuinely flush 0-margin violation, or an artifact of the enclosed layer having been clipped to the enclosing one by an intersection virtual layer (in which case the “0 margin” isn’t a real design fact, just where the boolean cut it off). The geometry can’t tell these apart, and neither can KLayout — its rules pick per-flag. Two params mirror that choice:

  • skip_coincident drops just the coincident edge pairs, still measuring the region’s other, real margins. Used when a region is deliberately clipped to its enclosing layer on one side (e.g. a seal-ring conductor intersected with EdgeSeal) but must still be checked on the sides that aren’t.

  • skip_clipped is the stronger, region-level form: if any edge of a region is coincident with the enclosing contour, the whole region is skipped, not just that edge pair. This encodes a “surrounded entirely by” semantics — a shape that reaches the enclosing boundary at all is out of scope for this rule (typically because crossing the boundary makes it a different rule’s concern, e.g. IHP’s NW.e explicitly title-scopes itself to ties surrounded entirely by NWell; one that crosses the edge is NW.d territory instead).

Neither flag is on by default: an untouched coincident edge is treated as a real 0-margin violation (e.g. Cnt.c, where a contact genuinely straddling the edge of its active area is exactly the defect being caught).

Layers

Two layers, positional:

  1. layers[0] — the enclosing region.

  2. layers[1] — the enclosed shapes being measured.

Parameters

interacting_only

Off by default (every enclosed shape must be fully inside some enclosing region, or it’s a violation). When set, a shape that overlaps no enclosing region at all is out of scope for this rule entirely (skipped, not flagged) — mirrors KLayout’s enclosed only checking shapes that actually interact with the enclosing layer (a via nowhere near a MIM cap isn’t “a MIM via” to begin with). A shape that partially overlaps an enclosing region is still measured, using only the facing pairs on its contained side.

skip_coincident

Off by default. Ignore inner/outer edge pairs that are coincident (flush, ~0 offset) — see Semantics.

skip_clipped

Off by default. Skip the whole enclosed region if any of its edges is coincident with the enclosing contour — see Semantics. Also halo-robust: whether an edge is clipped is a purely local property of the region, unlike its remaining margins, whose owning tile can shift with per-suite halo differences.

Violation markers

  • Fully unenclosed shape (no interacting_only): one point marker at the shape’s centroid.

  • Contained (or, under interacting_only, partially overlapping) shape whose measured margin is below value: one edge marker along the facing outer wall responsible for the worst margin.

KLayout equivalent

inner.enclosed(outer, value, metric: RBA::Region::projection, ...)skip_coincident mirrors consider_intersecting_edges: false / without_distance(0); skip_clipped has no single built-in KLayout flag and is a region-level generalization of the same idea.

Example

- id: Cnt.c
  check: min_enclosure
  layers: [Activ, ContOnActivNoSRAM]
  value: 0.07
# NW.e: only ties fully surrounded by NWell are in scope — one crossing the
# boundary is NW.d's concern instead.
- id: NW.e
  check: min_enclosure
  layers: [NWell, NActivInNWellNoTGO]
  value: 0.24
  params:
    skip_clipped: 1
# Seal.d: SealActiv is itself an `Activ AND EdgeSeal` intersection, so its own
# inward edge is a clip artifact, not a real margin — skip_coincident drops just
# that edge while still checking the genuine cross-frame margins.
- id: Seal.d
  check: min_enclosure
  layers: [SealActiv, SealCont]
  value: 1.30
  params:
    skip_coincident: 1
    interacting_only: 1