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/compact-power-routes.py
"""Remove redundant same-layer power-wire cycles and merge chains, preserving every junction.
Each spanning forest retains connectivity between all original wire vertices.
"""
import json,math
from pathlib import Path
from collections import defaultdict
c=json.load(open('dist/index/circuit.json'));d=json.load(open('design/routed-copper.json'));names={e['source_net_id']:e['name'] for e in c if e['type']=='source_net'}
protected={(round(p['x'],6),round(p['y'],6)) for p in c if p['type']=='pcb_port'}
before=sum(map(len,d['nets'].values()))
for sid,routes in d['nets'].items():
if names.get(sid) not in {'GND','V3V3','V1V8','VDD_CORE','VDD_MPU','DDR_1V5','A3V3','RTC_1V8'}:continue
keep=[r for r in routes if any(p['route_type']=='via' for p in r)];bylayer=defaultdict(set)
for r in routes:
if any(p['route_type']=='via' for p in r):continue
for a,b in zip(r,r[1:]):
assert a['layer']==b['layer']
aa=(round(a['x'],6),round(a['y'],6));bb=(round(b['x'],6),round(b['y'],6))
if aa!=bb:bylayer[a['layer']].add(tuple(sorted((aa,bb))))
for layer,edges in bylayer.items():
parent={}
def root(p):
parent.setdefault(p,p)
while parent[p]!=p:parent[p]=parent[parent[p]];p=parent[p]
return p
adj=defaultdict(set)
for a,b in sorted(edges,key=lambda e:math.dist(*e)):
ra,rb=root(a),root(b)
if ra==rb:continue
parent[rb]=ra;adj[a].add(b);adj[b].add(a)
breaks={p for p,ns in adj.items() if len(ns)!=2 or p in protected};seen=set()
for start in breaks:
for nxt in adj[start]:
if tuple(sorted((start,nxt))) in seen:continue
points=[start,nxt];seen.add(tuple(sorted((start,nxt))));prev,cur=start,nxt
while cur not in breaks:
other=next(v for v in adj[cur] if v!=prev);seen.add(tuple(sorted((cur,other))));points.append(other);prev,cur=cur,other
keep.append([dict(route_type='wire',x=x,y=y,width=.1,layer=layer) for x,y in points])
d['nets'][sid]=keep
# All indices have changed; future plane-tree regeneration must begin from this checkpoint.
d['planeBaseRouteCounts']={}
Path('design/routed-copper.json').write_text(json.dumps(d,separators=(',',':'))+'\n')
print('Compacted route records:',before,'->',sum(map(len,d['nets'].values())))