code wiki / _hdl_build / nx_decoder_fields_mem_test.nx

nx_decoder_fields_mem_test.nx source

↩ module page · 96 lines · 4451 B

1// nx_decoder_fields_mem_test.nx -- FUNCTIONAL gate-level verify of the decoder field extractors. 2// Builds the 6 field sub-networks (nx_decoder_fields_build) into a MEM sink, runs the gate-sim over 3// 200 pseudo-random 32-bit instructions, and diffs every field net against the behavioral oracle 4// (nx_rv64im_opcode/rd/funct3/rs1/rs2/funct7). 1200 checks must all match. Plus a KAT (add x3,x1,x2) 5// and a NEGATIVE CONTROL: a deliberately-wrong rd extractor (shift 8 not 7) MUST mismatch the oracle 6// -> proves the verify has teeth. Mirrors nx_alu_select_mem_test (one source, two sinks). Sovereign. 7// license_tier: ORIGINAL expect_exit: 0 8import "nx_decoder_select.nx" 9import "rv64im_min_decoder.nx" 10 11func _emit_cstr(s: *u8) -> i64 { 12 var n: i64 = 0 13 while s[n] != (0 as u8) { n = n + 1 } 14 sys_write(1, s, n) 15 return 0 16} 17func _emit_dec(v: i64) -> i64 { 18 let b: *u8 = sys_mmap(28) 19 let t2: *u8 = sys_mmap(28) 20 var n: i64 = v 21 if n < 0 { n = 0 - n } 22 var t: i64 = 0 23 if n == 0 { t2[0] = 48; t = 1 } 24 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 } 25 var i: i64 = 0 26 while i < t { b[i] = t2[t - 1 - i]; i = i + 1 } 27 sys_write(1, b, t) 28 return 0 29} 30 31func main() -> i64 { 32 let cells: *NxGsimCell = sys_mmap(48 * 512) as *NxGsimCell 33 let vals: *i64 = sys_mmap(8 * 512) as *i64 34 let g: *NxGsim = sys_mmap(64) as *NxGsim 35 g.cells = cells 36 g.vals = vals 37 let k: *NxCellSink = sys_mmap(64) as *NxCellSink 38 39 g.n_nets = 1 // net 0 = inst input 40 g.n_cells = 0 41 nx_sink_init_mem(k, g) 42 let outs: *i64 = sys_mmap(8 * 6) as *i64 43 nx_decoder_fields_build(k, 0, outs) 44 // a deliberately-WRONG rd extractor (shift 8 instead of 7) -- the negative control 45 let bad_rd: i64 = nx_dec_field(k, 0, 8, 31) 46 47 // ---- broad functional verify over 200 pseudo-random full-32-bit instructions ---- 48 var seed: i64 = 2463534242 49 var n: i64 = 0 50 var mism: i64 = 0 51 var bad_caught: i64 = 0 52 while n < 200 { 53 seed = (seed * 1103515245 + 12345) & 2147483647 54 let hi: i64 = seed & 65535 55 seed = (seed * 1103515245 + 12345) & 2147483647 56 let lo: i64 = seed & 65535 57 let inst: i64 = (hi << 16) | lo // full 32-bit instruction 58 g.vals[0] = inst 59 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(40); return 40 } 60 if g.vals[outs[0]] != nx_rv64im_opcode(inst) { mism = mism + 1 } 61 if g.vals[outs[1]] != nx_rv64im_rd(inst) { mism = mism + 1 } 62 if g.vals[outs[2]] != nx_rv64im_funct3(inst) { mism = mism + 1 } 63 if g.vals[outs[3]] != nx_rv64im_rs1(inst) { mism = mism + 1 } 64 if g.vals[outs[4]] != nx_rv64im_rs2(inst) { mism = mism + 1 } 65 if g.vals[outs[5]] != nx_rv64im_funct7(inst) { mism = mism + 1 } 66 if g.vals[bad_rd] != nx_rv64im_rd(inst) { bad_caught = bad_caught + 1 } 67 n = n + 1 68 } 69 _emit_cstr("decoder fields: checks=" as *u8); _emit_dec(n * 6) 70 _emit_cstr(" mismatches=" as *u8); _emit_dec(mism) 71 _emit_cstr(" bad_rd_caught=" as *u8); _emit_dec(bad_caught); _emit_cstr("\n" as *u8) 72 73 // ---- KAT: add x3, x1, x2 = 0x002081B3 ---- 74 let kat: i64 = 2130355 // 0x002081B3 = add x3, x1, x2 75 g.vals[0] = kat 76 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(41); return 41 } 77 var kat_ok: i64 = 1 78 if g.vals[outs[0]] != 51 { kat_ok = 0 } // opcode 0x33 79 if g.vals[outs[1]] != 3 { kat_ok = 0 } // rd 3 80 if g.vals[outs[2]] != 0 { kat_ok = 0 } // funct3 0 81 if g.vals[outs[3]] != 1 { kat_ok = 0 } // rs1 1 82 if g.vals[outs[4]] != 2 { kat_ok = 0 } // rs2 2 83 if g.vals[outs[5]] != 0 { kat_ok = 0 } // funct7 0 84 _emit_cstr("KAT add x3,x1,x2: opcode=" as *u8); _emit_dec(g.vals[outs[0]]) 85 _emit_cstr(" rd=" as *u8); _emit_dec(g.vals[outs[1]]) 86 _emit_cstr(" rs1=" as *u8); _emit_dec(g.vals[outs[3]]) 87 _emit_cstr(" rs2=" as *u8); _emit_dec(g.vals[outs[4]]); _emit_cstr("\n" as *u8) 88 89 // ---- verdict ---- 90 if mism != 0 { sys_exit(1); return 1 } // every field matches the oracle over 1200 checks 91 if kat_ok != 1 { sys_exit(2); return 2 } // known-answer add x3,x1,x2 exact 92 if bad_caught == 0 { sys_exit(3); return 3 } // neg-control: wrong-shift rd MUST diverge sometimes 93 _emit_cstr("decoder FIELDS gate-verify PASS (1200 checks 0 mismatch; KAT exact; neg-control fires)\n" as *u8) 94 sys_exit(0) 95 return 0 96}