"""--reserve-escapes: a crowded pin keeps a way out until it is routed.""" from __future__ import annotations from pathlib import Path from freeroute.board import build_board from freeroute.dsn import parse_dsn from freeroute.route.grid_router import GridRouter from freeroute.route.pipeline import ( _rule_clearance_dsn, _rule_width_dsn, build_exact_routing_result, ) SMD = (Path(__file__).resolve().parent.parent / "dsn" / "fixtures" / "smd_demo.dsn").read_text() def _router(): dsn = parse_dsn(SMD) s = dsn.resolution.value router = GridRouter( build_board(dsn), trace_width=round(_rule_width_dsn(dsn) * s), clearance=round(_rule_clearance_dsn(dsn) * s), orthogonal=True, resolution=2, reserve_escapes=True, ) conns = router._build_connections() router._conns = conns router._count_pending(conns) router._reserve_escapes(conns) return router, conns def test_a_reserved_escape_is_closed_to_other_nets_and_open_to_its_own(): router, conns = _router() assert router._reserved node, claims = next(iter(router._reserved.items())) pin_id, owner = claims[0] other = next(c.net_no for c in conns if c.net_no != owner) cell, layer = node[:2], node[2] assert router._enter_cost(cell, layer, other, True, conns) is None # even for rip-up assert router._enter_cost(cell, layer, owner, False, conns) is not None or node in router._keepout def test_the_escape_is_released_once_its_pin_is_routed(): router, conns = _router() node, claims = next(iter(router._reserved.items())) other = next(c.net_no for c in conns if c.net_no != claims[0][1]) cell, layer = node[:2], node[2] assert router._enter_cost(cell, layer, other, False, conns) is None for c in conns: # every connection routed: no pin is pending any more router._settle(c, -1) released = router._enter_cost(cell, layer, other, False, conns) reserved, router._reserved = router._reserved, {} assert released == router._enter_cost(cell, layer, other, False, conns) router._reserved = reserved def test_reserving_escapes_loses_nothing_on_the_demo_board(): plain = build_exact_routing_result(parse_dsn(SMD), resolution=2) reserved = build_exact_routing_result(parse_dsn(SMD), resolution=2, reserve_escapes=True) assert len(reserved.unrouted) <= len(plain.unrouted)