This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

NB-IoT NPUSCH Block Error Rate Simulation

This example shows how LTE Toolbox™ can be used to create an NB-IoT Narrowband Physical Uplink Shared Channel (NPUSCH) Block Error Rate (BLER) simulation in frequency-selective fading and Additive White Gaussian Noise (AWGN) using LTE Toolbox™.

Introduction

3GPP introduced a new air interface, Narrowband IoT (NB-IoT) optimized for low data rate machine type communications in LTE-Advanced Pro Release 13. NB-IoT provides cost and power efficiency improvements as it avoids the need for complex signaling overhead required for LTE based systems.

The example generates an NB-IoT NPUSCH BLER curve for a number of SNR points and transmission parameters. NPUSCH and narrowband demodulation reference signal (DM-RS) are transmitted in all slots. Operating on a slot by slot basis for each SNR point, the following steps are performed for the BLER calculation:

  • A resource grid populated with NPUSCH is generated

  • The grid is then SC-FDMA modulated to create the baseband waveform

  • This waveform is then passed through a noisy fading channel

  • Receiver operations (SC-FDMA demodulation, channel estimation, and equalization) are performed

  • The equalized symbols are decoded to obtain the block CRC

  • The performance of the NPUSCH is determined using the block CRC result at the output of the channel decoder

Simulation Configuration

The simulation length is 5 UL-SCH transport blocks for a number of SNR points SNRdB for different repetitions simReps. A larger number of transport blocks, numTrBlks should be used to produce meaningful throughput results. SNRdB and simReps can be a specified as a scalar or a numeric array.

numTrBlks = 5;              % Number of simulated transport blocks
SNRdB = [-20 -18 -15 -12.5 -10 -6.4 -3.5 0.7];  % Range of SNR values in dB
simReps = [2 16 64];        % Repetitions to simulate

NPUSCH Configuration

In this section we configure the parameters required for NPUSCH generation. There are two types of payload defined for NPUSCH transmission, format 1 ('Data') and format 2 ('Control'). For format 1, the UE uses the combination of MCS (modulation and coding scheme) and resource assignment signaled via the DCI to determine the transport block size from the set defined in TS 36.213 Table 16.5.1.2-2 [ 3 ]. For format 2, the NPUSCH carries the 1 bit ACK/NACK. In this example, the format is specified via the parameter chs.NPUSCHFormat and the transport block length via the parameter infoLen. The parameters used in this example are as per the A16-5 FRC defined in TS 36.104 Annex A.16 [ 4 ].

HARQ Operation NB-IoT has one or two UL HARQ processes and HARQ operation is asynchronous for NB-IoT UEs except for the repetitions within a bundle. Bundling operation relies on the HARQ entity for invoking the same HARQ process for each transmission that is part of the same bundle. Within a bundle HARQ retransmissions are non-adaptive and are triggered without waiting for feedback from previous transmissions according to repetitions. An uplink grant corresponding to a new transmission or a retransmission of the bundle is only received after the last repetition of the bundle. A retransmission of a bundle is also a bundle. For more details, see TS 36.321 section 5.4.2 [ 5 ]. In this example the bundle retransmissions are not modeled.

ue = struct();                        % Initialize the UE structure
ue.NBULSubcarrierSpacing = '15kHz';   % 3.75kHz, 15kHz
ue.NNCellID = 10;                     % Narrowband cell identity

chs = struct();
chs.NPUSCHFormat = 'Data';        % NPUSCH payload type ('Data' or 'Control')
% The number of subcarriers used for NPUSCH 'NscRU' depends on the NPUSCH
% format and subcarrier spacing 'NBULSubcarrierSpacing' as shown in TS 36.211
% Table 10.1.2.3-1. There are 1,3,6 or 12 continuous subcarriers for NPUSCH
chs.NBULSubcarrierSet = 0:11;     % Range is 0-11 (15kHz); 0-47 (3.75kHz)
chs.NRUsc = length(chs.NBULSubcarrierSet);
% The symbol modulation depends on the NPUSCH format and NscRU as given by
% TS 36.211 Table 10.1.3.2-1
chs.Modulation = 'QPSK';
chs.CyclicShift = 0;        % Cyclic shift required when NRUsc = 3 or 6
chs.RNTI = 20;              % RNTI value
chs.NLayers = 1;            % Number of layers
chs.NRU = 1;                % Number of resource units
chs.SlotIdx = 0;            % The slot index
chs.NTurboDecIts = 5;       % Number of turbo decoder iterations

% RV offset signaled via DCI (See 36.213 16.5.1.2)
rvDCI = 0;
% Calculate the RVSeq used according to the RV offset
rvSeq = [2*mod(rvDCI+0,2)  2*mod(rvDCI+1,2)];

if strcmpi(chs.NPUSCHFormat,'Data')
    infoLen = 136;   % Transport block size for NPUSCH format 1
elseif strcmpi(chs.NPUSCHFormat,'Control')
    if ~strcmpi(chs.Modulation,'BPSK')
        error('For NPUSCH format 2 (Control), the modulation must be BPSK');
    end
    infoLen = 1;    % ACK/NACK bit for NPUSCH format 2
    if length(chs.NBULSubcarrierSet) ~= 1
        error('The number of subcarriers must be 1 for control information');
    end
end

Propagation Channel Model Configuration

The structure channel contains the channel model configuration parameters.

channel = struct;                    % Initialize channel config structure
channel.Seed = 6;                    % Channel seed
channel.NRxAnts = 2;                 % 2 receive antennas
channel.DelayProfile ='ETU';         % Delay profile
channel.DopplerFreq = 1;             % Doppler frequency in Hz
channel.MIMOCorrelation = 'Low';     % Multi-antenna correlation
channel.NTerms = 16;                 % Oscillators used in fading model
channel.ModelType = 'GMEDS';         % Rayleigh fading model type
channel.InitPhase = 'Random';        % Random initial phases
channel.NormalizePathGains = 'On';   % Normalize delay profile power
channel.NormalizeTxAnts = 'On';      % Normalize for transmit antennas

Channel Estimator Configuration

In this example a perfect channel estimator is used which returns the channel modeled by the functions lteFadingChannel and lteHSTChannel. lteULPerfectChannelEstimate provides a perfect MIMO channel estimate after OFDM modulation. This is achieved by setting the channel to the desired configuration and sending a set of known symbols through it for each transmit antenna in turn.

For DM-RS signals in NPUSCH format 1, sequence-group hopping can be enabled or disabled by the higher layer cell-specific parameter groupHoppingEnabled. Sequence-group hopping for a particular UE can be disabled through the higher layer parameter groupHoppingDisabled as described in TS 36.211 Section 10.1.4.1.3 [ 1 ]. In this example, we use the SeqGroupHopping parameter to enable or disable sequence-group hopping

chs.SeqGroupHopping = true; % Enable/Disable Sequence-Group Hopping for UE
chs.Deltass = 0;            % Higher-layer parameter groupAssignmentNPUSCH

% Get number of time slots in a resource unit NULSlots
if strcmpi(chs.NPUSCHFormat,'Data')
    if strcmpi(ue.NBULSubcarrierSpacing,'3.75kHz')
        chs.NULSlots = 16;
    elseif strcmpi(ue.NBULSubcarrierSpacing,'15kHz')
        if chs.NRUsc == 12
            chs.NULSlots = 2;
        elseif chs.NRUsc == 6
            chs.NULSlots = 4;
        elseif chs.NRUsc == 3
            chs.NULSlots = 8;
        elseif chs.NRUsc == 1
            chs.NULSlots = 16;
        else
            error('Invalid number of subcarriers (%d), should be one of 1,3,6,12',chs.NRUsc);
        end
    else
        error('Invalid subcarrier spacing (%s), should be either 3.75kHz or 15kHz',ue.NBULSubcarrierSpacing);
    end
elseif strcmpi(chs.NPUSCHFormat,'Control')
    chs.NULSlots = 4;
else
    error('Invalid NPUSCH Format (%s), should be either Data or Control',chs.NPUSCHFormat);
end

Block Error Rate Simulation Loop

This part of the example shows how to perform NB-IoT NPUSCH link level simulation and plot BLER results for a number of repetition levels. For NPUSCH format 1 transmission for UL data transfer, a random stream of bits with the size of the desired transport block is CRC encoded, turbo encoded and rate matched to create the NPUSCH bits. These bits are interleaved per resource unit to apply a time-first mapping to create the codeword. For NPUSCH format 2 used for signaling HARQ feedback for NPDSCH, the transport channel encoding consists of bit repetitions to form the codeword. Scrambling, modulation, layer mapping and precoding are then applied to the codeword to form the complex NPUSCH symbols. The NPUSCH symbols and the corresponding DM-RS are then mapped on to the resource grid and the grid is SC-FDMA modulated to generate the time domain waveform. The waveform is then passed through a fading channel with AWGN. The received waveform is synchronized and a perfect channel estimate is calculated which is used to perform MMSE equalization to recover the transmitted grid. The NPUSCH symbols are then extracted and demodulation and channel decoding are performed to recover the transport block. After de-scrambling, the repetitive slots are soft-combined before rate recovery. The transport block error rate is calculated for each SNR point. The evaluation of the block error rate is based on the assumption that all the slots in a bundle are used to decode the transport block at the UE. A bundle is defined in the MAC layer (see 3GPP TS 36.321 5.4.2.1 [ 3 ]) as the NPUSCH.NRU NPUSCH.NULSlots NPUSCH.NRep slots used to carry a transport block.

% Get the slot grid and number of slots per frame
if strcmpi(ue.NBULSubcarrierSpacing,'15kHz')
    slotGridSize = [12, 7];
    NSlotsPerFrame = 20;      % Slots 0...19
    tSlot = 5e-4;
else
    slotGridSize = [48, 7];
    NSlotsPerFrame = 5;       % Slots 0...4
    tSlot = 0.02;
end

for repIdx = 1:numel(simReps)

    chs.NRep = simReps(repIdx); % Number of repetitions of the NPUSCH
    NSlotsPerBundle = chs.NRU*chs.NULSlots*chs.NRep; % Number of slots in a codeword bundle
    TotNSlots = numTrBlks*NSlotsPerBundle;   % Total number of simulated slots

    % Initialize BLER and throughput result
    maxThroughput = zeros(length(SNRdB),1);
    simThroughput = zeros(length(SNRdB),1);
    bler = zeros(1,numel(SNRdB)); % Initialize BLER result

    % The temporary variables 'ue_init', 'chs_init' and 'channel_init' are used to create
    % the temporary variables 'ue', 'chs' and 'channel' within the SNR loop to create
    % independent simulation loops for the 'parfor' loop
    ue_init = ue;
    chs_init = chs;
    channel_init = channel;

    for snrIdx = 1:numel(SNRdB)
    % parfor snrIdx = 1:numel(SNRdB)
    % To enable the use of parallel computing for increased speed comment out
    % the 'for' statement above and uncomment the 'parfor' statement below.
    % This needs the Parallel Computing Toolbox (TM). If this is not installed
    % 'parfor' will default to the normal 'for' statement.

        % Set the random number generator seed depending on the loop variable
        % to ensure independent random streams
        rng(snrIdx,'combRecursive');

        ue = ue_init;     % Initialize ue configuration
        chs = chs_init;   % Initialize chs configuration
        channel = channel_init; % Initialize fading channel configuration
        numBlkErrors = 0; % Number of transport blocks with errors
        dstateULSCH = []; % UL-SCH, need to be re-initialized for each trblk
        estate = [];      % Initialize NPDSCH encoder state
        dstate = [];      % Initialize NPDSCH decoder state
        trblk = [];       % Initialize the transport block
        txgrid = [];      % Full grid initialization
        statedmrs = [];   % DM-RS state

        % Display the number of slots being generated
        fprintf('\nGenerating %d slots corresponding to %d transport block(s) at %gdB SNR\n',TotNSlots,numTrBlks,SNRdB(snrIdx));

        for slotIdx = 0+(0:TotNSlots-1)
            % Calculate the frame number and slot number within the frame
            ue.NFrame = fix(slotIdx/NSlotsPerFrame);
            ue.NSlot = mod(slotIdx,NSlotsPerFrame);
            % Create the slot grid
            slotGrid = zeros(slotGridSize);

            if isempty(trblk)
               if strcmpi(chs.NPUSCHFormat,'Data')
                   % UL-SCH encoding is performed for the two RV values used for
                   % transmitting the codewords. The RV sequence used is determined
                   % from the rvDCI value signaled in the DCI and alternates
                   % between 0 and 2 as given in TS 36.213 Section 16.5.1.2

                   % Define the transport block which will be encoded to create the
                   % codewords for different RV
                   trblk = randi([0 1],infoLen,1);

                   % Determine the coded transport block size
                   [~, info] = hNPUSCHIndices(ue,chs);
                   outblklen = info.G;
                   % Create the codewords corresponding to the two RV values used
                   % in the first and second block, this will be repeated till all
                   % blocks are transmitted
                   chs.RV = rvSeq(1); % RV for the first block
                   cw = hNULSCH(chs,outblklen,trblk); % CRC and Turbo coding is repeated
                   chs.RV = rvSeq(2); % RV for the second block
                   cw = [cw hNULSCH(chs,outblklen,trblk)]; %#ok<AGROW> % CRC and Turbo coding is repeated
               else
                   trblk = randi([0 1],1); % 1 bit ACK
                   % For ACK, the same codeword is transmitted every block as
                   % defined in TS 36.212 Section 6.3.3
                   cw = hNULSCH(trblk);
               end
               blockIdx = 0; % First block to be transmitted
            end

            % Set the RV used for the current transport block
            chs.RV = rvSeq(mod(blockIdx,size(rvSeq,2))+1);

            % NPUSCH encoding and mapping onto the slot grid
            [txsym, estate] = hNPUSCH(ue,chs,cw(:,mod(blockIdx,size(cw,2))+1),estate);
            slotGrid(hNPUSCHIndices(ue,chs)) = txsym;
            % NPUSCH DRS and mapping on to the slot grid
            [dmrs,statedmrs] = hNPUSCHDRS(ue,chs,statedmrs);
            slotGrid(hNPUSCHDRSIndices(ue,chs)) = dmrs;

            % If a full block is transmitted, increment the clock counter so that
            % the correct codeword can be selected
            if estate.EndOfBlk
                blockIdx = blockIdx + 1;
            end

            % Perform SC-FDMA modulation to create the time domain waveform
            [txWaveform,scfdmaInfo] = lteSCFDMAModulate(ue,chs,slotGrid);

            % Add 25 sample padding. This is to cover the range of delays
            % expected from channel modeling (a combination of
            % implementation delay and channel delay spread)
            txWaveform =  [txWaveform; zeros(25, size(txWaveform,2))]; %#ok<AGROW>

            % Initialize channel time for each slot
            channel.InitTime = slotIdx*tSlot;

            % Pass data through channel model
            channel.SamplingRate = scfdmaInfo.SamplingRate;
            [rxWaveform,fadingInfo] = lteFadingChannel(channel, txWaveform);

            % Calculate noise gain
            SNR = 10^(SNRdB(snrIdx)/20);

            % Normalize noise power to take account of sampling rate, which is
            % a function of the IFFT size used in SC-FDMA modulation
            N0 = 1/(sqrt(2.0*double(scfdmaInfo.Nfft))*SNR);

            % Create additive white Gaussian noise
            noise = N0*complex(randn(size(rxWaveform)), ...
                                randn(size(rxWaveform)));

            % Add AWGN to the received time domain waveform
            rxWaveform = rxWaveform + noise;

            %------------------------------------------------------------------
            %            Receiver
            %------------------------------------------------------------------

            % Perform timing synchronization, extract the appropriate
            % subframe of the received waveform, and perform OFDM
            % demodulation
            offset  = hPerfectTimingEstimate(fadingInfo);

            % Synchronize the received waveform
            rxWaveform = rxWaveform(1+offset:end, :);

            % Perform SC-FDMA demodulation on the received data to recreate the
            % resource grid
            rxSlot = lteSCFDMADemodulate(ue,chs,rxWaveform);

            % Perfect channel estimation
            ue.TotSlots = 1; % Channel estimate for 1 slot
            estChannelGrid = lteULPerfectChannelEstimate(ue,chs,channel, offset);
            noiseGrid = lteSCFDMADemodulate(ue,chs,noise(1+offset:end ,:));
            noiseEst = var(noiseGrid(:));

            % Get NPUSCH indices
            npuschIndices = hNPUSCHIndices(ue,chs);

            % Get NPUSCH resource elements from the received slot
            [rxNpdschSymbols, npdschHest] = lteExtractResources(npuschIndices, ...
                rxSlot, estChannelGrid);

            % Decode NPUSCH
            [rxcw,dstate,symbols] = hNPUSCHDecode(...
                                 ue, chs, rxNpdschSymbols, npdschHest, noiseEst,dstate);

            % Decode the transport block when all the slots in a block have
            % been received
            if dstate.EndOfBlk
                % Soft-combining at transport channel decoder
                [out, err, dstateULSCH] = hNULSCHDecode(chs,infoLen,rxcw,dstateULSCH);
            end

            % If all the slots in the bundle have been received, count the
            % errors and reinitialize for the next bundle
            if dstate.EndOfTx
               if strcmpi(chs.NPUSCHFormat,'Control')
                   err = ~isequal(out,trblk);
               end
               numBlkErrors = numBlkErrors + err;
               % Re-initialize to enable the transmission of a new transport
               % block
               trblk = [];
               dstateULSCH = [];
               statedmrs = [];
            end
        end
        % Calculate the block error rate
        bler(snrIdx) = numBlkErrors/numTrBlks;
        fprintf('NPUSCH BLER = %.4f \n',bler(snrIdx));
        % Calculate the maximum and simulated throughput
        maxThroughput(snrIdx) = infoLen*numTrBlks; % Max possible throughput
        simThroughput(snrIdx) = infoLen*(numTrBlks-numBlkErrors);  % Simulated throughput
        fprintf('NPUSCH Throughput(%%) = %.4f %%\n',simThroughput(snrIdx)*100/maxThroughput(snrIdx));

    end

    % Plot Block Error Rate vs SNR Results
    if repIdx == 1
        figure;
        grid on;
        hold on;
        xlabel('SNR (dB)');
        ylabel('BLER');
        legendstr = {['NRep = ' num2str(chs_init.NRep)]};
    else
        legendstr = [legendstr ['NRep = ' num2str(chs_init.NRep)]]; %#ok<AGROW>
    end
    plot(SNRdB, bler, '-o');


end
% Set figure title
title(sprintf(' NPUSCH Carrying %s: NRUsc = %d, NRU = %d, TBS = %d',...
    chs_init.NPUSCHFormat,chs_init.NRUsc,chs_init.NRU,infoLen));
legend(legendstr);
Generating 20 slots corresponding to 5 transport block(s) at -20dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -18dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -15dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -12.5dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -10dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -6.4dB SNR
NPUSCH BLER = 0.4000 
NPUSCH Throughput(%) = 60.0000 %

Generating 20 slots corresponding to 5 transport block(s) at -3.5dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 20 slots corresponding to 5 transport block(s) at 0.7dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -20dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -18dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -15dB SNR
NPUSCH BLER = 0.6000 
NPUSCH Throughput(%) = 40.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -12.5dB SNR
NPUSCH BLER = 0.2000 
NPUSCH Throughput(%) = 80.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -10dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -6.4dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 160 slots corresponding to 5 transport block(s) at -3.5dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 160 slots corresponding to 5 transport block(s) at 0.7dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -20dB SNR
NPUSCH BLER = 1.0000 
NPUSCH Throughput(%) = 0.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -18dB SNR
NPUSCH BLER = 0.6000 
NPUSCH Throughput(%) = 40.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -15dB SNR
NPUSCH BLER = 0.2000 
NPUSCH Throughput(%) = 80.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -12.5dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -10dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -6.4dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 640 slots corresponding to 5 transport block(s) at -3.5dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

Generating 640 slots corresponding to 5 transport block(s) at 0.7dB SNR
NPUSCH BLER = 0.0000 
NPUSCH Throughput(%) = 100.0000 %

A larger number of transport blocks, numTrBlks should be used to produce meaningful throughput results. The following plot shows the simulation run with numTrBlks set to 5000 for different repetitions.

Selected Bibliography

  1. 3GPP TS 36.211 "Physical channels and modulation"

  2. 3GPP TS 36.212 "Multiplexing and channel coding"

  3. 3GPP TS 36.213 "Physical layer procedures"

  4. 3GPP TS 36.104 "Base Station (BS) radio transmission and reception"

  5. 3GPP TS 36.321 "Medium Access Control (MAC); Protocol specification"

  6. 3GPP TS 36.331 "Radio Resource Control (RRC); Protocol specification"

  7. 3GPP TS 36.300 "Overall description; Stage 2"

  8. O. Liberg, M. Sundberg, Y.-P. Wang, J. Bergman and J. Sachs, Cellular Internet of Things: Technologies, Standards and Performance, Elsevier, 2018.

Helper Functions

The following local functions are used in this example:

  • hNPUSCHIndices: NPUSCH indices for the slot

  • hNULSCH: Narrowband UL-SCH transport channel encode

  • hNPUSCH: NPUSCH encode

  • hNPUSCHDRS : NPUSCH DM-RS signals

  • hNPUSCHDRSIndices : NPUSCH DM-RS signal indices

  • hNPUSCHDecode: NPUSCH decode

  • hNULSCHDecode: Narrowband UL-SCH transport channel decode

  • hPerfectTimingEstimate : Perfect timing offset calculation