Skip to content

h12b: 45-degree kinds, stage 2 continued - #36

Merged
OmarSiwy merged 4 commits into
verification-hardeningfrom
agent/h12b
Oct 12, 2026
Merged

OmarSiwy merged 4 commits into
verification-hardeningfrom
agent/h12b

Conversation

@OmarSiwy

Copy link
Copy Markdown
Contributor

H12 stage 2 for the remaining geometric kinds on 45-degree geometry, kind by kind (enclosure first), each with hand-derived cases under the eight grid symmetries, the KLayout mirror on random octilinear layouts and the foundry decks; then stage 3 (DRC-116). Commits say per kind what measures 45-degree shapes and what still refuses.

The enclosure modes the foundries' KLayout decks check by edge pairs
(enclosing without touching edges, enclosed and enclosing by
projection) need KLayout's pair semantics on 45-degree edges: which
pairs count at all, how each edge is cut to the other's inner side,
and the near part each keeps. relation::pair_threshold2 ports
EdgeRelationFilter::check (default angle_limit, no projection bounds)
with euclidian_near_part_of_edge and var_near_part_of_edge, and
returns the least distance, twice squared, at which a pair is
reported. KLayout computes in floating point; here every crossing of
an axis edge with a 45-degree line is a lattice point and every
distance exact. projected_reach2 reads whether a reported part
reaches a corner (sky130's adjacent-sides idiom).

derive::inside_flags exposes inside_into's covered-polygon test.

Oracle: differential against narrowest_pair2, itself held to KLayout
by the nightly mirror: the width read pair by pair through the port
equals it on random merged octilinear shapes over 300 named seeds. A
port that misreads a cut, an angle, a zero-distance mode or a near
part disagrees on some figure.
min_enclosure, noncoincident_enclosure, asymmetric_enclosure and
adjacent_enclosure refused any layer with a 45-degree edge. Where
either layer has one, the rule now hosts each inner polygon in the
merged outer figure that covers it (inside_flags) and reads:

- every side: the Euclidean distance between the boundaries, exact;
- non-coincident, opposite and adjacent: the edge pairs the foundry
  decks check them by (relation::pair_threshold2), so an inner edge
  also pairs with a host edge at 45 degrees to it. Opposite and
  adjacent take rectangular inner shapes (cuts), as the decks do, and
  refuse one with a 45-degree edge.

full_width and an enclosure with a wire band still refuse: both cut
their layers into rectangles. Rectilinear layers take the old path
unchanged.

The octilinear KLayout differential gains a cut layer (squares placed
in met1 shapes' boxes, never meeting, as the mirror's enclosed reads
their merge) and the four kinds, plus min_enclosure and
noncoincident_enclosure of 45-degree met2 in met1.

Oracles: hand-derived cases in tests/drc_octilinear.rs (a square
`sqrt(1250)` from a chamfer, a diamond, an unhosted square, a triangle
on a chamfer, a square read past chamfers), each under the eight grid
symmetries; the KLayout mirror on 1500 random octilinear layouts,
which agrees on every layout (min_enclosure flagged on 2736 runs,
noncoincident 2704, opposite 1062, adjacent 1042). Goldens of the
three 45-degree fixtures record the enclosure rules as ran. A host
edge ignored, a misread pair angle or a missing near-part cut fails
the hand cases or the differential.
@OmarSiwy OmarSiwy added the heavy Run the nightly test tier on this pull request label Oct 12, 2026
Reading IHP's sg13g2_stdcell.gds whole, where every top cell sits at
the origin, tripped decompose_into's debug assertion ("a polygon's
rectangles cover exactly its area", 5563800 vs 2922600). The
decomposition was right; the polygon reaching it was not.
sg13g2_dfrbpq_2's Activ is one keyhole BOUNDARY around a hole; the
reader splits it into its outer and the hole, stored one after the
other. Validation then bound each hole to the smallest-boxed outer
holding its first vertex, and another cell's Activ drawn over the hole
(holding its corners, not its middle) won: that shape gained a hole
it does not cover, so its even-odd fill exceeded its claimed area,
and the keyhole lost its hole.

A reader stores a polygon's holes right after its outer (a keyhole, a
boolean's result), so validation now binds a hole to the nearest
outer row before it when that outer holds it, and falls back to the
innermost outer holding it only otherwise.

Oracles: construct-from-answer. A notched square stored before a
100-square and its hole: the hole is the 100-square's and both
decompose to exactly their areas (geom test); the same reduced from
the GDS, a keyhole written after the overlapping shape and read back
(tests/test_all.rs), which trips the original assertion without the
fix. The whole library now loads and runs every rule of
pdks/ihp_sg13g2.deck in a debug build.
must_be_inside and must_contain refused any layer with a 45-degree
edge. Where either layer has one, both layers are merged and read
exactly: an inner figure is held where the outer covers it
(inside_flags) and counted in the figure holding it; the area an
inner figure leaves outside is the sum of the outside parts
(subtraction_into) inside it, exact, reported rounded up so half a
unit outside reads 1. Rectilinear layers take the old path.

The octilinear KLayout differential gains inside(met2, met1),
inside(via1, met1) and contains(met1, via1) >= 1.

Oracles: hand-derived (a diamond inside an octagon, one halved by its
chamfer, outside 100; a half-unit triangle outside, reported 1; one
diamond held where two are asked) under the eight grid symmetries;
the KLayout mirror on 1500 random octilinear layouts agrees on every
one (must_be_inside flagged on 2336 runs, must_contain 1297). The
full local suite passes; CI was not waited for (stopped by the
coordinator).
@OmarSiwy

Copy link
Copy Markdown
Contributor Author

Landed on verification-hardening (workspace tests run locally; merge tier green on ab6b9f1).

@OmarSiwy
OmarSiwy merged commit e61fe8a into verification-hardening Oct 12, 2026
7 checks passed
@OmarSiwy
OmarSiwy deleted the agent/h12b branch October 12, 2026 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

heavy Run the nightly test tier on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant