В этом примере показано, как сгенерировать 5G тестовая модель NR (NR-TM) форма волны с помощью приложения 5G Waveform Generator и загрузить сгенерированную форму волны на векторный генератор сигнала Keysight™ для беспроводной передачи с помощью программного обеспечения Instrument Control Toolbox™. Пример затем получает переданный беспроводной сигнал с помощью сигнала Keysight анализатор и анализирует сигнал в MATLAB®.
Этот пример генерирует 5G форма волны NR-TM с помощью приложения 5G Waveform Generator, загружает и передает форму волны на генератор сигнала вектора Keysight, и затем получает форму волны с помощью сигнала Keysight анализатор для анализа формы волны в MATLAB. Эта схема показывает общий рабочий процесс.
Требования
Чтобы запустить этот пример, вам нужны эти инструменты:
Вектор Keysight E4438C ESG сигнализирует о генераторе
Сигнал Keysight N9030A PXA анализатор
В MATLAB, на вкладке Apps, кликают по приложению 5G Waveform Generator.
В разделе Waveform Type нажмите NR Test Models. В крайней левой панели приложения можно установить параметры для выбранной формы волны. Для этого примера:
Установите Частотный диапазон как FR1 (410 MHz - 7.125 GHz)
Установите Тестовую модель как NR-FR1-TM3.1 (Full band, uniform 64 QAM)
Установите полосу пропускания Канала (МГц) как 10
Установите Расстояние между поднесущими (kHz) как 30
Установите Дуплексный режим как FDD
.
На панели инструментов приложения нажмите Generate.
% Set the NR-TM parameters for the receiver nrtm = "NR-FR1-TM3.1"; % Reference channel bw = "10MHz"; % Channel bandwidth scs = "30kHz"; % Subcarrier spacing dm = "FDD"; % Duplexing mode
Этот рисунок показывает 5G на 10 МГц форму волны NR, видимую в основной полосе.
Загрузите сгенерированный сигнал на генератор сигнала RF по одному из поддерживаемых коммуникационных интерфейсов (требует Instrument Control Toolbox). Приложение автоматически находит генератор сигнала, который соединяется по интерфейсу TCP/IP. На вкладке Transmitter приложения выберите Agilent/Keysight Signal Generator SCPI
из списка Драйверов. Установите Центральную частоту (GHz) параметр к 3.4
и Выходная мощность (dBm) параметр к -15
. Приложение автоматически получает основополосную частоту дискретизации из сгенерированной формы волны. Чтобы запустить передачу, нажмите Transmit в панели инструментов.
Чтобы считать синфазное и квадратуру (IQ) данные в MATLAB для анализа, сконфигурируйте сигнал Keysight N9030A анализатор с помощью программного обеспечения Instrument Control Toolbox.
Задайте инструментальные параметры конфигурации на основе сигнала, который вы измеряете.
% Set parameters for the spectrum analyzer centerFrequency = 3.4e9; sampleRate = 15.36e6; measurementTime = 20e-3; mechanicalAttenuation = 0; %dB startFrequency = 3.39e9; stopFrequency = 3.41e9; resolutionBandwidth = 220e3; videoBandwidth = 220000;
Выполните эти шаги прежде, чем соединить со спектром анализатор.
Найдите, что ID ресурса Keysight N9030A сигнализирует об анализаторе.
Свяжите с инструментом с помощью интерфейса виртуальной инструментальной программной архитектуры (VISA).
Настройте размер входного буфера, чтобы содержать данные, которые возвращает инструмент.
Установите тайм-аут позволять достаточное количество времени для измерения и передачи данных.
foundVISA = visadevlist; resourceID = foundVISA(foundVISA.Model == "N9030A",:).ResourceName; resourceID = resourceID(contains(resourceID,"N9030A")); % Extract resourceID which contains "N9030A" sigAnalyzerObj = visadev(resourceID); sigAnalyzerObj.ByteOrder = "big-endian"; configureCallback(sigAnalyzerObj,"byte",85e6,@callbackFcn) sigAnalyzerObj.Timeout = 20;
Сбросьте инструмент к известному состоянию с помощью соответствующей стандартной команды для программируемых инструментов (SCPI). Запросите инструментальную идентичность, чтобы гарантировать, что правильный инструмент соединяется.
writeline(sigAnalyzerObj,"*RST"); instrumentInfo = writeread(sigAnalyzerObj,"*IDN?"); fprintf("Instrument identification information: %s",instrumentInfo);
Instrument identification information: Agilent Technologies,N9030A,US00071181,A.14.16
X-серийный сигнал и спектр анализаторы выполняют измерения IQ, а также измерения спектра. В этом примере вы получаете область времени данные IQ, визуализируете данные с помощью MATLAB и выполняете анализ сигнала полученных данных. Команды SCPI конфигурируют инструмент и задают формат передачи данных после того, как измерение будет завершено.
% Set up signal analyzer mode to basic IQ mode writeline(sigAnalyzerObj,":INSTrument:SELect BASIC"); % Set the center frequency writeline(sigAnalyzerObj,strcat(":SENSe:FREQuency:CENTer ",num2str(centerFrequency))); % Set the capture sample rate writeline(sigAnalyzerObj,strcat(":SENSe:WAVeform:SRATe ",num2str(sampleRate))); % Turn off averaging writeline(sigAnalyzerObj,":SENSe:WAVeform:AVER OFF"); % Set the spectrum analyzer to take one single measurement after the trigger line goes high writeline(sigAnalyzerObj,":INIT:CONT OFF"); % Set the trigger to external source 1 with positive slope triggering writeline(sigAnalyzerObj,":TRIGger:WAVeform:SOURce IMMediate"); writeline(sigAnalyzerObj,":TRIGger:LINE:SLOPe POSitive"); % Set the time for which measurement needs to be made writeline(sigAnalyzerObj,strcat(":WAVeform:SWE:TIME ",num2str(measurementTime))); % Turn off electrical attenuation writeline(sigAnalyzerObj,":SENSe:POWer:RF:EATTenuation:STATe OFF"); % Set the mechanical attenuation level writeline(sigAnalyzerObj,strcat(":SENSe:POWer:RF:ATTenuation ",num2str(mechanicalAttenuation))); % Turn IQ signal ranging to auto writeline(sigAnalyzerObj,":SENSe:VOLTage:IQ:RANGe:AUTO ON"); % Set the endianness of returned data writeline(sigAnalyzerObj,":FORMat:BORDer NORMal"); % Set the format of the returned data writeline(sigAnalyzerObj,":FORMat:DATA REAL,64");
Инициируйте инструмент, чтобы сделать измерение. Ожидайте операции измерения, чтобы завершиться, и затем читать - в форме волны. Прежде, чем обработать данные, разделите меня и компоненты Q из чередованных данных, которые получены от инструмента, и создайте комплексный вектор в MATLAB.
% Trigger the instrument and initiate measurement writeline(sigAnalyzerObj,"*TRG"); writeline(sigAnalyzerObj,":INITiate:WAVeform"); % Wait until measure operation is complete measureComplete = writeread(sigAnalyzerObj,"*OPC?"); % Read the IQ data writeline(sigAnalyzerObj,":READ:WAV0?"); data = readbinblock(sigAnalyzerObj,"double"); % Separate the data and build the complex IQ vector inphase = data(1:2:end); quadrature = data(2:2:end); rxWaveform = inphase+1i*quadrature;
Получите и отобразите информацию о последний раз полученных данных.
writeline(sigAnalyzerObj,":FETCH:WAV1?"); signalSpec = readbinblock(sigAnalyzerObj,"double"); % Display the measurement information captureSampleRate = 1/signalSpec(1); fprintf("Sample Rate (Hz) = %s",num2str(captureSampleRate));
Sample Rate (Hz) = 15360000
fprintf("Number of points read = %s",num2str(signalSpec(4)));
Number of points read = 307201
fprintf("Max value of signal (dBm) = %s",num2str(signalSpec(6)));
Max value of signal (dBm) = -39.0019
fprintf("Min value of signal (dBm) = %s",num2str(signalSpec(7)));
Min value of signal (dBm) = -107.9755
Постройте спектр полученной формы волны, чтобы подтвердить полосу пропускания полученного сигнала.
% Ensure rxWaveform is a column vector if ~iscolumn(rxWaveform) rxWaveform = rxWaveform.'; end % Plot the power spectral density (PSD) of the acquired signal spectrumPlotRx = dsp.SpectrumAnalyzer; spectrumPlotRx.SampleRate = captureSampleRate; spectrumPlotRx.SpectrumType = "Power density"; spectrumPlotRx.PowerUnits = "dBm"; spectrumPlotRx.Window = "Hamming"; spectrumPlotRx.SpectralAverages = 10; spectrumPlotRx.YLimits = [-140 -90]; spectrumPlotRx.YLabel = "PSD"; spectrumPlotRx.ShowLegend = false; spectrumPlotRx.Title = "Received Signal Spectrum: 10 MHz 5G NR-TM Waveform"; spectrumPlotRx(rxWaveform);
Переключите инструмент на спектр режим анализатора и сравните представление спектра, сгенерированное в MATLAB с представлением об анализаторе сигнала. Используйте дополнительные команды SCPI, чтобы сконфигурировать инструментальное измерение и настройки отображения.
% Switch back to the spectrum analyzer view writeline(sigAnalyzerObj,":INSTrument:SELect SA"); % Set the mechanical attenuation level writeline(sigAnalyzerObj,strcat(":SENSe:POWer:RF:ATTenuation ",num2str(mechanicalAttenuation))); % Set the center frequency, RBW, and VBW writeline(sigAnalyzerObj,strcat(":SENSe:FREQuency:CENTer ",num2str(centerFrequency))); writeline(sigAnalyzerObj,strcat(":SENSe:FREQuency:STARt ",num2str(startFrequency))); writeline(sigAnalyzerObj,strcat(":SENSe:FREQuency:STOP ",num2str(stopFrequency))); writeline(sigAnalyzerObj,strcat(":SENSe:BANDwidth:RESolution ",num2str(resolutionBandwidth))); writeline(sigAnalyzerObj,strcat(":SENSe:BANDwidth:VIDeo ",num2str(videoBandwidth))); % Enable continuous measurement on the spectrum analyzer writeline(sigAnalyzerObj,":INIT:CONT ON"); % Begin receiving the over-the-air signal writeline(sigAnalyzerObj,"*TRG");
Для инструментальной очистки очистите соединение КИП:
clear sigAnalyzerObj;
Чтобы остановить 5G передача формы волны NR-TM, в разделе Instrument по панели инструментов приложения, нажимают Stop Transmission.
Используйте generateWaveform
функция hNRReferenceWaveformGenerator
файл помощника, чтобы извлечь информацию о форме волны для определенного TM.
tmwavegen = hNRReferenceWaveformGenerator(nrtm,bw,scs,dm); [~,tmwaveinfo,resourcesInfo] = generateWaveform(tmwavegen);
Крупная компенсация смещения частоты Используя символы ссылки демодуляции (DM-RS)
Ищите смещения с шагом 1 кГц до 100 кГц.
frequencyCorrectionRange = -100e3:1e3:100e3;
[rxWaveform, coarseOffset] = DMRSFrequencyCorrection(rxWaveform,captureSampleRate,frequencyCorrectionRange,tmwavegen,resourcesInfo);
fprintf("Coarse frequency offset = %.0f Hz", coarseOffset)
Coarse frequency offset = 0 Hz
Прекрасная компенсация смещения частоты Используя DM-RS
Ищите смещения с шагом 5 Гц до 100 Гц
frequencyCorrectionRange = -100:5:100;
[rxWaveform, fineOffset] = DMRSFrequencyCorrection(rxWaveform,captureSampleRate,frequencyCorrectionRange,tmwavegen,resourcesInfo);
fprintf("Fine frequency offset = %.1f Hz", fineOffset)
Fine frequency offset = -30.0 Hz
Измерения EVM
Используйте hNRPDSCHEVM
функция, чтобы анализировать форму волны. Функция выполняет эти шаги.
Синхронизирует DM-RS по одной системе координат для дуплекса деления частоты (FDD) (две системы координат для дуплекса деления времени (TDD))
Демодулирует принятую форму волны
Оценивает канал
Компенсирует символы
Оценки и компенсируют общую ошибку фазы (CPE)
Задайте параметры конфигурации для hNRPDSCHEVM
функция.
cfg = struct(); cfg.PlotEVM = true; % Plot EVM statistics cfg.DisplayEVM = true; % Print EVM statistics cfg.Label = nrtm; % Set to TM name of captured waveform cfg.SampleRate = captureSampleRate; % Use sample rate during capture [evmInfo,eqSym,refSym] = hNRPDSCHEVM(tmwavegen.Config,rxWaveform,cfg);
RMS EVM, Peak EVM, slot 0: 2.848 19.257% RMS EVM, Peak EVM, slot 1: 2.829 15.633% RMS EVM, Peak EVM, slot 2: 2.812 15.226% RMS EVM, Peak EVM, slot 3: 2.864 14.929% RMS EVM, Peak EVM, slot 4: 2.932 14.695% RMS EVM, Peak EVM, slot 5: 2.934 16.210% RMS EVM, Peak EVM, slot 6: 2.835 17.239% RMS EVM, Peak EVM, slot 7: 2.897 16.520% RMS EVM, Peak EVM, slot 8: 2.924 16.450% RMS EVM, Peak EVM, slot 9: 2.883 16.497% RMS EVM, Peak EVM, slot 10: 2.889 17.794% RMS EVM, Peak EVM, slot 11: 2.853 16.835% RMS EVM, Peak EVM, slot 12: 2.860 19.586% RMS EVM, Peak EVM, slot 13: 2.908 16.476% RMS EVM, Peak EVM, slot 14: 2.947 17.077% RMS EVM, Peak EVM, slot 15: 2.950 15.162% RMS EVM, Peak EVM, slot 16: 2.940 20.989% RMS EVM, Peak EVM, slot 17: 2.927 16.974% RMS EVM, Peak EVM, slot 18: 2.876 14.606% RMS EVM, Peak EVM, slot 19: 2.860 19.478% Averaged RMS EVM frame 0: 2.889% Averaged overall RMS EVM: 2.889% Overall Peak EVM = 20.9891%
Измерения показывают, что демодуляция принятой формы волны успешна. Интерференция от компонента DC спектра анализатор к поднесущей DC вызывает высокие значения EVM в измерениях.
Эти функции помогают в обработке полученной формы волны 5G.
function [correctedWaveform,appliedFrequencyCorrection] = DMRSFrequencyCorrection(waveform,sampleRate,frequencyCorrectionRange,tmwavegen,resourcesInfo) % waveform - Waveform to be corrected. Needs to be a Nx1 column vector. % sampleRate - Sample rate of waveform % frequencyCorrectioRange - Range and granularity at which frequency % correction is inspected % tmwavegen and resourcesInfo - Outputs of generateWaveform method [pdschArray,~,carrier] = hListTargetPDSCHs(tmwavegen.Config,resourcesInfo.WaveformResources); bwpCfg = tmwavegen.Config.BandwidthParts{1,1}; nSlots = carrier.SlotsPerFrame; % Generate a reference grid spanning 10 ms (one frame). This grid % contains only the DM-RS and is used for synchronization. refGrid = referenceGrid(carrier,bwpCfg,pdschArray,nSlots); % Apply frequency offsets to the waveform as specified by % freuqnecyCorrectionRange. nSamples = (0:length(waveform)-1)'; frequencyShift = (2*pi*frequencyCorrectionRange.*nSamples)./sampleRate; % Each column represents an offset waveform. offsetWaveforms = waveform.*exp(1j*frequencyShift); [~,mag] = nrTimingEstimate(offsetWaveforms,carrier.NSizeGrid,... carrier.SubcarrierSpacing,nSlots,refGrid, ... "SampleRate",sampleRate); % Find the frequency at which the DM-RS correlation is at a maximum. [~,index] = max(max(mag)); appliedFrequencyCorrection = frequencyCorrectionRange(index); correctedWaveform = offsetWaveforms(:,index); end function refGrid = referenceGrid(carrier,bwpCfg,pdschArray,nSlots) % Create a reference grid for the required number of slots. The grid % contains the DM-RS symbols specified in pdschArray. The function % returns REFGRID of dimensions K-by-S-by-L, where K is the number of % subcarriers of size carrier.NSizeGrid, S is the number of symbols % spanning nSlots, and L is the number of layers. nSubcarriers = carrier.NSizeGrid * 12; L = carrier.SymbolsPerSlot*nSlots; % Number of OFDM symbols in the reference grid nLayers = size(pdschArray(1).Resources(1).ChannelIndices,2); bwpStart = bwpCfg.NStartBWP; bwpLen = bwpCfg.NSizeBWP; refGrid = zeros(nSubcarriers,L,nLayers); % Empty grid bwpGrid = zeros(bwpLen*12,L,nLayers); rbsPerSlot = bwpLen*12*carrier.SymbolsPerSlot; % Populate the DM-RS symbols in the reference grid for all slots. Place % bwpGrid in a carrier grid (at an appropriate location) in case the % BWP size is not the same as the carrier grid for slotIdx = carrier.NSlot + (0:nSlots-1) [~,~,dmrsIndices,dmrsSymbols] = hSlotResources(pdschArray,slotIdx); if ~isempty(dmrsIndices) for layerIdx = 1:nLayers if layerIdx <= size(dmrsIndices,2) dmrsIndices(:,layerIdx) = dmrsIndices(:,layerIdx) - rbsPerSlot*(layerIdx -1) + (L*bwpLen*12*(layerIdx-1)); bwpGrid(dmrsIndices(:,layerIdx)+(slotIdx-carrier.NSlot)*rbsPerSlot) = dmrsSymbols(:,layerIdx); end end refGrid(12*bwpStart+1:12*(bwpStart+bwpLen),:,:) = bwpGrid; end end end