code wiki / _hdl_build / nx_pcb_drc_gate.nx
nx_pcb_drc_gate.nx source
↩ module page · 74 lines · 5054 B
1// nx_pcb_drc_gate.nx -- GATE for the PCB DRC digital twin (real fab rules, real mils). Closes the omniforge ED "DRC" gap.
2// T1 MANUFACTURABLE -- two adjacent different-net traces at 12-mil pitch / 6-mil trace (gap=6) under the 6/6 rule -> 0 violations.
3// T2 CLEARANCE FAIL -- the SAME board at 10-mil pitch (gap=4 < 6) -> 2 clearance violations (the DRC catches the real short risk).
4// T3 WIDTH FAIL -- a 4-mil trace under the 6-mil width rule -> 1 width violation (too thin to etch reliably).
5// T4 NEVER-BRICK -- empty board = 0 violations; deterministic re-run.
6// T5 ROUTE+DRC TWIN -- route a real 2-net board on the shared router, DRC it at the standard fab class -> 0 (manufacturable).
7// GREEN iff all pass. Sovereign nx_cc->nxasm, no 3rd-party. expect_exit: 0 license_tier: ORIGINAL
8import "nx_pcb_drc.nx"
9import "nx_pcb_autoroute.nx"
10import "nx_syscalls.nx"
11
12func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
13func wn(v: i64) -> i64 { var m: i64=v; if m<0{w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
14func fill(a: *i64, n: i64, v: i64) -> i64 { var i: i64=0; while i<n { a[i]=v; i=i+1 } return 0 }
15
16func main() -> i64 {
17 w("=== nx_pcb_drc_gate: PCB design-rule-check DIGITAL TWIN (real fab rules, real mils) ===\n" as *u8)
18 var pass: i64 = 0; var total: i64 = 0
19 let usedby: *i64 = sys_mmap(8*64) as *i64
20
21 // board: net0 row0 cols0,1 ; net1 row1 cols0,1 -> two vertically-adjacent different-net pairs
22 fill(usedby, 16, 0 - 1)
23 usedby[0]=0; usedby[1]=0; usedby[4]=1; usedby[5]=1
24
25 // T1 manufacturable: 12 mil pitch, 6 mil trace -> gap 6 >= 6, width 6 >= 6
26 let v1: i64 = drc_check(usedby, 4, 4, 12, 6, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
27 total=total+1; if v1 == 0 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) }
28 w("T1 manufacturable (12-mil pitch, 6-mil trace, gap=6, rule 6/6): violations=" as *u8); wn(v1); w("\n" as *u8)
29
30 // T2 clearance fail: 10 mil pitch -> gap 4 < 6
31 let v2: i64 = drc_check(usedby, 4, 4, 10, 6, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
32 total=total+1; if v2 == 2 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) }
33 w("T2 clearance fail (10-mil pitch, gap=4 < 6): violations=" as *u8); wn(v2); w(" (real short risk caught)\n" as *u8)
34
35 // T3 width fail: 4 mil trace < 6 mil width rule
36 let v3: i64 = drc_check(usedby, 4, 4, 12, 4, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
37 total=total+1; if v3 == 1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) }
38 w("T3 width fail (4-mil trace < 6-mil rule): violations=" as *u8); wn(v3); w(" (too thin to etch)\n" as *u8)
39
40 // T4 never-brick: empty board + determinism
41 fill(usedby, 16, 0 - 1)
42 let v4a: i64 = drc_check(usedby, 4, 4, 10, 6, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
43 let v4b: i64 = drc_check(usedby, 4, 4, 10, 6, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
44 var t4ok: i64 = 1
45 if v4a != 0 { t4ok = 0 }
46 if v4a != v4b { t4ok = 0 }
47 total=total+1; if t4ok==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) }
48 w("T4 never-brick: empty=" as *u8); wn(v4a); w(" deterministic(" as *u8); wn(v4a); w("==" as *u8); wn(v4b); w(")\n" as *u8)
49
50 // T5 route + DRC twin: route 2 nets far apart, DRC manufacturable
51 let W: i64 = 4; let H: i64 = 4
52 let nh: i64 = H*(W-1); let nv: i64 = (H-1)*W
53 let ax: *i64=sys_mmap(8*4) as *i64; let ay: *i64=sys_mmap(8*4) as *i64
54 let bx: *i64=sys_mmap(8*4) as *i64; let by: *i64=sys_mmap(8*4) as *i64
55 let cap_h: *i64=sys_mmap(8*64) as *i64; let cap_v: *i64=sys_mmap(8*64) as *i64
56 let block: *i64=sys_mmap(8*64) as *i64; let ub2: *i64=sys_mmap(8*64) as *i64
57 let vis: *i64=sys_mmap(8*64) as *i64; let came: *i64=sys_mmap(8*64) as *i64
58 let q: *i64=sys_mmap(8*64) as *i64; let pathbuf: *i64=sys_mmap(8*64) as *i64
59 let sh: *i64=sys_mmap(8*2) as *i64; let ok: *i64=sys_mmap(8*2) as *i64
60 ax[0]=0; ay[0]=0; bx[0]=3; by[0]=0
61 ax[1]=0; ay[1]=3; bx[1]=3; by[1]=3
62 fill(cap_h, nh, 8); fill(cap_v, nv, 8)
63 pa_route_board(2, ax, ay, bx, by, W, H, cap_h, cap_v, block, ub2, vis, came, q, pathbuf, 1, sh, ok)
64 let v5: i64 = drc_check(ub2, W, H, 12, 6, FAB_STD_CLEAR_MIL, FAB_STD_WIDTH_MIL)
65 var t5ok: i64 = 1
66 if ok[0] != 1 { t5ok = 0 }
67 if v5 != 0 { t5ok = 0 }
68 total=total+1; if t5ok==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) }
69 w("T5 route+DRC twin: routed=" as *u8); wn(ok[0]); w(" DRC violations=" as *u8); wn(v5); w(" (manufacturable at 6/6)\n" as *u8)
70
71 w("\n=== nx_pcb_drc_gate " as *u8); wn(pass); w("/" as *u8); wn(total)
72 if pass == total { w(" GREEN (DRC digital twin: real fab rules in real mils, clearance + width, route->verify; the manufacturability twin)\n" as *u8); sys_exit(0); return 0 }
73 w(" RED\n" as *u8); sys_exit(1); return 1
74}