Repository navigation
E2c: eth_reply.t27 as merged in #8490 sends frames without a receipt, with checksum 0 and the wrong MAC and port #8530
Description
Follow-up to #8388 (closed by #8490). Part of #8327. Refs #6655.
Goal
Make specs/fpga/eth_reply.t27 do what #8388 asks: send one unicast UDP frame per receipt to the host whose request started the job, with a correct IPv4 checksum, source MAC, destination port and FCS, and nothing when there is no receipt.
Where we are
#8490 (written by a bee on queen-8388) merged eth_reply.t27 and a j_go output in trinet_node.t27. The generated RTL of master's eth_reply.t27 (gen-verilog, t27c 0.5.2 at f06ea76) was simulated in Icarus Verilog:
- 100 clocks after reset, with no
j_goand no receipt, it sends a full 73-byte frame: source MAC00:00:12:34:56:79(SRC_MAC = 305419897, not 02:27:00:00:00:01), IPv4 checksum00 00(ip_checksumis never computed;ip_checksum_step_fnis never called), UDP destination port69 94(bytes 44..45 sendSRC_PORT, not the latched port). - After
j_goand a receipt it sends nothing for the next 200 clocks: the frame loop runs onGAP_CYCLES = 2^24like EthBeacon, with no "receipt ready" input. - The receipt is latched whenever any
r_*input is non-zero; TrinetNode holdsr_*between receipts, so it is latched on every clock. - The header's reference values (checksum 0x8A4C, FCS 2C 7B 8E 91) disagree with an independent computation (Python
struct, RFC 791,zlib.crc32): for the V1 receipt to 192.168.1.101:50000, checksum 0xB625 and FCS 05 C5 5F 98. trinet_node.t27: the new testj_go_rises_exactly_when_a_job_startsfails (t27c test-report: 7 pass, 1 FAIL): it countsj_goonly on the clocks after the one that set it.seal --verifyoffpga_TrinetNode.jsonreports that the hashes differ.eth_reply.t27has no seal, no t27b row and no elaboration row;fpga-conformanceis red on the merge commit e84dad7.
Boundary
specs/fpga/eth_reply.t27replaced,.trinity/seals/fpga_EthReply.jsonnew.specs/fpga/trinet_node.t27: only the failing test is corrected;j_gostays as merged. Its seal is re-saved.- Ledgers as the gates need them (duplicate baseline for the CRC functions, elaboration row, t27b row).
User Scenarios & Testing
As in #8388: a receipt goes to the sender taken at job start, even if another host's frame arrived meanwhile; a receipt while a frame is on the line is counted and dropped; at least 12 idle clocks between frames; no frame without a receipt.
Success Criteria
-
t27c test-reportpasses for both specs, 0 vacuous; the reference checksum and FCS are asserted. - The generated RTL matches the independent frames byte for byte in simulation, and sends nothing without a receipt.
- OOC 125 MHz closes on three seeds.
- Seals verify with the PR tree's compiler; CI green on the final SHA.
Dmitrii Fedorov (@dmitrii-f-t27)
Requirements
FR-001: eth_reply.t27 MUST send exactly one unicast UDP frame per receipt to the host whose request started the job.
FR-002: eth_reply.t27 MUST compute and include a correct IPv4 header checksum (0xB625 for the V1 receipt to 192.168.1.101:50000).
FR-003: eth_reply.t27 MUST use source MAC 02:27:00:00:00:01 (not 00:00:12:34:56:79).
FR-004: eth_reply.t27 MUST use the latched destination UDP port from the originating request (not SRC_PORT).
FR-005: eth_reply.t27 MUST compute and append a correct FCS (05 C5 5F 98 for the V1 receipt).
FR-006: eth_reply.t27 MUST send no frame when there is no receipt pending.
FR-007: eth_reply.t27 MUST latch a receipt only when a new receipt arrives, not on every clock where r_* inputs are held non-zero.
FR-008: eth_reply.t27 MUST provide a "receipt ready" input to gate the frame loop instead of running on GAP_CYCLES = 2^24 unconditionally.
FR-009: eth_reply.t27 MUST enforce at least 12 idle clocks between transmitted frames.
FR-010: eth_reply.t27 MUST count and drop a receipt that arrives while a frame is on the line.
FR-011: trinet_node.t27 test j_go_rises_exactly_when_a_job_starts MUST count j_go on the clock that sets it, not only on subsequent clocks.
FR-012: eth_reply.t27 MUST have a seal (.trinity/seals/fpga_EthReply.json), a t27b row, and an elaboration row.
FR-013: fpga-conformance MUST pass (green) on the final commit.
FR-014: The generated RTL MUST match the independently computed frame bytes exactly in simulation.
FR-015: OOC timing closure at 125 MHz MUST succeed on three seeds.
FR-016: Seals MUST verify with the PR tree's compiler; CI MUST be green on the final SHA.
Activity
dmitrii-f-t27 commentedon Oct 10, 2026
In progress: the fix (a replacement eth_reply.t27 that passes these criteria in spec tests, generated-RTL simulation against independent frames, and OOC timing on three seeds: 142.27 / 153.87 / 160.51 MHz) is being opened as a pull request now. The label was added by mistake and this account cannot remove it.
Dmitrii Fedorov (@dmitrii-f-t27)
ci(t27b): eth_reply.t27 gets a pass row
perf(fpga): the job link closes timing when its three modules share a…
dmitrii-f-t27 commentedon Oct 10, 2026
Scope note: #8532 also carries two timing changes found when the three modules (EthRx, TrinetNode, EthReply) were placed together on the AX7203 — EthReply shifts its 61 data bytes out of eight registers instead of a 73-way byte table, and TrinetNode reads the next step code straight from (md, blk, sub) and registers the request flag. Behaviour is unchanged (same tests plus an equivalence test over all 59 engine states; the generated RTL still matches protocol.zig and the independent reply frames). With them the bench build closes timing in every domain at 100 Mb/s, and the board returned 10000 of 10000 keyed receipts verified on the host, none lost.
Dmitrii Fedorov (@dmitrii-f-t27)
Merge master (gHashTag#8535) into spec/eth-reply; Refs gHashTag#8530
Merge master (gHashTag#8564) into spec/eth-reply; Refs gHashTag#8530
ci(t27b): trinet_node.t27 gets its pass row back
Merge master into spec/eth-reply; Refs gHashTag#8530