Repository navigation
feat(fpga): trinet_node.t27 -- TRI-NET MAC32 job core with SipHash-2-4 receipts (E2b) - #8373
Merged
Merged
Conversation
…4 receipts (E2b) Closes #8356 TrinetNode takes the UDP payload EthRx hands out one byte per clock, runs one MAC32 job or key request per datagram and produces the 19-byte v2 receipt (Y, STATUS, NONCE, NODE_ID, SipHash-2-4 TAG) bit for bit as protocol.zig defines it. - The dot product is five clocks of field folds over agree/oppose bit masks, not one chain of 32 adders. - A SipHash half round takes two clocks: the two 64-bit sums go to registers, then rotate/XOR/write the other bank. The step code is decoded one clock early (tq). 59 clocks per receipt. - test-report 6/6, 0 vacuous: the SipHash paper vector, the dot product, seven receipts from protocol.zig (unkeyed, setkey, keyed, locked, +32, -32, reserved codes), busy drop, not-a-request, a frame EthRx rejected. - Seal from this tree's t27c 0.5.2, verify MATCH.
Contributor
This was referenced Oct 9, 2026
… close 125 MHz Refs #8356 Seed 3 of 4e36b2b reached 118.61 MHz: four LUT levels sat in front of the sum adder, the v/q bank select and an 8-bit compare of the step code. With the sums in registers the second bank is not needed any more: every step changes a word from its own old value and sum0/sum1 only. The bank (256 FF), ph and the bank helpers go; fa (half A or B) and fs (a sum step) are decoded a clock early, so the adder's operand is one LUT, v0 ^ (fa ? v1 : v3). OOC xc7a200tfbg484-2, 125 MHz, seeds 1/2/3: 127.24 / 134.26 / 131.08 MHz, 3592 cells (was 4753). test-report 6/6, 0 vacuous; seal MATCH; trinet_node elaborates clean in iverilog, so tools/elab_baseline.txt gets a 0 row.
Contributor
PR DashboardGenerated at: 2026-10-09 21:58:27 UTC
Summary
Seal Status
|
Contributor
PR DashboardGenerated at: 2026-10-09 22:02:04 UTC
Summary
Seal Status
|
Contributor
Author
|
compile-proofs (Coq) is red here for a cause outside this PR:
|
Contributor
PR DashboardGenerated at: 2026-10-09 22:14:12 UTC
Summary
Seal Status
|
Contributor
PR DashboardGenerated at: 2026-10-09 22:19:30 UTC
Summary
Seal Status
|
This was referenced Oct 9, 2026
5 tasks
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 #8356
Part of #8327 (E2: TRI-NET node over UDP on the AX7203). Refs #6655. Consumes the payload of
EthRx(#8370).Pull Request Checklist
Closes #8356t27c test-report specs/fpga/trinet_node.t27passes 6/6, 0 vacuoust27c 0.5.2,--verifyall MATCHDescription
specs/fpga/trinet_node.t27(moduleTrinetNode) is the job core of the TRI-NET node. The wire format is the onegHashTag/trinity-fpgasrc/trinet/protocol.zigdefines andfpga/portable/trinet_node_core.vimplements over UART; only the transport moves to UDP:AA 55 OP NONCE[4] W[8] X[8] TRIG(24 bytes); receiptA5 Y STATUS NONCE[4] NODE_ID[4] TAG[8];OP NONCE W X Y NODE_ID(26 bytes), keyed with the node key, the zero key while none is set, or the new key in the request that sets it.Hardware structure (so that 125 MHz closes):
tq), the A/B choice (fa) and the sum-step flag (fs) are decoded one clock early, so the adder's operand is one LUT,v0 ^ (fa ? v1 : v3).One receipt takes 59 clocks after the frame ends (about 2.1 million receipts per second at 125 MHz).
Testing
t27c test-report(Zig 0.16): paper vector a129ca6149be45e5, dot product, seven receipts from protocol.zig, busy drop, not-a-request, frame rejected by EthRxgen-verilogoutput (sha256ead9d72e..., the sealed one) in Icarus Verilog 13.0, driven like EthRx; receipts from protocol.zig itself (zig run gen.zig), not from the specsynth_xilinx -flatten -abc9 -nowidelut -nosrl, nextpnr-xilinx 0.9.7,xc7a200tfbg484-2, 125 MHzHow the timing got there (seed 1): one chain of 32 adders in the dot product 12.75 MHz; two-half add64 91.84; one 64-bit chain 112.66; carry-select forms 112.68 and 91.10 (synthesis merged them back into a chained pair); two-clock half round 115.19; step code registered 130.29 (but seed 3 118.61); one bank and a one-bit A/B select 127.24 / 134.26 / 131.08 on seeds 1/2/3.
The testbench and vector generator are outside the repo (hand-written .v/.py need an owner-approved entry in
tools/policy/foreign-exceptions.txt); sha256: testbench2fb108fe...,gen.zig8c33ae5a...,protocol.zigcopy52afc0d5....Review Notes
tools/elab_baseline.txtgetstrinet_node 0: the module elaborates clean in iverilog (fpga-conformance reads a module without a row as NEW).has_atduplicate, a home path in the t27b-loop skill, unlisted t27b specs) are fixed in gates: record has_at as a deliberate copy; no home path in the t27b-loop skill (#8361) #8362; this PR does not merge while they are red.