code wiki / _hdl_build / nx_fpga_bitstream_gate.nx

nx_fpga_bitstream_gate.nx source

↩ module page · 112 lines · 6260 B

1// nx_fpga_bitstream_gate.nx -- GATE for the sovereign bitstream encoder (M4 prjtrellis replacement). Encodes a real 2// fabric (the full-adder: SUM=parity3, COUT=maj3) and proves the bitstream is a faithful, loadable twin: 3// T1 STRUCTURAL RT -- encode->decode reconstructs inits/routing/outputs byte-exact (consumed == size). 4// T2 FUNCTIONAL RT -- the DECODED fabric run on fab_eval == the golden full-adder over all 8 input combos 5// (a loaded bitstream computes the design exactly). 6// T3 FORMAT SIZE -- packed size == 4 (magic) + 6 (hdr) + 2 cells*10 + 2 outs*2 = 34 bytes. 7// T4 LIAR-KILL -- flipping ONE bitstream byte makes the decoded fabric compute the WRONG answer (the bits are load-bearing). 8// T5 NEVER-BRICK -- deterministic (re-encode byte-identical); writes knowledge/nx_fpga.nbit (the sovereign .bit). 9// GREEN iff all pass. Sovereign nx_cc->nxasm, no Lattice/prjtrellis/Verilog. expect_exit: 0 license_tier: ORIGINAL 10import "nx_fpga_bitstream.nx" 11import "nx_fpga_fabric.nx" 12import "nx_fpga_lut.nx" 13import "nx_syscalls.nx" 14 15func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 16func wn(v: i64) -> i64 { var m: i64=v; if m<0{w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 } 17func parity3_init() -> i64 { var tt: i64=0; var i: i64=0; while i<16 { let a: i64=i&1; let b: i64=(i>>1)&1; let c: i64=(i>>2)&1; if (a^b^c)==1 { tt=tt|(1<<i) } i=i+1 } return tt } 18func maj3_init() -> i64 { var tt: i64=0; var i: i64=0; while i<16 { let a: i64=i&1; let b: i64=(i>>1)&1; let c: i64=(i>>2)&1; if (a+b+c)>=2 { tt=tt|(1<<i) } i=i+1 } return tt } 19 20func main() -> i64 { 21 w("=== nx_fpga_bitstream_gate: SOVEREIGN bitstream encoder (M4 prjtrellis replacement; no Lattice tools) ===\n" as *u8) 22 var pass: i64 = 0; var total: i64 = 0 23 24 let npi: i64 = 3; let ncells: i64 = 2; let npo: i64 = 2 25 let inits: *i64 = sys_mmap(8*4) as *i64 26 inits[0]=parity3_init(); inits[1]=maj3_init() 27 let src: *i64 = sys_mmap(8*16) as *i64 28 src[0]=0; src[1]=1; src[2]=2; src[3]=0 29 src[4]=0; src[5]=1; src[6]=2; src[7]=0 30 let po_src: *i64 = sys_mmap(8*4) as *i64 31 po_src[0]=npi+0; po_src[1]=npi+1 32 33 let buf: *u8 = sys_mmap(256) 34 let size: i64 = bs_encode(inits, src, po_src, ncells, npi, npo, buf) 35 36 // T3 format size 37 total=total+1; if size == 34 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 38 w("T3 format size: " as *u8); wn(size); w(" bytes (== 4 magic + 6 hdr + 2*10 cells + 2*2 outs = 34)\n" as *u8) 39 40 // decode 41 let inits2: *i64 = sys_mmap(8*4) as *i64 42 let src2: *i64 = sys_mmap(8*16) as *i64 43 let po2: *i64 = sys_mmap(8*4) as *i64 44 let hdr: *i64 = sys_mmap(8*4) as *i64 45 let consumed: i64 = bs_decode(buf, inits2, src2, po2, hdr) 46 47 // T1 structural round-trip 48 var s_ok: i64 = 1 49 if hdr[0]!=ncells { s_ok=0 } 50 if hdr[1]!=npi { s_ok=0 } 51 if hdr[2]!=npo { s_ok=0 } 52 if inits2[0]!=inits[0] { s_ok=0 } 53 if inits2[1]!=inits[1] { s_ok=0 } 54 var i: i64 = 0 55 while i < 8 { if src2[i]!=src[i] { s_ok=0 } i=i+1 } 56 if po2[0]!=po_src[0] { s_ok=0 } 57 if po2[1]!=po_src[1] { s_ok=0 } 58 if consumed != size { s_ok=0 } 59 total=total+1; if s_ok==1 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 60 w("T1 structural round-trip: decoded inits/routing/outputs byte-exact, consumed=" as *u8); wn(consumed); w("\n" as *u8) 61 62 // T2 functional round-trip: decoded fabric == golden full-adder 63 let pi: *i64 = sys_mmap(8*4) as *i64 64 let co: *i64 = sys_mmap(8*8) as *i64 65 var bad: i64 = 0; var v: i64 = 0 66 while v < 8 { 67 let a: i64=v&1; let b: i64=(v>>1)&1; let cin: i64=(v>>2)&1 68 pi[0]=a; pi[1]=b; pi[2]=cin 69 fab_eval(hdr[0], hdr[1], inits2, src2, pi, co) 70 let sum: i64 = fab_po(po2[0], hdr[1], pi, co) 71 let cout: i64 = fab_po(po2[1], hdr[1], pi, co) 72 if sum != (a^b^cin) { bad=bad+1 } 73 if cout != (((a+b+cin)>=2) as i64) { bad=bad+1 } 74 v=v+1 75 } 76 total=total+1; if bad==0 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 77 w("T2 functional round-trip: decoded fabric == golden full-adder over 8 combos, wrong=" as *u8); wn(bad); w("\n" as *u8) 78 79 // T4 liar-kill: corrupt one bitstream byte (cell0 init lo byte at offset 10) 80 let bad_buf: *u8 = sys_mmap(256) 81 i = 0 82 while i < size { bad_buf[i] = buf[i]; i=i+1 } 83 bad_buf[10] = ((bad_buf[10] as i64) ^ 1) as u8 84 bs_decode(bad_buf, inits2, src2, po2, hdr) 85 var liar: i64 = 0; v = 0 86 while v < 8 { 87 let a: i64=v&1; let b: i64=(v>>1)&1; let cin: i64=(v>>2)&1 88 pi[0]=a; pi[1]=b; pi[2]=cin 89 fab_eval(hdr[0], hdr[1], inits2, src2, pi, co) 90 let sum: i64 = fab_po(po2[0], hdr[1], pi, co) 91 if sum != (a^b^cin) { liar=liar+1 } 92 v=v+1 93 } 94 total=total+1; if liar>0 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 95 w("T4 liar-kill: a 1-byte bitstream flip makes SUM wrong in " as *u8); wn(liar); w("/8 (the fabric runs the bits)\n" as *u8) 96 97 // T5 never-brick: deterministic re-encode + write file 98 let buf2: *u8 = sys_mmap(256) 99 let size2: i64 = bs_encode(inits, src, po_src, ncells, npi, npo, buf2) 100 var diff: i64 = 0 101 if size2 != size { diff = 1 } 102 i = 0 103 while i < size { if (buf[i] as i64) != (buf2[i] as i64) { diff=1; i=size } else { i=i+1 } } 104 total=total+1; if diff==0 { pass=pass+1; w(" [PASS] " as *u8) } else { w(" [FAIL] " as *u8) } 105 w("T5 never-brick: deterministic re-encode byte-identical diff=" as *u8); wn(diff); w("\n" as *u8) 106 bs_write("knowledge/nx_fpga.nbit" as *u8, buf, size) 107 w(" wrote knowledge/nx_fpga.nbit (" as *u8); wn(size); w(" bytes, the sovereign bitstream)\n" as *u8) 108 109 w("\n=== nx_fpga_bitstream_gate " as *u8); wn(pass); w("/" as *u8); wn(total) 110 if pass == total { w(" GREEN (sovereign bitstream: encode/decode round-trip faithful + load-bearing + deterministic; the M4 prjtrellis replacement)\n" as *u8); sys_exit(0); return 0 } 111 w(" RED\n" as *u8); sys_exit(1); return 1 112}