初识LTE(四):LTE物理层编码全流程总结
零.代码地址
https://github.com/liu-zongxi/LTE_simulation
请大家看完觉得有用别忘了点赞收藏,github项目给star哦
一.代码流程的定性描述
发射机
LTE在进行发送之前,需要进行这些预处理(本次描述主要是针对业务信息的PDSCH信道)
-
生成数据,在真实系统中这就是需要发送的数据,仿真中我们一般会随机生成,数据的长度一定要是K_plus-24的倍数,这很重要,至于为什么我后续会补充在上一篇博客的码块分割内容中
-
添加CRC,在PDSCH中,我们使用的是CRC24,在尾部添加24个数据
- 这里简要说一下CRC,添加在后面的24位数后续在接收端应可以整除原数据+24个零,以此来验证没有发送错误,否则就要触发HARQ来重发
-
信道编码,进行码块操作,在PDSCH中,这里是以一个FRM来操作的,后面它会被映射到一个TB,所以也可以说是一个TB的操作,他的目的就是信道编码,减小误码率,它包含这么几部分
-
码块分割
码块分割的作用是为了匹配Turbo编码,因为Turbo编码的交织器要求输入要小于6144,如果输入小于6144则无需操作,大于则需要计算出
- 需要分割成几个码块
- 每个码块的长度是多少
这个在我上一篇博客中都可以找到答案,同时需要注意分割后的每一个码块都需要添加CRC
-
经过上诉操作,我们得到的数据就可以进行Turbo编码了,Turbo编码的结果是输出会增加四个比特,共增加4C个比特
-
之后是码率匹配,把当前Kplus长度的数据匹配到之前码块分割时计算好的比特,这个我的上一篇博客也已经详细描述了,LTE的码率一定要>1/3,也就是说最多冗余三倍,不可以更小,这是通过打孔实现的
-
以上就是一个TB处理的全过程,输入是一个长度为(K_plus-24)*24,输出长度则是(K_plus+4)*C/CodingRate
-
-
扰码,LTE使用的是31阶Gold码,它的具体原理也可以看我前面的博客,扰码输入输出长度不变,主要是增加保密性
-
调制,这就不赘述了
接收机
- 解调,这里是软解调,我的博客也介绍过了,通过距离来表示可靠度,越正就越可能是1,越负就越可能是0
- 解扰,异或的逆运算就是异或,软解扰则是通过*-1来解决,这我前面的博客也已经论述过了
- 信道解码,这里面包含了码块的处理和Turbo解码
- 首先进行码率解匹配,请看上一篇博客
- 然后进行解Turbo,这里涉及到自适应结束的问题,利用CRC检测,当CRC 检测正确时就可以提前结束,Turbo解码也是使用软比特的原因
- 验证CRC,完成接收
代码
最后附上代码,让各位看清楚
%% Constants
clear;clc;
prmLTE.maxIter = 6;
prmLTE.Rate = 1/3;
prmLTE.Mode = 1;
% 调制参数
ModulationMode=prmLTE.Mode; % QPSK
Mode_M_Mapping = [4 16 64];
M=Mode_M_Mapping(ModulationMode);
k=log2(M);
% Gold码参数
nS = 0; % 子帧索引起始
% Turbo码参数
nIters = 6; % Turbo解码迭代次数
FRM=2432-24; % Size of bit frame
Kplus=FRM+24;
Indices = lteIntrlvrIndices(Kplus);
maxIter = prmLTE.maxIter;
CodingRate = prmLTE.Rate;
% SNR设置
EbN0s = 0:0.2:2;
SNRs = EbN0s + 10*log10(k) + 10*log10(CodingRate);
nSNR = length(SNRs);
noiseVars = 10.^(-SNRs/10);
% 参数初始化
% 码率
maxNumErrs = 1e6;
maxNumBits = 1e6;
gss = ["-kx" "-^" "-ro" "-b>" "-g<" "-m+"]; % 画图图像,注意使用双引号
% Hist=dsp.Histogram('LowerLimit', 1, 'UpperLimit', maxIter, 'NumBins', maxIter, 'RunningHistogram', true);
array_iter = zeros(416, 1);
%% Processsing loop modeling transmitter, channel model and receiver
for iSNR = 1:nSNR
numErrs = 0; numBits = 0;
nS = 0;
snr = SNRs(iSNR);
noiseVar = noiseVars(iSNR);
num_while = 0;
while ((numErrs < maxNumErrs) && (numBits < maxNumBits))
num_while = num_while + 1;
% Transmitter
u = randi([0 1], FRM,1); % Randomly generated input bits
data= CbCRCGenerator(u); % Transport block CRC code
[t1, Kplus, C] = TbChannelCoding(data,prmLTE); % Transport Channel encoding
t2 = Scrambler(t1, nS); % Scrambler
t3 = Modulator(t2, ModulationMode); % Modulator
% Channel
c0 = AWGNChannel(t3, snr); % AWGN channel
% Receiver
r0 = DemodulatorSoft(c0, ModulationMode, noiseVar); % Demodulator
r1 = DescramblerSoft(r0, nS); % Descrambler
r2= TbChannelDecoding(r1, Kplus, C, prmLTE); % Transport Channel decoding
y = CbCRCDetector(r2); % Code block CRC dtector
% 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
ber = numErrs/numBits; % Compute Bit Error Rate (BER)
BERs(iSNR) = ber
end
semilogy(EbN0s, BERs(:), gs);
%% Clean up & collect results
% ber = numErrs/numBits; % Compute Bit Error Rate (BER)