code wiki / _hdl_build / nx_recip64_test.nx
nx_recip64_test.nx source
↩ module page · 97 lines · 3398 B
1// nx_recip64_test.nx -- proves the 64-bit Goldschmidt divider GATE-NETWORK
2// (nx_recip64_synth) emits what the bit-exact scalar computes: cross-checked vs
3// the proven unsigned oracle (nx_rv64im_udiv / urem), quotient AND remainder,
4// over dense-small + every power of two + random FULL 64-bit (incl. bit-63-set,
5// via xorshift) + the overflow edges. Known answer: "<ok> <total>" ok==total.
6
7import "nx_recip64.nx"
8import "rv64im_min_alu.nx"
9
10const R64T_HALF: i64 = 0 - 9223372036854775808 // 2^63
11
12func _emit_dec(v: i64) -> i64 {
13 let b: *u8 = sys_mmap(28); var n: i64 = v; if n < 0 { n = 0 - n }
14 let t: *u8 = sys_mmap(28); var k: i64 = 0
15 if n == 0 { t[0] = 48; k = 1 }
16 while n > 0 { t[k] = 48 + (n % 10); n = n / 10; k = k + 1 }
17 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
18 b[k] = 32; sys_write(1, b, k + 1); return 0
19}
20func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 }
21
22func r64t_chk(g: *NxGsim, qnet: i64, rnet: i64, N: i64, D: i64) -> i64 {
23 g.vals[0] = N
24 g.vals[1] = D
25 if nx_gsim_run(g) != NX_GSIM_OK { return 0 }
26 let gq: i64 = g.vals[qnet]
27 let gr: i64 = g.vals[rnet]
28 if gq != nx_rv64im_udiv(N, D) { return 0 }
29 if gr != nx_rv64im_urem(N, D) { return 0 }
30 return 1
31}
32
33func main() -> i64 {
34 let vals: *i64 = sys_mmap(8 * 4096) as *i64
35 let cells: *NxGsimCell = sys_mmap(48 * 4096) as *NxGsimCell
36 let g: *NxGsim = sys_mmap(64) as *NxGsim
37 g.vals = vals; g.n_nets = 2; g.cells = cells; g.n_cells = 0
38 let rob: *i64 = sys_mmap(8) as *i64; rob[0] = 0
39 let qnet: i64 = nx_recip64_synth(g, 0, 1, rob)
40 let rnet: i64 = rob[0]
41
42 var total: i64 = 0
43 var ok: i64 = 0
44
45 // dense small: D in [1,32], N in [0,511]
46 var D: i64 = 1
47 while D <= 32 {
48 var N: i64 = 0
49 while N <= 511 {
50 total = total + 1; ok = ok + r64t_chk(g, qnet, rnet, N, D)
51 N = N + 1
52 }
53 D = D + 1
54 }
55
56 // every power of two divisor, assorted dividends
57 var kb: i64 = 0
58 while kb < 64 {
59 let pd: i64 = 1 << kb
60 let nv: *i64 = sys_mmap(8 * 5) as *i64
61 nv[0]=0; nv[1]=1; nv[2]=pd; nv[3]=0-1; nv[4]=(0-1)-pd
62 var j: i64 = 0
63 while j < 5 { total = total + 1; ok = ok + r64t_chk(g, qnet, rnet, nv[j], pd); j = j + 1 }
64 kb = kb + 1
65 }
66
67 // random FULL 64-bit
68 var seed: i64 = 88172645463325252
69 var nr: i64 = 0
70 while nr < 5000 {
71 seed = seed ^ (seed << 13); seed = seed ^ nx_rv64im_lshr(seed, 7); seed = seed ^ (seed << 17)
72 let N: i64 = seed
73 seed = seed ^ (seed << 13); seed = seed ^ nx_rv64im_lshr(seed, 7); seed = seed ^ (seed << 17)
74 var D: i64 = seed
75 if D == 0 { D = 1 }
76 total = total + 1; ok = ok + r64t_chk(g, qnet, rnet, N, D)
77 nr = nr + 1
78 }
79
80 // edges
81 let en: *i64 = sys_mmap(8 * 8) as *i64
82 let ed: *i64 = sys_mmap(8 * 8) as *i64
83 en[0]=0-1; ed[0]=1
84 en[1]=0-1; ed[1]=0-1
85 en[2]=0-1; ed[2]=2
86 en[3]=0-1; ed[3]=R64T_HALF
87 en[4]=R64T_HALF; ed[4]=3
88 en[5]=0-1; ed[5]=(0-1)
89 en[6]=12345678901234; ed[6]=99991
90 en[7]=0-1; ed[7]=R64T_HALF + 1
91 var e: i64 = 0
92 while e < 8 { total = total + 1; ok = ok + r64t_chk(g, qnet, rnet, en[e], ed[e]); e = e + 1 }
93
94 _emit_dec(ok); _emit_dec(total); _nl()
95 if ok != total { sys_exit(1); return 1 }
96 sys_exit(0); return 0
97}