Skip to content

Commit 4f7b0bc

Browse files
author
Xavier Arteaga
committedJan 16, 2025
Initial PRS generator test
1 parent a878f31 commit 4f7b0bc

File tree

3 files changed

+216
-0
lines changed

3 files changed

+216
-0
lines changed
 

‎+srsTest/listSRSblocks.m

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
'port_channel_estimator', 'phy/upper/signal_processors/';...
6363
'prach_detector', 'phy/upper/channel_processors/'; ...
6464
'prach_generator', 'phy/upper/channel_processors/'; ...
65+
'prs_generator', 'phy/upper/signal_processors/prs/'; ...
6566
'ptrs_pdsch_generator', 'phy/upper/signal_processors/ptrs/'; ...
6667
'pucch_demodulator_format2', 'phy/upper/channel_processors/pucch/'; ...
6768
'pucch_demodulator_format3', 'phy/upper/channel_processors/pucch/'; ...

‎runSRSRANUnittest.m

+2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ function mustBeSRSBlock(a)
131131
unittestClass = ?srsPRACHDetectorUnittest;
132132
case 'prach_generator'
133133
unittestClass = ?srsPRACHGeneratorUnittest;
134+
case 'prs_generator'
135+
unittestClass = ?srsPRSGeneratorUnittest;
134136
case 'ptrs_pdsch_generator'
135137
unittestClass = ?srsPDSCHPTRSGeneratorUnittest;
136138
case 'pucch_demodulator_format2'

‎srsPRSGeneratorUnittest.m

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
%srsPRSGeneratorUnittest Unit tests for PRS generator functions.
2+
% This class implements unit tests for the PRS generator functions using the
3+
% matlab.unittest framework. The simplest use consists in creating an object with
4+
% testCase = srsPRSGeneratorUnittest
5+
% and then running all the tests with
6+
% testResults = testCase.run
7+
%
8+
% srsPRSGeneratorUnittest Properties (Constant):
9+
%
10+
% srsBlock - The tested block (i.e., 'ptrs_pdsch_generator').
11+
% srsBlockType - The type of the tested block, including layer
12+
% (i.e., 'phy/upper/signal_processors/prs').
13+
%
14+
% srsPRSGeneratorUnittest Properties (ClassSetupParameter):
15+
%
16+
% outputPath - Path to the folder where the test results are stored.
17+
%
18+
% srsPRSGeneratorUnittest Properties (TestParameter):
19+
%
20+
% Numerology - Defines the subcarrier spacing (0, 1).
21+
% DurationAndCombSize - Combinations of duration and comb size.
22+
%
23+
% srsPRSGeneratorUnittest Methods (TestTags = {'testvector'}):
24+
%
25+
% testvectorGenerationCases - Generates a test vector according to the provided
26+
% parameters.
27+
%
28+
% srsPRSGeneratorUnittest Methods (Access = protected):
29+
%
30+
% addTestIncludesToHeaderFile - Adds include directives to the test header file.
31+
% addTestDefinitionToHeaderFile - Adds details (e.g., type/variable declarations)
32+
% to the test header file.
33+
%
34+
% See also matlab.unittest.
35+
36+
% Copyright 2021-2024 Software Radio Systems Limited
37+
%
38+
% This file is part of srsRAN-matlab.
39+
%
40+
% srsRAN-matlab is free software: you can redistribute it and/or
41+
% modify it under the terms of the BSD 2-Clause License.
42+
%
43+
% srsRAN-matlab is distributed in the hope that it will be useful,
44+
% but WITHOUT ANY WARRANTY; without even the implied warranty of
45+
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46+
% BSD 2-Clause License for more details.
47+
%
48+
% A copy of the BSD 2-Clause License can be found in the LICENSE
49+
% file in the top-level directory of this distribution.
50+
51+
classdef srsPRSGeneratorUnittest < srsTest.srsBlockUnittest
52+
properties (Constant)
53+
%Name of the tested block.
54+
srsBlock = 'prs_generator'
55+
56+
%Type of the tested block.
57+
srsBlockType = 'phy/upper/signal_processors/prs'
58+
59+
%Minimum bandwidth in PRB. Given in TS38.214 Section 5.1.6.5.
60+
MinNumRB = 24;
61+
62+
%Maximum bandwidth in PRB. Given in TS38.214 Section 5.1.6.5.
63+
MaxNumRB = 272;
64+
65+
%Bandwidth granularity in PRB. Given in TS38.214 Section 5.1.6.5.
66+
ResNumRB = 4;
67+
68+
end
69+
70+
properties (Hidden)
71+
randomizeTestvector
72+
end
73+
74+
properties (ClassSetupParameter)
75+
%Path to results folder (old 'ptrs_pdsch_generator' tests will be erased).
76+
outputPath = {['testPRS', char(datetime('now', 'Format', 'yyyyMMdd''T''HHmmss'))]}
77+
end
78+
79+
properties (TestParameter)
80+
%Numerology, defines the subcarrier spacing (15kHz and 30kHz).
81+
Numerology = {0, 1}
82+
83+
%Valid combinations of comb size and duration. Valid combinations
84+
%are given in TS38.211 Section 7.4.1.7.3.
85+
DurationAndCombSize = {[2, 2], [4, 2], [6, 2], [12, 2], [4, 4], [12, 4], [6, 6], [12, 6], [12, 12]}
86+
end
87+
88+
methods (Access = protected)
89+
function addTestIncludesToHeaderFile(~, fileID)
90+
%addTestIncludesToHeaderFile Adds include directives to the test header file.
91+
fprintf(fileID, '#include "srsran/phy/upper/signal_processors/prs/prs_generator.h"\n');
92+
fprintf(fileID, '#include "srsran/phy/upper/signal_processors/prs/prs_generator_configuration.h"\n');
93+
fprintf(fileID, '#include "srsran/support/file_vector.h"\n');
94+
fprintf(fileID, '#include "../../../support/resource_grid_test_doubles.h"\n');
95+
fprintf(fileID, '#include "srsran/ran/precoding/precoding_codebooks.h"\n');
96+
end
97+
98+
function addTestDefinitionToHeaderFile(~, fileID)
99+
%addTestDetailsToHeaderFile Adds details (e.g., type/variable declarations) to the test header file.
100+
fprintf(fileID, 'struct test_case_t {\n');
101+
fprintf(fileID, ' prs_generator_configuration config;\n');
102+
fprintf(fileID, ' file_vector<resource_grid_writer_spy::expected_entry_t> symbols;\n');
103+
fprintf(fileID, '};\n');
104+
end
105+
106+
function initializeClassImpl(obj)
107+
obj.randomizeTestvector = randperm(1008);
108+
end
109+
end % of methods (Access = protected)
110+
111+
methods (Test, TestTags = {'testvector'})
112+
function testvectorGenerationCases(testCase, Numerology, DurationAndCombSize)
113+
%testvectorGenerationCases Generates a test vector for the given Numerology,
114+
% NumLayers, FrequencyDensity, TimeDensity, and
115+
% REOffset. Other parameters are selected randomly.
116+
117+
import srsTest.helpers.cellarray2str
118+
import srsTest.helpers.writeResourceGridEntryFile
119+
import srsTest.helpers.symbolAllocationMask2string
120+
import srsTest.helpers.RBallocationMask2string
121+
122+
% Derive test parameters.
123+
subcarrierSpacing = 15 * pow2(Numerology);
124+
numPRSSymbols = DurationAndCombSize(1);
125+
combSize = DurationAndCombSize(2);
126+
127+
% Generate a unique test ID.
128+
testID = testCase.generateTestID;
129+
130+
% Grid size, use maximum.
131+
nSizeGrid = 272;
132+
133+
% Select random parameters.
134+
NCellID = randi([0, 504]);
135+
REOffset = randi([0 combSize - 1]);
136+
numRB = randi([testCase.MinNumRB / testCase.ResNumRB, ...
137+
testCase.MaxNumRB / testCase.ResNumRB]) * testCase.ResNumRB;
138+
symbolStart = randi([0, 14 - numPRSSymbols]);
139+
RBOffset = randi([0, nSizeGrid - numRB]);
140+
NPRSID = randi([0 4095]);
141+
nSlot = randi([0 (10 * pow2(Numerology) - 1)]);
142+
nFrame = randi([0 1023]);
143+
amplitude = 10 * (rand() + 1);
144+
nStartGrid = randi([0, 2176 - numRB - RBOffset]);
145+
146+
% Fix parameters.
147+
cyclicPrefix = 'normal';
148+
149+
% Prepare carrier configuration.
150+
carrier = nrCarrierConfig( ...
151+
NCellID=NCellID,...
152+
SubcarrierSpacing=subcarrierSpacing,...
153+
CyclicPrefix=cyclicPrefix,...
154+
NSizeGrid=nSizeGrid,...
155+
NStartGrid=nStartGrid,...
156+
NSlot=nSlot,...
157+
NFrame=nFrame);
158+
159+
% Prepare PRS configuration.
160+
PRS = nrPRSConfig(...
161+
NumPRSSymbols=numPRSSymbols,...
162+
SymbolStart=symbolStart,...
163+
NumRB=numRB,...
164+
RBOffset=RBOffset,...
165+
CombSize=combSize,...
166+
REOffset=REOffset,...
167+
NPRSID=NPRSID);
168+
169+
% Call the PRS symbol processor MATLAB functions.
170+
symbols = nrPRS(carrier, PRS);
171+
indices = nrPRSIndices(carrier, PRS, ...
172+
IndexStyle='subscript', IndexBase='0based');
173+
174+
% Write each complex symbol along with their associated indices to
175+
% a binary file.
176+
testCase.saveDataFile('_test_output', testID, ...
177+
@writeResourceGridEntryFile, amplitude * symbols, indices);
178+
179+
% Convert parameters to srsRAN types.
180+
slotPointStr = cellarray2str({Numerology, nFrame, ...
181+
floor(nSlot / carrier.SlotsPerSubframe), ...
182+
rem(nSlot, carrier.SlotsPerSubframe)}, true);
183+
cyclicPrefixStr = ['cyclic_prefix::' upper(cyclicPrefix)];
184+
combSizeStr = ['static_cast<prs_comb_size>(' num2str(combSize) ')'];
185+
durationStr = ['static_cast<prs_num_symbols>(' num2str(numPRSSymbols) ')'];
186+
rbStart = carrier.NStartGrid + PRS.RBOffset;
187+
freqAllocConfig = cellarray2str({PRS.RBOffset, PRS.RBOffset + PRS.NumRB}, true);
188+
powerOffsetdB = 20 * log10(amplitude);
189+
precodingStr = 'precoding_configuration::make_wideband(make_identity(1))';
190+
191+
configCell = {...
192+
slotPointStr, ... % slot
193+
cyclicPrefixStr, ... % cyclic_prefix
194+
PRS.NPRSID, ... % n_id_prs
195+
combSizeStr, ... % comb_size
196+
REOffset, ... % comb_offset
197+
durationStr, ... % duration
198+
symbolStart, ... % start_symbol
199+
rbStart, ... % prb_start
200+
freqAllocConfig, ... % freq_alloc
201+
powerOffsetdB, ... % power_offset_dB
202+
precodingStr ... % precoding
203+
};
204+
205+
% Generate the test case entry.
206+
testCaseString = testCase.testCaseToString(testID, configCell, ...
207+
true, '_test_output');
208+
209+
% Add the test to the file header.
210+
testCase.addTestToHeaderFile(testCase.headerFileID, testCaseString);
211+
end % of function testvectorGenerationCases
212+
end % of methods (Test, TestTags = {'testvector'})
213+
end % of classdef srsPRSGeneratorUnittest

0 commit comments

Comments
 (0)
Please sign in to comment.