Route with copper zones, and let vias into no-tracks areas
freeroute ignored the DSN's planes (KiCad's zones), so it never knew that pads in a pour are joined by it. On the rc4 power stage those pads sit inside "keep router off" areas as well, and every connection to them was dropped without a word. - Read (plane <net> <shape>) and put each zone on the board as a ConductionArea of its net. Zones are not obstacles: KiCad refills them around other nets' copper. - The grid groups each net's pads and zone pieces that copper already joins (a pad in a zone, two zones sharing a pad) and routes only between groups. A connection may end on a zone by a via inside its copper, or by a track where tracks are allowed. - wire_keepout now blocks traces only, as KiCad's "no tracks" rule area does; via_keepout only vias; keepout both, in the grid and in the exact verifier. rc4 power stage, exact engine, resolution 2: 2 unconnected, down from 8 (FreeRouting JAR: 12), no DRC errors.
This commit is contained in:
@@ -143,10 +143,16 @@ def route_board_exact(
|
||||
for obstacle in board.get_obstacle_areas():
|
||||
if obstacle.layer not in signal_layers:
|
||||
continue
|
||||
blocks = (
|
||||
"all" if obstacle.blocks_wires and obstacle.blocks_vias
|
||||
else "wires" if obstacle.blocks_wires else "vias"
|
||||
)
|
||||
for tile in obstacle.tiles:
|
||||
box = tile.bounding_box()
|
||||
if not box.is_empty():
|
||||
tree.insert(TreeShape(next(owner), -1, frozenset({obstacle.layer}), box))
|
||||
tree.insert(
|
||||
TreeShape(next(owner), -1, frozenset({obstacle.layer}), box, blocks=blocks)
|
||||
)
|
||||
|
||||
via_layers = frozenset(signal_layers)
|
||||
accepted: dict[int, _Accepted] = {}
|
||||
@@ -155,9 +161,12 @@ def route_board_exact(
|
||||
# 25-pin supply net costs that one connection, not the whole net.
|
||||
for net_no, wires, vias in sorted(result.connections, key=lambda c: c[0]):
|
||||
boxes = _copper_boxes(wires, vias, half_width, via_layers, via_half)
|
||||
wire_count = len(_copper_boxes(wires, [], half_width, via_layers, via_half))
|
||||
if any(
|
||||
tree.clearance_conflict(box, net_no, layer, clearance)
|
||||
for box, box_layers in boxes
|
||||
tree.clearance_conflict(
|
||||
box, net_no, layer, clearance, "wire" if i < wire_count else "via"
|
||||
)
|
||||
for i, (box, box_layers) in enumerate(boxes)
|
||||
for layer in box_layers
|
||||
) or (outline is not None and not all(outline.box_clear(b, edge) for b, _ in boxes)):
|
||||
continue # exact-clearance conflict -> drop (may be recovered by shove)
|
||||
|
||||
Reference in New Issue
Block a user