code wiki / _hdl_build / nx_nhdl_gate.nx
nx_nhdl_gate.nx source
↩ module page · 123 lines · 7761 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_nhdl_gate.nx -- GATE for NHDL H1: the sovereign netlist format (a Verilog COMPETITOR), proven on the REAL
4// 584-cell CPU datapath (R32b decode+ALU) + a sequential counter, and BENCHMARKED head-to-head vs Verilog.
5// T1 NHDL round-trips the 584-cell CPU datapath BYTE-EXACT (emit->parse->re-emit identical) AND the re-parsed
6// netlist computes == nx_rv64im_alu_compute over the 5 ALU-class ops (lossless + functional).
7// T2 BENCHMARK vs Verilog: emit the SAME fabric to NHDL and to Verilog; NHDL is MUCH smaller, both lossless.
8// T3 SEQUENTIAL: a DFF counter fabric round-trips NHDL byte-exact (the 'D' cell kind works too).
9// T4 NEVER-BRICK (#26): bounded text, pure memory.
10// T5 LIAR-KILL: corrupt one byte of the NHDL text -> the re-parsed netlist computes WRONG (the format carries the logic).
11// Sovereign, no-float. expect_exit: 0 license_tier: ORIGINAL
12import "nx_nhdl.nx"
13import "nx_fpga_rexec.nx"
14import "nx_fpga_verilog.nx"
15import "nx_fpga_seq.nx"
16import "nx_fpga_fabric.nx"
17import "rv64im_min_alu.nx"
18import "nx_syscalls.nx"
19
20func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
21" as *u8); return ok }
22
23func ref_aop(f3: i64, f7b5: i64) -> i64 {
24 if f3==0 { if f7b5==1 { return NX_RV64IM_ALU_SUB } return NX_RV64IM_ALU_ADD }
25 if f3==4 { return NX_RV64IM_ALU_XOR }
26 if f3==6 { return NX_RV64IM_ALU_OR }
27 return NX_RV64IM_ALU_AND
28}
29
30func main() -> i64 {
31 gw("=== nx_nhdl_gate: NHDL H1 -- sovereign netlist format (Verilog COMPETITOR), proven + benchmarked ===\n" as *u8)
32 let W: i64=64
33 var pass: i64=0; var total: i64=0
34 // build the real 584-cell CPU datapath (decode+ALU)
35 let cinit: *i64=sys_mmap(8*700) as *i64; let csrc: *i64=sys_mmap(8*2800) as *i64; let ckind: *i64=sys_mmap(8*700) as *i64
36 let cpo: *i64=sys_mmap(8*72) as *i64; let onpi: *i64=sys_mmap(16) as *i64
37 let NCELLS: i64=fab_build_rexec_alu(W, cinit, csrc, ckind, cpo, onpi)
38 let NPI: i64=onpi[0]
39 let pi: *i64=sys_mmap(8*200) as *i64; let co: *i64=sys_mmap(8*800) as *i64
40
41 let f3s: *i64=sys_mmap(8*8) as *i64; let f7s: *i64=sys_mmap(8*8) as *i64
42 f3s[0]=0; f7s[0]=0; f3s[1]=0; f7s[1]=1; f3s[2]=4; f7s[2]=0; f3s[3]=6; f7s[3]=0; f3s[4]=7; f7s[4]=0
43 let nops: i64=5
44 let ka: *i64=sys_mmap(8*8) as *i64; let kb: *i64=sys_mmap(8*8) as *i64
45 ka[0]=123456789; kb[0]=37; ka[1]=0-1; kb[1]=5; ka[2]=(1<<63); kb[2]=3; ka[3]=0; kb[3]=0-1
46
47 // ---- T1: NHDL round-trip byte-exact + functional ----
48 let nbuf: *u8=sys_mmap(65536)
49 let nlen: i64=nhdl_emit(nbuf, "rexec_cpu" as *u8, NCELLS, NPI, W, ckind, cinit, csrc, cpo)
50 nbuf[nlen]=0 as u8
51 let rk: *i64=sys_mmap(8*700) as *i64; let ri: *i64=sys_mmap(8*700) as *i64; let rs: *i64=sys_mmap(8*2800) as *i64; let rp: *i64=sys_mmap(8*72) as *i64
52 let pn: *i64=sys_mmap(16) as *i64; let pno: *i64=sys_mmap(16) as *i64
53 let rnc: i64=nhdl_parse(nbuf, nlen, rk, ri, rs, rp, pn, pno)
54 let buf2: *u8=sys_mmap(65536)
55 let len2: i64=nhdl_emit(buf2, "rexec_cpu" as *u8, rnc, pn[0], pno[0], rk, ri, rs, rp)
56 var bdiff: i64=0
57 if len2!=nlen { bdiff=bdiff+1 }
58 var bx: i64=0; while bx<nlen { if nbuf[bx]!=buf2[bx] { bdiff=bdiff+1 } bx=bx+1 }
59 var fmis: i64=0
60 var oi: i64=0
61 while oi<nops {
62 let f3: i64=f3s[oi]; let f7: i64=f7s[oi]; let aop: i64=ref_aop(f3,f7)
63 var ki: i64=0
64 while ki<4 {
65 if fab_rexec_run(W, rnc, pn[0], ri, rs, rp, pi, co, f3, f7, ka[ki], kb[ki]) != nx_rv64im_alu_compute(aop, ka[ki], kb[ki]) { fmis=fmis+1 }
66 ki=ki+1
67 }
68 oi=oi+1
69 }
70 total=total+1; if bdiff==0 { if fmis==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
71 gw("T1 NHDL round-trip: byte-diffs=" as *u8); gn(bdiff); gw(" (len=" as *u8); gn(nlen); gw(") re-parsed-netlist functional-mismatches=" as *u8); gn(fmis); gw(" (rnc=" as *u8); gn(rnc); gw(" rnpi=" as *u8); gn(pn[0]); gw(")\n" as *u8)
72
73 // ---- T2: BENCHMARK vs Verilog (same fabric, both lossless; NHDL smaller) ----
74 let vbuf: *u8=sys_mmap(131072)
75 let vlen: i64=fab_emit_verilog_seq(vbuf, NCELLS, NPI, W, ckind, cinit, csrc, cpo)
76 let pct: i64=nlen*100/vlen
77 let xs: i64=vlen/nlen
78 total=total+1; if nlen<vlen { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
79 gw("T2 BENCHMARK vs Verilog (same 584-cell CPU datapath): NHDL=" as *u8); gn(nlen); gw("B Verilog=" as *u8); gn(vlen); gw("B -> NHDL is " as *u8); gn(pct); gw("% the size (~" as *u8); gn(xs); gw("x smaller), both lossless+sovereign\n" as *u8)
80
81 // ---- T3: SEQUENTIAL DFF round-trip (a counter fabric) ----
82 let CW: i64=4
83 let qk: *i64=sys_mmap(8*64) as *i64; let qi: *i64=sys_mmap(8*64) as *i64; let qs: *i64=sys_mmap(8*256) as *i64; let qp: *i64=sys_mmap(8*16) as *i64
84 seq_build_counter(CW, qk, qi, qs, qp)
85 let qnc: i64=3*CW+1
86 let qbuf: *u8=sys_mmap(8192)
87 let qlen: i64=nhdl_emit(qbuf, "counter" as *u8, qnc, 1, CW, qk, qi, qs, qp)
88 let q2k: *i64=sys_mmap(8*64) as *i64; let q2i: *i64=sys_mmap(8*64) as *i64; let q2s: *i64=sys_mmap(8*256) as *i64; let q2p: *i64=sys_mmap(8*16) as *i64
89 let q2pn: *i64=sys_mmap(16) as *i64; let q2po: *i64=sys_mmap(16) as *i64
90 let q2nc: i64=nhdl_parse(qbuf, qlen, q2k, q2i, q2s, q2p, q2pn, q2po)
91 let q3buf: *u8=sys_mmap(8192)
92 let q3len: i64=nhdl_emit(q3buf, "counter" as *u8, q2nc, q2pn[0], q2po[0], q2k, q2i, q2s, q2p)
93 var qdiff: i64=0
94 if q3len!=qlen { qdiff=qdiff+1 }
95 var qx: i64=0; while qx<qlen { if qbuf[qx]!=q3buf[qx] { qdiff=qdiff+1 } qx=qx+1 }
96 var dffcount: i64=0; var dz: i64=0; while dz<q2nc { if q2k[dz]==1 { dffcount=dffcount+1 } dz=dz+1 }
97 total=total+1; if qdiff==0 { if dffcount==CW { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
98 gw("T3 SEQUENTIAL DFF round-trip (counter): byte-diffs=" as *u8); gn(qdiff); gw(" reparsed-DFF-cells=" as *u8); gn(dffcount); gw("/" as *u8); gn(CW); gw("\n" as *u8)
99
100 // ---- T4: never-brick -- bounded text ----
101 total=total+1; if nlen>0 { if nlen<65536 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
102 gw("T4 NEVER-BRICK (#26): NHDL emit bounded (" as *u8); gn(nlen); gw(" bytes < buffer), pure memory, zero hardware-state writes\n" as *u8)
103
104 // ---- T5: liar-kill -- corrupt one byte of the NHDL text -> re-parsed netlist computes WRONG ----
105 var lpos: i64=0-1; var si: i64=0
106 while si<nlen { if nbuf[si]==(76 as u8) { if lpos<0 { lpos=si } } si=si+1 } // first 'L' (cell 0's line)
107 let dpos: i64=lpos+2 // first digit of cell 0's init
108 if (nbuf[dpos] as i64)==48 { nbuf[dpos]=49 as u8 } else { nbuf[dpos]=48 as u8 }
109 let ck2: i64=nhdl_parse(nbuf, nlen, rk, ri, rs, rp, pn, pno)
110 var liar_wrong: i64=0
111 var lt: i64=0
112 while lt<nops {
113 let f3: i64=f3s[lt]; let f7: i64=f7s[lt]
114 if fab_rexec_run(W, ck2, pn[0], ri, rs, rp, pi, co, f3, f7, 1234567, 89) != nx_rv64im_alu_compute(ref_aop(f3,f7), 1234567, 89) { liar_wrong=liar_wrong+1 }
115 lt=lt+1
116 }
117 total=total+1; if liar_wrong>0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
118 gw("T5 LIAR-KILL: 1 corrupted NHDL byte -> re-parsed netlist wrong on " as *u8); gn(liar_wrong); gw("/5 ops\n" as *u8)
119
120 gw("NHDL-GATE verdict=" as *u8)
121 if pass==total { gw("GREEN passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw(" END\n" as *u8); sys_exit(0); return 0 }
122 gw("RED passes=" as *u8); gn(pass); gw("/" as *u8); gn(total); gw(" END\n" as *u8); sys_exit(1); return 1
123}