“原文 Understanding LTE with MATLAB ,作者Houman Zarrinkoub,本文是对于该书的翻译,书中的专业性词汇给出了英文原文,图和表的排版都是参考原文,翻译不准确的地方请读者多多包涵。
本文仅限于个人学习,研究,交流,不得用于其他商业用途!”

4.3 信道编码
到目前为止,我们已经讨论了在物理信道处理中执行的调制和加扰操作。现在我们将结合TrCH处理,即信道编码,与调制和加扰。我们将介绍基于turbo编码的纠错编码和以CRC检测为代表的错误检测机制。表4.3总结了各种TrCH的信道编码方案。除了基于卷积编码的广播信道(BCH)外,大多数物理信道都采用turbo编码。

Turbo编码是LTE标准中规定的信道编码的基础。尽管turbo编码在许多以前的标准中已经被使用,但是它一直被视为与其他卷积编码方案一起的可选组件。然而,在LTE中,turbo编码是信道编码机制的驱动部件。基于我们的教学方法,我们将逐步建立LTE标准的TrCH处理,分五个步骤。首先,我们以1/3的编码率实现turbo编码算法。然后在Turbo译码器中加入早期终止机制。这使得Turbo解码器的计算复杂度可扩展。然后,我们介绍速率匹配操作,它通过对1/3速率涡轮编码器输出进行操作来提供任意给定速率的编码。介绍了与子块分割和码字重构相关的功能。最后,将所有组件放在一起,实现TrCH处理的处理链。在这本书中,我们省略了与HARQ处理相关的MATLAB函数的介绍。HARQ处理非常重要,因为它本质上减少了重传次数,并且提高了传输块错误检测之后的性能。这个省略符合我们声明的范围,该范围关注于稳态用户平面处理。
4.4 Turbo 编码
Turbo编码器属于称为并行级联卷积编码的一类信道编码算法[2]。顾名思义,turbo码是通过并行连接两个传统编码器并通过交织器将它们分开而形成的。LTE中Turbo码的选择受到多种因素的影响。首先是Turbo编码器的近香农约束性能。在turbo译码中,给定足够的迭代次数,turbo码可以具有远远超过传统卷积编码器的误码性能。此外,由于采用了创新的速率匹配机制,Turbo编码的适用性稍后再做讨论。
4.4.1 Turbo编码器
LTE采用基本速率为1/3的turbo编码作为其信道编码方案的基石,如图4.3所示:

LTE涡轮编码器基于由内部交织器分离的两个8状态分量编码器的并行级联。Turbo编码器的输出由三个码流组成。第一流的位通常被称为系统位。第二和第三流的比特——即两个组成编码器的输出——通常分别称为奇偶校验1和奇偶校验2比特流。每个组成编码器独立地由尾部比特终止。这意味着对于K位的输入块大小,由于网格终止,涡轮编码器的输出由三个长度为K+4位的流组成。这使得Turbo编码器的编码率略小于1/3。由于在每个流的末尾多路复用尾比特,所以系统位和奇偶校验1和奇偶校验2比特流都具有大小K+4。
为了完全指定turbo编码器,我们需要指定组成编码器和turbo代码内部交织器的网格结构。LTE交织器是基于一个简单的二次多项式置换(QPP)方案。交织器置换输入比特的索引。输出索引p(i)和输入索引i之间的关系由以下二次多项式表达式描述:

其中K是输入块的大小,f1和f2是取决于K值的常数。LTE允许输入块大小K为188个不同的值。最小块大小为40,最大块大小为6144。这些块大小和相应的f1和f2常数在文献[3]中进行了总结。
LTE turbo编码器是使用QPP交织器的无竞争编码器,它通过在交织操作中对存储器访问进行流线化来显著改善turbo码的性能。组成编码器的网格结构由以下两个多项式描述:

这描述了一个1/3 Turbo编码器,具有四个状态,并且在每个组成编码器处具有网格结构,由前馈和反馈连接多项式表示,八度值分别为13和15。
4.4.2 Turbo 解码器
在接收机中,turbo解码器将turbo编码器执行的操作反相。turbo译码器基于两个校验位(APP)译码器和反馈环路中的两个交织器的使用。在APP解码器中使用在turbo编码器中发现的相同的网格结构,以及相同的交织器。不同之处在于turbo解码是一种迭代操作。turbo译码器的性能和计算复杂度直接关系到所执行的迭代次数。
在接收机处,turbo解码器执行turbo编码器的逆操作。通过处理其输入信号,即解调和解扰器的输出,turbo解码器将恢复TrCH传输比特的最佳估计。请注意,Turbo解码器输入需要在LLRs中表示。如前所述,如果执行软判决解调,则解调器生成LLR。
4.4.3 MATLAB 例子
下面的两个MATLAB函数显示了LTE的Turobo码器和解码器的实现及其所有规范,使用通信系统工具箱的系统对象。在TurboEncoder函数中,我们使用comm.TurboEncoder系统对象,设置网格结构和交织器属性,以实现LTE标准中指定的功能。通过调用系统对象的step方法,对输入比特进行处理,生成Turbo编码比特作为输出。
1function y=TurboEncoder(u, intrlvrIndices)
2%#codegen
3persistent Turbo
4if isempty(Turbo)
5 Turbo = comm.TurboEncoder('TrellisStructure', poly2trellis(4, [13 15], 13), ...
6 'InterleaverIndicesSource','Input port');
7end
8y=step(Turbo, u, intrlvrIndices);
9end
类似地,TurboDecoder函数对其第一输入信号(u)进行操作,该信号是解调器和解扰器的LLR输出。Turbo解码器将恢复发送比特的最佳估计。该函数还将交织索引(intrlvrIndices)和解码器中使用的最大迭代次数(maxIter)作为输入。
1function y=TurboDecoder(u, intrlvrIndices, maxIter)
2%#codegen
3persistent Turbo
4if isempty(Turbo)
5 Turbo = comm.TurboDecoder('TrellisStructure', poly2trellis(4, [13 15], 13),...
6 'InterleaverIndicesSource','Input port', ...
7 'NumIterations', maxIter);
8end
9y=step(Turbo, u, intrlvrIndices);
10end
为了设置网格结构,我们使用通信系统工具箱的 ploy2trellis() 函数。由于LTE网格结构同时具有前馈和反馈连接多项式,我们首先建立多项式的二进制数表示,然后将二进制表示转换成八进制表示。通过查看图4.3中的涡轮编码器的框图,我们可以看出该编码器具有约束长度为4、生成器多项式矩阵为[1315]和反馈连接多项式为13。因此,为了设置网格结构,我们需要使用poly2trellis(4,[1315],13)函数。
为了构建基于QPP方案的LTE交织器,我们使用lteIntrlvrIndices() 函数。该函数基于仅允许的188个输入大小查找LTE交织器表,找到相应的f1和f2常数,并按照标准中的描述计算置换向量。
1function indices = lteIntrlvrIndices(blkLen)
2%#codegen
3
4[f1, f2] = getf1f2(blkLen);
5Idx = (0:blkLen-1).';
6indices = mod(f1*Idx + f2*Idx.^2, blkLen) + 1;
8end
9
其中comm.TurboEncoder和comm.TurboDecoder系统对象是基于直接MATLAB实现来表达算法的对象。因此,使用MATLAB编辑命令,我们可以检查每次使用这些系统对象时执行的MATLAB代码。基于MATLAB的系统对象的创建和创作超出了本书的范围;有关此主题的更多信息,请参考MATLAB文档[4]。为了说明MATLAB实现如何符合我们的期望,我们可以检查这个系统对象的stepimpl函数。
comm.TurboEncoder stepimpl函数执行两个卷积编码操作,首先针对输入信号,然后针对信号的交织版本。然后它捕获与网格终止相关的额外样本并将它们附加到Systematic和Parity流的末尾。comm.TurboDecoder stepimpl重复一系列操作,包括两个APP解码器和交织器,N次。N值对应于turbo解码器中的最大迭代次数。在每个处理迭代结束时,turbo解码器使用结果更新其最佳估计。
4.4.4 误码率测量
任何turbo编码器的性能取决于在解码操作中执行的迭代次数。这意味着,对于给定的涡轮编码器(例如,LTE标准中指定的编码器),随着迭代次数的增加,BER性能逐渐变好。函数chap4_ex03_nIter通过计算作为迭代次数的函数的BER性能来说明这一点。
1function [ber, numBits]=chap4_ex03_nIter(EbNo, maxNumErrs, maxNumBits, nIter)
2%% Constants
3clear functions;
4FRM=2432; % Size of bit frame
5Indices = lteIntrlvrIndices(FRM);
6M=4;k=log2(M);
7R= FRM/(3* FRM + 4*3);
8snr = EbNo + 10*log10(k) + 10*log10(R);
9noiseVar = 10.^(-snr/10);
10ModulationMode=1; % QPSK
11%% Processsing loop modeling transmitter, channel model and receiver
12numErrs = 0; numBits = 0; nS=0;
13while ((numErrs < maxNumErrs) && (numBits < maxNumBits))
14 % Transmitter
15 u = randi([0 1], FRM,1); % Randomly generated input bits
16 t0 = TurboEncoder(u, Indices); % Turbo Encoder
17 t1 = Scrambler(t0, nS); % Scrambler
18 t2 = Modulator(t1, ModulationMode); % Modulator
19 % Channel
20 c0 = AWGNChannel(t2, snr); % AWGN channel
21 % Receiver
22 r0 = DemodulatorSoft(c0, ModulationMode, noiseVar); % Demodulator
23 r1 = DescramblerSoft(r0, nS); % Descrambler
24 y = TurboDecoder(-r1, Indices, nIter); % Turbo Deocder
25 % Measurements
26 numErrs = numErrs + sum(y~=u); % Update number of bit errors
27 numBits = numBits + FRM; % Update number of bits processed
28 % Manage slot number with each subframe processed
29 nS = nS + 2; nS = mod(nS, 20);
30end
31%% Clean up & collect results
32ber = numErrs/numBits; % Compute Bit Error Rate (BER)
33
为了比较turbo编码器和传统卷积编码器的性能,我们还运行了一个名为chap4_ex03_viterbi.m的函数,它使用了1/3速率的卷积编码器、Viterbi解码器和软判决解调。
1function [ber, numBits]=chap4_ex03_viterbi(EbNo, maxNumErrs, maxNumBits)
2%% Constants
3FRM=2432; % Size of bit frame
4M=4;k=log2(M);
5R= FRM/(3* (FRM+6));
6snr = EbNo + 10*log10(k) + 10*log10(R);
7noiseVar = 10.^(-snr/10);
8ModulationMode=1; % QPSK
9%% Processsing loop modeling transmitter, channel model and receiver
10numErrs = 0; numBits = 0; nS=0;
11while ((numErrs < maxNumErrs) && (numBits < maxNumBits))
12 % Transmitter
13 u = randi([0 1], FRM,1); % Randomly generated input bits
14 t0 = ConvolutionalEncoder(u); % Convolutional Encoder
15 t1 = Scrambler(t0, nS); % Scrambler
16 t2 = Modulator(t1, ModulationMode); % Modulator
17 % Channel
18 c0 = AWGNChannel(t2, snr); % AWGN channel
19 % Receiver
20 r0 = DemodulatorSoft(c0, ModulationMode, noiseVar); % Demodulator
21 r1 = DescramblerSoft(r0, nS); % Descrambler
22 r2 = ViterbiDecoder(r1); % Viterbi Deocder
23 y=r2(1:FRM);
24 % Measurements
25 numErrs = numErrs + sum(y~=u); % Update number of bit errors
26 numBits = numBits + FRM; % Update number of bits processed
27 % Manage slot number with each subframe processed
28 nS = nS + 2; nS = mod(nS, 20);
29end
30%% Clean up & collect results
31ber = numErrs/numBits; % Compute Bit Error Rate (BER)
32end
33
图4.4比较了当使用Turbo解码的一次、三次或五次迭代与同样编码速率的典型维特比解码器时Turbo解码器的BER性能。随着迭代次数从1次增加到3次,然后增加到5次,我们看到BER曲线的形状反映了Turbo译码器的近最佳质量。该曲线在E/N一定值后呈现陡峭的斜率,例如,以5次迭代为最大迭代次数,结合QPSK和软判决解调器的LTE turbo解码器能够达到1.25dB的信噪比值2e_4。

图4.4 不同迭代次数情况下的Turbo编码与卷积编码误码率对比图
turbo编码的这种性能特征可以解释为什么在LTE标准中turbo编码被选择作为用户数据的强制信道编码机制。
通过执行以下脚本(chap4_ex03_nIter),我们可以测量作为迭代次数的函数的收发器计算时间。计算时间是对turbo编码和解码操作的计算复杂度的估计。
1%% Computation time of turbo coder
2%% as a function of number of iterations
3EbNo=1;
4maxNumErrs=1e6;
5maxNumBits=1e6;
6for nIter=1:6
7 clear functions
8 tic;
9 ber=chap4_ex03_nIter(EbNo, maxNumErrs, maxNumBits , nIter);
10 toc;
11end
12
表4.4总结了结果。如预期的,复杂度以及因此完成解码操作所需的时间与迭代次数成正比。

为了了解什么函数对我们迄今为止开发的收发器(chap4_ex03_nIter)的复杂性贡献最大,我们执行以下分析脚本。
1%% Profiling the turbo coder system model
2EbNo=1;
3maxNumErrs=1e6;
4maxNumBits=1e6;
5profile on
6ber=chap4_ex03_nIter(EbNo, maxNumErrs, maxNumBits , 1);
7profile viewer
系统模型的每行的执行时间总结在图4.5所示的分析报告中。

结果表明,采用固定的迭代值进行Turbo译码约占整个系统仿真时间的86%。因此,Turbo译码器被认为是系统的瓶颈之一。为了克服这个问题,LTE标准在LTE编码器中提供了一种机制,该机制使得能够尽早终止Turbo译码,而不会对Turbo译码的性能产生严重影响。这种早期终止机制将在下一节中讨论。
未完待续
2018/12/2
