code wiki / _hdl_build / nx_alu_divider_test.nx
nx_alu_divider_test.nx source
↩ module page · 55 lines · 2312 B
1// nx_alu_divider_test.nx -- proves the SYNTHESIZED divider gate-network computes
2// division 1:1 vs behavioral a/b + a%b (the invention engine's first hardware
3// invention; replaces the SIL-1 DIV-as-ADD stub with a VERIFIED-correct network).
4//
5// Synthesizes an 8-stage restoring divider, then sims it over 4 vectors and
6// asserts quotient == a/b AND remainder == a%b for each. Known answer (FAIL
7// LOUD): "28 4 11 1 17 0 7 2 " = q,r for 200/7, 100/9, 255/15, 37/5.
8
9import "nx_alu_divider.nx"
10
11func _emit_num(v: i64) -> i64 {
12 let b: *u8 = sys_mmap(28); var n: i64 = v; if n < 0 { n = 0 - n }
13 let t2: *u8 = sys_mmap(28); var t: i64 = 0
14 if n == 0 { t2[0] = 48; t = 1 }
15 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 }
16 var i: i64 = 0; while i < t { b[i] = t2[t - 1 - i]; i = i + 1 }
17 b[t] = 32; sys_write(1, b, t + 1); return 0
18}
19func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 }
20
21// run the synthesized divider for a/b, assert quotient + remainder vs behavioral.
22// returns 0 if correct, else a nonzero code.
23func _check(g: *NxGsim, quo_net: i64, rem_net: i64, a: i64, b: i64) -> i64 {
24 g.vals[0] = a
25 g.vals[1] = b
26 if nx_gsim_run(g) != NX_GSIM_OK { return 90 }
27 let q: i64 = g.vals[quo_net]
28 let r: i64 = g.vals[rem_net]
29 _emit_num(q); _emit_num(r)
30 if q != a / b { return 1 }
31 if r != a - (a / b) * b { return 2 } // a % b, computed without relying on %
32 return 0
33}
34
35func main() -> i64 {
36 let vals: *i64 = sys_mmap(512 * 8) as *i64
37 let cells: *NxGsimCell = sys_mmap(512 * 48) as *NxGsimCell
38 let g: *NxGsim = sys_mmap(64) as *NxGsim
39 g.vals = vals
40 g.n_nets = 2 // net0 = dividend a, net1 = divisor b (primary inputs)
41 g.cells = cells
42 g.n_cells = 0
43
44 let rem_out: *i64 = sys_mmap(8) as *i64
45 rem_out[0] = 0
46 let quo_net: i64 = nx_div_synth(g, 0, 1, 8, rem_out)
47 let rem_net: i64 = rem_out[0]
48
49 if _check(g, quo_net, rem_net, 200, 7) != 0 { _nl(); sys_exit(1); return 1 }
50 if _check(g, quo_net, rem_net, 100, 9) != 0 { _nl(); sys_exit(2); return 2 }
51 if _check(g, quo_net, rem_net, 255, 15) != 0 { _nl(); sys_exit(3); return 3 }
52 if _check(g, quo_net, rem_net, 37, 5) != 0 { _nl(); sys_exit(4); return 4 }
53 _nl()
54 sys_exit(0); return 0
55}