# comm.RSDecoder

Decode data using Reed-Solomon decoder

## Description

The `RSDecoder` object recovers a message vector from a Reed-Solomon codeword vector. For proper decoding, the property values for this object should match the property values in the corresponding RS Encoder object.

To decode data using a Reed-Solomon decoding scheme:

1. Define and set up your Reed-Solomon decoder object. See Construction.

2. Call `step` to decode data according to the properties of `comm.RSDecoder`. The behavior of `step` is specific to each object in the toolbox.

Note

Starting in R2016b, instead of using the `step` method to perform the operation defined by the System object™, you can call the object with arguments, as if it were a function. For example, ```y = step(obj,x)``` and `y = obj(x)` perform equivalent operations.

## Construction

`dec = comm.RSDecoder` creates a block decoder System object, `dec`. This object performs Reed-Solomon (RS) decoding.

`dec = comm.RSDecoder(N,K)` creates an RS decoder object, `dec` with the `CodewordLength` property set to `N` and the `MessageLength` property set to `K`.

`dec = comm.RSDecoder(N,K,GP)` creates an RS decoder object, `dec` with the `CodewordLength` property set to `N`, the `MessageLength` property set to `K`, and the `GeneratorPolynomial` property set to `GP`.

`dec = comm.RSDecoder(N,K,GP,S)` creates an RS decoder object, `dec` with the `CodewordLength` property set to `N`, the `MessageLength` property set to `K`, the `GeneratorPolynomial` property set to `GP`, and the `ShortMessageLength` property set to `S`.

`dec = comm.RSDecoder(N,K,GP,S,Name,Value)` creates an RS decoder object, `dec` with the `CodewordLength` property set to `N`, the `MessageLength` property set to `K`, the `GeneratorPolynomial` property set to `GP`, and each specified property `Name` set to the specified `Value`.

`dec = comm.RSDecoder(Name,Value)` creates an RS decoder object, `dec`, with each specified property name set to the specified value. You can specify additional name-value pair arguments in any order as (`Name1`,`Value1`,...,`NameN`,`ValueN`).

## Properties

Note

The input and output signal lengths are listed in Input and Output Signal Lengths in BCH and RS System Objects on the `comm.BCHDecoder` reference page.

 `BitInput` Assume that input is bits Specify whether the input comprises bits or integers. The default is `false`. When you set this property to `false`, the input data value to run the object must be a numeric, column vector of integers. Running the object outputs an encoded data output vector. The output result is a column vector of integers. Each symbol that forms the input message and output codewords is an integer in the range [0, 2M – 1]. These integers correspond to an element of the finite Galois field `gf`(2M). M is the degree of the primitive polynomial that you specify with the `PrimitivePolynomialSource` and `PrimitivePolynomial` properties.When you set this property to `true`, the input value must be a numeric, column vector of bits. The encoded data output result is a column vector of bits. `CodewordLength` Codeword length Specify the codeword length of the RS code in symbols as a double-precision, positive, integer scalar value. The default is `7`. For a full-length RS code, the value of this property must be 2M – 1, where M is an integer such that 3 ≤ M ≤ 16. `MessageLength` Message length Specify the message length in symbols as a double-precision positive integer scalar value. The default is `3`. `ShortMessageLengthSource` Short message length source Specify the source of the shortened message as `Auto` or `Property`. When you set this property to `Auto`, the RS code is defined by the `CodewordLength`, `MessageLength`, `GeneratorPolynomial`, and `PrimitivePolynomial` properties.When you set this property to `Property`, you must specify the `ShortMessageLength` property, which is used with the other properties to define the RS code. The default is `Auto`. `ShortMessageLength` Shortened message length Specify the length of the shortened message in symbols as a double-precision positive integer scalar whose value must be less than or equal to `MessageLength`. The default is `3`. When `ShortMessageLength` < `MessageLength`, the RS code is shortened. `GeneratorPolynomialSource` Source of generator polynomial Specify the source of the generator polynomial as `Auto` or `Property`. The default is `Auto`. When you set this property to `Auto`, the object automatically chooses the generator polynomial. The object calculates the generator polynomial based on the value of the `PrimitivePolynomial` property.When you set this property to `Property`, you must specify a generator polynomial using the `GeneratorPolynomial` property. `GeneratorPolynomial` Generator polynomial Specify the generator polynomial for the RS code as a double-precision integer row vector or as a Galois field row vector. The Galois field row vector entries must be in the range [0, 2M – 1] and represent a generator polynomial in descending order of powers. Each coefficient is an element of the Galois field `gf`(2M), represented in integer format. The length of the generator polynomial must be `CodewordLength` – `MessageLength` + 1. The default is the result of `rsgenpoly(7,3,[],[],'double')`, which corresponds to `[1 3 1 2 3]`. When you use this object to generate code, you must set the generator polynomial to a double-precision integer row vector. This property applies when you set `GeneratorPolynomialSource` to `Property`. `CheckGeneratorPolynomial` Enable generator polynomial checking Set this property to `true` to perform a generator polynomial check. The default is `true`. This check verifies that X`CodewordLength` + 1 is divisible by the generator polynomial specified in the `GeneratorPolynomial` property. For codes with generator polynomials of high degree, disabling the check speeds up processing. As a best practice, perform the check at least once before setting this property to `false`. A valid generator polynomial is given by (X – αB)×(X – α(B + 1))×...×(X-α(B + `CodewordLength` – `MessageLength` – 1)), where α is a root of the primitive polynomial and B is an integer. If the value of B is 1, then you can set this property to `false`. Otherwise, always set this property to `true`. For more information about B, see the `rsgenpoly` function reference page. This property applies when you set `GeneratorPolynomialSource` to `Property`. `PrimitivePolynomialSource` Source of primitive polynomial Specify the source of the primitive polynomial as `Auto` or `Property`. The default is `Auto`. When you set this property to `Auto`, the object uses a primitive polynomial of degree M = `ceil` (Fixed-Point Designer)(log2(`CodewordLength` + 1)).When you set this property to `Property`, you must specify a polynomial using `PrimitivePolynomial`. `PrimitivePolynomial` Primitive polynomial Specify the primitive polynomial that defines the finite field `gf`(2M) corresponding to the integers that form messages and codewords. The default is the result of `fliplr`(`de2bi`(`primpoly`(3))), which is `[1 0 1 1]` or the polynomial x3 + x + 1. Specify this property as a double-precision, binary, row vector that represents a primitive polynomial over `gf`(2) of degree M in descending order of powers. This property applies when you set `PrimitivePolynomialSource` to `Property`. `PuncturePatternSource` Source of puncture pattern Specify the source of the puncture pattern as `None` or `Property`. The default is `None`. When you set this property to `None`, the object does not apply puncturing to the code. When you set this property to `Property`, the object punctures the code based on a puncture pattern vector specified in `PuncturePattern`. `PuncturePattern` Puncture pattern vector Specify the pattern used to puncture the encoded data as a double-precision, binary column vector of length (`CodewordLength` – `MessageLength`). The default is `[ones(2,1); zeros(2,1)]`. Zeros in the puncture pattern vector indicate the position of the parity symbols that are punctured or excluded from each codeword. This property applies when you set `PuncturePatternSource` to `Property`. `ErasuresInputPort` Enable erasures input Set this property to `true` to specify a vector of erasures as an input when running the object. The default is `false`. The erasures input must be a double-precision or logical binary column vector that indicates which symbols of the input codewords to erase. The length of the erasures vector is explained in Input and Output Signal Lengths in BCH and RS System Objects. When you set this property to `false`, the object assumes no erasures. `NumCorrectedErrorsOutputPort` Enable number of corrected errors output Set this property to `true` to obtain the number of corrected errors as an output when running the object. The default is `true`. A nonnegative value in the i-th element of the error output vector, denotes the number of corrected errors in the i-th input codeword. A value of `-1` in the i-th element of the error output vector indicates that a decoding error occurred for that codeword. A decoding error occurs when an input codeword has more errors than the error correction capability of the RS code. `OutputDataType` Data type of output Specify the output data type as `Same as input`, `double`, or `logical`. The default is `Same as input`. This property applies when you set `BitInput` to `true`.

## Methods

 step Decode data using a Reed-Solomon decoder
Common to All System Objects
`release`

Allow System object property value changes

## Examples

collapse all

Transmit an RS-encoded, 8-DPSK-modulated symbol stream through an AWGN channel. Then, demodulate, decode, and count errors.

``` enc = comm.RSEncoder; mod = comm.DPSKModulator('BitInput',false); chan = comm.AWGNChannel(... 'NoiseMethod','Signal to noise ratio (SNR)','SNR',10); demod = comm.DPSKDemodulator('BitOutput',false); hDdecec = comm.RSDecoder; errorRate = comm.ErrorRate('ComputationDelay',3); for counter = 1:20 data = randi([0 7], 30, 1); encodedData = step(enc, data); modSignal = step(mod, encodedData); receivedSignal = step(chan, modSignal); demodSignal = step(demod, receivedSignal); receivedSymbols = step(hDdecec, demodSignal); errorStats = step(errorRate, data, receivedSymbols); end fprintf('Error rate = %f\nNumber of errors = %d\n', ... errorStats(1), errorStats(2))```
```Error rate = 0.115578 Number of errors = 69 ```

Transmit Reed-Solomon encoded data using QPSK over an AWGN channel. Demodulate and decode the received signal and collect error statistics. Compute theoretical bit error rate (BER) for coded and noncoded data. Plot the BER results to compare performance.

Define the example parameters.

```rng(1993); % Seed random number generator for repeatable results M = 4; % Modulation order bps = log2(M); % Bits per symbol N = 7; % RS codeword length K = 5; % RS message length```

Create modulator, demodulator, AWGN channel, and error rate objects.

```pskModulator = comm.PSKModulator('ModulationOrder',M,'BitInput',true); pskDemodulator = comm.PSKDemodulator('ModulationOrder',M,'BitOutput',true); awgnChannel = comm.AWGNChannel('BitsPerSymbol',bps); errorRate = comm.ErrorRate;```

Create a (7,5) Reed-Solomon encoder and decoder pair which accepts bit inputs.

```rsEncoder = comm.RSEncoder('BitInput',true,'CodewordLength',N,'MessageLength',K); rsDecoder = comm.RSDecoder('BitInput',true,'CodewordLength',N,'MessageLength',K);```

Set the range of ${E}_{b}/{N}_{0}$ values and account for RS coding gain. Initialize the error statistics matrix.

```ebnoVec = (3:0.5:8)'; ebnoVecCodingGain = ebnoVec + 10*log10(K/N); % Account for RS coding gain errorStats = zeros(length(ebnoVec),3);```

Estimate the bit error rate for each ${E}_{b}/{N}_{0}$ value. The simulation runs until either 100 errors or $1{0}^{7}$ bits is encountered. The main simulation loop processing includes encoding, modulation, demodulation, and decoding.

```for i = 1:length(ebnoVec) awgnChannel.EbNo = ebnoVecCodingGain(i); reset(errorRate) while errorStats(i,2) < 100 && errorStats(i,3) < 1e7 data = randi([0 1],1500,1); % Generate binary data encData = rsEncoder(data); % RS encode modData = pskModulator(encData); % Modulate rxSig = awgnChannel(modData); % Pass signal through AWGN rxData = pskDemodulator(rxSig); % Demodulate decData = rsDecoder(rxData); % RS decode errorStats(i,:) = errorRate(data,decData); % Collect error statistics end end```

Fit a curve to the BER data using `berfit`. Generate an estimate of QPSK performance with and without coding using the `bercoding` and `berawgn` functions.

```berCurveFit = berfit(ebnoVecCodingGain,errorStats(:,1)); berwCoding = bercoding(ebnoVec,'RS','hard',N,K,'psk',M,'nondiff'); berNoCoding = berawgn(ebnoVec,'psk',M,'nondiff');```

Plot the RS coded BER data, curve fit of the BER data, theoretical performance with RS coding, and theoretical performance without RS coding. The (7,5) RS code improves the ${E}_{b}/{N}_{0}$ required to achieve a $1{0}^{-2}$ bit error rate by approximately 1.2 dB.

```semilogy(ebnoVecCodingGain,errorStats(:,1),'b*', ... ebnoVecCodingGain,berCurveFit,'c-',ebnoVecCodingGain,berwCoding,'r',ebnoVec,berNoCoding) ylabel('BER') xlabel('Eb/No (dB)') legend('RS coded BER','Curve Fit','Theory with coding','Theory no coding') grid```

Transmit a shortened RS-encoded, 256-QAM-modulated symbol stream through an AWGN channel. Then demodulate, decode, and count errors.

Set the parameters for the Reed-Solomon code, where `N` is the codeword length, `K` is the nominal message length, and `S` is the shortened message length. Set the modulation order, `M`, and the number of frames, `L`.

```N = 255; K = 239; S = 188; M = 256; L = 50;```

Create an AWGN channel System object and an error rate System object.

```awgnChan = comm.AWGNChannel('NoiseMethod','Signal to noise ratio (Eb/No)', ... 'EbNo',15,'BitsPerSymbol',log2(M)); errorRate = comm.ErrorRate('ComputationDelay',3);```

Create the Reed-Solomon generator polynomial from the DVB-T standard.

`gp = rsgenpoly(N,K,[],0);`

Create a Reed-Solomon encoder and decoder pair using the shortened message length, `S`, and the DVB-T generator polynomial, `gp`.

```enc = comm.RSEncoder(N,K,gp,S); dec = comm.RSDecoder(N,K,gp,S);```

Generate random symbol frames whose length equals one message block. Encode, modulate, apply AWGN, demodulate, decode, and collect statistics.

```for counter = 1:L data = randi([0 1],S,log2(M)); encodedData = step(enc,bi2de(data)); modSignal = qammod(encodedData,M,'UnitAveragePower',true); rxSignal = awgnChan(modSignal); demodSignal = qamdemod(rxSignal,M,'UnitAveragePower',true); rxBits = dec(demodSignal); dataOut = de2bi(rxBits); errorStats = errorRate(data(:),dataOut(:)); end```

Display the error rate and number of errors.

```fprintf('Error rate = %5.2e\nNumber of errors = %d\n', ... errorStats(1), errorStats(2))```
```Error rate = 2.01e-02 Number of errors = 1509 ```

This example shows how to configure the `comm.RSEncoder` and `comm.RSDecoder` System objects to perform Reed-Solomon (RS) block coding with erasures when simulating a communications system. RS decoders can correct both errors and erasures. A receiver that identifies the most unreliable symbols in a given codeword can generate erasures. When a receiver erases a symbol, it replaces that symbol with a zero. The receiver then passes a flag to the decoder, indicating that the symbol is an erasure, not a valid code symbol. In addition, an encoder can generate punctures for which specific parity symbols are always removed from its output. The decoder, which knows the puncture pattern, inserts zeros in the puncture positions and treats those symbols as erasures. The decoder treats encoder-generated punctures and receiver-generated erasures the exact same way when it decodes a symbol. Puncturing also has the added benefit of making the code rate more flexible, at the expense of some error correction capability. Shortened codes achieve the same code rate flexibility without degrading the error correction performance, given the same demodulator input energy per bit to noise power spectral density ratio (Eb/N0). Note that puncturing is the removal of parity symbols from a codeword, and shortening is the removal of message symbols from a codeword.

This example shows the simulation of a communication system consisting of a random source, an RS encoder, a 64-QAM modulator, an AWGN channel, a 64-QAM demodulator, and an RS decoder. It includes analysis of RS coding with erasures by comparing the channel bit error rate (BER) performance versus the coded BER performance. This example obtains Channel BER by comparing inputs for the QAM modulator to outputs from the QAM demodulator and obtains Coded BER by comparing inputs for the RS encoder to outputs from the RS decoder.

Initialization

The helperRSCodingConfig.m helper function initializes simulation parameters, and configures the `comm.AWGNChannel` and `comm.ErrorRate` System objects used to simulate the communications system. The uncoded Eb/N0 ratio is set EbNoUncoded = 15 dB. Criteria to stop the simulation stop are defined to stop the simulation if 500 errors occur or a maximum 5e6 bits are transmitted.

`helperRSCodingConfig;`

Configure RS Encoder/Decoder

This example uses a (63,53) RS code operating with a 64-QAM modulation scheme. This code can correct (63-53)/2 = 5 errors, or it can alternatively correct (63-53) = 10 erasures. For each codeword at the output of the 64-QAM demodulator, the receiver determines the six least reliable symbols using the helperRSCodingGetErasures.m helper function. The indices that point to the location of these unreliable symbols are passed as an input to the RS decoder. The RS decoder treats these symbols as erasures resulting in an error correction capability of (10-6)/2 = 2 errors per codeword.

Create a `comm.RSEncoder` System object and set the `BitInput` property to false to specify that the encoder inputs and outputs are integer symbols.

```N = 63; % Codeword length K = 53; % Message length rsEncoder = comm.RSEncoder(N,K,'BitInput',false); numErasures = 6;```

Create a `comm.RSDecoder` System object matching the configuration of the `comm.RSEncoder` object.

`rsDecoder = comm.RSDecoder(N,K,'BitInput',false);`

Set the `ErasuresInputPort` property to true to specify erasures as an input to the decoder object.

`rsDecoder.ErasuresInputPort = true;`

Set the `NumCorrectedErrorsOutputPort` property to true so that the decoder outputs the number of corrected errors. A non negative value in the error output denotes the number of corrected errors in the input codeword. A value of –1 in the error output indicates a decoding error. A decoding error occurs when the input codeword has more errors than the error correction capability of the RS code.

`rsDecoder.NumCorrectedErrorsOutputPort = true;`

Run Stream Processing Loop

Simulate the communications system for an uncoded Eb/N0 ratio of 15 dB. The uncoded Eb/N0 is the ratio that would be measured at the input of the channel if there was no coding in the system.

The signal going into the AWGN channel is the encoded signal, so you must convert the uncoded Eb/N0 values so that they correspond to the energy ratio at the encoder output. This ratio is the coded Eb/N0 ratio. If you input K symbols to the encoder and obtain N output symbols, then the energy relation is given by the K/N rate. Set the `EbNo` property of the AWGN channel object to the computed coded Eb/N0 value.

```EbNoCoded = EbNoUncoded + 10*log10(K/N); channel.EbNo = EbNoCoded;```

Loop until the simulation reaches the target number of errors or the maximum number of transmissions.

```chanErrorStats = zeros(3,1); codedErrorStats = zeros(3,1); correctedErrors = 0; while (codedErrorStats(2) < targetErrors) && ... (codedErrorStats(3) < maxNumTransmissions)```

The data symbols transmit one message word at a time. Each message word has K symbols in the [0 N] range.

` data = randi([0 N],K,1);`

Encode the message word. The encoded word, `encData`, is `(N-numPunc)` symbols long.

` encData = rsEncoder(data);`

Modulate encoded data and add noise. then demodulate channel output.

``` modData = qammod(encData,M); chanOutput = channel(modData); demodData = qamdemod(chanOutput,M);```

Use the helperRSCodingGetErasures.m helper function to find the 6 least reliable symbols and generate an erasures vector. The length of the erasures vector must be equal to the number of symbols in the demodulated codeword. A one in the ith element of the vector erases the ith symbol in the codeword. Zeros in the vector indicate no erasures.

``` erasuresVec = helperRSCodingGetErasures(chanOutput,numErasures); ```

Decode the data. Accumulate the number of corrected errors using the cumulative sum object.

``` [estData,errs] = rsDecoder(demodData,erasuresVec); if (errs >= 0) correctedErrors = cumulativeSum(errs); end```

When computing the channel and coded BERs, convert integers to bits.

``` chanErrorStats(:,1) = ... chanBERCalc(reshape(de2bi(encData,log2(M))',[],1),reshape(de2bi(demodData,log2(M))',[],1)); codedErrorStats(:,1) = ... codedBERCalc(reshape(de2bi(data,log2(M))',[],1),reshape(de2bi(estData,log2(M))',[],1)); end```

The error rate measurement objects, `chanBERCalc` and `codedBERCalc`, output 3-by-1 vectors containing BER measurement updates, the number of errors, and the total number of bit transmissions. Display the channel BER, the coded BER and the total number of errors corrected by the RS decoder.

`chanBitErrorRate = chanErrorStats(1)`
```chanBitErrorRate = 0.0017 ```
`codedBitErrorRate = codedErrorStats(1)`
```codedBitErrorRate = 0 ```
`totalCorrectedErrors = correctedErrors`
```totalCorrectedErrors = 882 ```

You can add a for loop around the processing loop above to run simulations for a set of Eb/N0 values. Simulations were run offline for uncoded Eb/N0 values in 4:15 dB, target number of errors equal to 5000, and maximum number of transmissions equal to 50e6. The results from the simulation are shown. The channel BER is worse than the theoretical 64-QAM BER because Eb/N0 is reduced by the code rate.

Summary

This example utilized several System objects to simulate a 64-QAM communications system over an AWGN channel with RS block coding. It showed how to configure the RS decoder to decode symbols with erasures. System performance was measured using channel and coded BER curves obtained using error rate measurement System objects.

Helper functions used in this example:

This example shows how to configure the `comm.RSEncoder` and `comm.RSDecoder` System objects to perform Reed-Solomon (RS) block coding with erasures and puncture codes when simulating a communications system. An encoder can generate punctures to remove specific parity symbols from its output. given the puncture pattern, the decoder inserts zeros in the puncture positions and treats those symbols as erasures. The decoder treats encoder-generated punctures and receiver-generated erasures in exactly the same way when it decodes. Puncturing has the added benefit of making the code rate more flexible, at the expense of some error correction capability.

This example shows the simulation of a communication system consisting of a random source, an RS encoder, a 64-QAM modulator, an AWGN channel, a 64-QAM demodulator, and an RS decoder. It includes analysis of RS coding with erasures and puncturing by comparing the channel bit error rate (BER) performance versus the coded BER performance. This example obtains Channel BER by comparing inputs for the QAM modulator to outputs from the QAM demodulator. This example obtains Coded BER by comparing inputs for the RS encoder to outputs from the RS decoder.

Initialization

The helperRSCodingConfig.m helper function initializes simulation parameters, and configures the `comm.AWGNChannel` and `comm.ErrorRate` System objects used to simulate the communications system. The uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio, `EbNoUncoded` is set to 15 dB. Criteria to stop the simulation stop are defined to stop the simulation if 500 errors occur or a maximum $5×{10}^{6}$ bits are transmitted.

`helperRSCodingConfig;`

Configure RS Encoder/Decoder

This example uses the same (63,53) RS code operating with a 64-QAM modulation scheme that is configured for erasures and code puncturing. The RS algortihm decodes receiver-generated erasures and corrects encoder-generated punctures. For each codeword, the sum of the punctures and erasures cannot exceed twice the error-correcting capability of the code.

Create a `comm.RSEncoder` System object and set the `BitInput` property to false to specify that the encoder inputs and outputs are integer symbols.

```N = 63; % Codeword length K = 53; % Message length rsEncoder = comm.RSEncoder(N,K,'BitInput',false); numErasures = 6;```

Create a `comm.RSDecoder` System object matching the configuration of the `comm.RSEncoder` object. Then set the `ErasuresInputPort` property to true to specify erasures as an input to the decoder object.

```rsDecoder = comm.RSDecoder(N,K,'BitInput',false); rsDecoder.ErasuresInputPort = true;```

To enable code puncturing, set the `PuncturePatternSource` property to `'Property'` and set the `PuncturePattern` property to the desired puncture pattern vector. The same puncture vector must be specified in both the encoder and decoder. This example punctures two symbols from each codeword. Values of `1` in the puncture pattern vector indicate nonpunctured symbols, and values of `0` indicate punctured symbols.

```numPuncs = 2; rsEnc.PuncturePatternSource = 'Property'; rsEnc.PuncturePattern = [ones(N-K-numPuncs,1); zeros(numPuncs,1)]; rsDec.PuncturePatternSource = 'Property'; rsDec.PuncturePattern = rsEnc.PuncturePattern;```

Run Stream Processing Loop

Simulate the communications system for an uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio of 15 dB. The uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ is the ratio that would be measured at the input of the channel if there was no coding in the system.

The signal going into the AWGN channel is the encoded signal, so you must convert the uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values so that they correspond to the energy ratio at the encoder output. This ratio is the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio. If you input `K` symbols to the encoder and obtain `N` output symbols, then the energy relation is given by the `K`/`N` rate. Since the length of the codewords generated by the RS encoder is reduced by the number of punctures specified in the puncture pattern vector, the value of the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio needs to be adjusted to account for these punctures. In this example, The number of output symbols is (`N` - `numPuncs`) and the uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio relates to the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ as shown below. Set the `EbNo` property of the AWGN channel object to the computed coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value.

```EbNoCoded = EbNoUncoded + 10*log10(K/(N - numPuncs)); channel.EbNo = EbNoCoded; ```

Loop until the simulation reaches the target number of errors or the maximum number of transmissions.

```chanErrorStats = zeros(3,1); codedErrorStats = zeros(3,1); correctedErrors = 0; while (codedErrorStats(2) < targetErrors) && ... (codedErrorStats(3) < maxNumTransmissions)```

The data symbols transmit one message word at a time. Each message word has K symbols in the [0 `N`] range.

` data = randi([0 N],K,1);`

Encode the message word. The encoded word, `encData`, is (`N``numPunc`) symbols long.

` encData = rsEncoder(data);`

Modulate encoded data and add noise. then demodulate channel output.

``` modData = qammod(encData,M); chanOutput = channel(modData); demodData = qamdemod(chanOutput,M);```

Use the helperRSCodingGetErasures.m helper function to find the 6 least reliable symbols and generate an erasures vector. The length of the erasures vector must be equal to the number of symbols in the demodulated codeword. A one in the ith element of the vector erases the ith symbol in the codeword. Zeros in the vector indicate no erasures.

``` erasuresVec = helperRSCodingGetErasures(chanOutput,numErasures); ```

Decode the data. Accumulate the number of corrected errors using the cumulative sum object.

``` [estData,errs] = rsDecoder(demodData,erasuresVec); if (errs >= 0) correctedErrors = cumulativeSum(errs); end```

When computing the channel and coded BERs, convert integers to bits.

``` chanErrorStats(:,1) = ... chanBERCalc(reshape(de2bi(encData,log2(M))',[],1),reshape(de2bi(demodData,log2(M))',[],1)); codedErrorStats(:,1) = ... codedBERCalc(reshape(de2bi(data,log2(M))',[],1),reshape(de2bi(estData,log2(M))',[],1)); end```

The error rate measurement objects, `chanBERCalc` and `codedBERCalc`, output 3-by-1 vectors containing BER measurement updates, the number of errors, and the total number of bit transmissions. Display the channel BER, the coded BER and the total number of errors corrected by the RS decoder.

`chanBitErrorRate = chanErrorStats(1)`
```chanBitErrorRate = 0.0015 ```
`codedBitErrorRate = codedErrorStats(1)`
```codedBitErrorRate = 0 ```
`totalCorrectedErrors = correctedErrors`
```totalCorrectedErrors = 632 ```

You can add a for loop around the processing loop above to run simulations for a set of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values. Simulations were run offline for uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values in 4:15 dB, target number of errors equal to 5000, and maximum number of transmissions equal to $50×{10}^{6}$. This figure compares results achieved for

• RS coding with only erasures

• RS coding with erasures and puncturing

• Theoretical BER for 64-QAM

The coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ is slightly higher than the channel ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$, so the channel BER is slightly better in the punctured case. On the other hand, the coded BER is worse in the punctured case, because the two punctures reduce the error correcting capability of the code by one, leaving it able to correct only (10 – 6 – 2) / 2 = 1 error per codeword.

Summary

This example utilized functions and System objects to simulate a 64-QAM communications system over an AWGN channel with RS block coding. It showed how to configure the RS encoder/decoder System objects to obtain punctured codes. System performance was measured using channel and coded BER curves obtained using error rate measurement System objects.

Helper functions used in this example:

This example shows how to configure the `comm.RSEncoder` and `comm.RSDecoder` System objects to perform Reed-Solomon (RS) block coding to shorten the (63,53) code to a (28,18) code. The simulation of a communication system consisting of a random source, an RS encoder, a 64-QAM modulator, an AWGN channel, a 64-QAM demodulator, and an RS decoder is presented.

The effects of RS coding with erasures, puncturing, and shortening are analyzed by comparing the channel bit error rate (BER) performance versus the coded BER performance. This example obtains Channel BER by comparing inputs for the QAM modulator to outputs from the QAM demodulator and obtains Coded BER by comparing inputs for the RS encoder to outputs from the RS decoder. Puncturing is the removal of parity symbols from a codeword, and shortening is the removal of message symbols from a codeword. Puncturing has the benefit of making the code rate more flexible, at the expense of some error correction capability. Shortened codes achieve the same code rate flexibility without degrading the error correction performance for the same demodulator input ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$.

Initialization

The helperRSCodingConfig.m helper function initializes simulation parameters, and configures the `comm.AWGNChannel` and `comm.ErrorRate` System objects used to simulate the communications system. The uncoded${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio is set `EbNoUncoded` = 15 dB. Criteria to stop the simulation stop are defined to stop the simulation if 500 errors occur or a maximum $5×{10}^{6}$ bits are transmitted.

`helperRSCodingConfig;`

Configure RS Encoder/Decoder

This example uses a (63,53) RS code operating with a 64-QAM modulation scheme. The RS coding operation includes erasures, puncturing, and code shortening. This example shows how to shorten the (63,53) code to a (28,18) code.

To shorten a (63,53) code by 10 symbols to a (53,43) code, you can simply enter 53 and 43 for the `CodewordLength` and `MessageLength` properties, respectively (since $2⌈{\mathrm{log}}_{2}\left(53+1\right)⌉-1=63$). However, to shorten it by 35 symbols to a (28,18) code, you must explicitly specify that the symbols belong to the Galois field GF(26). Otherwise, the RS blocks will assume that the code is shortened from a (31,21) code (since $2⌈{\mathrm{log}}_{2}\left(28+1\right)⌉-1=31$).

Create a pair of `comm.RSEncoder` and `comm.RSDecoder` System objects so that they perform block coding with a (28,18) code shortened from a (63,53) code that is configured to input and output integer symbols. Configure the decoder to accept an erasure input and two punctures. For each codeword at the output of the 64-QAM demodulator, the receiver determines the six least reliable symbols using the helperRSCodingGetErasures.m helper function. The indices that point to the location of these unreliable symbols are passed as an input to the RS decoder.

```N = 63; % Codeword length K = 53; % Message length S = 18; % Shortenened message length numErasures = 6; numPuncs = 2; rsEncoder = comm.RSEncoder(N, K, 'BitInput', false); rsDecoder = comm.RSDecoder(N, K, 'BitInput', false, 'ErasuresInputPort', true); rsEncoder.PuncturePatternSource = 'Property'; rsEncoder.PuncturePattern = [ones(N-K-numPuncs,1); zeros(numPuncs,1)]; rsDecoder.PuncturePatternSource = 'Property'; rsDecoder.PuncturePattern = rsEncoder.PuncturePattern;```

Set the shortened codeword length and message length values.

```rsEncoder.ShortMessageLength = S; rsDecoder.ShortMessageLength = S;```

Specify the field of ${\mathrm{GF}\left(2}^{6}\right)$ in the RS encoder/decoder System objects, by setting the `PrimitivePolynomialSource` property to '`Property'` and the `PrimitivePolynomial` property to a 6th degree primitive polynomial.

```primPolyDegree = 6; rsEncoder.PrimitivePolynomialSource = 'Property'; rsEncoder.PrimitivePolynomial = de2bi(primpoly(primPolyDegree,'nodisplay'),'left-msb'); rsDecoder.PrimitivePolynomialSource = 'Property'; rsDecoder.PrimitivePolynomial = de2bi(primpoly(primPolyDegree,'nodisplay'),'left-msb');```

Run Stream Processing Loop

Simulate the communications system for an uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio of 15 dB. The uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ is the ratio that would be measured at the input of the channel if there was no coding in the system.

The signal going into the AWGN channel is the encoded signal, so you must convert the uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values so that they correspond to the energy ratio at the encoder output. This ratio is the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio. If you input `K` symbols to the encoder and obtain `N` output symbols, then the energy relation is given by the `K`/`N` rate. he value of the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio needs to be adjusted to account for shortened and punctured codewords. The number of output symbols is (`N` - `numPuncs` - `S`) and the uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ ratio relates to the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ as shown below. Set the `EbNo` property of the AWGN channel object to the computed coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ value.

```EbNoCoded = EbNoUncoded + 10*log10(S/(N - numPuncs - K + S)); channel.EbNo = EbNoCoded;```

Loop until the simulation reaches the target number of errors or the maximum number of transmissions.

```chanErrorStats = zeros(3,1); codedErrorStats = zeros(3,1); correctedErrors = 0; while (codedErrorStats(2) < targetErrors) && ... (codedErrorStats(3) < maxNumTransmissions)```

The data symbols transmit one message word at a time. Each message word has K-`S` symbols in the [0 (2^`primPolyDegree`)-1] range.

` data = randi([0 2^primPolyDegree-1],S,1);`

Encode the shortened message word. The encoded word encData is (`N`-`numPuncs`-`S`) symbols long.

` encData = rsEncoder(data);`

Modulate encoded data and add noise. then demodulate channel output.

``` modData = qammod(encData,M); chanOutput = channel(modData); demodData = qamdemod(chanOutput,M);```

Use the helperRSCodingGetErasures.m helper function to find the 6 least reliable symbols and generate an erasures vector. The length of the erasures vector must be equal to the number of symbols in the demodulated codeword. A one in the ith element of the vector erases the ith symbol in the codeword. Zeros in the vector indicate no erasures.

` erasuresVec = helperRSCodingGetErasures(chanOutput,numErasures); `

Decode the data. Accumulate the number of corrected errors using the cumulative sum object.

``` [estData,errs] = rsDecoder(demodData,erasuresVec); if (errs >= 0) correctedErrors = cumulativeSum(errs); end```

When computing the channel and coded BERs, convert integers to bits.

``` chanErrorStats(:,1) = ... chanBERCalc(reshape(de2bi(encData,log2(M))',[],1), ... reshape(de2bi(demodData,log2(M))',[],1)); codedErrorStats(:,1) = ... codedBERCalc(reshape(de2bi(data,log2(M))',[],1), ... reshape(de2bi(estData,log2(M))',[],1)); end```

The error rate measurement objects, `chanBERCalc` and `codedBERCalc`, output 3-by-1 vectors containing BER measurement updates, the number of errors, and the total number of bit transmissions. Display the channel BER, the coded BER, and the total number of errors corrected by the RS decoder.

`chanBitErrorRate = chanErrorStats(1)`
```chanBitErrorRate = 0.0036 ```
`codedBitErrorRate = codedErrorStats(1)`
```codedBitErrorRate = 9.6599e-05 ```
`totalCorrectedErrors = correctedErrors`
```totalCorrectedErrors = 1436 ```

You can add a for loop around the processing loop above to run simulations for a set of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values. Simulations were run offline for uncoded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values in 4:15 dB, target number of errors equal to 5000, and maximum number of transmissions equal to $50×{10}^{6}$. This figure compares results achieved for

• RS coding with only erasures

• RS coding with erasures and puncturing

• RS coding with erasures, puncturing, and shotening

• Theoretical BER for 64-QAM

The channel BER with shortening because the coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ is ddegraded. This degraded coded ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ occurs because the code rate of the shortened code is lower than that of the nonshortened code. Shortening also results in degraded coded BER, most noticably at lower ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values.

Summary

This example utilized several System objects to simulate a 64-QAM communications system over an AWGN channel with a shortened RS block code. It showed how to configure the RS decoder to shorten a (63,53) code to a (28,18) code. System performance was measured using channel and coded BER curves obtained using error rate measurement System objects.

Helper functions used in this example:

## Algorithms

This object implements the algorithm, inputs, and outputs described in Algorithms for BCH and RS Errors-only Decoding.

## References

[1] Clark, George C., and J. Bibb Cain. Error-Correction Coding for Digital Communications. Applications of Communications Theory. New York: Plenum Press, 1981.