Deep-space links get one chance at a frame. There is no retransmission across an interplanetary distance, so the error-correcting code carries the whole burden, and CCSDS 131.0-B-3 defines nine AR4JA code points for it: information blocks of 1024, 4096 and 16384 bits, each at rate 1/2, 2/3 and 4/5. The decoder in this story is our evaluation twin of the MathWorks CCSDS LDPC Decoder block, mirrored module by module in scalar mode so its behaviour can be audited against a known reference. It is deliberately not the folded, higher-throughput configuration we ship for rate-critical links. We verified it bit-exact against a golden model across all nine code points, then put it on a board. That is where it got interesting.
Bit-exact in simulation, deterministically wrong on hardware
In simulation the decoder was clean: 775 frames across all nine configurations, every bit matching the golden model. On the board, streaming frames back to back, the first frame came out perfect and every frame after it was wrong in the same way, missing a chunk at the start, roughly half the frame corrupted.
A failure that repeats identically is a gift. Random corruption points at signal integrity or marginal timing, which are slow to chase. A deterministic offset that starts exactly at the second frame points at a state machine that is re-arming, and it says the decoder itself is probably fine, because the decoder does not know what frame number it is on.
Read the manual before the waveform
The tempting move here is to open a waveform viewer and start hunting. We did not. Moving data between the fabric and the host is not a bespoke problem, it is a vendor-standard one with a documented set of modes, and the manual states the constraints plainly.
The capture path was running the data mover in its simple mode, which the manual describes as intended for one packet at a time: after a frame completes, software re-arms the engine for the next one. Meanwhile the decoder does not pause. It emits frame after frame with no gap. During the re-arm window the opening beats of the next frame have nowhere to go, and they are dropped. The first frame survives because it was armed in advance. Every frame after it loses its head.
The vendor's own answer is in the same manual: scatter-gather mode, where a ring of descriptors is armed ahead of time and stays armed. The next descriptor is ready before the current frame has finished, so there is no window in which the engine is deaf. After the switch, all nine configurations streamed continuously and matched bit for bit.
Passing once is not passing
Hardware gets lucky. A single clean run proves very little, so the bar we hold to is that the same continuous stream has to pass across multiple fresh boots with zero failures. The final tally was three fresh boots, nine configurations, three trials each: 81 runs, all clean.
Getting three fresh boots was its own detour. Software reboot on this board did nothing: the reset-reason register kept reporting a power-on reset no matter what was sent to it. The initial diagnosis was a missing firmware image, which turned out to be wrong on inspection, and was corrected rather than left standing. The reboot that worked came through the debug port, which also meant the multi-boot gate could run unattended.
The mode that did not work, recorded as such
We also evaluated the data mover's cyclic mode, which in principle never stops and would have been cheaper still. On this engine it does not work: the driver closes the descriptor ring for the transmit direction only, so the receive side halts after one pass. Tried, did not work, written down. A results table with no negative entries is a table that has not been read carefully, and the failures are what make the passes worth believing.
Watch it yourself
The console that ran alongside the board is published as a replay: real recorded data from the capture, every frame and every configuration, the per-frame bit comparison, and the BER waterfall of the fixed-point golden model against a MATLAB double-precision reference. You can pause it and scrub to any frame. No hardware is attached and nothing is simulated in the browser.
What this is worth to a customer
None of this is about decoder throughput: the twin is the slower, comparability-first build, and the folded configuration is the one to ask about for a rate-critical link. What it is about is everything between a design that decodes correctly and a system that keeps decoding correctly.
The decoder is the part everyone asks about, and it was not the part that was broken. What separated a design that works in simulation from one that works on a board was the plumbing around it: how frames are moved, how the receiver re-arms between them, and whether that holds when the frames never stop coming. We publish the numbers we measured, on the part we measured them on, including the mode that failed. If you are putting a deep-space FEC core on real hardware, that is the part worth asking about.