初识LTE(五):完整的SISO LTE 物理层实现

本文详细介绍了如何实现LTE物理层的SISO和SIMO模式,涉及参数初始化、PDSCH和DLSCH模块、主函数commlteSISO_step,以及独特的MCR均衡方法。通过代码实例,读者可以了解信道编码、解码和信道估计的全过程。
摘要由CSDN通过智能技术生成

初识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

这里主要设置的是用户可以自己调节的参数,包括

  1. PDSCH,也就是调制编码部分的参数,包括信道带宽(1.4-10MHz),天线个数,PDCCH大小,调制类型
  2. DLSCH,包括码率,Turbo解码最大迭代次数以及是否使用早停
  3. 信道模型,包括信道类型和相关度
  4. 接收机参数,如信道均衡方式
  5. 参数,如信噪比,可视化,最大迭代次数等

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

主函数主要进行了以下这几步骤,这和我上一篇博客是类似的,这里简要说一些其中的差别


发射机

  1. 生成数据,长度根据设定好的子帧长度来,这里的TBlen是根据getTBSize这个函数精心设计好的,确保最后经过编码码率匹配等操作后,正好是需要的大小
  2. CRC
  3. Coding,也就是DLSCH中做的工作,分块后添加CRC,Turbo编码,码率匹配,在重组,这里得到的就是PDSCHbit数了
  4. 绕码,调制,
  5. 生成CSR,这其实也是Gold编码,最后会生成一个长度为200的序列,为什么是200呢?选择400个在进行QPSK就变成200了!image-20220802182030387

最后生成是一个大小为(200,2,2,TX)的序列,第二维是说有两种CSR对应0和4符号,第三维是一个子帧中有两个时隙

之后它会被取出需要的个数,并且reshape成(2*prmLTEPDSCH.Nrb,4)这样的大小

  1. 进行映射,映射的整体思路是,获得信道的idx,然后把数据放进去,对于目前,我们只放置数据和CSR,并且把其他的位置空出来,这里就把CSR又一个个拍进去了,映射完大小变成了(600,14)
  2. OFDM发送并添加了CP,得到的大小就是七个NFFT加上CP的长度的输出了

信道

  1. 生成信道,这主要是利用自带的comm.LTEMIMOChannel函数来实现的,输出等大小的经过衰落的输出还有大小为(length,numPaths)的输出,也就是说每个多径信道都有一个增益
  2. 理想信道估计,这里的意思是直接用增益来估计信道,正常来说现实情况我们是无法获得增益的,把每个NFFT对应的增益在一个循环(CP+NFFT)内平均得到平均增益,最后得到的增益是一个大小为(14,numPaths),然后把他放置在大小为(14,Nfft)大小的h中就可以,就带了numPaths个数的时延的信道了,这就是时域的信道h,经过fft后再提取出data所在的位置,去掉CSR,这就是data对应的频域的信道了
  3. AWGN

接收机

  1. OFDM接收,得到(600,14)的信号
  2. 解映射,把data和CSR分开分别得到他们的长度
  3. 真正的信道估计,输入CSR,得到整个时频图上的信道,然后取出data对应的位置,去掉CSR对应的
  4. 信道均衡,利用预估出来的信号去均衡收到的信道
  5. 解调,解扰
  6. 解DLSCH,重新分块后解码率匹配,解Turbo
  7. 解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方式很独特,和我理解的不太一样,有懂得大佬还望不吝赐教

接收机

  1. OFDM接收,得到(600,14)的信号
  2. 解映射,把data和CSR分开分别得到他们的长度
  3. 真正的信道估计,输入CSR,得到整个时频图上的信道,然后取出data对应的位置,去掉CSR对应的
  4. 信道均衡,利用预估出来的信号去均衡收到的信道
  5. 解调,解扰
  6. 解DLSCH,重新分块后解码率匹配,解Turbo
  7. 解CRC
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值