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())))