code wiki / _hdl_build / nx_simd_isa.nx

nx_simd_isa.nx source

↩ module page · 50 lines · 2360 B

1// nx_simd_isa.nx -- a sovereign VECTOR ISA + SIMD emulator, so vectorized kernels 2// run as real vector MACHINE CODE and are proven by EXECUTION (the way we proved the 3// scalar RV64/ARM/x86 emit). Bits-up: Nishi has its own vector extension; the AVX2 / 4// NEON / RVV emit is then a DEPLOY-TIME lowering of this ISA to whatever vector unit 5// the spore/seed lands on (vertical co-design at the deploy boundary). 8 vector 6// registers x SV_W lanes (i64). Instruction = 2 words: [op|vd|va|vb, imm]. 7// 8// Ops: VLOAD vd,[imm] VSTORE [imm],va VADD/VMUL/VSUB vd,va,vb. One vector op does 9// SV_W lanes -- the throughput the uops.info/nanoBench cost model prices. 10 11import "nx_syscalls.nx" 12 13const SV_W: i64 = 8 14 15const SVOP_HALT: i64 = 0 16const SVOP_VLOAD: i64 = 1 17const SVOP_VSTORE: i64 = 2 18const SVOP_VADD: i64 = 3 19const SVOP_VMUL: i64 = 4 20const SVOP_VSUB: i64 = 5 21 22// encode one instruction at slot idx; returns idx+1. 23func sv_emit(prog: *i64, idx: i64, op: i64, vd: i64, va: i64, vb: i64, imm: i64) -> i64 { 24 prog[idx * 2] = op | (vd << 8) | (va << 16) | (vb << 24) 25 prog[idx * 2 + 1] = imm 26 return idx + 1 27} 28 29// execute a straight-line vector program on the vector register file + memory image. 30// VLOAD vd <- mem[imm..]; VSTORE mem[imm..] <- va; VADD/VMUL/VSUB vd = va (op) vb, 31// lane-wise. Returns the number of vector instructions executed. 32func sv_run(prog: *i64, ninstr: i64, vregs: *i64, mem: *i64) -> i64 { 33 var pc: i64 = 0 34 while pc < ninstr { 35 let w: i64 = prog[pc * 2] 36 let imm: i64 = prog[pc * 2 + 1] 37 let op: i64 = w & 0xFF 38 let vd: i64 = (w >> 8) & 0xFF 39 let va: i64 = (w >> 16) & 0xFF 40 let vb: i64 = (w >> 24) & 0xFF 41 var j: i64 = 0 42 if op == SVOP_VLOAD { while j < SV_W { vregs[vd * SV_W + j] = mem[imm + j]; j = j + 1 } } 43 if op == SVOP_VSTORE { while j < SV_W { mem[imm + j] = vregs[va * SV_W + j]; j = j + 1 } } 44 if op == SVOP_VADD { while j < SV_W { vregs[vd * SV_W + j] = vregs[va * SV_W + j] + vregs[vb * SV_W + j]; j = j + 1 } } 45 if op == SVOP_VMUL { while j < SV_W { vregs[vd * SV_W + j] = vregs[va * SV_W + j] * vregs[vb * SV_W + j]; j = j + 1 } } 46 if op == SVOP_VSUB { while j < SV_W { vregs[vd * SV_W + j] = vregs[va * SV_W + j] - vregs[vb * SV_W + j]; j = j + 1 } } 47 pc = pc + 1 48 } 49 return ninstr 50}