Matlab Toolbox - 4G/LTE
A UE that starts receiving a downlink signal does not know where a radio frame begins. Every later step, from the OFDM demodulation to the PBCH decoding, needs that starting point first.
This page will show you the process of detecting the Frame Offset for one radio frame (10 ms) from the received time domain data.
i) Create a physical layer symbols for all the channels (RS, PSS, SSS, PDCCH, PDSCH) for one subframe
ii) Put all the channel data into a resource grid of one subframe (1 ms)
iii) Repeat the step i)~ii) 10 times to produce the grid of one radio frame (10 ms)
iv) Perform OFDM Modulation to convert the resrouce grid to 10 ms of time domain data.
v) Apply Fading to the time domain data (This is optional)
vi) Calculate Frame Offset from the data from step iv) (or step v))
The steps up to iv) are the same as on the Constructing a whole radio frame page. Step vi) is the new part, and a single function does it. The function lteDLFrameOffset returns the number of samples from the start of the waveform to the start of the first radio frame it finds.
Followings are the topics to be covered in this page.
Detecting Frame Offset for Ideal Signal
What does the function return when nothing has disturbed the signal? This first case feeds the transmitted waveform straight into lteDLFrameOffset, so the true frame start is known. It is sample 0, and the result should say so.
% First you have to define properites of a eNodeB.
% NDLRB indicate System Bandwith in the unit of RBs.
% NDLRB 6 = 1.4 Mhz, NDLRB 15 = 3.0 Mhz, NDLRB 25 = 5.0 Mhz,
% NDLRB 50 = 10 Mhz, NDLRB 75 = 15 Mhz, NDLRB 100 = 20 Mhz
% CellRefP indicate number of downlink Antenna. CellRefP = 1 means 1 transmission antenna (SISO)
% NCellID indicate PCI (Physical Cell Identity) of the Cell
% NSubframe indicate the subframe number.
enb.CyclicPrefix = 'Normal';
enb.PHICHDuration = 'Normal';
enb.Ng = 'Sixth';
enb.NDLRB = 6;
enb.CellRefP = 1;
enb.DuplexMode = 'FDD';
enb.NFrame = 0;
enb.NCellID = 0;
txFrameGrid = [];
for subframeNo = 0:9
enb.NSubframe = subframeNo;
enb.CFI = 1;
PHICH_Group_Index = 0;
PHICH_Sequence_Index = 1;
HARQ_Indicator_Value = 0; % 0 = NACK, 1 = ACK
dci.NDLRB = enb.NDLRB;
dci.DCIFormat = 'Format1A';
dci.AllocationType = 0;
dci.Allocation.RIV = 18;
dci.ModCoding = 10;
dci.HARQNo = 0;
dci.NewData = 0;
dci.TPCPUCCH = 0;
dci.DuplexMode = 'FDD';
dci.NTxAnts = 1;
[dciMessage,dciMessageBits] = lteDCI(enb,dci);
C_RNTI = 100;
pdcchConfig.RNTI = C_RNTI;
pdcchConfig.PDCCHFormat = 0;
codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
pdcchDims = ltePDCCHInfo(enb);
pdcchBits = -1*ones(pdcchDims.MTot, 1);
candidates = ltePDCCHSpace(enb, pdcchConfig, {'bits', '1based'});
pdcchBits ( candidates(1, 1) : candidates(1, 2) ) = codedDciBits;
pdcch_sym = ltePDCCH(enb, pdcchBits);
pdcch_sym_ind = ltePDCCHIndices(enb,{'1based','re'});
pdcch_sym_arrayIndex = 0:length(pdcch_sym)-1;
% Generating PDSCH Symbols
pdsch.NTxAnts = 1;
pdsch.NLayers = 1;
pdsch.TxScheme = 'Port0';
pdsch.Modulation = {'16QAM'};
pdsch.RV = 0;
pdsch.RNTI = C_RNTI;
START_RB = 0;
N_RB = 4; %enb.NDLRB;
pdsch_prbs = (START_RB:(START_RB+N_RB-1)).';
[pdsch_sym_ind,pdschIndInfo] = ltePDSCHIndices(enb,pdsch,pdsch_prbs,{'1based','re'});
codedTrBlkSize = pdschIndInfo.G;
dlschTransportBlk = round(rand(1,codedTrBlkSize));
codeword = lteDLSCH(enb,pdsch,codedTrBlkSize,dlschTransportBlk);
pdsch_sym = ltePDSCH(enb,pdsch,codeword);
pdsch_sym_arrayIndex = 0:length(pdsch_sym)-1;
%fill in the resource grid
resourceGrid = lteDLResourceGrid(enb);
rsAnt0 = lteCellRS(enb,0);
indAnt0 = lteCellRSIndices(enb,0);
resourceGrid(indAnt0) = rsAnt0;
mib_bits = lteMIB(enb);
bch_cw = lteBCH(enb,mib_bits);
pss = ltePSS(enb);
pss_arrayIndex = 0:length(pss)-1;
pss_sym_ind = ltePSSIndices(enb,0,{'1based','re'});
sss = lteSSS(enb);
sss_arrayIndex = 0:length(sss)-1;
sss_sym_ind = lteSSSIndices(enb,0,{'1based','re'});
cfi_cw = lteCFI(enb);
pcfich_sym = ltePCFICH(enb,cfi_cw);
pcfich_sym_arrayIndex = 0:length(pcfich_sym)-1;
pcfich_sym_ind = ltePCFICHIndices(enb,{'1based','re'});
phich_sym = ltePHICH(enb,[PHICH_Group_Index,PHICH_Sequence_Index,HARQ_Indicator_Value]);
phich_sym_arrayIndex = 0:length(phich_sym)-1;
phich_sym_ind = ltePHICHIndices(enb,{'1based','re'});
pbch_sym = ltePBCH(enb,bch_cw);
pbch_sym_arrayIndex = 0:length(pbch_sym)-1;
pbch_sym_ind = ltePBCHIndices(enb,{'1based','re'});
pss_scale = 1.0;
sss_scale = 1.0;
phich_scale = 1.0;
pcfich_scale = 1.0;
pbch_scale = 1.0;
pdcch_scale = 1.0;
pdsch_scale = 1.0;
resourceGrid(pss_sym_ind) = pss_scale .* pss;
resourceGrid(sss_sym_ind) = sss_scale .* sss;
resourceGrid(pcfich_sym_ind) = pcfich_scale .* pcfich_sym;
resourceGrid(phich_sym_ind) = phich_scale .* phich_sym;
resourceGrid(pbch_sym_ind) = pbch_scale .* pbch_sym(1:length(pbch_sym_ind));
resourceGrid(pdcch_sym_ind) = pdcch_scale .* pdcch_sym;
resourceGrid(pdsch_sym_ind) = pdsch_scale .* pdsch_sym;
txFrameGrid = [txFrameGrid resourceGrid];
end;
[tx_waveform,tx_waveform_info] = lteOFDMModulate(enb,txFrameGrid);
[frame_offset,offset_corr]=lteDLFrameOffset(enb,tx_waveform);
The loop builds the ten subframes of one frame at 6 RB and joins them into txFrameGrid. The function lteOFDMModulate then converts the grid into one 10 ms waveform. At 6 RB, the toolbox uses a 128-point FFT and a sampling rate of 1.92 MHz, so the frame is 19200 samples long. The table below shows the result of lteDLFrameOffset.
Result = |
|
0 |
The offset is 0, because the waveform starts exactly at the frame boundary. The function finds it with the synchronization signals. The PSS alone repeats every 5 ms, in subframes 0 and 5, so it can only locate a half frame. The SSS resolves the rest: 36.211 v19.3.0 clause 6.11.2.1 defines a different combination of its two sequences for subframe 0 and for subframe 5. That difference tells the receiver which half frame is the first one.
The second output, offset_corr, holds the correlation that the offset comes from. The frame offset is the position of its peak, in samples at the sampling rate of the waveform.
lteDLFrameOffset : the number of samples before the first frame boundary.0 for the ideal signal : the waveform starts at the frame boundary.PSS every 5 ms, SSS different in subframes 0 and 5 : the SSS decides which half frame comes first.
Detecting Frame Offset for Faded Signal
A real receiver sees the signal only after the radio channel. This case passes the same waveform through lteFadingChannel before the detection, and the result is no longer 0. The question is what the new value means.
% First you have to define properites of a eNodeB.
% NDLRB indicate System Bandwith in the unit of RBs.
% NDLRB 6 = 1.4 Mhz, NDLRB 15 = 3.0 Mhz, NDLRB 25 = 5.0 Mhz,
% NDLRB 50 = 10 Mhz, NDLRB 75 = 15 Mhz, NDLRB 100 = 20 Mhz
% CellRefP indicate number of downlink Antenna. CellRefP = 1 means 1 transmission antenna (SISO)
% NCellID indicate PCI (Physical Cell Identity) of the Cell
% NSubframe indicate the subframe number.
enb.CyclicPrefix = 'Normal';
enb.PHICHDuration = 'Normal';
enb.Ng = 'Sixth';
enb.NDLRB = 6;
enb.CellRefP = 1;
enb.DuplexMode = 'FDD';
enb.NFrame = 0;
enb.NCellID = 0;
txFrameGrid = [];
for subframeNo = 0:9
enb.NSubframe = subframeNo;
enb.CFI = 1;
PHICH_Group_Index = 0;
PHICH_Sequence_Index = 1;
HARQ_Indicator_Value = 0; % 0 = NACK, 1 = ACK
dci.NDLRB = enb.NDLRB;
dci.DCIFormat = 'Format1A';
dci.AllocationType = 0;
dci.Allocation.RIV = 18;
dci.ModCoding = 10;
dci.HARQNo = 0;
dci.NewData = 0;
dci.TPCPUCCH = 0;
dci.DuplexMode = 'FDD';
dci.NTxAnts = 1;
[dciMessage,dciMessageBits] = lteDCI(enb,dci);
C_RNTI = 100;
pdcchConfig.RNTI = C_RNTI;
pdcchConfig.PDCCHFormat = 0;
codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
pdcchDims = ltePDCCHInfo(enb);
pdcchBits = -1*ones(pdcchDims.MTot, 1);
candidates = ltePDCCHSpace(enb, pdcchConfig, {'bits', '1based'});
pdcchBits ( candidates(1, 1) : candidates(1, 2) ) = codedDciBits;
pdcch_sym = ltePDCCH(enb, pdcchBits);
pdcch_sym_ind = ltePDCCHIndices(enb,{'1based','re'});
pdcch_sym_arrayIndex = 0:length(pdcch_sym)-1;
% Generating PDSCH Symbols
pdsch.NTxAnts = 1;
pdsch.NLayers = 1;
pdsch.TxScheme = 'Port0';
pdsch.Modulation = {'16QAM'};
pdsch.RV = 0;
pdsch.RNTI = C_RNTI;
START_RB = 0;
N_RB = 4; %enb.NDLRB;
pdsch_prbs = (START_RB:(START_RB+N_RB-1)).';
[pdsch_sym_ind,pdschIndInfo] = ltePDSCHIndices(enb,pdsch,pdsch_prbs,{'1based','re'});
codedTrBlkSize = pdschIndInfo.G;
dlschTransportBlk = round(rand(1,codedTrBlkSize));
codeword = lteDLSCH(enb,pdsch,codedTrBlkSize,dlschTransportBlk);
pdsch_sym = ltePDSCH(enb,pdsch,codeword);
pdsch_sym_arrayIndex = 0:length(pdsch_sym)-1;
%fill in the resource grid
resourceGrid = lteDLResourceGrid(enb);
rsAnt0 = lteCellRS(enb,0);
indAnt0 = lteCellRSIndices(enb,0);
resourceGrid(indAnt0) = rsAnt0;
mib_bits = lteMIB(enb);
bch_cw = lteBCH(enb,mib_bits);
pss = ltePSS(enb);
pss_arrayIndex = 0:length(pss)-1;
pss_sym_ind = ltePSSIndices(enb,0,{'1based','re'});
sss = lteSSS(enb);
sss_arrayIndex = 0:length(sss)-1;
sss_sym_ind = lteSSSIndices(enb,0,{'1based','re'});
cfi_cw = lteCFI(enb);
pcfich_sym = ltePCFICH(enb,cfi_cw);
pcfich_sym_arrayIndex = 0:length(pcfich_sym)-1;
pcfich_sym_ind = ltePCFICHIndices(enb,{'1based','re'});
phich_sym = ltePHICH(enb,[PHICH_Group_Index,PHICH_Sequence_Index,HARQ_Indicator_Value]);
phich_sym_arrayIndex = 0:length(phich_sym)-1;
phich_sym_ind = ltePHICHIndices(enb,{'1based','re'});
pbch_sym = ltePBCH(enb,bch_cw);
pbch_sym_arrayIndex = 0:length(pbch_sym)-1;
pbch_sym_ind = ltePBCHIndices(enb,{'1based','re'});
pss_scale = 1.0;
sss_scale = 1.0;
phich_scale = 1.0;
pcfich_scale = 1.0;
pbch_scale = 1.0;
pdcch_scale = 1.0;
pdsch_scale = 1.0;
resourceGrid(pss_sym_ind) = pss_scale .* pss;
resourceGrid(sss_sym_ind) = sss_scale .* sss;
resourceGrid(pcfich_sym_ind) = pcfich_scale .* pcfich_sym;
resourceGrid(phich_sym_ind) = phich_scale .* phich_sym;
resourceGrid(pbch_sym_ind) = pbch_scale .* pbch_sym(1:length(pbch_sym_ind));
resourceGrid(pdcch_sym_ind) = pdcch_scale .* pdcch_sym;
resourceGrid(pdsch_sym_ind) = pdsch_scale .* pdsch_sym;
txFrameGrid = [txFrameGrid resourceGrid];
end;
[tx_waveform,tx_waveform_info] = lteOFDMModulate(enb,txFrameGrid);
chcfg.Seed = 1;
chcfg.DelayProfile = 'EVA';
chcfg.NRxAnts = 1;
chcfg.InitPhase = 0;
chcfg.ModelType = 'GMEDS';
chcfg.NTerms = 16;
chcfg.NormalizeTxAnts = 'On';
chcfg.NormalizePathGains = 'On';
chcfg.DopplerFreq = 10;
chcfg.MIMOCorrelation = 'Low';
chcfg.SamplingRate = tx_waveform_info.SamplingRate;
chcfg.InitTime = 0;
rx_waveform = lteFadingChannel(chcfg,tx_waveform);
[frame_offset,offset_corr]=lteDLFrameOffset(enb,rx_waveform);
The channel uses the EVA delay profile with a Doppler frequency of 10 Hz and one receive antenna. EVA is one of the multipath models of 36.101 v20.0.0 Table B.2.1-3. It has nine taps, from 0 ns to 2510 ns, and the strongest after the first one sits at 370 ns with -0.6 dB. The Channel : Fading page shows what such a channel does to the waveform. The table below shows the new result.
Result = |
|
7 |
The offset is 7 samples, which is about 3.6 microseconds at 1.92 MHz. The transmitter has not moved the frame, since the ideal case gives 0. The difference is the delay that the channel adds to the signal. The EVA taps spread the signal over 2.51 microseconds, about 5 samples, and the fading model also filters the signal, which adds a delay of its own. So the received frame starts later than the transmitted one, and the function reports where it starts in the received waveform.
This is the value the receiver needs. The OFDM demodulator should start at the frame as received, not as transmitted. So a receiver removes the first frame_offset samples of rx_waveform before it calls lteOFDMDemodulate.
7 samples for the faded signal : about 3.6 microseconds at 1.92 MHz.EVA spreads the signal over 2.51 microseconds : 36.101 Table B.2.1-3.The offset is the received frame start : use it to trim rx_waveform before the demodulation.
Disclaimer !
This page is only to show you the overall logics and visualization for various LTE physical layer channels. I haven't investigated much about verifying about the accuracy.
If you think the code is not so efficient, it is 100% my fault. I haven't made any effort for effiecient code. I just tried to create code as simple as possible for the readers. As you know, easy-to-read code is not always efficient for a specific chipset.
If you find any mistake in terms of accuracy, it is also very highly likely be my fault. Not the problem of Matlab tool box itself.
Any comment and corrections if you find any mistake will be welcome and appreciated.
Reference
[1] 3GPP TS 36.211 v19.3.0 - clause 6.11, Synchronization signals
[2] 3GPP TS 36.101 v20.0.0 - Table B.2.1-3, Extended Vehicular A model