Convolutional Codes & Viterbi Decoding
Convolutional encoders turn a bit stream into a finite-state trellis; Viterbi decoding finds the maximum-likelihood sequence by retaining one survivor per state. This entry fixes generator conventions, works a complete noisy trellis, derives hard and soft metrics, and covers termination, puncturing, distance, complexity, and interoperability.
A convolutional encoder has memory: each input bit affects several successive output symbols. That memory turns isolated symbol decisions into a sequence problem. The Viterbi algorithm solves the maximum-likelihood (ML) sequence problem on the encoder's trellis without enumerating every possible input sequence; at each time and state it discards any path that can never beat the best path reaching the same state.
This elegant rule does not make implementations interchangeable. Generator orientation, bit order, output order, symbol inversion, puncturing phase, starting state, termination, soft-metric polarity, and traceback policy are all on-wire protocol. Two encoders described as “rate 1/2, , generators 171/133 octal” can still disagree on every transmitted bit if those conventions differ.
Encoder as a finite-state convolution #
For one input bit per step and output bits, a binary rate- feed-forward encoder computes
where is modulo-2 addition, memory bits are stored, and constraint length is . The state is the previous inputs, so the trellis has states. Complexity grows exponentially in memory, not in frame length.
For the worked code, use rate , , generators
With state , input emits
and the next state is .
| Current state | input 0 → output, next | input 1 → output, next |
|---|---|---|
| 00 | 00, 00 | 11, 10 |
| 01 | 11, 00 | 00, 10 |
| 10 | 10, 01 | 01, 11 |
| 11 | 01, 01 | 10, 11 |
This transition table is a better interoperability fixture than a polynomial label. Generate it from the actual implementation and compare all states before testing long random frames.
The trellis unfolds time #
At time , each state has two outgoing branches for binary input. A path through the trellis uniquely determines the input sequence, encoder state sequence, and output sequence. Without termination, input bits create paths; with states, only best partial paths need survive at each step.
For a memoryless channel, the likelihood of a complete path factors by branches. Taking negative logarithms turns the product into an additive path metric:
where is a legal transition and is its branch metric. The decoder stores the winning predecessor and input for each destination state.
Why may the loser be discarded permanently? Two paths merging into the same state have identical possible futures because the encoder state contains all relevant memory. Every future suffix adds the same candidate suffix metrics to both histories. The path already worse at the merge can never become better later. This is Bellman's principle of optimality in a finite-state channel.
Worked Viterbi decode with one channel error #
Start the encoder in state 00 and send information bits 1011, then append two zero tail bits to return to state 00:
input: 1 0 1 1 0 0
output: 11 10 00 01 01 11
receive:11 11 00 01 01 11
The second received pair differs from the transmitted pair in one bit. With hard decisions, branch metric is Hamming distance. Initial metrics are and infinity for the other states. After each received pair, the survivor metrics are:
| step / received | state 00 | state 01 | state 10 | state 11 |
|---|---|---|---|---|
| 0 / — | 0 | ∞ | ∞ | ∞ |
| 1 / 11 | 2 | ∞ | 0 | ∞ |
| 2 / 11 | 4 | 1 | 2 | 1 |
| 3 / 00 | 3 | 2 | 1 | 2 |
| 4 / 01 | 3 | 2 | 3 | 1 |
| 5 / 01 | 3 | 1 | 3 | 3 |
| 6 / 11 | 1 | 4 | 3 | 4 |
Because termination declares final state 00, traceback begins there and recovers 101100; removing the two tail bits yields payload 1011. The final metric 1 equals the single flipped coded bit.
Hard and soft branch metrics #
For hard received bits and expected coded bits , use Hamming distance
Hard slicing throws away reliability. For BPSK mapping , with real observation and known variance , the AWGN negative log-likelihood is, up to a common positive scale and constant,
If the detector supplies bit LLRs , a convenient max-log branch cost is
The exact scale can be common to every branch, but sign, saturation, quantization, and relative reliability cannot. Before blaming the code, verify that positive LLR really means the decoder's expected bit value and that punctured positions contribute zero information, not a confident zero bit.
Soft decisions usually provide a substantial coding advantage over hard decisions because a barely wrong sample and a deeply wrong sample no longer receive the same unit penalty. The gain is not magic attached to “8-bit soft input”; it depends on calibrated metrics and sufficient quantization around the decision boundary. Excess range spent on rare large magnitudes can leave too few useful levels near zero.
Free distance controls error events #
For a linear convolutional code, the all-zero path may represent the transmitted codeword without loss of generality. The free distance is the minimum Hamming weight of any nonzero trellis path that diverges from and later remerges with the zero path. It plays the role that minimum distance plays for block codes.
At high SNR, errors are dominated by low-weight divergence–remergence events, not independent coded-bit flips. A union bound uses the distance spectrum: both the number of events at each distance and the number of information-bit errors they cause matter. This is why two codes with the same rate and constraint length can have different performance.
A transfer-function or exhaustive trellis search can compute the spectrum for a small code. A practical verification should also inject each short low-weight event and confirm the decoder's metric and traceback, because those are the cases that dominate the error floor and expose convention mistakes.
Termination defines the path set #
Three common frame contracts are distinct:
| Mode | Encoder action | Decoder boundary knowledge | Cost/risk |
|---|---|---|---|
| zero-tail | append bits that force a known state, often zero | known start and end state | rate loss for payload bits |
| tail-biting | choose start state equal to final state | equality known, state unknown | no tail overhead; decoder must resolve circular state |
| continuous | retain state across frames/stream | state must be preserved or reacquired | best asymptotic rate; reset/loss boundaries are protocol-critical |
For the six-step worked example, forcing the end to 00 turns a metric-1 path into the answer even if another state had happened to have a smaller metric. Without a declared final state, the decoder chooses the minimum-metric state after adequate delay. These are different ML problems.
Streaming decoders usually trace back after several constraint lengths because survivor paths tend to merge. A rule such as is only a starting convention; puncturing, code spectrum, SNR, and required residual error rate change the needed depth. Verify traceback depth against long error events rather than copying a constant blindly.
Puncturing preserves the mother trellis #
Puncturing deletes selected mother-code symbols according to a periodic mask. A rate- encoder can therefore create higher effective rates while using the same state transitions. If input bits generate mother symbols and the mask transmits of them, the effective rate is
Example: across two input bits, a mask
transmits three of four mother symbols, producing rate . At the decoder, the missing symbol is an erasure: insert a neutral branch contribution at exactly the right mother-code position.
Puncturing phase is part of framing. A one-symbol slip can leave the Viterbi decoder producing plausible but systematically wrong data because every later soft value is assigned to the wrong generator output. A known short frame should test each allowed puncturing phase and reset boundary.
The archived CCSDS 131.0-B-5 profile provides a concrete rate- encoder with connection vectors 171 and 133 octal and specified punctured rates , , , and . It also specifies output ordering and historical symbol-inversion details; those details must be copied from the chosen issue, not reconstructed from polynomial names. CCSDS now lists 131.0-B-6 (April 2026) as the current issue, superseding B-5, so a new implementation must verify its mission profile against Issue 6 rather than treating the archived 2023 issue as current.
Catastrophic and recursive encoders #
A feed-forward encoder is catastrophic if some infinite-weight input sequence produces a finite-weight output sequence: many information errors can become almost invisible on the channel. For a binary rate- feed-forward encoder, a common algebraic test is that the generator polynomials must not share a nontrivial common factor.
Recursive systematic convolutional (RSC) encoders deliberately feed a polynomial back into the state update and transmit the input systematically. Recursion is essential to turbo-code behavior because a finite-weight input can produce a long parity response. It is not the same as a catastrophic feed-forward realization; rational generator notation, feedback convention, and termination all need an explicit state-space definition.
Viterbi, BCJR, and sequence estimation #
Viterbi returns the most likely sequence under the trellis/channel model. It does not in general return the individually most likely value of every bit. BCJR computes posterior probabilities or bit LLRs by forward and backward recursions and is the natural constituent algorithm for iterative decoding. Sequential decoders explore promising paths with variable effort and can be attractive for long-constraint-length codes, but their worst-case work is less predictable.
The same Viterbi dynamic program also handles finite-state channels for maximum-likelihood sequence estimation (MLSE). There the state represents channel memory rather than encoder memory—or a joint super-trellis represents both. The survivor argument remains valid only if the state contains all memory needed to make future observations independent of the discarded history.
Implementation contract and tests #
Write the contract before optimizing:
- generator polynomials and whether the current input is the MSB or LSB coefficient;
- shift-register direction, state-bit order, and next-state equation;
- encoder output order, serialization order, and any symbol inversion;
- initial/final state and zero-tail, tail-biting, or continuous semantics;
- puncturing matrix, reading order, phase, and reset boundary;
- modulation bit mapping and LLR sign/scale/saturation;
- branch-metric normalization, renormalization, tie-breaking, traceback depth, and output latency.
Then test in increasing scope:
- exhaust all state/input transitions against a hand-reviewed table;
- encode short known vectors, including reset and termination boundaries;
- verify the worked one-error trellis above step by step;
- compare soft branch metrics with direct channel log-likelihoods;
- inject punctures as erasures at every phase;
- compare a long optimized decoder against a simple reference decoder on identical received metrics;
- sweep , record actual error counts and confidence, and inspect low-weight error events.
| Failure signature | First place to look |
|---|---|
| noiseless decode fails immediately | generator/state/output-bit convention |
| only first or last bits fail | initial state, tail bits, traceback flush, or latency alignment |
| unpunctured works, punctured fails | puncture matrix orientation or phase; erasures inserted as hard bits |
| hard decoding works, soft is worse | LLR polarity, normalization, clipping, or symbol-to-bit mapping |
| periodic error bursts | puncture period, frame slip, metric renormalization, or state reset cadence |
| two decoders differ only on rare frames | tie-breaking, traceback depth, tail-biting initialization, or overflow |
Convolutional codes are no longer the universal default for new high-throughput links; LDPC, turbo, and polar families often win at large block lengths or modern parallel hardware. They remain operationally important in space and legacy links, short control channels, and as constituent or conceptual codes. More importantly, the trellis discipline—explicit state, additive likelihood metrics, survivor evidence, and bit-exact boundary contracts—generalizes far beyond one coding family.