Count on a zone's connectivity only when no track can cross it
A zone outline is where copper may go, not where it ends up: on the rc4 sense board the board-wide GND pours break into islands around other nets' tracks, and treating every pad inside them as connected left 28 GND islands unjoined (63 unconnected against 42 without zones). Trust a zone only when a no-tracks rule area covers it on its layer, as the power stage's pours are covered; route the rest with tracks as before. rc4, exact engine, resolution 2: power stage 5 unconnected (JAR 12), sense board 41 (JAR 32), no DRC errors on either.
This commit is contained in:
@@ -506,6 +506,23 @@ class GridRouter:
|
||||
self._zone_cells[key] = sorted(set(nodes))
|
||||
return self._zone_cells[key]
|
||||
|
||||
def _zone_is_solid(self, zone, coverage: float = 0.95) -> bool:
|
||||
"""Whether a zone's fill can be trusted to be one piece of copper.
|
||||
|
||||
A zone outline is where copper may go, not where it will be: other
|
||||
nets' tracks through a board-wide pour break its fill into islands,
|
||||
and a pad inside the outline need not reach the rest of the net. It
|
||||
is safe to count on only when no track can cross it, which is what a
|
||||
no-tracks rule area over the zone guarantees (the rc4 power pours).
|
||||
Otherwise the zone is left out and its pads are routed with tracks.
|
||||
"""
|
||||
cells = [cell for tile in zone.tiles for cell in self._cells_in_box(tile.bounding_box(), 0)
|
||||
if zone.polygon.contains(self._cell_center(cell))]
|
||||
if not cells:
|
||||
return False
|
||||
covered = sum((*cell, zone.layer) in self._keepout for cell in cells)
|
||||
return covered >= coverage * len(cells)
|
||||
|
||||
def _group_ends(self, group, net_no: int, conns) -> dict[Node, Pin | None]:
|
||||
"""End nodes of a group, each mapped to its pin (None for a zone cell)."""
|
||||
ends: dict[Node, Pin | None] = {}
|
||||
@@ -693,7 +710,7 @@ class GridRouter:
|
||||
pins_by_net = self._pins_by_net()
|
||||
zones_by_net: dict[int, list] = {}
|
||||
for zone in self.board.get_conduction_areas():
|
||||
if zone.layer in self.layers and zone.net_nos:
|
||||
if zone.layer in self.layers and zone.net_nos and self._zone_is_solid(zone):
|
||||
zones_by_net.setdefault(zone.net_nos[0], []).append(zone)
|
||||
conns: list[_Connection] = []
|
||||
nets = set(pins_by_net) | set(zones_by_net)
|
||||
|
||||
Reference in New Issue
Block a user