Main Content

NB-IoT Downlink In-Band and Guardband Waveform Generation and Analysis

This example shows how to generate a narrowband internet of things (NB-IoT) downlink waveform for in-band and guardband operation modes on an LTE carrier by using the LTE Toolbox™. The example also shows an analysis of the quality of the recovered NB-IoT physical downlink shared channel (NPDSCH) through error vector magnitude (EVM) measurements.


To support maximum flexibility of the NB-IoT deployment, 3GPP defines these three NB-IoT modes of operation:

  • Standalone: NB-IoT carrier deployed outside the LTE spectrum, e.g., the spectrum used for GSM or satellite communications

  • Guardband: NB-IoT carrier deployed in the guardband between two LTE carriers

  • In-band: NB-IoT carrier deployed in resource blocks of an LTE carrier

This example focuses on the in-band and guardband modes. For more information on generating a standalone NB-IoT downlink waveform, see the NB-IoT Downlink Waveform Generation example. This figure shows a sketch of in-band and guardband modes for a 5 MHz LTE carrier.

In-band mode can be further grouped depending on the physical cell identity (PCI) used, Inband-SamePCI and Inband-DifferentPCI. If Inband-SamePCI, the physical layer cell identity and PCI are the same and the user equipment (UE) can make assumptions about the ports and channel from LTE signals. The NB-IoT master information block (MIB-NB) indicates the operation mode. The network can use radio resource control information to allocate a non-anchor carrier to a UE operating in an anchor carrier, see Section of TS 36.331 and sections and in [ 5 ].

Table 16.8-1 of TS 36.213 restricts the allowed physical resource block (PRB) indices for in-band mode of an NB-IoT anchor carrier to these values. In-band mode of NB-IoT is not supported on a 1.4 MHz LTE carrier. For guardband mode of NB-IoT, the allowed PRB indices depend on the guardband size of the LTE carrier. Guardband mode of NB-IoT is not supported on a 1.4 MHz and 3 MHz LTE carrier. This table shows the allowed PRB indices for both in-band and guardband modes.

prbTable = nbAllowedPRB()
prbTable=6×3 table
       LTE Bandwidth             Allowed PRB indices for NB-IoT in-band mode          Allowed PRB indices for NB-IoT guardband mode
    ___________________    _______________________________________________________    _____________________________________________

    "1.4 MHz (  6 RBs)"    {1x0 double                                           }       {1x0 double                          }    
    "  3 MHz ( 15 RBs)"    {[                                               2 12]}       {1x0 double                          }    
    "  5 MHz ( 25 RBs)"    {[                                          2 7 17 22]}       {[                             -1 25]}    
    " 10 MHz ( 50 RBs)"    {[                              4 9 14 19 30 35 40 45]}       {[                       -2 -1 50 51]}    
    " 15 MHz ( 75 RBs)"    {[            2 7 12 17 22 27 32 42 47 52 57 62 67 72]}       {[           -4 -3 -2 -1 75 76 77 78]}    
    " 20 MHz (100 RBs)"    {[4 9 14 19 24 29 34 39 44 55 60 65 70 75 80 85 90 95]}       {[-5 -4 -3 -2 -1 100 101 102 103 104]}    

The example shows how to:

  • Generate a waveform for an NB-IoT in-band operation mode

  • Retrieve the original NB-IoT waveform from the received combined waveform containing both the NB-IoT and the LTE waveforms

  • Measure NPDSCH EVM to verify the quality of the recovered NB-IoT waveform

These figures show the steps to generate the waveform and the processing steps at the receiver to compute the NPDSCH EVM. The frequency correction at the receiver introduces a phase offset to each OFDM symbol. For this reason, the example applies symbol phase compensation to the NB-IoT resource grid before combining it with the LTE grid.

Simulation Configuration

The example specifies an in-band operation mode of an NB-IoT anchor carrier on a 5 MHz LTE carrier. You can use the nbPRB parameter to change the index of the LTE PRB for NB-IoT allocation. To study the effect of the LTE interference on the NPDSCH EVM, run the example again without LTE interference by setting lteDisabled to true.

operationMode = "Inband-SamePCI"; % NB-IoT operation mode
ltecfg = struct(); % LTE configuration
ltecfg.TotSubframes = 10; % Number of subframes
ltecfg.NDLRB = 25; % Number of downlink resource blocks
nbPRB = 7; % PRB in which the NB-IoT is deployed (0-based)
lteDisabled = false; % Set to true to disable the LTE component
nbPowerBoost = 6; % NB-IoT power boost in dB

% Verify that the PRB chosen for the NB-IoT operation mode in the LTE carrier is allowed.

NB-IoT Downlink Configuration and Resource Grid Generation

Configure the NB-IoT downlink waveform generator. The example uses the NBIoTDownlinkWaveformGenerator class to generate the NB-IoT resource grid. See the NB-IoT Downlink Waveform Generation example for more information about NBIoTDownlinkWaveformGenerator.

ngen = NBIoTDownlinkWaveformGenerator;
ngen.Config.CellRefP = 1;
ngen.Config.NNCellID = 0;
ngen.Config.NFrame = 0;
ngen.Config.TotSubframes = ltecfg.TotSubframes;
ngen.Config.OperationMode = operationMode;
ngen.Config.NPDSCH.StartSubframe = 2;
ngen.Config.NPDSCH.NRep = 1;
ngen.Config.Windowing = 3; % Set Windowing to 3, as shown in Table E.5.1-1a of TS 36.104

Display the resource grid.


Generate the NB-IoT downlink waveform and resource grid.

[nbWaveform,nbGrid,nbInfo] = generateWaveform(ngen);
nbInfo = struct with fields:
            SamplingRate: 1920000
                    Nfft: 128
               Windowing: 3
     CyclicPrefixLengths: [10 9 9 9 9 9 9 10 9 9 9 9 9 9]
    SubframeChannelTypes: ["NPBCH"    "NPDCCH"    "NPDSCH"    "NPDSCH"    "SIB1-NB"    "NPSS"    "NPDSCH"    "NPDSCH"    "Unused"    "NSSS"]

LTE Downlink Configuration and Resource Grid Generation

Configure the LTE carrier. If you selected in-band operation mode, the example leaves the nbPRB PRB index empty in the LTE configuration.

nbPRB = double(nbPRB);
ltecfg.PDSCH.PRBSet = (0:ltecfg.NDLRB-1)'; % Full PRB allocation for LTE
if contains(ngen.Config.OperationMode,'Inband')
    ltecfg.PDSCH.PRBSet(nbPRB+1) = []; % Leave nbPRB empty for in-band NB-IoT

Generate the LTE resource grid. The example uses lteRMCDLTool to generate the wideband resource grid.

[~,lteGrid,lteInfo] = lteRMCDLTool(ltecfg,[1 0 0 1]);

Waveform Generation

The example combines LTE and NB-IoT resource grids before generating the waveform. The hNBInbandGuardbandCombineGrid function applies pre-OFDM symbol phase compensation to the NB-IoT grid to deal with the distortion that the receiver introduces when shifting the received waveform to bring NB-IoT in baseband.

Generate the combined resource grid and get the NB-IoT frequency offset.

% Create the parameter structure needed to generate the combined grid
combGridParams = struct();
combGridParams.OperationMode = ngen.Config.OperationMode;
combGridParams.NBPRB = nbPRB;
combGridParams.OFDMInfo = nbInfo;
combGridParams.LTEDisabled = lteDisabled;
[combGrid,offset] = hNBInbandGuardbandCombinedGrid(combGridParams,lteGrid,nbGrid*db2mag(nbPowerBoost));

Generate the waveform.

OSR = lteInfo.SamplingRate/nbInfo.SamplingRate; % Oversampling ratio for NB-IoT
wavecfg.Windowing = ngen.Config.Windowing*OSR; % Use the same windowing as the NB-IoT waveform
txWaveform = lteOFDMModulate(wavecfg,combGrid);

Plot the power spectrum of the transmitted waveform.

txPlot = spectrumAnalyzer('SampleRate',lteInfo.SamplingRate,'Title','Transmitted Waveform Power Spectrum');

NB-IoT Synchronization and Filtering

This section follows these steps:

  • Frequency correction. Shift the received waveform in frequency to bring the NB-IoT spectrum to baseband (0 Hz).

  • Filter out the LTE component and downsample. Downsample the waveform to the NB-IoT sampling rate and filter out the frequencies outside the NB-IoT band.

  • Time synchronization. Remove any potential time delay added by the filter.

Plot the spectrogram of the received waveform. This plot shows the frequency occupied by the NB-IoT component in the received wideband waveform.

rxWaveform = txWaveform;

Frequency Correction

Shift the received waveform to bring the NB-IoT component to baseband. The plot shows the power spectrum of the received waveform after the frequency correction.

rxWaveformB = lteFrequencyCorrect(ltecfg,rxWaveform,offset); % Received waveform with NB-IoT in baseband
combinedSpecPlotB = spectrumAnalyzer('SampleRate',lteInfo.SamplingRate,'Title','Received Waveform Power Spectrum with NB-IoT in Baseband');

Filtering and Downsampling of NB-IoT Waveform

This example uses the resample function to downsample the wideband waveform to the nominal NB-IoT sampling rate of 1.92 MHz. Furthermore, the default FIR antialiasing lowpass filter implemented in the resample function filters out the unwanted LTE waveform, without the need of an additional lowpass filter.

rxwave = resample(rxWaveformB,1,OSR);

Plot the power spectrum of the recovered NB-IoT waveform against the power spectrum of the original NB-IoT waveform generated by the NB-IoT waveform generator NBIoTDownlinkWaveformGenerator. Because the power of the generated waveform depends on the FFT size, divide the original waveform by the oversampling rate so that both waveforms have a comparable power.

filteredSpecPlot = spectrumAnalyzer('SampleRate',nbInfo.SamplingRate,'Title','Original and Recovered NB-IoT Waveform Power Spectrum',...
    'ChannelNames',{'Original NB-IoT waveform','Recovered NB-IoT waveform'},'ShowLegend',true);

Plot the spectrogram of the recovered NB-IoT waveform. This plot shows the baseband narrowband waveform after extracting it from the received wideband waveform.


Time Synchronization

Extract NB-IoT configuration parameters for time synchronization and EVM measurements.

enb = ngen.Config;
enb.NSubframe = lteInfo.NSubframe;

Apply time synchronization to the resulting waveform.

timeOffset = lteNBDLFrameOffset(enb,rxwave); % Time delay in samples
rxwave = rxwave(1+timeOffset:end,:);

EVM Measurements

Channel Estimator Configuration for EVM measurements

Parameterize the channel estimator at the receiver end using the structure cec.

cec = struct;                        % Channel estimation config structure
cec.PilotAverage = 'UserDefined';    % Type of pilot symbol averaging
cec.FreqWindow = 13;                 % Frequency window size
cec.TimeWindow = 9;                  % Time window size
cec.InterpType = 'Cubic';            % 2D interpolation type
cec.InterpWindow = 'Centered';       % Interpolation window type
cec.InterpWinSize = 1;               % Interpolation window size
cec.Reference = 'NRS';               % Reference signal for channel estimation

Process EVM

The hNPDSCHEVM function provides per subframe and average EVM measurements. The example also displays plots with the EVM versus time and subcarriers.

[evmmeas,plots] = hNPDSCHEVM(enb,cec,rxwave,nbInfo);
EVM subframe 2: 0.210%
EVM subframe 3: 0.176%
EVM subframe 6: 0.207%
EVM subframe 7: 0.192%
Averaged EVM frame 0: 0.197%
Averaged overall EVM: 0.197%


  1. 3GPP TS 36.101. “Evolved Universal Terrestrial Radio Access (E-UTRA); User Equipment (UE) Radio Transmission and Reception.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

  2. 3GPP TS 36.104. "Evolved Universal Terrestrial Radio Access (E-UTRA); Base Station (BS) Radio Transmission and Reception." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

  3. 3GPP TS 36.213. "Evolved Universal Terrestrial Radio Access (E-UTRA); Physical Layer Procedures." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

  4. 3GPP TS 36.331. "Evolved Universal Terrestrial Radio Access (E-UTRA); Radio Resource Control (RRC); Protocol specification." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

  5. O. Liberg, M. Sundberg, Y.-P. Wang, J. Bergman, J. Sachs and G. Wikstrom, Cellular Internet of Things: From Massive Deployments to Critical 5G Applications, Elsevier, 2020.

Local Functions

function prbTable = nbAllowedPRB()
    % Generate a table showing the PRB indices allowed for NB-IoT in-band
    % and guardband operation mode for each LTE bandwidth.

    NDLRBList = [6 15 25 50 75 100];
    bwMHz = [1.4 3 5 10 15 20]; % Bandwidth in MHz
    bw = (pad(string(bwMHz),'left') + repmat(" MHz (",size(bwMHz)) + pad(string(NDLRBList),'left') + repmat(" RBs)",size(bwMHz)))';

    % In-band mode
    % The allowed PRB indices for in-band mode of NB-IoT anchor
    % carrier are derived from Table 16.8-1 of TS 36.213.
    prbIndexOdd = [-35:5:-5 5:5:35]; % DC (i.e., PRB 0) is excluded
    prbIndexEven = [-46:5:-6 5:5:45]; % DC (i.e., PRB 0) is excluded
    PRBInband = cell(length(NDLRBList),1);
    for ibw = 1:length(NDLRBList)
        if mod(NDLRBList(ibw),2) % Odd
            prbTemp = prbIndexOdd + floor(NDLRBList(ibw)/2);
        else % Even
            prbTemp = prbIndexEven + floor(NDLRBList(ibw)/2);
        prbTemp(prbTemp<0 | prbTemp>=NDLRBList(ibw)) = [];
        PRBInband{ibw} = prbTemp;
    PRBVariableNameInband = "Allowed PRB indices for NB-IoT in-band mode";

    % Guardband mode
    % The allowed PRB indices for NB-IoT guardband mode are derived
    % here for all channel bandwidths.
    totalGuardHz = bwMHz*1e6 - NDLRBList*12*15e3; % Total guardband in Hz
    NRBGuard = floor((totalGuardHz/2) / (12*15e3)); % Number of RBs allowed on each side of the guardband for all BWs
    PRBGuard = cellfun(@(x,y)([-x:-1, y+(0:(x-1))]),num2cell(NRBGuard(:)),num2cell(NDLRBList(:)),'UniformOutput',false); % Allowed PRB indices for guardband (0-based)
    PRBVariableNameGuard = "Allowed PRB indices for NB-IoT guardband mode";

    prbTable = table(bw,PRBInband,PRBGuard);
    prbTable.Properties.VariableNames = ["LTE Bandwidth" PRBVariableNameInband PRBVariableNameGuard];

function verifyNBPRB(nbPRB,NDLRB,operationMode)
    % Check whether the PRB chosen for the NB-IoT operation mode in the LTE
    % carrier is allowed.
    prbTable = nbAllowedPRB();

    r = contains(prbTable{:,1},string(NDLRB)+" RBs"); % prbTable row associated to the given bandwidth
    c = 1+contains(operationMode,'Inband')*1+contains(operationMode,'Guard')*2; % prbTable column associated to the given operation mode

    errorFlag = ismember(nbPRB,prbTable{r,c}{1}); % If true, the selected nbPRB is allowed
    tmp = extract(prbTable{r,1},digitsPattern);
    msg = "The chosen PRB index ("+string(nbPRB)+") is invalid for "+operationMode+" operation mode on a "+string(tmp(1))+...
        " MHz LTE carrier. See 'prbTable' for the allowed PRB indices for all combinations of LTE bandwidth and operation mode.";
    assert(errorFlag,msg); % Throws an error if the chosen nbPRB is invalid for the given combination of NDLRB and operation mode