code wiki / _hdl_build / nx_precision_test.nx
nx_precision_test.nx source
↩ module page · 88 lines · 4717 B
1// nx_precision_test.nx -- ACCEPTANCE GATE for the sub-micron precision substrate
2// (nx_micron_geom + nx_metrology). Every KAT exact integer.
3import "nx_micron_geom.nx"
4import "nx_metrology.nx"
5import "nx_syscalls.nx"
6
7func qt_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
8func qt_putn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); 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; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 }
9
10func main() -> i64 {
11 var pass: i64 = 0
12 var total: i64 = 0
13
14 // T1: unit ladder -- 1mm = 1e6 nm = 1000 um; a 5nm gate is 5 units
15 total = total + 1
16 var t1: i64 = 1
17 if mg_mm(1) != 1000000 { t1 = 0 }
18 if mg_um(1000) != 1000000 { t1 = 0 }
19 if mg_to_um_floor(5500) != 5 { t1 = 0 }
20 if t1 == 1 { pass = pass + 1 } else { qt_puts("T1 FAIL units\n" as *u8) }
21
22 // T2: scale calibration -- 100mm (1e8 nm) with +50ppm -> +5000nm; -50ppm -> -5000nm
23 total = total + 1
24 var t2: i64 = 1
25 if mg_scale_ppm(100000000, 50) != 100005000 { t2 = 0 }
26 if mg_scale_ppm(100000000, 0 - 50) != 99995000 { t2 = 0 }
27 if mg_correct(100000000, 50, 0 - 2000) != 100003000 { t2 = 0 } // +5000 scale, -2000 offset
28 if t2 == 1 { pass = pass + 1 } else { qt_puts("T2 FAIL scale " as *u8); qt_putn(mg_scale_ppm(100000000,50)); qt_puts("\n" as *u8) }
29
30 // T3: stage resolution -- 80 steps/mm -> 12500nm (12.5um) step; 200 -> 5000nm; 50000 -> 20nm
31 total = total + 1
32 var t3: i64 = 1
33 if mg_step_resolution_nm(80) != 12500 { t3 = 0 }
34 if mg_step_resolution_nm(200) != 5000 { t3 = 0 }
35 if mg_step_resolution_nm(50000) != 20 { t3 = 0 }
36 if t3 == 1 { pass = pass + 1 } else { qt_puts("T3 FAIL res\n" as *u8) }
37
38 // T4: addressability -- 80 steps/mm CANNOT address a 1um(1000nm) feature; 50000 steps/mm CAN
39 total = total + 1
40 var t4: i64 = 1
41 if mg_can_address(80, 1000) != 0 { t4 = 0 } // 12.5um step > 1um feature
42 if mg_can_address(50000, 1000) != 1 { t4 = 0 } // 20nm step <= 1um feature
43 if t4 == 1 { pass = pass + 1 } else { qt_puts("T4 FAIL addr\n" as *u8) }
44
45 // ---- metrology on a measured machine: commanded vs measured (nm) ----
46 let cmd: *i64 = sys_mmap(64) as *i64
47 let meas: *i64 = sys_mmap(64) as *i64
48 // commanded 10/20/30/40/50 mm; measured each +120nm bias and +50ppm scale-ish noise
49 cmd[0]=10000000; cmd[1]=20000000; cmd[2]=30000000; cmd[3]=40000000; cmd[4]=50000000
50 meas[0]=10000620; meas[1]=20001120; meas[2]=30001620; meas[3]=40002120; meas[4]=50002620
51
52 // T5: max deviation = 2620 nm (the 50mm point)
53 total = total + 1
54 if mt_max_deviation(cmd, meas, 5) == 2620 { pass = pass + 1 } else { qt_puts("T5 FAIL maxdev=" as *u8); qt_putn(mt_max_deviation(cmd,meas,5)); qt_puts("\n" as *u8) }
55
56 // T6: mean offset = (620+1120+1620+2120+2620)/5 = 8100/5 = 1620 nm
57 total = total + 1
58 if mt_mean_offset(cmd, meas, 5) == 1620 { pass = pass + 1 } else { qt_puts("T6 FAIL meanoff=" as *u8); qt_putn(mt_mean_offset(cmd,meas,5)); qt_puts("\n" as *u8) }
59
60 // T7: verdict -- 2620nm dev FAILS a 1000nm tolerance, PASSES a 5000nm tolerance
61 total = total + 1
62 var t7: i64 = 1
63 if mt_verdict(2620, 1000) != MT_FAIL { t7 = 0 }
64 if mt_verdict(2620, 5000) != MT_PASS { t7 = 0 }
65 if t7 == 1 { pass = pass + 1 } else { qt_puts("T7 FAIL verdict\n" as *u8) }
66
67 // T8: resolution class ladder -- the honest CPU gate
68 total = total + 1
69 var t8: i64 = 1
70 if mt_resolution_class(120000) != MT_CLASS_FDM { t8 = 0 } // 120um = bracket
71 if mt_resolution_class(8000) != MT_CLASS_FINE { t8 = 0 } // 8um = PCB/printed-electronics
72 if mt_resolution_class(2000) != MT_CLASS_MICRON { t8 = 0 } // 2um = 4004-class chip
73 if mt_resolution_class(300) != MT_CLASS_SUBMICRON { t8 = 0 } // 0.3um = modern CPU
74 if t8 == 1 { pass = pass + 1 } else { qt_puts("T8 FAIL class\n" as *u8) }
75
76 // T9: can_make -- a 120um-accurate FDM machine CANNOT make a 1um transistor; a 300nm machine CAN
77 total = total + 1
78 var t9: i64 = 1
79 if mt_can_make(120000, 1000) != 0 { t9 = 0 } // FDM cannot make a 1um gate
80 if mt_can_make(300, 1000) != 1 { t9 = 0 } // submicron CAN
81 if mt_can_make(300, 500) != 1 { t9 = 0 } // and a 0.5um gate
82 if t9 == 1 { pass = pass + 1 } else { qt_puts("T9 FAIL canmake\n" as *u8) }
83
84 qt_puts("PRECISION " as *u8); qt_putn(pass); qt_puts("/" as *u8); qt_putn(total); qt_puts("\n" as *u8)
85 if pass == total { qt_puts("PRECISION ALL-PASS\n" as *u8); sys_exit(0) }
86 sys_exit(1)
87 return 1
88}