文章目录
初识LTE(五):完整的SISO LTE 物理层实现
零.代码地址
https://github.com/liu-zongxi/LTE_simulation
请大家看完觉得有用别忘了点赞收藏,github项目给star哦
一.实现整体过程
1.参数初始化
这部分主要由以下几个函数来实现
commlteSISO_params
% PDSCH
numTx = 1; % Number of transmit antennas
numRx = 1; % Number of receive antennas
chanBW = 4; % Index to chanel bandwidth used [1,....6]
contReg = 1; % No. of OFDM symbols dedictaed to control information [1,...,3]
modType = 2; % Modulation type [1, 2, 3] for ['QPSK,'16QAM','64QAM']
% DLSCH
cRate = 1/3; % Rate matching target coding rate
maxIter = 6; % Maximum number of turbo decoding terations
fullDecode = 0; % Whether "full" or "early stopping" turbo decoding is performed
% Channel model
chanMdl = 'frequency-selective-high-mobility';
corrLvl = 'Low';
% Simulation parametrs
Eqmode = 2; % Type of equalizer used [1,2] for ['ZF', 'MMSE']
chEstOn = 1; % Whether channel estimation is done or ideal channel model used
maxNumErrs = 1e7; % Maximum number of errors found before simulation stops
maxNumBits = 1e7; % Maximum number of bits processed before simulation stops
visualsOn = 1; % Whether to visualize channel response and constellations
snrdB = 16; % Value of SNR used in this experiment
这里主要设置的是用户可以自己调节的参数,包括
- PDSCH,也就是调制编码部分的参数,包括信道带宽(1.4-10MHz),天线个数,PDCCH大小,调制类型
- DLSCH,包括码率,Turbo解码最大迭代次数以及是否使用早停
- 信道模型,包括信道类型和相关度
- 接收机参数,如信道均衡方式
- 参数,如信噪比,可视化,最大迭代次数等
commlteSISO_initialize prmsPDSCH prmsDLSCH
function [prmLTEPDSCH, prmLTEDLSCH, prmMdl] = commlteSISO_initialize(chanBW, contReg, modType, Eqmode,...
cRate,maxIter, fullDecode, chanMdl, corrLvl, chEstOn, maxNumErrs, maxNumBits)
% Create the parameter structures
% PDSCH and DLSCH
prmLTEPDSCH = prmsPDSCH(chanBW, contReg, modType);
prmLTEPDSCH.Eqmode=Eqmode;
prmLTEPDSCH.modType=modType;
prmLTEDLSCH = prmsDLSCH(cRate,maxIter, fullDecode, prmLTEPDSCH);
% Channel parameters
prmMdl.chanMdl = chanMdl;
prmMdl.corrLevel = corrLvl;
prmMdl.chEstOn = chEstOn;
switch modType
case 1
snrdBs=[0:4:8, 9:12];
case 2
snrdBs=[0:4:12, 13:16];
otherwise
snrdBs=0:4:24;
end
prmMdl.snrdBs=snrdBs;
prmMdl.maxNumBits=maxNumBits;
prmMdl.maxNumErrs=maxNumErrs;
function p= prmsPDSCH(chanBW, contReg, modType, varargin)
% LTEPDSCHPRMS Returns parameter structures for LTE PDSCH simulation.
%
% Assumes a FDD, normal cyclic prefix, full-bandwidth, single-user
% SISO or SIMO downlink transmission.
%% PDSCH parameters
switch chanBW
case 1 % 1.4 MHz
BW = 1.4e6; N = 128; cpLen0 = 10; cpLenR = 9;
Nrb = 6; chanSRate = 1.92e6;
case 2 % 3 MHz
BW = 3e6; N = 256; cpLen0 = 20; cpLenR = 18;
Nrb = 15; chanSRate = 3.84e6;
case 3 % 5 MHz
BW = 5e6; N = 512; cpLen0 = 40; cpLenR = 36;
Nrb = 25; chanSRate = 7.68e6;
case 4 % 10 MHz
BW = 10e6; N = 1024; cpLen0 = 80; cpLenR = 72;
Nrb = 50; chanSRate = 15.36e6;
case 5 % 15 MHz
BW = 15e6; N = 1536; cpLen0 = 120; cpLenR = 108;
Nrb = 75; chanSRate = 23.04e6;
case 6 % 20 MHz
BW = 20e6; N = 2048; cpLen0 = 160; cpLenR = 144;
Nrb = 100; chanSRate = 30.72e6;
end
p.BW = BW; % Channel bandwidth
p.N = N; % NFFT
p.cpLen0 = cpLen0; % Cyclic prefix length for 1st symbol,特殊CP
p.cpLenR = cpLenR; % Cyclic prefix length for remaining,普通CP
p.Nrb = Nrb; % Number of resource blocks,RB的的个数,6-110
p.chanSRate = chanSRate; % Channel sampling rate
p.contReg = contReg;
p.numTx = 1;
p.numRx = 1;
p.numLayers = 1;
p.numCodeWords = 1;
% For Normal cyclic prefix, FDD mode
p.deltaF = 15e3; % subcarrier spacing,子载波间隔
p.Nrb_sc = 12; % no. of subcarriers per resource block,一个RB12个子载波
p.Ndl_symb = 7; % no. of OFDM symbols in a slot,一个slot7个OFDM符号
% Actual PDSCH bits calculation - accounting for PDCCH, PBCH, PSS, SSS
numResources = (p.Nrb*p.Nrb_sc)*(p.Ndl_symb*2);% 总个数
numCSRRE = 2*2*2 * p.Nrb; % CSR, RE per OFDMsym/slot/subframe per RB
numContRE = (10 + 12*(p.contReg-1))*p.Nrb;
numBCHRE = 60+72+72+72; % removing the CSR present in 1st symbol
numSSSRE=72;
numPSSRE=72;
numDataRE=zeros(3,1);
% Account for BCH, PSS, SSS and PDCCH for subframe 0
numDataRE(1)=numResources-numCSRRE-numContRE-numSSSRE - numPSSRE-numBCHRE;
% Account for PSS, SSS and PDCCH for subframe 5
numDataRE(2)=numResources-numCSRRE-numContRE-numSSSRE - numPSSRE;
% Account for PDCCH only in all other subframes
numDataRE(3)=numResources-numCSRRE-numContRE;
% Maximum data resources - with no extra overheads (only CSR + data)
p.numResources=numResources;
p.numCSRResources = numCSRRE;
p.numContRE = numContRE;
p.numBCHRE = numBCHRE;
p.numSSSRE=numSSSRE;
p.numPSSRE=numPSSRE;
p.numDataRE=numDataRE;
p.numDataResources = p.numResources - p.numCSRResources;
% Modulation types , bits per symbol, number of layers per codeword
Qm = 2 * modType;
p.Qm = Qm;
p.numLayPerCW = p.numLayers/p.numCodeWords;
% Maximum data bits - with no extra overheads (only CSR + data)
p.numDataBits = p.numDataResources*Qm*p.numLayPerCW;
numPDSCHBits =numDataRE*Qm*p.numLayPerCW;
p.numPDSCHBits = numPDSCHBits;
p.maxG = max(numPDSCHBits);
function p= prmsPDSCH(chanBW, contReg, modType, varargin)
% LTEPDSCHPRMS Returns parameter structures for LTE PDSCH simulation.
%
% Assumes a FDD, normal cyclic prefix, full-bandwidth, single-user
% SISO or SIMO downlink transmission.
%% PDSCH parameters
switch chanBW
case 1 % 1.4 MHz
BW = 1.4e6; N = 128; cpLen0 = 10; cpLenR = 9;
Nrb = 6; chanSRate = 1.92e6;
case 2 % 3 MHz
BW = 3e6; N = 256; cpLen0 = 20; cpLenR = 18;
Nrb = 15; chanSRate = 3.84e6;
case 3 % 5 MHz
BW = 5e6; N = 512; cpLen0 = 40; cpLenR = 36;
Nrb = 25; chanSRate = 7.68e6;
case 4 % 10 MHz
BW = 10e6; N = 1024; cpLen0 = 80; cpLenR = 72;
Nrb = 50; chanSRate = 15.36e6;
case 5 % 15 MHz
BW = 15e6; N = 1536; cpLen0 = 120; cpLenR = 108;
Nrb = 75; chanSRate = 23.04e6;
case 6 % 20 MHz
BW = 20e6; N = 2048; cpLen0 = 160; cpLenR = 144;
Nrb = 100; chanSRate = 30.72e6;
end
p.BW = BW; % Channel bandwidth
p.N = N; % NFFT
p.cpLen0 = cpLen0; % Cyclic prefix length for 1st symbol,特殊CP
p.cpLenR = cpLenR; % Cyclic prefix length for remaining,普通CP
p.Nrb = Nrb; % Number of resource blocks,RB的的个数,6-110
p.chanSRate = chanSRate; % Channel sampling rate
p.contReg = contReg;
p.numTx = 1;
p.numRx = 1;
p.numLayers = 1;
p.numCodeWords = 1;
% For Normal cyclic prefix, FDD mode
p.deltaF = 15e3; % subcarrier spacing,子载波间隔
p.Nrb_sc = 12; % no. of subcarriers per resource block,一个RB12个子载波
p.Ndl_symb = 7; % no. of OFDM symbols in a slot,一个slot7个OFDM符号
% Actual PDSCH bits calculation - accounting for PDCCH, PBCH, PSS, SSS
numResources = (p.Nrb*p.Nrb_sc)*(p.Ndl_symb*2);% 总个数
numCSRRE = 2*2*2 * p.Nrb; % CSR, RE per OFDMsym/slot/subframe per RB
numContRE = (10 + 12*(p.contReg-1))*p.Nrb;
numBCHRE = 60+72+72+72; % removing the CSR present in 1st symbol
numSSSRE=72;
numPSSRE=72;
numDataRE=zeros(3,1);
% Account for BCH, PSS, SSS and PDCCH for subframe 0
numDataRE(1)=numResources-numCSRRE-numContRE-numSSSRE - numPSSRE-numBCHRE;
% Account for PSS, SSS and PDCCH for subframe 5
numDataRE(2)=numResources-numCSRRE-numContRE-numSSSRE - numPSSRE;
% Account for PDCCH only in all other subframes
numDataRE(3)=numResources-numCSRRE-numContRE;
% Maximum data resources - with no extra overheads (only CSR + data)
p.numResources=numResources;
p.numCSRResources = numCSRRE;
p.numContRE = numContRE;
p.numBCHRE = numBCHRE;
p.numSSSRE=numSSSRE;
p.numPSSRE=numPSSRE;
p.numDataRE=numDataRE;
p.numDataResources = p.numResources - p.numCSRResources;
% Modulation types , bits per symbol, number of layers per codeword
Qm = 2 * modType;
p.Qm = Qm;
p.numLayPerCW = p.numLayers/p.numCodeWords;
% Maximum data bits - with no extra overheads (only CSR + data)
p.numDataBits = p.numDataResources*Qm*p.numLayPerCW;
numPDSCHBits =numDataRE*Qm*p.numLayPerCW;
p.numPDSCHBits = numPDSCHBits;
p.maxG = max(numPDSCHBits);
function p2 = prmsDLSCH(cRate,maxIter, fullDecode, p)
% 13 15 是转换为二进制后反馈多项式的表达式,约束长度为4,反馈迭代次数为13
p2.trellis = poly2trellis(4, [13 15], 13);
if (cRate >= 1) || (cRate <= 0)
error('Wrong coding rate');
end
p2.cRate = cRate;
modType = 0.5*p.Qm;
% 这里长度就是3,因为有三种不同长度的子帧05和普通的
TBLenVec = zeros(1, length(p.numPDSCHBits));
C = zeros(1, length(TBLenVec)); Kplus = zeros(1, length(C));
for i = 1:length(TBLenVec)
TBLenVec(i) = getTBsizeRMC(modType, p2.cRate, p.Nrb, ...
p.numLayPerCW, p.numPDSCHBits(i));
[C(i), ~, Kplus(i)] = lteCblkSegParams(TBLenVec(i));
end
p2.TBLenVec = TBLenVec;
p2.maxTBLen = max(p2.TBLenVec);
p2.maxC = max(C);
p2.minC = min(C);
p2.maxKplus = max(Kplus);
p2.maxIter = maxIter;
p2.fullDecode = fullDecode;
该函数把我们设置好的参数传入,并生成所需要的PDSCH和DLSCH的参数
- PDSCH包括
- 根据带宽类型获得真正的带宽,RB的个数,NFFT点数,CP长度以及分辨率
- 之前传入的天线个数,层数PDCCH大小等
- OFDM相关的子载波间隔,一个时隙中的符号个数,一个RB中的RE个数等
- 计算出各个信道SSS,PSS,BCH等的大小
- 一些比特数的计算
- DLSCH包括
- 码率,调制方式,子镇长度,分块个数,K+
- 信道参数
- 信道种类chanMdl
- 信道相关性,即平坦与否
- 信噪比
2.主函数
主函数主要在commlteSISO_step中实现
commlteSISO_step
function [dataIn, dataOut, txSig, rxSig, dataRx, yRec, csr_ref]...
= commlteSISO_step(nS, snrdB, prmLTEDLSCH, prmLTEPDSCH, prmMdl)
%% TX
% Generate payload
% 生成数据,0号子帧和10号时隙的长度和别的是不同的
% 因为BCH和SSS的缘故,注意nS表示的是时隙而不是子帧
dataIn = genPayload_HZ(nS, prmLTEDLSCH.TBLenVec);
% 添加CRC
% Transport block CRC generation
tbCrcOut1 =CRCgenerator(dataIn);
% Channel coding includes - CB segmentation, turbo coding, rate matching,
% bit selection, CB concatenation - per codeword
[data, Kplus1, C1] = lteTbChannelCoding(tbCrcOut1, nS, prmLTEDLSCH, prmLTEPDSCH);
%Scramble codeword
scramOut = lteScramble(data, nS, 0, prmLTEPDSCH.maxG);
% Modulate
modOut = Modulator(scramOut, prmLTEPDSCH.modType);
% Generate Cell-Specific Reference (CSR) signals
csr = CSRgenerator(nS, prmLTEPDSCH.numTx);
% Resource grid filling
% 一个RB中有8个参考信号
E=8*prmLTEPDSCH.Nrb;
csr_ref=reshape(csr(1:E),2*prmLTEPDSCH.Nrb,4);
txGrid = REmapper_1Tx(modOut, csr_ref, nS, prmLTEPDSCH);
% OFDM transmitter
txSig = OFDMTx(txGrid, prmLTEPDSCH);
%% Channel
% SISO Fading channel
[rxFade, chPathG] = MIMOFadingChan(txSig, prmLTEPDSCH, prmMdl);
% 注意这里预估出的H是只有dataidx的,他是理想的根据chPathG即信道增益获得的
idealhD = lteIdChEst(prmLTEPDSCH, prmMdl, chPathG, nS);
% Add AWG noise
nVar = 10.^(0.1.*(-snrdB));
rxSig = AWGNChannel2(rxFade, nVar);
%% RX
% OFDM Rx
rxGrid = OFDMRx(rxSig, prmLTEPDSCH);
% updated for numLayers -> numTx
[dataRx, csrRx, idx_data] = REdemapper_1Tx(rxGrid, nS, prmLTEPDSCH);
% MIMO channel estimation
if prmMdl.chEstOn
chEst = ChanEstimate_1Tx(prmLTEPDSCH, csrRx, csr_ref, 'interpolate');
hD=chEst(idx_data);
else
hD = idealhD;
end
% Frequency-domain equalizer
yRec = Equalizer(dataRx, hD, nVar, prmLTEPDSCH.Eqmode);
% Demodulate
demodOut = DemodulatorSoft(yRec, prmLTEPDSCH.modType, nVar);
% Descramble both received codewords
rxCW = lteDescramble(demodOut, nS, 0, prmLTEPDSCH.maxG);
% Channel decoding includes - CB segmentation, turbo decoding, rate dematching
[decTbData1, ~,~] = lteTbChannelDecoding(nS, rxCW, Kplus1, C1, prmLTEDLSCH, prmLTEPDSCH);
% Transport block CRC detection
[dataOut, ~] = CRCdetector(decTbData1);
end
主函数主要进行了以下这几步骤,这和我上一篇博客是类似的,这里简要说一些其中的差别
发射机
- 生成数据,长度根据设定好的子帧长度来,这里的TBlen是根据getTBSize这个函数精心设计好的,确保最后经过编码码率匹配等操作后,正好是需要的大小
- CRC
- Coding,也就是DLSCH中做的工作,分块后添加CRC,Turbo编码,码率匹配,在重组,这里得到的就是PDSCHbit数了
- 绕码,调制,
- 生成CSR,这其实也是Gold编码,最后会生成一个长度为200的序列,为什么是200呢?选择400个在进行QPSK就变成200了!
最后生成是一个大小为(200,2,2,TX)的序列,第二维是说有两种CSR对应0和4符号,第三维是一个子帧中有两个时隙
之后它会被取出需要的个数,并且reshape成(2*prmLTEPDSCH.Nrb,4)这样的大小
- 进行映射,映射的整体思路是,获得信道的idx,然后把数据放进去,对于目前,我们只放置数据和CSR,并且把其他的位置空出来,这里就把CSR又一个个拍进去了,映射完大小变成了(600,14)
- OFDM发送并添加了CP,得到的大小就是七个NFFT加上CP的长度的输出了
信道
- 生成信道,这主要是利用自带的comm.LTEMIMOChannel函数来实现的,输出等大小的经过衰落的输出还有大小为(length,numPaths)的输出,也就是说每个多径信道都有一个增益
- 理想信道估计,这里的意思是直接用增益来估计信道,正常来说现实情况我们是无法获得增益的,把每个NFFT对应的增益在一个循环(CP+NFFT)内平均得到平均增益,最后得到的增益是一个大小为(14,numPaths),然后把他放置在大小为(14,Nfft)大小的h中就可以,就带了numPaths个数的时延的信道了,这就是时域的信道h,经过fft后再提取出data所在的位置,去掉CSR,这就是data对应的频域的信道了
- AWGN
接收机
- OFDM接收,得到(600,14)的信号
- 解映射,把data和CSR分开分别得到他们的长度
- 真正的信道估计,输入CSR,得到整个时频图上的信道,然后取出data对应的位置,去掉CSR对应的
- 信道均衡,利用预估出来的信号去均衡收到的信道
- 解调,解扰
- 解DLSCH,重新分块后解码率匹配,解Turbo
- 解CRC
二.SIMO的一些补充
SIMO的修改非常少,增加一维,循环接收就可以了
唯一值得说的是MCR的方式
function [y, num, denum] = Equalizer_simo(in, hD, nVar, EqMode)
%#codegen
% 这里同时完成了MCR
% MCR就是每个天线各自均衡H*,然后相加
switch EqMode
case 1 % Zero forcing
num = conj(hD);
denum=conj(hD).*hD;
case 2 % MMSE
num = conj(hD);
denum=conj(hD).*hD+nVar;
otherwise
error('Two equalization mode available: Zero forcing or MMSE');
end
y = sum(in .*num,2)./sum(denum,2);
这里的MCR方式很独特,和我理解的不太一样,有懂得大佬还望不吝赐教
接收机
- OFDM接收,得到(600,14)的信号
- 解映射,把data和CSR分开分别得到他们的长度
- 真正的信道估计,输入CSR,得到整个时频图上的信道,然后取出data对应的位置,去掉CSR对应的
- 信道均衡,利用预估出来的信号去均衡收到的信道
- 解调,解扰
- 解DLSCH,重新分块后解码率匹配,解Turbo
- 解CRC