주요 콘텐츠

NR NTN PDSCH 처리량

이 예제에서는 3GPP NR 표준에 정의된 대로 NTN(비지상망) 채널에서 5G NR(New Radio) 링크의 PDSCH(physical downlink shared channel) 처리량을 측정하는 방법을 보여줍니다. 이 예제에서는 PDSCH와 DL-SCH(downlink shared channel)를 구현합니다. 송신기 모델에는 PDSCH DM-RS(복조 기준 신호)와 PDSCH PT-RS(위상 추적 기준 신호)가 포함됩니다. 이 예제에서는 NTN 협대역 및 NTN TDL(탭 지연선) 전파 채널을 지원합니다.

소개

이 예제에서는 3GPP NR 표준[1], [2], [3], [4]에 정의된 대로 5G 링크의 PDSCH 처리량을 측정합니다.

이 예제는 다음 5G NR 기능을 모델링합니다.

  • DL-SCH 전송 채널 코딩

  • 계층 개수에 따라 달라지는 다중 코드워드

  • PDSCH, PDSCH DM-RS, PDSCH PT-RS 생성

  • 가변 부반송파 간격과 프레임 뉴머놀로지

  • 일반 및 확장 순환 전치

  • NTN 협대역 및 NTN TDL 전파 채널 모델

그 밖의 시뮬레이션 기능은 다음과 같습니다.

  • SVD(특이값 분해)를 사용한 PDSCH 프리코딩.

  • CP-OFDM(순환 전치 직교 주파수 분할 다중화) 변조.

  • 슬롯별 및 비슬롯별 PDSCH 매핑과 DM-RS 매핑.

  • 타이밍 동기화 및 채널 추정.

  • 전체 반송파에 걸친 BWP(단일 부분 대역폭).

  • 송신기에서의 도플러 사전 보정과 수신기에서의 도플러 보정.

  • (선택 사항) 최대 32개의 프로세스를 지원하는 하이브리드 자동 반복 요청(HARQ).

  • (선택 사항) 메모리 효과가 있거나 메모리 효과가 없는 전력 증폭기 모델링. 메모리 효과가 있는 전력 증폭기 모델링에는 RF Toolbox™가 필요합니다.

  • (선택 사항) 정적 전파 지연과 시변 전파 지연 모델링.

다음 그림은 구현된 처리 체인을 보여줍니다. 명확성을 위해 DM-RS와 PT-RS 생성은 생략되었습니다.

23b_c1_update1_png.PNG

이 예제에서 구현된 단계에 대한 자세한 설명은 5G NR 통신 링크 모델링하기 (5G Toolbox) 항목과 DL-SCH and PDSCH Transmit and Receive Processing Chain (5G Toolbox) 항목을 참조하십시오.

이 예제에서는 광대역 및 서브대역 프리코딩을 지원합니다. SVD를 사용하고 할당(광대역 프리코딩의 경우)이나 서브대역의 모든 PDSCH PRB에서 채널 추정을 평균화하여 프리코딩 행렬을 구합니다.

총 시뮬레이션 시간을 줄이기 위해 Parallel Computing Toolbox™를 사용하여 송신 전력 루프의 송신 전력 값 범위를 병렬로 실행할 수 있습니다.

시뮬레이션 길이, 송신기, 수신기 구성하기

시뮬레이션의 길이를 10ms 프레임의 개수로 설정합니다. 기본적으로 이 예제에서는 2개의 프레임을 사용하지만 의미 있는 처리량 결과를 얻으려면 많은 개수의 10ms 프레임이 필요합니다. 시뮬레이션할 송신 전력 값의 범위를 설정합니다. 송신기 전력은 도플러 사전 보정을 수행하기 전의 시간 영역 파형의 전력으로 정의되며 전력 증폭기의 이득을 포함합니다. 수신기에는 잡음 지수(noise figure)와 안테나 온도(antenna temperature)가 포함됩니다. 잡음 지수는 수신기 내부 잡음을 모델링하고, 안테나 온도는 입력 잡음을 모델링합니다. 이 수신기는 안테나 소자별로 잡음을 지정합니다.

simParameters = struct;                   % Create simParameters structure to
                                          % contain all key simulation parameters
simParameters.NFrames = 2;                % Number of 10 ms frames
simParameters.TxPower = 60:65;            % Transmit power (dBm)
simParameters.RxNoiseFigure = 6;          % Noise figure (dB)
simParameters.RxAntennaTemperature = 290; % Antenna temperature (K)

displaySimulationInformation 변수를 true로 설정하여 각 송신 전력점에서 처리량 시뮬레이션에 대한 정보를 표시합니다.

displaySimulationInformation = true;

전력 증폭기 구성

이 예제에서는 메모리(memory) 전력 증폭기와 메모리리스(memoryless) 전력 증폭기 모델링을 모두 지원합니다. 메모리 효과가 있는 전력 증폭기를 모델링하기 위해서는 이 예제에 RF Toolbox™가 필요합니다.

메모리 전력 증폭기나 메모리리스 전력 증폭기 비선형성을 구성하려면 enablePA 변수를 사용하십시오. 전력 증폭기로 전달되는 입력 신호는 최대 신호 진폭을 갖는 정규화된 신호입니다.

메모리리스 전력 증폭기

TR 38.803의 Annex A에 정의된 다음의 메모리리스 전력 증폭기 모델(paModel) 중 하나를 선택할 수 있습니다.

  • 2.1 GHz Gallium Arsenide (GaAs)

  • 2.1 GHz Gallium Nitride (GaN)

  • 28 GHz complementary metal-oxide semiconductor (CMOS)

  • 28 GHz GaN

또는 paModelCustom으로 설정하고 paCharacteristics 변수를 사용하여 메모리리스 전력 증폭기 특성을 3개의 열을 갖는 행렬로 정의할 수 있습니다. 첫 번째 열은 입력 전력을 dBm 단위로 정의합니다. 두 번째 열은 출력 전력을 dBm 단위로 정의합니다. 세 번째 열은 출력 위상을 도 단위로 정의합니다. paCharacteristics 변수를 빈 값으로 설정하고 paModelCustom으로 설정하면 이 예제에서 2.1GHz LDMOS(laterally-diffused metal-oxide semiconductor) 도허티 기반 증폭기가 사용됩니다.

paModelCustom 이외의 값으로 설정하면 파형에 적용되는 메모리리스 비선형성은 전력 증폭기에 대해 다음 방정식을 따릅니다.

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

이 방정식에서,

  • yP(n)은 출력 신호입니다.

  • x(n)은 입력 신호입니다.

  • Kp는 다항식 차수의 집합입니다.

  • ak는 다항식 계수입니다.

메모리 효과가 있는 전력 증폭기

파형에 메모리 효과가 적용된 비선형성은 다음 메모리 다항 방정식을 따릅니다.

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

이 방정식에서,

  • M은 메모리 다항식 깊이입니다.

  • K는 메모리 다항식 차수입니다.

  • amk는 다항식 계수입니다.

메모리 효과가 있는 전력 증폭기를 모델링하려면 hasMemory 변수를 true로 설정하고 coefficients 변수를 사용하여 다항식 계수를 제공합니다. coefficients 변수는 메모리 다항식 깊이와 같은 행 개수와 메모리 다항식 차수와 같은 열 개수를 갖는 행렬입니다. coefficients를 빈 값으로 설정하면 디폴트 값이 적용됩니다.

기본적으로 이 예제에서는 enablePAfalse로 설정합니다.

enablePA = false;                 % true or false
hasMemory = false;                % true or false
paModel = "2.1GHz GaAs"; % "2.1GHz GaAs", "2.1GHz GaN", "28GHz CMOS", "28GHz GaN", or "Custom"
paCharacteristics = [];         % Lookup table as empty or a matrix with columns: Pin (dBm) | Pout (dBm) | Phase (degrees)
coefficients = [];              % Memory polynomial coefficients

enablePAtrue로 설정하면 scaleFactor 변수를 사용하여 전력 증폭기 비선형성을 유도하기 위한 최대 입력 신호 진폭을 조정하십시오. scaleFactor는 전력 증폭기의 동작 영역을 제어하며 각 송신 안테나에 적용됩니다. scaleFactor 변수를 사용하여 전력 백오프를 설정할 수도 있습니다. 예를 들어 전력 증폭기를 통과하는 신호에 3dB의 전력 백오프를 제공하려면 scaleFactor를 -3으로 설정합니다. 입력 신호가 전력 증폭기 모델의 특성 범위 내에 있도록 하십시오.

scaleFactor가 비어 있으면 이 예제는 다음과 같은 경우에 디폴트 값 -35dB를 사용합니다.

  • hasMemoryfalse이고, paModelCustom이고, paCharacteristics가 비어 있습니다.

  • hasMemorytrue이고 coefficients가 비어 있습니다.

나머지 경우에서 scaleFactor를 빈 값으로 설정하면 이 예제는 디폴트 값 0dB을 사용합니다.

scaleFactor = []; % Amplitude scaling, in dB

도플러 보정 구성

이 예제에서는 송신기에서와 수신기에서의 두 가지 도플러 보정 구성을 지원합니다. 송신기에서의 보정의 경우 DopplerPreCompensator를 활성화합니다. DopplerPreCompensator 필드를 true로 설정하면 위성 이동으로 인한 도플러를 고려하여, 송신된 파형에 도플러 사전 보정을 적용합니다. 수신기에서의 보정의 경우 RxDopplerCompensator 필드를 활성화합니다. RxDopplerCompensator 필드를 true로 설정하면 순환 전치와 기준 신호를 사용하여 수신된 파형의 도플러 편이를 추정하고 보정합니다. RxDopplerCompensator 필드를 true로 설정할 때 RxDopplerCompensationMethod 필드를 사용하여 수신기에서 도플러를 추정하고 보정하는 기법을 선택할 수 있습니다. RxDopplerCompensationMethod 필드는 다음을 지원합니다.

  • 수신기가 먼저 주파수나 도플러 편이를 보정한 다음 타이밍 오프셋을 보정하는 독립적 시간-주파수 동기화(independent time-freq).

  • 수신기가 주파수와 시간을 한 번에 보정하는 결합 시간-주파수 동기화(joint time-freq).

기본적으로 이 예제에서는 UE(사용자 단말)가 위성 빔 중심에 있다고 가정합니다. 다음 이미지에 표시된 대로 위성 빔 중심이 아닌 위치에 있는 UE를 모델링하고 빔의 모든 UE에 공통된 도플러 편이(fd,common)를 적용하려면 PreCompensationDopplerShift 필드를 사용할 수 있습니다. PreCompensationDopplerShift 필드가 비어 있으면 이 예제에서는 fd,common을 UE에서의, 위성으로 인한 도플러 편이(fd,sat)로 사용합니다. 이 예제에서는 fd,common이 알려져 있다고 가정합니다. PreCompensationDopplerShift 필드가 비어 있지 않을 때 링크 성능을 관측하려면 DopplerPreCompensator 필드와 RxDopplerCompensator 필드를 모두 true로 설정해야 합니다. DopplerPreCompensator를 활성화하면 fd,common을 보정하고, RxDopplerCompensator를 활성화하면 UE 이동으로 인한 도플러 편이와 함께 잔차 위성 도플러 편이(fd,sat-fd,common)를 보정합니다.

ntn_pdsch_link_ex1.PNG

simParameters.DopplerPreCompensator = true;
simParameters.PreCompensationDopplerShift = [];                   % In Hz
simParameters.RxDopplerCompensator = false;
simParameters.RxDopplerCompensationMethod = "independent time-freq";
% The example uses below fields to estimate Doppler shift, when
% RxDopplerCompensator is set to true and RxDopplerCompensationMethod is
% set to joint 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;

초기 타이밍 동기화 알고리즘 선택

초기 타이밍 동기화를 위한 알고리즘을 선택합니다.

  • 자기 상관(auto corr): 수신기가 PDSCH DM-RS의 자기 상관(auto correlation)을 사용하여 타이밍 동기화를 수행합니다.

  • 차등 상관(diff corr): 수신기가 PDSCH DM-RS와의 차등 상관(differential correlation)을 사용하여 타이밍 동기화를 수행합니다.

  • 결합 시간-주파수 기법(joint time-freq): 수신기가 초기 주파수와 초기 타이밍을 한 번에 보정하여 타이밍 동기화를 수행합니다.

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;

반송파 및 PDSCH 구성

시뮬레이션의 주요 파라미터를 설정합니다. 이러한 파라미터에는 다음이 포함됩니다.

  • 리소스 블록(RB)의 대역폭

  • 부반송파 간격(SCS)(단위: kHz): 15, 30, 60, 120, 240, 480 또는 960

  • 순환 전치 길이(CP): 일반 또는 확장

  • 셀 ID

  • 송신 안테나와 수신 안테나 개수

다음과 같은 DL-SCH 파라미터와 PDSCH 파라미터를 포함하는 하위 구조체를 만듭니다.

  • 목표 코드율

  • 할당된 리소스 블록(PRBSet)

  • 변조 방식: QPSK, 16QAM, 64QAM 또는 256QAM

  • 계층 개수

  • PDSCH 매핑 유형

  • DM-RS 구성 파라미터

  • PT-RS 구성 파라미터

% Set waveform type and PDSCH numerology (SCS and CP type)
simParameters.Carrier = nrCarrierConfig;
simParameters.Carrier.SubcarrierSpacing = 30;
simParameters.Carrier.CyclicPrefix = "Normal";
% Bandwidth in number of RBs (11 RBs at 30 kHz SCS for 5 MHz bandwidth)
simParameters.Carrier.NSizeGrid = 11;
% Physical layer cell identity
simParameters.Carrier.NCellID = 1;

% PDSCH/DL-SCH parameters
% This PDSCH definition is the basis for all PDSCH transmissions in the
% throughput simulation
simParameters.PDSCH = nrPDSCHConfig;
% This structure is to hold additional simulation parameters for the DL-SCH
% and PDSCH
simParameters.PDSCHExtension = struct();

% Define PDSCH time-frequency resource allocation per slot to be full grid
% (single full grid BWP)
% PDSCH PRB allocation
simParameters.PDSCH.PRBSet = 0:simParameters.Carrier.NSizeGrid-1;
% Starting symbol and number of symbols of each PDSCH allocation
simParameters.PDSCH.SymbolAllocation = [0,simParameters.Carrier.SymbolsPerSlot];
simParameters.PDSCH.MappingType = "A";

% Scrambling identifiers
simParameters.PDSCH.NID = simParameters.Carrier.NCellID;
simParameters.PDSCH.RNTI = 1;

% PDSCH resource block mapping (TS 38.211 Section 7.3.1.6)
simParameters.PDSCH.VRBToPRBInterleaving = 0;
simParameters.PDSCH.VRBBundleSize = 4;

% Define the number of transmission layers to be used
simParameters.PDSCH.NumLayers = 1;

% Define codeword modulation and target coding rate
% The number of codewords is directly dependent on the number of layers so
% ensure that layers are set first before getting the codeword number
if simParameters.PDSCH.NumCodewords > 1
    % Multicodeword transmission (when number of layers being > 4)
    simParameters.PDSCH.Modulation = ["16QAM","16QAM"];
    % Code rate used to calculate transport block sizes
    simParameters.PDSCHExtension.TargetCodeRate = [490 490]/1024;
else
    simParameters.PDSCH.Modulation = "16QAM";
    % Code rate used to calculate transport block size
    simParameters.PDSCHExtension.TargetCodeRate = 490/1024;
end

% DM-RS and antenna port configuration (TS 38.211 Section 7.4.1.1)
simParameters.PDSCH.DMRS.DMRSPortSet = []; % Use empty to auto-configure the DM-RS ports
simParameters.PDSCH.DMRS.DMRSTypeAPosition = 2;
simParameters.PDSCH.DMRS.DMRSLength = 1;
simParameters.PDSCH.DMRS.DMRSAdditionalPosition = 2;
simParameters.PDSCH.DMRS.DMRSConfigurationType = 2;
simParameters.PDSCH.DMRS.NumCDMGroupsWithoutData = 1;
simParameters.PDSCH.DMRS.NIDNSCID = 1;
simParameters.PDSCH.DMRS.NSCID = 0;

% PT-RS configuration (TS 38.211 Section 7.4.1.2)
simParameters.PDSCH.EnablePTRS = 0;
simParameters.PDSCH.PTRS.TimeDensity = 1;
simParameters.PDSCH.PTRS.FrequencyDensity = 2;
simParameters.PDSCH.PTRS.REOffset = "00";
% PT-RS antenna port, subset of DM-RS port set. Empty corresponds to lowest
% DM-RS port number
simParameters.PDSCH.PTRS.PTRSPortSet = [];

% Reserved PRB patterns, if required (for CORESETs, forward compatibility etc)
simParameters.PDSCH.ReservedPRB{1}.SymbolSet = [];   % Reserved PDSCH symbols
simParameters.PDSCH.ReservedPRB{1}.PRBSet = [];      % Reserved PDSCH PRBs
simParameters.PDSCH.ReservedPRB{1}.Period = [];      % Periodicity of reserved resources

% Additional simulation and DL-SCH related parameters
% PDSCH PRB bundling (TS 38.214 Section 5.1.2.3)
simParameters.PDSCHExtension.PRGBundleSize = [];     % 2, 4, or [] to signify "wideband"
% Rate matching or transport block size (TBS) parameters
% Set PDSCH rate matching overhead for TBS (Xoh) to 6 when PT-RS is enabled, otherwise 0
simParameters.PDSCHExtension.XOverhead = 6*simParameters.PDSCH.EnablePTRS;
% HARQ parameters
% Number of parallel HARQ processes to use
simParameters.PDSCHExtension.NHARQProcesses = 1;
% Enable retransmissions for each process, using redundancy version (RV) sequence [0,2,3,1]
simParameters.PDSCHExtension.EnableHARQ = false;
% LDPC decoder parameters
% Available algorithms: Belief propagation, Layered belief propagation,
%                       Normalized min-sum, Offset min-sum
simParameters.PDSCHExtension.LDPCDecodingAlgorithm = "Normalized min-sum";
simParameters.PDSCHExtension.MaximumLDPCIterationCount = 6;

% Define the overall transmission antenna geometry at end-points
% For NTN narrowband channel, only single-input-single-output (SISO)
% transmission is allowed
% Number of PDSCH transmission antennas (1,2,4,8,16,32,64,128,256,512,1024) >= NumLayers
simParameters.NumTransmitAntennas = 1;
if simParameters.PDSCH.NumCodewords > 1 % Multi-codeword transmission
    % Number of UE receive antennas (even number >= NumLayers)
    simParameters.NumReceiveAntennas = 8;
else
    % Number of UE receive antennas (1 or even number >= NumLayers)
    simParameters.NumReceiveAntennas = 1;
end
% Define data type for resource grids and waveforms
simParameters.DataType = "double";

OFDM 변조 단계 이후 기저대역 파형에 대한 정보를 가져옵니다.

waveformInfo = nrOFDMInfo(simParameters.Carrier);

전파 채널 모델 생성

시뮬레이션을 위한 채널 모델 객체를 만듭니다. NTN 협대역 및 NTN TDL 채널 모델이 모두 지원됩니다[5], [6]. NTN 협대역 및 NTN TDL 채널을 모델링하는 방법에 대한 자세한 내용은 Model NR NTN Channel 항목을 참조하십시오.

% Define the general NTN propagation channel parameters
% Set the NTN channel type to Narrowband for an NTN narrowband channel and
% set the NTN channel type to TDL for an NTN TDL channel.
simParameters.NTNChannelType = "Narrowband";

% Include or exclude free space path loss
simParameters.IncludeFreeSpacePathLoss = true;

% Delay model configuration
% This example models only one-way propagation delay and provides immediate
% feedback without any delay
simParameters.DelayModel = "None";    % "None", "Static", or "Time-varying"

% Set the parameters common to both NTN narrowband and NTN TDL channels
simParameters.CarrierFrequency = 2e9;                  % Carrier frequency (in Hz)
simParameters.ElevationAngle = 50;                     % Elevation angle (in degrees)
simParameters.MobileSpeed = 3*1000/3600;               % Speed of mobile terminal (in m/s)
simParameters.MobileAltitude = 0;                      % Mobile altitude (in m)
simParameters.SatelliteAltitude = 600000;              % Satellite altitude (in m)
simParameters.SampleRate = waveformInfo.SampleRate;
simParameters.RandomStream = "mt19937ar with seed";
simParameters.Seed = 73;
simParameters.OutputDataType = simParameters.DataType;

% Set the following fields for NTN narrowband channel
if simParameters.NTNChannelType == "Narrowband"
    simParameters.Environment = "Urban";
    simParameters.AzimuthOrientation = 0;
end

% Set the following fields for NTN TDL channel
if simParameters.NTNChannelType == "TDL"
    simParameters.DelayProfile = "NTN-TDL-A";
    simParameters.DelaySpread = 30e-9;
end

% Cross-check the PDSCH layering against the channel geometry
HelperNRNTNThroughput.validateNumLayers(simParameters);

% Calculate the Doppler shift due to satellite movement
c = physconst("lightspeed");
satelliteDopplerShift = dopplerShiftCircularOrbit( ...
    simParameters.ElevationAngle,simParameters.SatelliteAltitude, ...
    simParameters.MobileAltitude,simParameters.CarrierFrequency);

% Define NTN narrowband channel based on the specified fields in
% simParameters structure
if simParameters.NTNChannelType == "Narrowband"
    channel = p681LMSChannel;
    channel.Environment = simParameters.Environment;
    channel.AzimuthOrientation = simParameters.AzimuthOrientation;
    channel.CarrierFrequency = simParameters.CarrierFrequency;
    channel.ElevationAngle = simParameters.ElevationAngle;
    channel.MobileSpeed = simParameters.MobileSpeed;
    channel.SatelliteDopplerShift = satelliteDopplerShift;
end

% Define NTN TDL channel based on specified fields in simParameters
% structure
if simParameters.NTNChannelType == "TDL"
    channel = nrTDLChannel;
    channel.DelayProfile = simParameters.DelayProfile;
    channel.DelaySpread = simParameters.DelaySpread;
    channel.SatelliteDopplerShift = satelliteDopplerShift;
    channel.MaximumDopplerShift = ...
        simParameters.MobileSpeed*simParameters.CarrierFrequency/c;
    channel.NumTransmitAntennas = simParameters.NumTransmitAntennas;
    channel.NumReceiveAntennas = simParameters.NumReceiveAntennas;
end

% Assign the parameters common to both TDL and narrowband channels
channel.SampleRate = simParameters.SampleRate;
channel.RandomStream = simParameters.RandomStream;
channel.Seed = simParameters.Seed;

% Get the maximum number of delayed samples due to a channel multipath
% component. The maximum number of delayed samples is calculated from the
% channel path with the maximum delay and the implementation delay of the
% channel filter. This number of delay samples is required later to buffer
% and process the received signal with the expected length.
chInfo = info(channel);
maxChDelay = ceil(max(chInfo.PathDelays*channel.SampleRate)) + ...
    chInfo.ChannelFilterDelay;

처리 루프

각 송신 전력점의 처리량을 확인하려면 다음 단계를 사용하여 각 송신 인스턴스에 대한 PDSCH 데이터를 분석합니다.

  1. 전송 블록 생성 — PDSCH 구성에 따라 각 코드워드에 대한 전송 블록 크기를 구합니다. 주어진 HARQ 프로세스의 송신 상태에 따라 각 송신에 대해 새로운 전송 블록을 생성합니다.

  2. 리소스 그리드 생성 nrDLSCH (5G Toolbox) System object™가 전송 채널 코딩을 수행합니다. 객체는 입력 전송 블록에서 작동합니다. nrPDSCH (5G Toolbox) 함수는 인코딩된 데이터 비트를 변조합니다. 변조된 심볼에 구현별 MIMO(다중 입력 다중 출력) 프리코딩을 적용합니다. 이 변조된 심볼을 기준 신호와 함께 리소스 그리드에 매핑합니다.

  3. 파형 생성 nrOFDMModulate (5G Toolbox) 함수는 생성된 리소스 그리드의 OFDM 변조를 수행하여 시간 영역 파형을 제공합니다. 각 안테나의 최대 파형 진폭으로 파형을 정규화합니다.

  4. 전력 증폭기 비선형성 적용 — 입력 스케일링 인자에 따라 정규화된 파형의 진폭을 조정합니다. 메모리 전력 증폭기나 메모리리스 전력 증폭기 비선형성을 기저대역 OFDM 파형에 적용합니다. 파형 전력을 원하는 송신 전력으로 스케일링합니다.

  5. 도플러 사전 보정 적용 — 생성된 파형에 위성 이동으로 인한 도플러 편이를 적용하여 채널로 인한 위성 도플러 편이를 사전 보정합니다.

  6. 잡음 있는 채널 모델링 및 적용 — 전파 지연에 따라, 생성된 파형을 지연시킵니다. 지연된 파형을 NTN 협대역 또는 NTN TDL 페이딩 채널에 통과시켜 페이딩된 파형을 얻습니다. 경로 손실을 적용하고 페이딩된 파형에 열 잡음을 추가합니다.

  7. 초기 동기화 수행 — 에너지 감지를 사용하여 신호의 존재를 확인합니다. 에너지 감지 후, 수신된 파형은 초기 슬롯의 PDSCH DM-RS를 사용하여 초기 타이밍 오프셋을 얻습니다. 초기 동기화가 이루어질 때까지 이 단계를 수행합니다.

  8. 도플러 보정 적용 — 수신된 파형의 도플러 편이를 추정하고 도플러 편이를 보정합니다.

  9. 동기화 및 OFDM 복조 수행 — 타이밍 동기화를 위해, 수신된 파형을 PDSCH DM-RS와 상관시킵니다. nrOFDMDemodulate (5G Toolbox) 함수는 동기화된 신호를 OFDM 복조합니다.

  10. 채널 추정 수행 — 채널 추정을 위해 PDSCH DM-RS가 사용됩니다.

  11. 이퀄라이제이션 및 CPE 보정 수행 nrEqualizeMMSE (5G Toolbox) 함수는 수신된 PDSCH RE에 대해 이퀄라이제이션을 수행합니다. PT-RS 심볼을 사용하여 CPE(공통 위상 오차)를 추정한 다음 기준 PT-RS OFDM 심볼의 범위 내에서 각 OFDM 심볼의 오차를 보정합니다.

  12. 프리코딩 행렬 계산 — SVD를 사용하여 다음 송신을 위한 프리코딩 행렬 W를 생성합니다.

  13. PDSCH 디코딩 — 수신된 코드워드를 추정하기 위해 nrPDSCHDecode (5G Toolbox) 함수를 사용하여 잡음 추정과 함께 이퀄라이제이션된 PDSCH 심볼을 복조하고 디스크램블합니다.

  14. DL-SCH 디코딩 — 디코딩된 소프트 비트를 nrDLSCHDecoder (5G Toolbox) System object에 통과시킵니다. 객체는 코드워드를 디코딩하고 블록 CRC(순환 중복 검사) 오류를 반환합니다. CRC 오류를 사용하여 HARQ 프로세스를 업데이트합니다. 이 예제에서는 CRC 오류를 사용하여 PDSCH 링크의 처리량을 결정합니다.

% Compute the noise amplitude per receive antenna
kBoltz = physconst("boltzmann");
NF = 10^(simParameters.RxNoiseFigure/10);
T0 = 290;                                               % Noise temperature at the input (K)
Teq = simParameters.RxAntennaTemperature + T0*(NF-1);   % K
N0_ampl = sqrt(kBoltz*waveformInfo.SampleRate*Teq/2.0);

% Number of transmit power points
numTxPowerPoints = length(simParameters.TxPower);
% Array to store the maximum throughput for all transmit power points
maxThroughput = zeros(numTxPowerPoints,1);
% Array to store the simulation throughput for all transmit power points
simThroughput = zeros(numTxPowerPoints,1);
% Array to store the signal-to-noise ratio (SNR) for all transmit power points
snrVec = zeros(numTxPowerPoints,1);

% Common Doppler shift for use in the simulations
if isempty(simParameters.PreCompensationDopplerShift)
    commonDopplerShift = satelliteDopplerShift;
else
    commonDopplerShift = simParameters.PreCompensationDopplerShift;
end

% Set up RV sequence for all HARQ processes
if simParameters.PDSCHExtension.EnableHARQ
    % In the final report of RAN WG1 meeting #91 (R1-1719301), it was
    % observed in R1-1717405 that if performance is the priority, [0 2 3 1]
    % should be used. If self-decodability is the priority, it should be
    % taken into account that the upper limit of the code rate at which
    % each RV is self-decodable is in the following order: 0>3>2>1
    rvSeq = [0 2 3 1];
else
    % In case of HARQ disabled, RV is set to 0
    rvSeq = 0;
end

% Create DL-SCH encoder System object to perform transport channel encoding
encodeDLSCH = nrDLSCH;
encodeDLSCH.MultipleHARQProcesses = true;
encodeDLSCH.TargetCodeRate = simParameters.PDSCHExtension.TargetCodeRate;

% Create DL-SCH decoder System object to perform transport channel decoding
decodeDLSCH = nrDLSCHDecoder;
decodeDLSCH.MultipleHARQProcesses = true;
decodeDLSCH.TargetCodeRate = simParameters.PDSCHExtension.TargetCodeRate;
decodeDLSCH.LDPCDecodingAlgorithm = simParameters.PDSCHExtension.LDPCDecodingAlgorithm;
decodeDLSCH.MaximumLDPCIterationCount = ...
    simParameters.PDSCHExtension.MaximumLDPCIterationCount;

% Initialize objects to model delay
tmpInfo = HelperNRNTNThroughput.initializeDelayObjects(simParameters,waveformInfo);
staticDelay = tmpInfo.StaticDelay;
variableIntegerDelay = tmpInfo.VariableIntegerDelay;
variableFractionalDelay = tmpInfo.VariableFractionalDelay;
maxVarPropDelay = tmpInfo.MaxVariablePropDelay;
numVariableIntegSamples = tmpInfo.NumVariableIntegerDelaySamples;
numVariableFracDelaySamples = tmpInfo.NumVariableFractionalDelaySamples;
delayInSeconds = tmpInfo.DelayInSeconds;
pathLoss = tmpInfo.PathLoss;
SU = tmpInfo.SlantDistance;

% Get the starting time of each slot
[slotTimes,symLen] = HelperNRNTNThroughput.getSlotTimes( ...
    simParameters.Carrier.SymbolsPerSlot,waveformInfo.SymbolLengths, ...
    waveformInfo.SampleRate,simParameters.NFrames,simParameters.DataType);

% Check the number of HARQ processes and initial propagation delay
initialSlotDelay = find(slotTimes>=delayInSeconds(1),1)-1;
if simParameters.PDSCHExtension.EnableHARQ
    if simParameters.PDSCHExtension.NHARQProcesses < initialSlotDelay
        error("In case of HARQ, this example supports transmission of continuous data only. " + ... 
            "Set the number of HARQ processes (" + (simParameters.PDSCHExtension.NHARQProcesses) +...
            ") to a value greater than or equal to the maximum propagation delay in slots (" + ...
            initialSlotDelay +").")
    end
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.RxDopplerCompensator == 1 ...
        && simParameters.RxDopplerCompensationMethod == "joint time-freq"
    fVals = simParameters.FrequencyRange(1):simParameters.FrequencyResolution:simParameters.FrequencyRange(2);
else
    % In case of no receiver Doppler compensation, treat the frequency
    % value is 0 Hz.
    fVals = 0;
end

% Initialize the power amplifier function handle or System object depending
% on the input configuration
[hpa,hpaDelay,paInputScaleFactor] = ...
    HelperNRNTNThroughput.initializePA(paModel,hasMemory,paCharacteristics,coefficients);

% Repeat hpa to have independent processing for each antenna
hpa = repmat({hpa},1,simParameters.NumTransmitAntennas);

% Update the power amplifier input scaling factor, based on scaleFactor
if ~isempty(scaleFactor)
    paInputScaleFactor = scaleFactor;
end

% Set a threshold value to detect the valid OFDM symbol boundary. For a
% SISO case, a threshold of 0.48 can be used to have probability of
% incorrect boundary detection around 0.01. Use 0 to avoid thresholding
% logic.
dtxThresold = 0.48;

% Use an offset to account for the common delay. The example, by default,
% does not introduce any common delay and only passes through the channel.
sampleDelayOffset = 0; % Number of samples

% Set usePreviousShift variable to true, to use the shift value estimated
% in first slot directly for the consecutive slots. When set to false, the
% shift is calculated for each slot, considering the range of shift values
% to be whole cyclic prefix length. This is used in the estimation of
% integer Doppler shift.
usePreviousShift = false;

% Set useDiffCorr variable to true, to use the shift estimated from
% differential correlation directly in the integer Doppler shift
% estimation. When set to false, the range of shift values also include the
% shift estimated from differential correlation.
useDiffCorr = true;

% Set the amplitude scaling factor to use in energy detection. For the
% default case, a factor of 1.03 is used to avoid missed detections at 60
% dBm transmit power. A value of 0 assumes each sample is an actual signal.
amplThreshold = 1.03;

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

% Processing loop
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 simulation-level parameter structures so that they
    % are not Parallel Computing Toolbox broadcast variables when using parfor
    simLocal = simParameters;
    waveinfoLocal = waveformInfo;

    % Make copies of channel-level parameters to simplify subsequent
    % parameter referencing
    carrier = simLocal.Carrier;
    rxCarrier = carrier;
    pdsch = simLocal.PDSCH;
    pdschextra = simLocal.PDSCHExtension;
    % Copy of the decoder handle to help Parallel Computing Toolbox
    % classification
    decodeDLSCHLocal = decodeDLSCH;
    decodeDLSCHLocal.reset();       % Reset decoder at the start of each transmit power point

    % Make copies of intermediate variables to have warning-free execution
    % with Parallel Computing Toolbox
    thres = dtxThresold;
    sampleOffset = sampleDelayOffset;
    usePrevShift = usePreviousShift;
    useDiffCorrFlag = useDiffCorr;
    N0 = N0_ampl;
    pl_dB = pathLoss;
    varIntegSamples = numVariableIntegSamples;
    varFracSamples = numVariableFracDelaySamples;
    fValsVec = fVals;
    inifValsVec = inifVals;
    threshFactor = amplThreshold;
    initialDelay = initialSlotDelay;
    preDopplerShift = commonDopplerShift;

    % 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
    reset(channel);

    % 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(staticDelay)
    if isa(variableIntegerDelay,"dsp.VariableIntegerDelay")
        reset(variableIntegerDelay)
    end
    if isa(variableFractionalDelay,"dsp.VariableFractionalDelay")
        reset(variableFractionalDelay)
    end

    % Reset the moving RMS object
    reset(mrms)

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

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

    % Initialize the state of all HARQ processes
    % Create a parallel array of all HARQ processes
    harqEntity = cell(pdschextra.NHARQProcesses,1);
    for harqId = 1:pdschextra.NHARQProcesses
        harqEntity{harqId} = HARQEntity(harqSequence(harqId),rvSeq,pdsch.NumCodewords);
    end

    % Total number of slots in the simulation period
    NSlots = simLocal.NFrames*carrier.SlotsPerFrame;

    % Obtain a precoding matrix (wtx) to use in the transmission of the
    % first transport block
    [estChannelGrid,sampleTimes] = HelperNRNTNThroughput.getInitialChannelEstimate(...
        carrier,simLocal.NumTransmitAntennas,channel,simLocal.DataType);
    newWtx = HelperNRNTNThroughput.getPrecodingMatrix( ...
        carrier,pdsch,estChannelGrid,pdschextra.PRGBundleSize);

    % Loop over the entire waveform length
    for nslot = 0:NSlots-1

        % Update carrier slot number to account for new slot transmission
        carrier.NSlot = nslot;

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

        % Set transport block depending on the HARQ process
        for cwIdx = 1:pdsch.NumCodewords
            % Create a new DL-SCH transport block for new data in the
            % current process
            if harqEntity{txHarqProc+1}.NewData(cwIdx)
                trBlk = randi([0 1],trBlkSizes(cwIdx),1,'int8');
                setTransportBlock(encodeDLSCH,trBlk,cwIdx-1,harqEntity{txHarqProc+1}.HARQProcessID);
                % Flush decoder soft buffer explicitly for any new data
                % because of previous RV sequence time out
                if harqEntity{txHarqProc+1}.SequenceTimeout(cwIdx)
                    resetSoftBuffer(decodeDLSCHLocal,cwIdx-1,harqEntity{txHarqProc+1}.HARQProcessID);
                end
            end
        end

        % Get precoding matrix (wtx) calculated in previous slot
        wtx = newWtx;

        % Create a structure with transport block encoder
        dlsch = struct;
        dlsch.Encoder = encodeDLSCH;
        dlsch.RedundancyVersion = harqEntity{txHarqProc+1}.RedundancyVersion;
        dlsch.HARQProcessID = harqEntity{txHarqProc+1}.HARQProcessID;

        % Generate time-domain waveform
        txWaveform0 = HelperNRNTNThroughput.generatePDSCHWaveform( ...
            carrier,pdsch,dlsch,wtx,simLocal.DataType);

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

        % Adjust the waveform amplitude and pass the waveform through power
        % amplifier
        if (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 = 10*log10(sum(var(txWaveform)));
        powerScaling = (txPowerdBm-30)-wavePower;      % In dB
        txWaveform = db2mag(powerScaling)*txWaveform;

        % Apply Doppler pre-compensation depending on DopplerPreCompensator
        % field
        txWaveform = HelperNRNTNThroughput.compensateDopplerShift(...
            txWaveform,channel.SampleRate, ...
            preDopplerShift,simLocal.DopplerPreCompensator);

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

        % Apply fixed or static delay
        delayedTx = staticDelay(txWaveform);
        % Apply variable integer delay
        if isa(variableIntegerDelay,"dsp.VariableIntegerDelay")
            delayedTx = variableIntegerDelay(delayedTx,varIntegSamples(carrier.NSlot+1));
        end
        % Apply variable fractional delay
        if isa(variableFractionalDelay,"dsp.VariableFractionalDelay")
            delayedTx = variableFractionalDelay(delayedTx,varFracSamples(carrier.NSlot+1));
        end

        % Pass the waveform through the channel
        txWaveform = delayedTx;
        [rxWaveform,pathGains] = channel(txWaveform);

        % Add thermal noise to the received time-domain waveform. Multiply
        % the noise variance with 2 as wgn function performs the scaling
        % within.
        noise = wgn(size(rxWaveform,1),size(rxWaveform,2),2*(N0^2),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 + cast(noise,simLocal.DataType);

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

        % Compute the moving RMS of the signal and perform energy detection
        % for initial synchronization
        metric = mrms(complex(rxWaveform));
        idx = metric > (sqrt(2)*N0*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

            % Use the whole buffered waveform for receiver and generate the
            % reference signals for this particular slot to use for
            % waveform processing.
            rxData = rxBuff;
            [refPDSCHIndices,refPDSCHIndicesInfo] = nrPDSCHIndices(rxCarrier,pdsch);
            refDMRSSymbols = nrPDSCHDMRS(rxCarrier,pdsch);
            refDMRSIndices = nrPDSCHDMRSIndices(rxCarrier,pdsch);
            refPTRSSymbols = nrPDSCHPTRS(rxCarrier,pdsch);
            refPTRSIndices = nrPDSCHPTRSIndices(rxCarrier,pdsch);
        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));

        % Due to large Doppler shift, the estimate using the DM-RS
        % correlation gives an inaccurate estimate. Thus, perform joint
        % time and Doppler shift estimation for the received signal to get
        % the initial timing offset.
        if rxCarrier.NSlot == 0
            if simLocal.InitialTimingSynchronization == "auto corr"
                initialOffset = nrTimingEstimate(rxCarrier,rxData,refDMRSIndices,refDMRSSymbols);
            elseif simLocal.InitialTimingSynchronization == "diff corr"
                initialOffset = HelperNRNTNThroughput.diffcorr( ...
                    rxCarrier,rxData,refDMRSIndices,refDMRSSymbols);
            else
                initialOffset = HelperNRNTNThroughput.jointTimeFreq( ...
                    rxCarrier,rxData,refDMRSIndices,refDMRSSymbols,inifValsVec);
            end
            d = maxVarPropDelay;
            if d > initialOffset
                d = initialOffset;
            end
        else
            % Use the timing estimate for the required number of samples
            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+maxVarPropDelay+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,:);

        if simLocal.RxDopplerCompensator && ...
                simLocal.RxDopplerCompensationMethod == "joint time-freq"
            % Perform joint time-frequency synchronization
            [offset,fOEst] = HelperNRNTNThroughput.jointTimeFreq( ...
                rxCarrier,rxWaveform,refDMRSIndices,refDMRSSymbols,fValsVec);
            % Compensate Doppler shift
            rxWaveform = HelperNRNTNThroughput.compensateDopplerShift( ...
                rxWaveform,waveinfoLocal.SampleRate, ...
                fOEst,true);
            % Estimate and compensate the residual Doppler shift
            [fractionalDopplerShift,detFlag] = ...
                HelperNRNTNThroughput.estimateFractionalDopplerShift( ...
                rxWaveform,rxCarrier.SubcarrierSpacing,waveinfoLocal.Nfft, ...
                waveinfoLocal.CyclicPrefixLengths(2),0,true);
            rxWaveform = HelperNRNTNThroughput.compensateDopplerShift( ...
                rxWaveform,waveinfoLocal.SampleRate, ...
                fractionalDopplerShift,true);
            % Get the estimated Doppler shift value
            estimatedDS = fractionalDopplerShift + fOEst;
        else
            % Perform fractional Doppler frequency shift estimation and
            % compensation. Use the cyclic prefix in the OFDM waveform to
            % compute the fractional Doppler shift.
            [fractionalDopplerShift,detFlag] = ...
                HelperNRNTNThroughput.estimateFractionalDopplerShift( ...
                rxWaveform,rxCarrier.SubcarrierSpacing,waveinfoLocal.Nfft, ...
                waveinfoLocal.CyclicPrefixLengths(2),thres, ...
                simLocal.RxDopplerCompensator);
            rxWaveform = HelperNRNTNThroughput.compensateDopplerShift( ...
                rxWaveform,waveinfoLocal.SampleRate, ...
                fractionalDopplerShift,simLocal.RxDopplerCompensator);

            % Perform integer Doppler frequency shift estimation and
            % compensation. Use the demodulation reference signals to
            % compute the integer Doppler shift.
            [integerDopplerShift,shiftOut] = ...
                HelperNRNTNThroughput.estimateIntegerDopplerShift( ...
                rxCarrier,rxWaveform,refDMRSIndices,refDMRSSymbols,sampleOffset, ...
                usePrevShift,useDiffCorrFlag,shiftOut-sampleOffset,totalDelay, ...
                (simLocal.RxDopplerCompensator && detFlag));
            rxWaveform = HelperNRNTNThroughput.compensateDopplerShift( ...
                rxWaveform,waveinfoLocal.SampleRate, ...
                integerDopplerShift,simLocal.RxDopplerCompensator);

            % Get the estimated Doppler shift value
            estimatedDS = fractionalDopplerShift + integerDopplerShift;

            % For timing synchronization, correlate the received waveform with
            % the PDSCH 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

        % Perform OFDM demodulation on the received data to recreate the
        % resource grid. Include zero padding in the event that practical
        % synchronization results in an incomplete slot being demodulated.
        rxGrid = nrOFDMDemodulate(rxCarrier,rxWaveform);
        [K,L,R] = size(rxGrid);
        if (L < rxCarrier.SymbolsPerSlot)
            rxGrid = cat(2,rxGrid,zeros(K,rxCarrier.SymbolsPerSlot-L,R));
        end

        % Perform least squares channel estimation between the received
        % grid and each transmission layer, using the PDSCH DM-RS for each
        % layer. This channel estimate includes the effect of transmitter
        % precoding.
        [estChannelGrid,noiseEst] = nrChannelEstimate(rxCarrier,rxGrid,...
            refDMRSIndices,refDMRSSymbols,'CDMLengths',pdsch.DMRS.CDMLengths);

        % Get PDSCH REs from the received grid and estimated channel grid
        [pdschRx,pdschHest] = nrExtractResources(...
            refPDSCHIndices,rxGrid,estChannelGrid);

        % Remove precoding from estChannelGrid prior to precoding
        % matrix calculation
        estChannelGridPorts = HelperNRNTNThroughput.precodeChannelEstimate(...
            rxCarrier,estChannelGrid,conj(wtx));

        % Get precoding matrix for next slot
        newWtx = HelperNRNTNThroughput.getPrecodingMatrix(...
            rxCarrier,pdsch,estChannelGridPorts,pdschextra.PRGBundleSize);

        % Perform equalization
        [pdschEq,csi] = nrEqualizeMMSE(pdschRx,pdschHest,noiseEst);

        % Common phase error (CPE) compensation
        if ~isempty(refPTRSIndices)
            % Initialize temporary grid to store equalized symbols
            tempGrid = nrResourceGrid(rxCarrier,pdsch.NumLayers);

            % Extract PT-RS symbols from received grid and estimated
            % channel grid
            [ptrsRx,ptrsHest,~,~,~,ptrsLayerIndices] = ...
                nrExtractResources(refPTRSIndices,rxGrid,estChannelGrid,tempGrid);

            % Equalize PT-RS symbols and map them to tempGrid
            ptrsEq = nrEqualizeMMSE(ptrsRx,ptrsHest,noiseEst);
            tempGrid(ptrsLayerIndices) = ptrsEq;

            % Estimate the residual channel at the PT-RS locations in
            % tempGrid
            cpe = nrChannelEstimate(tempGrid,refPTRSIndices,refPTRSSymbols,...
                CyclicPrefix=rxCarrier.CyclicPrefix);

            % Sum estimates across subcarriers, receive antennas, and
            % layers. Then, get the CPE by taking the angle of the
            % resultant sum
            cpe = angle(sum(cpe,[1 3 4]));

            % Map the equalized PDSCH symbols to tempGrid
            tempGrid(refPDSCHIndices) = pdschEq;

            % Correct CPE in each OFDM symbol within the range of reference
            % PT-RS OFDM symbols
            symLoc = ...
                refPDSCHIndicesInfo.PTRSSymbolSet(1)+1:refPDSCHIndicesInfo.PTRSSymbolSet(end)+1;
            tempGrid(:,symLoc,:) = tempGrid(:,symLoc,:).*exp(-1i*cpe(symLoc));

            % Extract PDSCH symbols
            pdschEq = tempGrid(refPDSCHIndices);
        end

        if ~any(isnan(pdschEq))
            % Decode PDSCH symbols
            [dlschLLRs,rxSymbols] = nrPDSCHDecode(rxCarrier,pdsch,pdschEq,noiseEst);

            % Scale the decoded log-likelihood ratios (LLRs) by channel state
            % information (CSI)
            csi = nrLayerDemap(csi);                                    % CSI layer demapping
            for cwIdx = 1:pdsch.NumCodewords
                Qm = length(dlschLLRs{cwIdx})/length(rxSymbols{cwIdx}); % Bits per symbol
                csi{cwIdx} = repmat(csi{cwIdx}.',Qm,1);                 % Expand by each bit
                                                                        % per symbol
                dlschLLRs{cwIdx} = dlschLLRs{cwIdx} .* csi{cwIdx}(:);   % Scale by CSI
            end

            % Decode the DL-SCH transport channel
            decodeDLSCHLocal.TransportBlockLength = trBlkSizes;
            [decbits,blkerr] = decodeDLSCHLocal(dlschLLRs,pdsch.Modulation,...
                pdsch.NumLayers,harqEntity{rxHarqProc+1}.RedundancyVersion,...
                harqEntity{rxHarqProc+1}.HARQProcessID);
        else
            blkerr = true;
        end

        % 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,refPDSCHIndicesInfo.G);
        rxCarrier.NSlot = rxCarrier.NSlot + 1;

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

    end

    % Display the results
    if displaySimulationInformation == 1
        snrdb = 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);
        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,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,simThroughput(txPowIdx)*100/maxThroughput(txPowIdx));
        end
    end

end
Throughput(Mbps) for 2 frame(s) at transmit power 60 dBm (modeled SNR per RE 5.3762 dB): 0.0000
Throughput(%) for 2 frame(s) at transmit power 60 dBm (modeled SNR per RE 5.3762 dB): 0.0000
Throughput(Mbps) for 2 frame(s) at transmit power 61 dBm (modeled SNR per RE 6.3762 dB): 0.0000
Throughput(%) for 2 frame(s) at transmit power 61 dBm (modeled SNR per RE 6.3762 dB): 0.0000
Throughput(Mbps) for 2 frame(s) at transmit power 62 dBm (modeled SNR per RE 7.3762 dB): 0.3368
Throughput(%) for 2 frame(s) at transmit power 62 dBm (modeled SNR per RE 7.3762 dB): 5.2632
Throughput(Mbps) for 2 frame(s) at transmit power 63 dBm (modeled SNR per RE 8.3762 dB): 5.8940
Throughput(%) for 2 frame(s) at transmit power 63 dBm (modeled SNR per RE 8.3762 dB): 92.1053
Throughput(Mbps) for 2 frame(s) at transmit power 64 dBm (modeled SNR per RE 9.3762 dB): 6.3992
Throughput(%) for 2 frame(s) at transmit power 64 dBm (modeled SNR per RE 9.3762 dB): 100.0000
Throughput(Mbps) for 2 frame(s) at transmit power 65 dBm (modeled SNR per RE 10.3762 dB): 6.3992
Throughput(%) for 2 frame(s) at transmit power 65 dBm (modeled SNR per RE 10.3762 dB): 100.0000

결과

측정된 처리량을 표시합니다. 이 값은 데이터 송신에 사용 가능한 리소스를 고려했을 때의 링크의 최대 가능한 처리량의 백분율입니다.

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=11 / SCS=30kHz, 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;

다음 그림은 5MHz 송신 대역폭을 사용하는 30kHz SCS의 반송파에 대해 1000프레임(NFrames = 1000, TxPower = 60:70)을 시뮬레이션하여 구한 처리량 결과를 보여줍니다. 시뮬레이션 설정에는 NTN 협대역 채널을 사용하는 PDSCH 구성과 디폴트 반송파가 포함됩니다. Doppler Pre-compensation(도플러 사전 보정)에 해당하는 선은 DopplerPreCompensator 필드를 true로, PreCompensationDopplerShift[]로, RxDopplerCompensator 필드를 false로 설정하여 얻을 수 있습니다. Rx Doppler Compensation(Rx 도플러 보정)에 해당하는 선은 DopplerPreCompensator 필드를 false로, RxDopplerCompensator 필드를 true로, RxDopplerCompensationMethod 필드를 "independent time-freq"로 설정하여 얻을 수 있습니다.

23b_longrun_default.jpg

심층 탐구

이 예제를 사용하여 다음 옵션을 더 자세히 살펴볼 수 있습니다.

  • 다른 위성 궤도에 대한 각 송신 전력에서의 처리량을 분석하려면 위성 고도와 위성 속도를 변경해 봅니다.

  • 도플러 보정 기법 없이 링크 성능을 관측하려면 DopplerPreCompensator 필드와 RxDopplerCompensator 필드를 false로 설정합니다.

  • 도플러 사전 보정이 없고 수신기 기법을 사용하여 도플러 편이를 보정하는 경우에서 링크 성능을 관측하려면 DopplerPreCompensator 필드를 false로 설정하고 RxDopplerCompensator 필드를 true로 설정합니다. 수신기 도플러 보정에 대해 "joint time-freq" 또는 "independent time-freq" 방법을 선택합니다.

  • 다양한 시나리오의 처리량 성능을 확인하려면 반송파 뉴머롤로지, 송신 안테나 개수, 수신 안테나 개수를 변경하고 채널 모델 유형을 TDL로 설정합니다.

  • 전파 지연이 있는 경우의 처리량 성능을 확인하려면 DelayModel"Static"이나 "Time-varying"으로 설정합니다.

  • NTN과 지상망의 처리량 성능을 비교하려면 NR PDSCH 처리량 (5G Toolbox)에 나와 있는 대로 nrTDLChannel (5G Toolbox) 채널 객체와 nrCDLChannel (5G Toolbox) 채널 객체를 사용합니다.

지원 파일

이 예제에서는 다음 헬퍼 함수를 사용합니다.

정선된 참고 문헌

[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] 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.

참고 항목

함수

도움말 항목