Repository navigation
fpga(ax7203): ternary mat-vec over real tern-tc-9m weights in DDR3, UART receipt (Closes #10461) - #10475
Open
gHashTag wants to merge 9 commits into
Open
fpga(ax7203): ternary mat-vec over real tern-tc-9m weights in DDR3, UART receipt (Closes #10461)#10475gHashTag wants to merge 9 commits into
gHashTag wants to merge 9 commits into
Conversation
…ART receipt (Closes #10461) Cell 26 of specs/igla/own_model.t27 (epic #10024), the compute step on top of the DDR3 read path of #10248. - specs/fpga/ddr3_ternary_matvec.t27: the board spec. It receives the 20,480 bytes of blocks.0.attn.k.weight (tern-tc-9m, sha256 3102abdf...ce9c, offset 10,589,476) on UART RX P20, packs them into 640 beats of 256 bits, writes them to DDR3, reads them back one beat at a time and steps through their trits one per clock: y_r = sum_c w_rc * x_c, x_c = int8(37c + 11), wrapping 32 bits. Receipt on N15: T27 TERN N= S= C= Y= E= F= L= PASS|FAIL. - specs/fpga/tern9m_l0_k_weights.t27: the same bytes as 2,560 u64 words made with od, and the tests that compute S_EXPECT and Y_EXPECT from them with the board spec's own fold and trit_term; the FF-as-+1 mutant and a one-byte change both miss. - Tests on the Railway lab: 9/9 and 5/5, 0 vacuous. A copy of the board spec with the FF trit read as +1 fails its own test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 18, 2026
Merged
Contributor
…cs shared (Refs #10461) fold, hex_digit and the PASS/FAIL verdict characters were written three times, in rc_filter_ax7203, ddr3_head_bandwidth and ddr3_ternary_matvec; dupe-bodies named them. They now live in one pure module, specs/fpga/board_receipt.t27 (4 tests, 0 vacuous), and each board spec uses it. ddr3_head_bandwidth keeps its own four-verdict verdict_char for the SLOW and KILL lines. The head_bandwidth and rc_filter netlists emitted after the move equal the ones from before it, up to line order, comments and the function name. Seals written on the Railway lab with zig on PATH; three t27b ledger rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-10-18 14:06:04 UTC
Summary
Seal Status
|
Contributor
PR DashboardGenerated at: 2026-10-18 14:20:43 UTC
Summary
Seal Status
|
board_receipt.t27 now holds the one hex_digit the three AX7203 board specs had each written, so the group is gone and the gate asked for the ceiling to come down with it: 1 line removed by tools/dupe_scan.py --bless. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-10-18 14:36:58 UTC
Summary
Seal Status
|
This was referenced Oct 18, 2026
…#10461) Both specs arrive with cell 26 and gen-verilog emits a module for each, so the ratchet read them as NEW. board_receipt elaborates clean. The 8 in the weights spec are all names it takes by `use` from board_receipt and from ddr3_ternary_matvec (a t27b spec gen-verilog skips); the weights are test data the board receives over the UART, never synthesized. Measured on CI (iverilog 12.0) and on the Railway lab (11.0): 214 errors, baseline now 214. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-10-18 15:04:58 UTC
Summary
Seal Status
|
This was referenced Oct 18, 2026
…print (Refs #10461) The mutant test only said Y != Y_EXPECT and the byte-0 test only said S and Y differ. Both now also assert the exact values, read off the spec's own failing assert_eq with 0 in their place, not off the board: - Y_MUT_FF = 0x3E5E6C8ED51DF5C8, Y of the FF-as-+1 mutant on the real bytes - S_FLIP0 = 0x4B58160720ABB81C, Y_FLIP0 = 0x9A50D884522C2320, the real design on the bytes with byte 0 changed from FF to 01 On the AX7203 the mutant bitstream printed Y=3E5E6C8ED51DF5C8 FAIL and the design printed S=C=4B58160720ABB81C Y=9A50D884522C2320 FAIL, so each negative control fails for the predicted reason. 5/5 pass, 0 vacuous (asserts 4, 3, 1, 2, 6); resealed on the Railway lab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-10-18 16:43:06 UTC
Summary
Seal Status
|
This was referenced Oct 18, 2026
Contributor
PR DashboardGenerated at: 2026-10-18 17:01:15 UTC
Summary
Seal Status
|
This was referenced Oct 18, 2026
Merged
Merged
This branch has not been deployed
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.
Closes #10461
Cell 26 of
specs/igla/own_model.t27("Full model on FPGA, DDR3"), epic #10024. #10248 measured the DDR3 read path on the AX7203. This PR adds the compute step on top of it: real ternary weights in DDR3, a mat-vec computed from them on the board, and a UART receipt that is checked against the spec's own test.Board receipts (AX7203,
xc7a200tfbg484-2, 2026-10-18)T27 TERN N=0000000000000280 S=4B58160720ABB863 C=4B58160720ABB863 Y=9A50D884522C233D E=0000000000000000 F=0000000000000000 L=0000000000000001 PASST27 TERN N=0000000000000280 S=4B58160720ABB81C C=4B58160720ABB81C Y=9A50D884522C2320 E=0000000000000000 F=0000000000000000 L=0000000000000001 FAILT27 TERN N=0000000000000280 S=4B58160720ABB863 C=4B58160720ABB863 Y=3E5E6C8ED51DF5C8 E=0000000000000000 F=0000000000000000 L=0000000000000001 FAILassert_eqwith 0 in their place, not typed in from the board (FR-002).S_FLIP0/Y_FLIP0, which the spec computed before the board run.Y_MUT_FF. That value was read off the spec after the board printed it, and the spec comment says so.How each run was done:
openFPGALoader -c digilent_hs2 --ftdi-serial 210512180081 <bit>.litex>prompt, upload withdd ... bs=512to/dev/cu.usbserial-130at 115200 8N1.cat.Bitstreams flashed:
e1afe42f028ca7bd29ae6a5eb17fd464b5436bded637e065269259ec3ef4f58347c0f05d147182ddffd64226f625f9f929d27d80c47e690203b673ae23d018b7Bytes uploaded:
970a7f55e7da107a657d6c6b61e46167d919e070fd906a1265294e688c216fd03535984d233655a38e0c963af0dc2520c09385c56e936a12fea5bd1864a19dc8The first board run found a spec bug (fixed in b0d3fc8)
The first route that calibrated printed the right N, S, C and Y with E=F=0, and still said FAIL.
s_wantandy_wantreset to 0. The tests assigned them before each run, so the spec passed while the hardware compared a correct receipt against 0.Both registers now reset to the pinned constants. A new first test asserts the values out of reset, before any test assigns them, and that test fails with the old
= 0initializers. The fix is in the spec, not in the hardware: the board found the gap, and the spec now has the test that catches it.DDR3 calibration is route luck
An all-zero FAIL receipt is not a data verdict. In those runs
core_init_erroris set: the LiteDRAM BIOS read leveling finished but the memtest failed, and the state machine reports V_FAIL with nothing computed.Whether a route passes the memtest depends on the route:
The
clkFmax per seed, from nextpnr-xilinx on the Railway lab:No route meets 100 MHz. The critical path is in the LiteDRAM core's VexRiscv BIOS CPU (
core.VexRiscv.lastStageIsValid), not in the mat-vec. Fmax does not predict calibration: seed 5 is the fastest design route and it fails the memtest. Design seeds 10, 11 and 14 and mutant seeds 4, 6 and 8 were built but not flashed. Two working routes were enough.What is in it
specs/fpga/ddr3_ternary_matvec.t27is the board spec. It uses the same LiteDRAM core, clock and pins asddr3_head_bandwidth.t27.T27 TERN N=<beats> S=<write sum> C=<read sum> Y=<output sum> E=<bad trits> F=<bad frames> L=<line> PASS|FAILspecs/fpga/tern9m_l0_k_weights.t27is the data spec.blocks.0.attn.k.weightofplayra/tern-tc-9m, fromc_infer/model.bin(16,953,800 bytes, sha2563102abdf35057924e077a86db4fdac726e4fe1f6574df47f39a638ba99a3ce9c): offset 10,589,476, 20,480 bytes, held as 2,560 u64 words.trit_termand the sharedfold, and assert the board spec's constants. They also pin the two FAIL receipts the negative controls print.wte) is tied and f32, so the PR uses the first ternary projection of the same checkpoint.specs/fpga/board_receipt.t27is a pure module (no pins, no state) holdingfold,hex_digitandpass_fail_char.rc_filter_ax7203,ddr3_head_bandwidthand the new board spec each had their own copy of these, and dupe-bodies flagged them. Now each oneuses this module.ddr3_head_bandwidthkeeps its own four-verdictverdict_charfor the SLOW and KILL lines.ddr3_head_bandwidthandrc_filter_ax7203netlists emitted after the move equal the ones from before it, up to line order, comments and the moved function's name.Spec results (Railway lab)
ddr3_ternary_matvec.t27: 10/10 pass, 0 vacuous. Asserts per test: 5, 3, 14, 321, 5, 50, 12, 2, 640, 8.tern9m_l0_k_weights.t27: 5/5 pass, 0 vacuous. Asserts per test: 4, 3, 1, 2, 6. The tests check:Y_MUT_FF;S_FLIP0/Y_FLIP0, and restoring FF gives the expected values back.board_receipt.t27: 4/4 pass, 0 vacuous.xc7a200tfbg484-2), fasm2frames and xc7frames2bit. Every stage returned rc 0 except the PnR failures listed above.Review
Cell 26 is named in
own_model.t27only after the reviewer bee approves this head (FR-006). That is why this PR carriesno-auto-merge.CI notes
cli-triwas red on master after claw: the merger merges as TRI CLAW and on workflow_run of the required checks #10474 (tri census pin --gate). claw: refresh -- update-branch every behind, conflict-free PR after a merge (Closes #10397) #10482 fixed it, and that is merged into this branch.fpga-conformance: the elaboration ratchet had no rows for the two new gen-verilog modules. bda018e addsboard_receipt 0andtern9m_l0_k_weights 8, with a note intools/elab_baseline.txt. All 8 are names the weights spec takes byuse(gen-verilog binds no imports). The weights are test data the board receives over the UART and are never synthesized.Documented t27c subcommands existwas red because master's gate file differed. gate: lower MAX_DEAD_TRI 140 -> 138 after #10500 removed two dead tri mentions (Closes #10513) #10514 changed it on master, and master is merged into this branch at 9e8ff7a.t27b-native-ratchetis red from master. On 9e8ff7a the four UNLISTED specs areanalog/bench,analog/linear,analog/linear_zohandanalog/mos_table, which master added in analog M1c: exact zero-order-hold discretization for the linear cell, and the h / h/2 convergence check #10503 and fix: re-seal mos_table.t27 with the zig cache set, and derive the openXC7 path in the analog skill (Closes #10521) #10523. This PR touches none of them; UNEXPECTED FAILURE, UNEXPECTED PASS and STALE are all 0. The ledger steward's re-derive (ledger: re-derive from master 380a81f24923, as its lab verdict APPLY says (Closes #10447) #10448) is the place to fix it.Corpus ratchet (expected-failure ledger)fails in itstri types ratchetstep: ledger 107, observed 108,+ Ring NEW conflict.Ringis the struct master'sanalog/linear_zoh.t27added in analog: linear_zoh.t27 -- exact zero-order-hold constants for the linear cell, and the h/2 convergence check (Closes #10503) #10528. analog: linear_zoh.t27 -- rename struct Ring to RingPeak, it collided with another type named Ring and moved the types ratchet 107 -> 108 (Closes #10503) #10539 renames it toRingPeak. This PR declares no type namedRing.claw-sarifneedssecurity-events: writeon the TRI CLAW App, so it is not this PR's to fix.This PR adds no code in any language other than t27.
🤖 Generated with Claude Code