High Rate Convolutional Codes for Turbo Coding
Concatenated convolutional codes offer high reliability and have gained in prominence and usage as turbo codes. The comm.TurboEncoder
and comm.TurboDecoder
System objects support rate 1/n convolutional codes only. This example shows the parallel concatenation of two rate 2/3 convolutional codes to achieve an effective rate 1/3 turbo code by using comm.ConvolutionalEncoder
and comm.APPDecoder
System objects.
System Parameters
blkLength = 1024; % Block length EbNo = 0:5; % Eb/No values to loop over numIter = 3; % Number of decoding iterations maxNumBlks = 1e2; % Maximum number of blocks per Eb/No value
Convolutional Encoder/Decoder Parameters
trellis = poly2trellis([5 4],[23 35 0; 0 5 13]); k = log2(trellis.numInputSymbols); % number of input bits n = log2(trellis.numOutputSymbols); % number of output bits intrIndices = randperm(blkLength/k)'; % Random interleaving decAlg = 'True App'; % Decoding algorithm modOrder = 2; % PSK-modulation order
Initialize System Objects
Initialize Systems object™ for convolutional encoding, APP Decoding, BPSK modulation and demodulation, AWGN channel, and error rate computation. The demodulation output soft bits using a log-likelihood ratio method.
cEnc1 = comm.ConvolutionalEncoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated'); cEnc2 = comm.ConvolutionalEncoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated'); cAPPDec1 = comm.APPDecoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated', ... 'Algorithm',decAlg); cAPPDec2 = comm.APPDecoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated', ... 'Algorithm',decAlg); bpskMod = comm.BPSKModulator; bpskDemod = comm.BPSKDemodulator( ... 'DecisionMethod','Log-likelihood ratio', ... 'VarianceSource','Input port'); awgnChan = comm.AWGNChannel( ... 'NoiseMethod','Variance', ... 'VarianceSource','Input port'); bitError = comm.ErrorRate; % BER measurement
Frame Processing Loop
Loop through a range of values to generate results for BER performance. The helperTurboEnc
and helperTurboDec
helper functions perform the turbo encoding and decoding.
ber = zeros(length(EbNo),1); bitsPerSymbol = log2(modOrder); turboEncRate = k/(2*n); for ebNoIdx = 1:length(EbNo) % Calculate the noise variance from EbNo EsNo = EbNo(ebNoIdx) + 10*log10(bitsPerSymbol); SNRdB = EsNo + 10*log10(turboEncRate); % Account for code rate noiseVar = 10^(-SNRdB/10); for numBlks = 1:maxNumBlks % Generate binary data data = randi([0 1],blkLength,1); % Turbo encode the data [encodedData,outIndices] = helperTurboEnc( ... data,cEnc1,cEnc2, ... trellis,blkLength,intrIndices); % Modulate the encoded data modSignal = bpskMod(encodedData); % Pass the modulated signal through an AWGN channel receivedSignal = awgnChan(modSignal,noiseVar); % Demodulate the noisy signal using LLR to output soft bits demodSignal = bpskDemod(receivedSignal,noiseVar); % Turbo decode the demodulated data receivedBits = helperTurboDec( ... -demodSignal,cAPPDec1,cAPPDec2, ... trellis,blkLength,intrIndices,outIndices,numIter); % Calculate the error statistics errorStats = bitError(data,receivedBits); end ber(ebNoIdx) = errorStats(1); reset(bitError); end
Display Results
While the practical wireless systems, such as LTE and CCSDS, specify base rate-1/n convolutional codes for turbo codes, the results show use of higher rate convolutional codes as turbo codes is viable.
figure; semilogy(EbNo, ber, '*-'); grid on; xlabel('E_b/N_0 (dB)'); ylabel('BER'); title('High Rate Convolutional Codes for Turbo Coding'); legend(['N = ' num2str(blkLength) ', ' num2str(numIter) ' iterations']);
Helper Functions
function [yEnc,outIndices] = helperTurboEnc( ... data,hCEnc1,hCEnc2,trellis,blkLength,intrIndices) % Turbo encoding using two parallel convolutional encoders. % No tail bits handling and assumes no output stream puncturing. % Trellis parameters k = log2(trellis.numInputSymbols); n = log2(trellis.numOutputSymbols); cLen = blkLength*n/k; punctrVec = [0;0;0;0;0;0]; % assumes all streams are output N = length(find(punctrVec==0)); % Encode random data bits y1 = hCEnc1(data); y2 = hCEnc2( ... reshape(intrlv(reshape(data,k,[])',intrIndices)',[],1)); y1D = reshape(y1(1:cLen),n,[]); y2D = reshape(y2(1:cLen),n,[]); yDTemp = [y1D; y2D]; y = yDTemp(:); % Generate output indices vector using puncturing vector idx = 0 : 2*n : (blkLength - 1)*2*(n/k); punctrVecIdx = find(punctrVec==0); dIdx = repmat(idx, N, 1) + punctrVecIdx; outIndices = dIdx(:); yEnc = y(outIndices); end function yDec = helperTurboDec( ... yEnc,cAPPDec1,cAPPDec2,trellis, ... blkLength,intrIndices,inIndices,numIter) % Turbo decoding using two a-posteriori probability (APP) decoders % Trellis parameters k = log2(trellis.numInputSymbols); n = log2(trellis.numOutputSymbols); rCodLen = 2*(n/k)*blkLength; typeyEnc = class(yEnc); % Re-order encoded bits according to outIndices x = zeros(rCodLen,1); x(inIndices) = yEnc; % Generate output of first encoder yD = reshape(x(1:rCodLen),2*n,[]); lc1D = yD(1:n, :); Lc1_in = lc1D(:); % Generate output of second encoder lc2D = yD(n+1:2*n, :); Lc2_in = lc2D(:); % Initialize unencoded data input Lu1_in = zeros(blkLength,1,typeyEnc); % Turbo Decode out1 = zeros(blkLength/k,k,typeyEnc); for iterIdx = 1 : numIter [Lu1_out, ~] = cAPPDec1(Lu1_in,Lc1_in); tmp = Lu1_out(1:blkLength); Lu2_in = reshape(tmp,k,[])'; [Lu2_out, ~] = cAPPDec2( ... reshape(Lu2_in(intrIndices, :)',[],1),Lc2_in); out1(intrIndices, :) = reshape(Lu2_out(1:blkLength),k,[])'; Lu1_in = reshape(out1',[],1); end % Calculate llr and decoded bits for the final iteration llr = reshape(out1', [], 1) + Lu1_out(1:blkLength); yDec = cast((llr>=0), typeyEnc); end