Contenuto principale

NR NTN PUSCH Throughput

Since R2026a

This example measures 5G New Radio (NR) physical uplink shared channel (PUSCH) throughput over a non-terrestrial network (NTN) service link assuming a regenerative satellite payload. The example supports NTN narrowband, NTN tapped delay line (TDL), and NTN clustered delay line (CDL) propagation channels.

Introduction

NTN extend 5G coverage beyond terrestrial cellular infrastructure to remote, rural, oceanic, and under-served regions. In satellite-based NTN deployments, platforms such as low Earth orbit (LEO), medium Earth orbit (MEO), or geostationary Earth orbit (GEO) satellites integrate into the 5G architecture to provide wide-area connectivity. Depending on the payload architecture, a satellite operates in one of the two modes:

  • Transparent (bent-pipe) mode: Forwards the received RF signal to a gateway without onboard signal processing.

  • Regenerative mode: Performs signal processing functions such as demodulation and decoding onboard, implementing all or part of the gNodeB base station functionality.

NTN defines two main radio links:

  • Service link: Between the user equipment (UE) and the satellite.

  • Feeder link: Between the satellite and the gateway, based on 3GPP or non-3GPP technologies.

This example assumes a regenerative satellite payload as defined by 3GPP NR standards [1], [2], [3], [4], [6], and [7] and measures PUSCH throughput for the service link.

The figure shows an NTN scenario with a regenerative payload as shown in Figure 4.1-2 in 3GPP TR 38.821 [7].

Illustration of a Non-Terrestrial Network (NTN) scenario with a regenerative payload satellite highlighting the ground user equipment connecting the satellite

The figure shows the processing chain for the 5G NTN service uplink using a regenerative satellite payload. To simplify the figure, the demodulation reference signals (DM-RS) and phase tracking reference signals (PT-RS) generation blocks are omitted.

Block diagram of the processing chain for a 5G NTN service uplink using a regenerative payload satellite

The processing blocks include:

UL-SCH (Uplink Shared Channel)

  • UL-SCH transport channel coding.

  • Multiple codewords, dependent on the number of layers.

  • Optional hybrid automatic repeat request (HARQ) support up to 32 processes.

PUSCH (Physical Uplink Shared Channel)

  • Codebook-based and non-codebook-based PUSCH transmission schemes.

  • PUSCH, PUSCH DM-RS, and PUSCH PT-RS generation.

  • Slot-wise and non-slot-wise PUSCH and DM-RS mapping.

Implementation specific precoding

  • Optional PUSCH transform precoding. Set the transform precoding to true for DFT-s-OFDM and false for CP-OFDM.

  • This example does not include closed-loop adaptation of the MIMO precoding according to channel conditions. For codebook-based transmission, the MIMO precoding matrix is selected using the TPMI parameter. For non-codebook-based transmission (or for mapping antenna ports to physical antennas in codebook-based transmission), the MIMO precoding matrix is an identity matrix.

NTN Channel Model

  • NTN Narrowband, NTN TDL, and NTN CDL propagation channel models.

  • Optional static and time-varying propagation delay modeling.

Other features of the simulation are:

  • Optional power amplifier modeling with and without memory. The power amplifier modeling with memory requires RF Toolbox™.

  • Doppler pre-compensation at the transmitter, and Doppler compensation at the receiver.

  • Timing synchronization and channel estimation.

To reduce the total simulation time, you can use Parallel Computing Toolbox™ to execute the range of transmit power values of the transmit power loop in parallel.

Configure Simulation Parameters

Set the simulation length in terms of the number of 10 ms frames. By default, the example uses 3 frames, but a large number of 10 ms frames is necessary to produce meaningful throughput results. For the NR NTN uplink, the UE transmit power (TxPower) represents the post power amplifier output power, before applying Doppler pre-compensation. The receiver parameters include the gain over system noise temperature (RxGByT, in dB/K) and receiver gain (RxGain, in dBi) to model the receiver noise. These parameter values align with the LEO-600 satellite characteristics specified in Table 6.1.1.1-1 of 3GPP TR 38.821 [7].

simParameters = struct;          % Create simParameters structure to
                                 % contain all key uplink simulation parameters
simParameters.NFrames = 3;       % Number of 10 ms frames
simParameters.TxPower = 18:2:30; % UE transmit power (dBm)
simParameters.RxGByT = 1.1;      % Receiver Gain over System Noise Temperature (G/T, in dB/K).
simParameters.RxGain = 30;       % Receiver Gain (G, in dBi)

Set the displaySimulationInformation variable to true to display information about the throughput simulation at each transmit power point.

displaySimulationInformation =  true;

Configure Carrier and PUSCH Parameters

This example uses default parameters based on the G-FR1-NTN-A3-1 scenario defined in Section 6.1.3.3.3 of 3GPP TR 38.108 [9].

% Carrier Configuration as defined in TS 38.211 Sections 4.2, 4.3, and 4.4
simParameters.Carrier = nrCarrierConfig;
simParameters.Carrier.NCellID = 0;     % Physical layer cell identity. Range:[0, 1007]
simParameters.Carrier.SubcarrierSpacing = 15; % 15 | 30 | 60 | 120 (kHz)
simParameters.Carrier.CyclicPrefix = "Normal";      % "Normal" | "Extended" (Extended CP is relevant for 60 kHz SCS only)
simParameters.Carrier.NSizeGrid = 25;                           % 25 RBs (12 subcarriers per RB) at 15kHz SCS - 5 MHz bandwidth

% PUSCH as defined in TS 38.211 Sections 6.3.1, 6.4.1.1, and 6.4.1.2
% This PUSCH definition is the basis for all PUSCH transmissions in the
% throughput simulation
simParameters.PUSCH = nrPUSCHConfig;
simParameters.PUSCH.Modulation = "QPSK";                           % "pi/2-BPSK" | "QPSK" | "16QAM" | "64QAM" | "256QAM"
simParameters.PUSCH.NumLayers = 1;                            % Number of transmission layers
simParameters.PUSCH.MappingType = "A";                          % "A" | "B"
simParameters.PUSCH.SymbolAllocation = [0,simParameters.Carrier.SymbolsPerSlot]; % Starting symbol and number of symbols of each PUSCH allocation
simParameters.PUSCH.PRBSet = 0:simParameters.Carrier.NSizeGrid-1;                % Full grid time-frequency resource allocation per slot
simParameters.PUSCH.TransformPrecoding = false;                   % true for DFT-s-OFDM, false for CP-OFDM. If transform precoding is enabled, the number of layers should be set to 1.
simParameters.PUSCH.TransmissionScheme = "nonCodebook";                   % "codebook" | "nonCodebook"
simParameters.PUSCH.NumAntennaPorts = 1;                                         % Number of antenna ports for codebook-based precoding
simParameters.PUSCH.NID = simParameters.Carrier.NCellID;                         % Scrambling identifier
simParameters.PUSCH.RNTI = 1;                          % UE identifier
simParameters.PUSCH.EnablePTRS = false;                           % Enable or disable PT-RS

% DM-RS and antenna port configuration as defined in TS 38.211 Section 6.4.1.1
simParameters.PUSCH.DMRS.DMRSConfigurationType = 1;   % 1 | 2
simParameters.PUSCH.DMRS.DMRSTypeAPosition = 2;       % 2 | 3. Set when Mapping type is A
simParameters.PUSCH.DMRS.DMRSAdditionalPosition = 1;  % 0 | 1 | 2 | 3. Additional DM-RS symbol positions
simParameters.PUSCH.DMRS.DMRSLength = 1;              % 1 | 2. Number of front-loaded DM-RS symbols
simParameters.PUSCH.DMRS.NIDNSCID = 0;         % Range: [0,65535]. Scrambling identity for CP-OFDM
simParameters.PUSCH.DMRS.NRSID = 0;             % Range: [0,1007]. Scrambling ID for low-PAPR sequences (0...1007)
simParameters.PUSCH.DMRS.NSCID = 0;                   % 0 | 1. Scrambling initialization for CP-OFDM
simParameters.PUSCH.DMRS.NumCDMGroupsWithoutData = 2; % 1 | 2 | 3 . Number of CDM groups without data
simParameters.PUSCH.DMRS.GroupHopping = 0;            % 0 | 1. Group hopping
simParameters.PUSCH.DMRS.SequenceHopping = 0;         % 0 | 1. Sequence hopping

% PUSCH PT-RS configuration when PTRS is enabled as defined in TS 38.211 Section 6.4.1.2
simParameters.PUSCH.PTRS.TimeDensity = 1;       % 1 | 2 | 4. PT-RS time density (L_PT-RS)
simParameters.PUSCH.PTRS.FrequencyDensity = 2;  % 2 | 4. PT-RS frequency density (K_PT-RS)
simParameters.PUSCH.PTRS.REOffset = "00";          % 00 | 01 | 10 | 11. PT-RS resource element offset
simParameters.PUSCH.PTRS.NumPTRSGroups = 2;     % 2 | 4 | 8. Number of PT-RS groups
simParameters.PUSCH.PTRS.NumPTRSSamples = 2;    % 2 | 4.  Number of PT-RS samples per PT-RS group
simParameters.PUSCH.PTRS.NID = 0;          % Range: [0,1007]. PT-RS scrambling identity

% This structure is to hold additional simulation parameters for the UL-SCH
% and PUSCH
simParameters.PUSCHExtension = struct();
simParameters.PUSCHExtension.TargetCodeRate = 308/1024;                    % TS 38.214 Section 6.1.4.1
simParameters.PUSCHExtension.XOverhead = 6*simParameters.PUSCH.EnablePTRS; % Set PUSCH rate matching overhead for TBS (Xoh) to 6 when PT-RS is enabled, otherwise 0
simParameters.PUSCHExtension.NHARQProcesses = 4;    % Number of parallel HARQ processes to use
simParameters.PUSCHExtension.EnableHARQ = true;            % Enable retransmissions for each process, using RV sequence [0,2,3,1]
simParameters.PUSCHExtension.EnableCBGTransmission = false; % Enable CBG-based transmission, otherwise TB-based transmission
simParameters.PUSCHExtension.MaxNumCBG = 4;                                % Maximum number of CBGs per transport block for each HARQ process in CBG-based transmission
simParameters.PUSCHExtension.LDPCDecodingAlgorithm = "Normalized min-sum"; % "Belief propagation" | "Layered belief propagation" | "Normalized min-sum" | "Offset min-sum"
simParameters.PUSCHExtension.MaximumLDPCIterationCount = 6;                % Maximum number of LDPC iterations
simParameters.PUSCHExtension.DMRSPower = 3;                                % The ratio of DM-RS RE power to PUSCH resource element (RE) power in dB

% Define the overall transmission antenna geometry at end-points
% For NTN Narrowband channel, only single-input-single-output (SISO) transmission is allowed
% Number of PUSCH transmission antennas >= NumLayers
simParameters.NumTransmitAntennas = 1;
if simParameters.PUSCH.NumCodewords > 1   % Multi-codeword transmission
    simParameters.NumReceiveAntennas = 8; % Number of NTN receive antennas (even number >= NumLayers)
else
    simParameters.NumReceiveAntennas = 1; % Number of NTN receive antennas (1 or even number >= NumLayers)
end

% Use these array size parameters for NTN CDL channel to model transmit and
% receive antennas
simParameters.TxArraySize = [1 1 1 1 1];       % [M N P Mg Ng], product of all values must be equal to NumTransmitAntennas
simParameters.RxArraySize = [1 1 1 1 1];       % [M N P Mg Ng], product of all values must be equal to NumReceiveAntennas
simParameters.DataType = "double"; % Define data type for resource grids and waveforms

Get information about the baseband waveform after the OFDM modulation step.

waveformInfo = nrOFDMInfo(simParameters.Carrier);

Configure Power Amplifier

Enable or disable power amplifier (PA) modeling using EnablePA. When you enable PA modeling, the example supports two modes:

  • Memoryless PA modeling: Applies predefined or custom nonlinearity models.

  • Memory-based PA modeling: Requires RF Toolbox™ and uses polynomial coefficients to model PA behavior with memory effects. To enable memory-based PA modeling, set HasPAMemory to true.

Memoryless Power Amplifier

To model a memoryless PA, set the PAModel parameter to one of the predefined PA types specified in Annex A of TR 38.803 [8]. The supported models are:

  • 2.1 GHz Gallium Arsenide (GaAs)

  • 2.1 GHz Gallium Nitride (GaN)

  • 28 GHz complementary metal-oxide semiconductor (CMOS)

  • 28 GHz GaN

These PA models are provided for generic NR waveform nonlinearity evaluation. In NR NTN uplink scenarios, only the 2.1 GHz GaAs/GaN reflect realistic UE hardware. For these PA models, the memoryless nonlinearity applied to the waveform is as follows:

yP(n)=kKpakx(n)|x(n)|2k,

where:

  • yP(n) is the output signal.

  • x(n) is the input signal.

  • Kp is the set of polynomial degree(s).

  • ak is the polynomial coefficient.

Alternatively, you can set PAModel to Custom and use PACharacteristics to define the memoryless power amplifier characteristics as a matrix with three columns. The first column defines the input power in dBm. The second column defines the output power in dBm. The third column defines the output phase in degrees. When you set the PACharacteristics variable to empty and PAModel to Custom, this example uses a 2.1 GHz laterally-diffused metal-oxide semiconductor (LDMOS) Doherty-based amplifier.

Power Amplifier With Memory

The nonlinearity with memory applied to the waveform follows this polynomial equation:

yP(n)=m=0M-1k=0K-1amkx(n-m)|x(n-m)|k.

In this equation:

  • M is the memory-polynomial depth.

  • K is the memory-polynomial degree.

  • amk is the polynomial coefficient.

To model the PA with memory, set the PACoefficients variable to provide the polynomial coefficients. The PACoefficients variable is a matrix with number of rows corresponding to memory-polynomial depth and number of columns corresponding to memory-polynomial degree. When you set PACoefficients to empty, the example uses a default 2.44 GHz memory polynomial model as defined in TR 38.803 Appendix A [8].

simParameters.EnablePA = false;                 % true or false
simParameters.HasPAMemory = false;              % true or false
% Power amplifier parameters
simParameters.PAModel = "2.1GHz GaAs"; % "2.1GHz GaAs", "2.1GHz GaN", "28GHz CMOS", "28GHz GaN", or "Custom"
simParameters.PACharacteristics = [];         % Lookup table as empty or a matrix with columns: Pin (dBm) | Pout (dBm) | Phase (degrees)
simParameters.PACoefficients = [];            % Memory polynomial coefficients

The input signal passed to the power amplifier is normalized to its maximum amplitude. Use the PAScaleFactor variable to modify the maximum input signal amplitude to excite the power amplifier nonlinearity. PAScaleFactor controls the operating region of the power amplifier and is applied to each transmit antenna. You can also use the PAScaleFactor variable to set power backoff. For example, to provide a power backoff of 3 dB to a signal passed through the power amplifier, set PAScaleFactor to -3. Ensure that the input signal is within the characterization range of the power amplifier model.

When PAScaleFactor is empty, the example uses a default value of -35 dB in these cases:

  • HasPAMemory is false, PAModel is Custom, and PACharacteristics is empty.

  • HasPAMemory is true and PACoefficients is empty.

In all other cases, when you set PAScaleFactor to empty, the example uses a default value of 0 dB.

simParameters.PAScaleFactor = []; % Amplitude scaling, in dB

Configure Doppler Compensation

The example supports Doppler compensation at both the transmitter and the receiver. Transmitter Doppler compensation applies pre-compensation to the transmitted waveform to correct for Doppler shift caused by satellite and UE movement. Receiver Doppler compensation corrects the residual Doppler shift of the received waveform using the cyclic prefix and reference signals. You can specify the technique for Doppler estimation and compensation at the receiver using the RxDopplerCompensationMethod field. The RxDopplerCompensationMethod field supports:

  • Independent time-frequency synchronization (independent time-freq), where the receiver compensates for frequency or Doppler shift first and then compensates for timing offset.

  • Joint time-frequency synchronization (joint time-freq), where the receiver compensates for both frequency and time at once.

% Doppler compensation parameters
simParameters.RxDopplerCompensationMethod = "independent time-freq";
% Set the search range of Doppler shift in Hz [MIN,MAX]
simParameters.FrequencyRange = [-50e3 50e3];
% Set the search range resolution of Doppler shift in Hz
simParameters.FrequencyResolution = 1e3;

Configure UE and Satellite Position and Velocity

NTN supports two UE categories: with global navigation satellite system (GNSS) support and without GNSS support. For UEs equipped with GNSS, refer to the GPS Legacy Navigation Receiver Positioning Using C/A-Code (Satellite Communications Toolbox) example to estimate the UE position. In scenarios where the GNSS signal is weak, or unavailable, or where the receiver does not have a GNSS module, use the Receiver Position Estimation Using Range and Range-Rate Measurements in NTN Systems (Satellite Communications Toolbox) example to estimate the UE position. In this example, the initial positions and velocities of the UE are specified directly in Earth-Centered Earth-Fixed (ECEF) coordinates.

In NR NTN systems, the UE requires satellite position and velocity information to pre-compensate the Doppler shift. The NTN gNodeB shares the satellite ephemeris information in system information block SIB19 to the UE for NTN access. Ephemeris is expressed either using a position and velocity state vector in ECEF or using orbital parameters in Earth-Centered Inertial (ECI). This example uses ephemeris data in the form of orbital parameters. The parameters defining the orbit are semi-major axis, eccentricity, inclination, right ascension of the ascending node, argument of periapsis, and true anomaly.

By default, this example models a typical NTN scenario in which a ground-based UE communicates with a LEO satellite in a circular polar orbit. The scenario starts at 12:10:18 UTC on December 3, 2025, and runs for 60 seconds. The UE is positioned near the Earth's surface, with a velocity vector representing a slowly moving ground terminal. These default values enable realistic modeling of Doppler effects, propagation delay, and dynamic link geometry as the satellite moves along its circular orbit.

% Satellite scenario simulation parameters
simParameters.ScenarioStartTime = datetime(2025,12,3,12,10,18,'TimeZone','UTC');
simParameters.ScenarioRunTime = 60; % in seconds

% UE position and velocity
simParameters.UEPosition = [-2325213.67; 5933245.99; 265303.05]; % ECEF coordinates [x,y,z] in m
simParameters.UEVelocity = [-0.977; 0.213; 0];                   % ECEF coordinates [x,y,z] in m/s

% Satellite orbital parameters
simParameters.SemiMajorAxis = 6971000; % in meters (altitude ≈ 600 km above Earth's surface)
simParameters.Eccentricity = 0;        % Circular
simParameters.Inclination = 90;        % degrees
simParameters.RAAN = 0;                % degrees
simParameters.Argofperiapsis = 0;      % degrees
simParameters.TrueAnomaly = 0;         % degrees (satellite's position in its orbit at scenario start)

Configure NTN Propagation Channel Model

Create the channel model object for the simulation by setting the NTNChannelType property to select from the Narrowband, TDL, and CDL channel models as described in [5], [6]. For more information on how to model these channels, see Model NR NTN Channel (Satellite Communications Toolbox). To include free-space path loss in the simulation, set EnablePathLoss to true. Specify the carrier frequency for the NTN channel using the CarrierFrequency property, for example, S-band (1980–2010 MHz) or Ka-band (29.5–30.0 GHz), as defined in 3GPP TS 38.811 Section 5.2 [6].

% Define the general NTN propagation channel parameters
simParameters.NTNChannelType = "Narrowband"; % "Narrowband" | "TDL" | "CDL"

% Enable or disable free space path loss
simParameters.EnablePathLoss = true;
% Enable or disable satellite Doppler shift
simParameters.EnableDoppler = true;
% Enable or disable modeling of propagation delay
simParameters.EnableDelay = false;

% Link variation model configuration. Controls how path loss, Doppler
% shift, and propagation delay are updated during the simulation. This
% example models only one-way propagation delay and provides immediate
% feedback without any delay. Set this parameter if any of EnablePathLoss,
% EnableDoppler, or EnableDelay is set to true.
simParameters.LinkVariationModel = "Static"; % "Static" | "Time-varying"

% Set the parameters common to NTN channels
simParameters.CarrierFrequency = 2e9;                % Carrier frequency (in Hz)
simParameters.OutputDataType = simParameters.DataType;

% Channel type specific parameter configuration
if simParameters.NTNChannelType == "Narrowband"
    simParameters.Environment = "Urban";
    simParameters.AzimuthOrientation = 0;
elseif (simParameters.NTNChannelType == "TDL" || simParameters.NTNChannelType == "CDL")
    simParameters.DelayProfile = "NTN-"+ simParameters.NTNChannelType + "-A";
    simParameters.DelaySpread = 30e-9; % seconds (TS 38.901 Section 7.7.3)
end

% Validate PUSCH layering against the channel geometry
HelperNRNTNThroughput.validateNumLayers(simParameters);

Select Initial Timing Synchronization Algorithm

Select an algorithm for initial timing synchronization.

  • Auto correlation (auto corr): The receiver performs timing synchronization using auto correlation with PUSCH DM-RS.

  • Differential correlation (diff corr): The receiver performs timing synchronization using differential correlation with PUSCH DM-RS.

  • Joint time-frequency technique (joint time-freq): The receiver performs timing synchronization by compensating for initial frequency and initial timing at once.

% Timing Synchronization parameters
simParameters.InitialTimingSynchronization = "joint time-freq";
% The example uses below fields to perform initial synchronization, when
% InitialTimingSynchronization is set to joint time-freq.
% Set the initial search range of Doppler shift in Hz [MIN,MAX]
simParameters.InitialFrequencyRange = [-50e3 50e3];
% Set the initial search range resolution of Doppler shift in Hz
simParameters.InitialFrequencyResolution = 1e3;

Initialization

% Compute the access intervals between a moving user equipment (UE) and a
% satellite and find the earliest feasible satellite access start time. For
% each slot beginning at the access start time, calculate elevation, path
% loss, Doppler, and delay
slotParams = HelperNRNTNThroughput.computeAccessSlotParameters(simParameters, waveformInfo);
Access interval table (periods when satellite is visible to UE):
       Source        Target    IntervalNumber         StartTime                EndTime           Duration    StartOrbit    EndOrbit
    _____________    ______    ______________    ____________________    ____________________    ________    __________    ________

    "Satellite 1"     "UE"           1           03-Dec-2025 12:10:18    03-Dec-2025 12:11:18       60           1            1    

Transmission start time : 03-Dec-2025 12:10:18 UTC
% Check the number of HARQ processes and initial propagation delay
initialSlotDelay = find(seconds(slotParams.SlotTimes-slotParams.AccessStartTime)>=slotParams.DelayInSeconds(1),1)-1;
if simParameters.PUSCHExtension.EnableHARQ
    if simParameters.PUSCHExtension.NHARQProcesses < initialSlotDelay
        error("In case of HARQ, this example supports transmission of continuous data only. " + ...
            "Set the number of HARQ processes (" + (simParameters.PUSCHExtension.NHARQProcesses) +...
            ") to a value greater than or equal to the maximum propagation delay in slots (" + ...
            initialSlotDelay +").")
    end
end

% Initialize objects to model delay
delayObjInfo = HelperNRNTNThroughput.initializeDelayObjects(simParameters,waveformInfo,slotParams.DelayInSeconds);

% Compute the noise power per receive antenna
kBoltz = physconst("boltzmann");
NTemp = simParameters.RxGain - simParameters.RxGByT;
NTemp_amp = 10^(NTemp/10); % Linear scale
noisePow = kBoltz*waveformInfo.SampleRate*NTemp_amp;

% Set up RV sequence for all HARQ processes
if simParameters.PUSCHExtension.EnableHARQ
    rvSeq = [0 2 3 1];
else
    rvSeq = 0;
end

% Set up maximum number of CBGs in retransmission
if simParameters.PUSCHExtension.EnableCBGTransmission
    maxNumCBG = simParameters.PUSCHExtension.MaxNumCBG;
else
    maxNumCBG = 1;
end

% Create UL-SCH encoder System object to perform transport channel encoding
encodeULSCH = nrULSCH;
encodeULSCH.MultipleHARQProcesses = true;
encodeULSCH.CBGTransmission = true;
encodeULSCH.TargetCodeRate = simParameters.PUSCHExtension.TargetCodeRate;

% Create UL-SCH decoder System object to perform transport channel decoding
decodeULSCH = nrULSCHDecoder;
decodeULSCH.MultipleHARQProcesses = true;
decodeULSCH.CBGTransmission = true;
decodeULSCH.TargetCodeRate = simParameters.PUSCHExtension.TargetCodeRate;
decodeULSCH.LDPCDecodingAlgorithm = simParameters.PUSCHExtension.LDPCDecodingAlgorithm;
decodeULSCH.MaximumLDPCIterationCount = ...
    simParameters.PUSCHExtension.MaximumLDPCIterationCount;

% Initialize the power amplifier function handle or System object depending
% on the input configuration
[hpa,hpaDelay,paInputScaleFactor] = ...
    HelperNRNTNThroughput.initializePA(simParameters.PAModel,simParameters.HasPAMemory,simParameters.PACharacteristics,simParameters.PACoefficients);
% Repeat hpa to have independent processing for each antenna
hpa = repmat({hpa},1,simParameters.NumTransmitAntennas);
% Update the power amplifier input scaling factor, based on PAScaleFactor
if ~isempty(simParameters.PAScaleFactor)
    paInputScaleFactor = simParameters.PAScaleFactor;
end

% Initial frequency shift search space
if simParameters.InitialTimingSynchronization == "joint time-freq"
    inifVals = simParameters.InitialFrequencyRange(1):simParameters.InitialFrequencyResolution:simParameters.InitialFrequencyRange(2);
else
    inifVals = 0;
end

% Frequency shift search space
if simParameters.RxDopplerCompensationMethod == "joint time-freq"
    fVals = simParameters.FrequencyRange(1):simParameters.FrequencyResolution:simParameters.FrequencyRange(2);
else
    fVals = 0;
end

dtxThresold = 0.48;       % Threshold value to detect the valid OFDM symbol boundary.
sampleDelayOffset = 0;    % Offset to account for the common delay
usePreviousShift = false; % Set to true to use the shift value estimated in first slot directly.
useDiffCorr = true;       % Use the shift estimated from differential correlation directly in the integer Doppler shift estimation.
amplThreshold = 1.03;     % Amplitude scaling factor to use in energy detection.

% Use the minimum number of samples for a slot in the whole frame as
% window length
mrms = dsp.MovingRMS;
slotsPerSubFrameFlag = simParameters.Carrier.SlotsPerSubframe > 1;
symLen = cumsum(waveformInfo.SymbolLengths); % Lengths of each OFDM symbol in a slot
mrms.WindowLength = symLen((1+(slotsPerSubFrameFlag))*simParameters.Carrier.SymbolsPerSlot) ...
    -slotsPerSubFrameFlag*symLen(simParameters.Carrier.SymbolsPerSlot);

if (strcmpi(simParameters.PUSCH.TransmissionScheme,'codebook'))
    % Codebook-based MIMO precoding, F precodes between PUSCH
    % transmit antenna ports and transmit antennas
    F = eye(simParameters.PUSCH.NumAntennaPorts,simParameters.NumTransmitAntennas);
else
    % Non-codebook-based MIMO precoding, F precodes between PUSCH
    % layers and transmit antennas
    F = eye(simParameters.PUSCH.NumLayers,simParameters.NumTransmitAntennas);
end
txSize = size(F,1);

% Compute the number of slots
NSlots = simParameters.NFrames*simParameters.Carrier.SlotsPerFrame;

% Define NTN channel based on the specified fields in simParameters
% structure and compute maximum channel delay
[chan, maxChDelay, ueDoppler] = HelperNRNTNThroughput.configureNTNChannel(simParameters,slotParams.ElevationAngle,waveformInfo.SampleRate);

numTxPowerPoints = length(simParameters.TxPower);
maxThroughput = zeros(numTxPowerPoints,1);
simThroughput = zeros(numTxPowerPoints,1);
snrVec = zeros(numTxPowerPoints,1);
snrdb = zeros(numTxPowerPoints,1);

Processing Loop

To determine the throughput at each transmit power point, analyze the PUSCH data for each transmission instance using these steps.

  1. Generate the transport block — Check the transmission status of the specified HARQ process to determine if retransmission is required. If retransmission is not needed, get the transport block size for each codeword depending on the PUSCH configuration and generate new data.

  2. Generate the resource grid — Perform transport channel coding using the nrULSCH System object™. The object operates on the input transport block and maintains an internal copy for potential retransmissions. Modulate the encoded data bits using the nrPUSCH function. Apply implementation-specific multiple-input-multiple-output (MIMO) precoding to the modulated symbols. If TxScheme is set to 'codebook', note that nrPUSCH already applies codebook-based MIMO precoding internally and the implementation-specific precoding is an additional stage. Finally, map the precoded symbols and reference signals to the resource grid.

  3. Generate the waveform — The nrOFDMModulate function provides the time-domain waveform by performing OFDM modulation of the generated resource grid. Normalize the waveform with the maximum waveform amplitude for each antenna.

  4. Apply power amplifier nonlinearities — Scale the amplitude of normalized waveform depending on the input scaling factor. Apply the memory or memoryless power amplifier nonlinearities to the baseband OFDM waveform. Scale the waveform power to the desired transmit power.

  5. Apply Doppler pre-compensation — Apply the Doppler shift due to satellite and UE movement to the generated waveform to pre-compensate the channel induced Doppler shift.

  6. Model and apply a noisy channel — Delay the generated waveform depending on the propagation latency. Pass the delayed waveform through an NTN narrowband, NTN TDL, or NTN CDL fading channel to get the faded waveform. Apply path loss and add thermal noise to the faded waveform.

  7. Perform initial synchronization — Check the presence of the signal using energy detection. After energy detection, the received waveform uses the PUSCH DM-RS of the initial slot to get the initial timing offset. Perform this step till the initial synchronization is achieved.

  8. Apply Doppler compensation — Estimate the Doppler shift in the received waveform and compensate the Doppler shift.

  9. Perform synchronization and OFDM demodulation — For timing synchronization, the received waveform is correlated with the PUSCH DM-RS. The nrOFDMDemodulate function then OFDM-demodulates the synchronized signal.

  10. Perform channel estimation — For channel estimation, PUSCH DM-RS is used.

  11. Perform equalization and CPE compensation — The nrEqualizeMMSE function equalizes the received PUSCH REs. Use the PT-RS symbols to estimate the common phase error (CPE) and then correct the error in each OFDM symbol within the range of the reference PT-RS OFDM symbols.

  12. Decode the PUSCH — Demodulate and descramble the equalized PUSCH symbols, along with a noise estimate using the nrPUSCHDecode function to obtain an estimate of the received codewords.

  13. Decode the UL-SCH and update the HARQ process with the block CRC error — Pass the decoded soft bits through the nrULSCHDecoder System object. The object decodes the codeword and returns the block cyclic redundancy check (CRC) error. Update the HARQ process with the CRC error. This example determines the throughput of the PUSCH link using the CRC error.

for txPowIdx = 1:numTxPowerPoints% Comment out for parallel computing
% parfor txPowIdx = 1:numTxPowerPoints % Uncomment for parallel computing
    % To reduce the total simulation time, you can execute this loop in
    % parallel by using Parallel Computing Toolbox features. Comment
    % out the for-loop statement and uncomment the parfor-loop statement.
    % If Parallel Computing Toolbox is not installed, parfor-loop defaults
    % to a for-loop statement. Because the parfor-loop iterations are
    % executed in parallel in a nondeterministic order, the simulation
    % information displayed for each transmit power point can be intertwined.
    % To switch off the simulation information display, set the
    % displaySimulationInformation variable (defined earlier in this
    % example) to false.

    % Reset the random number generator so that each transmit power point
    % experiences the same noise realization
    rng(0,"twister");

    % Make copies of the parameter structures so that they are not Parallel
    % Computing Toolbox broadcast variables when using parfor
    simLocal = simParameters;
    waveinfoLocal = waveformInfo;
    carrier = simLocal.Carrier;
    rxCarrier = carrier;
    pusch = simLocal.PUSCH;
    puschextra = simLocal.PUSCHExtension;
    decodeULSCHLocal = decodeULSCH;
    decodeULSCHLocal.reset();

    % Make copies of intermediate variables to have warning-free execution
    % with Parallel Computing Toolbox
    delayParams = delayObjInfo;
    slot_Params = slotParams;
    thres = dtxThresold;
    sampleOffset = sampleDelayOffset;
    usePrevShift = usePreviousShift;
    useDiffCorrFlag = useDiffCorr;
    noisePower = noisePow;
    fValsVec = fVals;
    inifValsVec = inifVals;
    threshFactor = amplThreshold;
    initialDelay = initialSlotDelay;
    maxDopplerUE = ueDoppler;

    % Initialize temporary variables
    offset = 0;
    shiftOut = 0;
    txHarqProc = 0;
    rxHarqProc = 0;
    prevWave = [];
    pathFilters = [];
    rxBuff = [];
    syncCheck = true;

    % Reset the channel so that each transmit power point experiences the
    % same channel realization
    channel = chan;
    reset(channel);

    % Create PUSCH object configured for the non-codebook transmission
    % scheme, used for receiver operations that are performed with respect
    % to the PUSCH layers
    puschNonCodebook = pusch;
    puschNonCodebook.TransmissionScheme = 'nonCodebook';

    % Reset the power amplifier
    for numHPA = 1:numel(hpa)
        if ~isa(hpa{numHPA},"function_handle")
            reset(hpa{numHPA})
        end
    end

    % Reset the delay objects
    reset(delayParams.StaticDelay)
    if isa(delayParams.VariableIntegerDelay,"dsp.VariableIntegerDelay")
        reset(delayParams.VariableIntegerDelay)
    end
    if isa(delayParams.VariableFractionalDelay,"dsp.VariableFractionalDelay")
        reset(delayParams.VariableFractionalDelay)
    end

    % Reset the moving RMS object
    reset(mrms)

    % Transmit power value in dBm
    txPowerdBm = simLocal.TxPower(txPowIdx);
    txPowerdBw = txPowerdBm-30;

    % Specify the order in which we cycle through the HARQ process
    % identifiers
    harqSequence = 0:puschextra.NHARQProcesses-1;

    % Initialize the state of all HARQ processes
    % Create a parallel array of all HARQ processes
    harqEntity = cell(puschextra.NHARQProcesses,1);
    for harqId = 1:puschextra.NHARQProcesses
        harqEntity{harqId} = HARQEntity(harqSequence(harqId),rvSeq,pusch.NumCodewords,maxNumCBG);
    end
    
    % Loop over the entire waveform length
    for nslot = 0:NSlots-1

        % Update carrier slot number to account for new slot transmission
        carrier.NSlot = nslot;
        harqProc = harqEntity{txHarqProc+1};

        % Calculate the transport block sizes for the transmission in the slot
        trBlkSizes = nrTBS(pusch,puschextra.TargetCodeRate,puschextra.XOverhead,carrier);

        % Set transport block depending on the HARQ process
        for cwIdx = 1:pusch.NumCodewords
            % Create a new UL-SCH transport block for new data in the
            % current process
            if harqProc.NewData(cwIdx)
                trBlk = randi([0 1],trBlkSizes(cwIdx),1,'int8');
                setTransportBlock(encodeULSCH,trBlk,BlockID=cwIdx-1, ...
                    HARQID=harqProc.HARQProcessID);
                % Flush decoder soft buffer explicitly for any new data
                % because of previous RV sequence time out
                if harqProc.SequenceTimeout(cwIdx)
                    resetSoftBuffer(decodeULSCHLocal,BlockID=cwIdx-1, ...
                        HARQID=harqProc.HARQProcessID);
                end
            end
        end

        % Create a structure with transport block encoder to generate PUSCH
        % waveform
        ulsch = struct(Encoder = encodeULSCH, ...
            RedundancyVersion = harqProc.RedundancyVersion, ...
            HARQProcessID = harqProc.HARQProcessID, ...
            CBGTI = harqProc.CBGTI);

        % Generate time-domain waveform
        txWaveform0 = HelperNRNTNThroughput.generatePUSCHWaveform( ...
            carrier,pusch,ulsch,F,simLocal.PUSCHExtension.DMRSPower,simLocal.DataType);

        % Normalize the waveform with maximum waveform amplitude
        txWaveform = txWaveform0;
        txWaveform(:,1:txSize) = txWaveform0(:,1:txSize)./max(abs(txWaveform0(:,1:txSize)));

        % Power amplifier and scaling
        if (simLocal.EnablePA == 1)
            % Scale the amplitude of the waveform, as applicable
            txWaveform = txWaveform.*db2mag(paInputScaleFactor);

            % Pass the adjusted waveform through the power amplifier
            for colIdx = 1:size(txWaveform,2)
                hpaTemp = hpa{colIdx};
                txWaveform(:,colIdx) = hpaTemp(txWaveform(:,colIdx));
            end
        end

        % Scale the waveform power based on the input transmit power
        wavePower = pow2db(sum(var(txWaveform(:,1:txSize))));
        powerScaling = txPowerdBw-wavePower;      % in dB
        txWaveform = db2mag(powerScaling)*txWaveform;

        % Apply Doppler pre-compensation
        txWaveform = HelperNRNTNThroughput.compensateDopplerShift(...
            txWaveform,channel.SampleRate, ...
            slot_Params.PreCompDopplerShift(carrier.NSlot+1),true);

        % Apply path loss to the signal
        txWaveform = txWaveform*db2mag(-slotParams.PathLoss(carrier.NSlot+1));

        % Apply fixed or static delay
        delayedTx = delayParams.StaticDelay(txWaveform);
        % Apply variable integer delay
        if isa(delayParams.VariableIntegerDelay,"dsp.VariableIntegerDelay")
            delayedTx = delayParams.VariableIntegerDelay(delayedTx, ...
                cast(delayParams.NumVariableIntegerDelaySamples(carrier.NSlot+1),class(delayedTx)));
        end
        % Apply variable fractional delay
        if isa(delayParams.VariableFractionalDelay,"dsp.VariableFractionalDelay")
            delayedTx = delayParams.VariableFractionalDelay(delayedTx, ...
                cast(delayParams.NumVariableFractionalDelaySamples(carrier.NSlot+1),class(delayedTx)));
        end

        % Pass the waveform through the channel
        txWaveform = delayedTx;
        if simLocal.NTNChannelType~="CDL"
            channel.SatelliteDopplerShift = slot_Params.SatelliteDopplerShift(carrier.NSlot+1);
        else
            channel.MaximumDopplerShift = [slot_Params.SatelliteDopplerShift(carrier.NSlot+1) maxDopplerUE]; % [Rx_Sat Tx_UE]
        end
        rxWaveform = channel(txWaveform);
        rxWaveform = rxWaveform.*db2mag(simParameters.RxGain);

        % Add thermal noise to the received time-domain waveform.
        noise = wgn(size(rxWaveform,1),size(rxWaveform,2),noisePower,1,"linear","complex");
        sigPowerRE = sum(var(rxWaveform))*((waveinfoLocal.Nfft)^2/(carrier.NSizeGrid*12));
        noisePowerRE = sum(var(noise))*(waveinfoLocal.Nfft);
        snrVec(txPowIdx) = snrVec(txPowIdx) + sigPowerRE./noisePowerRE;
        rxWaveform = rxWaveform + noise;

        % Update the transmit HARQ process number
        if puschextra.EnableHARQ
            txHarqProc = mod(txHarqProc+1,puschextra.NHARQProcesses);
        end

        % Compute the moving RMS of the signal and perform energy detection
        % for initial synchronization
        metric = mrms(complex(rxWaveform));
        idx = metric > (sqrt(noisePower)*threshFactor);
        if ~any(idx(:)) && (rxCarrier.NSlot == 0)
            % Store the waveform that didn't pass the metric to use for
            % initial synchronization
            prevWave = rxWaveform;
            continue;
        end
        % Provide a warning when initial synchronization is missed
        if (rxCarrier.NSlot == 0) && syncCheck
            syncCheck = false;
            if (carrier.NSlot > initialDelay)
                warning("Initial slot synchronization is missed for transmit power of %d dBm. " + ...
                    "This can cause failure of all the slots. " + ...
                    "For proper synchronization, increase the transmit power.",txPowerdBm)
            end
        end

        % Buffer all the valid signal such that the length of 3 slots is
        % used for initial synchronization, and some portion of previous
        % slot is used for next slot.
        rxBuff = [rxBuff;prevWave;rxWaveform]; %#ok<AGROW>
        prevWave = [];
        if (size(rxBuff,1) < (3*(mrms.WindowLength))) && (rxCarrier.NSlot == 0)
            continue
        else
            % Here onwards reception happens continuously rxCarrier

            % Use the whole buffered waveform for receiver and generate the
            % reference signals for this particular slot to use for
            % waveform processing.
            rxData = rxBuff;
            refDMRSSymbols = db2mag(simLocal.PUSCHExtension.DMRSPower)*nrPUSCHDMRS(rxCarrier,puschNonCodebook);
            refDMRSIndices = nrPUSCHDMRSIndices(rxCarrier,puschNonCodebook);
        end

        % Gather the number of samples to be processed in current
        % receiver slot.
        % 1. Find the number of cyclic prefix samples used in the current
        % receiver slot and sum of all samples
        % 2. Add the FFT size corresponding to number of OFDM symbols
        % in current slot with the resultant value in step 1
        cpl = circshift(waveinfoLocal.CyclicPrefixLengths,-rxCarrier.NSlot*rxCarrier.SymbolsPerSlot);
        numSamplesInRxSlot = waveinfoLocal.Nfft*rxCarrier.SymbolsPerSlot + sum(cpl(1:rxCarrier.SymbolsPerSlot));

        % Perform initial time synchronization
        dmrsParams = struct(DMRSIndices = refDMRSIndices, DMRSSymbols = refDMRSSymbols);
        if rxCarrier.NSlot == 0
            initialOffset = HelperNRNTNThroughput.estimateInitialTimingOffset( ...
                rxCarrier,rxData,dmrsParams,simLocal.InitialTimingSynchronization,inifValsVec);
            d = min(delayParams.MaxVariablePropDelay,initialOffset);
        else
            initialOffset = 0;
            d = 0;
        end

        % From the starting position provided by initial offset, consider
        % the length of received waveform such that all the delays due to
        % channel, power amplifier, and propagation distance are covered.
        totalDelay = maxChDelay+delayParams.MaxVariablePropDelay+hpaDelay;
        endIdx = initialOffset+numSamplesInRxSlot+totalDelay;
        if endIdx > size(rxData,1)
            endIdx = size(rxData,1);
        end
        rxWaveform = rxData(initialOffset+1:endIdx,:);
        % Update the buffer with portion of present slot data to process
        % the next slot
        rxBuff = rxData(initialOffset-d+(numSamplesInRxSlot+1):end,:);

        % Perform Doppler compensation at the receiver
        rxDopplerParams = struct(CompensationMethod = simLocal.RxDopplerCompensationMethod, ...
            RxCarrier = rxCarrier, FreqSearchRange = fValsVec, Threshold = thres, ...
            UsePrevShift = usePrevShift, SampleOffset = sampleOffset, ...
            Shift = shiftOut-sampleOffset, UseDiffCorrFlag = useDiffCorrFlag, TotalDelay = totalDelay);
        [rxWaveform,offsetVal,shiftOut] = HelperNRNTNThroughput.compensateRxDoppler(rxWaveform, rxDopplerParams, dmrsParams, waveinfoLocal);
        if ~isempty(offsetVal)
            offset = offsetVal;
        end

        if ~(simLocal.RxDopplerCompensationMethod == "joint time-freq")
            % For timing synchronization, correlate the received waveform with
            % the PUSCH DM-RS to give timing offset estimate t and correlation
            % magnitude mag. The function hSkipWeakTimingOffset is used to
            % update the receiver timing offset. If the correlation peak in mag
            % is weak, the current timing estimate t is ignored and the
            % previous estimate offset is used.
            [t,mag] = nrTimingEstimate(rxCarrier,rxWaveform, ...
                refDMRSIndices,refDMRSSymbols);
            offset = hSkipWeakTimingOffset(offset,t,mag);
        end

        rxWaveform = rxWaveform(1+offset:end,:);
        if size(rxWaveform,1) > numSamplesInRxSlot
            rxWaveform = rxWaveform(1:numSamplesInRxSlot,:);
        end
        
        % Initialize parameters for bit recovery
        harqProc = harqEntity{rxHarqProc+1};
        decodeULSCHLocal.TransportBlockLength = trBlkSizes;
        ulschDecParams = struct(Decoder = decodeULSCHLocal, ...
            RedundancyVersion = harqProc.RedundancyVersion, ...
            HARQProcessID = harqProc.HARQProcessID, ...
            CBGTI = harqProc.CBGTI);

        % Recover bits from the received waveform
        [decbits,blkerr,cbgerr,rxInfo] = HelperNRNTNThroughput.recoverPUSCHBits(rxWaveform,rxCarrier,dmrsParams,puschNonCodebook,ulschDecParams);

        % Store values to calculate throughput
        simThroughput(txPowIdx) = simThroughput(txPowIdx) + sum(~blkerr .* trBlkSizes);
        maxThroughput(txPowIdx) = maxThroughput(txPowIdx) + sum(trBlkSizes);

        % Update current process with CRC error and increment slot number
        updateProcess(harqEntity{rxHarqProc+1},blkerr,trBlkSizes,rxInfo.G,cbgerr);
        rxCarrier.NSlot = rxCarrier.NSlot + 1;

        % Increment the receiver HARQ process number
        if puschextra.EnableHARQ
            rxHarqProc = mod(rxHarqProc+1,puschextra.NHARQProcesses);
        end

    end

    % Display the results
    if displaySimulationInformation == 1
        snrdb(txPowIdx) = pow2db(snrVec(txPowIdx)./NSlots);
        if rxCarrier.NSlot == 0
            fprintf("\nNo slot is processed in the receiver at transmit power %d dBm (modeled SNR per RE %.4f dB)", ...
                txPowerdBm,snrdb(txPowIdx));
        else
            fprintf("\nThroughput(Mbps) for %d frame(s) at transmit power %d dBm (modeled SNR per RE %.4f dB): %.4f\n",...
                simLocal.NFrames,txPowerdBm,snrdb(txPowIdx),1e-6*simThroughput(txPowIdx)/(simLocal.NFrames*10e-3));
            fprintf("Throughput(%%) for %d frame(s) at transmit power %d dBm (modeled SNR per RE %.4f dB): %.4f\n",...
                simLocal.NFrames,txPowerdBm,snrdb(txPowIdx),simThroughput(txPowIdx)*100/maxThroughput(txPowIdx));
        end
    end
end
Throughput(Mbps) for 3 frame(s) at transmit power 18 dBm (modeled SNR per RE -7.9035 dB): 0.0000
Throughput(%) for 3 frame(s) at transmit power 18 dBm (modeled SNR per RE -7.9035 dB): 0.0000
Throughput(Mbps) for 3 frame(s) at transmit power 20 dBm (modeled SNR per RE -5.9035 dB): 0.0717
Throughput(%) for 3 frame(s) at transmit power 20 dBm (modeled SNR per RE -5.9035 dB): 3.5714
Throughput(Mbps) for 3 frame(s) at transmit power 22 dBm (modeled SNR per RE -3.9047 dB): 0.2152
Throughput(%) for 3 frame(s) at transmit power 22 dBm (modeled SNR per RE -3.9047 dB): 10.7143
Throughput(Mbps) for 3 frame(s) at transmit power 24 dBm (modeled SNR per RE -1.9053 dB): 0.4304
Throughput(%) for 3 frame(s) at transmit power 24 dBm (modeled SNR per RE -1.9053 dB): 21.4286
Throughput(Mbps) for 3 frame(s) at transmit power 26 dBm (modeled SNR per RE 0.0971 dB): 0.7891
Throughput(%) for 3 frame(s) at transmit power 26 dBm (modeled SNR per RE 0.0971 dB): 39.2857
Throughput(Mbps) for 3 frame(s) at transmit power 28 dBm (modeled SNR per RE 2.0982 dB): 1.5781
Throughput(%) for 3 frame(s) at transmit power 28 dBm (modeled SNR per RE 2.0982 dB): 78.5714
Throughput(Mbps) for 3 frame(s) at transmit power 30 dBm (modeled SNR per RE 4.0972 dB): 2.0085
Throughput(%) for 3 frame(s) at transmit power 30 dBm (modeled SNR per RE 4.0972 dB): 100.0000

Results

Display the measured throughput, which is the percentage of the maximum possible throughput of the link given the available resources for data transmission.

figure;
plot(simParameters.TxPower,simThroughput*100./maxThroughput,'o-.')
xlabel('Input Transmit Power (dBm)'); ylabel('Throughput (%)'); grid on;
title(sprintf('NTN %s (%dx%d) / NRB=%d / SCS=%dkHz', ...
simParameters.NTNChannelType,simParameters.NumTransmitAntennas, ...
simParameters.NumReceiveAntennas,simParameters.Carrier.NSizeGrid,...
simParameters.Carrier.SubcarrierSpacing));

Figure contains an axes object. The axes object with title NTN Narrowband (1x1) / NRB=25 / SCS=15kHz, xlabel Input Transmit Power (dBm), ylabel Throughput (%) contains an object of type line.

% Bundle key parameters and results into a combined structure for recording
simResults.simParameters = simParameters;
simResults.simThroughput = simThroughput;
simResults.maxThroughput = maxThroughput;

This next figure shows the throughput results obtained by simulating 1000 frames (NFrames = 1000, TxPower = 20:40) for a carrier with a 15 kHz SCS occupying a 5 MHz transmission bandwidth. The simulation setup includes the default carrier and PUSCH configuration with an NTN narrowband channel.

Further Exploration

You can use this example to further explore these options:

  • To check the throughput performance of different scenarios, change the carrier numerology and the number of transmit and receive antennas, and set the channel model type to TDL or CDL.

  • To check the throughput performance in the time-varying channel, set the LinkVariationModel to "Time-varying".

  • To compare the throughput performance in an NTN and terrestrial network, use the nrTDLChannel and the nrCDLChannel channel objects as shown in NR PUSCH Throughput.

  • To analyze the throughput at each transmit power for a different satellite orbit, vary the satellite orbital parameters. To configure an elliptical orbit, set the eccentricity to a value greater than zero depending on how elongated you want the orbit. Adjust the argument of periapsis and true anomaly to define the orientation and starting position within the ellipse. For real satellite orbits, you can import orbital parameters from a TLE (Two-Line Element) file using a suitable parser.

Supporting Files

The example uses these helper functions:

  • HARQEntity.m — Manage a set of parallel HARQ processes

  • hCompensateCPE.m — Compensate common phase error

  • HelperNRNTNThroughput.m — Class defining the supporting functions used in the example

  • hSkipWeakTimingOffset.m — Skip timing offset estimates with weak correlation

References

[1] 3GPP TS 38.211. "NR; Physical channels and modulation." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[2] 3GPP TS 38.212. "NR; Multiplexing and channel coding." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[3] 3GPP TS 38.213. "NR; Physical layer procedures for control." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[4] 3GPP TS 38.214. "NR; Physical layer procedures for data." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[5] 3GPP TR 38.901. "Study on channel model for frequencies from 0.5 to 100 GHz." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[6] 3GPP TR 38.811. "Study on new radio (NR) to support non-terrestrial networks." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[7] 3GPP TR 38.821. "Solutions for NR to support non-terrestrial networks (NTN)." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[8] 3GPP TR 38.803. "Study on new radio access technology: Radio Frequency (RF) and co-existence aspects." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[9] 3GPP TR 38.108. "NR; Satellite Access Node radio transmission and reception." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

[10] ITU-R Recommendation P.681-11 (08/2019). "Propagation data required for the design systems in the land mobile-satellite service." P Series; Radio wave propagation.

See Also

Topics