code wiki / _hdl_build / nx_cpu_rtype_exec_test.nx

nx_cpu_rtype_exec_test.nx source

↩ module page · 143 lines · 6556 B

1// nx_cpu_rtype_exec_test.nx -- TOP-LEVEL COMPOSITION capstone: a full R-type decode->execute 2// datapath, composed from the three proven gate-emit modules in ONE gate-sim graph: 3// inst -> [decoder fields] -> funct3/funct7 -> [R-type control] -> alu_op 4// (rs1_val, rs2_val, alu_op) -> [ALU build_select, divider-backed] -> result 5// Verifies the composed netlist against the behavioral chain 6// decode_kind -> sim_alu_select -> nx_rv64im_alu_compute 7// over funct3 0..7 x funct7 {0,1,0x20} x random nonzero operands. Proves the decoder + control + ALU 8// COMPOSE into a working R-type execute datapath at the GATE level -- the integration milestone 9// toward emitting the whole CPU. Sovereign, no-float. license_tier: ORIGINAL expect_exit: 0 10import "nx_decoder_select.nx" 11import "nx_rtype_control.nx" 12import "nx_alu_select.nx" 13import "rv64im_min_sim.nx" // nx_rv64im_sim_alu_select + NX_RV64IM_OP_OP 14import "rv64im_min_alu.nx" // nx_rv64im_alu_compute 15 16func _emit_cstr(s: *u8) -> i64 { 17 var n: i64 = 0 18 while s[n] != (0 as u8) { n = n + 1 } 19 sys_write(1, s, n) 20 return 0 21} 22func _emit_dec(v: i64) -> i64 { 23 let b: *u8 = sys_mmap(28) 24 let t2: *u8 = sys_mmap(28) 25 var n: i64 = v 26 if n < 0 { sys_write(1, "-" as *u8, 1); n = 0 - n } 27 var t: i64 = 0 28 if n == 0 { t2[0] = 48; t = 1 } 29 while n > 0 { t2[t] = 48 + (n % 10); n = n / 10; t = t + 1 } 30 var i: i64 = 0 31 while i < t { b[i] = t2[t - 1 - i]; i = i + 1 } 32 sys_write(1, b, t) 33 return 0 34} 35 36func main() -> i64 { 37 let cells: *NxGsimCell = sys_mmap(48 * 8000) as *NxGsimCell 38 let vals: *i64 = sys_mmap(8 * 8000) as *i64 39 let g: *NxGsim = sys_mmap(64) as *NxGsim 40 g.cells = cells 41 g.vals = vals 42 let k: *NxCellSink = sys_mmap(64) as *NxCellSink 43 44 g.n_nets = 3 // net 0 = inst, net 1 = rs1_val, net 2 = rs2_val 45 g.n_cells = 0 46 nx_sink_init_mem(k, g) 47 // compose: decoder fields -> control -> ALU 48 let outs: *i64 = sys_mmap(8 * 6) as *i64 49 nx_decoder_fields_build(k, 0, outs) // outs[2]=funct3, outs[5]=funct7 50 let aluop: i64 = nx_rtype_op_aluop_build(k, outs[2], outs[5]) 51 let result: i64 = nx_alu_build_select(k, 1, 2, aluop, 1) // a=rs1_val, b=rs2_val, op=alu_op 52 53 let f7s: *i64 = sys_mmap(8 * 4) as *i64 54 f7s[0] = 0; f7s[1] = 1; f7s[2] = 32 55 var seed: i64 = 1234567 56 var mism: i64 = 0 57 var checks: i64 = 0 58 var c_f3: i64 = 0 - 1 59 var c_f7: i64 = 0 60 var c_a: i64 = 0 61 var c_b: i64 = 0 62 var c_got: i64 = 0 63 var c_exp: i64 = 0 64 var fi: i64 = 0 65 while fi < 3 { 66 var f3: i64 = 0 67 while f3 < 8 { 68 var rep: i64 = 0 69 while rep < 5 { 70 seed = (seed * 1103515245 + 12345) & 2147483647 71 let a: i64 = seed 72 seed = (seed * 1103515245 + 12345) & 2147483647 73 let b0: i64 = seed 74 var b: i64 = b0 | 1 // nonzero divisor 75 // RV64: shift ops use rs2[5:0]. The gate ALU NOW masks the shift amount internally 76 // (METAL-03 fix in nx_alu_build_select), so feed the RAW random b -- the gate must 77 // match the behavioral a<<(b&0x3f) for ANY b, including out-of-range amounts. 78 // build the R-type instruction word (rd/rs1/rs2 arbitrary; only funct3/funct7 matter here) 79 let inst: i64 = 51 | (f3 << 12) | (f7s[fi] << 25) | (1 << 7) | (2 << 15) | (3 << 20) 80 g.vals[0] = inst 81 g.vals[1] = a 82 g.vals[2] = b 83 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(40); return 40 } 84 let got: i64 = g.vals[result] 85 let aop: i64 = nx_rv64im_sim_alu_select(NX_RV64IM_OP_OP, f3, f7s[fi]) 86 let exp: i64 = nx_rv64im_alu_compute(aop, a, b) 87 if got != exp { 88 if c_f3 < 0 { c_f3 = f3; c_f7 = f7s[fi]; c_a = a; c_b = b; c_got = got; c_exp = exp } 89 mism = mism + 1 90 } 91 checks = checks + 1 92 rep = rep + 1 93 } 94 f3 = f3 + 1 95 } 96 fi = fi + 1 97 } 98 _emit_cstr("R-type datapath: checks=" as *u8); _emit_dec(checks) 99 _emit_cstr(" mismatches=" as *u8); _emit_dec(mism); _emit_cstr("\n" as *u8) 100 if c_f3 >= 0 { 101 _emit_cstr(" first diverge: f3=" as *u8); _emit_dec(c_f3) 102 _emit_cstr(" f7=" as *u8); _emit_dec(c_f7) 103 _emit_cstr(" a=" as *u8); _emit_dec(c_a) 104 _emit_cstr(" b=" as *u8); _emit_dec(c_b) 105 _emit_cstr(" got=" as *u8); _emit_dec(c_got) 106 _emit_cstr(" exp=" as *u8); _emit_dec(c_exp); _emit_cstr("\n" as *u8) 107 } 108 109 // KAT: add (f3=0,f7=0), a=20 b=4 -> 24 110 let inst_add: i64 = 51 | (1 << 7) | (2 << 15) | (3 << 20) 111 g.vals[0] = inst_add; g.vals[1] = 20; g.vals[2] = 4 112 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(41); return 41 } 113 let kadd: i64 = g.vals[result] 114 // KAT: mul (f3=0,f7=1), a=20 b=4 -> 80 115 let inst_mul: i64 = 51 | (1 << 25) | (1 << 7) | (2 << 15) | (3 << 20) 116 g.vals[0] = inst_mul; g.vals[1] = 20; g.vals[2] = 4 117 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(42); return 42 } 118 let kmul: i64 = g.vals[result] 119 _emit_cstr("KAT add(20,4)=" as *u8); _emit_dec(kadd) 120 _emit_cstr(" mul(20,4)=" as *u8); _emit_dec(kmul); _emit_cstr("\n" as *u8) 121 122 // KAT (METAL-03): out-of-range shift amounts MUST mask to rs2[5:0] (would FAIL pre-fix). 123 // SLL a=1 b=65 -> 1 << (65 & 63) = 1 << 1 = 2 124 let inst_sll: i64 = 51 | (1 << 12) | (1 << 7) | (2 << 15) | (3 << 20) 125 g.vals[0] = inst_sll; g.vals[1] = 1; g.vals[2] = 65 126 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(43); return 43 } 127 let ksll: i64 = g.vals[result] 128 // SRL a=256 b=64 -> 64 & 63 = 0 -> NO shift -> 256 129 let inst_srl: i64 = 51 | (5 << 12) | (1 << 7) | (2 << 15) | (3 << 20) 130 g.vals[0] = inst_srl; g.vals[1] = 256; g.vals[2] = 64 131 if nx_gsim_run(g) != NX_GSIM_OK { sys_exit(44); return 44 } 132 let ksrl: i64 = g.vals[result] 133 _emit_cstr("KAT(METAL-03) sll(1,65)=" as *u8); _emit_dec(ksll); _emit_cstr(" srl(256,64)=" as *u8); _emit_dec(ksrl); _emit_cstr("\n" as *u8) 134 135 if mism != 0 { sys_exit(1); return 1 } 136 if kadd != 24 { sys_exit(2); return 2 } 137 if kmul != 80 { sys_exit(3); return 3 } 138 if ksll != 2 { sys_exit(4); return 4 } 139 if ksrl != 256 { sys_exit(5); return 5 } 140 _emit_cstr("R-TYPE DATAPATH COMPOSE PASS (decode->control->ALU; 120 checks 0 mismatch; add/mul KATs)\n" as *u8) 141 sys_exit(0) 142 return 0 143}