初识LTE(二):LTE中的调制和编码技术
一.调制与解调
1.调制
LTE中调制用到的就是QPSK还有QAM
调制非常简单,这里不详细说了,利用matlab自带的各种函数都可以实现
%--------------------------数字信号QAM调制--------------------%
%-----------------------author:lzx-------------------------%
%-----------------------date:2022年6月20日15点01分-----------------%
function y=Modulator(u, Mode)
%% Initialization
% 调用了调制函数
% SymbolMapping选择使用格雷码或是自己定义
% CustomSymbolMapping决定定义的内容
persistent QPSK QAM16 QAM64
if isempty(QPSK)
QPSK = comm.PSKModulator(4, 'BitInput', true, ...
'PhaseOffset', pi/4, 'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', [0 2 3 1]);
QAM16 = comm.RectangularQAMModulator(16, 'BitInput',true,...
'NormalizationMethod','Average power',...
'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', [11 10 14 15 9 8 12 13 1 0 4 5 3 2 6 7]);
QAM64 = comm.RectangularQAMModulator(64, 'BitInput',true,...
'NormalizationMethod','Average power',...
'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', [47 46 42 43 59 58 62 63 45 44 40 41 ...
57 56 60 61 37 36 32 33 49 48 52 53 39 38 34 35 51 50 54 55 7 ...
6 2 3 19 18 22 23 5 4 0 1 17 16 20 21 13 12 8 9 25 24 28 29 15 ...
14 10 11 27 26 30 31]);
end
%% Processing
switch Mode
case 1
y=step(QPSK, u);
case 2
y=step(QAM16, u);
case 3
y=step(QAM64, u);
otherwise
error('Invalid Modulation Mode. Use {1,2, or 3}');
end
2.解调
解调是值得拿出来说说的,因为LTE使用了LLR软解调,这是之前没有接触过的,网上也没有很多资料,这里我在一篇硕博士论文里看到的解释分享出来给大家
看完这个大家应该很明白是在做什么了吧,计算过程就是找出 最近的零点和最近的一点的差,这个值越大,这个比特为0的概率就越大,越负则为1的概率就越大,即他自带了可能性的信息.
function y = DescramblerHard(u, nS)
% Downlink descrambling
persistent hSeqGen hInt2Bit;
if isempty(hSeqGen)
maxG=43200;
hSeqGen = comm.GoldSequence('FirstPolynomial',[1 zeros(1, 27) 1 0 0 1],...
'FirstInitialConditions', [zeros(1, 30) 1], ...
'SecondPolynomial', [1 zeros(1, 27) 1 1 1 1],...
'SecondInitialConditionsSource', 'Input port',...
'Shift', 1600,...
'VariableSizeOutput', true,...
'MaximumOutputSize', [maxG 1]);
% hInt2Bit = comm.IntegerToBit('BitsPerInteger', 31);
end
% Parameters to compute initial condition
RNTI = 1;
NcellID = 0;
q=0;
% Initial conditions
c_init = RNTI*(2^14) + q*(2^13) + floor(nS/2)*(2^9) + NcellID;
% Convert to binary vector
% iniStates = step(hInt2Bit, c_init);
iniStates = int2bit(c_init, 31);
% Generate scrambling sequence
nSamp = size(u, 1);
seq = step(hSeqGen, iniStates, nSamp);
% Descramble
y = xor(u(:,1), seq(:,1));
%------------------数字信号QAM解调,并考虑了信噪比-----------------%
%-----------------------author:lzx-------------------------%
%-----------------------date:2022年6月20日15点14分-----------------%
function y=DemodulatorSoft(u, Mode, NoiseVar)
%% Initialization
% 调用了调制函数
% SymbolMapping选择使用格雷码或是自己定义
% CustomSymbolMapping决定定义的内容
% 软解调设置了Approximate log-likelihood ratio
persistent QPSK QAM16 QAM64
if isempty(QPSK)
QPSK = comm.PSKDemodulator(...
'ModulationOrder', 4, ...
'BitOutput', true, ...
'PhaseOffset', pi/4, 'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', [0 2 3 1],...
'DecisionMethod', 'Approximate log-likelihood ratio', ...
'VarianceSource', 'Input port');
QAM16 = comm.RectangularQAMDemodulator(...
'ModulationOrder', 16, ...
'BitOutput', true, ...
'NormalizationMethod', 'Average power', 'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', [11 10 14 15 9 8 12 13 1 0 4 5 3 2 6 7],...
'DecisionMethod', 'Approximate log-likelihood ratio', ...
'VarianceSource', 'Input port');
QAM64 = comm.RectangularQAMDemodulator(...
'ModulationOrder', 64, ...
'BitOutput', true, ...
'NormalizationMethod', 'Average power', 'SymbolMapping', 'Custom', ...
'CustomSymbolMapping', ...
[47 46 42 43 59 58 62 63 45 44 40 41 57 56 60 61 37 36 32 33 ...
49 48 52 53 39 38 34 35 51 50 54 55 7 6 2 3 19 18 22 23 5 4 0 1 ...
17 16 20 21 13 12 8 9 25 24 28 29 15 14 10 11 27 26 30 31],...
'DecisionMethod', 'Approximate log-likelihood ratio', ...
'VarianceSource', 'Input port');
end
%% Processing
switch Mode
case 1
y=step(QPSK, u, NoiseVar);
case 2
y=step(QAM16,u, NoiseVar);
case 3
y=step(QAM64, u, NoiseVar);
otherwise
error('Invalid Modulation Mode. Use {1,2, or 3}');
end
二.Gold码加扰
1. Gold码原理
Gold码实际上是两个序列组合而成的,每个序列都有自己的规则和起始值
LTE中使用31阶Gold码,一个序列初始值是阶跃函数,一个序列初始值自己定义,然后生成,最后和比特流异或来获得输出
%------------------------Gold扰码-----------------------%
%-----------------------author:lzx-------------------------%
%-----------------------date:2022年6月20日15点14分-----------------%
function y = Scrambler(u, nS)
% Downlink scrambling
% u:输入的比特流
% nS:当前子帧的索引
persistent hSeqGen
if isempty(hSeqGen)
maxG=43200;
hSeqGen = comm.GoldSequence('FirstPolynomial',[1 zeros(1, 27) 1 0 0 1],...
'FirstInitialConditions', [zeros(1, 30) 1], ...
'SecondPolynomial', [1 zeros(1, 27) 1 1 1 1],...
'SecondInitialConditionsSource', 'Input port',...
'Shift', 1600,...
'VariableSizeOutput', true,...
'MaximumOutputSize', [maxG 1]);
% hInt2Bit = comm.IntegerToBit('BitsPerInteger', 31);
end
% Parameters to compute initial condition
RNTI = 1;
NcellID = 0;
q =0;
% Initial conditions
c_init = RNTI*(2^14) + q*(2^13) + floor(nS/2)*(2^9) + NcellID;
% Convert initial condition to binary vector
% iniStates = step(hInt2Bit, c_init);
iniStates = int2bit(c_init, 31);
% Generate the scrambling sequence
nSamp = size(u, 1);
% 得到输出
seq = step(hSeqGen, iniStates, nSamp);
% 保持和输入长度一致
seq2=zeros(size(u));
seq2(:)=seq(1:numel(u),1);
% Scramble input with the scrambling sequence
y = xor(u, seq2);
2.解扰
解扰非常简单,异或的比特再次异或就可以得到原比特,但是如果是之前所说的软解调出来的数呢
软解调得到的结果,大于零表示1,小于零表示0,现在如何恢复异或呢,如果本身是和1异或,大于0应该小于0,小于0应该大于0,所以×-1
如果是和0异或,则应该保持不变,这就是软解扰
%------------------------Gold扰码解扰-----------------------%
%------------------------author:lzx-------------------------%
%-----------------------date:2022年6月21日14点30分-----------------%
function y = DescramblerHard(u, nS)
% Downlink descrambling
persistent hSeqGen hInt2Bit;
if isempty(hSeqGen)
maxG=43200;
hSeqGen = comm.GoldSequence('FirstPolynomial',[1 zeros(1, 27) 1 0 0 1],...
'FirstInitialConditions', [zeros(1, 30) 1], ...
'SecondPolynomial', [1 zeros(1, 27) 1 1 1 1],...
'SecondInitialConditionsSource', 'Input port',...
'Shift', 1600,...
'VariableSizeOutput', true,...
'MaximumOutputSize', [maxG 1]);
% hInt2Bit = comm.IntegerToBit('BitsPerInteger', 31);
end
% Parameters to compute initial condition
RNTI = 1;
NcellID = 0;
q=0;
% Initial conditions
c_init = RNTI*(2^14) + q*(2^13) + floor(nS/2)*(2^9) + NcellID;
% Convert to binary vector
% iniStates = step(hInt2Bit, c_init);
iniStates = int2bit(c_init, 31);
% Generate scrambling sequence
nSamp = size(u, 1);
seq = step(hSeqGen, iniStates, nSamp);
% Descramble
y = xor(u(:,1), seq(:,1));
%------------------------Gold扰码解扰-----------------------%
%------------------------author:lzx-------------------------%
%-----------------------date:2022年6月21日14点30分-----------------%
function y = DescramblerSoft(u, nS)
% Downlink descrambling
% 这里的软解扰是针对之前的软解调说的,而不是针对加扰,输入是LLR则输出也是LLR
persistent hSeqGen hInt2Bit;
if isempty(hSeqGen)
maxG=43200;
hSeqGen = comm.GoldSequence('FirstPolynomial',[1 zeros(1, 27) 1 0 0 1],...
'FirstInitialConditions', [zeros(1, 30) 1], ...
'SecondPolynomial', [1 zeros(1, 27) 1 1 1 1],...
'SecondInitialConditionsSource', 'Input port',...
'Shift', 1600,...
'VariableSizeOutput', true,...
'MaximumOutputSize', [maxG 1]);
% hInt2Bit = comm.IntegerToBit('BitsPerInteger', 31);
end
% Parameters to compute initial condition
RNTI = 1;
NcellID = 0;
q=0;
% Initial conditions
c_init = RNTI*(2^14) + q*(2^13) + floor(nS/2)*(2^9) + NcellID;
% Convert to binary vector
% iniStates = step(hInt2Bit, c_init);
iniStates = int2bit(c_init, 31);
% Generate scrambling sequence
nSamp = size(u, 1);
seq = step(hSeqGen, iniStates, nSamp);
seq2=zeros(size(u));
seq2(:)=seq(1:numel(u),1);
% If descrambler inputs are log-likelihood ratios (LLRs) then
% Convert sequence to a bipolar format
% 变换一下符号,0变1,1变-1
seq2 = 1-2.*seq2;
% Descramble
% 即结果是,如果本身加扰是0,则不发生变化
% 如果加扰是1,则会被反向,即0变1,1变0
% 在LLR中,本身就是大于0表示1,小于0表示0
% 可以看到这样和异或的结果是相同的
% 即他仍然保留了软解调的大小差异
y = u.*seq2;
三.Turbo编码
1.Turbo编码原理
Turbo编码是很不好懂的技术,尤其是像我这样没有学过信息论,没有受过本科通信训练的人。
Turbo编码输出三个序列,第一个是原序列,后面两个是卷积码序列
同时,2,3序列存在一个交织器,交织器就是重新打乱序列,他的规则是这样的
同时,因为使用的是卷积码,最后会使用咬尾码进行清理,最后得到的长度是K+4
2. Turbo解码
Turbo解码是真的很复杂,我花了很久也没弄得很明白,这里只做一些转述吧