code wiki / _hdl_build / nx_nhdl_hier.nx

nx_nhdl_hier.nx source

↩ module page · 98 lines · 4961 B

1// nx_nhdl_hier.nx -- LIB: NHDL H2 -- HIERARCHY for the sovereign netlist format: a module DEFINED ONCE and 2// INSTANTIATED many times (the "folded" netlist the researched 'Netlist' entry describes: "5 definitions -> 3// 128 instances -> a million cells" -- compact reuse, the thing a flat netlist or a Verilog cell-dump can't do). 4// 5// GRAMMAR (v2): 6// .nhdl 2 7// .def <name> <npi> <npo> <ncells> # a reusable module definition (local net numbering) 8// L .. / D .. # its cells 9// .po <local nets> 10// .enddef 11// .top <npi> <npo> # the top module 12// .inst <name> <innet0> .. <innet{npi-1}> # instantiate <name>, wiring its PIs to top nets (PI / prior-inst output) 13// ... 14// .po <top nets> 15// .end 16// 17// ELABORATION (unfolding) -> a single flat fabric, via the PROVEN fab_append (R32a): each .inst appends the module's 18// cells with an inmap from its listed inputs; the instance's outputs become new top nets (tracked h2c[]). The flat 19// result runs on fab_eval and round-trips through H1. NEVER-BRICK (#26): pure memory, bounded, deterministic. 20// license_tier: ORIGINAL 21import "nx_nhdl.nx" 22import "nx_fpga_compose.nx" 23import "nx_fpga_fabric.nx" 24import "nx_syscalls.nx" 25const K_MAGIC_2048: i64 = 2048 26const K_MAGIC_4096: i64 = 4096 27 28// emit cell lines (no wrapper) -- for a .def body 29func nh_emit_cells(buf: *u8, o: i64, ncells: i64, kind: *i64, init: *i64, src: *i64) -> i64 { 30 var oo: i64=o; var k: i64=0 31 while k<ncells { 32 if kind[k]==1 { oo=nh_ws(buf,oo,"D \x00" as *u8); oo=nh_wi(buf,oo,src[k*4+0]); oo=nh_ws(buf,oo,"\n\x00" as *u8) } 33 else { 34 oo=nh_ws(buf,oo,"L \x00" as *u8); oo=nh_wi(buf,oo,init[k]) 35 oo=nh_ws(buf,oo," \x00" as *u8); oo=nh_wi(buf,oo,src[k*4+0]); oo=nh_ws(buf,oo," \x00" as *u8); oo=nh_wi(buf,oo,src[k*4+1]) 36 oo=nh_ws(buf,oo," \x00" as *u8); oo=nh_wi(buf,oo,src[k*4+2]); oo=nh_ws(buf,oo," \x00" as *u8); oo=nh_wi(buf,oo,src[k*4+3]); oo=nh_ws(buf,oo,"\n\x00" as *u8) 37 } 38 k=k+1 39 } 40 return oo 41} 42 43// parse ncells cell lines into kind/init/src (pp advanced) 44func nh_parse_cells(buf: *u8, pp: *i64, len: i64, ncells: i64, kind: *i64, init: *i64, src: *i64) -> i64 { 45 var k: i64=0 46 while k<ncells { 47 pp[0]=nh_skip_ws(buf, pp[0], len) 48 let kc: i64=buf[pp[0]] as i64 49 pp[0]=pp[0]+1 50 if kc==68 { kind[k]=1; init[k]=0; src[k*4+0]=nh_rd_int(buf,pp,len); src[k*4+1]=0; src[k*4+2]=0; src[k*4+3]=0 } 51 else { kind[k]=0; init[k]=nh_rd_int(buf,pp,len); src[k*4+0]=nh_rd_int(buf,pp,len); src[k*4+1]=nh_rd_int(buf,pp,len); src[k*4+2]=nh_rd_int(buf,pp,len); src[k*4+3]=nh_rd_int(buf,pp,len) } 52 k=k+1 53 } 54 return 0 55} 56 57// ELABORATE hierarchical NHDL (one .def + N .inst) -> flat fabric. Returns flat ncells; outnpi/outnpo set; cpo filled. 58func nhdl_hier_elaborate(buf: *u8, len: i64, cinit: *i64, csrc: *i64, ckind: *i64, cpo: *i64, outnpi: *i64, outnpo: *i64) -> i64 { 59 let pp: *i64=sys_mmap(16) as *i64; pp[0]=0 60 nh_skip_word(buf,pp,len) // .nhdl 61 nh_skip_word(buf,pp,len) // 2 62 // ----- the module definition ----- 63 nh_skip_word(buf,pp,len) // .def 64 nh_skip_word(buf,pp,len) // <name> 65 let m_npi: i64=nh_rd_int(buf,pp,len); let m_npo: i64=nh_rd_int(buf,pp,len); let m_nc: i64=nh_rd_int(buf,pp,len) 66 let mk: *i64=sys_mmap(8*512) as *i64; let mi: *i64=sys_mmap(8*512) as *i64; let ms: *i64=sys_mmap(8*K_MAGIC_2048) as *i64; let mpo: *i64=sys_mmap(8*128) as *i64 67 nh_parse_cells(buf,pp,len,m_nc,mk,mi,ms) 68 nh_skip_word(buf,pp,len) // .po 69 var jj: i64=0; while jj<m_npo { mpo[jj]=nh_rd_int(buf,pp,len); jj=jj+1 } 70 nh_skip_word(buf,pp,len) // .enddef 71 // ----- the top module ----- 72 nh_skip_word(buf,pp,len) // .top 73 let NPI: i64=nh_rd_int(buf,pp,len); let TNPO: i64=nh_rd_int(buf,pp,len) 74 outnpi[0]=NPI; outnpo[0]=TNPO 75 let h2c: *i64=sys_mmap(8*K_MAGIC_4096) as *i64 // hierarchical net -> composed net 76 var h: i64=0; while h<NPI { h2c[h]=h; h=h+1 } 77 var next_h: i64=NPI 78 var cn: i64=0 79 let inmap: *i64=sys_mmap(8*128) as *i64 80 // ----- instances until .po (peek: '.inst' starts with 'i', '.po' with 'p') ----- 81 var go: i64=1 82 while go==1 { 83 let q: i64=nh_skip_ws(buf, pp[0], len) 84 if (buf[q+1] as i64)==105 { 85 nh_skip_word(buf,pp,len) // .inst 86 nh_skip_word(buf,pp,len) // <name> 87 var p: i64=0 88 while p<m_npi { inmap[p]=h2c[nh_rd_int(buf,pp,len)]; p=p+1 } 89 let base: i64=fab_append(NPI, cinit, csrc, ckind, cn, m_npi, m_nc, mi, ms, mk, inmap) 90 cn=cn+m_nc 91 var o: i64=0 92 while o<m_npo { h2c[next_h]=fab_sub_out(NPI, base, m_npi, mpo[o], inmap); next_h=next_h+1; o=o+1 } 93 } else { go=0 } 94 } 95 nh_skip_word(buf,pp,len) // .po 96 var t: i64=0; while t<TNPO { cpo[t]=h2c[nh_rd_int(buf,pp,len)]; t=t+1 } 97 return cn 98}