nb-凯发k8网页登录
this example shows how lte toolbox™ can be used to create a nb-iot narrowband physical downlink shared channel (npdsch) block error rate (bler) simulation under frequency-selective fading and additive white gaussian noise (awgn) channel.
introduction
3gpp release 13 of lte started to add support for narrowband iot applications. release 13 defines a single nb-iot ue category, namely cat-nb1, and release 14 adds cat-nb2 which allows for larger transport block sizes. this example focuses on release 13 nb-iot.
the example generates a nb-iot npdsch bler curve for a number of snr points and transmission parameters. npss and nsss are transmitted in appropriate subframes and the npss is used for practical timing synchronization. npss and nsss subframes are not used for npdsch transmission. the nrs is transmitted in npdsch subframes and is used for practical channel estimation. npbch transmission gaps are not considered in this example.
simulation configuration
the simulation length is 4 dl-sch transport blocks for a number of snr points. a larger number of numtrblks
should be used to produce meaningful throughput results. snr
can be an array of values or a scalar. the simulation is performed over different repetition values to compare the performance improvement with repetitions.
numtrblks = 4; % number of simulated transport blocks snrdb = -32:4:0; % snr range in db ireps = [0 5 9]; % range of reps simulated
setup higher layer parameters
setup the following higher layer parameters which are used to configure the npdsch in the next section:
the variable
npdschdatatype
indicates whether the npdsch is carrying the systeminformationblocktype1-nb (sib1-nb) or not, and whether the npdsch is carrying the broadcast control channel (bcch) or not. the allowed values ofnpdschdatatype
are'sib1nb'
,'bcchnotsib1nb'
and'notbcch'
. note that sib1-nb belongs to the bcch.the number of npdsch repetitions and the transport block size (tbs) are affected by whether npdsch is carrying sib1-nb or not (see 3gpp ts 36.213 16.4.1.3 and 16.4.1.5 [ 2 ]).
npdschdatatype
set to'sib1nb'
indicates that the npdsch is carrying sib1-nb;npdschdatatype
set to either'bcchnotsib1nb'
or'notbcch'
indicates that the npdsch is not carrying sib1-nb.the npdsch repetition pattern and the scrambling sequence generation is affected by whether npdsch is carrying bcch or not (see 3gpp ts 36.211 10.2.3 [ 1 ]).
npdschdatatype
set to either'sib1nb'
or'bcchnotsib1nb'
indicates that the npdsch is carrying bcch;npdschdatatype
set to'notbcch'
indicates that the npdsch is not carrying bcch.
npdschdatatype = 'notbcch'; % the allowed values are 'sib1nb', 'bcchnotsib1nb' or 'notbcch'
the variable
isf
configures the number of subframes for a npdsch according to 3gpp ts 36.213 table 16.4.1.3-1 [ 2 ]. valid values forisf
are 0...7.
when the npdsch carries the sib1-nb:
the variable
schedulinginfosib1
configures the number of npdsch repetitions according to 3gpp ts 36.213 table 16.4.1.3-3 and the tbs according to table 16.4.1.5.2-1 [ 2 ]. valid values forschedulinginfosib1
are 0...11.
when the npdsch does not carry the sib1-nb:
isf = 0; % resource assignment field in dci (dci format n1 or n2) schedulinginfosib1 = 0; % scheduling information field in masterinformationblock-nb (mib-nb) imcs = 4; % modulation and coding scheme field in dci (dci format n1 or n2)
enb configuration
configure the starting frame and subframe numbers (enb.nframe
and enb.nsubframe
) in the simulation for each snr point, the narrowband physical cell id enb.nncellid
, the number of nrs antenna ports (enb.nbrefp
, one antenna port indicates port 2000 is used, two antenna ports indicates port 2000 and port 2001 are used), the nb-iot operation mode enb.operationmode
which can be any value as follows:
'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'inband-samepci'
: nb-iot carrier deployed in resource blocks of a lte carrier, withenb.nbrefp
the same as the number of crs portsenb.cellrefp
'inband-differentpci'
: nb-iot carrier deployed in resource blocks of a lte carrier, withenb.nbrefp
different asenb.cellrefp
enb.cellrefp
is configured when the operation mode is 'inband-differentpci'
. the starting ofdm symbol index in a subframe for npdsch is configured using enb.controlregionsize
, when the values of npdschdatatype
and enb.operationmode
satisfy the following conditions:
npdschdatatype
is either'bcchnotsib1nb'
or'notbcch'
enb.operationmode
is either'inband-samepci'
or'inband-differentpci'
enb.nframe = 0; % simulation starting frame number enb.nsubframe = 0; % simulation starting subframe number enb.nncellid = 0; % nb-iot physical cell id enb.nbrefp = 2; % number of nrs antenna ports, should be either 1 or 2 enb.operationmode = 'inband-differentpci'; % the allowed values are 'inband-samepci', 'inband-differentpci', 'guardband' or 'standalone' if strcmpi(enb.operationmode,'inband-samepci') enb.cellrefp = enb.nbrefp; % the allowed values are nbrefp or 4 enb.ncellid = enb.nncellid; elseif strcmpi(enb.operationmode,'inband-differentpci') enb.cellrefp = 4; % number of cell rs antenna ports (must be equal to nbrefp or 4) enb.ncellid = 1; end if (strcmpi(npdschdatatype,'bcchnotsib1nb') || strcmpi(npdschdatatype,'notbcch')) && ... (strcmpi(enb.operationmode,'inband-samepci') || strcmpi(enb.operationmode,'inband-differentpci')) enb.controlregionsize = 3; % the allowed values are 0...13 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 = 1; % 1 receive antenna channel.delayprofile ='epa'; % delay profile channel.dopplerfreq = 5; % 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 the parameter perfectchannelestimator
controls channel estimator behavior. valid values are true
or false
. when set to true
, a perfect channel estimator is used otherwise a practical estimator is used, based on the values of the received nrs.
% channel estimator behavior
perfectchannelestimator = true;
the practical channel estimator is configured with a structure cec
. an epa delay profile with 5hz doppler causes the channel to change slowly over time. therefore only frequency averaging is performed over pilot estimates by setting the time window to 1 resource element (re) and frequency window to 25 to ensure averaging over all subcarriers for the resource block.
% configure channel estimator cec.pilotaverage = 'userdefined'; % type of pilot symbol averaging cec.timewindow = 1; % time window size in res cec.freqwindow = 25; % frequency window size in res cec.interptype = 'cubic'; % 2d interpolation type cec.interpwindow = 'centered'; % interpolation window type cec.interpwinsize = 3; % interpolation window size cec.reference = 'nrs'; % channel estimator reference signal
npdsch configuration
obtain the following npdsch parameters from the higher layer configurations defined above:
the number of repetitions (
nrep
)the number of subframes used for a npdsch when there is no repetition (
nsf
)the transport block size (
tbs
)
these parameters can be obtained by using the class hnpdschinfo
. hnpdschinfo
also provides method displaysubframepattern
to display the npdsch repetition pattern, which is shown in the next section.
for repidx = 1:numel(ireps)
npdschinfo = hnpdschinfo; npdschinfo.npdschdatatype = npdschdatatype; npdschinfo.isf = isf; if strcmpi(npdschdatatype,'sib1nb') % npdsch carrying sib1-nb npdschinfo.schedulinginfosib1 = schedulinginfosib1; else % npdsch not carrying sib1-nb npdschinfo.irep = ireps(repidx); % repetition number field in dci (dci format n1 or n2) npdschinfo.imcs = imcs; % modulation and coding scheme field in dci (dci format n1 or n2) end
create the structure npdsch
using the obtained number of repetitions (npdschinfo.nrep
), the number of subframes of a npdsch (npdschinfo.nsf
) from the class instance npdschinfo
, input parameter npdschdatatype
and the radio network temporary identifier rnti. note that nsf = 8
is used when npdschdatatype
is 'sib1nb'
.
npdsch.nsf = npdschinfo.nsf; npdsch.nrep = npdschinfo.nrep; npdsch.npdschdatatype = npdschdatatype; npdsch.rnti = 1;
compute codeword length and transport block size.
[~,info] = ltenpdschindices(enb,npdsch); rmoutlen = info.g; % bit length after rate matching, i.e. codeword length trblklen = npdschinfo.tbs; % transport block size
display subframe repetition pattern
the variable displaypattern
controls the display of the npdsch subframe repetition pattern. an example is shown in the following figure for the case when the npdsch carries the bcch, the npdsch consists of npdschinfo.nsf = 3
different subframes, each color represents a subframe which represents 1 ms. each subframe is repeated npdschinfo.nrep = 4
times, thus a total of 12 subframes are required to transmit the npdsch.
% the npdsch repetition pattern for the current configuration is % displayed below displaypattern = false; % display npdsch repetition pattern if displaypattern == true npdschinfo.displaysubframepattern; end
block error rate simulation loop
this part of the example shows how to perform nb-iot npdsch link level simulation and plot bler results. the transmit and receive chain is depicted in the following figure.
a random stream of bits with the size of the desired transport block undergoes crc encoding, convolutional encoding and rate matching to obtain the npdsch bits, which are repeated according to a specific subframe repetition pattern. scrambling, modulation, layer mapping and precoding are then applied to form the complex npdsch symbols. these symbols along with the nrs signals are mapped to the grid and ofdm modulated to create the time domain waveform. this is then passed through a fading channel and awgn is added. the noisy waveform is then synchronized and demodulated. channel estimation and equalization is performed on the recovered npdsch symbols after which channel decoding and demodulation are performed to recover the transport block. after de-scrambling, the repetitive subframes are soft-combined before rate recover. 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 subframes in a bundle is used to decode the transport block at the ue. a bundle is defined in the mac layer (see 3gpp ts 36.321 5.3.2.1 [ 3 ]) as the npdsch.nsf
npdsch.nrep
subframes used to carry a transport block.
% absolute subframe number at the starting point of the simulation nsubframe = enb.nframe*10 enb.nsubframe; % initialize bler and throughput result maxthroughput = zeros(length(snrdb),1); simthroughput = zeros(length(snrdb),1); bler = zeros(1,numel(snrdb)); % the temporary variables 'enb_init' and 'channel_init' are used to create % the temporary variable 'enb' and 'channel' within the snr loop to create % independent simulation loops for the 'parfor' loop enb_init = enb; 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. if this is not installed % 'parfor' will default to the normal 'for' statement. % set the random number generator seed depending to the loop variable % to ensure independent random streams rng(snridx,'combrecursive'); fprintf('\nsimulating %d transport blocks at %gdb snr\n',numtrblks,snrdb(snridx)); enb = enb_init; % initialize enodeb configuration channel = channel_init; % initialize fading channel configuration txcw = []; % initialize the transmitted codeword numblkerrors = 0; % number of transport blocks with errors estate = []; % initialize npdsch encoder state dstate = []; % initialize npdsch decoder state lastoffset = 0; % initialize overall frame timing offset offset = 0; % initialize frame timing offset subframegrid = ltenbresourcegrid(enb); % initialize the subframe grid subframeidx = nsubframe; numrxtrblks = 0; while (numrxtrblks < numtrblks) % set current subframe and frame numbers enb.nsubframe = mod(subframeidx,10); enb.nframe = floor((subframeidx)/10); % generate the npss symbols and indices npsssymbols = ltenpss(enb); npssindices = ltenpssindices(enb); % map the symbols to the subframe grid subframegrid(npssindices) = npsssymbols; % generate the nsss symbols and indices nssssymbols = ltensss(enb); nsssindices = ltensssindices(enb); % map the symbols to the subframe grid subframegrid(nsssindices) = nssssymbols; % establish if either npss or nsss is transmitted and if so, % do not transmit npdsch in this subframe isdatasubframe = isempty(npsssymbols) && isempty(nssssymbols); % create a new transport block and encode it when the % transmitted codeword is empty. the receiver sets the codeword % to empty to signal that all subframes in a bundle have been % received (it is also empty before the first transmission) if isempty(txcw) txtrblk = randi([0 1],trblklen,1); txcw = ltendlsch(rmoutlen,txtrblk); end if (isdatasubframe) % generate npdsch symbols and indices for a subframe [txnpdschsymbols,estate] = ltenpdsch(enb,npdsch,txcw,estate); npdschindices = ltenpdschindices(enb,npdsch); % map the symbols to the subframe grid subframegrid(npdschindices) = txnpdschsymbols; % generate the nrs symbols and indices nrssymbols = ltenrs(enb); nrsindices = ltenrsindices(enb); % map the symbols to the subframe grid subframegrid(nrsindices) = nrssymbols; end % perform ofdm modulation to generate the time domain waveform [txwaveform,ofdminfo] = nbofdmmodulate(enb,subframegrid); % 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, enb.nbrefp)]; %#ok% initialize channel time for each subframe channel.inittime = subframeidx/1000; % pass data through channel model channel.samplingrate = ofdminfo.samplingrate; [rxwaveform,fadinginfo] = ltefadingchannel(channel, txwaveform); % calculate noise gain including compensation for downlink power % allocation snr = 10^(snrdb(snridx)/10); % normalize noise power to take account of sampling rate, which % is a function of the ifft size used in ofdm modulation, and % the number of antennas n0 = 1/sqrt(2.0*enb.nbrefp*double(ofdminfo.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 if(perfectchannelestimator) offset = hperfecttimingestimate(fadinginfo); else % in this example, the subframe offset calculation relies % on npss present in subframe 5, so we need to pad the % subframes before it so that the frame offset returned by % ltenbdlframeoffset is the offset for subframe 5 sftsamples = ofdminfo.samplingrate*1e-3; if (enb.nsubframe==5) padding = zeros([sftsamples*5,size(rxwaveform,2)]); offset = ltenbdlframeoffset(enb, [padding; rxwaveform]); if (offset > 25) || (offset < 0) offset = lastoffset; end lastoffset = offset; end end % synchronize the received waveform rxwaveform = rxwaveform(1 offset:end, :); % perform ofdm demodulation on the received data to recreate the % resource grid rxsubframe = nbofdmdemodulate(enb,rxwaveform); % channel estimation if(perfectchannelestimator) % perfect channel estimation estchannelgrid = nbdlperfectchannelestimate(enb, channel, offset); noisegrid = nbofdmdemodulate(enb, noise(1 offset:end ,:)); noiseest = var(noisegrid(:)); else [estchannelgrid, noiseest] = ltedlchannelestimate( ... enb, cec, rxsubframe); end if (isdatasubframe) % get npdsch indices npdschindices = ltenpdschindices(enb, npdsch); % get pdsch resource elements from the received subframe. scale the % received subframe by the pdsch power factor rho. the pdsch is % scaled by this amount, while the cell reference symbols used for % channel estimation (used in the pdsch decoding stage) are not. [rxnpdschsymbols, npdschhest] = lteextractresources(npdschindices, ... rxsubframe, estchannelgrid); % decode npdsch [rxcw,dstate,symbols] = ltenpdschdecode(... enb, npdsch, rxnpdschsymbols, npdschhest, noiseest,dstate); % decode the transport block when all the subframes in a bundle % have been received if dstate.endoftx [trblkout,blkerr] = ltendlschdecode(trblklen,rxcw); numblkerrors = numblkerrors blkerr; numrxtrblks = numrxtrblks 1; % re-initialize to enable the transmission of a new transport block txcw = []; end end subframeidx = subframeidx 1; end % calculate the block error rate bler(snridx) = numblkerrors/numtrblks; fprintf('npdsch bler = %.4f \n',bler(snridx)); % calculate the maximum and simulated throughput maxthroughput(snridx) = trblklen*numtrblks; % max possible throughput simthroughput(snridx) = trblklen*(numtrblks-numblkerrors); % simulated throughput fprintf('npdsch throughput(%%) = %.4f %%\n',simthroughput(snridx)*100/maxthroughput(snridx)); end
simulating 4 transport blocks at -32db snr
simulating 4 transport blocks at -32db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -28db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -24db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -20db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -16db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -12db snr npdsch bler = 0.2500 npdsch throughput(%) = 75.0000 % simulating 4 transport blocks at -8db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at -4db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at 0db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 %
simulating 4 transport blocks at -32db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -28db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -24db snr npdsch bler = 0.2500 npdsch throughput(%) = 75.0000 % simulating 4 transport blocks at -20db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at -16db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at -12db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at -8db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at -4db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 % simulating 4 transport blocks at 0db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 %
plot block error rate vs snr results
if repidx == 1 fh = figure; grid on; hold on; xlabel('snr (db)'); ylabel('bler'); legendstr = {['nrep = ' num2str(npdsch.nrep)]}; else legendstr = [legendstr ['nrep = ' num2str(npdsch.nrep)]]; %#okend figure(fh); plot(snrdb, bler, '-o');
end % set figure title if strcmpi(npdschdatatype,'sib1nb') npdsch.nsf = 8; end title([' ' char(npdsch.npdschdatatype) ': tbs=' num2str(trblklen)... '; nsf=' num2str(npdsch.nsf) '; ' num2str(enb_init.nbrefp) ' nrs port(s)' ]); legend(legendstr);
the following plot shows the simulation run with numtrblks
set to 1000 while using the perfect channel estimator.
appendix
this example uses the helper functions:
selected bibliography
3gpp ts 36.211 "physical channels and modulation"
3gpp ts 36.213 "physical layer procedures"
3gpp ts 36.321 "medium access control (mac) protocol specification"
3gpp ts 36.101 "user equipment (ue) radio transmission and reception"
local functions
% nb-iot dl ofdm modulator function [waveform,info] = nbofdmmodulate(enb,grid) % apply default window size according to ts 36.104 table e.5.1-1a if(~isfield(enb,'windowing')) enb.windowing = 6; end % use nb-iot sc-fdma to get the 1/2 subcarrier shift on the ofdm modulation enb.nbulsubcarrierspacing = '15khz'; [waveform,info] = ltescfdmamodulate(enb,grid); end % nb-iot dl ofdm demodulator function grid = nbofdmdemodulate(enb,rxwaveform) % use nb-iot sc-fdma to get the 1/2 subcarrier shift on the ofdm modulation enb.nbulsubcarrierspacing = '15khz'; grid = ltescfdmademodulate(enb,rxwaveform,0.55); % cp fraction of 0.55 end % nb-iot dl perfect channel estimator function h = nbdlperfectchannelestimate(enb,channel,timefreqoffset) % reconfigure nb-iot ul perfect channel estimator to perform dl perfect % channel estimation enb.nbulsubcarrierspacing = '15khz'; enb.ntxants = enb.nbrefp; enb.totslots = 2; h = lteulperfectchannelestimate(enb, channel,timefreqoffset); end
npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -28db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -24db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -20db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -16db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -12db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -8db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at -4db snr npdsch bler = 1.0000 npdsch throughput(%) = 0.0000 % simulating 4 transport blocks at 0db snr npdsch bler = 0.0000 npdsch throughput(%) = 100.0000 %