1、概述、 

1.1 编码器

图1 Turbo编码器结构图

如图1所示,LTE使用 1/3码率 的 Turbo编码器作为信道编码方案的基础。内部采用两个3阶 RSC编码器并联,并由交织器一分为二。Turbo编码器输出为以下3个部分:

  • 第一比特为系统比特;
  • 卷积编码器1输出 —— 奇偶校验1比特流;
  • 卷积编码器2输出 —— 奇偶校验2比特流;

卷积编码器均包含卷尾,因此 K bit 的比特流,Turbo编码器输出三个 (K+4)bit 的比特流,导致Turbo编码效率略低于 1/3.

1.2 交织

    LTE交织器由正交多项式序列(QPP)构成,交织器转换输入比特。输出比特指数 p(i) 和输入指数 i 的关系可以由下面的正交多项式表示:

                           p(i)=(f_1\cdot i\, +\, f_2\cdot i^2) \, mod\, (k)

K 和 f1, f2的关系,详细可参考:

Turbo编码原理及基本概念https://blog.csdn.net/snowman898/article/details/123818131

1.3  译码器 

    Turbo译码器使用两个后验概率(APP)译码器和两个交织器构成反馈环。Turbo译码器的计算复杂度与迭代次数直接相关。译码基本原理可参照:

Turbo译码原理说明(一)https://blog.csdn.net/snowman898/article/details/124318295

2、Matlab仿真实现

 2.1  编码Matlab实现

     我们使用通信系统工具箱的系统对象 comm.TurboEncoder 进行编码,并设置网络结构和交织器属性符合LTE标准定义。

function y = lte_TurboEncoder(u, intrlvrIndices)

persistent Turbo
if isempty(Turbo)
    Turbo = comm.TurboEncoder('TrellisStructure', poly2trellis(4, [13 15],13), ...
                 'InterleaverIndicesSource', 'Input port');
end

y = step(Turbo, u, intrlvrIndices);

 2.2  译码Matlab实现

    译码器实现时,函数同时调用交织指数(intrlvrIndices)以及 最大迭代次数(maxIter)两个参数作为输入。

function [y,flag,inters]  = lte_TurboDecoder(u, intrlvrIndices, maxIter)
MAXITER = 6;
persistent Turbo
if isempty(Turbo)
    Turbo = comm.TurboDecoder('TrellisStructure', poly2trellis(4, [13 15],13), ...
                     'InterleaverIndicesSource', 'Input port', 'MaximumIterations', MAXITER);
%                  'InterleaverIndicesSource', 'Input port', 'NumIterations', maxIter);
                             
end

[y,flag,inters] = step(Turbo, u, intrlvrIndices);

一般 LTE译码 5~7次较为合理,可以同时兼顾译码性能和计算复杂度。

其中 intrlvrIndices 详细代码如下:

function indices = lte_IntrlvrIndices(blkLen)
% codegen
[f1,f2] = getf1f2(blkLen);
Idx = (0:blkLen-1).';
indices = mod(f1*Idx + f2*Idx.^2, blkLen) + 1;
end

 2.2  BER测量

    Turbo译码的运算性能取决于迭代次数,对于一个给定的译码器,越高的迭代次数意味着越好的BER性能。代码如下所示:

function [ber, numBits] = chapter4_ex03_nIter(EbNo, maxNumErrs, maxNumBits, nIter)

persistent AWGN
AWGN = comm.AWGNChannel;

FRM = 2432;
R = FRM/(3*FRM+4*3);

Indices = lte_IntrlvrIndices(FRM);

% Modulation Mode 
ModulationMode = 1;          % 1--QPSK  2--QAM16  3-- QAM6
k = 2* ModulationMode;
snr = EbNo + 10*log10(k)+10*log10(R);

AWGN.EbNo = snr;
% Compute noise variance
noiseVar = 10.^(-snr/10);

% Processing loop: transmitter, channel model and receiver
numErrs = 0;  numBits = 0;
nS = 0;

while((numErrs < maxNumErrs) && (numBits < maxNumBits))
    % Transmitter
    u = randi([0,1], FRM, 1);
    t0 = lte_TurboEncoder(u,Indices);
    t1 = lte_Scrambler(t0, nS);
    t2 = lte_Modulator(t1, ModulationMode);
    
    % channel
    c0 = AWGN.step(t2);
    
    % Receiver
    r0 = lte_DemodulatorSoft(c0,ModulationMode, noiseVar);
    r1 = lte_DescramblerSoft(r0, nS); 

    y = lte_TurboDecoder(-r1, Indices, nIter);
    
    % Measurements
    numErrs =numErrs+ sum(y~=u);
    numBits = numBits + FRM;
    
    nS = nS + 2;
    nS = mod(nS, 20);
end

% Compute BER
ber = numErrs/numBits;

如果我们将迭代次数分别设置为1、3和5次,如下图所示:

图2  Turbo随着迭代次数增加性能改变

 2.3 Turbo译码早期终止机制

     Turbo译码器的迭代次数 是 Turbo译码器主要特性之一。LTE标准提供了一个有效途径,通过引入早期终止机制解决这一问题。通过对 Turbo编码器添加crc校验,可以在迭代译码结束时检出是否存在错误比特。若CRC不存在错误比特,可提前终止译码。这一方案可以大幅降低Turbo译码器计算复杂度,且不会带来性能损失。

考虑CRC排列顺序

    添加的CRC比特可以采用顺序或者逆序排列。UTRA采用CRC逆序排列,但在LTE研究中,逆序排列没有性能上的提高,却会增加系统处理的复杂度。因此,LTE采用顺序排列

考虑CRC处理方式

    当对较长的传输数据块进行分段时,一种选择是先对整个TB进行CRC处理,然后再进行分段处理,称为 TB CRC;另一是先进行分段处理,然后再对每个CB添加CRC校验处理,称为CB CRC。LTE选择的是两者结合,如下图所示:

图3-1  LTE CRC处理机制

 图3-2  LTE CRC具体实现过程

由图3-2可知,先将TB添加24bit crc校验,当传输块大于6144bit(maxCBlkLen = 6144,含crc),先进行码块分段,再在每个CB上添加 24 bit CRC校验。此方法可以有效降低高速率传输时译码的平均迭代次数。应注意的是,LTE采用不同的CRC多项式分别生成 CB CRC和TB CRC。

function [y, flag, iters]=lte_TurboDecoder_crc(u, intrlvrIndices)
%#codegen
maxIter=6;
persistent TurboCrc
if isempty(TurboCrc)
    TurboCrc = commLTETurboDecoder('InterleaverIndicesSource',  'Input port', ...
        'MaximumIterations', maxIter);
end
[y, flag, iters] = step(TurboCrc, u,  intrlvrIndices);

值得注意的是,commLTETurboDecoder这一函数原型只存在早期MATLAB版本中(R2015及以前),函数如下所示:

classdef commLTETurboDecoder < matlab.System %#ok<*EMCLS>
%commLTETurboDecoder Decode input using an early-terminating LTE turbo decoder.
%   H = commLTETurboDecoder creates an LTE turbo decoder System object, H.
%   This object uses the a-posteriori probability (APP) constituent decoder
%   to iteratively decode the parallel-concatenated convolutionally encoded
%   input data. It uses a CRC check for early decoder termination and
%   outputs only the message bits (minus the checksum) corresponding to the
%   code-block.
%
%   H = commLTETurboDecoder(Name, Value) creates an LTE turbo decoder
%   object, H, with the specified property Name set to the specified Value.
%   You can specify additional name-value pair arguments in any order as
%   (Name1, Value1, ... , NameN, ValueN).
%
%   H = commLTETurboDecoder(INTERLVRINDICES, MAXITER) creates an LTE turbo
%   decoder object, H, with the InterleaverIndices property set to

最终,我们给出包含早期终止机制的Turbo_crc译码:

function [ber, numBits]=chap4_ex04_crc(EbNo, maxNumErrs, maxNumBits)
%% Constants
clear functions;
FRM=2432-24; % Size of bit frame
Kplus=FRM+24;
Indices = lteIntrlvrIndices(Kplus);
ModulationMode=1;
k=2*ModulationMode;
CodingRate=Kplus/(3*Kplus+12);
snr = EbNo + 10*log10(k) + 10*log10(CodingRate);
noiseVar = 10.^(-snr/10);
%% Processsing loop modeling transmitter, channel model and receiver
numErrs = 0; numBits = 0; nS=0;
while ((numErrs < maxNumErrs) && (numBits < maxNumBits))
    % Transmitter
    u  =  randi([0 1], FRM,1);                % Randomly generated input bits
    data= CbCRCGenerator(u);                  % Transport block CRC code
    t0 = TurboEncoder(data, Indices);         % Turbo Encoder
    t1 = Scrambler(t0, nS);                   % Scrambler
    t2 = Modulator(t1, ModulationMode);       % Modulator

    % Channel
    c0 = AWGNChannel(t2, snr);                % AWGN channel

    % Receiver
    r0 = DemodulatorSoft(c0, ModulationMode, noiseVar);          % Demodulator
    r1 = DescramblerSoft(r0, nS);                                % Descrambler
    [y, ~, ~]  = TurboDecoder_crc(-r1, Indices);                 % Turbo Deocder

    % Measurements
    numErrs     = numErrs + sum(y~=u);        % Update number of bit errors
    numBits     = numBits + FRM;              % Update number of bits processed

    % Manage slot number with each subframe processed
    nS = nS + 2; nS = mod(nS, 20);
end

%% Clean up & collect results
ber = numErrs/numBits;                        % Compute Bit Error Rate (BER)

代码完整运行可自行下载:

LTETurbo编译码综合仿真-编解码文档类资源-CSDN下载1、Turbo设置最大迭代次数的编译码性能仿真,迭代次数分别设置为1/3/52、带早期终止机制的T更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/snowman898/85391832

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐