code wiki / _hdl_build / nx_pcb_autoroute.nx

nx_pcb_autoroute.nx source

↩ module page · 43 lines · 2317 B

1// nx_pcb_autoroute.nx -- LIB: sovereign PCB copper AUTOROUTER, built by REUSING the silicon place-and-route 2// router (nx_fpga_pnr / pnr_route_net_ex). ONE shared routing engine serves BOTH FPGA fabric routing AND PCB 3// trace routing -- the "shared resources" architecture, literally. Routes a netlist of 2-pad nets on a single 4// copper layer (a WxH grid); node-keepout blocking keeps different nets NODE-disjoint (no shorts / crossings = 5// the core DRC). Reports total copper length + a short count (0 = DRC-clean) + a routed flag. This closes the 6// omniforge ED "interactive autorouter" gap sovereignly (vs KiCad/Freerouting -- benchmark only). never-brick 7// #26: pure memory, bounded (BFS <= W*H per net), deterministic, zero hardware writes. license_tier: ORIGINAL 8import "nx_fpga_pnr.nx" 9import "nx_syscalls.nx" 10 11// route every net (pad a[n] -> b[n]) on the WxH board. useblock==1 -> each routed trace's nodes are KEPT OUT for 12// later nets (single-layer DRC: no crossings). shortout[0] = # grid nodes shared by >1 net (0 when blocking). 13// ok[0]=1 iff every net routed. Returns total copper length (hops). Caller must (re)fill cap_h/cap_v before the call. 14func pa_route_board(nnets: i64, ax: *i64, ay: *i64, bx: *i64, by: *i64, 15 W: i64, H: i64, cap_h: *i64, cap_v: *i64, 16 block: *i64, usedby: *i64, vis: *i64, came: *i64, q: *i64, pathbuf: *i64, 17 useblock: i64, shortout: *i64, ok: *i64) -> i64 { 18 let cells: i64 = W * H 19 var i: i64 = 0 20 while i < cells { usedby[i] = 0 - 1; block[i] = 0; i = i + 1 } 21 var total: i64 = 0 22 var allok: i64 = 1 23 var shorts: i64 = 0 24 var nidx: i64 = 0 25 while nidx < nnets { 26 let len: i64 = pnr_route_net_ex(W, H, cap_h, cap_v, block, ax[nidx], ay[nidx], bx[nidx], by[nidx], vis, came, q, pathbuf) 27 if len < 0 { allok = 0 } else { 28 total = total + len 29 var k: i64 = 0 30 while k <= len { 31 let node: i64 = pathbuf[k] 32 if usedby[node] >= 0 { if usedby[node] != nidx { shorts = shorts + 1 } } 33 usedby[node] = nidx 34 if useblock == 1 { block[node] = 1 } 35 k = k + 1 36 } 37 } 38 nidx = nidx + 1 39 } 40 shortout[0] = shorts 41 ok[0] = allok 42 return total 43}