В этом примере показано, как сгенерировать, агрегируйтесь и демодулируйте несколько нисходящих несущих, использующих функции 5G Toolbox™.
Этот пример генерирует форму волны NR с агрегацией несущей (CA). Чтобы выполнить агрегацию несущей, пример вычисляет смещения частоты для внутриполосы непрерывный случай CA, как описано в Разделе TS 38.104 5.3 А. Пример также поддерживает настроенную внутриполосу, состоящую из нескольких несмежных участков, и сценарии межполосы CA.
Чтобы сгенерировать агрегированную нисходящую форму волны, пример конфигурирует стандартно-совместимый нисходящий фиксированный ссылочный канал (FRC) для каждой несущей компонента. TS 38.101-1 Приложений A.3 задают физический нисходящий канал совместно использованный канал (PDSCH) FRCs для FR1 и TS 38.101-2 Приложений A.3, задает PDSCH FRCs для FR2. Для генерации сигналов FRC можно задать полосу пропускания канала, расстояние между поднесущими, модуляцию, режим дуплекса и ячейку ID. Для получения дополнительной информации о том, как сгенерировать DL FRCs, смотрите 5G NR-TM и Генерация сигналов FRC.
После генерации несущих компонента (CCS) пример передискретизирует формы волны к общей частоте дискретизации и комбинирует CCS, чтобы сгенерировать агрегированную форму волны.
Наконец, пример фильтрует и прореживает выбранный CC, чтобы выполнить измерения EVM и декодирование PDSCH.
Векторный ChannelBandwidths
задает полосу пропускания для каждого CC. Длина этого вектора соответствует количеству CCS. Элементы ChannelBandwidths
должен быть в наборе {5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90 100} МГц для FR1 и в наборе {50, 100, 200, 400} МГц для FR2. TS 38.101-1 Разделов 5.5A.1 Таблица 5.5A.1-1 и TS 38.101-2 Разделов 5.5A.1 список Таблиц 5.5A.1-1 допустимые комбинации полос пропускания для FR1 и агрегации несущей FR2, соответственно.
Если ccSpacings
вектор пуст, пример вычисляет интервалы между последовательными несущими, ccSpacings
, как описано в TS 38.104. Чтобы выбрать интервалы по вашему выбору, добавьте интервалы в ccSpacings
вектор.
% Configure three carriers for the aggregation. You can select a different % number of carriers by modifying the number of elements in the % |channelBandwidths|, |SCSs|, |modulations|, and |nCellIDs| vectors. frequencyRange = 'FR1'; % (FR1 or FR2) channelRaster = 100; % Channel raster in kHz (15, 60 or 100) channelBandwidths = [60 40 40]; % Channel bandwidths in MHz % (5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, % 90 or 100 for FR1) % (50, 100, 200 or 400 for FR2) SCSs = [30 30 30]; % Subcarrier spacings in kHz % (15, 30 or 60 for FR1) % (60 or 120 for FR2) modulations = {'QPSK' '64QAM' '256QAM'}; % ('QPSK', '64QAM' or '256QAM' for FR1) % ('QPSK', '16QAM' or '64QAM' for FR2) nCellIDs = [1 2 3]; % Cell IDs duplexMode = 'TDD'; % Duplex mode ('TDD' or 'FDD') sv = '15.2.0'; % Standard version ('15.1.0', '15.2.0' or '15.7.0') numSubframes = 10; % Number of subframes to generate per carrier % Choose the spacings between consecutive carriers, |ccSpacings|, or leave % the vector empty for calculating the spacings, as described in TS 38.104 % Section 5.3A ccSpacings = []; % MHz % Select the CC to demodulate CCofInterest = 2; % Verify the number of CCs, channel bandwidths, subcarrier spacings, % modulations, and spacings. Additionally, check that the spacings are % greater than 0. hNRVerifyCarrierParameters(length(channelBandwidths),length(SCSs),... length(modulations),length(nCellIDs),ccSpacings);
Сгенерируйте конфигурационную структуру для каждого CC с помощью hNRReferenceWaveformGenerator
. Сохраните конфигурационные структуры для всего CCS в массиве ячеек.
% Establish the number of component carriers numCC = length(channelBandwidths); % CC configuration referenceChannel = cell(1,numCC); wavegen = cell(1,numCC); for i = 1:numCC % Select a reference channel, FRC, based on the chosen modulation and % frequency range referenceChannel{i} = strcat('DL-FRC-',frequencyRange,'-',modulations{i}); % Create a generator object for the above PDSCH FRC reference channel wavegen{i} = hNRReferenceWaveformGenerator(referenceChannel{i},... channelBandwidths(i),SCSs(i),duplexMode,nCellIDs(i),sv); end
Чтобы выполнить агрегацию несущей, необходимо вычислить параметры частоты, описанные в TS 38.104, Разделы 5.3 и 5.4.
Fc_offset
вектор, содержащий центральную частоту каждого CC в основной полосе
F_offset_low
смещение частоты от более низкого Fc_offset
к ниже агрегированному ребру полосы пропускания
F_offset_high
смещение частоты от верхнего Fc_offset
к верхнему агрегированному ребру полосы пропускания канала
F_edge_low
более низкое ребро агрегированной полосы пропускания канала
F_edge_high
верхнее ребро агрегированной полосы пропускания канала
BW_channel_CA
агрегированная полоса пропускания канала всего CCS
Сосредоточьте более низкий компонент несущей в основной полосе (Fc_offset(1)
= 0 Гц), и вычисляют центральную частоту для остальной части CCS. Чтобы определить центральные частоты следующим, метод описал в Разделе TS 38.104 5.3 А, необходимо вычислить минимальные защитные полосы и минимальные интервалы CC. В качестве альтернативы, чтобы выбрать ваши собственные центральные частоты, выберите непустой ccSpacings
вектор.
% Get the largest SCS configuration, |SCSConfig|, among the SCS % configurations supported for each two consecutive channel bandwidths to % obtain the minimum guardband, as described in TS 38.104 Section 5.4.1.2. table = hGetGBTable(frequencyRange); % Minimum guardband table if isequal(frequencyRange,'FR1') if any(channelBandwidths(:) == 5) SCSConfig = 1; else SCSConfig = 2; end else SCSConfig = 3; end % Calculate the minimum guardband, as described in TS 38.104 Section 5.3.3 % Table 5.3.3-1 for FR1 and Table 5.3.3-1 for FR2, to obtain the minimum CC % spacings. minimumGuardBand = zeros(1,numCC); NDLRB = zeros(1,numCC); scs = strcat(num2str(2^SCSConfig*15),'kHz'); % Common SCS in kHz to extract % minimum guardband for i = 1:numCC NDLRB(i) = wavegen{i}.Config.SCSCarriers{1}.NSizeGrid; minimumGuardBand(i) = table{{scs},{strcat(num2str(channelBandwidths(i)),... 'MHz');}}; % kHz minimumGuardBand(i) = minimumGuardBand(i)*1e-3; % MHz end % Compute the minimum CC spacings, as defined in TS 38.104 Section % 5.4.1.2. Use these spacings to calculate the center frequencies and for % filtering each CC. minCCSpacings = zeros(1,numCC-1); % Minimum CC spacing for k = 2:numCC minCCSpacings(k-1) = hNRCarrierAggregationChannelSpacing( ... channelBandwidths(k-1), channelBandwidths(k), minimumGuardBand(k-1), ... minimumGuardBand(k),channelRaster,SCSConfig); % MHz end % Determine the center frequency for each CC with respect to 0 Hz. % Initially, the lower carrier frequency is at baseband (Fc_offset(1) = 0 Hz). Fc_offset = zeros(1,numCC); if isempty(ccSpacings) ccSpacings = minCCSpacings; end for k = 2:numCC Fc_offset(k) = Fc_offset(k-1) + ccSpacings(k-1); % MHz end
Вычислите смещения частоты от более низких и верхних центральных частот до более низких и верхних агрегированных ребер полосы пропускания, соответственно, как описано в Разделе TS 38.104 5.3 А.
F_offset_low = (NDLRB(1)*12+1)*(SCSs(1)*1e-3)/2 + minimumGuardBand(1); % MHz F_offset_high = (NDLRB(end)*12-1)*(SCSs(end)*1e-3)/2 + minimumGuardBand(end); %MHz
Вычислите более низкие и верхние ребра агрегированной полосы пропускания канала, Раздел TS 38.104 5.3 А.
F_edge_low = Fc_offset(1) - F_offset_low; % MHz F_edge_high = Fc_offset(end) + F_offset_high; % MHz
Вычислите агрегированную полосу пропускания канала, Раздел TS 38.104 5.3 А
BW_channel_CA = F_edge_high - F_edge_low; % MHz fprintf('BW_channel_CA: %0.4f MHz\n',BW_channel_CA);
BW_channel_CA: 141.0800 MHz
Определите сдвиг частоты, чтобы сосредоточить агрегированную полосу пропускания канала в основной полосе (0 Гц).
shiftToCenter = -1*(BW_channel_CA/2 + F_edge_low); % Center aggregated bandwidth at baseband Fc_offset = Fc_offset + shiftToCenter; F_edge_low = Fc_offset(1) - F_offset_low; F_edge_high = Fc_offset(end) + F_offset_high; % Display frequency band edges fprintf('F_edge_low: %0.4f MHz\n',F_edge_low);
F_edge_low: -70.5400 MHz
fprintf('F_edge_high: %0.4f MHz\n',F_edge_high);
F_edge_high: 70.5400 MHz
fprintf('F_offset_low: %0.4f MHz\n',F_offset_low);
F_offset_low: 30.7050 MHz
fprintf('F_offset_high: %0.4f MHz\n',F_offset_high);
F_offset_high: 20.6750 MHz
% Display carrier frequencies fprintf('\n'); for i = 1:numCC fprintf('Component Carrier %d:\n',i); fprintf(' Fc: %0.4f MHz\n', Fc_offset(i)); end
Component Carrier 1:
Fc: -39.8350 MHz
Component Carrier 2:
Fc: 9.9650 MHz
Component Carrier 3:
Fc: 49.8650 MHz
Вычислите необходимые факторы сверхдискретизации для каждой несущей компонента, OSRs
, использовать общую частоту дискретизации для агрегированной формы волны.
% Obtain sample rates of the component carriers CCSR = zeros(1,numCC); carriers = cell(1,numCC); for i = 1:numCC carriers{i} = nrCarrierConfig; carriers{i}.NCellID = nCellIDs(i); carriers{i}.NSizeGrid = NDLRB(i); carriers{i}.SubcarrierSpacing = SCSs(i); carriers{i}.CyclicPrefix = wavegen{i}.Config.BandwidthParts{1}.CyclicPrefix; info = nrOFDMInfo(carriers{i}); CCSR(i) = info.SampleRate; % Hz end % Calculate the oversampling ratio for the largest BW CC to ensure the % waveform occupies a maximum of 85% of the total bandwidth, |bwfraction| bwfraction = 0.85; % Bandwidth utilization of 85% OSR = (BW_channel_CA/bwfraction)/(max(CCSR)/1e6); % To simplify the resampling operation, choose an oversampling ratio which % is a power of 2: calculate the next power of two above OSR OSR = 2^ceil(log2(OSR)); % Calculate the overall sample rate for the aggregated waveform SR = OSR*max(CCSR); % Hz fprintf('\nOutput sample rate: %0.4f Ms/s\n\n',SR/1e6);
Output sample rate: 245.7600 Ms/s
% Calculate the individual oversampling factors for the component carriers
OSRs = SR./CCSR;
Вызовите generateWaveform
функция от hNRReferenceWaveformGenerator
файл помощника, чтобы сгенерировать форму волны для каждого CC. Передискретизируйте каждую несущую к общей частоте дискретизации. Наконец, используйте comm.MultibandCombiner
к частоте модулируют несущие к соответствующей центральной частоте и агрегировали CCS, чтобы сформировать объединенную форму волны.
% Generate and aggregate the component carriers tmwaveinfo = cell(1,numCC); waveInfo = cell(1,numCC); resourcesInfo = cell(1,numCC); clear waveform for i = numCC:-1:1 % Generate each CC [wf,waveInfo{i},resourcesInfo{i}] = generateWaveform(wavegen{i},... numSubframes); % Resample the CCs so that they have the same sample rate waveform(:,i) = resample(wf,OSRs(i),1)/OSRs(i); end % Aggregate all CC. comm.MultibandCombiner applies the frequency offsets % and combines the resulting signals together. carrierAggregator = comm.MultibandCombiner(InputSampleRate = SR,... FrequencyOffsets = Fc_offset*1e6,... OutputSampleRateSource = 'Property',... OutputSampleRate = SR); waveform = carrierAggregator(waveform);
Отобразите спектр несущей агрегированный сигнал при помощи hNRCarrierAggregationPlotSpectrum
функция помощника. График спектра показывает отдельные полосы пропускания несущей. Этот пример не делает upconvert форма волны к радиочастоте (RF), центр агрегированной полосы пропускания в основной полосе (0 Гц).
specPlot = hNRCarrierAggregationPlotSpectrum(waveform,SR,... 'Power Spectrum of Carrier Aggregation',{'Signal spectrum'});
Выберите CC, затем демодулируйте, отфильтруйте и проредите CC по вашему выбору, выполнив эти шаги.
Принесите CC к основной полосе (0 Гц)
Вычислите полосу пропускания и частоты полосы задерживания фильтра
Отфильтруйте соседний CCS при помощи спроектированного фильтра и проредите CC.
% Verify carrier of interest ID if CCofInterest > numCC || CCofInterest <= 0 || mod(CCofInterest,1) ~= 0 error('nr5g:NRDownlinkCarrierAggregationExample:CCOutOfRange',... 'Cannot demodulate CC number %d, choose an integer number that falls between 1 and %d\n',... CCofInterest, numCC) ; end fprintf(1,'Extracting CC number %d: \n', CCofInterest);
Extracting CC number 2:
% Define downsampling filter order filterOrder = 201; % Precalculate the filter passband and stopband values for all CC firPassbandVec = (NDLRB*12-1).*(SCSs*1e-3)/2 / (SR/1e6/2); firStopbandVec = hNRCarrierAggregationStopband(minCCSpacings,NDLRB,SR,SCSs); % Choose the passband and stopband values for the carrier of interest firPassband = firPassbandVec(CCofInterest); firStopband = firStopbandVec(CCofInterest); % Pad signal with zeros to consider filter transient response length waveform = [waveform; zeros(filterOrder*2,size(waveform,2))]; % Center the carrier of interest at 0 Hz frequencyShifter = comm.PhaseFrequencyOffset(SampleRate = SR,... FrequencyOffset = -Fc_offset(CCofInterest)*1e6); demodulatedCC = frequencyShifter(waveform); % To ease the filter design requirements, apply the downsampling in two % stages if necessary. Use a downsampling factor of 4 in the initial stage. % If the quality of the resulting signal is not as required, consider a % different filter design in this initial stage. if (firStopband < 0.1) % Downsample by 4 in the initial stage SRC = 4; demodulatedCC = resample(demodulatedCC,1,SRC); % Update passband and stopband values firPassband = firPassband * SRC; firStopband = firStopband * SRC; else % Do not apply an extra downsampling SRC = 1; end % Design the lowpass filter to filter out the CC of your choice frEdges = [0 firPassband firStopband 1]; firFilter = dsp.FIRFilter; firFilter.Numerator = firpm(filterOrder,frEdges,[1 1 0 0]); % Display the response of the designed filter fvtool(firFilter,'Analysis','freq');
% Filter the signal to extract the component of interest rxWaveform = firFilter(demodulatedCC); % Plot the demodulated and filtered spectra filteredSpecPlot = ... hNRCarrierAggregationPlotSpectrum([demodulatedCC, rxWaveform],SR,... 'Demodulated and Filtered Waveform Power Spectrum',... {'Carrier aggregated signal' 'Filtered signal'});
% Downsample the filtered carrier to its baseband rate
rxWaveform = downsample(rxWaveform,OSRs(CCofInterest)/SRC);
hNRPDSCHEVM
функция помощника возвращает PDSCH EVM путем выполнения синхронизации, демодуляции OFDM, оценки канала и эквализации. Функция отображает EVM для каждого паза и системы координат и полный EVM, усредненный по целой входной форме волны. Функция также строит эти графики: EVM на символ OFDM, паз, поднесущую и полный EVM.
% Parameterize the channel estimator configuration using the structure |cfg| cfg = struct(); cfg.Evm3GPP = true; % To measure EVM as defined in TS 38.104, Annex B(FR1) % / Annex C(FR2) set |Evm3GPP| to |true|. cfg.TargetRNTIs = []; cfg.PlotEVM = true; cfg.DisplayEVM = true; cfg.Label = wavegen{CCofInterest}.ConfiguredModel{1}; % Perform EVM measurements and plot results [evmInfo,eqSym,refSym] = hNRPDSCHEVM(wavegen{CCofInterest}.Config,... rxWaveform,cfg);
EVM stats for BWP idx : 1 Low edge RMS EVM, Peak EVM, slot 1: 3.111 8.587% High edge RMS EVM, Peak EVM, slot 1: 2.795 8.020% Low edge RMS EVM, Peak EVM, slot 2: 3.008 8.550% High edge RMS EVM, Peak EVM, slot 2: 2.774 7.533% Low edge RMS EVM, Peak EVM, slot 3: 3.156 9.854% High edge RMS EVM, Peak EVM, slot 3: 2.796 7.604% Low edge RMS EVM, Peak EVM, slot 4: 2.984 8.644% High edge RMS EVM, Peak EVM, slot 4: 2.784 7.600% Low edge RMS EVM, Peak EVM, slot 5: 2.968 8.779% High edge RMS EVM, Peak EVM, slot 5: 2.774 7.659% Low edge RMS EVM, Peak EVM, slot 6: 3.106 9.877% High edge RMS EVM, Peak EVM, slot 6: 2.783 7.265% Low edge RMS EVM, Peak EVM, slot 10: 3.129 10.707% High edge RMS EVM, Peak EVM, slot 10: 2.779 8.086% Low edge RMS EVM, Peak EVM, slot 11: 3.105 9.934% High edge RMS EVM, Peak EVM, slot 11: 2.767 7.837% Low edge RMS EVM, Peak EVM, slot 12: 3.071 8.785% High edge RMS EVM, Peak EVM, slot 12: 2.780 7.284% Low edge RMS EVM, Peak EVM, slot 13: 3.010 8.784% High edge RMS EVM, Peak EVM, slot 13: 2.792 7.980% Low edge RMS EVM, Peak EVM, slot 14: 3.005 8.365% High edge RMS EVM, Peak EVM, slot 14: 2.789 7.437% Low edge RMS EVM, Peak EVM, slot 15: 2.944 8.279% High edge RMS EVM, Peak EVM, slot 15: 2.791 7.852% Low edge RMS EVM, Peak EVM, slot 16: 3.057 8.974% High edge RMS EVM, Peak EVM, slot 16: 2.788 7.686% Averaged low edge RMS EVM, frame 0: 3.051% Averaged high edge RMS EVM, frame 0: 2.784% Averaged RMS EVM frame 0: 3.051%
Averaged overall RMS EVM: 3.051% Overall Peak EVM = 10.7065%
Декодируйте PDSCH восстановленного сигнала и проверьте получившийся CRC на наличие ошибок.
% Perform time synchronization on the input waveform offset = nrTimingEstimate(carriers{CCofInterest},rxWaveform,... waveInfo{CCofInterest}.ResourceGridBWP); rxWaveform = rxWaveform(1+offset:end,:); % Perform OFDM demodulation rxGrid = nrOFDMDemodulate(carriers{CCofInterest},rxWaveform); % Get the allocated slots and OFDM symbols per slot allocatedSlots = zeros(1,size(resourcesInfo{CCofInterest}.WaveformResources.PDSCH.Resources,2)); for i=1:length(allocatedSlots) allocatedSlots(i) = resourcesInfo{CCofInterest}.WaveformResources.PDSCH.Resources(i).NSlot; end L = carriers{CCofInterest}.SymbolsPerSlot; % OFDM symbols per slot % Create a DLSCH decoder System object decodeDLSCH = nrDLSCHDecoder; decodeDLSCH.MultipleHARQProcesses = false; decodeDLSCH.TargetCodeRate = wavegen{CCofInterest}.Config.PDSCH{1}.TargetCodeRate; decodeDLSCH.LDPCDecodingAlgorithm = 'Normalized min-sum'; decodeDLSCH.MaximumLDPCIterationCount = 6; for NSlot=1:length(allocatedSlots) % Extract slot SlotID = allocatedSlots(NSlot); rxSlot = rxGrid(:,(1:L)+(SlotID*L),:); refSlot = waveInfo{CCofInterest}.ResourceGridBWP(:,(1:L)+(SlotID*L),:); % Perform channel estimation [estChannelGrid,noiseEst] = nrChannelEstimate(carriers{CCofInterest},... rxSlot,refSlot); % Get PDSCH resource elements from the received grid and channel estimate pdschIndices = resourcesInfo{CCofInterest}.WaveformResources.PDSCH.Resources(NSlot).ChannelIndices; [pdschRx,pdschHest] = nrExtractResources(pdschIndices,rxSlot,estChannelGrid); % Perform equalization [pdschEq,csi] = nrEqualizeMMSE(pdschRx,pdschHest,noiseEst); % Perform layer demapping, symbol demodulation, and descrambling modulation = wavegen{CCofInterest}.Config.PDSCH{1}.Modulation; RNTI = wavegen{CCofInterest}.Config.PDSCH{1}.RNTI; [dlschLLRs,rxSymbols] = nrPDSCHDecode(pdschEq,modulation,... carriers{CCofInterest}.NCellID,RNTI,noiseEst); % Scale LLRs by CSI csi = nrLayerDemap(csi); % CSI layer demapping NumCW = size(resourcesInfo{CCofInterest}.WaveformResources.PDSCH.Resources(NSlot).Codeword,2); for cwIdx = 1:NumCW 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}(:); % Scaled symbols end % Calculate the transport block sizes for the codewords in the slot trBlkSize = resourcesInfo{CCofInterest}.WaveformResources.PDSCH.Resources(NSlot).TransportBlockSize; % Decode the DL-SCH transport channel decodeDLSCH.TransportBlockLength = trBlkSize; NLayers = wavegen{CCofInterest}.Config.PDSCH{1}.NumLayers; RVSequence = wavegen{CCofInterest}.Config.PDSCH{1}.RVSequence; [decbits,crc] = decodeDLSCH(dlschLLRs,modulation,NLayers,RVSequence); % Display the CRC status if crc disp(['Slot ' num2str(SlotID) ': CRC failed']); else disp(['Slot ' num2str(SlotID) ': CRC passed']); end end
Slot 1: CRC passed Slot 2: CRC passed Slot 3: CRC passed Slot 4: CRC passed Slot 5: CRC passed Slot 6: CRC passed Slot 10: CRC passed Slot 11: CRC passed Slot 12: CRC passed Slot 13: CRC passed Slot 14: CRC passed Slot 15: CRC passed Slot 16: CRC passed
3GPP TS 38.104 "NR; передача радио Базовой станции (BS) и прием" Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.
3GPP TS 38.101-1 "NR; передача радио Оборудования пользователя (UE) и прием; Часть 1: Область значений 1 Автономное". Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.
3GPP TS 38.101-2 "NR; передача радио Оборудования пользователя (UE) и прием: Часть 2: Область значений 2 Автономных". Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.