seveibar/am3352-dev-board
A 324-ball TI AM3352 ARM processor with DDR3, LCD, USB, Ethernet, storage, serial, analog, clock, reset, power, and JTAG interfaces, paired with configurable JST-GH board connectors and constrained PCB routing.
- Version
- 1.0.2
- License
- unset
- Stars
- 0
scripts/save-phase.py
"""Turn successful autorouter output into checked tscircuit saved phase paths."""
import json,sys,collections,math
from pathlib import Path
phase=int(sys.argv[1]); d=Path('dist/autorouter-debug')
s=json.loads((d/'board.source-and-pcb.circuit.json').read_text())
pads={e['pcb_port_id']:e for e in s if e['type']=='pcb_port'}
ports={e['source_port_id']:e for e in s if e['type']=='source_port'}
parts={e['source_component_id']:e['name'] for e in s if e['type']=='source_component'}
edges=json.loads((d/f'phase-{phase}.output.traces.json').read_text())
def match(point):
found=[p for p in pads.values() if math.hypot(p['x']-point['x'],p['y']-point['y'])<1e-4 and point.get('layer',point.get('from_layer')) in p['layers']]
assert len(found)==1,(point,found)
return found[0]['pcb_port_id']
def reverse(route):
r=[]
for point in route[::-1]:
p=dict(point)
if p['route_type']=='via':p['from_layer'],p['to_layer']=p['to_layer'],p['from_layer']
r.append(p)
return r
pending=[(match(e['route'][0]),match(e['route'][-1]),e['route']) for e in edges]
paths=[]
while pending:
degree=collections.Counter(p for a,b,_ in pending for p in (a,b))
for i,(a,b,route) in enumerate(pending):
if degree[a]==1 or degree[b]==1:
if degree[a]!=1:a,b,route=b,a,reverse(route)
port=ports[pads[a]['source_port_id']]
paths.append({'connection':f".{parts[port['source_component_id']]} > .pin{port['pin_number']}",'route':route})
pending.pop(i);break
else:raise ValueError('Route graph has a cycle; cannot convert with a unique starting port')
out=Path(f'design/phase-{phase+1}-routes.json');out.write_text(json.dumps(paths,indent=2)+'\n');print(out,len(paths))