The router began as a port of FreeRouting and has grown its own engine (negotiated congestion, tree nets, exact checks, axis escapes), and 'freeroute' was one letter from the project it no longer follows. The package, module and command are now rpmroute; the freeroute command stays as an alias, and the RPMROUTE / RPMROUTE_ORACLE_JAVA variables fall back to the old FREEROUTE names. Version 2026.10.07. Routing is unchanged: a PCBench board routes to a byte-identical session either way.
44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
"""--rollback: a rip-up that loses connections is undone, leaving no trace."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from rpmroute.board import build_board
|
|
from rpmroute.dsn import parse_dsn
|
|
from rpmroute.route.grid_router import GridRouter
|
|
from rpmroute.route.pipeline import _rule_clearance_dsn, _rule_width_dsn, route_dsn_board
|
|
|
|
FIXTURES = Path(__file__).resolve().parent.parent / "dsn" / "fixtures"
|
|
|
|
|
|
def _routed_router(name):
|
|
dsn = parse_dsn((FIXTURES / name).read_text())
|
|
s = dsn.resolution.value
|
|
router = GridRouter(
|
|
build_board(dsn),
|
|
trace_width=round(_rule_width_dsn(dsn) * s),
|
|
clearance=round(_rule_clearance_dsn(dsn) * s),
|
|
rollback=True,
|
|
)
|
|
return router, router.route()
|
|
|
|
|
|
@pytest.mark.parametrize("name", ["ripup_needed.dsn", "true_density.dsn", "kicad_routable.dsn"])
|
|
def test_occupancy_only_holds_routed_connections(name):
|
|
router, _ = _routed_router(name)
|
|
conns = router._conns
|
|
assert all(conns[i].routed for i in router._cell_owner.values())
|
|
assert all(conns[i].routed for claims in router._via_claims.values() for i in claims)
|
|
assert all(conns[i].routed for claims in router._halo.values() for i in claims)
|
|
|
|
|
|
@pytest.mark.parametrize("name", ["ripup_needed.dsn", "true_density.dsn", "kicad_routable.dsn"])
|
|
def test_rollback_never_routes_fewer_than_plain_rip_up(name):
|
|
text = (FIXTURES / name).read_text()
|
|
plain, _, _ = route_dsn_board(parse_dsn(text), rollback=False)
|
|
undo, _, _ = route_dsn_board(parse_dsn(text))
|
|
assert undo.unrouted <= plain.unrouted
|