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}