认识LTE(九):LTE物理层系统仿真

发布于:2023-01-09 ⋅ 阅读:(593) ⋅ 点赞:(0)

认识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);

发射机的整体工作是这样的

  1. 生成比特,这个比特的长度是(TBlen,1),这个TBlen是经过静心设计的,首先他和带宽相关的RE数量是匹配的,其次他和码率匹配生成的Kplus也是匹配的,如果是多流,那么就要多次生成比特
  2. DLSCH的操作,CRC,lteTbChannelCoding,绕码,调制,这一段我们前面已经详述了,不再赘述,总之最后生成(nSamp,1)的数据
  3. MIMO操作,MIMO里操作就是预编码和层映射,先来看预编码
    1. TM1,SISO,不进行预编码
    2. TM2,SIMO,他进行SFBC,预编码和层映射是一次性完成的,SFBC是1:2的预编码,一个符号会被以它本身以及他的共轭的方式发送两次,因此对于两天线,大小变为(nSamp,2),对于四天线变为(nSamp,4),但这其中天线是交替空缺的,始终只有两根天线在同时工作,本质上还是1:2
    3. TM3,开环MIMO,这就要首先进行层映射了,直接变成(nSamp/v, v)就可以了,然后进行预编码,TM3的预编码是一个v*v(层数)的矩阵,其中包含了CDD,那么得到的输出就还是(nSamp/v, v)。
    4. TM4和TM3从size的变化上来看是完全一致的不做赘述,不过我们考虑一下多流的情况,经过层映射会变成(nSamp*codewords/v, v),然后在进行操作
  4. 生成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);

信道整体是这样仿真的

  1. MIMO信道,这个信道的生成涉及到多径个数,多径时延,多径的功率,多普勒频移,天线的相关性等
  2. 计算nVar,为什么会有sigPow呢?这相当于把信号能量归一化了
  3. 进行AWGN
  4. 注意,信道会把信号的层数从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

接收机的工作流程是这样的

  1. OFDM和时频反映射,这在之前详细说过了
  2. 信道估计和插值,信道通过CSR估计后进行插值,然后把data对应的信道提取出来,这我有一篇博客是专门写这个的,不赘述,我们得到的h和时频的大小是一致的,提取出data对应的信号后,他的大小是(nSamp, Ntx,NRx),第一维度肯定是固定的,后面取决于天线数
  3. 进行信道均衡,这也是要分模式的
    1. MCR,这是对应于SISO,SIMO或者是TM3TM4的单天线情况,他把相同大小的h和data进行按元素乘法,然后在天线上加权,这就是MCR,得到的数据就是(nSamp, 1)
    2. TM2,进行解SFBC,需要注意的是解SFBC他是隐藏着一个MCR的,也就是说我每根天线收到的s最后还是会合并到一起,所以最后的结果也是(nSamp, 1)
    3. TM3,TM3首先思考一下,data的大小是(nSamp, nRx),h的大小是(nSamp, nTx,nRx),W的大小是(Nl,Nl),然后三者按nSamp挨个相乘,得到的就是(nSamp, nTx),然后在进行解映射,如果nTx不等于nRx该如何?没想明白,这里后面一定会补充!
    4. TM4是类似的,不赘述,这就实现了MIMO
  4. 后面进行反层映射,DLSCH的解码,不多赘述了
本文含有隐藏内容,请 开通VIP 后查看