Add PicoRV32/Tang Nano 9K target, verified on real hardware#1
Open
delaidam wants to merge 1 commit into
Open
Conversation
Ports the C99 ternary inference engine to a PicoRV32 RISC-V soft-core on a Tang Nano 9K FPGA (nano/tiny config), following the CONTRIBUTING.md invitation for new c_engine/targets/ boards. UART platform layer, PicoRV32 toolchain conventions, and the Gowin EDA flow are adapted (not referenced) from the FreeRTOS-TetriSaraj project's proven UART-only top; that project itself is untouched. Verified end-to-end on physical hardware, not just simulated: firmware boots, model loads, and both the flash/RAM budget and real stack high-water mark were measured directly on-device (17512/32768 B flash, 14456/16384 B RAM including a measured 304 B stack, not inferred). Along the way, found and fixed two real hardware/toolchain bugs specific to this target (documented in detail in the target and hardware READMEs): - RAM starting at address 0x0 aliasing a legitimate pointer with NULL, silently short-circuiting every atome_predict_next() call. - rv32imc (compressed ISA) silently producing zero UART output once progmem grows past ~8 KB on this exact progmem.v/picosoc_noflash.v pair; the target now defaults to rv32im. Also isolated (via temporary, uncommitted instrumentation, not by modifying the engine) a third bug that lives in c_engine/upstream's atome_load() binary parser: the ATOME01 format's 7-byte magic string leaves every subsequent float field 3 bytes off a 4-byte boundary, which PicoRV32's default CATCH_MISALIGN trap turns into a silent permanent hang with no bus-error handler wired up. Confirmed upstream (not target-specific) by running the same checkpoint to completion natively, bit-exact against the Python reference. This blocks a real on-hardware parity run until fixed upstream; will be filed as a separate issue. A real fixed-seed checkpoint (nano_seed42.atome) is included and ready to use the moment that lands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the C99 ternary inference engine to a PicoRV32 RISC-V soft-core on
a Tang Nano 9K FPGA (
nano/tinyconfig), per CONTRIBUTING.md'sinvitation for new
c_engine/targets/boards. UART platform layer,PicoRV32 toolchain conventions, and the Gowin EDA flow are adapted from
the FreeRTOS-TetriSaraj project's proven UART-only top (not referenced,
not modified — this PR ships its own copies under
hardware/tangnano9k/).Verified end-to-end on physical hardware, not just simulated:
firmware boots, the model loads, and both the flash/RAM budget and the
real stack high-water mark were measured directly on-device (17512/32768 B
flash, 14456/16384 B RAM including a measured 304 B stack — not inferred).
See
c_engine/targets/picorv32-tangnano9k/README.mdandhardware/tangnano9k/for full writeups and captured UART evidence.Along the way this found and fixed two real hardware/toolchain bugs
specific to this target:
0x0aliasing a legitimate pointer with NULL,silently short-circuiting every
atome_predict_next()call.rv32imc(compressed ISA) silently producing zero UART output onceprogmem grows past ~8 KB on this exact hardware; the target defaults
to
rv32im.One thing this PR does not fix, because it lives outside
c_engine/targets/and outside the scope CONTRIBUTING.md sets for boardPRs: real inference currently hangs on this hardware once it reaches the
first
LayerNorm, root-caused to a misaligned-pointer bug inatome_load()'s binary parser (details + reproduction in the targetREADME's "A third bug" section). Confirmed upstream, not target-specific,
by running the same checkpoint to completion natively (bit-exact against
the Python reference). Filing that separately as its own issue. A real
fixed-seed checkpoint (
nano_seed42.atome) ships in this PR and is readyto use for a real parity run the moment that's fixed.