min_windowed_density¶
The chip is split into window × window µm tiles, and the combined density of one
or more layers must be at least value (%) in every tile.
Semantics¶
Coverage is computed on the shared merge cache (so overlapping/nested shapes are not
double-counted) and summed exactly via polygon clipping to each window, accumulated from
the cache’s own tiles so a region spanning cache tiles is still counted once. This is the
tiled analogue of min_density: instead of one chip-wide percentage, every
window-sized tile gets its own.
The tile grid always starts at the chip’s raw bounding box — the first window is
[0, window) in each axis, regardless of boundary_layer. Real chip dimensions are
rarely an exact multiple of the window size, so the last row/column of tiles is usually
smaller than a full window, and may extend past the actual seal ring entirely.
That’s what the optional boundary_layer/boundary_datatype params are for — the
same convention min_density uses. They restrict which area within each window
counts as checkable to that layer’s bounding box, not its drawn area (a seal ring is a
hollow frame; its own merged area would wildly undercount the die it encloses). Without
this, an edge or corner window that falls outside the seal ring — or only partly inside
it — is measured against its full nominal window area and can fail the density floor for
a reason that has nothing to do with underfill: there was simply nothing there to fill. A
window with zero overlap with the boundary box is skipped outright (density is undefined
for a zero-area denominator, not a violation).
This historical failure mode is worth calling out explicitly, since it’s exactly the bug
this param set was added to fix: on a 900×900 µm die with an 800 µm window and no
boundary_layer, the last row and column of tiles are measured against a doubled
(200 µm-tall) denominator, of which only the first 100 µm can ever hold real geometry —
reading roughly half the true density and falsely tripping the floor.
Layers¶
One or more layers; their merged areas are summed for the numerator, per window.
Parameters¶
windowRequired. The tile size in µm (square tiles).
boundary_layerGDS layer number for the per-window density denominator’s bounding box (e.g. a seal ring). Optional — if omitted, each window’s full nominal area is the denominator.
boundary_datatypeGDS datatype paired with
boundary_layer. Optional, defaults to0.
Violation markers¶
One edge marker per offending window, spanning its four corners, reporting the window’s actual density.
KLayout equivalent¶
layer.with_density(nil, value, tile_size, tile_boundary) — a genuinely tiled density
check (tile_count left at its default, one tile per window), with the tile boundary
set from the seal-ring layer.
Example¶
- id: M4Fil.h
check: min_windowed_density
layers: [Metal4, Metal4.filler, Metal4.mask]
value: 25.00
params:
window: 800.0
boundary_layer: 39 # EdgeSeal — density is only meaningful inside the seal ring