Adds ripup_needed.dsn: one signal layer (B.Cu is a power plane, so vias
are impossible) with two nets whose greedy order strands NET_B, but where
rip-up reroutes NET_A around NET_B to connect both.
Tests: greedy (rip_up=False) leaves >= 1 connection unrouted with no vias;
rip-up connects all with no vias; the result is deterministic across
re-runs; rip-up keeps endpoints on pads and produces no same-layer cross
between nets (ripped traces leave no orphaned occupancy). The crossing
board's single-layer test now targets the greedy path explicitly, and a
regression test asserts the real KiCad board still connects all four of
its multi-pin nets. Oracle-gated parity added for the congested board.
Adds crossing_2net.dsn: NET_A is a full-width horizontal wall and NET_B's
pins sit above and below it, so single-layer routing cannot connect NET_B
but two-layer routing succeeds by dipping to the other layer through vias.
Tests assert the multi-layer invariants: single-layer routing leaves a net
unrouted with no vias; multi-layer connects both nets with >= 1 via; the
SES contains a via scope; every via sits at a real layer transition of its
net's path; trace/via endpoints still land on the pads; traces stay on
valid layers and within the outline; and no two different nets cross on the
same layer. Oracle-gated parity tests cover the simple and crossing boards.
Implements a working autorouter and the Java-free replacement for the
freerouting.jar step: dsn_text -> parse_dsn -> build_board -> route ->
write_ses.
GridRouter is a single-layer A* maze search over a uniform occupancy
grid: a cell is blocked by another net's pad (inflated by clearance +
half trace width) or a keepout; each net's ratsnest is connected pin to
pin; a routed trace then blocks other nets. The cell path becomes a
trace polyline whose endpoints are the exact pin locations. Board-unit
paths are converted back to DSN units for the SES (wire (path ...))
scopes.
This is an MVP, not a port of FreeRouting's expansion-room maze:
free-space rooms, rip-up-and-retry, multi-layer via search, and shove
are deferred (they raise quality/coverage, not the connectivity
milestone). It reaches connectivity on boards whose nets route on one
layer without crossing.
Adds tests/dsn/fixtures/simple_2net.dsn (a guaranteed-routable 2-net
board). Invariant tests: both nets route, the emitted SES parses, every
trace stays on a valid layer and within the board outline, and every
routed net's trace endpoints sit exactly on its two pads. An oracle-gated
test asserts connectivity parity with the reference FreeRouting JAR on
the simple board.