Main Content

Release 10 PUSCH Multiple Codeword Throughput Conformance Test

This example measures the throughput performance of the Physical Uplink Shared Channel (PUSCH) with closed-loop spatial multiplexing using the LTE Toolbox™ under a 2-codeword Release 10 UL-MIMO scenario, based on conformance test conditions as defined in Table 8.2.1.1-7 of TS 36.104.

Introduction

TS 36.104, Table 8.2.1.1-7 [ 1 ] defines a minimum fraction of 70% throughput for a physical uplink shared channel (PUSCH) transmission for a given signal-to-noise ratio (SNR) assuming hybrid automatic repeat request (HARQ) retransmissions. A normal cyclic prefix, Extended Pedestrian A (EPA5) propagation channel and Fixed Reference Channel (FRC) A3-2 are used, but amended to transmit two identically-configured codewords in parallel. In order to assist Precoding Matrix Indicator (PMI) selection for closed-loop spatial multiplexing, the Sounding Reference Signal (SRS) is transmitted which allows full-rank channel estimation even when the PUSCH is being transmitted with fewer transmit layers than transmit antennas.

If SRS is used the PUSCH capacity is shorted as the last symbol of the subframe where SRS is transmitted is not used for PUSCH in any User Equipment (UE) in the cell.

Simulation Configuration

The example is executed for a simulation length of 10 frames at an SNR of -0.1 dB as per TS 36.104, Table 8.2.1.1-7 [ 1 ]. A large number of NFrames should be used to produce meaningful throughput results. SNRIn can be an array of values or a scalar.

NFrames = 10; % Number of frames
SNRIn = -0.1; % SNR range in dB

UE Configuration

User Equipment (UE) settings are specified in a structure.

frc.RC = 'A3-2';                 % FRC number
frc.DuplexMode = 'FDD';          % Duplex mode
frc.TotSubframes = 1;            % Total number of subframes to generate
frc.NCellID = 10;                % Cell identity
frc.CyclicPrefixUL = 'Normal';   % Uplink cyclic prefix length
frc.CyclicPrefix = 'Normal';     % Downlink cyclic prefix length
frc.NTxAnts = 4;                 % Number of transmit antennas

Configure SRS within UE configuration to allow for channel estimation.

frc.SRS.SubframeConfig = 1;    % Cell-specific schedule: 2 ms periodicity
frc.SRS.NTxAnts = frc.NTxAnts; % Configure SORTD same as no of UE antennas
frc.SRS.BWConfig = 7;          % Cell-specific SRS bandwidth
frc.SRS.BW = 0;                % UE-specific SRS bandwidth
frc.SRS.ConfigIdx = 0;         % UE-specific schedule:  2ms periodicity
frc.SRS.CyclicShift = 0;       % Cyclic shift 0
frc.SRS.SeqGroup = 0;          % Sequence group 0
frc.SRS.SeqIdx = 0;            % Base sequence 0
frc.SRS.TxComb = 0;            % Transmission comb 0
frc.SRS.FreqPosition = 0;      % Frequency-domain position 0
frc.SRS.HoppingBW = 0;         % Disable hopping (as HoppingBW >=0 BW)

Set the PMI delay for the closed-loop spatial multiplexing. This is the delay of a PMI being passed from UE to eNodeB.

pmiDelay = 8;

Propagation Channel Model Configuration

Propagation channel model characteristics are set using a structure containing the fields specified below. These are set according to TS 36.104, Table 8.2.1.1-7 [ 1 ].

chcfg.NRxAnts = 4;               % Number of receive antennas
chcfg.DelayProfile = 'EPA';      % Delay profile
chcfg.DopplerFreq = 5.0;         % Doppler frequency
chcfg.MIMOCorrelation = 'Low';   % MIMO correlation
chcfg.Seed = 9;                  % Channel seed
chcfg.NTerms = 16;               % Oscillators used in fading model
chcfg.ModelType = 'GMEDS';       % Rayleigh fading model type
chcfg.InitPhase = 'Random';      % Random initial phases
chcfg.NormalizePathGains = 'On'; % Normalize delay profile power
chcfg.NormalizeTxAnts = 'On';    % Normalize for transmit antennas

Channel Estimator Configuration

The variable perfectChanEstimator controls channel estimator behavior. Valid values are true or false. When set to true a perfect channel estimator is used otherwise an imperfect estimate of the channel is used, based on the values of received pilot signals.

% Controls channel estimator behavior
perfectChanEstimator = false;      % Valid values are true or false
reference = 'Antennas';            % Channel reference

Imperfect channel estimation is configured using a structure cec. Here cubic interpolation will be used with an averaging window of 12-by-1 Resource Elements (REs). This configures the channel estimator to use a special mode which ensures the ability to despread and orthogonalize the different overlapping PUSCH transmissions.

% Channel estimator configuration
cec.PilotAverage = 'UserDefined'; % Type of pilot symbol averaging
cec.FreqWindow = 12;              % Frequency averaging window in REs (special mode)
cec.TimeWindow = 1;               % Time averaging window in REs (special mode)
cec.InterpType = 'Cubic';         % 2D interpolation type

RMC-UL Configuration

To generate the uplink Reference Model Channel (RMC) the LTE Toolbox functions lteRMCUL and lteRMCULTool are used. lteRMCULTool creates a configuration structure for given UE settings; specific to a given Fixed Reference Channel (FRC). This configuration structure is constructed as per TS 36.104, Annex A [ 1 ] and is used by lteRMCULTool to generate an SC-FDMA modulated waveform. The sub-structure PUSCH defines the parameters associated with PUSCH and contains the vector defining the transport data capacity per subframe. These lengths are used when decoding Uplink Shared Channel (UL-SCH).

In this example two codewords are used for the PUSCH. The size of four parameters depend on the number of codewords used:

  • frc.PUSCH.Modulation - Each cell contains the modulation scheme for a codeword.

  • frc.PUSCH.TrBlkSizes - Each row contains the transport block sizes for a codeword.

  • frc.PUSCH.CodedTrBlkSizes - Each row contains the coded transport block sizes for a codeword.

  • frc.PUSCH.RVSeq - Each row contains the Redundancy Versions (RVs) for a codeword.

% Generate parameter structure for single codeword A3-2 FRC
frc = lteRMCUL(frc);

% Then update Physical Uplink Shared Channel (PUSCH) parameters to define
% two identically configured single layer codewords
frc.PUSCH.NLayers = 2;  % the layers are shared across the 2 codewords
frc.PUSCH.Modulation = repmat({frc.PUSCH.Modulation}, 1, 2);
frc.PUSCH.TrBlkSizes = repmat(frc.PUSCH.TrBlkSizes, 2, 1);
frc.PUSCH.RVSeq = repmat(frc.PUSCH.RVSeq, 2, 1);

% Record transport block sizes for each subframe in a frame
trBlkSizes = frc.PUSCH.TrBlkSizes;

% The number of codewords is the number of transport block sizes
ncw = size(trBlkSizes,1);

% Record RV sequence
rvSequence = frc.PUSCH.RVSeq;

Set Propagation Channel Model Sampling Rate

The sampling rate for the channel model is set using the value returned from lteSCFDMAInfo.

dims = lteSCFDMAInfo(frc);
chcfg.SamplingRate = dims.SamplingRate;

System Processing

The conformance test may be carried out over a number of SNR points. To determine the throughput at each SNR point, the PUSCH data is analyzed on a subframe by subframe basis using the following steps:

  • Update Current HARQ Process. The HARQ process either carries new transport data or a retransmission of previously sent transport data depending upon the Acknowledgment (ACK) or Negative Acknowledgment (NACK) based on CRC results. All this is handled by the HARQ scheduler, hHARQScheduling.m. The PUSCH data is updated based on the HARQ state.

  • Set PMI. A PMI is taken sequentially from a set of PMIs, txPMIs, each subframe and used by the eNodeB to select a precoding matrix. When a PMI is used by the eNodeB for a transmission it is replaced with a PMI selected by the UE. This PMI is then used to select a precoding matrix after pmiDelay subframes. Initially a set of pmiDelay random PMIs is used.

  • Create Transmit Waveform. The data generated by the HARQ process is passed to lteRMCULTool, which produces an OFDM modulated waveform, containing the physical channels and signals.

  • Noisy Channel Modeling. The waveform is passed through a fading channel and Additive White Gaussian Noise (AWGN) noise added. The noise power is normalized to take account of the sampling rate.

  • Synchronization and SC-FDMA Demodulation. The received symbols are offset to account for a combination of implementation delay and channel delay spread. The symbols are then SC-FDMA demodulated.

  • Channel Estimation. The channel response and noise are estimated using either a perfect or imperfect channel estimator. These estimates are used to aid the soft decoding of the PUSCH. If imperfect channel estimation is used, the SRS is utilized to enhance estimation. This information is passed in the variable refGrid which contains known transmitted SRS symbols in their correct locations. All other locations are represented by a NaN.

  • Equalization, Combining and PUSCH Decoding. The equalization is performed using lteEqualizeMMSE and then ltePUSCHDecode completes the reception processing under the assumption that the input is already equalized.

  • UL-SCH Decoding. The vector of decoded soft bits is passed to lteULSCHDecode; this decodes the codewords and returns the block CRC error used to determine the throughput of the system. The contents of the new soft buffer, harqProc(harqID).decState, is available at the output of this function to be used for the next subframe.

  • Update PMI. A PMI is selected and fed back to the eNodeB for use in future subframes. For perfect channel estimation the PMI is updated every subframe. For imperfect channel estimation a PMI update only occurs when an SRS transmission occurs and therefore a full-rank channel estimate is available, from which PMI can be estimated and selected.

% Store results for each SNR point and each subframe containing data for
% the whole simulation
nDataTBS = sum(trBlkSizes(:)~=0)*NFrames;
crc = zeros(numel(SNRIn), nDataTBS);  % Total block CRC error vector
tput = zeros(numel(SNRIn), nDataTBS); % Total throughput vector
ResultIndex = 1; % SNR point result index

for SNRdB = SNRIn

    % Configure random number generators
    rng('default');

    % Noise configuration
    fprintf('\nSimulating at %gdB SNR for a total %d Frame(s)', ...
            SNRdB, NFrames);
    SNR = 10^(SNRdB/20);
    N = 1/(SNR*sqrt(double(dims.Nfft)))/sqrt(2.0*frc.NTxAnts);

    % Initialize state of all HARQ processes
    harqProcesses = hNewHARQProcess(frc);
    % Initialize HARQ process IDs to 1 as the first non-zero transport
    % block will always be transmitted using the first HARQ process. This
    % will be updated with the full sequence output by lteRMCULTool after
    % the first call to the function
    harqProcessSequence = 1;

    % Use random PMIs for the first 'pmiDelay' subframes until feedback is
    % available from the UE if multiple transmit antennas are used
    if (frc.NTxAnts>1)
        pmidims = lteULPMIInfo(frc, frc.PUSCH);
        txPMIs = randi([0 pmidims.MaxPMI], pmidims.NSubbands, pmiDelay);
    end

    % Initialize result store for SNR point tested
    crcSNR = zeros(nDataTBS/ncw, ncw);  % Intermediate block CRC
    tputSNR = zeros(nDataTBS/ncw, ncw); % Intermediate throughput
    dataSubframeIndex = 1;

    % Loop for all subframes at this SNR
    offsetused = 0;
    for subframeNo = 0:(NFrames*10-1)

        % Update subframe number
        frc.NSubframe = mod(subframeNo, 10);

        % If this is an uplink subframe
        duplexDims = lteDuplexingInfo(frc);
        if(strcmp(duplexDims.SubframeType,'Uplink')==1)

            % Get HARQ process ID for the subframe from HARQ process sequence
            harqID = harqProcessSequence(mod(subframeNo, length(harqProcessSequence))+1);

            % If there is a transport block scheduled in the current subframe
            % (indicated by non-zero 'harqID'), perform transmission and
            % reception. Otherwise continue to the next subframe
            if harqID == 0
                continue;
            end

            % Update current HARQ process
            harqProcesses(harqID) = hHARQScheduling( ...
                harqProcesses(harqID), subframeNo, rvSequence);

            % Update the PUSCH transmission config with HARQ process state
            frc.PUSCH = harqProcesses(harqID).txConfig;
            data = harqProcesses(harqID).data;

            % Set the PMI to the appropriate value in the delay queue (if
            % multiple antennas are being used)
            if (frc.NTxAnts>1)
                pmiIdx = mod(subframeNo, pmiDelay);
                frc.PUSCH.PMI = txPMIs(:, pmiIdx+1);
            end

            % Create transmit waveform and get the HARQ scheduling ID
            % sequence from 'frcOut' structure output which also contains
            % the waveform configuration and OFDM modulation parameters
            [txWaveform,~,frcOut] = lteRMCULTool(frc, data);

            % 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, frc.NTxAnts)]; %#ok<AGROW>

            % Get the HARQ ID sequence from 'frcOut' for HARQ processing
            harqProcessSequence = frcOut.PUSCH.HARQProcessSequence;

            % Pass data through the fading channel model. The
            % initialization time for channel modeling is set each subframe
            % to simulate a continuously varying channel.
            chcfg.InitTime = subframeNo/1000;
            rxWaveform = lteFadingChannel(chcfg, txWaveform);

            % Add noise at the receiver
            noise = N*complex(randn(size(rxWaveform)), ...
                randn(size(rxWaveform)));
            rxWaveform = rxWaveform + noise;

            % Calculate synchronization offset
            offset = lteULFrameOffset(frc, frc.PUSCH, rxWaveform);
            if (offset < 25)
                offsetused = offset;
            end

            % SC-FDMA demodulation
            rxSubframe = lteSCFDMADemodulate(frc, rxWaveform...
                        (1+offsetused:end, :));

            % Mark this subframe as not being involved in PMI update
            updatePMI = false;

            % Channel and noise estimation
            if (perfectChanEstimator)
                % Create reference grid - not required for perfect channel
                % estimator, but needed as an input to lteULPMISelect to
                % match call with imperfect channel estimator.
                refGrid = NaN(lteULResourceGridSize(frc)); %#ok

                % Perfect channel estimation, perfect knowledge of all REs
                % and perfect knowledge of channel noise
                estChannelGrid = lteULPerfectChannelEstimate( ...
                    frc, chcfg, offsetused);
                n = lteSCFDMADemodulate(frc, noise(1+offsetused:end, :));
                noiseEst = var(reshape(n, numel(n), 1));
                updatePMI = true;
            else
                % Use imperfect channel estimator with support from the SRS
                % if available
                if (strcmpi(reference, 'Antennas')==1 || ...
                        (frc.NTxAnts == frc.PUSCH.NLayers))
                    refGrid = NaN(lteULResourceGridSize(frc));
                    if (isfield(frc, 'SRS'))
                        [srsIndices, srsIndicesDims] = lteSRSIndices( ...
                                frc, frc.SRS);
                        if (~isempty(srsIndices))
                            srsSymbols = lteSRS(frc, frc.SRS);
                            refGrid(srsIndices) = srsSymbols;
                            updatePMI = true;
                        end
                    end
                end
                cec.Reference = reference;
                [estChannelGrid, noiseEst] = lteULChannelEstimate( ...
                    frc, frc.PUSCH, cec, rxSubframe, refGrid);
            end

            % Shorten PUSCH capacity shortening as appropriate
            if (isfield(frc, 'SRS'))
                srsDims = lteSRSInfo(frc, frc.SRS);
                frc.Shortened = srsDims.IsSRSSubframe;
            else
                frc.Shortened = 0;
            end

            % Set up variable indicating the current transport block sizes
            TBSs = trBlkSizes(:, mod(subframeNo, 10)+1).';

            % Extract REs corresponding to the PUSCH from the given
            % subframe across all receive antennas and channel estimates.
            puschIndices = ltePUSCHIndices(frc, frc.PUSCH);
            [puschRx, puschEstCh] = lteExtractResources( ...
                puschIndices, rxSubframe, estChannelGrid);

            % Equalization and combining, layer demapping, transform
            % deprecoding, demodulation and descrambling of the received
            % data
            ulschDims = lteULSCHInfo(frc, frc.PUSCH, TBSs, 'chsconcat');
            rxSymbols = lteEqualizeMMSE(puschRx, puschEstCh, noiseEst);
            rxEncodedBits = ltePUSCHDecode(frc, ulschDims, rxSymbols);

            % UL-SCH transport decoding
            [rxdata, harqProcesses(harqID).blkerr, ...
                harqProcesses(harqID).decState] = lteULSCHDecode( ...
                frc, ulschDims, TBSs, rxEncodedBits, ...
                harqProcesses(harqID).decState);

            % Store block CRC and throughput results for subframes
            % containing transport data
            crcSNR(dataSubframeIndex, :) = harqProcesses(harqID).blkerr;
            tputSNR(dataSubframeIndex, :) = TBSs.* ...
                (1-harqProcesses(harqID).blkerr);
            dataSubframeIndex = dataSubframeIndex + 1;

            % Provide PMI feedback (if multiple antennas are being used)
            if (frc.NTxAnts>1)
                if (~any(TBSs) || ~updatePMI)
                    % Use previous PMI value if in a subframe not used for
                    % uplink in TDD, or if PMI update is not configured for
                    % this subframe.
                    PMI = txPMIs(:, mod(pmiIdx-1, pmiDelay)+1);
                else
                    % Update PMI estimate. If not using the perfect channel
                    % estimator, redo channel estimation using only the SRS
                    % for PMI selection purposes.
                    if (~perfectChanEstimator)
                        cec.Reference = 'None';
                        [estChannelGrid, noiseEst] = ...
                            lteULChannelEstimate(frc, frc.PUSCH, cec, ...
                            rxSubframe, refGrid);
                    end
                    PMI = lteULPMISelect(frc, frc.PUSCH, ...
                        estChannelGrid, noiseEst, refGrid, cec);
                end
                txPMIs(:, pmiIdx+1) = PMI;
            end
        end
    end

    % Record the block CRC error and bit throughput for the total number of
    % frames simulated at an SNR point
    crc(ResultIndex, :) = crcSNR(:);
    tput(ResultIndex, :) = tputSNR(:);
    ResultIndex = ResultIndex + 1;
    disp(' ');

end
Simulating at -0.1dB SNR for a total 10 Frame(s) 

Results

The throughput results for the simulation are contained in crc and tput. crc is a matrix where each row contains the results of decoding the CRC for a particular SNR. Each column contains the CRC result for a transport block containing PUSCH data at an SNR. tput is a matrix where each row contains the bit throughput per subframe for a particular SNR. Each column contains the throughput result for a transport block containing PUSCH data at an SNR.

The throughput results are plotted as a percentage of total capacity and actual bit throughput for the range of SNR values input using hMultiCodewordPUSCHResults.m.

hMultiCodewordPUSCHResults(SNRIn, NFrames, trBlkSizes, crc, tput);

Appendix

This example uses these helper functions.

Selected Bibliography

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