code wiki / _hdl_build / nx_pcb_drc.nx

nx_pcb_drc.nx source

↩ module page · 43 lines · 2294 B

1// nx_pcb_drc.nx -- LIB: PCB design-rule-check DIGITAL TWIN. Verifies a routed board against REAL fabrication rules 2// in REAL units (mils) -- a twin of the fab's own DRC, so "passes DRC" means "really manufacturable at this fab class". 3// Rules (data-driven, rule #11): min copper-to-copper CLEARANCE and min trace WIDTH. A standard 2-layer fab is 6/6 mil; 4// advanced is 4/4. The edge-to-edge gap between two orthogonally-adjacent traces is (pitch - trace_width) mils; if that 5// is below the clearance rule the board shorts/bridges in real fab -> a violation. A trace narrower than the width rule 6// can't be etched reliably -> a violation. Composes the routed grid from nx_pcb_autoroute. never-brick #26: pure 7// arithmetic, bounded, deterministic. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9 10// real fab classes (mils): standard 2-layer = 6/6 (clearance/width). Not magic numbers -- the real manufacturable limits. 11const FAB_STD_CLEAR_MIL: i64 = 6 12const FAB_STD_WIDTH_MIL: i64 = 6 13 14// count design-rule violations on the routed board (usedby[c] = net id per grid cell, -1 = empty). 15// pitch_mils = grid step, tw_mils = trace width. Returns total violations (width-rule + clearance-rule). 16func drc_check(usedby: *i64, W: i64, H: i64, pitch_mils: i64, tw_mils: i64, min_clear_mils: i64, min_width_mils: i64) -> i64 { 17 var viol: i64 = 0 18 if tw_mils < min_width_mils { viol = viol + 1 } // width rule (global) 19 let ortho_gap: i64 = pitch_mils - tw_mils // edge-to-edge gap for orthogonal adjacency 20 var cy: i64 = 0 21 while cy < H { 22 var cx: i64 = 0 23 while cx < W { 24 let c: i64 = cy*W + cx 25 let n: i64 = usedby[c] 26 if n >= 0 { 27 if cx + 1 < W { 28 let c2: i64 = cy*W + (cx+1) 29 let n2: i64 = usedby[c2] 30 if n2 >= 0 { if n2 != n { if ortho_gap < min_clear_mils { viol = viol + 1 } } } 31 } 32 if cy + 1 < H { 33 let c2: i64 = (cy+1)*W + cx 34 let n2: i64 = usedby[c2] 35 if n2 >= 0 { if n2 != n { if ortho_gap < min_clear_mils { viol = viol + 1 } } } 36 } 37 } 38 cx = cx + 1 39 } 40 cy = cy + 1 41 } 42 return viol 43}