Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

NR PDSCH 처리량

이 참조 시뮬레이션에서는 3GPP NR 표준에서 정의한 대로 5G NR(New Radio) 링크의 PDSCH(physical downlink shared channel) 처리량을 측정하는 방법을 보여줍니다. 이 예제는 PDSCH와 DL-SCH(downlink shared channel)를 구현합니다. 송신기 모델은 PDSCH DM-RS(복조 기준 신호)와 PDSCH PT-RS(위상 추적 기준 신호)를 포함합니다. 이 예제는 CDL(클러스터 지연선) 및 TDL(탭 지연선) 전파 채널을 모두 지원합니다. 완벽한 또는 실질적인 동기화와 채널 추정을 수행할 수 있습니다. 총 시뮬레이션 시간을 줄이려면, Parallel Computing Toolbox™를 사용하여 SNR 루프의 SNR 점들을 병렬로 실행할 수 있습니다.

소개

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

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

  • DL-SCH 전송 채널 코딩

  • 다중 코드워드(계층 개수에 따라 달라짐)

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

  • 가변 부반송파 간격과 프레임 뉴머롤로지(2^n * 15kHz)

  • 일반 순환 전치와 확장 순환 전치

  • TDL 전파 채널 모델과 CDL 전파 채널 모델

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

  • SVD를 사용한 PDSCH 서브대역 프리코딩

  • CP-OFDM 변조

  • PDSCH와 DM-RS 매핑(슬롯별인 경우 및 슬롯별이 아닌 경우)

  • 완벽한 또는 실질적인 동기화와 채널 추정

  • 16개 프로세스를 사용한 HARQ 작업

  • 이 예제는 전체 반송파에서 단일 부분 대역폭을 사용함

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

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

이 예제에서는 광대역 프리코딩과 서브대역 프리코딩을 모두 지원합니다. 할당 내 전체(광대역의 경우) 또는 서브대역 내의 PDSCH PRB에 대해 SVD를 사용한 채널 추정 평균화를 통해 프리코딩 행렬을 결정합니다.

총 시뮬레이션 시간을 줄이려면, Parallel Computing Toolbox를 사용하여 SNR 루프의 SNR 점들을 병렬로 실행할 수 있습니다.

시뮬레이션 길이와 SNR 점

10ms 프레임 수에 대한 시뮬레이션 길이를 설정합니다. 의미 있는 처리량 결과를 산출하려면 큰 수의 NFrames를 사용해야 합니다. 시뮬레이션할 SNR 점을 설정합니다. 각 계층의 SNR은 RE별로 정의되며 모든 안테나에서의 신호와 잡음의 영향을 포함합니다. 이 예제에서 사용하는 SNR 정의에 대한 설명은 SNR Definition Used in Link Simulations 항목을 참조하십시오.

simParameters = struct();       % Clear simParameters variable to contain all key simulation parameters
simParameters.NFrames = 2;      % Number of 10 ms frames
simParameters.SNRIn = [-5 0 5]; % SNR range (dB)

채널 추정기 구성

논리형 변수 PerfectChannelEstimator는 채널 추정과 동기화 동작을 제어합니다. true로 설정되면 완벽한 채널 추정과 동기화가 사용됩니다. 그렇지 않으면, 수신된 PDSCH DM-RS의 값에 따라 실질적인 채널 추정과 동기화가 사용됩니다.

simParameters.PerfectChannelEstimator = true;

시뮬레이션 진단

변수 DisplaySimulationInformation은 각 서브프레임에 사용된 HARQ 프로세스 ID와 같은 시뮬레이션 정보 표시를 제어합니다. CRC 오류의 경우, RV 시퀀스에 대한 인덱스 값도 표시됩니다.

simParameters.DisplaySimulationInformation = true;

DisplayDiagnostics 플래그를 사용해서 계층별 EVM을 플로팅할 수 있습니다. 이 플롯은 이퀄라이제이션 후의 수신 신호의 품질을 모니터링합니다. 계층별 EVM Figure에는 다음 사항이 표시됩니다.

  • 슬롯당 계층별 EVM: 시간에 따른 EVM의 변화를 보여줍니다.

  • 리소스 블록당 계층별 EVM: 주파수에서의 EVM을 보여줍니다.

이 Figure는 시뮬레이션이 진행됨에 따라 변화하며 각 슬롯마다 업데이트됩니다. 일반적으로 SNR이 낮거나 채널 페이딩이 발생하면 신호 품질이 떨어집니다(높은 EVM). 채널은 각 계층에 다르게 영향을 미치므로 계층마다 EVM 값이 다를 수 있습니다.

경우에 따라 일부 계층은 다른 계층보다 훨씬 높은 EVM을 가질 수 있습니다. 이러한 낮은 품질 계층은 CRC 오류를 야기할 수 있습니다. 이 동작은 SNR이 낮거나 채널 조건에 너무 많은 계층을 사용했을 때 발생할 수 있습니다. SNR을 높이거나, 계층 개수를 줄이거나, 안테나 개수를 늘이거나, 더 강인한 송신(더 낮은 변조 방식과 목표 코드율)을 만드는 등의 방법을 함께 써서 이러한 상황을 방지할 수 있습니다.

simParameters.DisplayDiagnostics = false;

반송파 및 PDSCH 구성

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

  • 리소스 블록의 대역폭(리소스 블록당 12개의 부반송파)

  • 부반송파 간격: 15, 30, 60, 120(kHz)

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

  • 셀 ID

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

DL-SCH 파라미터와 PDSCH 파라미터를 포함하는 하위 구조도 지정됩니다. 여기에는 다음이 포함됩니다.

  • 목표 코드율

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

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

  • 계층 개수

  • PDSCH 매핑 유형

  • DM-RS 구성 파라미터

  • PT-RS 구성 파라미터

시뮬레이션 전체에 적용되는 기타 파라미터는 다음과 같습니다.

  • 전파 채널 모델 지연 프로파일(TDL 또는 CDL)

% Set waveform type and PDSCH numerology (SCS and CP type)
simParameters.Carrier = nrCarrierConfig;         % Carrier resource grid configuration
simParameters.Carrier.NSizeGrid = 51;            % Bandwidth in number of resource blocks (51 RBs at 30 kHz SCS for 20 MHz BW)
simParameters.Carrier.SubcarrierSpacing = 30;    % 15, 30, 60, 120 (kHz)
simParameters.Carrier.CyclicPrefix = 'Normal';   % 'Normal' or 'Extended' (Extended CP is relevant for 60 kHz SCS only)
simParameters.Carrier.NCellID = 1;               % Cell identity

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

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

% 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; % Disable interleaved resource mapping
simParameters.PDSCH.VRBBundleSize = 4;

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

% 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'};             % 'QPSK', '16QAM', '64QAM', '256QAM'
    simParameters.PDSCHExtension.TargetCodeRate = [490 490]/1024;   % Code rate used to calculate transport block sizes
else
    simParameters.PDSCH.Modulation = '16QAM';                       % 'QPSK', '16QAM', '64QAM', '256QAM'
    simParameters.PDSCHExtension.TargetCodeRate = 490/1024;         % Code rate used to calculate transport block sizes
end

% DM-RS and antenna port configuration (TS 38.211 Section 7.4.1.1)
simParameters.PDSCH.DMRS.DMRSPortSet = 0:simParameters.PDSCH.NumLayers-1; % DM-RS ports to use for the layers
simParameters.PDSCH.DMRS.DMRSTypeAPosition = 2;      % Mapping type A only. First DM-RS symbol position (2,3)
simParameters.PDSCH.DMRS.DMRSLength = 1;             % Number of front-loaded DM-RS symbols (1(single symbol),2(double symbol))
simParameters.PDSCH.DMRS.DMRSAdditionalPosition = 2; % Additional DM-RS symbol positions (max range 0...3)
simParameters.PDSCH.DMRS.DMRSConfigurationType = 2;  % DM-RS configuration type (1,2)
simParameters.PDSCH.DMRS.NumCDMGroupsWithoutData = 1;% Number of CDM groups without data
simParameters.PDSCH.DMRS.NIDNSCID = 1;               % Scrambling identity (0...65535)
simParameters.PDSCH.DMRS.NSCID = 0;                  % Scrambling initialization (0,1)

% PT-RS configuration (TS 38.211 Section 7.4.1.2)
simParameters.PDSCH.EnablePTRS = 0;                  % Enable or disable PT-RS (1 or 0)
simParameters.PDSCH.PTRS.TimeDensity = 1;            % PT-RS time density (L_PT-RS) (1, 2, 4)
simParameters.PDSCH.PTRS.FrequencyDensity = 2;       % PT-RS frequency density (K_PT-RS) (2 or 4)
simParameters.PDSCH.PTRS.REOffset = '00';            % PT-RS resource element offset ('00', '01', '10', '11')
simParameters.PDSCH.PTRS.PTRSPortSet = [];           % PT-RS antenna port, subset of DM-RS port set. Empty corresponds to lower DM-RS port number

% 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"
%
% HARQ process and rate matching/TBS parameters
simParameters.PDSCHExtension.XOverhead = 6*simParameters.PDSCH.EnablePTRS; % Set PDSCH rate matching overhead for TBS (Xoh) to 6 when PT-RS is enabled, otherwise 0
simParameters.PDSCHExtension.NHARQProcesses = 16;    % Number of parallel HARQ processes to use
simParameters.PDSCHExtension.EnableHARQ = true;      % Enable retransmissions for each process, using RV sequence [0,2,3,1]

% 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
% If using a CDL propagation channel then the integer number of antenna elements is
% turned into an antenna panel configured when the channel model object is created
simParameters.NTxAnts = 8;                        % Number of PDSCH transmission antennas (1,2,4,8,16,32,64,128,256,512,1024) >= NumLayers
if simParameters.PDSCH.NumCodewords > 1           % Multi-codeword transmission
    simParameters.NRxAnts = 8;                    % Number of UE receive antennas (even number >= NumLayers)
else
    simParameters.NRxAnts = 2;                    % Number of UE receive antennas (1 or even number >= NumLayers)
end

% Define data type ('single' or 'double') for resource grids and waveforms
simParameters.DataType = 'single';

% Define the general CDL/TDL propagation channel parameters
simParameters.DelayProfile = 'CDL-C';   % Use CDL-C model (Urban macrocell model)
simParameters.DelaySpread = 300e-9;
simParameters.MaximumDopplerShift = 5;

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

시뮬레이션은 샘플 레이트 같은 기저대역 파형에 대한 다양한 정보의 영향을 받습니다.

waveformInfo = nrOFDMInfo(simParameters.Carrier); % Get information about the baseband waveform after OFDM modulation step

전파 채널 모델 생성

시뮬레이션을 위한 채널 모델 객체를 만듭니다. CDL 채널 모델과 TDL 채널 모델이 모두 지원됩니다[5].

% Constructed the CDL or TDL channel model object
if contains(simParameters.DelayProfile,'CDL','IgnoreCase',true)

    channel = nrCDLChannel; % CDL channel object

    % Turn the number of antennas into antenna panel array layouts. If
    % NTxAnts is not one of (1,2,4,8,16,32,64,128,256,512,1024), its value
    % is rounded up to the nearest value in the set. If NRxAnts is not 1 or
    % even, its value is rounded up to the nearest even number.
    channel = hArrayGeometry(channel,simParameters.NTxAnts,simParameters.NRxAnts);
    simParameters.NTxAnts = prod(channel.TransmitAntennaArray.Size);
    simParameters.NRxAnts = prod(channel.ReceiveAntennaArray.Size);
else
    channel = nrTDLChannel; % TDL channel object

    % Set the channel geometry
    channel.NumTransmitAntennas = simParameters.NTxAnts;
    channel.NumReceiveAntennas = simParameters.NRxAnts;
end

% Assign simulation channel parameters and waveform sample rate to the object
channel.DelayProfile = simParameters.DelayProfile;
channel.DelaySpread = simParameters.DelaySpread;
channel.MaximumDopplerShift = simParameters.MaximumDopplerShift;
channel.SampleRate = waveformInfo.SampleRate;

지연된 샘플의 최대 개수를 채널 다중 경로 성분별로 가져옵니다. 이 값은 가장 큰 지연을 가진 채널 경로와 채널 필터의 구현 지연을 사용하여 계산됩니다. 나중에 채널 필터를 플러시하여 수신된 신호를 얻기 위해 이 값이 필요합니다.

chInfo = info(channel);
maxChDelay = chInfo.MaximumChannelDelay;

처리 루프

각 SNR 점에서의 처리량을 결정하려면 다음 단계를 사용하여 송신 인스턴스별로 PDSCH 데이터를 분석합니다.

  • 현재 HARQ 프로세스 업데이트. 주어진 HARQ 프로세스에 대한 송신 상태를 확인하여 재송신이 필요한지 여부를 결정합니다. 그렇지 않은 경우라면 새 데이터를 생성합니다.

  • 리소스 그리드 생성. nrDLSCH System object를 호출하여 채널 코딩을 수행합니다. 이 객체는 입력 전송 블록에서 동작하며 재송신이 필요할 경우를 대비하여 전송 블록의 내부 복사본을 보관합니다. nrPDSCH 함수를 사용하여 PDSCH에서 코딩된 비트를 변조합니다. 그런 다음, 결과로 생성된 신호에 프리코딩을 적용합니다.

  • 파형 생성. 생성된 그리드에 OFDM 변조를 수행합니다.

  • 잡음 채널 모델링. 파형을 CDL 또는 TDL 페이딩 채널에 통과시킵니다. AWGN을 추가합니다. 이 예제에서 사용하는 SNR 정의에 대한 설명은 SNR Definition Used in Link Simulations 항목을 참조하십시오.

  • 동기화 및 OFDM 복조 수행. 완벽한 동기화의 경우, 채널 임펄스 응답을 복원하여 수신된 파형을 동기화합니다. 실질적인 동기화의 경우, 수신된 파형을 PDSCH DM-RS와 상관시킵니다. 그런 다음 OFDM은 동기화된 신호를 복조합니다.

  • 채널 추정 수행. 완벽한 채널 추정의 경우, 채널 임펄스 응답을 복원하고 OFDM 복조를 수행합니다. 실질적인 채널 추정의 경우, PDSCH DM-RS를 사용합니다.

  • 이퀄라이제이션 및 CPE 보상 수행. MMSE는 추정된 채널을 이퀄라이징합니다. PT-RS 심볼을 사용하여 CPE(공통 위상 오차)를 추정하고, 그런 다음 기준 PT-RS OFDM 심볼의 범위 내에서 각 OFDM 심볼의 오류를 수정합니다.

  • 프리코딩 행렬 계산. SVD(특이값 분해)를 사용하여 다음 송신을 위한 프로코딩 행렬 W를 생성합니다.

  • PDSCH 디코딩. 수신된 코드워드의 추정값을 구하려면 nrPDSCHDecode 함수를 사용하여 잡음 추정값과 함께 모든 송신 및 수신 안테나 쌍에 대해 복구된 PDSCH 심볼을 복조하고 디스크램블링합니다.

  • DL-SCH(downlink shared channel) 디코딩 및 블록 CRC 오류로 HARQ 프로세스 업데이트. 디코딩된 소프트 비트로 구성된 벡터를 nrDLSCHDecoder System object에 전달합니다. 이 객체는 코드워드를 디코딩하고 시스템의 처리량을 결정하는 데 사용되는 블록 CRC 오류를 반환합니다.

% Array to store the maximum throughput for all SNR points
maxThroughput = zeros(length(simParameters.SNRIn),1);
% Array to store the simulation throughput for all SNR points
simThroughput = zeros(length(simParameters.SNRIn),1);

% Set up redundancy version (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
    % HARQ disabled - single transmission with RV=0, no retransmissions
    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
% Use layered belief propagation for LDPC decoding, with half the number of
% iterations as compared to the default for belief propagation decoding
decodeDLSCH = nrDLSCHDecoder;
decodeDLSCH.MultipleHARQProcesses = true;
decodeDLSCH.TargetCodeRate = simParameters.PDSCHExtension.TargetCodeRate;
decodeDLSCH.LDPCDecodingAlgorithm = simParameters.PDSCHExtension.LDPCDecodingAlgorithm;
decodeDLSCH.MaximumLDPCIterationCount = simParameters.PDSCHExtension.MaximumLDPCIterationCount;

for snrIdx = 1:numel(simParameters.SNRIn)      % comment out for parallel computing
% parfor snrIdx = 1:numel(simParameters.SNRIn) % uncomment for parallel computing
% To reduce the total simulation time, you can execute this loop in
% parallel by using the Parallel Computing Toolbox. Comment out the 'for'
% statement and uncomment the 'parfor' statement. If the Parallel Computing
% Toolbox is not installed, 'parfor' defaults to normal 'for' statement.
% Because parfor-loop iterations are executed in parallel in a
% nondeterministic order, the simulation information displayed for each SNR
% point can be intertwined. To switch off simulation information display,
% set the 'displaySimulationInformation' variable above to false

    % Reset the random number generator so that each SNR point will
    % experience the same noise realization
    rng('default');

    % Take full copies of the simulation-level parameter structures so that they are not
    % PCT broadcast variables when using parfor
    simLocal = simParameters;
    waveinfoLocal = waveformInfo;

    % Take copies of channel-level parameters to simplify subsequent parameter referencing
    carrier = simLocal.Carrier;
    pdsch = simLocal.PDSCH;
    pdschextra = simLocal.PDSCHExtension;
    decodeDLSCHLocal = decodeDLSCH;  % Copy of the decoder handle to help PCT classification of variable
    decodeDLSCHLocal.reset();        % Reset decoder at the start of each SNR point
    pathFilters = [];

    % Prepare simulation for new SNR point
    SNRdB = simLocal.SNRIn(snrIdx);
    fprintf('\nSimulating transmission scheme 1 (%dx%d) and SCS=%dkHz with %s channel at %gdB SNR for %d 10ms frame(s)\n', ...
        simLocal.NTxAnts,simLocal.NRxAnts,carrier.SubcarrierSpacing, ...
        simLocal.DelayProfile,SNRdB,simLocal.NFrames);

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

    % Initialize the state of all HARQ processes
    harqEntity = HARQEntity(harqSequence,rvSeq,pdsch.NumCodewords);

    % Reset the channel so that each SNR point will experience the same
    % channel realization
    reset(channel);

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

    % Obtain a precoding matrix (wtx) to be used in the transmission of the
    % first transport block
    estChannelGridAnts = getInitialChannelEstimate(carrier,simLocal.NTxAnts,channel,simLocal.DataType);
    newWtx = hSVDPrecoders(carrier,pdsch,estChannelGridAnts,pdschextra.PRGBundleSize);

    % Timing offset, updated in every slot for perfect synchronization and
    % when the correlation is strong for practical synchronization
    offset = 0;

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

        % Update the carrier slot numbers for new slot
        carrier.NSlot = nslot;

        % Calculate the transport block sizes for the transmission in the slot
        [pdschIndices,pdschIndicesInfo] = nrPDSCHIndices(carrier,pdsch);
        trBlkSizes = nrTBS(pdsch.Modulation,pdsch.NumLayers,numel(pdsch.PRBSet),pdschIndicesInfo.NREPerPRB,pdschextra.TargetCodeRate,pdschextra.XOverhead);

        % HARQ processing
        for cwIdx = 1:pdsch.NumCodewords
            % If new data for current process and codeword then create a new DL-SCH transport block
            if harqEntity.NewData(cwIdx)
                trBlk = randi([0 1],trBlkSizes(cwIdx),1);
                setTransportBlock(encodeDLSCH,trBlk,cwIdx-1,harqEntity.HARQProcessID);
                % If new data because of previous RV sequence time out then flush decoder soft buffer explicitly
                if harqEntity.SequenceTimeout(cwIdx)
                    resetSoftBuffer(decodeDLSCHLocal,cwIdx-1,harqEntity.HARQProcessID);
                end
            end
        end

        % Encode the DL-SCH transport blocks
        codedTrBlocks = encodeDLSCH(pdsch.Modulation,pdsch.NumLayers, ...
            pdschIndicesInfo.G,harqEntity.RedundancyVersion,harqEntity.HARQProcessID);

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

        % Create resource grid for a slot
        pdschGrid = nrResourceGrid(carrier,simLocal.NTxAnts,OutputDataType=simLocal.DataType);

        % PDSCH modulation and precoding
        pdschSymbols = nrPDSCH(carrier,pdsch,codedTrBlocks);
        [pdschAntSymbols,pdschAntIndices] = nrPDSCHPrecode(carrier,pdschSymbols,pdschIndices,wtx);

        % PDSCH mapping in grid associated with PDSCH transmission period
        pdschGrid(pdschAntIndices) = pdschAntSymbols;

        % PDSCH DM-RS precoding and mapping
        dmrsSymbols = nrPDSCHDMRS(carrier,pdsch);
        dmrsIndices = nrPDSCHDMRSIndices(carrier,pdsch);
        [dmrsAntSymbols,dmrsAntIndices] = nrPDSCHPrecode(carrier,dmrsSymbols,dmrsIndices,wtx);
        pdschGrid(dmrsAntIndices) = dmrsAntSymbols;

        % PDSCH PT-RS precoding and mapping
        ptrsSymbols = nrPDSCHPTRS(carrier,pdsch);
        ptrsIndices = nrPDSCHPTRSIndices(carrier,pdsch);
        [ptrsAntSymbols,ptrsAntIndices] = nrPDSCHPrecode(carrier,ptrsSymbols,ptrsIndices,wtx);
        pdschGrid(ptrsAntIndices) = ptrsAntSymbols;

        % OFDM modulation
        txWaveform = nrOFDMModulate(carrier,pdschGrid);

        % Pass data through channel model. Append zeros at the end of the
        % transmitted waveform to flush channel content. These zeros take
        % into account any delay introduced in the channel. This is a mix
        % of multipath delay and implementation delay. This value may
        % change depending on the sampling rate, delay profile and delay
        % spread
        txWaveform = [txWaveform; zeros(maxChDelay,size(txWaveform,2))]; %#ok<AGROW>
        [rxWaveform,pathGains,sampleTimes] = channel(txWaveform);

        % Add AWGN to the received time domain waveform
        % Normalize noise power by the IFFT size used in OFDM modulation,
        % as the OFDM modulator applies this normalization to the
        % transmitted waveform. Also normalize by the number of receive
        % antennas, as the channel model applies this normalization to the
        % received waveform, by default
        SNR = 10^(SNRdB/10);
        N0 = 1/sqrt(simLocal.NRxAnts*double(waveinfoLocal.Nfft)*SNR);
        noise = N0*randn(size(rxWaveform),"like",rxWaveform);
        rxWaveform = rxWaveform + noise;

        if (simLocal.PerfectChannelEstimator)
            % Perfect synchronization. Use information provided by the
            % channel to find the strongest multipath component
            pathFilters = getPathFilters(channel);
            [offset,mag] = nrPerfectTimingEstimate(pathGains,pathFilters);
        else
            % Practical 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(carrier,rxWaveform,dmrsIndices,dmrsSymbols);
            offset = hSkipWeakTimingOffset(offset,t,mag);
            % Display a warning if the estimated timing offset exceeds the
            % maximum channel delay
            if offset > maxChDelay
                warning(['Estimated timing offset (%d) is greater than the maximum channel delay (%d).' ...
                    ' This will result in a decoding failure. This may be caused by low SNR,' ...
                    ' or not enough DM-RS symbols to synchronize successfully.'],offset,maxChDelay);
            end
        end
        rxWaveform = rxWaveform(1+offset:end,:);

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

        if (simLocal.PerfectChannelEstimator)
            % Perfect channel estimation, using the value of the path gains
            % provided by the channel. This channel estimate does not
            % include the effect of transmitter precoding
            estChannelGridAnts = nrPerfectChannelEstimate(carrier,pathGains,pathFilters,offset,sampleTimes);

            % Get perfect noise estimate (from the noise realization)
            noiseGrid = nrOFDMDemodulate(carrier,noise(1+offset:end ,:));
            noiseEst = var(noiseGrid(:));

            % Get PDSCH resource elements from the received grid and
            % channel estimate
            [pdschRx,pdschHest,~,pdschHestIndices] = nrExtractResources(pdschIndices,rxGrid,estChannelGridAnts);

            % Apply precoding to channel estimate
            pdschHest = nrPDSCHPrecode(carrier,pdschHest,pdschHestIndices,permute(wtx,[2 1 3]));
        else
            % Practical 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
            [estChannelGridPorts,noiseEst] = hSubbandChannelEstimate(carrier,rxGrid,dmrsIndices,dmrsSymbols,pdschextra.PRGBundleSize,'CDMLengths',pdsch.DMRS.CDMLengths);

            % Average noise estimate across PRGs and layers
            noiseEst = mean(noiseEst,'all');

            % Get PDSCH resource elements from the received grid and
            % channel estimate
            [pdschRx,pdschHest] = nrExtractResources(pdschIndices,rxGrid,estChannelGridPorts);

            % Remove precoding from estChannelGridPorts to get channel
            % estimate w.r.t. antennas
            estChannelGridAnts = precodeChannelEstimate(carrier,estChannelGridPorts,conj(wtx));
        end

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

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

            % Extract PT-RS symbols from received grid and estimated
            % channel grid
            [ptrsRx,ptrsHest,~,~,ptrsHestIndices,ptrsLayerIndices] = nrExtractResources(ptrsIndices,rxGrid,estChannelGridAnts,tempGrid);
            ptrsHest = nrPDSCHPrecode(carrier,ptrsHest,ptrsHestIndices,permute(wtx,[2 1 3]));

            % 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,ptrsIndices,ptrsSymbols);

            % 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(pdschIndices) = pdschEq;

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

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

        % Decode PDSCH physical channel
        [dlschLLRs,rxSymbols] = nrPDSCHDecode(carrier,pdsch,pdschEq,noiseEst);

        % Display EVM per layer, per slot and per RB
        if (simLocal.DisplayDiagnostics)
            plotLayerEVM(NSlots,nslot,pdsch,size(pdschGrid),pdschIndices,pdschSymbols,pdschEq);
        end

        % Scale LLRs by 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.RedundancyVersion,harqEntity.HARQProcessID);

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

        % Update current process with CRC error and advance to next process
        procstatus = updateAndAdvance(harqEntity,blkerr,trBlkSizes,pdschIndicesInfo.G);
        if (simLocal.DisplaySimulationInformation)
            fprintf('\n(%3.2f%%) NSlot=%d, %s',100*(nslot+1)/NSlots,nslot,procstatus);
        end

        % Get precoding matrix for next slot
        newWtx = hSVDPrecoders(carrier,pdsch,estChannelGridAnts,pdschextra.PRGBundleSize);

     end

    % Display the results dynamically in the command window
    if (simLocal.DisplaySimulationInformation)
        fprintf('\n');
    end
    fprintf('\nThroughput(Mbps) for %d frame(s) = %.4f\n',simLocal.NFrames,1e-6*simThroughput(snrIdx)/(simLocal.NFrames*10e-3));
    fprintf('Throughput(%%) for %d frame(s) = %.4f\n',simLocal.NFrames,simThroughput(snrIdx)*100/maxThroughput(snrIdx));

end
Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at -5dB SNR for 2 10ms frame(s)

(2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission failed (RV=0,CR=0.474736).
(5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission failed (RV=0,CR=0.474736).
(7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission failed (RV=0,CR=0.474736).
(10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission failed (RV=0,CR=0.474736).
(12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission failed (RV=0,CR=0.474736).
(15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission failed (RV=0,CR=0.474736).
(17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission failed (RV=0,CR=0.474736).
(20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission failed (RV=0,CR=0.474736).
(22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission failed (RV=0,CR=0.474736).
(25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission failed (RV=0,CR=0.474736).
(27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission failed (RV=0,CR=0.474736).
(30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission failed (RV=0,CR=0.474736).
(32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission failed (RV=0,CR=0.474736).
(35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission failed (RV=0,CR=0.474736).
(37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission failed (RV=0,CR=0.474736).
(40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission failed (RV=0,CR=0.474736).
(42.50%) NSlot=16, HARQ Proc 0: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(45.00%) NSlot=17, HARQ Proc 1: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(47.50%) NSlot=18, HARQ Proc 2: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(50.00%) NSlot=19, HARQ Proc 3: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(52.50%) NSlot=20, HARQ Proc 4: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(55.00%) NSlot=21, HARQ Proc 5: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(57.50%) NSlot=22, HARQ Proc 6: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(60.00%) NSlot=23, HARQ Proc 7: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(62.50%) NSlot=24, HARQ Proc 8: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(65.00%) NSlot=25, HARQ Proc 9: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(67.50%) NSlot=26, HARQ Proc 10: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(70.00%) NSlot=27, HARQ Proc 11: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(72.50%) NSlot=28, HARQ Proc 12: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(75.00%) NSlot=29, HARQ Proc 13: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(77.50%) NSlot=30, HARQ Proc 14: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(80.00%) NSlot=31, HARQ Proc 15: CW0: Retransmission #1 passed (RV=2,CR=0.474736).
(82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission failed (RV=0,CR=0.474736).
(85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission failed (RV=0,CR=0.474736).
(87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission failed (RV=0,CR=0.474736).
(90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission failed (RV=0,CR=0.474736).
(92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission failed (RV=0,CR=0.474736).
(95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission failed (RV=0,CR=0.474736).
(97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission failed (RV=0,CR=0.474736).
(100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission failed (RV=0,CR=0.474736).

Throughput(Mbps) for 2 frame(s) = 24.1728
Throughput(%) for 2 frame(s) = 40.0000

Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at 0dB SNR for 2 10ms frame(s)

(2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).
(22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736).
(25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736).
(27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736).
(30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736).
(32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736).
(35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736).
(37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736).
(40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736).
(42.50%) NSlot=16, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(45.00%) NSlot=17, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(47.50%) NSlot=18, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(50.00%) NSlot=19, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(52.50%) NSlot=20, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(55.00%) NSlot=21, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(57.50%) NSlot=22, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(60.00%) NSlot=23, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).
(62.50%) NSlot=24, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736).
(65.00%) NSlot=25, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736).
(67.50%) NSlot=26, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736).
(70.00%) NSlot=27, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736).
(72.50%) NSlot=28, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736).
(75.00%) NSlot=29, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736).
(77.50%) NSlot=30, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736).
(80.00%) NSlot=31, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736).
(82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).

Throughput(Mbps) for 2 frame(s) = 60.4320
Throughput(%) for 2 frame(s) = 100.0000

Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at 5dB SNR for 2 10ms frame(s)

(2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).
(22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736).
(25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736).
(27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736).
(30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736).
(32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736).
(35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736).
(37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736).
(40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736).
(42.50%) NSlot=16, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(45.00%) NSlot=17, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(47.50%) NSlot=18, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(50.00%) NSlot=19, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(52.50%) NSlot=20, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(55.00%) NSlot=21, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(57.50%) NSlot=22, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(60.00%) NSlot=23, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).
(62.50%) NSlot=24, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736).
(65.00%) NSlot=25, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736).
(67.50%) NSlot=26, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736).
(70.00%) NSlot=27, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736).
(72.50%) NSlot=28, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736).
(75.00%) NSlot=29, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736).
(77.50%) NSlot=30, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736).
(80.00%) NSlot=31, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736).
(82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736).
(85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736).
(87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736).
(90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736).
(92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736).
(95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736).
(97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736).
(100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736).

Throughput(Mbps) for 2 frame(s) = 60.4320
Throughput(%) for 2 frame(s) = 100.0000

결과

측정된 처리량을 표시합니다. 이 값은 데이터 송신에 주어진 사용 가능한 리소스에 대한 링크의 최대 가능 처리량의 백분율로 계산됩니다.

figure;
plot(simParameters.SNRIn,simThroughput*100./maxThroughput,'o-.')
xlabel('SNR (dB)'); ylabel('Throughput (%)'); grid on;
title(sprintf('%s (%dx%d) / NRB=%d / SCS=%dkHz', ...
              simParameters.DelayProfile,simParameters.NTxAnts,simParameters.NRxAnts, ...
              simParameters.Carrier.NSizeGrid,simParameters.Carrier.SubcarrierSpacing));

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

아래 Figure는 10000개의 서브프레임을 시뮬레이션하여 얻은 처리량 결과를 보여줍니다(NFrames = 1000, SNRIn = -18:2:16).

정선된 참고 문헌

  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.

로컬 함수

function validateNumLayers(simParameters)
% Validate the number of layers, relative to the antenna geometry

    numlayers = simParameters.PDSCH.NumLayers;
    ntxants = simParameters.NTxAnts;
    nrxants = simParameters.NRxAnts;
    antennaDescription = sprintf('min(NTxAnts,NRxAnts) = min(%d,%d) = %d',ntxants,nrxants,min(ntxants,nrxants));
    if numlayers > min(ntxants,nrxants)
        error('The number of layers (%d) must satisfy NumLayers <= %s', ...
            numlayers,antennaDescription);
    end

    % Display a warning if the maximum possible rank of the channel equals
    % the number of layers
    if (numlayers > 2) && (numlayers == min(ntxants,nrxants))
        warning(['The maximum possible rank of the channel, given by %s, is equal to NumLayers (%d).' ...
            ' This may result in a decoding failure under some channel conditions.' ...
            ' Try decreasing the number of layers or increasing the channel rank' ...
            ' (use more transmit or receive antennas).'],antennaDescription,numlayers); %#ok<SPWRN>
    end

end

function estChannelGrid = getInitialChannelEstimate(carrier,nTxAnts,propchannel,dataType)
% Obtain channel estimate before first transmission. This can be used to
% obtain a precoding matrix for the first slot.

    ofdmInfo = nrOFDMInfo(carrier);

    chInfo = info(propchannel);
    maxChDelay = chInfo.MaximumChannelDelay;

    % Temporary waveform (only needed for the sizes)
    tmpWaveform = zeros((ofdmInfo.SampleRate/1000/carrier.SlotsPerSubframe)+maxChDelay,nTxAnts,dataType);

    % Filter through channel
    [~,pathGains,sampleTimes] = propchannel(tmpWaveform);

    % Perfect timing synch
    pathFilters = getPathFilters(propchannel);
    offset = nrPerfectTimingEstimate(pathGains,pathFilters);

    % Perfect channel estimate
    estChannelGrid = nrPerfectChannelEstimate(carrier,pathGains,pathFilters,offset,sampleTimes);

end

function estChannelGrid = precodeChannelEstimate(carrier,estChannelGrid,W)
% Apply precoding matrix W to the last dimension of the channel estimate

    [K,L,R,P] = size(estChannelGrid);
    estChannelGrid = reshape(estChannelGrid,[K*L R P]);
    estChannelGrid = nrPDSCHPrecode(carrier,estChannelGrid,reshape(1:numel(estChannelGrid),[K*L R P]),W);
    estChannelGrid = reshape(estChannelGrid,K,L,R,[]);

end

function plotLayerEVM(NSlots,nslot,pdsch,siz,pdschIndices,pdschSymbols,pdschEq)
% Plot EVM information

    persistent slotEVM;
    persistent rbEVM
    persistent evmPerSlot;

    if (nslot==0)
        slotEVM = comm.EVM;
        rbEVM = comm.EVM;
        evmPerSlot = NaN(NSlots,pdsch.NumLayers);
        figure;
    end
    evmPerSlot(nslot+1,:) = slotEVM(pdschSymbols,pdschEq);
    subplot(2,1,1);
    plot(0:(NSlots-1),evmPerSlot,'o-');
    xlabel('Slot number');
    ylabel('EVM (%)');
    legend("layer " + (1:pdsch.NumLayers),'Location','EastOutside');
    title('EVM per layer per slot');

    subplot(2,1,2);
    [k,~,p] = ind2sub(siz,pdschIndices);
    rbsubs = floor((k-1) / 12);
    NRB = siz(1) / 12;
    evmPerRB = NaN(NRB,pdsch.NumLayers);
    for nu = 1:pdsch.NumLayers
        for rb = unique(rbsubs).'
            this = (rbsubs==rb & p==nu);
            evmPerRB(rb+1,nu) = rbEVM(pdschSymbols(this),pdschEq(this));
        end
    end
    plot(0:(NRB-1),evmPerRB,'x-');
    xlabel('Resource block');
    ylabel('EVM (%)');
    legend("layer " + (1:pdsch.NumLayers),'Location','EastOutside');
    title(['EVM per layer per resource block, slot #' num2str(nslot)]);

    drawnow;

end

참고 항목

객체

함수

관련 항목