code wiki / _hdl_build / nx_pattern_emit5.nx
nx_pattern_emit5.nx source
↩ module page · 112 lines · 8129 B
1// nx_pattern_emit5.nx -- PATTERN EMITTERS: GEOMETRY (shape 9 of 10) + PID_LOOP (shape 10 of 10). With
2// these + SCAFFOLD (team-owned scaffold_author) the Builder's pattern library is 10/10 hands-off.
3// GEOMETRY: nm coords + area/spacing/DRC (the mask_geom / micron_geom / fab_slice shape). min_feat and
4// min_gap are SPEC PARAMS (the process node's design rules), baked from the assignment -- rule 11.
5// Negative dimensions are REFUSED (-1), never silently absd.
6// PID_LOOP: error -> control with the PLANT SIM AS ORACLE (the heater_pid shape). The emitter SIMULATES
7// the closed loop (first-order plant x += u/8) AT EMIT TIME and REFUSES to author gains that do not
8// converge -- a mechanical pre-flight, no Claude judgment. The exact simulated endpoint is baked into
9// the authored test as a KAT (bit-exact integer replay) plus a convergence bound + integral-clamp KAT.
10// Extends emit(231)/emit2(235)/emit3(241)/emit4(262). LAWS: struct-free, integer-only, flat ifs,
11// <=6 args per func (filed >6-stack-args miscompile). license_tier: ORIGINAL
12import "nx_pattern_emit.nx"
13import "nx_syscalls.nx"
14const K_MAGIC_3000: i64 = 3000
15
16// ============ GEOMETRY ============
17func pe5_emit_geometry(fd: i64, name: *u8, min_feat: i64, min_gap: i64) -> i64 {
18 pe_w(fd, "// AUTHORED BY THE NISHI BUILDER (pattern: GEOMETRY) -- nm-domain area/spacing/DRC, no Claude logic\n" as *u8)
19 pe_w(fd, "import \"nx_syscalls.nx\"\n" as *u8)
20 pe_w(fd, "func " as *u8); pe_w(fd, name); pe_w(fd, "_area(w: i64, h: i64) -> i64 { if w < 0 { return 0 - 1 } if h < 0 { return 0 - 1 } return w * h }\n" as *u8)
21 pe_w(fd, "func " as *u8); pe_w(fd, name); pe_w(fd, "_spacing_ok(x1: i64, w1: i64, x2: i64) -> i64 { if x2 >= x1 + w1 + " as *u8); pe_wn(fd, min_gap)
22 pe_w(fd, " { return 1 } return 0 }\n" as *u8)
23 pe_w(fd, "func " as *u8); pe_w(fd, name); pe_w(fd, "_drc(w: i64, h: i64) -> i64 { if w < " as *u8); pe_wn(fd, min_feat)
24 pe_w(fd, " { return 0 } if h < " as *u8); pe_wn(fd, min_feat); pe_w(fd, " { return 0 } return 1 }\n" as *u8)
25 return 1
26}
27// boundary KATs computed FROM the design rules: DRC at exactly min_feat passes, one nm under fails;
28// spacing at exactly min_gap passes, one nm short fails; area refuses negatives
29func pe5_emit_geometry_test(fd: i64, name: *u8, min_feat: i64, min_gap: i64) -> i64 {
30 pe_w(fd, "// AUTHORED BY THE NISHI BUILDER (pattern: GEOMETRY test) -- design-rule boundary KATs\n" as *u8)
31 pe_w(fd, "import \"" as *u8); pe_w(fd, name); pe_w(fd, ".nx\"\nimport \"nx_syscalls.nx\"\n" as *u8)
32 pe_w(fd, "func main() -> i64 {\n var bad: i64 = 0\n" as *u8)
33 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_area(300, 400) != 120000 { bad = bad + 1 }\n" as *u8)
34 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_area(0 - 1, 400) + 1 != 0 { bad = bad + 1 }\n" as *u8)
35 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_drc(" as *u8); pe_wn(fd, min_feat); pe_w(fd, ", " as *u8); pe_wn(fd, min_feat); pe_w(fd, ") != 1 { bad = bad + 1 }\n" as *u8)
36 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_drc(" as *u8); pe_wn(fd, min_feat - 1); pe_w(fd, ", " as *u8); pe_wn(fd, min_feat); pe_w(fd, ") != 0 { bad = bad + 1 }\n" as *u8)
37 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_spacing_ok(1000, 2000, " as *u8); pe_wn(fd, K_MAGIC_3000 + min_gap); pe_w(fd, ") != 1 { bad = bad + 1 }\n" as *u8)
38 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_spacing_ok(1000, 2000, " as *u8); pe_wn(fd, K_MAGIC_3000 + min_gap - 1); pe_w(fd, ") != 0 { bad = bad + 1 }\n" as *u8)
39 pe_w(fd, " if bad == 0 { sys_exit(0) }\n sys_exit(1)\n return 1\n}\n" as *u8)
40 return 1
41}
42func pe5_author_geometry(name: *u8, modpath: *u8, testpath: *u8, min_feat: i64, min_gap: i64) -> i64 {
43 let mf: i64 = sys_openat_wr(modpath, 0x1a4); if mf < 0 { return 0 }
44 pe5_emit_geometry(mf, name, min_feat, min_gap); sys_close(mf)
45 let tf: i64 = sys_openat_wr(testpath, 0x1a4); if tf < 0 { return 0 }
46 pe5_emit_geometry_test(tf, name, min_feat, min_gap); sys_close(tf)
47 return 1
48}
49
50// ============ PID_LOOP ============
51// the shared closed-loop integer sim (emitter pre-flight AND test-KAT derivation use the SAME ops the
52// authored core uses -> the baked endpoint replays bit-exact). Plant: x += u/8. Returns final x.
53func pe5_sim_final(kp: i64, ki: i64, imax: i64, sp: i64, steps: i64) -> i64 {
54 var x: i64 = 0
55 var integ: i64 = 0
56 var s: i64 = 0
57 while s < steps {
58 let err: i64 = sp - x
59 integ = integ + err
60 if integ > imax { integ = imax }
61 if integ < 0 - imax { integ = 0 - imax }
62 let u: i64 = (kp * err + ki * integ) / 1000
63 x = x + u / 8
64 s = s + 1
65 }
66 return x
67}
68func pe5_emit_pid(fd: i64, name: *u8, kp: i64, ki: i64, imax: i64) -> i64 {
69 pe_w(fd, "// AUTHORED BY THE NISHI BUILDER (pattern: PID_LOOP) -- integer PI, gains pre-flighted vs the plant sim\n" as *u8)
70 pe_w(fd, "import \"nx_syscalls.nx\"\n" as *u8)
71 pe_w(fd, "func " as *u8); pe_w(fd, name); pe_w(fd, "_pid(err: i64, integ: *i64) -> i64 {\n" as *u8)
72 pe_w(fd, " integ[0] = integ[0] + err\n" as *u8)
73 pe_w(fd, " if integ[0] > " as *u8); pe_wn(fd, imax); pe_w(fd, " { integ[0] = " as *u8); pe_wn(fd, imax); pe_w(fd, " }\n" as *u8)
74 pe_w(fd, " if integ[0] < 0 - " as *u8); pe_wn(fd, imax); pe_w(fd, " { integ[0] = 0 - " as *u8); pe_wn(fd, imax); pe_w(fd, " }\n" as *u8)
75 pe_w(fd, " return (" as *u8); pe_wn(fd, kp); pe_w(fd, " * err + " as *u8); pe_wn(fd, ki); pe_w(fd, " * integ[0]) / 1000\n}\n" as *u8)
76 return 1
77}
78// the test replays the SAME closed loop against the authored core and asserts the emit-time endpoint
79// bit-exact, the convergence bound (|sp-x| <= sp/20), and the integral clamp
80func pe5_emit_pid_test(fd: i64, name: *u8, kp: i64, ki: i64, imax: i64) -> i64 {
81 let sp: i64 = 1000
82 let steps: i64 = 60
83 let fin: i64 = pe5_sim_final(kp, ki, imax, sp, steps)
84 let cu: i64 = (kp * (imax * 2) + ki * imax) / 1000
85 pe_w(fd, "// AUTHORED BY THE NISHI BUILDER (pattern: PID_LOOP test) -- plant-sim replay KAT, endpoint baked at emit time\n" as *u8)
86 pe_w(fd, "import \"" as *u8); pe_w(fd, name); pe_w(fd, ".nx\"\nimport \"nx_syscalls.nx\"\n" as *u8)
87 pe_w(fd, "func main() -> i64 {\n var bad: i64 = 0\n" as *u8)
88 pe_w(fd, " let ig: *i64 = sys_mmap(16) as *i64\n ig[0] = 0\n" as *u8)
89 pe_w(fd, " var x: i64 = 0\n var s: i64 = 0\n" as *u8)
90 pe_w(fd, " while s < " as *u8); pe_wn(fd, steps); pe_w(fd, " { x = x + " as *u8); pe_w(fd, name); pe_w(fd, "_pid(" as *u8); pe_wn(fd, sp); pe_w(fd, " - x, ig) / 8; s = s + 1 }\n" as *u8)
91 pe_w(fd, " if x != " as *u8); pe_wn(fd, fin); pe_w(fd, " { bad = bad + 1 }\n" as *u8)
92 pe_w(fd, " var dev: i64 = " as *u8); pe_wn(fd, sp); pe_w(fd, " - x\n if dev < 0 { dev = 0 - dev }\n" as *u8)
93 pe_w(fd, " if dev > " as *u8); pe_wn(fd, sp / 20); pe_w(fd, " { bad = bad + 1 }\n" as *u8)
94 pe_w(fd, " let ig2: *i64 = sys_mmap(16) as *i64\n ig2[0] = 0\n" as *u8)
95 pe_w(fd, " if " as *u8); pe_w(fd, name); pe_w(fd, "_pid(" as *u8); pe_wn(fd, imax * 2); pe_w(fd, ", ig2) != " as *u8); pe_wn(fd, cu); pe_w(fd, " { bad = bad + 1 }\n" as *u8)
96 pe_w(fd, " if ig2[0] != " as *u8); pe_wn(fd, imax); pe_w(fd, " { bad = bad + 1 }\n" as *u8)
97 pe_w(fd, " if bad == 0 { sys_exit(0) }\n sys_exit(1)\n return 1\n}\n" as *u8)
98 return 1
99}
100// PRE-FLIGHT then author: gains that do not converge on the plant sim are REFUSED (returns 0 -- a
101// mechanical quality gate, the 'plant sim as oracle' of the catalog).
102func pe5_author_pid(name: *u8, modpath: *u8, testpath: *u8, kp: i64, ki: i64, imax: i64) -> i64 {
103 let fin: i64 = pe5_sim_final(kp, ki, imax, 1000, 60)
104 var dev: i64 = 1000 - fin
105 if dev < 0 { dev = 0 - dev }
106 if dev > 50 { return 0 }
107 let mf: i64 = sys_openat_wr(modpath, 0x1a4); if mf < 0 { return 0 }
108 pe5_emit_pid(mf, name, kp, ki, imax); sys_close(mf)
109 let tf: i64 = sys_openat_wr(testpath, 0x1a4); if tf < 0 { return 0 }
110 pe5_emit_pid_test(tf, name, kp, ki, imax); sys_close(tf)
111 return 1
112}