Rip every user of a shared via, and judge vias round at the outline
Two connections of a net can share a via. The grid kept one owner per via cell next to the claim list, and the search and rip-up read only that owner: a route of another net through the via ripped the first user and left the second's via under the new trace. The exact check then threw one of them out. The search and rip-up now read the claim list, and the single owner is gone. The exact check also tested a via against the outline as its square box, whose corner reaches past a 45-degree chamfer where the round via does not. The grid keeps the via's centre its radius plus the edge clearance from the outline, as KiCad measures it; the exact check now does the same. kitspace_minisumo_v3 seed 4: 4 rejected connections to 0, 11 failed to 7.
This commit is contained in:
@@ -299,9 +299,9 @@ class GridRouter:
|
||||
self._zone_cells: dict[int, list[Node]] = {}
|
||||
# per-connection occupancy (owner = connection index)
|
||||
self._cell_owner: dict[Node, int] = {}
|
||||
self._via_owner: dict[Cell, int] = {}
|
||||
# every connection whose via covers a cell, in claim order: a via two
|
||||
# connections share still blocks after the first of them is ripped
|
||||
# connections share still blocks after the first of them is ripped,
|
||||
# and a route through it must rip all of them
|
||||
self._via_claims: dict[Cell, list[int]] = {}
|
||||
# trace halos: node -> indices of the connections claiming it
|
||||
self._halo: dict[Node, list[int]] = {}
|
||||
@@ -520,9 +520,7 @@ class GridRouter:
|
||||
if owner is not None and conns[owner].net_no != net_no:
|
||||
blocking = owner
|
||||
else:
|
||||
via_owner = self._via_owner.get(cell)
|
||||
if via_owner is not None and conns[via_owner].net_no != net_no:
|
||||
blocking = via_owner
|
||||
blocking = self._via_blocker(cell, net_no, conns)
|
||||
if blocking is None:
|
||||
for i in self._halo.get(node, ()):
|
||||
if conns[i].net_no != net_no:
|
||||
@@ -537,6 +535,17 @@ class GridRouter:
|
||||
return None
|
||||
return self.rip_penalty * (1 + rip_count)
|
||||
|
||||
def _via_others(self, cell: Cell, net_no: int, conns: list[_Connection]) -> list[int]:
|
||||
"""Connections of other nets whose via covers ``cell``: all of them,
|
||||
since two connections of a net can share one via."""
|
||||
return [i for i in self._via_claims.get(cell, ()) if conns[i].net_no != net_no]
|
||||
|
||||
def _via_blocker(self, cell: Cell, net_no: int, conns: list[_Connection]) -> int | None:
|
||||
"""The other net's via connection on ``cell`` hardest to rip (the
|
||||
penalty and the rip cap go by it), or None."""
|
||||
others = self._via_others(cell, net_no, conns)
|
||||
return max(others, key=lambda i: conns[i].rip_count) if others else None
|
||||
|
||||
def _via_cells(self, cell: Cell) -> list[Cell]:
|
||||
"""The cell a via sits in plus the neighbours its copper reaches."""
|
||||
r = self.via_reach
|
||||
@@ -927,9 +936,7 @@ class GridRouter:
|
||||
if not any(g.overlaps(t) for tiles in other for t in tiles for g in grown):
|
||||
continue
|
||||
owners.add(owner)
|
||||
via_owner = self._via_owner.get(c)
|
||||
if via_owner is not None and conns[via_owner].net_no != net_no:
|
||||
owners.add(via_owner)
|
||||
owners.update(self._via_others(c, net_no, conns))
|
||||
return owners
|
||||
|
||||
def _end_penalty(self, pin: Pin, node: Node, net_no: int, allow_ripup: bool, conns) -> float:
|
||||
@@ -1206,7 +1213,6 @@ class GridRouter:
|
||||
if conn.index not in claims:
|
||||
claims.append(conn.index)
|
||||
conn.via_halo.append(c)
|
||||
self._via_owner.setdefault(c, conn.index)
|
||||
ends = ((conn.a_end, wire_segs[0], 0), (conn.b_end, wire_segs[-1], -1)) if wire_segs else ()
|
||||
conn.stubs = []
|
||||
for pin, (layer, cells), at in ends:
|
||||
@@ -1259,11 +1265,6 @@ class GridRouter:
|
||||
claims = self._via_claims.get(cell)
|
||||
if claims is not None and conn.index in claims:
|
||||
claims.remove(conn.index)
|
||||
if self._via_owner.get(cell) == conn.index:
|
||||
if claims:
|
||||
self._via_owner[cell] = claims[0]
|
||||
else:
|
||||
del self._via_owner[cell]
|
||||
if claims is not None and not claims:
|
||||
del self._via_claims[cell]
|
||||
conn.via_halo = []
|
||||
@@ -1308,9 +1309,7 @@ class GridRouter:
|
||||
owner = self._cell_owner.get((cx, cy, cl))
|
||||
if owner is not None and conns[owner].net_no != net_no:
|
||||
owners.add(owner)
|
||||
via_owner = self._via_owner.get((cx, cy))
|
||||
if via_owner is not None and conns[via_owner].net_no != net_no:
|
||||
owners.add(via_owner)
|
||||
owners.update(self._via_others((cx, cy), net_no, conns))
|
||||
for i in self._halo.get((cx, cy, cl), ()):
|
||||
if conns[i].net_no != net_no:
|
||||
owners.add(i)
|
||||
|
||||
Reference in New Issue
Block a user