认识LTE(九):LTE物理层系统仿真
零.代码地址
https://github.com/liu-zongxi/LTE_simulation
请大家看完觉得有用别忘了点赞收藏,github项目给star哦
一.系统全流程详解
1.发射机
%------------------------LTE系统发射机函数-----------------------%
%------------------------author:lzx----------------------------%
%------------------------date:2022年8月17日14点35分-----------------%
function [txSig, csr_ref, dataIn] = commlteSystem_Tx(nS, prmLTEDLSCH, prmLTEPDSCH, prmMdl)
%#codegen
%------------------------------第一步:生成数据并完成调制,size第二维为1--------------------------------%
% Generate payload
% TBSize是精心选择出来的,得到输入的长度
dataIn1 = genPayload(nS, prmLTEDLSCH.TBLenVec);
% Transport block CRC generation
% 加CRC
tbCrcOut1 =CRCgenerator(dataIn1);
% Channel coding includes - CB segmentation, turbo coding, rate matching,
% bit selection, CB concatenation - per codeword
% DLSCH编码
[data1, Kplus1, C1] = lteTbChannelCoding(tbCrcOut1, nS, prmLTEDLSCH, prmLTEPDSCH);
%Scramble codeword
% 扰码
scramOut = lteScramble(data1, nS, 0, prmLTEPDSCH.maxG);
% Modulate
% 调制
modOut = Modulator(scramOut, prmLTEPDSCH.modType);
%------------------------------第二步:根据不同模式进行预编码和层映射--------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%
% MIMO transmitter based on the mode
%%%%%%%%%%%%%%%%%%%%%%%
numTx=prmLTEPDSCH.numTx;
dataIn= dataIn1;
% 得到K+,C还有预编码矩阵
Kplus=Kplus1;
C=C1;
Wn=complex(ones(numTx,numTx));
% 根据模式,MIMO操作不同
switch prmLTEPDSCH.txMode
case 1 % Mode 1: Single-antenna (SIMO mode)
% SISO,不进行预编码
PrecodeOut =modOut;
case 2 % Mode 2: Transmit diversity
% TD with SFBC
% SIMO空分复用
PrecodeOut = TDEncode(modOut(:,1),prmLTEPDSCH.numTx);
case 3 % Mode 3: Open-loop Spatial multiplexing
% 开环MIMO
LayerMapOut = LayerMapper(modOut, [], prmLTEPDSCH);
% Precoding
PrecodeOut = SpatialMuxPrecoderOpenLoop(LayerMapOut, prmLTEPDSCH);
case 4 % Mode 4: Closed-loop Spatial multiplexing
% 闭环MIMO
if prmLTEPDSCH.numCodeWords==1
% Layer mapping
LayerMapOut = LayerMapper(modOut, [], prmLTEPDSCH);
else
dataIn2 = genPayload(nS, prmLTEDLSCH.TBLenVec);
tbCrcOut2 =CRCgenerator(dataIn2);
[data2, Kplus2, C2] = TbChannelCoding(tbCrcOut2, nS, prmLTEDLSCH, prmLTEPDSCH);
scramOut2 = Scramble(data2, nS, 0, prmLTEPDSCH.maxG);
modOut2 = Modulator(scramOut2, prmLTEPDSCH.modType);
% Layer mapping
LayerMapOut = LayerMapper(modOut, modOut2, prmLTEPDSCH);
dataIn= [dataIn1;dataIn2];
Kplus=[Kplus1;Kplus2];
C=[C1; C2];
end
% Precoding
usedCbIdx = prmMdl.cbIdx;
[PrecodeOut, Wn] = SpatialMuxPrecoder(LayerMapOut, prmLTEPDSCH, usedCbIdx);
% PrecodeOut = SpatialMuxPrecoderOpenLoop(LayerMapOut, prmLTEPDSCH);
end
%------------------------------第三步:生成CSR,用于信道的预测--------------------------------%
% Generate Cell-Specific Reference (CSR) signals
numTx=prmLTEPDSCH.numTx;
csr = CSRgenerator(nS, numTx);
csr_ref=complex(zeros(2*prmLTEPDSCH.Nrb, 4, numTx));
for m=1:numTx
csr_pre=csr(1:2*prmLTEPDSCH.Nrb,:,:,m);
csr_ref(:,:,m)=reshape(csr_pre,2*prmLTEPDSCH.Nrb,4);
end
%------------------------------第四步:时频映射还有OFDM--------------------------------%
% Resource grid filling
txGrid = REmapper_mTx(PrecodeOut, csr_ref, nS, prmLTEPDSCH);
% OFDM transmitter
txSig = OFDMTx(txGrid, prmLTEPDSCH);
发射机的整体工作是这样的
- 生成比特,这个比特的长度是(TBlen,1),这个TBlen是经过静心设计的,首先他和带宽相关的RE数量是匹配的,其次他和码率匹配生成的Kplus也是匹配的,如果是多流,那么就要多次生成比特
- DLSCH的操作,CRC,lteTbChannelCoding,绕码,调制,这一段我们前面已经详述了,不再赘述,总之最后生成(nSamp,1)的数据
- MIMO操作,MIMO里操作就是预编码和层映射,先来看预编码
- TM1,SISO,不进行预编码
- TM2,SIMO,他进行SFBC,预编码和层映射是一次性完成的,SFBC是1:2的预编码,一个符号会被以它本身以及他的共轭的方式发送两次,因此对于两天线,大小变为(nSamp,2),对于四天线变为(nSamp,4),但这其中天线是交替空缺的,始终只有两根天线在同时工作,本质上还是1:2
- TM3,开环MIMO,这就要首先进行层映射了,直接变成(nSamp/v, v)就可以了,然后进行预编码,TM3的预编码是一个v*v(层数)的矩阵,其中包含了CDD,那么得到的输出就还是(nSamp/v, v)。
- TM4和TM3从size的变化上来看是完全一致的不做赘述,不过我们考虑一下多流的情况,经过层映射会变成(nSamp*codewords/v, v),然后在进行操作
- 生成CSR,做时频映射,再进行OFDM,也就是说目前存在Ntx个时频块,这个在我前面的博客里也有详述
2.信道
%------------------------LTE系统信道函数-----------------------%
%------------------------author:lzx----------------------------%
%------------------------date:2022年8月17日14点54分-----------------%
function [rxSig, chPathG, nVar] = commlteSystem_Channel(txSig, snrdB, prmLTEPDSCH, prmMdl )
%#codegen
% MIMO Fading channel
[rxFade, chPathG] = MIMOFadingChan(txSig, prmLTEPDSCH, prmMdl);
% Add AWG noise
% nVar=(10.^(0.1.*(-snrdB)))*ones(1,prmLTEPDSCH.numRx);
sigPow = 10*log10(var(rxFade));
nVar = 10.^(0.1.*(sigPow-snrdB));
rxSig = AWGNChannel(rxFade, nVar);
信道整体是这样仿真的
- MIMO信道,这个信道的生成涉及到多径个数,多径时延,多径的功率,多普勒频移,天线的相关性等
- 计算nVar,为什么会有sigPow呢?这相当于把信号能量归一化了
- 进行AWGN
- 注意,信道会把信号的层数从Ntx变成NRx
3.接收机
%------------------------LTE系统接收机函数-----------------------%
%------------------------author:lzx----------------------------%
%------------------------date:2022年8月17日15点16分-----------------%
function [dataOut, dataRx, yRec, CbFlag, cbIdx] = commlteSystem_Rx(nS, csr_ref, rxSig, chPathG, nVar, ...
prmLTEDLSCH, prmLTEPDSCH, prmMdl)
%#codegen
%------------------------------第一步:OFDM和时频解映射,得到CSR和data--------------------------------%
% OFDM Rx
rxGrid = OFDMRx(rxSig, prmLTEPDSCH);
% updated for numLayers -> numTx
[dataRx, csrRx, idx_data] = REdemapper_mTx(rxGrid, nS, prmLTEPDSCH);
%------------------------------第二步:信道估计和信道插值,PMI反馈--------------------------------%
% MIMO channel estimation
if prmMdl.chEstOn
chEst = ChanEstimate_mTx(prmLTEPDSCH, csrRx, csr_ref, prmMdl.chEstOn);
hD = ExtChResponse(chEst, idx_data, prmLTEPDSCH);
else
idealChEst = IdChEst(prmLTEPDSCH, prmMdl, chPathG);
hD = ExtChResponse(idealChEst, idx_data, prmLTEPDSCH);
end
% PMI codebook selection
if (prmMdl.enPMIfback)
cbIdx = PMICbSelect( hD, prmMdl.enPMIfback, prmLTEPDSCH.numTx, ...
prmLTEPDSCH.numLayers, nVar );
else
cbIdx=prmMdl.cbIdx;
end
%------------------------------第三步:根据模式进行MIMO的均衡和解层映射--------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MIMO Receiver based on the mode
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
switch prmLTEPDSCH.txMode
case 1
% Based on Maximum-Combining Ratio (MCR)
yRec = Equalizer_simo(dataRx, hD, max(nVar), prmLTEPDSCH);
cwOut = yRec;
case 2
% Based on Transmit Diversity with SFBC combiner
yRec = TDCombine(dataRx, hD, prmLTEPDSCH.numTx, prmLTEPDSCH.numRx);
cwOut = yRec;
case 3
yRec = MIMOReceiver_OpenLoop(dataRx, hD, prmLTEPDSCH, nVar);
% Demap received codeword(s)
[cwOut, ~] = LayerDemapper(yRec, prmLTEPDSCH);
case 4
% Based on Spatial Multiplexing
Wn = PrecoderMatrix(prmMdl.cbIdx, prmLTEPDSCH.numTx, prmLTEPDSCH.numLayers);
yRec = MIMOReceiver(dataRx, hD, prmLTEPDSCH, nVar, Wn);
% yRec = MIMOReceiver_OpenLoop(dataRx, hD, prmLTEPDSCH, nVar);
% Demap received codeword(s)
[cwOut1, cwOut2] = LayerDemapper(yRec, prmLTEPDSCH);
if prmLTEPDSCH.numCodeWords==1
cwOut = cwOut1;
else
cwOut = [cwOut1, cwOut2];
end
end
%------------------------------第四步:多流处理--------------------------------%
% Codeword processing
switch nS
case 0
outLen = prmLTEDLSCH.TBLenVec(1);
case 10
outLen = prmLTEDLSCH.TBLenVec(2);
otherwise
outLen = prmLTEDLSCH.TBLenVec(3);
end
C=zeros(2,1);Kplus=C;
for n=1:2
[C(n), ~, Kplus(n)] = lteCblkSegParams(outLen);
end
if prmLTEPDSCH.numCodeWords==1
dataOut=false(outLen,1);
else
dataOut=false(2*outLen,1);
end
%------------------------------第五步:解DLSCH--------------------------------%
index=1:outLen;
for n = 1:prmLTEPDSCH.numCodeWords
% Demodulation
if prmLTEPDSCH.Eqmode == 3
% not necessary in case of Sphere Decoding
demodOut = cwOut(:,n);
else
% Demodulate
demodOut = DemodulatorSoft(cwOut(:,n), prmLTEPDSCH.modType, max(nVar));
end
% Descramble received codeword
rxCW = lteDescramble(demodOut, nS, 0, prmLTEPDSCH.maxG);
% Channel decoding includes CB segmentation, turbo decoding, rate dematching
[decTbData, ~,~] = lteTbChannelDecoding(nS, rxCW, Kplus(n), C(n), prmLTEDLSCH, prmLTEPDSCH);
% Transport block CRC detection
[dataOut(index), CbFlag] = CRCdetector(decTbData);
index = index + outLen;
end
接收机的工作流程是这样的
- OFDM和时频反映射,这在之前详细说过了
- 信道估计和插值,信道通过CSR估计后进行插值,然后把data对应的信道提取出来,这我有一篇博客是专门写这个的,不赘述,我们得到的h和时频的大小是一致的,提取出data对应的信号后,他的大小是(nSamp, Ntx,NRx),第一维度肯定是固定的,后面取决于天线数
- 进行信道均衡,这也是要分模式的
- MCR,这是对应于SISO,SIMO或者是TM3TM4的单天线情况,他把相同大小的h和data进行按元素乘法,然后在天线上加权,这就是MCR,得到的数据就是(nSamp, 1)
- TM2,进行解SFBC,需要注意的是解SFBC他是隐藏着一个MCR的,也就是说我每根天线收到的s最后还是会合并到一起,所以最后的结果也是(nSamp, 1)
- TM3,TM3首先思考一下,data的大小是(nSamp, nRx),h的大小是(nSamp, nTx,nRx),W的大小是(Nl,Nl),然后三者按nSamp挨个相乘,得到的就是(nSamp, nTx),然后在进行解映射,如果nTx不等于nRx该如何?没想明白,这里后面一定会补充!
- TM4是类似的,不赘述,这就实现了MIMO
- 后面进行反层映射,DLSCH的解码,不多赘述了
本文含有隐藏内容,请 开通VIP 后查看