Main Content

ターボ符号化のための高レート畳み込み符号

連結畳み込み符号は高い信頼性を実現し、ターボ符号として注目されるようになり、使用率が増加しました。comm.TurboEncoderおよびcomm.TurboDecoderSystem object はレート 1/n 畳み込み符号のみをサポートします。この例では、comm.ConvolutionalEncoderおよびcomm.APPDecoderSystem object を使用することにより、効果的なレート 1/3 ターボ符号を達成するための 2 つのレート 2/3 畳み込み符号の並列連結を示します。

システム パラメーター

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

畳み込み符号化器/復号化器パラメーター

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

System object の初期化

畳み込み符号化、APP 復号化、BPSK 変調と復調、AGWN チャネル、およびエラー レート計算用の System object™ を初期化します。対数尤度比メソッドを使用して、復調は軟ビットを出力します。

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

フレーム処理ループ

Eb/N0 値の範囲全体をループして、BER 性能に対する結果を生成します。補助関数 helperTurboEnc および helperTurboDec は、ターボ符号化と復号化を実行します。

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

結果の表示

LTE や CCSDS などの実用無線システムではターボ符号用に基本レート 1/n の畳み込み符号を指定しますが、ターボ符号が実行可能になると、結果にはより高いレートの畳み込み符号の使用が示されます。

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']);

Figure contains an axes object. The axes object with title High Rate Convolutional Codes for Turbo Coding contains an object of type line. This object represents N = 1024, 3 iterations.

補助関数

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