code wiki / _hdl_build / nx_fpga_dc.nx
nx_fpga_dc.nx
buildroot/runtime/_hdl_build/nx_fpga_dc.nx
about
nx_fpga_dc.nx -- LIB: RUNG 30 of the sovereign FPGA-boot sim -- the DISPLAY-CONTROLLER peripheral
(an MMIO-mapped framebuffer + scanout). This is the missing rung between the (complete in-sim) RV64IM
CPU and a GAME with graphics: the SoC modeled so far has UART text only; this adds pixels.
THE HONEST HARDWARE MODEL (what is "real gates" vs what is a memory block):
- FRAMEBUFFER STORAGE = a caller-owned memory block of W*H packed-RGB i64 words. In real silicon a
framebuffer is BRAM / external DRAM -- a memory block -- NOT a LUT4/DFF fabric (the fabric RAM tops
out at 16 words by its single-LUT4 address decode). So modeling storage as a memory block is the
FAITHFUL hardware model, not a shortcut.
- THE MMIO ADDRESS DECODE runs ON THE FABRIC -- this is the gate-level logic a display controller adds
to the bus. It composes the PROVEN nx_fpga_addsub subtractor (rungs R6/R7, gate-verified == the
behavioral ALU): for a store address `addr`,
idx = addr - FB_BASE (fabric subtractor result = the linear pixel index)
ge_base = carry_out(addr - FB_BASE) (== 1 iff addr >= FB_BASE; the R8b SLTU convention:
carry-out of a-b is 1 iff a >= b unsigned)
ge_end = carry_out(addr - FB_END) (== 1 iff addr >= FB_END)
in_fb = ge_base AND (NOT ge_end) (FB_BASE <= addr < FB_END)
The substantive decision (two wide unsigned compares + the index subtraction) is a real fabric
computation driven only from the subtractor's bitstream via fab_eval; the final 1-bit AND of the two
decoded flags is orchestration (exactly as the fabric-CPU gates read fabric POs and orchestrate).
SCANOUT: read the framebuffer block -> the games' i64 packed-RGB format (R | G<<8 | B<<16) -> the gate
encodes it to a PNG (write_png) so the fabric's pixels are eyeball-verifiable.
NEVER-BRICK (#26): pure integer, bounded (exactly 2 subtractor passes per decoded store, each O(W) cells),
total, deterministic, caller-owned state, ZERO persistent/hardware writes. A framebuffer pixel write is
volatile VRAM -- a `gui`-axis capability that cannot corrupt firmware/CMOS/NVRAM/EEPROM BY CONSTRUCTION,
so it carries no brick risk even when this peripheral is later bound to a real linear framebuffer.
license_tier: ORIGINAL
dependencies 3 imports · 3 importers
imports: nx_fpga_addsub.nxnx_fpga_fabric.nxnx_syscalls.nx
imported by: nx_fpga_cpu_dc_gate.nxnx_fpga_dc_gate.nxnx_game_display_gate.nx
structs
| 36 | struct NxFpgaDC |
consts
| 33 | const K_MAGIC_2654435761: i64 = 2654435761 |
functions
| 53 | func dc_pack(r: i64, g: i64, b: i64) -> i64 |
| 59 | func dc_init(dc: *NxFpgaDC, fb: *i64, fbw: i64, fbh: i64, base: i64, addr_w: i64, |
| 79 | func dc_decode(dc: *NxFpgaDC, addr: i64) -> i64 |
| 95 | func dc_store(dc: *NxFpgaDC, addr: i64, value: i64) -> i64 |
| 106 | func dc_clear(dc: *NxFpgaDC, color: i64) -> i64 |
| 114 | func dc_checksum(dc: *NxFpgaDC) -> i64 called by 1: main |