Vyges Loom · Physical construction

vyges-fin

Fill the gaps until every layer meets its density floor.

Verified shape for shape, and safe to re-run — fill is cleared and regenerated wholesale, so it never accumulates.

View source on GitHub →

What it does

Used by: anyone streaming out to a foundry — density rules are a tape-out gate, and fill is how you pass them.

Foundries require each metal layer to carry a minimum density across the die, because chemical-mechanical polishing behaves badly over large empty regions. Meeting that floor means placing fill shapes into every gap the design leaves — without touching a real wire, a real instance or a real obstruction.

vyges-fin computes the non-fill area per layer as the union of every placed instance’s shapes, every routed wire box (vias decomposed) and every obstruction, then tiles what remains with shapes of the sizes the rules declare.

.odb + JSON fill rules  ──►  vyges-fin  ──►  fill shapes (layer, mask, OPC flag, coordinates)

Re-running it twice gives you the same design, not twice the fill

Existing fill is cleared before filling. Fill is regenerated wholesale, never patched — so running the step again is idempotent, and an incremental flow that touches it repeatedly does not accumulate junk.

OPC fill is placed only where the rules declare an opc section, and only after non-OPC fill, clearing both the design and the fill just placed — so the two passes cannot overlap each other.

A layer the rules never mention is skipped and reported, not silently filled with a guess.

A run that filled nothing says so

Status is one of filled, planned, vacuous or error — and vacuous is not filled. It means the run placed no shape at all, and the declared assertion passes only on filled, so a no-op fails rather than reporting work that never happened.

Zero can still be the right answer — a design already above every density floor needs no fill — which is exactly why the engine reports the counts and lets you decide, instead of deciding for you.

Density is a tape-out gate, and fill is the least interesting way to miss one. Every fill is a whole shape of a size the rules declare, no two on a layer overlap, and a layer the rules never mention is skipped and reported rather than filled with a guess. It is the part of sign-off you should be able to stop thinking about.

Not maximal, and it says so: the tiling is a fixed grid anchored at each sub-area’s bounding box rather than a swept origin, so density is not maximal by construction — and the spacing check is deliberately conservative, which can exclude a position that would in fact have been legal.

Try it

$ vyges install physical   # one-time: fetch the construction engines into ~/.vyges/bin
$ vyges physical fin density-fill design.odb --rules fill-rules.json   # fill to the density floor
$ vyges physical fin density-fill design.odb --rules fill-rules.json \
    --area '0 0 500 500'   # fill one rectangle only
$ vyges physical fin density-fill design.odb --rules fill-rules.json --dry-run   # plan it, write nothing

Exit status is the verdict: 0 filled or vacuous (read the count) · 1 refused · 2 error.

Where it sits in the flow

Last, or nearly — after routing, when the gaps are final. The fill it places is geometry that vyges-drc then checks for density on the streamed-out layout: one suite builds the fill, another proves it met the rule.

Open core · Apache-2.0

A clean-room Rust engine writing the shared design database through vyges-opendb, so the block you check is the block you built. See all the engines & the data spine →