Error Correction Coding: Part 5
Error Correction Coding: Part 5
Reed-Solomon Codes
Eric DeFelice
Department of Electrical Engineering
Rochester Institute of Technology
ebd9423@rit.edu
Abstract Reed-Solomon codes are block based cyclic errorcorrecting codes that are implemented by using many of the
techniques and concepts that were introduced previously. These
codes are used in a variety of applications, including storage
device systems and communications systems.
They are
particularly good at correcting burst errors in a system. This is a
desirable feature, as many other codes are adept at correcting
random errors, so Reed-Solomon codes can be used in
conjunction with these other codes to form a very reliable errorcorrection system.
In this paper, an introduction of Reed-Solomon codes will be
presented, and the properties of this code will be looked at. Since
Reed-Solomon codes are linear block codes, we will not go over
the specifics of the encoder and decoder, as we have already
looked at linear block codes in depth previously. Matlab
examples of Reed-Solomon codes will be looked at to show the
codes performance. Puncturing and shortening will then be
introduced, and simulations of these concepts will be looked at to
see their effect on the communications system.
I.
INTRODUCTION
MATLAB SIMULATIONS
10
-2
10
BER
-3
10
Uncoded System
RS(63,53) System
RS(63,53) System with 2 punctures
-4
10
9
10
SNR in dB
11
12
13
14
15
-1
10
-2
BER
10
-3
10
Uncoded System
RS(63,53) System
4
9
10
SNR in dB
11
12
13
14
15
This figure shows that the BER does increase a little bit
when two of the parity symbols are punctured. This is
expected as we now have less error correction as well as fewer
data bits per block when compared to the un-coded system.
The final simulation was done to look at the effects of
shortening the RS code. For this simulation, the RS(63,53)
code was shortened by 35 symbols, so to make it similar to an
RS(28,18) code. In theory this code should provide good error
correction, but would have worse data rate, as we have many
more parity symbols per data symbols now. Also to make this
work, the encoder must encode the symbols still using a
generator in the GF(26) field, and the random symbols must be
selected from that field as well. The results from this
simulation are seen in figure 3.
10
-2
10
-3
BER
10
-4
10
Uncoded System
RS(63,53) System
RS(63,53) System with 2 punctures
RS(63,53) System shortened by 35 symbols
-5
10
9
10
SNR in dB
11
12
13
14
15
CONCLUSION
[3]
[4]
APPENDIX
%% Error correction coding : Weeks 9-10
%% Reed-Solomon coding
close all;
clear all;
clc;
%% Initialize variables
% Set the simulation stop criteria by defining the target number of errors
% and maximum number of transmissions.
targetErrors = 500;
maxNumTransmissions = 5e6;
% Simulate the encoder over a range of SNRs
EbNoUncoded = 4:15;
% Define variables for coded and uncoded BER
codedBER = zeros(1,length(EbNoUncoded));
uncodedBER = zeros(1,length(EbNoUncoded));
% Perform the simulations over the range of SNRs
for i=1:length(EbNoUncoded)
%64-QAM Modulator variables
M = 64; % Modulation order
% Setup modem to 6-bit, gray coded, with integer input/output
hMod
= comm.RectangularQAMModulator(M, 'SymbolMapping', 'Gray',...
'BitInput', false);
hDemod = comm.RectangularQAMDemodulator(M, 'SymbolMapping', 'Gray',...
'BitOutput', false);
% AWGN Channel variables
% Channel model
hChan = comm.AWGNChannel('NoiseMethod', 'Signal to noise ratio (Eb/No)');
% There is no up/down-sampling, and set signal power to 42 Watts.
hChan.SamplesPerSymbol = 1;
hChan.SignalPower = 42;
% Set the bits per symbol to log2(M) or 6 bps for 64-QAM
hChan.BitsPerSymbol = log2(M);
% Error rate measurement variables
% Objects for channel BER and coded BER
hChanBERCalc = comm.ErrorRate;
hCodedBERCalc = comm.ErrorRate;
% Integer to bit converters for 64-QAM
hIntToBit1 = comm.IntegerToBit('BitsPerInteger', log2(M));
hIntToBit2 = comm.IntegerToBit('BitsPerInteger', log2(M));
% Cumulative sum object to count the number of error symbols corrected by
% Reed-Solomon decoder
hCumSum = dsp.CumulativeSum;
% Reed-Solomon encoder
% Use a code with 53 message symbols and 10 parity symbols, so the total codeword
% is 63 symbols
N = 63;
K = 53;
hEnc = comm.RSEncoder(N,K, 'BitInput', false);
% Reed-Solomon Decoder
hDec = comm.RSDecoder(N,K, 'BitInput', false, 'ErasuresInputPort', true);
hDec.NumCorrectedErrorsOutputPort = true;
% We will correct symbols by picking out the least reliable ones and
% marking them as erasures. This variable sets how many erasures we will
% declare.
numErasures = 6;
% Set the coded SNR to the uncoded SNR minus the noise from the code bits
% This is because there are extra redundant bits that only increase the
% noise power and not the signal power, as they don't contain data
EbNoCoded = EbNoUncoded(i) + 10*log10(K/N);
hChan.EbNo = EbNoCoded;
% Perform coding and decoding until the target number of errors has occurred
% or until the maximum number of transmissions has occurred
chanErrorStats = zeros(3,1);
codedErrorStats = zeros(3,1);
correctedErrors = 0;
while (codedErrorStats(2) < targetErrors) && ...
(codedErrorStats(3) < maxNumTransmissions)
% Data symbols - transmit 1 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 symbols long.
encData = step(hEnc, data);
% Modulate encoded data.
modData = step(hMod, encData);
% Send the modulated data through the AWGN channel model.
chanOutput = step(hChan, modData);
% Demodulate channel output.
demodData = step(hDemod, chanOutput);
% Find the 6 least reliable symbols and generate an erasures vector using
% the getErasuresRSCodingDemo function. A one in the ith element of the
% vector erases the ith symbol in the codeword.
% Zeros in the vector indicate no erasures.
erasuresVec = getErasuresRSCodingDemo(chanOutput,numErasures);
% Decode data using the decoder, the demodulated data and the erasures
% vector
[estData errs] = step(hDec, demodData, erasuresVec);
% Accumulate the number of corrected errors using the cumulative sum object.
if errs >= 0
correctedErrors = step(hCumSum, errs);
end
% Convert integers to bits and compute the channel BER.
chanErrorStats(:,1) = ...
step(hChanBERCalc,step(hIntToBit1,encData),step(hIntToBit1,demodData));
% Convert integers to bits and compute the coded BER.
codedErrorStats(:,1) = ...
step(hCodedBERCalc,step(hIntToBit2,data),step(hIntToBit2,estData));
end
% Set the BER for the current SNR
codedBER(i) = codedErrorStats(1);
uncodedBER(i) = chanErrorStats(1);
end
% Plot the BER vs SNR
semilogy(EbNoUncoded,uncodedBER,'m-','linewidth',2.0);
hold on
semilogy(EbNoUncoded,codedBER,'b-','linewidth',2.0);
title('64-QAM with Reed-Solomon coding over AWGN Simulation');xlabel('SNR in dB');ylabel('BER');
legend('Uncoded System','RS(63,53) System');
%axis tight
%grid
%% Perform simulations with puncturing
% Define variables for coded and uncoded BER
codedBER_w_punc = zeros(1,length(EbNoUncoded));
% Perform the simulations over the range of SNRs
for i=1:length(EbNoUncoded)
%64-QAM Modulator variables
hCodedBERCalc = comm.ErrorRate;
% Integer to bit converters for 64-QAM
hIntToBit1 = comm.IntegerToBit('BitsPerInteger', log2(M));
hIntToBit2 = comm.IntegerToBit('BitsPerInteger', log2(M));
% Cumulative sum object to count the number of error symbols corrected by
% Reed-Solomon decoder
hCumSum = dsp.CumulativeSum;
% Reed-Solomon encoder
% Use a code with 53 message bits and 10 parity bits, so the total codeword
% is 63 bits
N = 63;
K = 53;
hEnc = comm.RSEncoder(N,K, 'BitInput', false);
% Reed-Solomon Decoder
hDec = comm.RSDecoder(N,K, 'BitInput', false, 'ErasuresInputPort', true);
hDec.NumCorrectedErrorsOutputPort = true;
% We will correct symbols by picking out the least reliable ones and
% marking them as erasures. This variable sets how many erasures we will
% declare.
numErasures = 6;
% Shorten the code by 35 symbols
% This would give us a RS(28,18) code, so much more parity symbols per data
% symbols
shortenLength = 35;
% Set the shortened codeword length and message length values
hEnc.CodewordLength = N - shortenLength;
hEnc.MessageLength = K - shortenLength;
hDec.CodewordLength = N - shortenLength;
hDec.MessageLength = K - shortenLength;
% We need to updated the primitive polynomial at the encoder so that it
% knows that the original code is an RS(63,53) code. We set the primitive
% polynomial to be in the GF(2^6) field to show this.
hEnc.PrimitivePolynomialSource = 'Property';
hEnc.PrimitivePolynomial = de2bi(primpoly(6, 'nodisplay'), 'left-msb');
hDec.PrimitivePolynomialSource = 'Property';
hDec.PrimitivePolynomial = de2bi(primpoly(6, 'nodisplay'), 'left-msb');
% Set the coded SNR to the uncoded SNR minus the noise from the code bits
% This is because there are extra redundant bits that only increase the
% noise power and not the signal power, as they don't contain data
EbNoCoded = EbNoUncoded(i) + 10*log10((K-shortenLength)/(N-shortenLength));
hChan.EbNo = EbNoCoded;
% Perform coding and decoding until the target number of errors has occurred
% or until the maximum number of transmissions has occurred
chanErrorStats = zeros(3,1);
codedErrorStats = zeros(3,1);
correctedErrors = 0;
while (codedErrorStats(2) < targetErrors) && ...
(codedErrorStats(3) < maxNumTransmissions)
% Data symbols - transmit 1 message word at a time. Each message word has
% K symbols in the [0 N] range. We now need to specify N to be 2^6-1
% because we have changed the code length.
data = randi([0 2^6-1],K-shortenLength,1);
% Encode the message word. The encoded word encData is N symbols long.
encData = step(hEnc, data);
% Modulate encoded data.
modData = step(hMod, encData);