LTE-M Uplink Waveform Generation
This example shows how to create an uplink LTE-M transmission consisting of the Physical Uplink Shared Channel (PUSCH) and associated demodulation reference signals (DM-RS) including repetitions and frequency hopping. When compared to pre-release 13 devices, Cat-M devices offer lower cost and complexity, enhanced coverage by the introduction of repetitions and an extended DRX for further power saving.
Introduction
The cell-specific subframe bitmap broadcasted on the System Information (SI) indicates which subframes are capable of LTE-M transmissions. LTE-M devices can optionally enable repetitions for the PUSCH and PUCCH to enhance coverage. The network configures a set of possible repetitions containing 4 values for CE mode A (pusch-maxNumRepetitionCEmodeA
as given in TS 36.213 Table 8-2b [ 3 ]) and 8 values for CE mode B (pusch-maxNumRepetitionCEmodeB
as given in TS 36.213 Table 8-2c [ 3 ]). From this set, the network dynamically selects the actual repetitions and signals this to the UE as part of the scheduling grant. Uplink scheduling grants for LTE-M devices are carried on the MPDCCH using DCI format 6-0A for devices operating in CE mode A and 6-0B for devices operating in CE mode B. A scheduling grant ending in downlink subframe n is valid for an uplink PUSCH transmission starting in uplink subframe n+4. In the case of transmissions with frequency hopping, the grant indicates the narrowband for the first transmission. Subsequent allocations can hop between narrowbands as defined in TS 36.211 Section 5.3.4 [ 1 ].
PUSCH
For Cat-M1 (Release 13) devices, PUSCH is always transmitted in a single narrowband. In Cat-M2 (Release 14), devices in CE mode A can optionally transmit over up to 24 PRBs if the higher layer parameter ce-pusch-maxBandwidth-config
is set to 5MHz as indicated in TS 36.211 Section 5.3.4 [ 1 ]/TS 36.306 Section 4.3.4.64 [ 4 ]. LTE-M PUSCH can have up to 32 repetitions in CE mode A (see TS 36.213 Table 8-2b [ 3 ])and up to 2048 repetitions in CE mode B (see TS 36.213 Table 8-2c [ 3 ]). For BL/CE UE in CE mode A, PUSCH frequency hopping is enabled when the higher-layer parameter pusch-HoppingConfig
is set and the frequency hopping flag in DCI format 6-0A indicates frequency hopping. For BL/CE UE in CE mode B, PUSCH frequency hopping is enabled when the higher-layer parameter pusch-HoppingConfig
is set. If frequency hopping is not enabled for PUSCH, all PUSCH repetitions are located at the same PRB resources. If frequency hopping is enabled for PUSCH, PUSCH is transmitted in a subframe within the NabsPUSCH
consecutive uplink subframes using the same number of consecutive PRBs as in the previous subframe starting from the same starting PRB resource within narrowband. If a resource assignment or frequency hopping would result in a PUSCH resource allocation outside the allocatable PRBs then the PUSCH transmission in that subframe is dropped.
ue = struct(); % Initialize the structure ue.NULRB = 50; % Bandwidth ue.DuplexMode = 'FDD'; % Duplex mode ue.TDDConfig = 1; % UL/DL configuration if TDD duplex mode ue.CyclicPrefixUL = 'Normal'; % The cyclic prefix length ue.NCellID = 1; % Cell identity ue.RNTI = 1; % RNTI value ue.NFrame = 0; % Frame number ue.NSubframe = 0; % Subframe number ue.NTxAnts = 1; % Number of transmit antennas ue.Shortened = 1; % Last symbol availability (allocation for SRS) % Set up hopping specific parameters ue.HoppingOffset = 1;% Narrowband offset between one narrowband and the next narrowband % a PUSCH hops to, expressed as a number of uplink narrowbands ue.NChULNB = 2; % Number of consecutive absolute subframes over which % PUCCH or PUSCH stays at the same pusch = struct(); pusch.CEMode = 'A'; % CE mode A or CE mode B pusch.Hopping = true; % Enable/Disable frequency hopping pusch.NRepPUSCH = 8; % The total number of PUSCH repetitions pusch.Modulation = 'QPSK'; % Symbol modulation pusch.RV = 0; % Initial redundancy version for UL-SCH processing (rv_DCI) pusch.NLayers = 1; % Number of layers pusch.TrBlkSizes = 100; % Transport block size
PUSCH Allocation - The PUSCH bandwidth is usually a single 1.4MHz narrowband. There are 6 RBs in each narrowband, all can be allocated in CE mode A and 1 or 2 RBs in CE mode B. An extended BW of 5MHz possible in Cat-M2 CE mode A configuration (See TS 36.306 Section 4.3.4.64 [ 4 ]). We use the InitPRBSet
and InitNarrowbandIndex
to specify the PRBs in a narrowband and the narrowband used in transmission. If frequency hopping is disabled, LTE-M PUSCH will be transmitted in the PRBs specified by the InitPRBSet
and InitNarrowbandIndex
parameters. If hopping is enabled, the hopping rules determine the narrowband used per subframe. The 5MHz bandwidth is inferred via the use of more than 6 PRBs in the InitPRBSet
parameter. In this case the hopping will be disabled and the InitNarrowbandIndex
ignored.
% Specify 1-based relative indices of RBs within a narrowband for all cases % except 5MHz Cat-M2 CE mode A. If 5MHz Cat-M2 CE mode A, these are the % absolute PRBs used for transmission pusch.InitPRBSet = (2:3)'; % Narrowband used for transmission (non-hopping, non-5MHz) pusch.InitNarrowbandIndex = 1; % Specify the power scaling in dB for PUSCH, PUSCH DM-RS pusch.PUSCHPower = 30; pusch.PUSCHDMRSPower = 100; % Turn off hopping if allocation spans multiple narrowbands if numel(pusch.InitPRBSet) > 6 pusch.Hopping = false; end
UL-SCH Encoding
For BL/CE UEs in CE mode B, resource elements in the last SC-FDMA symbol in a subframe configured with cell specific SRS shall be counted in the PUSCH mapping but not used for transmission of the PUSCH. Hence if CE mode B, turn off shortening when creating the coded transport block.
% Identify all uplink subframes in a frame info = arrayfun(@(x)lteDuplexingInfo(setfield(ue,'NSubframe',x)),0:9); ulsfs = arrayfun(@(x)strcmpi(x.SubframeType,'Uplink'),info); % In this example, we assume that the first absolute subframe in which % PUSCH is transmitted is the first available uplink subframe pusch.InitNSubframe = find(ulsfs,1)-1; % Calculate the allocation pusch.PRBSet = getPUSCHAllocation(ue,pusch); ueTemp = ue; % Create coded transport block for all symbols if strcmpi(pusch.CEMode,'B') && ue.Shortened ueTemp.Shortened = 0; end [~,info] = ltePUSCHIndices(ueTemp,pusch); % Define UL-SCH message bits trData = ones(pusch.TrBlkSizes(1),1); % Prepare for the creation of the coded UL-SCH bits pusch.BetaCQI = 2.0; pusch.BetaRI = 2.0; pusch.BetaACK = 2.0;
LTE-M PUSCH Generation
In this example, we generate the LTE-M PUSCH and the corresponding DM-RS signals with repetitions and optional frequency hopping. pusch.NRepPUSCH
controls the number of PUSCH repetitions. The UE-specific parameter pusch.Hopping
enables hopping and the cell-wide parameters ue.HoppingOffset
and ue.NChULNB
defines the hopping pattern. In this example, if the allocation spans more than one narrowband, frequency hopping will be disabled. For LTE-M, the same scrambling sequence is applied per subframe to PUSCH for a block of Nacc
subframes. Different RV values are used across the set of subframe blocks. All other processing stages, such as symbol modulation, layer mapping, precoding, and mapping to resource elements, are the same for the LTE PUSCH.
% Number of subframes in a scrambling block Nacc = 1; if strcmpi(ue.DuplexMode,'FDD') && strcmpi(pusch.CEMode,'B') Nacc = 4; elseif strcmpi(ue.DuplexMode,'TDD') && strcmpi(pusch.CEMode,'B') Nacc = 5; end % Total BL/CE subframes to simulate (all uplink subframes are BL/CE % subframes) and the PUSCH is transmitted without any subframe gaps totmtcSubframes = pusch.NRepPUSCH; % Total absolute subframes to simulate startSubframe = ue.NFrame*10+ue.NSubframe; % Initial absolute subframe number lastabssf = getlastabsSF(ulsfs,pusch.InitNSubframe,totmtcSubframes); totSubframes = lastabssf-startSubframe+1; % Create a resource grid for the entire transmission. The PUSCH and % DM-RS symbols will be mapped in this array subframeSize = lteULResourceGridSize(ue); sfgrid = zeros([subframeSize(1) subframeSize(2)*totSubframes subframeSize(3:end)]); mpuschSym = []; % Initialize PUSCH symbols jblock = 0; % Nacc subframe block counter for sf = startSubframe + (0:totSubframes -1) % Set current absolute subframe and frame numbers ue.NSubframe = mod(sf,10); ue.NFrame = floor((sf)/10); % Skip processing if this is not an uplink subframe duplexInfo = lteDuplexingInfo(ue); if ~strcmpi(duplexInfo.SubframeType,'Uplink') continue end % Calculate the PRBSet used in the current subframe prbset = getPUSCHAllocation(ue,pusch); % Calculate the PUSCH indices for the current subframe. For BL/CE UEs % in CE mode B, resource elements in the last SC-FDMA symbol in a % subframe configured with cell specific SRS shall be counted in the % PUSCH mapping but not used for transmission of the PUSCH pusch.PRBSet = prbset; mpuschIndices = ltePUSCHIndices(ue,pusch); % Create an empty subframe grid subframe = lteULResourceGrid(ue); % Encode PUSCH symbols from the codeword for a block of subframes, % selecting a new RV for each block. In the case of repetition, the % same symbols are repeated in each of a block of NRepPUSCH subframes. % Frequency hopping is applied as required if ~mod(sf,Nacc) || isempty(mpuschSym) ueTemp = ue; if strcmpi(pusch.CEMode,'B') && ue.Shortened ueTemp.Shortened = 0; % Create symbols for full subframe end % Create PUSCH codeword data for a block of Nacc subframes, that % all share the same RV index rvimap = [0 2 3 1]; blkrv = rvimap(mod(jblock+pusch.RV,4)+1); codedTrBlock = lteULSCH(ueTemp,setfield(pusch,'RV',blkrv),info.G,trData); %#ok<SFLD> mpuschSym = ltePUSCH(ueTemp,pusch,codedTrBlock)*db2mag(pusch.PUSCHPower); jblock = jblock + 1; % Increment subframe block counter end % Map SRS punctured PUSCH symbols to the subframe grid subframe(mpuschIndices) = mpuschSym(1:numel(mpuschIndices)); % Create and map the DMRS symbols ue.Hopping = 'Off'; % DRS hopping ue.SeqGroup = 0; % PUSCH sequence group ue.CyclicShift = 0; % Used for n1DMRS % For LTE-M UEs, a cyclic shift field of '000' shall be assumed when % determining n2DMRS from Table 5.5.2.1.1-1 of TS 36.211 pusch.DynCyclicShift = 0; % Cyclic shift of '000' for n2DMRS pusch.OrthCover = 'Off'; % No orthogonal cover sequence mpuschDrs = ltePUSCHDRS(ue,pusch)*db2mag(pusch.PUSCHDMRSPower); mpuschDrsIndices = ltePUSCHDRSIndices(ue,pusch); subframe(mpuschDrsIndices) = mpuschDrs; % Now assign the current subframe into the overall grid sfgrid(:,(1:subframeSize(2))+sf*subframeSize(2),:) = subframe; end
Create Time Domain Baseband Waveform
Create the time domain baseband waveform by OFDM modulating the resource grid. The resulting matrix has a column for each transmission layer of the PUSCH.
waveform = lteSCFDMAModulate(ue,sfgrid);
Plot Transmitted Grid and Baseband Waveform
Plot the grid and time domain baseband waveform. If the transmission uses more than one port, only the first port is shown. Note that the resource grid plot uses the power levels of the PUSCH and the DM-RS to assign colors to the resource elements.
% Create an image of overall resource grid. Since the PUSCH undergo % transform precoding, we need to assign a single power level to all % symbols to visualize in the plot plotgrid = abs(sfgrid(:,:,1)); % Get the DM-RS positions drspos = (plotgrid==db2mag(pusch.PUSCHDMRSPower)); plotgrid(drspos) = 0; % Now set all PUSCH symbols to one power level to plot plotgrid(plotgrid~=0) = db2mag(pusch.PUSCHPower); % Now write back the DRS and plot plotgrid(drspos) = db2mag(pusch.PUSCHDMRSPower); figure im = image(plotgrid); cmap = parula(64); colormap(im.Parent,cmap); axis xy; title(sprintf('LTE-M CEMode%s Uplink RE Grid (NRepPUSCH = %d)',pusch.CEMode,pusch.NRepPUSCH)) xlabel('OFDM symbols') ylabel('Subcarriers') % Create the legend box to indicate the channel/signal types associated with the REs reNames = {'PUSCH';'PUSCH DRS'}; clevels = round(db2mag([pusch.PUSCHPower pusch.PUSCHDMRSPower])); N = numel(reNames); L = line(ones(N),ones(N), 'LineWidth',8); % Generate lines % Set the colors according to cmap set(L,{'color'},mat2cell(cmap( min(1+clevels,length(cmap) ),:),ones(1,N),3)); % Set the colors according to cmap legend(reNames{:});
Local Functions
The following local functions are used in this example:
calcNarrowbandPRBSets
- Calculate narrowbands and associated PRBsgetPUSCHAllocation
- Calculate the PUSCH subframe allocationgetlastabsSF
- Calculate the last subframe number for PUSCH
Selected Bibliography
3GPP TS 36.211 "Physical channels and modulation"
3GPP TS 36.212 "Multiplexing and channel coding"
3GPP TS 36.213 "Physical layer procedures"
3GPP TS 36.306 "User Equipment (UE) radio access capabilities"
3GPP TS 36.331 "Radio Resource Control (RRC) Protocol specification"
O. Liberg, M. Sundberg, Y.-P. Wang, J. Bergman and J. Sachs, Cellular Internet of Things: Technologies, Standards and Performance, Elsevier, 2018.
E. Dahlman, S. Parkvall and J Skold 4G LTE-Advanced Pro and The Road to 5G
Local Functions
% Calculate the widebands, narrowbands and PRBSets for the LTE carrier bandwidth function [prbsets,nNB,nWB] = calcNarrowbandPRBSets(NULRB) % Narrowbands & Widebands (See 36.211 Section 5.2.4) NULNB = floor(NULRB/6); nNB = 0:(NULNB-1); % Narrowbands if NULNB >= 4 NULWB = floor(NULNB/4); else NULWB = 1; end nWB = 0:(NULWB-1); % Widebands % PRBs in a narrowband ii = 0:5; ii0 = floor(NULRB/2) - 6*(NULNB/2); prbsets = zeros(6,numel(nNB)); for nb = 1:numel(nNB) if mod(NULRB,2) && nNB(nb)>= (NULNB/2) prbsets(:,nb) = 6*(nNB(nb))+ii0+ii + 1; else prbsets(:,nb) = 6*(nNB(nb))+ii0+ii; end end end % Calculate the resource blocks allocated for PUSCH in the subframe function prbset = getPUSCHAllocation(ue,chs) % If 5MHz mode (up to 24 PRBs can be used), the allocation is the same % as InitPRBSet if numel(chs.InitPRBSet) > 6 prbset = chs.InitPRBSet; return; end % Get the narrowbands and corresponding resources [prbsets,nNB] = calcNarrowbandPRBSets(ue.NULRB); if max(chs.InitNarrowbandIndex) > max(nNB) error('Invalid narrowband(s) specified. There are only %d narrowbands in the bandwidth from 0...%d', nNB+1, nNB); end % If frequency hopping is disabled, the allocation is the same for % every subframe if ~chs.Hopping prbset = prbsets(chs.InitPRBSet,chs.InitNarrowbandIndex+1); return end % Hopping narrowband calculation according to TS 36.211 Section 5.3.4 j0 = floor((chs.InitNSubframe)/ue.NChULNB); % Calculate the narrowband for this subframe ue.NSubframe = ue.NFrame*10+ue.NSubframe; % Get the absolute subframe number if mod(floor(ue.NSubframe/ue.NChULNB-j0),2) == 0 nnBi = chs.InitNarrowbandIndex; else nnBi = mod(chs.InitNarrowbandIndex+ue.HoppingOffset,numel(nNB)); end % Calculate the PRBSet for this subframe, they are on the same RBs % within the narrowband [rbstartIndex,nbstartIndex] = find(prbsets == chs.InitPRBSet(1)); [rbendIndex,nbendIndex] = find(prbsets == chs.InitPRBSet(end)); if (isempty(rbstartIndex) || isempty(rbendIndex)) || (nbstartIndex ~= nbendIndex) error('Invalid PRBSet specified, must be resources within single narrowband'); end prbset = prbsets(rbstartIndex:rbstartIndex+numel(chs.InitPRBSet)-1,nnBi+1); end % Get the absolute subframe number which is used for the last transmission % of a channel function lastabssf = getlastabsSF(ulsfs,InitNSubframe,totmtcSubframes) numulsfsinFrame = sum(ulsfs); % Number of active sfs in a frame ulsfsinFrame = find(ulsfs); % UL subframes in the frame (1-based) % Find the first absolute subframe and frame initabssf = mod(InitNSubframe,10); initabsf = floor(InitNSubframe/10); startIdxwithinFrame = initabssf+1; % 1-based index to the UL sf if ~ulsfs(startIdxwithinFrame) error(['Invalid absolute subframe number of the first uplink subframe', ... ' intended for PUSCH (%d) specified. This is not an uplink subframe'],InitNSubframe) end sfslastFrame = mod((find(ulsfsinFrame==startIdxwithinFrame)-1)+totmtcSubframes,numulsfsinFrame); % subframes to tx in the last frame if sfslastFrame % Find the subframe number corresponding to the last subframe to transmit sfsnumlastFrame = find(ulsfs,sfslastFrame)-1; sfsnumlastFrame = sfsnumlastFrame(end); else % No partial frames required sfsnumlastFrame = 0; end lastabssf = (initabsf + floor(((find(ulsfsinFrame==startIdxwithinFrame)-1)+totmtcSubframes)/numulsfsinFrame)) * 10 + sfsnumlastFrame; end