vyges physical fin — CLI reference
Generated from vyges physical fin --help — this page is the tool’s own output, verbatim.
vyges physical fin — density fill: metal shapes in the gaps, to meet per-layer density rules
USAGE:
vyges physical fin density-fill <design.odb> --rules FILE [--area 'lx ly ux uy']
vyges physical fin --describe
vyges physical fin --help
OPTIONS:
--rules FILE JSON fill rules, per layer (required)
--area 'l b r t' fill this rectangle, in MICRONS (default: the core area)
--out-odb FILE write the database here (default: IN PLACE, over the input)
--out-def FILE also write the result as DEF (for diffing against a golden)
--dry-run report what would be filled, write nothing
-o FILE write the report to FILE instead of stdout
--json emit JSON (the default)
--describe print a machine-readable JSON description of the command
EXIT STATUS:
0 filled fill was placed and the database written
0 vacuous the run placed nothing -- NOT a completed fill; read the count
1 refused the design cannot be filled as asked
2 error usage error, unreadable database or rules, no DBU scale, or a failed write
Contract
Generated from vyges physical fin --describe.
fin
density fill: metal fill shapes placed in the gaps to meet per-layer density rules
Maturity: structured
density-fill {odb}
| Input | Type | Required | Description |
|---|---|---|---|
odb | string | yes | path to the design database (.odb) |
rules | string | yes | path to the JSON fill rules |
area | string | no | fill rectangle in microns, ‘lx ly ux uy’ |
out_odb | string | no | write the database here instead of in place |
out | string | no | write the report to FILE instead of stdout |
Consumes: odb
Artifacts: fill_report (report_path)
Assertion: fill-placed — passes when status equals filled
Provenance limitations
- input_hash covers the argument vector, not the content of the .odb or the rules file it names.
- status is one of filled, planned, vacuous or error. 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 it rather than reporting a fill that did not happen. Zero can still be the right answer – a design already above every density floor needs no fill – so read fills and layers_filled and decide. A dry run reports planned, which never claimed to have filled anything.
- Validated against OpenROAD density fill at a pinned commit across six cases covering a power grid, a macro, a non-rectangular core, a restricted –area and a multi-mask rules file: every fill shape matches in layer, mask, OPC flag and coordinates.
- Also checked against invariants that need no reference: every fill is a whole shape of a size the rules declare, and no two fills on a layer overlap. Those hold of any correct fill.
- Existing fill is CLEARED before filling: fill is regenerated wholesale, never patched, so re-running is idempotent rather than cumulative.
- Non-fill area is the union, per layer, of every placed instance’s shapes, every net’s routed wire boxes (vias decomposed), and every obstruction. A layer the rules do not mention is skipped and reported.
- The tiling is a fixed grid anchored at each sub-area’s bounding box. Upstream notes KLayout sweeps the tile origin looking for maximum fill and does not do so; neither does this, so fill density is not maximal by construction.
- prune() is conservative: it forbids fill near two regions that are closer than the fill spacing, which may exclude a position that would in fact have been legal.
- OPC fill is placed only where the rules state an
opcsection, and only after non-OPC fill, clearing both the design and the fill just placed. - Correlated at pin 945a9f48dc6e5cc91d865daa92c45a1094cb682c: 6 of 6 cases reproduce OpenROAD density fill exactly, fill for fill (26360, 7518, 25095, 12437, 758, 26360 shapes). Only one case has an upstream golden; the rest are ours, scored against an oracle run at our own pin. The algorithm is reimplemented from the published behaviour, not transliterated.
- MASK NUMBERING is scored, and nothing upstream reaches it: every shipped rules file states datatype as a bare number, which makes num_masks 1 and writes mask 0 on every fill. The sixth case states datatype as a list of three, which is the only thing that turns the path on. Mask assignment restarts in each sub-area and numbers rectangles y-major, matching the reference exactly; both were wrong before that case existed, on identical geometry.