code wiki / _hdl_build / nx_metrology.nx

nx_metrology.nx source

↩ module page · 81 lines · 3500 B

1// nx_metrology.nx -- the ACCURACY GATE (operator: "i want that level of accuracy"). Given what a 2// machine was COMMANDED to position/print vs what was MEASURED, this computes the real error and 3// maps it to a RESOLUTION CLASS = what the machine can actually MAKE. This is the honest bridge 4// from "how accurate is my machine" to "can it print a CPU": only SUBMICRON class reaches 5// transistor scale; FDM class makes brackets; MICRON makes fine features / PCB traces. 6// Inputs are nm arrays (commanded[], measured[]). All integer. 7// Composes nx_micron_geom (nm units). LAWS: struct-free, integer-only. license_tier: ORIGINAL 8import "nx_micron_geom.nx" 9import "nx_syscalls.nx" 10 11// resolution classes (coarsest -> finest); a feature can be MADE only if class resolution <= feature 12const MT_CLASS_FDM: i64 = 0 // >= 50 um deviation -- enclosures, brackets, bodies 13const MT_CLASS_FINE: i64 = 1 // >= 5 um -- fine FDM / resin / PCB traces (printed electronics) 14const MT_CLASS_MICRON: i64 = 2 // >= 1 um -- 4004-class lithography (Zeloof/Hacker Fab floor) 15const MT_CLASS_SUBMICRON:i64 = 3 // < 1 um -- modern-ish CPU features (the operator's target) 16 17const MT_PASS: i64 = 1 18const MT_FAIL: i64 = 0 19 20func mt_abs(x: i64) -> i64 { if x < 0 { return 0 - x } return x } 21 22// max absolute deviation (nm) between measured and commanded over n points 23func mt_max_deviation(cmd: *i64, meas: *i64, n: i64) -> i64 { 24 var m: i64 = 0 25 var i: i64 = 0 26 while i < n { 27 let d: i64 = mt_abs(meas[i] - cmd[i]) 28 if d > m { m = d } 29 i = i + 1 30 } 31 return m 32} 33 34// mean signed offset (nm): average of (measured - commanded) = systematic home/backlash bias 35func mt_mean_offset(cmd: *i64, meas: *i64, n: i64) -> i64 { 36 if n <= 0 { return 0 } 37 var s: i64 = 0 38 var i: i64 = 0 39 while i < n { s = s + (meas[i] - cmd[i]); i = i + 1 } 40 return s / n 41} 42 43// mean scale error in PPM: average over points (excluding cmd==0) of (meas-cmd)*1e6/cmd. 44// (per-point ratio avoids the i64 overflow a least-squares sum of nm*nm would hit.) 45func mt_scale_error_ppm(cmd: *i64, meas: *i64, n: i64) -> i64 { 46 var s: i64 = 0 47 var cnt: i64 = 0 48 var i: i64 = 0 49 while i < n { 50 if cmd[i] != 0 { 51 s = s + ((meas[i] - cmd[i]) * 1000000) / cmd[i] 52 cnt = cnt + 1 53 } 54 i = i + 1 55 } 56 if cnt == 0 { return 0 } 57 return s / cnt 58} 59 60// accuracy verdict: PASS iff max deviation <= tolerance (nm) 61func mt_verdict(max_dev_nm: i64, tol_nm: i64) -> i64 { 62 if max_dev_nm <= tol_nm { return MT_PASS } 63 return MT_FAIL 64} 65 66// map a measured max-deviation to the resolution CLASS (what the machine can make). 67// Reliable feature size ~ a few x the deviation; we classify by the deviation threshold directly 68// (conservative: the class boundary IS the deviation, so a claimed class is provable, not hoped). 69func mt_resolution_class(max_dev_nm: i64) -> i64 { 70 if max_dev_nm >= 50000 { return MT_CLASS_FDM } // >= 50 um 71 if max_dev_nm >= 5000 { return MT_CLASS_FINE } // >= 5 um 72 if max_dev_nm >= 1000 { return MT_CLASS_MICRON } // >= 1 um 73 return MT_CLASS_SUBMICRON // < 1 um 74} 75 76// can this measured machine MAKE a feature of the given size? (its class resolution <= feature) 77// returns 1/0. Honest CPU gate: a 1um transistor needs class MICRON or finer. 78func mt_can_make(max_dev_nm: i64, feature_nm: i64) -> i64 { 79 if max_dev_nm <= feature_nm { return 1 } 80 return 0 81}