ACS Test Waveform Generation for 5G NR Receiver Testing
This example provides a framework that enables you to generate a waveform for the adjacent channel selectivity (ACS) receiver test, as specified in TS 38.141-1, Section 7.4.1, to test a 5G NR receiver. The framework provides a simplified receiver model for the test. However, you can replace this simplified model by an arbitrary receiver model that measures throughput and EVM.
Introduction
The aim of this example is to provide a framework for you to simulate the ACS test on your receiver model. To illustrate the workflow, the example provides a simplified receiver model that you can replace with your receiver model under test.
The ACS test requires a reference measurement channel, as a signal of interest, and an interference in an adjacent frequency. The example generates these waveforms at an oversampled rate , where is the oversampling ratio and is the nominal sampling rate of the signal of interest. The example then uses the simplified receiver model to measure the EVM and throughput of the received signal. To pass the test, the receiver under tests must have a throughput greater than or equal to 95% of the maximum throughput of the reference measurement channel.
Set Waveform Parameters
Select a reference measurement channel from TS 38.141-1, Table 7.2.5-1. The example displays the valid bandwidth and subcarrier spacing values for the selected reference channel.
signalDefinition.ulnrref = "G-FR1-A1-1";
ACSTestExampleHelpers.displayBWSCS(signalDefinition.ulnrref)
Possible BW for G-FR1-A1-1: [5 10 15] (MHz) Possible SCS for G-FR1-A1-1: 15 (kHz)
Specify the bandwidth and subcarrier spacing.
signalDefinition.BW = 5; % Bandwidth (MHz) signalDefinition.SCS = 15; % Subcarrier spacing (kHz)
Specify the value of reference sensitivity power level (Prefsens) in dBm. Prefsens is a function of the reference measurement channel and the carrier frequency for a wide area base station, as defined in TS 38.141-1, Table 7.2.5-1.
ACSTestExampleHelpers.displayValidSensitivityPowerLevels();
Ref. channel Prefsens (dBm) f<=3 GHz Prefsens (dBm) 3 GHz<f<=4.2 GHz Prefsens (dBm) 4.2<f<=6 GHz ____________ _______________________ _______________________________ ___________________________ "G-FR1-A1-1" -101 -100.7 -100.5 "G-FR1-A1-2" -101.1 -100.8 -100.6 "G-FR1-A1-3" -98.2 -97.9 -97.7 "G-FR1-A1-4" -94.6 -94.3 -94.1 "G-FR1-A1-5" -94.9 -94.6 -94.4 "G-FR1-A1-6" -95 -94.7 -94.5
signalDefinition.Prefsens = -101; % dBm
Specify the duplexing mode and the resource block (RB) allocation offset.
signalDefinition.dm = "FDD"; % Duplexing mode signalDefinition.rbOffset = 0; % RB offset (allocation offset) ACSTestExampleHelpers.validateParameters(signalDefinition);
Reference measurement channel: G-FR1-A1-1 Modulation: QPSK Bandwidth (RBs): 25 Allocated RBs: 25 RB offset: 0
Specify the simulation length in number of frames to calculate the throughput.
simulationLengthInFrames = 5; % Number of frames to simulate
Calculate Sampling Rate
Calculate the sampling rate of the signal of interest and the interference. Both signals are sampled at the same rate, , before aggregation. is the oversampling ratio. is the nominal sampling rate of the signal of interest and is a function of the bandwidth and subcarrier spacing of the signal of interest.
Specify the oversampling ratio as a power of two. The filtering stages of the simplified receiver model requires the oversampling ratio to be at least 8. If necessary, adjust this value according to your receiver model.
N = 16; % Oversampling ratio
Calculate the sampling rate, . The calculateFs
helper function performs the following operations:
Checks that the bandwidth and subcarrier spacing combination is defined according to TS 38.101-1, Tables 5.3.2-1 and 5.3.2-2.
Checks that the oversampling ratio,
N
, is a power of two equal to or greater than 8.Calculates the nominal sampling rate of the signal of interest, , and checks that is sufficient to represent the aggregation of the signal of interest and the interference.
Calculates the center frequency offset of the interfering signal from the center of the signal of interest band,
iFoffset
, as specified in TS 38.141-1, Table 7.4.1.5-2.
[Fs,iFoffset] = ACSTestExampleHelpers.calculateFs(signalDefinition.BW,signalDefinition.SCS,N);
Fs = 122.88 MHz = 16*7.68 MHz Fs_nominal = 7.68 MHz BW = 5 MHz. iBW = 5 MHz iFoffset = 5.0025 MHz
Generate Signal of Interest and Interference
Generate the signal of interest at the sampling rate and with the required power.
rng("default") % Reset the random number generator numSubframes = 10*simulationLengthInFrames+1; % Add an extra subframe to allow for delay caused by filters [waveform,carrier,pusch,puschExt,frcResourceInfo] = ACSTestExampleHelpers.generateSignalOfInterest(signalDefinition,Fs,numSubframes); disp("Signal power: "+(10*log10(rms(waveform)^2)+30)+" dBm")
Signal power: -95 dBm
Generate the interfering signal, as defined in TS 38.141-1, Table 7.4.1.5-2. This interference has the same sampling rate and length as the signal of interest.
powerInterf = ACSTestExampleHelpers.getInterferencePowerLevel(); [interfWaveform,interfDefinition]= ACSTestExampleHelpers.generateInterference(signalDefinition.BW,numSubframes,Fs,powerInterf); disp("Interference power: "+(10*log10(rms(interfWaveform)^2)+30)+" dBm")
Interference power: -52 dBm
Combine Signal of Interest and Interference
Use the multiband combiner to apply a frequency offset to the interfering signal. Then add the interfering signal to the signal of interest. Both signals are sampled at the same rate of Hz.
sigAggregator = comm.MultibandCombiner(InputSampleRate = Fs, ... FrequencyOffsets = [0 iFoffset], OutputSampleRateSource = 'Property', ... OutputSampleRate = Fs); aggregatedWaveform = sigAggregator([waveform interfWaveform]); % Plot spectrum of aggreggated signal saCombined = spectrumAnalyzer("SampleRate",Fs,"Title","Aggregated Waveform"); saCombined(aggregatedWaveform);
Simplified Receiver Model
The simplified receiver model of this example adds thermal noise, then performs the filtering and resampling stages. The sampling rate of the resulting signal is .
The digital front-end model includes:
Two cascaded identical halfband filters to decrease the sampling rate by a factor of 4.
FIR lowpass filter to decrease the sampling rate to .
You can replace this simplified model by your receiver model and study the effect the receiver has on the throughput and EVM of the decoded signal.
Design the receiver filters.
[halfbandDecimator1,halfbandDecimator2,firFilter] = ACSTestExampleHelpers.designFilters(carrier,Fs,interfDefinition,iFoffset);
Display the FIR filter response.
filterAnalyzer(firFilter,SampleRates=Fs/4,FilterNames="FIR", Analysis="magnitude",OverlayAnalysis="phase")
Create the thermal noise object and apply noise to the received signal.
noiseFloor = comm.ThermalNoise("NoiseMethod","Noise temperature","NoiseTemperature",290,"SampleRate",Fs); rxWaveform = noiseFloor(aggregatedWaveform);
Apply halfband filters and visualize the spectrum of the resulting signal.
filteredWaveform = halfbandDecimator1(rxWaveform); filteredWaveform = halfbandDecimator2(filteredWaveform); % Spectrum analyzer to visualize output of halfband filters saHalfBand = spectrumAnalyzer("SampleRate",Fs/4,"Title","Halfband Filters Output"); saHalfBand(filteredWaveform);
Apply FIR filtering and visualize the spectrum of the resampled signal.
% FIR filering and resampling stage filteredWaveform = resample(filteredWaveform,1,N/4,firFilter.Numerator); % Normalise received signal filteredWaveform = filteredWaveform/(rms(filteredWaveform)); % Spectrum analyzer to visualize output of FIR filter saResampled = spectrumAnalyzer("SampleRate",Fs/N,"Title","Resampled Signal"); % Plot spectrum of filtered signal saResampled(filteredWaveform);
Synchronize and apply OFDM demodulation.
% Synchronize timingOffset = nrTimingEstimate(carrier,filteredWaveform,frcResourceInfo.ResourceGrids.ResourceGridBWP,"SampleRate",Fs/N); filteredWaveform = filteredWaveform(1+timingOffset:end,:); % OFDM Demodulation carrier.NFrame = 0; carrier.NSlot = 0; rxGrid = nrOFDMDemodulate(carrier,filteredWaveform,"SampleRate",Fs/N);
Decode all slots, then measure the throughput and the EVM of the received signal.
% Number of symbols per slot symPerSlot = frcResourceInfo.ResourceGrids.Info.SymbolsPerSlot; % Number of slots in signal of interest, ignore the last slot as it may not % be complete due to delay in the filters numSlots = numSubframes*frcResourceInfo.ResourceGrids.Info.SlotsPerSubframe-1; % Create DL-SCH object decodeULSCH = nrULSCHDecoder; decodeULSCH.TargetCodeRate = puschExt.TargetCodeRate; decodeULSCH.LDPCDecodingAlgorithm = 'Normalized min-sum'; % Initialize variables and storage txedTrBlkSizes = []; % Vector of transport block sizes slotThPut = []; % Instantaneous throughput per slot runningSimThPut = nan(1,numSlots); % Accumulated throughput per slot runningMaxThPut = nan(1,numSlots); % Accumulated maximum throughput per slot symIdx = 1; % OFDM symbol index % EVM object evm = comm.EVM(); evmV = []; % vector of EVM values % List of active slots for TDD activeSlots = [frcResourceInfo.WaveformResources.PUSCH.Resources.NSlot]; % Process all slots, skip the last slot, it may not be complete due to delay in the filters for slotNum = 0:numSlots-1 % Extract slot of interest gridSlot = rxGrid(:,symIdx:symIdx+symPerSlot-1,:); if any(activeSlots == slotNum) % skip inactive slots carrier.NSlot = slotNum; % new slot number % DM-RS and PUSCH resources for current slot (used for channel estimation) resIdx = find(activeSlots == slotNum); % resources index dmrsIndices = frcResourceInfo.WaveformResources.PUSCH.Resources(resIdx).DMRSIndices; dmrsSymbols = frcResourceInfo.WaveformResources.PUSCH.Resources(resIdx).DMRSSymbols; puschIndices= frcResourceInfo.WaveformResources.PUSCH.Resources(resIdx).ChannelIndices; puschSymbols=frcResourceInfo.WaveformResources.PUSCH.Resources(resIdx).ChannelSymbols; trBlkSize = frcResourceInfo.WaveformResources.PUSCH.Resources(resIdx).TransportBlockSize; % Channel estimation [estChannelGrid,noiseEst] = nrChannelEstimate(carrier,gridSlot,dmrsIndices,dmrsSymbols,'CDMLengths',frcResourceInfo.WaveformResources.PUSCH.CDMLengths); % Get PDSCH resource elements from the received grid and channel estimate [puschRx,puschHest] = nrExtractResources(puschIndices,gridSlot,estChannelGrid); % Equalization [puschEq,csi] = nrEqualizeMMSE(puschRx,puschHest,noiseEst); % EVM measurement evmV = [evmV evm(puschEq,puschSymbols)]; % Decode PUSCH physical channel [ulschLLRs,rxSymbols] = nrPUSCHDecode(carrier,pusch,puschEq,noiseEst); % Appply csi (scale ulsch LLRs) csi = nrLayerDemap(csi); Qm = length(ulschLLRs) / length(rxSymbols); csi = reshape(repmat(csi{1}.',Qm,1),[],1); ulschLLRs = ulschLLRs .* csi; % Decode the UL-SCH transport channel decodeULSCH.TransportBlockLength = trBlkSize; [decbits,blkerr] = decodeULSCH(ulschLLRs,pusch.Modulation,pusch.NumLayers,puschExt.RVSequence); decodeULSCH.resetSoftBuffer(); % No HARQ, reset buffer manually if blkerr disp("CRC error in slot: "+slotNum) end % Store results if any(trBlkSize) % only for slots with data txedTrBlkSizes = [txedTrBlkSizes trBlkSize]; slotThPut = [slotThPut trBlkSize.*(1-blkerr)]; end runningSimThPut(slotNum+1) = sum(slotThPut,2); runningMaxThPut(slotNum+1) = sum(txedTrBlkSizes,2); end % Update OFDM symbol index symIdx = symIdx+symPerSlot; end
Display Results
Plot the accumulated throughput and display the final throughput and EVM values.
% Plot running throughput figure; plot(runningSimThPut*100./runningMaxThPut,'.-') ylabel('Throughput (%)'); xlabel('Slot'); title('Throughput'); grid on; hold on idx1 = find(~isnan(runningSimThPut),1,'last'); idx2 = find(~isnan(runningMaxThPut),1,'last'); finalThroughput = runningSimThPut(idx1)*100./runningMaxThPut(idx2); plot([1 length(runningSimThPut)],finalThroughput*[1 1],'x:') legend("Throughput","Final throughput")
disp("Final throughput: "+finalThroughput+"%")
Final throughput: 100%
disp("EVM post equalization: "+evmV(end)+" %")
EVM post equalization: 32.424 %
The EVM degradation is primarily due to the aliasing of the interfering signal after filtering and resampling. However, the EVM degradation does not affect the overall throughput because the QPSK modulation of the signal of interest, combined with the LDPC decoding, ensures that the decoded signal is robust against errors.