LTE物理层概述(7)-- LTE之Turbo编码及其matlab仿真1
LTE 信道编码 Turbo Matlab仿真
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 的关系可以由下面的正交多项式表示:
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)
代码完整运行可自行下载:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)