code wiki / _hdl_build / nx_isa_synth_sov.nx
nx_isa_synth_sov.nx
buildroot/runtime/_hdl_build/nx_isa_synth_sov.nx
about
nx_isa_synth_sov.nx -- SHAPE-DISCOVERY SYNTHESIS: the team is given only (a,b)->T(a,b) examples
and must DISCOVER the control-flow CLASS that fits -- straight-line, conditional, or loop -- AND
the computation, then prove it on god. Removes the last crutch of the trilogy (shape was TOLD).
One UNIFIED program space (gene[0]=shape in {0 straight, 1 conditional, 2 loop}; gene[1..7]=payload):
shape 0 STRAIGHT: res = op2( op1(reg,reg), reg ) over {0,a,b}
shape 1 COND: if cmp(a,b) then op(reg,reg) else op(reg,reg) over {0,a,b}
shape 2 LOOP: acc=0; i=a; while i>0 { acc += op2(op1(reg,reg),reg); i-- } over {0,i,a,b}
All three terminate, so the search never hangs. The GA searches shape AND payload together, so it
DISCOVERS the structure. Emit dispatches to the matching RV64 skeleton (each path already verified
in nx_isa_equiv/cf/loop_sov); run BOTH T and G on rv64im_min_sim over 12 HELD-OUT; verify
sim(T)==sim(G). When the derived SHAPE != the target shape but sim==sim, that is structural
divergence with behavioral equivalence -- reported. Controls: FAITHFUL (one known program of EACH
shape on god == known answer) + NEGATIVE (a perturbed G the differential must catch). license_tier: ORIGINAL
dependencies 9 imports · 0 importers
imports: nx_syscalls.nxnishi_hdl_primitives.nxrv64im_min_decoder.nxrv64im_min_alu.nxrv64im_min_regfile.nxrv64im_min_csr.nxrv64im_min_clint.nxrv64im_min_uart.nxrv64im_min_sim.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 24 | const EVO_MAGIC_2862933555777941757: i64 = 2862933555777941757 |
| 25 | const EVO_MAGIC_3037000493: i64 = 3037000493 |
| 26 | const EVO_MAGIC_1000000000000: i64 = 1000000000000 |
| 27 | const EVO_MAGIC_10000000000000: i64 = 10000000000000 |
| 28 | const EVO_MAGIC_1000000000: i64 = 1000000000 |
| 29 | const EVO_MAGIC_2654435761: i64 = 2654435761 |
| 30 | const EVO_MAGIC_12345: i64 = 12345 |
| 32 | const GLEN: i64 = 8 // [shape, p1..p7] |
| 33 | const EVO_P: i64 = 400 |
| 34 | const EVO_G: i64 = 1500 |
| 35 | const EVO_T: i64 = 5 |
| 36 | const NTRAIN: i64 = 8 |
| 37 | const NHELD: i64 = 12 |
| 39 | const IR_MEM_BASE: i64 = 0x80000000 |
| 40 | const IR_MEM_SIZE: i64 = 8192 |
| 41 | const IR_TX_CAP: i64 = 256 |
| 42 | const RES_OFF: i64 = 0x700 |
functions
| 44 | func su_rand(s: *i64) -> i64 { s[0] = s[0] * EVO_MAGIC_2862933555777941757 + EVO_MAGIC_3037000493; return (s[0] >> 17) & 0x3fffffff } |
| 45 | func su_abs(x: i64) -> i64 { if x < 0 { return 0 - x } return x } called by 1: su_fit |
| 47 | func su_ta(i: i64) -> i64 { if i==0 {return 6} if i==1 {return 4} if i==2 {return 9} if i==3 {return 5} if i==4 {return 7} if i==5 {return 3} if i==6 {return 8} return 2 } |
| 48 | func su_tb(i: i64) -> i64 { if i==0 {return 4} if i==1 {return 7} if i==2 {return 2} if i==3 {return 9} if i==4 {return 3} if i==5 {return 6} if i==6 {return 5} return 8 } |
| 49 | func su_ha(i: i64) -> i64 { if i==0 {return 3} if i==1 {return 8} if i==2 {return 11} if i==3 {return 2} if i==4 {return 10} if i==5 {return 13} if i==6 {return 7} if i==7 {return 4} if i==8 {return 12} if i==9 {return 6} if i==10 {return 9} return 5 } |
| 50 | func su_hb(i: i64) -> i64 { if i==0 {return 5} if i==1 {return 2} if i==2 {return 7} if i==3 {return 11} if i==4 {return 4} if i==5 {return 3} if i==6 {return 9} if i==7 {return 8} if i==8 {return 2} if i==9 {return 13} if i==10 {return 6} return 10 } |
| 53 | func su_aluop(op: i64, x: i64, y: i64) -> i64 called by 1: su_eval_at |
| 58 | func su_reg(idx: i64, a: i64, b: i64) -> i64 { // straight/cond reg: 0->0 1->a 2->b 3->a called by 1: su_eval_at |
| 64 | func su_regl(idx: i64, i: i64, a: i64, b: i64) -> i64 { // loop reg: 0->0 1->i 2->a 3->b called by 1: su_eval_at |
| 70 | func su_cmp(c: i64, a: i64, b: i64) -> i64 |
| 76 | func su_eval_at(g: *i64, base: i64, a: i64, b: i64) -> i64 |
| 96 | func su_eval(g: *i64, a: i64, b: i64) -> i64 { return su_eval_at(g, 0, a, b) } |
| 99 | func rv_addi(rd: i64, rs1: i64, imm: i64) -> i64 { return ((imm & 0xFFF) << 20) | (rs1 << 15) | (rd << 7) | 0x13 } |
| 100 | func rv_lui(rd: i64, imm20: i64) -> i64 { return ((imm20 & 0xFFFFF) << 12) | (rd << 7) | 0x37 } |
| 101 | func rv_rtype(f7: i64, rs2: i64, rs1: i64, f3: i64, rd: i64) -> i64 { return (f7 << 25) | (rs2 << 20) | (rs1 << 15) | (f3 << 12) | (rd << 7) | 0x33 } called by 1: su_emit |
| 102 | func rv_store_imm(rs2: i64, rs1: i64, f3: i64, imm: i64) -> i64 { return (((imm >> 5) & 0x7f) << 25) | (rs2 << 20) | (rs1 << 15) | (f3 << 12) | ((imm & 0x1f) << 7) | 0x23 } called by 1: su_emit_tail |
| 103 | func rv_branch(f3: i64, rs1: i64, rs2: i64, imm: i64) -> i64 { return (((imm >> 12) & 1) << 31) | (((imm >> 5) & 0x3f) << 25) | (rs2 << 20) | (rs1 << 15) | (f3 << 12) | (((imm >> 1) & 0xf) << 8) | (((imm >> 11) & 1) << 7) | 0x63 } called by 1: su_emit |
| 104 | func rv_jal(rd: i64, imm: i64) -> i64 { return (((imm >> 20) & 1) << 31) | (((imm >> 1) & 0x3ff) << 21) | (((imm >> 11) & 1) << 20) | (((imm >> 12) & 0xff) << 12) | (rd << 7) | 0x6f } called by 1: su_emit |
| 105 | func su_f7(op: i64) -> i64 { if (op % 3) == 1 { return 0x20 } if (op % 3) == 2 { return 0x01 } return 0x00 } called by 1: su_emit |
| 106 | func su_bf3(c: i64) -> i64 { if c == 0 { return 4 } if c == 1 { return 5 } if c == 2 { return 0 } return 1 } called by 1: su_emit |
| 107 | func su_regx(idx: i64) -> i64 { if idx == 0 { return 0 } if idx == 1 { return 1 } if idx == 2 { return 2 } return 1 } // straight/cond: a=x1 b=x2 called by 1: su_emit |
| 108 | func su_regxl(idx: i64) -> i64 { if idx == 0 { return 0 } if idx == 1 { return 4 } if idx == 2 { return 1 } return 2 } // loop: i=x4 a=x1 b=x2 called by 1: su_emit |
| 109 | func rv_w32(buf: *u8, off: i64, w: i64) -> i64 |
| 117 | func su_emit_tail(mem: *u8, o: i64) -> i64 |
| 127 | func su_emit(mem: *u8, g: *i64, a: i64, b: i64) -> i64 |
| 159 | func su_read_i64(mem: *u8, off: i64) -> i64 called by 1: su_run_prog |
| 164 | func su_run_prog(g: *i64, a: i64, b: i64) -> i64 |
| 187 | func su_randslot(idx: i64, state: *i64) -> i64 { if idx == 0 { return su_rand(state) % 3 } return su_rand(state) % 4 } |
| 188 | func su_fill(g: *i64, base: i64, state: *i64) -> i64 { var i: i64 = 0; while i < GLEN { g[base + i] = su_randslot(i, state); i = i + 1 } return 0 } |
| 190 | func su_nontrivial(T: *i64) -> i64 |
| 206 | func su_compose(state: *i64, T: *i64) -> i64 |
| 211 | func su_fit(pop: *i64, base: i64, T: *i64) -> i64 |
| 224 | func su_tourney(fit: *i64, state: *i64) -> i64 |
| 229 | func su_mut(g: *i64, base: i64, state: *i64) -> i64 { let idx: i64 = su_rand(state) % GLEN; g[base + idx] = su_randslot(idx, state); return 0 } |
| 230 | func su_derive(T: *i64, state: *i64, G: *i64) -> i64 |
| 263 | func su_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 264 | func su_pn(v: i64) -> i64 |
| 274 | func su_shape(s: i64) -> i64 { if s == 0 { su_p("straight") } else { if s == 1 { su_p("cond") } else { su_p("loop") } } return 0 } |
| 278 | func su_set8(g: *i64, s: i64, p1: i64,p2: i64,p3: i64,p4: i64,p5: i64,p6: i64,p7: i64) -> i64 called by 1: su_faithful |
| 281 | func su_faithful() -> i64 |
| 294 | func su_hw_agree(A: *i64, B: *i64) -> i64 |
| 299 | func su_hw_faithful(T: *i64) -> i64 |
| 304 | func su_seed(seed: i64) -> i64 |
| 326 | func su_negctl(seed: i64) -> i64 |
| 348 | func main() -> i64 |