Main Content

Viterbi Decoder

Decode convolutionally encoded data using Viterbi algorithm

  • Library:
  • Wireless HDL Toolbox / Error Detection and Correction

  • Viterbi Decoder block

Description

The Viterbi Decoder block decodes convolutionally encoded data using a RAM-based traceback implementation. Viterbi decoding is widely used in LTE standard TS 36.212 [1] and other forward-error-correction (FEC) applications such as wireless networks (802.11a/b/g/n/ac), digital satellite communications, digital video broadcast (DVB), IEEE 802.16, and HiperLAN. To support any of these standards, the block accepts convolution codes with constraint lengths of 3 to 9, code rates 1/2 to 1/7, and provides continuous, terminated, and truncated modes. The block provides an architecture and interface suitable for HDL code generation.

The block supports decoding of punctured codes by providing an optional erasure input port. You can use the Depuncturer block to insert neutral values in a punctured sample stream, and generate the erasure signal.

The Viterbi Decoder block accepts input samples as hard-decision binary values or soft-decision log-likelihood-ratios (LLR). Each sample is a column vector, whose length depends on the encoding scheme. The first waveform shows continuous operation mode with input samples of signed 4-bit data, using the default block parameters. The Traceback depth is 32. The block returns the first decoded output data sample after 148 clock cycles. The decoding latency is 4×Traceback depth + Constraint length + 13 valid input cycles.

The second waveform shows three frames in terminated operation mode. The input is unsigned 4-bit samples, and the block is using the trellis (7,[171 133 112]). The Traceback depth is 32. The input and output ctrl buses are expanded to show their three control signals. The latency from each input ctrl.start to output ctrl.start is also 148 clock cycles.

The control signals in the bus indicate the validity of each sample and the boundaries of the frame. To convert a matrix into a sample stream and corresponding control signals, use the Frame To Samples block or the whdlFramesToSamples function. For a full description of the streaming sample interface, see Streaming Sample Interface.

Ports

Input

expand all

Input sample, specified as an n-by-1 column vector, where n is the length of the generator polynomial. The block performs soft-decision decoding when the input data type is fixed point or integer and hard-decision decoding when the input data type is Boolean or fixdt(0,1,0). The block performs unquantized soft-decision decoding for single and double data types, but these data types are not supported for HDL code generation.

For soft-decision input samples, the block supports word lengths up to 16 bits. For HDL code generation, a word length more than 8 bits is not recommended due to hardware resource usage. The input data must have a fraction length of 0.

Data Types: int8 | int16 | uint8 | uint16 | Boolean | fixdt(0,1,0) | fixdt(S,WL,0) | single | double

Control signal that indicates when the sample from the data input port is valid. When the valid input port is 1 (true), the block captures the values of the data input port. When the valid input port is 0 (false), the block ignores the input samples.

Dependencies

To enable this port, set Operation mode to Continuous.

Data Types: Boolean

Neutral symbol locations, specified as a column vector of binary values the same size as the input data vector. When an erasure element is 1 (true), the corresponding input data element is a depunctured neutral value, and the decoder does not update the branch metric. When an erasure element is 0 (false), the block uses the corresponding input data element to update the branch metric. You can use the Depuncturer block to drive this port.

Dependencies

To enable this port, select Enable erasure input port.

Data Types: Boolean

Clear internal state, specified as a Boolean scalar. When reset is 1 (true), after one cycle, the block stops the current calculation and clears internal branch and state metrics.

Dependencies

To enable this port, set Operation mode to Continuous and select Enable reset input port.

Data Types: Boolean

Control signals accompanying the sample stream, specified as a samplecontrol bus. The bus includes the start, end, and valid control signals, which indicate the boundaries of the frame and the validity of the input samples.

Dependencies

To enable this port, set Operation mode to Terminated or Truncated.

Data Types: bus

Output

expand all

Output sample, returned as a scalar with the same data type as the input samples.

Data Types: int8 | int16 | uint8 | uint16 | Boolean | fixdt(0,1,0) | fixdt(S,WL,0) | single | double

Control signal that indicates when the sample from the data output port is valid. The block sets the valid port to 1 (true) when there is a valid sample on the output data port.

Dependencies

Tho enable this port, set Operation mode to Continuous.

Data Types: Boolean

Control signals accompanying the sample stream, returned as a samplecontrol bus. The bus includes the start, end, and valid control signals, which indicate the boundaries of the frame and the validity of the samples.

Dependencies

To enable this port, set Operation mode to Terminated or Truncated.

Data Types: bus

Parameters

expand all

Trellis constraint length, specified as an integer in the range [3, 9].

Code generation polynomial, specified as a 1-by-n vector of octal values, where n is the length of the polynomial. The block accepts polynomials from 2 to 7 elements long.

Select this parameter to enable the erasure port.

Number of trellis branches used to construct each traceback path, specified as an integer. The block supports traceback depth in the range [3, 128]. For nonpunctured samples, the recommended depth is 5×constraintLength. For punctured samples, the recommended depth is 10×constraintLength. These values balance decoding accuracy with the amount of memory used.

End of frame behavior, specified as one of these modes:

  • Continuous – The block does not clear the internal state metric. The input valid signal qualifies the input samples.

  • Truncated – The block resets the state metrics after each frame, and the traceback path starts at the state with the best metric and ends in the all-zeros state. The input ctrl bus qualifies the input samples and marks the frame boundaries.

    Note

    This mode requires a minimum space of Constraint length–1 cycles between frames .

  • Terminated – The block resets the state metrics after each frame, and the traceback path always starts and ends in the all-zeros state. The input ctrl bus qualifies the input samples and marks the frame boundaries.

Select this parameter to enable the reset port. When reset is 1 (true), after one cycle, the block stops the current calculation and clears internal branch and state metrics.

Dependencies

To enable this parameter, set Operation mode to Continuous.

Algorithms

expand all

The Viterbi Decoder block implements a RAM-based traceback using K-pointer odd algorithm [2]. The parameter K is the number of read pointers required in the algorithm. This implementation has a K value of two, and accesses three memories using two read and one write pointers. The three types of operations are:

  • Write (Wr): Save the survivor path information in memory.

  • Traceback (TB): Read the survivor path information from the memory, and compute the previous state based on the current state and survivor branch. The earliest state traced by this process is then used as the initial state to decode the previous memory block of the data.

  • Decoding (Dec): Read the survivor path information from the memory and decode the input.

Each of the three memories is Traceback depth (tbd) size. The K-pointer algorithm takes 4×Traceback depth cycles to decode the data.

The diagram shows how the three operations use the three memory banks. For two multiples of Traceback depth, write the survivor metrics in forward direction to Mem#1 and Mem#2. Then, while continuing to write to Mem#3, traceback from Mem#2 to find the minimum index. Use that index as a pointer to traceback from Mem#1 and obtain the decoded value. After the decoded value is read, the block writes the new input survivor path to the same location. This write starts the next decoding cycle.

In the Viterbi algorithm, the add-compare logic can cause a state metric overflow. These overflows degrade the decoder performance. Modulo normalization is used to mitigate the effects of overflow [3]. The block implements modular arithmetic using two's complement adders and subtractors as shown in the diagram. A subtractor is used in place of a comparator. An overflow is detected by checking the most significant bit (MSB) of (m1-m2), where m1m2 are the normalization metrics. When an overflow is detected, m1 and m2 provide a wrapped value.

References

[1] 3GPP TS 36.212. "Multiplexing and channel coding." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network; Evolved Universal Terrestrial Radio Access (E-UTRA). URL: https://www.3gpp.org.

[2] Horwitz, M., and R. Braun. "A Generalised Design Technique for Traceback Survivor Memory Management in Viterbi Decoders." Proceedings of the 1997 South African Symposium on Communications and Signal Processing: 63-68. Piscataway, NJ: IEEE, 1997.

[3] Shung, C.b., P.h. Siegel, G. Ungerboeck, and H.k. Thapar. "VLSI Architectures for Metric Normalization in the Viterbi Algorithm." IEEE International Conference on Communications, Including Supercomm Technical Sessions: vol 4. 1726-728. New York, N.Y. : IEEE, 1990.

Extended Capabilities

Introduced in R2018b