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}