diff --git a/bench/diagnose.py b/bench/diagnose.py index 6dc268f..aa9cbcc 100644 --- a/bench/diagnose.py +++ b/bench/diagnose.py @@ -106,6 +106,15 @@ def _capture_conflicts() -> list: return log +def _wall_name(wall, names) -> str: + if isinstance(wall, str): + if wall.startswith("fixed copper of net "): + net = int(wall.rsplit(" ", 1)[1]) + return f"fixed copper of {names.get(net, net)}" + return wall + return names.get(wall, "pads/keepouts") + + def _gap(a, b) -> int: dx = max(b.ll.x - a.ur.x, a.ll.x - b.ur.x, 0) dy = max(b.ll.y - a.ur.y, a.ll.y - b.ur.y, 0) @@ -118,6 +127,25 @@ def _fresh(seen) -> GridRouter: return router +def _static_wall(router: GridRouter, node) -> str: + """What static copper closes a node: a keepout, copper already on the + board (a fixed via or track, by net), or a pad.""" + if node in router._keepout: + return "keepout" + fixed = getattr(router, "_diag_fixed", None) + if fixed is None: + fixed = router._diag_fixed = {} + margin = router.clearance + router.half_width + for net, layers, box in router.board.get_fixed_copper(): + for cell in router._cells_in_box(box, margin): + for layer in layers: + fixed[(*cell, layer)] = net + net = fixed.get(node) + if net is not None: + return f"fixed copper of net {net}" + return "pads" + + def _flood(router: GridRouter, pin, net_no: int, conns) -> tuple[int, Counter]: """How many nodes a pin can reach through free cells (up to FLOOD_LIMIT), and which other nets' copper bounds the region.""" @@ -146,7 +174,7 @@ def _flood(router: GridRouter, pin, net_no: int, conns) -> tuple[int, Counter]: for owner in owners: walls[conns[owner].net_no] += 1 if not owners: - walls[0] += 1 # a pad or keepout + walls[_static_wall(router, n)] += 1 continue seen.add(n) frontier.append(n) @@ -224,7 +252,9 @@ def diagnose( if reach < FLOOD_LIMIT: walled.append({ "pin": end, "reach": reach, - "walls": [names.get(n, "pads/keepouts") for n, _ in walls.most_common(4)], + "walls": [ + _wall_name(n, names) for n, _ in walls.most_common(4) + ], }) row["kind"] = "walled-in" if walled else "congestion" if walled: