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}