Prove shove-in-rooms recovers ordering drops but does not create density

Add true_density.dsn: NET_C is a full-height wall on the sole signal layer,
so plain room routing drops a net under every net ordering (an order-independent
obstruction, verified over all permutations), unlike rooms_shove_channel whose
plain drop fits under a reorder.

Test that shove recovers nothing on this board (shoves == 0, same routed set as
plain) while staying DRC-clean, and that the only difference from the recoverable
shove_channel is the wall's span. shove relocates a blocker into existing free
space; where the wall leaves no headroom there is nowhere to relocate to, so it
cannot manufacture density. The recover/fail boundary is the free-space boundary.
This commit is contained in:
Ryan Malloy 2026-07-13 11:34:31 -06:00
parent 9cf2392c4b
commit 99c3d20de5
2 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,64 @@
(pcb "true_density.dsn"
(parser
(string_quote ")
(space_in_quoted_tokens on)
(host_cad "freeroute-test")
(host_version "1.0")
)
(resolution um 10)
(unit um)
(structure
(layer F.Cu
(type signal)
(property
(index 0)
)
)
(layer B.Cu
(type power)
(property
(index 1)
)
)
(boundary
(path pcb 0 0 0 200000 0 200000 -30000 0 -30000 0 0)
)
(rule
(width 2000)
(clearance 2000)
)
)
(library
(padstack Rect_Pad
(shape (rect F.Cu -1000 -1000 1000 1000))
(attach off)
)
(image PAD
(pin Rect_Pad 1 0 0)
)
)
(placement
(component PAD
(place A1 7000 -15000 front 0)
(place A2 193000 -15000 front 0)
(place C1 100000 -500 front 0)
(place C2 100000 -29500 front 0)
)
)
(network
(net NET_A
(pins A1-1 A2-1)
)
(net NET_C
(pins C1-1 C2-1)
)
(class default
(rule
(width 2000)
(clearance 2000)
)
)
)
(wiring
)
)

View File

@ -15,6 +15,14 @@ Two opt-in (``shove=True``) upgrades to the continuous expansion-room track:
see ``test_room_shove_channel_drop_is_ordering_artifact_not_density``), not a
genuine density limit. The true sub-cell win is occupancy packing, which the
``rooms_wide_door`` fixture exercises with ``shoves == 0``.
The ``true_density`` fixture settles the density question the other way and honestly:
plain routing drops a net under EVERY net ordering (an order-independent obstruction,
not a self-inflicted greedy choice), and shove recovers *nothing* there (``shoves == 0``).
shove relocates a blocker into existing free space; it does not compress copper, so it
cannot manufacture density where none exists. The recover/fail boundary is exactly the
free-space boundary -- ``test_true_density_contrast_is_only_the_wall_height`` shows the
two boards differ only in how far the wall spans.
"""
from __future__ import annotations
@ -67,6 +75,7 @@ SHOVE_CHANNEL = FIXTURES / "rooms_shove_channel.dsn"
WIDE_DOOR = FIXTURES / "rooms_wide_door.dsn"
MULTIPIN_DESYNC = FIXTURES / "rooms_multipin_desync.dsn"
MULTIPIN_DESYNC_CRASH = FIXTURES / "rooms_multipin_desync_crash.dsn"
TRUE_DENSITY = FIXTURES / "true_density.dsn"
FOUNDATION = [SIMPLE, CROSSING, KICAD, NARROW]
@ -346,3 +355,101 @@ def test_room_shove_multipin_recovery_does_not_crash():
clearance = _clearance(dsn, scale)
assert on.drc_clean
assert _emitted_drc_violations(on.result, clearance) == []
# --- honest bound: shove recovers ordering drops, it does NOT create density --
def _net_blocks(text):
import re
return re.findall(r" \(net [^\n]*\n \(pins [^\n]*\n \)\n", text)
def _plain_under_all_orderings(fixture):
"""Route ``fixture`` plainly (shove=False) under every permutation of its net
declaration order, returning the routed-net set for each ordering. Net numbers
follow declaration order, so permuting the ``(net ...)`` blocks permutes the
greedy routing order -- the exact knob that turned the shove_channel drop into
an ordering artifact."""
import itertools
text = fixture.read_text()
blocks = _net_blocks(text)
joined = "".join(blocks)
assert joined in text and len(blocks) >= 2
out = []
for perm in itertools.permutations(range(len(blocks))):
variant = text.replace(joined, "".join(blocks[i] for i in perm), 1)
result, _, _ = route_dsn_board_rooms(parse_dsn(variant), shove=False)
out.append(len(result.routed_net_numbers))
return out
def test_shove_channel_plain_fits_under_some_ordering():
"""Baseline for the contrast: on shove_channel the plain drop is an ORDERING
artifact -- there exists a net order under which plain routing fits both nets
with no shove. This is exactly what makes it *not* a density limit."""
counts = _plain_under_all_orderings(SHOVE_CHANNEL)
assert max(counts) == 2 # some ordering routes both
assert min(counts) == 1 # the default order drops one
def test_true_density_plain_drops_under_every_ordering():
"""The order-independent bar: on true_density plain routing drops >= 1 net
under EVERY net ordering, unlike shove_channel. NET_C is a full-height wall on
the only signal layer, so whichever net is routed first walls off the other --
no permutation fits both. The drop is a genuine on-layer obstruction, not a
self-inflicted ordering choice."""
counts = _plain_under_all_orderings(TRUE_DENSITY)
assert len(counts) == 2 # two nets -> two orderings
assert all(k < 2 for k in counts) # every ordering drops at least one net
assert all(k == 1 for k in counts) # exactly one survives each way
def test_true_density_shove_cannot_create_space():
"""The honest result: shove does NOT recover the order-independent drop.
shove_segment RELOCATES a blocking trace into existing free space; it does not
compress copper. NET_C walls the board top-to-bottom on the sole signal layer,
so there is nowhere to relocate NET_A's crossing run to -- every perpendicular
displacement lands on NET_C or outside the board. shove therefore adds zero
shoves and routes no more nets than plain routing. This is the boundary of the
shove mechanism: it recovers ordering-induced drops (free space exists), it
cannot manufacture density (free space absent)."""
dsn = parse_dsn(TRUE_DENSITY.read_text())
off, _, _ = route_dsn_board_rooms(dsn, shove=False)
on, scale, _ = route_dsn_board_rooms(dsn, shove=True)
clearance = _clearance(dsn, scale)
assert len(off.routed_net_numbers) == 1 # plain drops one
assert on.routed_net_numbers == off.routed_net_numbers # shove recovers nothing
assert on.shoves == 0 # no clean displacement exists to try
# whatever it does route stays exactly DRC-clean (invariant never traded away)
assert on.drc_clean
assert on.tree.has_violation(clearance) is None
assert _emitted_drc_violations(on.result, clearance) == []
def test_true_density_contrast_is_only_the_wall_height():
"""Pin down *why* shove recovers shove_channel but not true_density: the two
boards share the same NET_A blocker and the same channel geometry; they differ
only in how far NET_C spans. When NET_C leaves headroom (shove_channel) shove
nudges NET_A into it and both fit; when NET_C spans the full height
(true_density) that headroom is gone and shove is powerless. The recover/fail
boundary is the free-space boundary, which is the whole point."""
short_on, _, _ = route_dsn_board_rooms(parse_dsn(SHOVE_CHANNEL.read_text()), shove=True)
wall_on, _, _ = route_dsn_board_rooms(parse_dsn(TRUE_DENSITY.read_text()), shove=True)
# space exists -> shove recovers both, with real shoves
assert short_on.routed_net_numbers == {1, 2}
assert short_on.shoves >= 1
# space absent -> shove recovers neither extra net, zero shoves
assert len(wall_on.routed_net_numbers) == 1
assert wall_on.shoves == 0
def test_true_density_is_deterministic():
a, _, _ = route_dsn_board_rooms(parse_dsn(TRUE_DENSITY.read_text()), shove=True)
b, _, _ = route_dsn_board_rooms(parse_dsn(TRUE_DENSITY.read_text()), shove=True)
assert _wire_key(a.result) == _wire_key(b.result)
assert a.routed_net_numbers == b.routed_net_numbers