code wiki / _hdl_build / nx_alu_divider_r4_test.nx

nx_alu_divider_r4_test.nx source

↩ module page · 75 lines · 3148 B

1// nx_alu_divider_r4_test.nx -- the divider's FULL qual+quant exceed proof. 2// QUAL: radix-4 divider exhaustively correct over the whole 8-bit space. 3// QUANT: radix-4 has FEWER subtract-stages than radix-2 (measured from the 4// netlist by counting SUB cells = the sequential remainder-update depth). 5// A full S-class exceed = BOTH (faster AND still 100%-correct). Honest scope: 6// this is the STAGE-COUNT (iteration-latency) quant win; the further SRT 7// carry-save (no carry-propagate add in the loop) win is a later step. 8// 9// Known answer (FAIL LOUD): "65280 65280 4 8 " = ok, total, r4_subtract_stages, 10// r2_subtract_stages. exit 0 iff 100%-correct AND r4_subs < r2_subs. 11 12import "nx_alu_divider_r4.nx" 13 14func _emit_num(v: i64) -> i64 { 15 let b: *u8 = sys_mmap(28); var n: i64 = v; if n < 0 { n = 0 - n } 16 let t2: *u8 = sys_mmap(28); var t: i64 = 0 17 if n == 0 { t2[0] = 48; t = 1 } 18 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 } 19 var i: i64 = 0; while i < t { b[i] = t2[t - 1 - i]; i = i + 1 } 20 b[t] = 32; sys_write(1, b, t + 1); return 0 21} 22func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 } 23 24func count_kind(g: *NxGsim, kind: i64) -> i64 { 25 var c: i64 = 0 26 var i: i64 = 0 27 while i < g.n_cells { if g.cells[i].kind == kind { c = c + 1 } i = i + 1 } 28 return c 29} 30 31func main() -> i64 { 32 // ---- radix-4 divider ---- 33 let v4: *i64 = sys_mmap(512 * 8) as *i64 34 let c4: *NxGsimCell = sys_mmap(512 * 48) as *NxGsimCell 35 let g4: *NxGsim = sys_mmap(64) as *NxGsim 36 g4.vals = v4; g4.n_nets = 2; g4.cells = c4; g4.n_cells = 0 37 let ro4: *i64 = sys_mmap(8) as *i64; ro4[0] = 0 38 let quo4: i64 = nx_div_synth_r4(g4, 0, 1, 8, ro4) 39 let rem4: i64 = ro4[0] 40 let subs4: i64 = count_kind(g4, NX_GATE_KIND_SUB) 41 42 // QUAL: exhaustive verification over the whole 8-bit space 43 var total: i64 = 0 44 var ok: i64 = 0 45 var a: i64 = 0 46 while a < 256 { 47 var b: i64 = 1 48 while b < 256 { 49 g4.vals[0] = a; g4.vals[1] = b 50 if nx_gsim_run(g4) != NX_GSIM_OK { sys_exit(20); return 20 } 51 let q: i64 = g4.vals[quo4]; let r: i64 = g4.vals[rem4] 52 let bq: i64 = a / b 53 total = total + 1 54 if q == bq { if r == a - bq * b { ok = ok + 1 } } 55 b = b + 1 56 } 57 a = a + 1 58 } 59 60 // ---- radix-2 baseline (for the QUANT stage comparison) ---- 61 let v2: *i64 = sys_mmap(512 * 8) as *i64 62 let c2: *NxGsimCell = sys_mmap(512 * 48) as *NxGsimCell 63 let g2: *NxGsim = sys_mmap(64) as *NxGsim 64 g2.vals = v2; g2.n_nets = 2; g2.cells = c2; g2.n_cells = 0 65 let ro2: *i64 = sys_mmap(8) as *i64; ro2[0] = 0 66 let dummy: i64 = nx_div_synth(g2, 0, 1, 8, ro2) 67 let subs2: i64 = count_kind(g2, NX_GATE_KIND_SUB) 68 69 _emit_num(ok); _emit_num(total); _emit_num(subs4); _emit_num(subs2); _nl() 70 71 if ok != total { sys_exit(1); return 1 } // QUAL: radix-4 100%-correct 72 if total != 65280 { sys_exit(2); return 2 } 73 if subs4 >= subs2 { sys_exit(3); return 3 } // QUANT: radix-4 fewer subtract-stages 74 sys_exit(0); return 0 75}