code wiki / _hdl_build / nx_fpga_compose.nx

nx_fpga_compose.nx source

↩ module page · 50 lines · 3052 B

1// nx_fpga_compose.nx -- LIB: RUNG 32a -- COMPOSE separate module-fabrics into ONE unified fabric. 2// 3// The CPU rungs (R11..R20) build SEPARATE fabrics (decode, ALU, regfile, PC, IMEM/DMEM RAM) and wire them 4// together in host NishiLang per clock step. To emit the WHOLE CPU as ONE Yosys-synthesizable Verilog netlist 5// (R29 emitted only the ALU) -- the artifact nextpnr/prjtrellis consume toward an ECP5 bitstream -- the datapath 6// must BE a single composed fabric. fab_append copies a sub-fabric's cells into a growing composed fabric, 7// REMAPPING every net: a sub-fabric cell ref (s >= snpi) -> the composed cell slot it landed in; a sub-fabric 8// PI ref (s < snpi) -> the composed net it is WIRED to (inmap[s], either a composed PI or a prior sub-fabric's 9// output). LUT (kind 0) and DFF (kind 1) cells are copied uniformly, so sequential state (regfile/PC/RAM) 10// composes exactly like combinational logic. The composed fabric runs unchanged on fab_eval / seq_eval / seq_tick 11// and serializes through nx_fpga_verilog. 12// NEVER-BRICK (#26): pure memory, bounded by total cells, deterministic (same inputs -> same netlist), zero 13// hardware-state writes. license_tier: ORIGINAL 14import "nx_fpga_fabric.nx" 15import "nx_syscalls.nx" 16 17// Append one sub-fabric's bitstream into the composed fabric arrays. Returns the base cell-offset where the 18// sub-fabric's cell 0 landed (so its cell c is composed NET NPI + base + c, usable to wire later sub-fabrics). 19// NPI composed fabric primary-input count (constant across the whole compose) 20// cinit,csrc,ckind growing composed bitstream (caller-allocated big enough), already holding `cn` cells 21// cn current composed cell count 22// snpi,sn sub-fabric PI count / cell count 23// sinit,ssrc,skind sub-fabric bitstream (skind = its per-cell kind; pass all-0 for a combinational module) 24// inmap inmap[p] = composed NET each sub-fabric PI p reads from (composed PI <NPI, or NPI+base'+c) 25func fab_append(NPI: i64, cinit: *i64, csrc: *i64, ckind: *i64, cn: i64, 26 snpi: i64, sn: i64, sinit: *i64, ssrc: *i64, skind: *i64, inmap: *i64) -> i64 { 27 let base: i64 = cn 28 var k: i64 = 0 29 while k < sn { 30 let dst: i64 = base + k 31 ckind[dst] = skind[k] 32 cinit[dst] = sinit[k] 33 var j: i64 = 0 34 while j < 4 { 35 let s: i64 = ssrc[k*4+j] 36 var rs: i64 = NPI + base + (s - snpi) // default: a cell ref -> remapped composed cell net 37 if s < snpi { rs = inmap[s] } // a PI ref -> the wired composed net 38 csrc[dst*4+j] = rs 39 j = j + 1 40 } 41 k = k + 1 42 } 43 return base 44} 45 46// Map a sub-fabric OUTPUT (one of its po_src[] entries) to a composed NET id, for wiring into a later sub-fabric. 47func fab_sub_out(NPI: i64, base: i64, snpi: i64, sub_po: i64, inmap: *i64) -> i64 { 48 if sub_po < snpi { return inmap[sub_po] } // a passthrough PI 49 return NPI + base + (sub_po - snpi) // a cell output 50}