code wiki / _hdl_build / nx_alu_divider_exhaustive_test.nx

nx_alu_divider_exhaustive_test.nx source

↩ module page · 67 lines · 2589 B

1// nx_alu_divider_exhaustive_test.nx -- the divider EXCEED on the VERIFICATION 2// dimension: prove the synthesized divider correct over the ENTIRE 8-bit input 3// space (all dividends 0..255 x all divisors 1..255 = 65280 pairs), quotient AND 4// remainder, 1:1 vs behavioral. 5// 6// MEET (floor) = a correct divider on a few vectors. EXCEED (this) = correctness 7// PROVEN-BY-CONSTRUCTION at 100% input-space coverage -- the guarantee incumbent 8// synthesis flows (Yosys/ABC) do NOT give (structural-only; can silently 9// miscompile -- the SynFuzz finding). Named incumbent: an unverified emitted 10// divider. Measurable dimension: verified-coverage = 100% (65280/65280). 11// 12// (This is the VERIFICATION exceed; the PERFORMANCE exceed = radix-4 SRT fewer 13// stages, scoped next by the exceed-calibration. Honest: don't conflate them.) 14// 15// Known answer (FAIL LOUD): "65280 65280 " (ok, total). exit 0 iff ok == total. 16 17import "nx_alu_divider.nx" 18 19func _emit_num(v: i64) -> i64 { 20 let b: *u8 = sys_mmap(28); var n: i64 = v; if n < 0 { n = 0 - n } 21 let t2: *u8 = sys_mmap(28); var t: i64 = 0 22 if n == 0 { t2[0] = 48; t = 1 } 23 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 } 24 var i: i64 = 0; while i < t { b[i] = t2[t - 1 - i]; i = i + 1 } 25 b[t] = 32; sys_write(1, b, t + 1); return 0 26} 27func _nl() -> i64 { let z: *u8 = sys_mmap(2); z[0] = 10; sys_write(1, z, 1); return 0 } 28 29func main() -> i64 { 30 let vals: *i64 = sys_mmap(512 * 8) as *i64 31 let cells: *NxGsimCell = sys_mmap(512 * 48) as *NxGsimCell 32 let g: *NxGsim = sys_mmap(64) as *NxGsim 33 g.vals = vals 34 g.n_nets = 2 35 g.cells = cells 36 g.n_cells = 0 37 38 let rem_out: *i64 = sys_mmap(8) as *i64 39 rem_out[0] = 0 40 let quo_net: i64 = nx_div_synth(g, 0, 1, 8, rem_out) 41 let rem_net: i64 = rem_out[0] 42 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 g.vals[0] = a 50 g.vals[1] = b 51 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(20); return 20 } 52 let q: i64 = g.vals[quo_net] 53 let r: i64 = g.vals[rem_net] 54 let bq: i64 = a / b 55 let br: i64 = a - bq * b 56 total = total + 1 57 if q == bq { if r == br { ok = ok + 1 } } 58 b = b + 1 59 } 60 a = a + 1 61 } 62 63 _emit_num(ok); _emit_num(total); _nl() 64 if ok != total { sys_exit(1); return 1 } // every input pair must verify 65 if total != 65280 { sys_exit(2); return 2 } // 256 dividends x 255 divisors 66 sys_exit(0); return 0 67}