exponenta event banner

Пропускная способность NR PDSCH

Этот пример шоу, как измерить физическую передачу информации из космоса, разделил канал (PDSCH) пропускная способность 5G связь New Radio (NR), как определено 3GPP стандарт NR. Пример реализует PDSCH и нисходящий совместно используемый канал (DL-SCH). Модель передатчика включает в себя опорные сигналы демодуляции PDSCH (DM-RS), опорные сигналы отслеживания фазы PDSCH (PT-RS) и пакеты сигнала синхронизации (SS). В примере поддерживаются каналы распространения как кластерной линии задержки (CDL), так и линии задержки с отводом (TDL). Можно выполнить идеальную или практическую синхронизацию и оценку канала. Для сокращения общего времени моделирования можно параллельно выполнять точки SNR в цикле SNR с помощью Toolbox™ параллельных вычислений.

Введение

Этот пример измеряет пропускную способность PDSCH 5G связь, как определено 3GPP НОМЕР стандарта [1], [2], [3], [4].

Пример моделирует их 5G НОМЕР особенностей:

  • Кодирование транспортного канала DL-SCH

  • Несколько кодовых слов в зависимости от количества уровней

  • Формирование PDSCH, PDSCH DM-RS и PDSCH PT-RS

  • Генерация пакетов SS (PSS/SSS/PBCH/PBCH DM-RS)

  • Переменные интервалы между поднесущими и числовые кадры (2 ^ n * 15 кГц) для обычного и расширенного циклического префикса

  • Модели каналов распространения TDL и CDL

Другие особенности моделирования:

  • Предварительное кодирование PDSCH с использованием SVD

  • CP-OFDM модуляция

  • Отображение PDSCH и DM-RS по слотам и без слотов

  • Формирование пакетов SS (варианты A-E, управление битовой картой блока SS/PBCH)

  • Идеальная или практичная синхронизация и оценка канала

  • Работа HARQ с 16 процессами

  • В примере используется одна часть полосы пропускания на всей несущей

На рисунке показана реализованная цепочка обработки. Для ясности генерация пакетов DM-RS, PT-RS и SS опущена.

В этом примере поддерживается как широкополосное, так и поддиапазонное предварительное кодирование. Матрица предварительного кодирования определяется с использованием SVD путем усреднения оценки канала по всем PRB PDSCH в распределении (широкополосный случай) или в поддиапазоне. Отсутствует формирование луча на каких-либо блоках SS/PBCH в пакете SS.

Для сокращения общего времени моделирования можно использовать панель инструментов параллельных вычислений для параллельного выполнения точек SNR контура SNR.

Длина моделирования и точки SNR

Задайте длину моделирования с точки зрения количества кадров 10 мс. Большое количество NFrames должно использоваться для получения значимых результатов пропускной способности. Установите точки SNR для моделирования. SNR для каждого уровня определяется по RE и включает в себя влияние сигнала и шума на все антенны.

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;

Диагностика моделирования

При моделировании всегда отображается результат передачи CRC/отказа PDSCH для процесса HARQ, используемого в каждом слоте. Сюда входит используемое значение RV и мгновенная кодовая скорость. Следует отметить, что скорость кодирования может отличаться от целевой скорости кодирования процесса, особенно в слоте, содержащем блоки SS, когда происходит потеря физических ресурсов, доступных для PDSCH. Это увеличение скорости кодирования может потребовать дополнительных повторных передач транспортного блока для успешного приема, даже при высоком SNR.

DisplayDiagnostics флаг активизирует печать EVM на уровне. Этот график контролирует качество принимаемого сигнала после выравнивания. На рисунке EVM для каждого уровня показаны:

  • EVM на уровень на слот, что показывает эволюцию EVM во времени.

  • EVM на уровень на блок ресурсов, который показывает частоту EVM.

Этот рисунок эволюционирует с моделированием и обновляется с каждым слотом. Обычно низкое SNR или замирание канала может привести к снижению качества сигнала (высокое EVM). Канал влияет на каждый уровень по-разному, поэтому значения EVM могут различаться между уровнями.

В некоторых случаях некоторые слои могут иметь гораздо более высокий EVM, чем другие. Эти низкокачественные уровни могут привести к ошибкам CRC. Такое поведение может быть вызвано низким SNR или использованием слишком большого количества уровней для условий канала. Избежать этой ситуации можно за счет сочетания более высокого SNR, меньшего количества уровней, большего количества антенн и более надежной передачи (более низкая схема модуляции и целевая скорость кодирования).

simParameters.DisplayDiagnostics = false;

Конфигурирование полки и PDSCH

Задайте ключевые параметры моделирования. К ним относятся:

  • Полоса пропускания в блоках ресурсов (12 поднесущих на блок ресурсов).

  • Интервал между поднесущими: 15, 30, 60, 120, 240 (кГц)

  • Длина циклического префикса: обычный или расширенный

  • Идентификатор ячейки

  • Количество передающих и приемных антенн

Также указана подструктура, содержащая параметры DL-SCH и PDSCH. Это включает в себя:

  • Целевая кодовая скорость

  • Выделенные блоки ресурсов (PRASEet)

  • Схема модуляции: 'QPSK', '16QAM', '64QAM', '256QAM'.

  • Количество слоев

  • Тип отображения PDSCH

  • Параметры конфигурации DM-RS

  • Параметры конфигурации PT-RS

Другими широкими параметрами моделирования являются:

  • Модель канала распространения: «TDL» или «CDL-»;

  • Параметры конфигурации пакета SS. Следует отметить, что генерация пакетов SS может быть отключена путем установки SSBTransmitted в поле [0 0 0 0].

% Set waveform type and PDSCH numerology (SCS and CP type)
simParameters.Carrier = nrCarrierConfig;
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, 240 (kHz)
simParameters.Carrier.CyclicPrefix = 'Normal';   % 'Normal' or 'Extended' (Extended CP is relevant for 60 kHz SCS only)
simParameters.Carrier.NCellID = 1;               % Cell identity

% SS burst configuration
% The burst can be disabled by setting the SSBTransmitted field to all zeros
simParameters.SSBurst = struct();
simParameters.SSBurst.BlockPattern = 'Case B';    % 30 kHz subcarrier spacing
simParameters.SSBurst.SSBTransmitted = [0 1 0 1]; % Bitmap indicating blocks transmitted in the burst
simParameters.SSBurst.SSBPeriodicity = 20;        % SS burst set periodicity in ms (5, 10, 20, 40, 80, 160)

% 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 = 0; % 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 = 'Layered belief propagation';
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 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 overall number of antennas into a specific antenna panel
    % array geometry. The number of antennas configured is updated when
    % nTxAnts is not one of (1,2,4,8,16,32,64,128,256,512,1024) or nRxAnts
    % is not 1 or even.
    [channel.TransmitAntennaArray.Size, channel.ReceiveAntennaArray.Size] = ...
        hArrayGeometry(simParameters.NTxAnts,simParameters.NRxAnts);
    nTxAnts = prod(channel.TransmitAntennaArray.Size);
    nRxAnts = prod(channel.ReceiveAntennaArray.Size);
    simParameters.NTxAnts = nTxAnts;
    simParameters.NRxAnts = nRxAnts;
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 = ceil(max(chInfo.PathDelays*channel.SampleRate)) + chInfo.ChannelFilterDelay;

Резервирование ресурсов PDSCH, соответствующих пакету SS

В этом разделе показано, как зарезервировать ресурсы для передачи пакета SS.

% Get information about the SS burst configuration
% Some dependent parameter assignments are required first
simParameters.SSBurst.NCellID = simParameters.Carrier.NCellID;
simParameters.SSBurst.SampleRate = waveformInfo.SampleRate;
ssbInfo = hSSBurstInfo(simParameters.SSBurst);

% Map the occupied subcarriers and transmitted symbols of the SS burst
% (defined in the SS burst numerology) to PDSCH PRBs and symbols in the
% PDSCH BWP/carrier numerology
[mappedPRB,mappedSymbols] = mapNumerology(ssbInfo.OccupiedSubcarriers,ssbInfo.OccupiedSymbols,ssbInfo.NRB,simParameters.Carrier.NSizeGrid,ssbInfo.SubcarrierSpacing,simParameters.Carrier.SubcarrierSpacing);
% Configure the PDSCH to reserve these resources so that the PDSCH
% transmission does not overlap the SS burst
reservation = nrPDSCHReservedConfig;
reservation.SymbolSet = mappedSymbols;
reservation.PRBSet = mappedPRB;
reservation.Period = simParameters.SSBurst.SSBPeriodicity * (simParameters.Carrier.SubcarrierSpacing/15); % Period in slots
simParameters.PDSCH.ReservedPRB{end+1} = reservation;

Цикл обработки

Чтобы определить пропускную способность в каждой точке SNR, проанализируйте данные PDSCH для каждого экземпляра передачи, используя следующие шаги:

  • Обновить текущий процесс HARQ. Проверьте CRC предыдущей передачи для данного процесса HARQ. Определите, требуется ли повторная передача. Если повторная передача не требуется, создайте новые данные.

  • Создание сетки ресурсов. Выполнение кодирования канала путем вызова nrDLSCH Системный объект. Объект работает на входном транспортном блоке и сохраняет внутреннюю копию транспортного блока в случае, если требуется повторная передача. Модулировать кодированные биты в PDSCH с помощью nrPDSCH функция. Затем примените предварительное кодирование к результирующему сигналу.

  • Генерация формы сигнала. OFDM модулирует сформированную сетку.

  • Шумное моделирование канала. Передача сигнала через канал замирания CDL или TDL. Добавить AWGN. SNR определяется для каждого RE в каждой антенне UE. Для SNR 0 дБ сигнал и шум вносят одинаковый вклад в энергию на PDSCH RE на приемную антенну.

  • Выполните синхронизацию и демодуляцию OFDM. Для идеальной синхронизации восстановите импульсную характеристику канала для синхронизации принятого сигнала. Для практической синхронизации коррелируйте принятый сигнал с PDSCH DM-RS. Затем OFDM демодулирует синхронизированный сигнал.

  • Выполните оценку канала. Для совершенной оценки канала восстановите импульсную характеристику канала и выполните демодуляцию OFDM. Для практической оценки канала используйте PDSCH DM-RS.

  • Выполните выравнивание и компенсацию CPE. MMSE выравнивает оцененный канал. Оцените общую фазовую ошибку (CPE), используя символы PT-RS, затем исправьте ошибку в каждом символе OFDM в диапазоне опорных символов PT-RS OFDM.

  • Вычисление матрицы предварительного кодирования. Создайте матрицу W предварительного кодирования для следующей передачи с использованием разложения сингулярных значений (SVD).

  • Декодируйте PDSCH. Чтобы получить оценку принятых кодовых слов, демодулируют и дескремблируют восстановленные символы PDSCH для всех пар передающих и приемных антенн вместе с оценкой шума, используя nrPDSCHDecode функция.

  • Декодировать DL-SCH и сохранять ошибку CRC блока для процесса HARQ. Передать вектор декодированных мягких битов в nrDLSCHDecoder Системный объект. Объект декодирует кодовое слово и возвращает ошибку 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 to be used, according to the HARQ configuration
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

    % Set the random number generator settings to default values
    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 simply subsequent parameter referencing
    carrier = simLocal.Carrier;
    pdsch = simLocal.PDSCH;
    pdschextra = simLocal.PDSCHExtension;
    ssburst = simLocal.SSBurst;
    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 = [];
    ssbWaveform = [];

    % 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',...
        simParameters.NTxAnts,simParameters.NRxAnts,carrier.SubcarrierSpacing, ...
        simLocal.DelayProfile,SNRdB,simLocal.NFrames);

    % Initialize variables used in the simulation and analysis
    bitTput = [];           % Number of successfully received bits per transmission
    txedTrBlkSizes = [];    % Number of transmitted info bits per transmission

    % Specify the order in which we cycle through the HARQ processes
    harqSequence = 1:pdschextra.NHARQProcesses;

    % Initialize the state of all HARQ processes
    harqProcesses = hNewHARQProcesses(pdschextra.NHARQProcesses,rvSeq,pdsch.NumCodewords);
    harqProcCntr = 0; % HARQ process counter

    % 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;

    % Index to the start of the current set of SS burst samples to be
    % transmitted
    ssbSampleIndex = 1;

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

    % 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;

        % Generate a new SS burst when necessary
        if (ssbSampleIndex==1)
            nSubframe = carrier.NSlot / carrier.SlotsPerSubframe;
            ssburst.NFrame = floor(nSubframe / 10);
            ssburst.NHalfFrame = mod(nSubframe / 5,2);
            [ssbWaveform,~,ssbInfo] = hSSBurst(ssburst);
        end

        % Get HARQ process index for the current PDSCH from HARQ index table
        harqProcIdx = harqSequence(mod(harqProcCntr,length(harqSequence))+1);

        % Update current HARQ process information (this updates the RV
        % depending on CRC pass or fail in the previous transmission for
        % this HARQ process)
        harqProcesses(harqProcIdx) = hUpdateHARQProcess(harqProcesses(harqProcIdx),pdsch.NumCodewords);

        % Calculate the transport block sizes for the codewords 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
        % Check CRC from previous transmission per codeword, i.e. is a retransmission required?
        for cwIdx = 1:pdsch.NumCodewords
            newdata = false;
            if harqProcesses(harqProcIdx).blkerr(cwIdx) % Error for last recorded decoding
                if (harqProcesses(harqProcIdx).RVIdx(cwIdx)==1) % Signals the start of the RV sequence
                    resetSoftBuffer(decodeDLSCHLocal,cwIdx-1,harqProcIdx-1);  % Explicit reset required in this case
                    newdata = true;
                end
            else    % No error
                newdata = true;
            end
            if newdata
                trBlk = randi([0 1],trBlkSizes(cwIdx),1);
                setTransportBlock(encodeDLSCH,trBlk,cwIdx-1,harqProcIdx-1);
            end
        end

        % Encode the DL-SCH transport blocks
        codedTrBlocks = encodeDLSCH(pdsch.Modulation,pdsch.NumLayers,...
            pdschIndicesInfo.G,harqProcesses(harqProcIdx).RV,harqProcIdx-1);

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

        % Resource grid array
        pdschGrid = nrResourceGrid(carrier,simLocal.NTxAnts);

        % PDSCH modulation and precoding
        pdschSymbols = nrPDSCH(carrier,pdsch,codedTrBlocks);
        [pdschAntSymbols,pdschAntIndices] = hPRGPrecode(size(pdschGrid),carrier.NStartGrid,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] = hPRGPrecode(size(pdschGrid),carrier.NStartGrid,dmrsSymbols,dmrsIndices,wtx);
        pdschGrid(dmrsAntIndices) = dmrsAntSymbols;

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

        % OFDM modulation of associated resource elements
        txWaveform = nrOFDMModulate(carrier, pdschGrid);

        % Add the appropriate portion of SS burst waveform to the
        % transmitted waveform
        Nt = size(txWaveform,1);
        txWaveform = txWaveform + ssbWaveform(ssbSampleIndex + (0:Nt-1),:);
        ssbSampleIndex = mod(ssbSampleIndex + Nt,size(ssbWaveform,1));

        % 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))];
        [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/20); % Calculate linear noise gain
        N0 = 1/(sqrt(2.0*simLocal.NRxAnts*double(waveinfoLocal.Nfft))*SNR);
        noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform)));
        rxWaveform = rxWaveform + noise;

        if (simLocal.PerfectChannelEstimator)
            % Perfect synchronization. Use information provided by the channel
            % to find the strongest multipath component
            pathFilters = getPathFilters(channel); % get path filters for perfect channel estimation
            [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
            estChannelGrid = 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 precoding matrix for next slot
            newWtx = getPrecodingMatrix(carrier,pdsch,estChannelGrid);

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

            % Apply precoding to channel estimate
            pdschHest = hPRGPrecode(size(estChannelGrid),carrier.NStartGrid,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
            [estChannelGrid,noiseEst] = nrChannelEstimate(carrier,rxGrid,dmrsIndices,dmrsSymbols,'CDMLengths',pdsch.DMRS.CDMLengths);

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

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

            % Get precoding matrix for next slot
            newWtx = getPrecodingMatrix(carrier,pdsch,estChannelGridPorts);
        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,estChannelGrid,tempGrid);

            if (simLocal.PerfectChannelEstimator)
                % Apply precoding to channel estimate
                ptrsHest = hPRGPrecode(size(estChannelGrid),carrier.NStartGrid,ptrsHest,ptrsHestIndices,permute(wtx,[2 1 3]));
            end

            % 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
        % Write the decoding CRC error back into the HARQ process state structure
        decodeDLSCHLocal.TransportBlockLength = trBlkSizes;
        [decbits,harqProcesses(harqProcIdx).blkerr] = decodeDLSCHLocal(dlschLLRs,pdsch.Modulation,pdsch.NumLayers,harqProcesses(harqProcIdx).RV,harqProcIdx-1);

        % Store values to calculate throughput (only for active PDSCH instances)
        if(any(trBlkSizes ~= 0))
            bitTput = [bitTput trBlkSizes.*(1-harqProcesses(harqProcIdx).blkerr)];
            txedTrBlkSizes = [txedTrBlkSizes trBlkSizes];
        end

        % Update HARQ process counter
        harqProcCntr = harqProcCntr + 1;

        % Display transport block CRC error information per codeword managed by current HARQ process
        icr = trBlkSizes./pdschIndicesInfo.G;    % Instantaneous code rate
        csn = mod(nslot,carrier.SlotsPerFrame);  % Slot number in frame
        fprintf('\n(%3.2f%%) HARQ Proc %d: ',100*(nslot+1)/NSlots,harqProcIdx);
        estrings = {'passed','failed'};
        rvi = harqProcesses(harqProcIdx).RVIdx;
        for cw=1:length(rvi)
            cwrvi = rvi(cw);
            % Create a report on the RV state given position in RV sequence and decoding error
            if cwrvi == 1
                ts = sprintf('Initial transmission (NSlot=%d,RV=%d,CR=%f)',csn,rvSeq(cwrvi),icr(cw));
            else
                ts = sprintf('Retransmission #%d (NSlot=%d,RV=%d,CR=%f)',cwrvi-1,csn,rvSeq(cwrvi),icr(cw));
            end
            fprintf('CW%d:%s %s. ',cw-1,ts,estrings{1+harqProcesses(harqProcIdx).blkerr(cw)});
        end

     end

    % Calculate maximum and simulated throughput
    maxThroughput(snrIdx) = sum(txedTrBlkSizes); % Max possible throughput
    simThroughput(snrIdx) = sum(bitTput,2);      % Simulated throughput

    % Display the results dynamically in the command window
    fprintf([['\n\nThroughput(Mbps) for ', num2str(simLocal.NFrames) ' frame(s) '],...
        '= %.4f\n'], 1e-6*simThroughput(snrIdx)/(simLocal.NFrames*10e-3));
    fprintf(['Throughput(%%) for ', num2str(simLocal.NFrames) ' frame(s) = %.4f\n'],...
        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%) HARQ Proc 1: CW0:Initial transmission (NSlot=0,RV=0,CR=0.513458) failed. 
(5.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=1,RV=0,CR=0.513458) failed. 
(7.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=2,RV=0,CR=0.451578) failed. 
(10.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=3,RV=0,CR=0.451578) failed. 
(12.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=4,RV=0,CR=0.451578) failed. 
(15.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=5,RV=0,CR=0.451578) failed. 
(17.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=6,RV=0,CR=0.451578) failed. 
(20.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=7,RV=0,CR=0.451578) failed. 
(22.50%) HARQ Proc 9: CW0:Initial transmission (NSlot=8,RV=0,CR=0.451578) failed. 
(25.00%) HARQ Proc 10: CW0:Initial transmission (NSlot=9,RV=0,CR=0.451578) failed. 
(27.50%) HARQ Proc 11: CW0:Initial transmission (NSlot=10,RV=0,CR=0.451578) failed. 
(30.00%) HARQ Proc 12: CW0:Initial transmission (NSlot=11,RV=0,CR=0.451578) failed. 
(32.50%) HARQ Proc 13: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) failed. 
(35.00%) HARQ Proc 14: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) failed. 
(37.50%) HARQ Proc 15: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) failed. 
(40.00%) HARQ Proc 16: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) failed. 
(42.50%) HARQ Proc 1: CW0:Retransmission #1 (NSlot=16,RV=2,CR=0.451578) passed. 
(45.00%) HARQ Proc 2: CW0:Retransmission #1 (NSlot=17,RV=2,CR=0.451578) passed. 
(47.50%) HARQ Proc 3: CW0:Retransmission #1 (NSlot=18,RV=2,CR=0.451578) passed. 
(50.00%) HARQ Proc 4: CW0:Retransmission #1 (NSlot=19,RV=2,CR=0.451578) passed. 
(52.50%) HARQ Proc 5: CW0:Retransmission #1 (NSlot=0,RV=2,CR=0.451578) passed. 
(55.00%) HARQ Proc 6: CW0:Retransmission #1 (NSlot=1,RV=2,CR=0.451578) passed. 
(57.50%) HARQ Proc 7: CW0:Retransmission #1 (NSlot=2,RV=2,CR=0.451578) passed. 
(60.00%) HARQ Proc 8: CW0:Retransmission #1 (NSlot=3,RV=2,CR=0.451578) passed. 
(62.50%) HARQ Proc 9: CW0:Retransmission #1 (NSlot=4,RV=2,CR=0.451578) passed. 
(65.00%) HARQ Proc 10: CW0:Retransmission #1 (NSlot=5,RV=2,CR=0.451578) passed. 
(67.50%) HARQ Proc 11: CW0:Retransmission #1 (NSlot=6,RV=2,CR=0.451578) passed. 
(70.00%) HARQ Proc 12: CW0:Retransmission #1 (NSlot=7,RV=2,CR=0.451578) passed. 
(72.50%) HARQ Proc 13: CW0:Retransmission #1 (NSlot=8,RV=2,CR=0.451578) passed. 
(75.00%) HARQ Proc 14: CW0:Retransmission #1 (NSlot=9,RV=2,CR=0.451578) passed. 
(77.50%) HARQ Proc 15: CW0:Retransmission #1 (NSlot=10,RV=2,CR=0.451578) passed. 
(80.00%) HARQ Proc 16: CW0:Retransmission #1 (NSlot=11,RV=2,CR=0.451578) passed. 
(82.50%) HARQ Proc 1: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) failed. 
(85.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) failed. 
(87.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) failed. 
(90.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) failed. 
(92.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=16,RV=0,CR=0.451578) failed. 
(95.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=17,RV=0,CR=0.451578) failed. 
(97.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=18,RV=0,CR=0.451578) failed. 
(100.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=19,RV=0,CR=0.451578) failed. 

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%) HARQ Proc 1: CW0:Initial transmission (NSlot=0,RV=0,CR=0.513458) passed. 
(5.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=1,RV=0,CR=0.513458) passed. 
(7.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=2,RV=0,CR=0.451578) passed. 
(10.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=3,RV=0,CR=0.451578) passed. 
(12.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=4,RV=0,CR=0.451578) passed. 
(15.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=5,RV=0,CR=0.451578) passed. 
(17.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=6,RV=0,CR=0.451578) passed. 
(20.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=7,RV=0,CR=0.451578) passed. 
(22.50%) HARQ Proc 9: CW0:Initial transmission (NSlot=8,RV=0,CR=0.451578) passed. 
(25.00%) HARQ Proc 10: CW0:Initial transmission (NSlot=9,RV=0,CR=0.451578) passed. 
(27.50%) HARQ Proc 11: CW0:Initial transmission (NSlot=10,RV=0,CR=0.451578) passed. 
(30.00%) HARQ Proc 12: CW0:Initial transmission (NSlot=11,RV=0,CR=0.451578) passed. 
(32.50%) HARQ Proc 13: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) passed. 
(35.00%) HARQ Proc 14: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) passed. 
(37.50%) HARQ Proc 15: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) passed. 
(40.00%) HARQ Proc 16: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) passed. 
(42.50%) HARQ Proc 1: CW0:Initial transmission (NSlot=16,RV=0,CR=0.451578) passed. 
(45.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=17,RV=0,CR=0.451578) passed. 
(47.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=18,RV=0,CR=0.451578) passed. 
(50.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=19,RV=0,CR=0.451578) passed. 
(52.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=0,RV=0,CR=0.451578) passed. 
(55.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=1,RV=0,CR=0.451578) passed. 
(57.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=2,RV=0,CR=0.451578) passed. 
(60.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=3,RV=0,CR=0.451578) passed. 
(62.50%) HARQ Proc 9: CW0:Initial transmission (NSlot=4,RV=0,CR=0.451578) passed. 
(65.00%) HARQ Proc 10: CW0:Initial transmission (NSlot=5,RV=0,CR=0.451578) passed. 
(67.50%) HARQ Proc 11: CW0:Initial transmission (NSlot=6,RV=0,CR=0.451578) passed. 
(70.00%) HARQ Proc 12: CW0:Initial transmission (NSlot=7,RV=0,CR=0.451578) passed. 
(72.50%) HARQ Proc 13: CW0:Initial transmission (NSlot=8,RV=0,CR=0.451578) passed. 
(75.00%) HARQ Proc 14: CW0:Initial transmission (NSlot=9,RV=0,CR=0.451578) passed. 
(77.50%) HARQ Proc 15: CW0:Initial transmission (NSlot=10,RV=0,CR=0.451578) passed. 
(80.00%) HARQ Proc 16: CW0:Initial transmission (NSlot=11,RV=0,CR=0.451578) passed. 
(82.50%) HARQ Proc 1: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) passed. 
(85.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) passed. 
(87.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) passed. 
(90.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) passed. 
(92.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=16,RV=0,CR=0.451578) passed. 
(95.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=17,RV=0,CR=0.451578) passed. 
(97.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=18,RV=0,CR=0.451578) passed. 
(100.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=19,RV=0,CR=0.451578) passed. 

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%) HARQ Proc 1: CW0:Initial transmission (NSlot=0,RV=0,CR=0.513458) passed. 
(5.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=1,RV=0,CR=0.513458) passed. 
(7.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=2,RV=0,CR=0.451578) passed. 
(10.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=3,RV=0,CR=0.451578) passed. 
(12.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=4,RV=0,CR=0.451578) passed. 
(15.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=5,RV=0,CR=0.451578) passed. 
(17.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=6,RV=0,CR=0.451578) passed. 
(20.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=7,RV=0,CR=0.451578) passed. 
(22.50%) HARQ Proc 9: CW0:Initial transmission (NSlot=8,RV=0,CR=0.451578) passed. 
(25.00%) HARQ Proc 10: CW0:Initial transmission (NSlot=9,RV=0,CR=0.451578) passed. 
(27.50%) HARQ Proc 11: CW0:Initial transmission (NSlot=10,RV=0,CR=0.451578) passed. 
(30.00%) HARQ Proc 12: CW0:Initial transmission (NSlot=11,RV=0,CR=0.451578) passed. 
(32.50%) HARQ Proc 13: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) passed. 
(35.00%) HARQ Proc 14: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) passed. 
(37.50%) HARQ Proc 15: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) passed. 
(40.00%) HARQ Proc 16: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) passed. 
(42.50%) HARQ Proc 1: CW0:Initial transmission (NSlot=16,RV=0,CR=0.451578) passed. 
(45.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=17,RV=0,CR=0.451578) passed. 
(47.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=18,RV=0,CR=0.451578) passed. 
(50.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=19,RV=0,CR=0.451578) passed. 
(52.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=0,RV=0,CR=0.451578) passed. 
(55.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=1,RV=0,CR=0.451578) passed. 
(57.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=2,RV=0,CR=0.451578) passed. 
(60.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=3,RV=0,CR=0.451578) passed. 
(62.50%) HARQ Proc 9: CW0:Initial transmission (NSlot=4,RV=0,CR=0.451578) passed. 
(65.00%) HARQ Proc 10: CW0:Initial transmission (NSlot=5,RV=0,CR=0.451578) passed. 
(67.50%) HARQ Proc 11: CW0:Initial transmission (NSlot=6,RV=0,CR=0.451578) passed. 
(70.00%) HARQ Proc 12: CW0:Initial transmission (NSlot=7,RV=0,CR=0.451578) passed. 
(72.50%) HARQ Proc 13: CW0:Initial transmission (NSlot=8,RV=0,CR=0.451578) passed. 
(75.00%) HARQ Proc 14: CW0:Initial transmission (NSlot=9,RV=0,CR=0.451578) passed. 
(77.50%) HARQ Proc 15: CW0:Initial transmission (NSlot=10,RV=0,CR=0.451578) passed. 
(80.00%) HARQ Proc 16: CW0:Initial transmission (NSlot=11,RV=0,CR=0.451578) passed. 
(82.50%) HARQ Proc 1: CW0:Initial transmission (NSlot=12,RV=0,CR=0.451578) passed. 
(85.00%) HARQ Proc 2: CW0:Initial transmission (NSlot=13,RV=0,CR=0.451578) passed. 
(87.50%) HARQ Proc 3: CW0:Initial transmission (NSlot=14,RV=0,CR=0.451578) passed. 
(90.00%) HARQ Proc 4: CW0:Initial transmission (NSlot=15,RV=0,CR=0.451578) passed. 
(92.50%) HARQ Proc 5: CW0:Initial transmission (NSlot=16,RV=0,CR=0.451578) passed. 
(95.00%) HARQ Proc 6: CW0:Initial transmission (NSlot=17,RV=0,CR=0.451578) passed. 
(97.50%) HARQ Proc 7: CW0:Initial transmission (NSlot=18,RV=0,CR=0.451578) passed. 
(100.00%) HARQ Proc 8: CW0:Initial transmission (NSlot=19,RV=0,CR=0.451578) passed. 

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;

На рисунке ниже показаны результаты производительности, полученные при моделировании 10000 подкадров (NFrames = 1000, SNRIn = -18:2:16).

Приложение

В этом примере используются следующие вспомогательные функции:

Избранная библиография

  1. 3GPP ТС 38.211. "НР; Физические каналы и модуляция. "Проект партнерства 3-го поколения; Техническая спецификация на сеть радиодоступа группы.

  2. 3GPP TS 38.212. "НР; мультиплексирование и канальное кодирование. "Проект партнерства 3-го поколения; Техническая спецификация на сеть радиодоступа группы.

  3. 3GPP ТС 38.213. "НР; Процедуры физического уровня для контроля. "Проект партнерства 3-го поколения; Техническая спецификация на сеть радиодоступа группы.

  4. 3GPP TS 38.214. "НР; Процедуры физического уровня для данных. "Проект партнерства третьего поколения; Техническая спецификация на сеть радиодоступа группы.

  5. 3GPP ТР 38.901. «Исследование модели канала для частот от 0,5 до 100 ГГц». Проект партнерства 3-го поколения; Техническая спецификация на сеть радиодоступа группы.

Локальные функции

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

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

    % Display a warning if the maximum possible rank of the channel equals
    % the number of layers
    if (nlayers > 2) && (nlayers == min(ntxants,nrxants))
        warning(['The maximum possible rank of the channel, given by %s, is equal to NLayers (%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,nlayers); %#ok<SPWRN>
    end

end

function estChannelGrid = getInitialChannelEstimate(carrier,nTxAnts,propchannel)
% 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 = ceil(max(chInfo.PathDelays*propchannel.SampleRate)) + chInfo.ChannelFilterDelay;

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

    % 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 wtx = getPrecodingMatrix(carrier,pdsch,hestGrid)
% Calculate precoding matrices for all PRGs in the carrier that overlap
% with the PDSCH allocation

    % Maximum CRB addressed by carrier grid
    maxCRB = carrier.NStartGrid + carrier.NSizeGrid - 1;

    % PRG size
    if (isfield(pdsch,'PRGBundleSize') && ~isempty(pdsch.PRGBundleSize))
        Pd_BWP = pdsch.PRGBundleSize;
    else
        Pd_BWP = maxCRB + 1;
    end

    % PRG numbers (1-based) for each RB in the carrier grid
    NPRG = ceil((maxCRB + 1) / Pd_BWP);
    prgset = repmat((1:NPRG),Pd_BWP,1);
    prgset = prgset(carrier.NStartGrid + (1:carrier.NSizeGrid).');

    [~,~,R,P] = size(hestGrid);
    wtx = zeros([pdsch.NumLayers P NPRG]);
    for i = 1:NPRG

        % Subcarrier indices within current PRG and within the PDSCH
        % allocation
        thisPRG = find(prgset==i) - 1;
        thisPRG = intersect(thisPRG,pdsch.PRBSet(:) + carrier.NStartGrid,'rows');
        prgSc = (1:12)' + 12*thisPRG';
        prgSc = prgSc(:);

        if (~isempty(prgSc))

            % Average channel estimate in PRG
            estAllocGrid = hestGrid(prgSc,:,:,:);
            Hest = permute(mean(reshape(estAllocGrid,[],R,P)),[2 3 1]);

            % SVD decomposition
            [~,~,V] = svd(Hest);
            wtx(:,:,i) = V(:,1:pdsch.NumLayers).';

        end

    end

    wtx = wtx / sqrt(pdsch.NumLayers); % Normalize by NumLayers

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 = hPRGPrecode([K L R P],carrier.NStartGrid,estChannelGrid,reshape(1:numel(estChannelGrid),[K*L R P]),W);
    estChannelGrid = reshape(estChannelGrid,K,L,R,[]);

end

function [mappedPRB,mappedSymbols] = mapNumerology(subcarriers,symbols,nrbs,nrbt,fs,ft)
% Map the SSBurst numerology to PDSCH numerology. The outputs are:
%   - mappedPRB: 0-based PRB indices for carrier resource grid (arranged in a column)
%   - mappedSymbols: 0-based OFDM symbol indices in a slot for carrier resource grid (arranged in a row)
% The input parameters are:
%   - subcarriers: 1-based row subscripts for SSB resource grid (arranged in a column)
%   - symbols: 1-based column subscripts for SSB resource grid (arranged in an N-by-4 matrix, 4 symbols for each transmitted burst in a row, N transmitted bursts)
%     SSB resource grid is sized using ssbInfo.NRB, normal CP, spanning 5 subframes
%   - nrbs: source (SSB) NRB
%   - nrbt: target (carrier) NRB
%   - fs: source (SSB) SCS
%   - ft: target (carrier) SCS

    mappedPRB = unique(fix((subcarriers-(nrbs*6) - 1)*fs/(ft*12) + nrbt/2),'stable');

    symbols = symbols.';
    symbols = symbols(:).' - 1;

    if (ft < fs)
        % If ft/fs < 1, reduction
        mappedSymbols = unique(fix(symbols*ft/fs),'stable');
    else
        % Else, repetition by ft/fs
        mappedSymbols = reshape((0:(ft/fs-1))' + symbols(:)'*ft/fs,1,[]);
    end

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);
    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);
    xlabel('Resource block');
    ylabel('EVM (%)');
    legend("layer " + (1:pdsch.NumLayers),'Location','EastOutside');
    title(['EVM per layer per resource block, slot #' num2str(nslot)]);

    drawnow;

end

См. также

Объекты

Функции