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}