code wiki / _hdl_build / nx_nxgate_sim_test.nx

nx_nxgate_sim_test.nx source

↩ module page · 69 lines · 3390 B

1// nx_nxgate_sim_test.nx -- proof-of-life GATE for the gate-level functional 2// simulator (VERIFIER organ's hardware oracle, SIL-3). 3// 4// Builds a small word-level netlist by hand and proves: 5// (1) the simulator EVALUATES combinational cells correctly (XOR/ADD/SUB/MUL/ 6// EQ/MUX) over an input vector; 7// (2) it CATCHES the SIL-1 stub class: a DIV represented as an ADD cell (what 8// the ALU gate emitter actually emits today) DIVERGES from behavioral DIV 9// -- the divergence the verifier exists to surface. 10// 11// Vector a=12 b=4. Known answer (FAIL LOUD): "8 16 8 48 0 16 16 3 " = 12// xor add sub mul eq mux divstub realdiv. (divstub=16 != realdiv=3 -> caught) 13 14import "nx_nxgate_sim.nx" 15 16func _emit_num(v: i64) -> i64 { 17 let b: *u8 = sys_mmap(28); var n: i64 = v; if n < 0 { n = 0 - n } 18 let t2: *u8 = sys_mmap(28); var t: i64 = 0 19 if n == 0 { t2[0] = 48; t = 1 } 20 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 } 21 var i: i64 = 0; while i < t { b[i] = t2[t - 1 - i]; i = i + 1 } 22 b[t] = 32; sys_write(1, b, t + 1); return 0 23} 24func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 } 25 26func main() -> i64 { 27 let vals: *i64 = sys_mmap(64 * 8) as *i64 28 let cells: *NxGsimCell = sys_mmap(16 * 40) as *NxGsimCell 29 let g: *NxGsim = sys_mmap(64) as *NxGsim 30 g.vals = vals 31 g.n_nets = 9 32 g.cells = cells 33 g.n_cells = 7 34 35 // nets: 0=a 1=b (inputs); 2=xor 3=add 4=sub 5=mul 6=eq 7=mux 8=divstub 36 cells[0].kind = NX_GATE_KIND_XOR; cells[0].fanout = 2; cells[0].f0 = 0; cells[0].f1 = 1; cells[0].f2 = 0 - 1 37 cells[1].kind = NX_GATE_KIND_ADD; cells[1].fanout = 3; cells[1].f0 = 0; cells[1].f1 = 1; cells[1].f2 = 0 - 1 38 cells[2].kind = NX_GATE_KIND_SUB; cells[2].fanout = 4; cells[2].f0 = 0; cells[2].f1 = 1; cells[2].f2 = 0 - 1 39 cells[3].kind = NX_GATE_KIND_MUL; cells[3].fanout = 5; cells[3].f0 = 0; cells[3].f1 = 1; cells[3].f2 = 0 - 1 40 cells[4].kind = NX_GATE_KIND_EQ; cells[4].fanout = 6; cells[4].f0 = 0; cells[4].f1 = 1; cells[4].f2 = 0 - 1 41 // mux (emitter convention sel?this:prev): sel=net6(eq=0), this=net4(sub=8), prev=net3(add=16) -> sel==0 picks prev=16 42 cells[5].kind = NX_GATE_KIND_MUX; cells[5].fanout = 7; cells[5].f0 = 6; cells[5].f1 = 4; cells[5].f2 = 3 43 // the SIL-1 stub: ALU emits an ADD cell where DIV belongs 44 cells[6].kind = NX_GATE_KIND_ADD; cells[6].fanout = 8; cells[6].f0 = 0; cells[6].f1 = 1; cells[6].f2 = 0 - 1 45 46 vals[0] = 12 47 vals[1] = 4 48 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(10); return 10 } 49 50 let xr: i64 = vals[2] 51 let ar: i64 = vals[3] 52 let sr: i64 = vals[4] 53 let mr: i64 = vals[5] 54 let er: i64 = vals[6] 55 let xm: i64 = vals[7] 56 let dv: i64 = vals[8] 57 let real_div: i64 = 12 / 4 58 _emit_num(xr); _emit_num(ar); _emit_num(sr); _emit_num(mr); _emit_num(er); _emit_num(xm); _emit_num(dv); _emit_num(real_div) 59 _nl() 60 61 if xr != 8 { sys_exit(1); return 1 } // 12 ^ 4 62 if ar != 16 { sys_exit(2); return 2 } // 12 + 4 63 if sr != 8 { sys_exit(3); return 3 } // 12 - 4 64 if mr != 48 { sys_exit(4); return 4 } // 12 * 4 65 if er != 0 { sys_exit(5); return 5 } // 12 == 4 -> 0 66 if xm != 16 { sys_exit(6); return 6 } // MUX sel=0 -> in0 (add=16) 67 if dv == real_div { sys_exit(7); return 7 } // STUB CATCH: ADD(16) must NOT equal DIV(3) 68 sys_exit(0); return 0 69}