# comm.TurboEncoder

Encode input signal using parallel concatenated encoding scheme

## Description

The comm.TurboEncoder System object™ applies a parallel concatenated encoding scheme to a binary input message. This coding scheme uses two convolutional encoders and appends the termination bits at the end of the encoded data bit stream. For more information, see Parallel Concatenated Convolutional Encoding Scheme.

To encode a binary input message using a parallel concatenated encoding scheme:

1. Create the comm.TurboEncoder object and set its properties.

2. Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

## Creation

### Description

example

turboenc = comm.TurboEncoder creates a turbo encoder System object. This object performs turbo encoding using the default object configuration.

example

turboenc = comm.TurboEncoder(Name,Value) sets properties using one or more name-value pairs. For example, comm.TurboEncoder('InterleaverIndicesSource','Input port') configures a turbo encoder System object with the interleaver indices to be supplied as an input argument to the System object when it is called. Enclose each property name in quotes.

example

turboenc = comm.TurboEncoder(trellis,interlvrindices) creates a turbo encoder System object with the TrellisStructure and InterleaverIndices properties set to trellis and interlvrindices, respectively. The trellis input must be specified as described by the TrellisStructure property. The interlvrindices input must be specified as described by the InterleaverIndices property.

## Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the release function unlocks them.

If a property is tunable, you can change its value at any time.

For more information on changing property values, see System Design in MATLAB Using System Objects.

Trellis description of the constituent convolutional code, specified as a structure that contains the trellis description for a rate KN code. K is the number of input bit streams, and N is the number of output bit streams.

Note

K must be 1 for the turbo coder. For more information, see Coding Rate.

You can either use the poly2trellis function to create the trellis structure or create it manually. For more about this structure, see Trellis Description of a Convolutional Code and the istrellis function.

The trellis structure contains these fields.

Number of symbols input to the encoder, specified as an integer equal to 2K, where K is the number of input bit streams.

Data Types: double

Number of symbols output from the encoder, specified as an integer equal to 2N, where N is the number of output bit streams.

Data Types: double

Number of states in the encoder, specified as a power of 2.

Data Types: double

Next states for all combinations of current states and current inputs, specified as a matrix of integers. The matrix size must be numStates by 2K.

Data Types: double

Outputs for all combinations of current states and current inputs, specified as a matrix of octal numbers. The matrix size must be numStates by 2K.

Data Types: double

Data Types: struct

Source of interleaver indices, specified as 'Property' or 'Input port'.

• When you set this property to 'Property', the object executes using the interleaver indices that you specified with the InterleaverIndices property when configuring the object.

• When you set this property to 'Input port', the object executes using the input argument interlvrindices when you call the object. The vector length and values for the interleaver indices and binary input message can change with each call to the object.

Data Types: char | string

Interleaver indices, specified as a column vector of integers. The vector must be of length L, where L is the length of the binary input message. Each element of the vector must be an integer in the range [1, L] and must be unique. The interleaver indices define the mapping used to permute the input bits at the encoder.

Tunable: Yes

#### Dependencies

To enable this property, set the InterleaverIndicesSource property to 'Property'.

Data Types: double

Source of output indices, specified as 'Auto', 'Property', or 'Input port'.

• When you set this property to 'Auto', the object computes output indices that puncture the second systematic stream and include all tail bits.

• When you set this property to 'Property', the object uses the output indices that you specify for the OutputIndices property.

• When you set this property to 'Input port', the object executes using the output indices specified by the input argument outindices. The vector length and values for the output indices, and the coded output signal can change with each call to the object.

Data Types: char | string

Output indices for the bit ordering and puncturing used on the fully encoded data, specified as a column vector of integers. The number of bits output from the encoder equals the length of this property. The maximum length must not exceed the fully encoded length of (L+mLen) × N × 2, where L is the input block length, mLen is the memory length, and N is the number of encoded streams for the constituent coder.

#### Dependencies

To enable this property, set the OutputIndicesSource property to 'Property'.

Data Types: double

## Usage

### Description

example

codeword = turboenc(message) encodes the input message using the parallel concatenated convolutional encoding scheme specified by the trellis structure and interleaver indices. turboenc returns the binary encoded codeword. message and codeword are column vectors of numeric, logical, or unsigned fixed-point values with word length 1 (fi (Fixed-Point Designer) object). For more information, see Parallel Concatenated Convolutional Encoding Scheme.

example

codeword = turboenc(message,interlvrindices) additionally specifies the interleaver indices. interlvrindices must be a column vector containing integers in the range [1, L] with no repeated values. L is the length of the binary input message, message. This syntax applies when the InterleaverIndicesSource property is set to 'Input port'. The interleaver indices define the mapping used to permute the input bits at the encoder.

codeword = turboenc(message,interlvrindices,outindices) additionally specifies the bit ordering and puncturing used when encoding the message data. To enable this syntax, set the OutputIndicesSource property to 'Input port'. The output indices vector values must be relative to the fully encoded data for the coding scheme, including the tail bits for all streams.

### Input Arguments

expand all

Input message, specified as a binary column vector of length L, where L is the length of the uncoded input message.

Data Types: double | int8 | fi(data,0,1)

Interleaver indices, specified as a column vector of integers. The vector must be of length L, where L is the length of the binary input message. Each element of the vector must be an integer in the range [1, L] and must be unique. The interleaver indices define the mapping used to permute the input bits at the encoder.

#### Dependencies

To enable this argument, set the InterleaverIndicesSource property to 'Input port'.

Data Types: double

Output indices for the bit ordering and puncturing used on the fully encoded data, specified as a column vector of integers. Element values in the outindices vector must be relative to the fully encoded data for the coding scheme, including the tail bits for all streams.

#### Dependencies

To enable this argument, set the OutputIndicesSource property to 'Input port'.

Data Types: double

### Output Arguments

expand all

Parallel concatenated codeword, returned as a binary column vector of length M, where M is the number of bits in the parallel concatenated codeword. This output inherits its data type from the message input.

Data Types: double | int8 | fi(data,0,1)

## Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj, use this syntax:

release(obj)

expand all

 step Run System object algorithm release Release resources and allow changes to System object property values and input characteristics reset Reset internal states of System object

## Examples

collapse all

Encode an input message by using a rate 1/3 turbo encoder configuration with the default trellis structure, poly2trellis(4,[13 15],13), as represented in this figure.

For an input message with 64 bits, the codeword output from the encoder is 204 bits. The first 192 bits output correspond to the three 64 bit streams, interlaced as ${\mathit{X}}_{\mathit{k}}$, ${\mathit{Z}}_{\mathit{k}}$, and ${\mathit{Z}}_{\mathit{k}}^{\prime }$. The systematic bit stream, ${\mathit{X}}_{\mathit{k}}$, and parity bit stream, ${\mathit{Z}}_{\mathit{k}}$, are from the first encoder and the parity bit stream, ${\mathit{Z}}_{\mathit{k}}^{\prime }$, is from the second encoder. When the switches are in the lower position, signals follow the dashed lines and the last 12 bits correspond to the tail bits from the two encoders. The first group of six bits (three systematic bits and three parity bits) are the output tail bits from the first constituent encoder. The second group of six bits (three systematic bits and three parity bits) are the output tail bits from the second constituent encoder.

Create a turbo encoder using the default settings. Generate a frame of binary message data, and then encode the message data.

rng default
turboenc = comm.TurboEncoder;
frameLen = 64; % Frame length
data = randi([0 1],frameLen,1);
encData = turboenc(data);
codewordLen = length(encData);

Compute the coding rate. Due to the tail bits, the encoder output code rate is slightly less than 1/3.

codingrate = frameLen/codewordLen
codingrate = 0.3137

Define output indices by using the OutputIndices property. Show full-length encoded output and punctured encoded output for a rate 1/2 code and 10-bit block length.

Initialize Parameters

Define parameters to initialize the encoder.

blkLen = 10;
trellis = poly2trellis(4,[13 15],13);
n = log2(trellis.numOutputSymbols);
mLen = log2(trellis.numStates);

Full-Length Encoded Output

Initialize variables and a turbo encoder System object for full-length coding. Display the turbo coding rate. Check the length of the coded output versus the length of the output indices vector.

fullOut = (1:(mLen+blkLen)*2*n)';
outLen = length(fullOut);
netRate = blkLen/outLen;
data = randi([0 1],blkLen,1);
intIndices  = randperm(blkLen);

turboEnc = comm.TurboEncoder('TrellisStructure',trellis);
turboEnc.InterleaverIndices = intIndices;
turboEnc.OutputIndicesSource = 'Property';
turboEnc.OutputIndices = fullOut;

encMsg = turboEnc(data);   % Encode

disp(['Turbo coding rate: ' num2str(netRate)])
Turbo coding rate: 0.19231
encOutLen = length(encMsg) % Display encoded length
encOutLen = 52
isequal(encOutLen,outLen)  % Check lengths
ans = logical
1

Punctured Encoded Output

Specify the output indices for puncturing of the second systematic stream by using the getTurboIOIndices function. Initialize variables and a turbo encoder System object for punctured coding. Display the turbo coding rate. Check the length of the coded output versus the length of the output indices vector.

puncOut = getTurboIOIndices(blkLen,n,mLen);
outLen = length(puncOut);
netRate = blkLen/outLen;
data = randi([0 1],blkLen,1);
intIndices  = randperm(blkLen);

turboEnc = comm.TurboEncoder('TrellisStructure',trellis);
turboEnc.InterleaverIndices = intIndices;
turboEnc.OutputIndicesSource = 'Property';
turboEnc.OutputIndices = puncOut;

encMsg = turboEnc(data);   % Encode

disp(['Turbo coding rate: ' num2str(netRate)])
Turbo coding rate: 0.25641
encOutLen = length(encMsg) % Display encoded length
encOutLen = 39
isequal(encOutLen, outLen) % Check lengths
ans = logical
1

Compare Full and Punctured Outputs

The output of the encoder interlaces the individual bit streams. The third bit of every 4-bit tuple is removed from the full-length code to produce the punctured code. This third output bit stream corresponds to the second systematic bit stream. Display the indices of the full-length code and the indices of the punctured code to show that the third bit of every 4-bit tuple is punctured.

fullOut'
ans = 1×52

1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39    40    41    42    43    44    45    46    47    48    49    50

puncOut'
ans = 1×39

1     2     4     5     6     8     9    10    12    13    14    16    17    18    20    21    22    24    25    26    28    29    30    32    33    34    36    37    38    40    41    42    44    45    46    48    49    50    52

Simulate the transmission and reception of BPSK data over an AWGN channel by using turbo encoding and decoding.

Specify simulation parameters, and then compute the effective coding rate and noise variance. For BPSK modulation, ${\mathit{E}}_{\mathrm{S}}/{\mathit{N}}_{0}$ equals ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ because the number of bits per symbol (bps) is 1. To ease reuse of this code for other modulation schemes, calculations in this example include the bps terms. Define the packet length, trellis structure, and number of iterations. Calculate the noise variance using ${\mathit{E}}_{\mathrm{S}}/{\mathit{N}}_{0}$ and the code rate. Set the random number generator to its default state to ensure that the results are repeatable.

modOrd = 2; % Modulation order
bps = log2(modOrd); % Bits per symbol
EbNo = 1; % Energy per bit to noise power spectral density ratio in dB
EsNo = EbNo + 10*log10(bps); % Energy per symbol to noise power spectral density ratio in dB

L = 256; % Input packet length in bits
trellis = poly2trellis(4,[13 15 17],13);
numiter = 4;
n = log2(trellis.numOutputSymbols);
numTails = log2(trellis.numStates)*n;
M = L*(2*n - 1) + 2*numTails; % Output codeword packet length
rate = L/M; % Coding rate

snrdB = EsNo + 10*log10(rate); % Signal to noise ratio in dB
noiseVar = 1./(10.^(snrdB/10)); % Noise variance

rng default

Generate random interleaver indices.

intrlvrIndices = randperm(L);

Create a turbo encoder and decoder pair. Use the defined trellis structure and random interleaver indices. Configure the decoder to run a maximum of four iterations.

turboenc = comm.TurboEncoder(trellis,intrlvrIndices);
turbodec = comm.TurboDecoder(trellis,intrlvrIndices,numiter);

Create a BPSK modulator and demodulator pair, where the demodulator outputs soft bits determined using an LLR method.

bpskmod = comm.BPSKModulator;
bpskdemod = comm.BPSKDemodulator('DecisionMethod','Log-likelihood ratio', ...
'Variance',noiseVar);

Create an AWGN channel object and an error rate object.

awgnchan = comm.AWGNChannel('NoiseMethod','Variance','Variance',noiseVar);
errrate = comm.ErrorRate;

The main processing loop performs these steps.

1. Generate binary data.

2. Turbo encode the data.

3. Modulate the encoded data.

4. Pass the modulated signal through an AWGN channel.

5. Demodulate the noisy signal by using LLR to output soft bits.

6. Turbo decode the demodulated data. Because the bit mapping from the demodulator is opposite of the mapping expected by the turbo decoder, the decoder input must use the inverse of the demodulated signal.

7. Calculate the error statistics.

for frmIdx = 1:100
data = randi([0 1],L,1);
encodedData = turboenc(data);
modSignal = bpskmod(encodedData);
end

Display the error data.

fprintf('Bit error rate = %5.2e\nNumber of errors = %d\nTotal bits = %d\n', errorStats)
Bit error rate = 2.34e-04
Number of errors = 6
Total bits = 25600

Simulate an end-to-end communication link by using a 16-QAM signal and turbo codes in an AWGN channel. Inside a frame processing loop, packet sizes are randomly selected to be 500, 1000, or 1500 bits. Because the packet size varies, the interleaver indices are provided to the turbo encoder and decoder as an input argument of their associated System object. Compare turbo coded bit error rate results to uncoded bit error rate results.

Initialize Simulation

Set the modulation order and range of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values. Compute the number of bits per symbol and the energy per symbol to noise ratio (${\mathit{E}}_{\mathrm{S}}/{\mathit{N}}_{0}$) based on the modulation order and ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$. To get repeatable results, seed the random number.

modOrder = 16;               % Modulation order
bps = log2(modOrder);        % Bits per symbol
EbNo = (2:0.5:4);            % Energy per bit to noise power spectral density ratio in dB
EsNo = EbNo + 10*log10(bps); % Energy per symbol to noise power spectral density ratio in dB
rng(1963);

Create a turbo encoder and decoder pair. Because the packet length varies for each frame, specify that the interleaver indices be supplied by an input argument of the System object when executed. Specify that the decoder perform four iterations.

turboEnc = comm.TurboEncoder('InterleaverIndicesSource','Input port');
turboDec = comm.TurboDecoder('InterleaverIndicesSource','Input port','NumIterations',4);
trellis = poly2trellis(4,[13 15 17],13);
n = log2(turboEnc.TrellisStructure.numOutputSymbols);
numTails = log2(turboEnc.TrellisStructure.numStates)*n;

Create an error rate object.

errRate = comm.ErrorRate;

Main Processing Loop

The frame processing loop performs these steps.

1. Select a random packet length, and generate random binary data.

2. Compute the output codeword length and coding rate.

3. Compute the signal to noise ratio (SNR) and noise variance.

4. Generate interleaver indices.

5. Turbo encode the data.

6. Apply 16-QAM modulation, and normalize the average signal power.

7. Pass the modulated signal through an AWGN channel.

8. Demodulate the noisy signal by using an LLR method, output soft bits, and normalize the average signal power.

9. Turbo decode the data. Because the bit mapping order from the demodulator is opposite the mapping order expected by the turbo decoder, the decoder input must use the inverse of the demodulated signal.

10. Calculate the error statistics.

ber = zeros(1,length(EbNo));
for k = 1:length(EbNo)
% numFrames = 100;
errorStats = zeros(1,3);
%for pktIdx = 1:numFrames
L = 500*randi([1 3],1,1);         % Packet length in bits
M = L*(2*n - 1) + 2*numTails;     % Output codeword packet length
rate = L/M;                       % Coding rate for current packet
snrdB = EsNo(k) + 10*log10(rate); % Signal to noise ratio in dB
noiseVar = 1./(10.^(snrdB/10));   % Noise variance

while errorStats(2) < 100 && errorStats(3) < 1e7
data = randi([0 1],L,1);
intrlvrIndices = randperm(L);
encodedData = turboEnc(data,intrlvrIndices);
modSignal = qammod(encodedData,modOrder, ...
'InputType','bit','UnitAveragePower',true);
rxSignal = awgn(modSignal,snrdB);
demodSignal = qamdemod(rxSignal,modOrder,'OutputType','llr', ...
'UnitAveragePower',true,'NoiseVariance',noiseVar);
rxBits = turboDec(-demodSignal,intrlvrIndices); % Demodulated signal is negated
errorStats = errRate(data,rxBits);
end
% Save the BER data and reset the bit error rate object
ber(k) = errorStats(1);
reset(errRate)
end

Plot Results

Plot the bit error rate and compare it to the uncoded bit error rate.

semilogy(EbNo,ber,'-o')
grid
xlabel('Eb/No (dB)')
ylabel('Bit Error Rate')
uncodedBER = berawgn(EbNo,'qam',modOrder); % Estimate of uncoded BER
hold on
semilogy(EbNo,uncodedBER)
legend('Turbo','Uncoded','location','sw')

expand all

## References

[1] Berrou, C., A. Glavieux, and P. Thitimajshima. “Near Shannon Limit Error-Correcting Coding and Decoding: Turbo-Codes.” Proceedings of ICC 93 - IEEE International Conference on Communications, Geneva, Switzerland, May 1993, 1064–70. https://doi.org/10.1109/icc.1993.397441.

[2] Benedetto, S., G. Montorsi, D. Divsalar, and F. Pollara. "A Soft-Input Soft-Output Maximum A Posterior (MAP) Module to Decode Parallel and Serial Concatenated Codes." Jet Propulsion Lab TDA Progress Report, 42–127, (November 1996).

[3] Schlegel, Christian, and Lance Perez. Trellis and Turbo Coding. IEEE Press Series on Digital & Mobile Communication. Piscataway, NJ ; Hoboken, NJ: IEEE Press ; Wiley-Interscience, 2004.

[4] 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). https://www.3gpp.org.

## Version History

Introduced in R2012a