@@ -59,8 +59,8 @@ static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs)
5959{
6060 // As per Section 6.4.1.4.3, the parameter \f$m_{SRS}\f$ = 0 is an index that, along with \f$C_{SRS}\f$, maps to the
6161 // bandwidth of the SRS resources.
62- constexpr uint8_t b_srs_0 = 0 ;
63- std::optional<srsran:: srs_configuration> srs_params = srs_configuration_get (c_srs, b_srs_0);
62+ constexpr uint8_t b_srs_0 = 0 ;
63+ std::optional<srs_configuration> srs_params = srs_configuration_get (c_srs, b_srs_0);
6464 srsran_sanity_check (srs_params.has_value () and nof_ul_rbs >= srs_params.value ().m_srs ,
6565 " The SRS configuration is not valid" );
6666
@@ -70,14 +70,13 @@ static unsigned compute_freq_shift(unsigned c_srs, unsigned nof_ul_rbs)
7070static bool is_ul_slot (unsigned offset, const tdd_ul_dl_config_common& tdd_cfg)
7171{
7272 const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe (tdd_cfg.ref_scs ));
73- return srsran::get_active_tdd_ul_symbols (tdd_cfg, slot_index, cyclic_prefix::NORMAL). length () != 0 ;
73+ return has_active_tdd_ul_symbols (tdd_cfg, slot_index) ;
7474}
7575
76- static bool is_partually_ul_slot (unsigned offset, const tdd_ul_dl_config_common& tdd_cfg)
76+ static bool is_partially_ul_slot (unsigned offset, const tdd_ul_dl_config_common& tdd_cfg)
7777{
78- const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe (tdd_cfg.ref_scs ));
79- const unsigned nof_symbols = srsran::get_active_tdd_ul_symbols (tdd_cfg, slot_index, cyclic_prefix::NORMAL).length ();
80- return nof_symbols != 0 and nof_symbols != NOF_OFDM_SYM_PER_SLOT_NORMAL_CP;
78+ const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe (tdd_cfg.ref_scs ));
79+ return is_tdd_partial_ul_slot (tdd_cfg, slot_index);
8180}
8281
8382// Helper that updates the starting SRS config with user-defined parameters.
@@ -120,6 +119,8 @@ du_srs_policy_max_ul_rate::cell_context::cell_context(const du_cell_config& cfg)
120119du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate (span<const du_cell_config> cell_cfg_list_) :
121120 cells(cell_cfg_list_.begin(), cell_cfg_list_.end())
122121{
122+ static constexpr unsigned primary_cell_index = 0U ;
123+
123124 for (auto & cell : cells) {
124125 if (not cell.cell_cfg .srs_cfg .srs_period .has_value ()) {
125126 continue ;
@@ -139,6 +140,7 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span<const du_cell_config>
139140
140141 const auto srs_period_slots = static_cast <unsigned >(cell.cell_cfg .srs_cfg .srs_period .value ());
141142 // Reserve the size of the vector and set the SRS counter of each offset to 0.
143+ cell.slot_resource_cnt .reserve (srs_period_slots);
142144 cell.slot_resource_cnt .assign (srs_period_slots, 0U );
143145 cell.srs_res_offset_free_list .reserve (du_srs_policy_max_ul_rate::cell_context::max_nof_srs_res);
144146 cell.nof_res_per_symb_interval = static_cast <unsigned >(cell.cell_cfg .srs_cfg .tx_comb ) *
@@ -152,42 +154,33 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span<const du_cell_config>
152154 }
153155
154156 // Verify whether the offset maps to a partially- or fully-UL slot.
155- if (cell_cfg_list_[0 ].tdd_ul_dl_cfg_common .has_value () and
156- not is_ul_slot (offset, cell_cfg_list_[0 ].tdd_ul_dl_cfg_common .value ())) {
157+ if (cell_cfg_list_[primary_cell_index ].tdd_ul_dl_cfg_common .has_value () and
158+ not is_ul_slot (offset, cell_cfg_list_[primary_cell_index ].tdd_ul_dl_cfg_common .value ())) {
157159 continue ;
158160 }
159161
160162 for (auto & res : cell.cell_srs_res_list ) {
161163 // Handle TDD and FDD configurations separately, as we treat partially-UL slots differently from
162164 // fully-UL slots.
163- if (cell_cfg_list_[0 ].tdd_ul_dl_cfg_common .has_value ()) {
164- const auto & tdd_cfg = cell_cfg_list_[0 ].tdd_ul_dl_cfg_common .value ();
165- // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the
165+ if (cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common .has_value () and
166+ is_partially_ul_slot (offset, cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common .value ())) {
167+ // For partially-UL slots, we need to check if the SRS can be placed in the UL symbols of the slot.
168+ const auto & tdd_cfg = cell_cfg_list_[primary_cell_index].tdd_ul_dl_cfg_common .value ();
169+ const unsigned slot_index = offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe (tdd_cfg.ref_scs ));
170+ // As per Section 6.4.1.4.1, TS 38.211, the SRS resources can only be placed in the last 6 symbols of the
166171 // slot.
167- if (is_partually_ul_slot (offset, cell_cfg_list_[0 ].tdd_ul_dl_cfg_common .value ())) {
168- const unsigned slot_index =
169- offset % (NOF_SUBFRAMES_PER_FRAME * get_nof_slots_per_subframe (tdd_cfg.ref_scs ));
170- // As per Section 6.4.1.4.1, TS 38.211, the SRS resources can only be placed in the last 6 symbols of the
171- // slot.
172- static constexpr unsigned max_srs_symbols = 6U ;
173- const unsigned nof_ul_symbols_for_srs =
174- std::min (srsran::get_active_tdd_ul_symbols (tdd_cfg, slot_index, cyclic_prefix::NORMAL).length (),
175- max_srs_symbols);
176- if (res.symbols .start () < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_ul_symbols_for_srs) {
177- continue ;
178- }
179- }
180- // This is the fully-UL slot case: check if the SRS can be placed in the UL symbols of the slot.
181- else if (res.symbols .start () <
182- NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell.cell_cfg .srs_cfg .max_nof_symbols .to_uint ()) {
172+ static constexpr unsigned max_srs_symbols = 6U ;
173+ const unsigned nof_ul_symbols_for_srs =
174+ std::min (get_active_tdd_ul_symbols (tdd_cfg, slot_index, cyclic_prefix::NORMAL).length (), max_srs_symbols);
175+ if (res.symbols .start () < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - nof_ul_symbols_for_srs) {
183176 continue ;
184177 }
185178 }
186- // FDD case .
187- else {
188- if (res.symbols .start () < NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell. cell_cfg . srs_cfg . max_nof_symbols . to_uint ()) {
189- continue ;
190- }
179+ // NOTE: for TDD, the offset that are not UL slots are skipped above .
180+ // FDD case and TDD case for fully-UL slot.
181+ else if (res.symbols .start () <
182+ NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - cell. cell_cfg . srs_cfg . max_nof_symbols . to_uint ()) {
183+ continue ;
191184 }
192185 cell.srs_res_offset_free_list .emplace_back (res.cell_res_id , offset);
193186 }
@@ -197,48 +190,50 @@ du_srs_policy_max_ul_rate::du_srs_policy_max_ul_rate(span<const du_cell_config>
197190
198191bool du_srs_policy_max_ul_rate::alloc_resources (cell_group_config& cell_grp_cfg)
199192{
193+ static constexpr unsigned primary_cell_index = 0U ;
194+
200195 // TODO: Adapt this to the case of UEs with multiple cells configs.
201- srsran_assert (
202- cells[cell_grp_cfg. cells [ 0 ]. serv_cell_cfg . cell_index ] .cell_cfg .ue_ded_serv_cell_cfg .ul_config .has_value () and
203- not cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .has_value (),
204- " UE UL config should be non-empty but with an empty SRS config" );
196+ srsran_assert (cells[cell_grp_cfg. cells [primary_cell_index]. serv_cell_cfg . cell_index ]
197+ .cell_cfg .ue_ded_serv_cell_cfg .ul_config .has_value () and
198+ not cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .has_value (),
199+ " UE UL config should be non-empty but with an empty SRS config" );
205200
206- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .emplace (
207- cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].default_srs_cfg );
201+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .emplace (
202+ cells[cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .cell_index ].default_srs_cfg );
208203
209204 // If periodic SRS is not enabled, don't allocate anything and exit with success.
210- if (not cells[0 ].cell_cfg .srs_cfg .srs_period .has_value ()) {
205+ if (not cells[primary_cell_index ].cell_cfg .srs_cfg .srs_period .has_value ()) {
211206 return true ;
212207 }
213208
214209 // The UE SRS configuration is taken from a base configuration, saved in the GNB. The UE specific parameters will be
215210 // added later on in this function.
216- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .emplace (
217- cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].default_srs_cfg );
218- srs_config& ue_srs_cfg = cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .value ();
219- auto & free_srs_list = cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].srs_res_offset_free_list ;
211+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .emplace (
212+ cells[cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .cell_index ].default_srs_cfg );
213+ srs_config& ue_srs_cfg = cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .value ();
214+ auto & free_srs_list = cells[cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .cell_index ].srs_res_offset_free_list ;
220215
221216 // Verify where there are SRS resources to allocate a new UE.
222217 if (free_srs_list.empty ()) {
223218 // If the allocation failed, reset the SRS configuration.
224- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
219+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
225220 return false ;
226221 }
227222
228223 // Find the best resource ID and offset for this UE, according to the class policy.
229- auto srs_res_id_offset = cells[0 ].find_optimal_ue_srs_resource ();
224+ auto srs_res_id_offset = cells[primary_cell_index ].find_optimal_ue_srs_resource ();
230225
231226 if (srs_res_id_offset == free_srs_list.end ()) {
232227 // If the allocation failed, reset the SRS configuration.
233- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
228+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
234229 return false ;
235230 }
236231
237- const auto & du_res_it = cells[0 ].get_du_srs_res_cfg (srs_res_id_offset->first );
232+ const auto & du_res_it = cells[primary_cell_index ].get_du_srs_res_cfg (srs_res_id_offset->first );
238233
239- if (du_res_it == cells[0 ].cell_srs_res_list .end ()) {
234+ if (du_res_it == cells[primary_cell_index ].cell_srs_res_list .end ()) {
240235 // If the allocation failed, reset the SRS configuration.
241- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
236+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
242237 return false ;
243238 }
244239
@@ -250,12 +245,13 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg)
250245 // NOTE: given that there is only 1 SRS resource per UE, we can assume that the SRS resource ID is 0.
251246 only_ue_srs_res.id .cell_res_id = du_res.cell_res_id ;
252247 only_ue_srs_res.id .ue_res_id = static_cast <srs_config::srs_res_id>(0U );
253- srsran_assert (cells[0 ].cell_cfg .ul_carrier .nof_ant == 1 or cells[0 ].cell_cfg .ul_carrier .nof_ant == 2 or
254- cells[0 ].cell_cfg .ul_carrier .nof_ant == 4 ,
248+ srsran_assert (cells[primary_cell_index].cell_cfg .ul_carrier .nof_ant == 1 or
249+ cells[primary_cell_index].cell_cfg .ul_carrier .nof_ant == 2 or
250+ cells[primary_cell_index].cell_cfg .ul_carrier .nof_ant == 4 ,
255251 " The number of UL antenna ports is not valid" );
256252 only_ue_srs_res.nof_ports =
257- static_cast <srs_config::srs_resource::nof_srs_ports>(cells[0 ].cell_cfg .ul_carrier .nof_ant );
258- only_ue_srs_res.tx_comb .size = cells[0 ].cell_cfg .srs_cfg .tx_comb ;
253+ static_cast <srs_config::srs_resource::nof_srs_ports>(cells[primary_cell_index ].cell_cfg .ul_carrier .nof_ant );
254+ only_ue_srs_res.tx_comb .size = cells[primary_cell_index ].cell_cfg .srs_cfg .tx_comb ;
259255 only_ue_srs_res.tx_comb .tx_comb_offset = du_res.tx_comb_offset .to_uint ();
260256 only_ue_srs_res.tx_comb .tx_comb_cyclic_shift = du_res.cs ;
261257 only_ue_srs_res.freq_domain_pos = du_res.freq_dom_position ;
@@ -264,16 +260,18 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg)
264260 only_ue_srs_res.sequence_id = du_res.sequence_id ;
265261
266262 // Update the SRS configuration with the parameters that are common to the cell.
267- only_ue_srs_res.freq_hop .c_srs = cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].srs_common_params .c_srs ;
263+ only_ue_srs_res.freq_hop .c_srs =
264+ cells[cell_grp_cfg.cells [primary_cell_index].serv_cell_cfg .cell_index ].srs_common_params .c_srs ;
268265 // We assume that the frequency hopping is disabled and that the SRS occupies all possible RBs within the BWP. Refer
269266 // to Section 6.4.1.4.3, TS 38.211.
270267 only_ue_srs_res.freq_hop .b_srs = 0U ;
271268 only_ue_srs_res.freq_hop .b_hop = 0U ;
272269 only_ue_srs_res.freq_domain_shift =
273- cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].srs_common_params .freq_shift ;
270+ cells[cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .cell_index ].srs_common_params .freq_shift ;
274271
275- only_ue_srs_res.periodicity_and_offset .emplace (srs_config::srs_periodicity_and_offset{
276- .period = cells[0 ].cell_cfg .srs_cfg .srs_period .value (), .offset = static_cast <uint16_t >(srs_offset)});
272+ only_ue_srs_res.periodicity_and_offset .emplace (
273+ srs_config::srs_periodicity_and_offset{.period = cells[primary_cell_index].cell_cfg .srs_cfg .srs_period .value (),
274+ .offset = static_cast <uint16_t >(srs_offset)});
277275
278276 // Update the SRS resource set with the SRS id.
279277 ue_srs_cfg.srs_res_set_list .front ().srs_res_id_list .front () = only_ue_srs_res.id .ue_res_id ;
@@ -282,12 +280,12 @@ bool du_srs_policy_max_ul_rate::alloc_resources(cell_group_config& cell_grp_cfg)
282280 free_srs_list.erase (srs_res_id_offset);
283281
284282 // Update the SRS resource per slot counter.
285- ++cells[0 ].slot_resource_cnt [srs_offset];
283+ ++cells[primary_cell_index ].slot_resource_cnt [srs_offset];
286284
287285 return true ;
288286}
289287
290- std::vector<std::pair< unsigned , unsigned > >::const_iterator
288+ std::vector<du_srs_policy_max_ul_rate::cell_context::pair_res_id_offset >::const_iterator
291289du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource ()
292290{
293291 // The weights assigned here can be set to arbitrarily value, as long as:
@@ -301,7 +299,7 @@ du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource()
301299
302300 const auto weight_function = [&](const pair_res_id_offset& srs_res) {
303301 if (cell_cfg.tdd_ul_dl_cfg_common .has_value () and
304- is_partually_ul_slot (srs_res.second , cell_cfg.tdd_ul_dl_cfg_common .value ())) {
302+ is_partially_ul_slot (srs_res.second , cell_cfg.tdd_ul_dl_cfg_common .value ())) {
305303 return 0U ;
306304 }
307305
@@ -338,24 +336,27 @@ du_srs_policy_max_ul_rate::cell_context::find_optimal_ue_srs_resource()
338336
339337void du_srs_policy_max_ul_rate::dealloc_resources (cell_group_config& cell_grp_cfg)
340338{
341- if (not cells[0 ].cell_cfg .srs_cfg .srs_period .has_value () or
342- not cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .has_value ()) {
339+ static constexpr unsigned primary_cell_index = 0U ;
340+
341+ if (not cells[primary_cell_index].cell_cfg .srs_cfg .srs_period .has_value () or
342+ not cell_grp_cfg.cells [primary_cell_index].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .has_value ()) {
343343 return ;
344344 }
345345
346- const auto & ue_srs_cfg = cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .value ();
347- auto & free_srs_list = cells[cell_grp_cfg.cells [0 ].serv_cell_cfg .cell_index ].srs_res_offset_free_list ;
346+ const auto & ue_srs_cfg = cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .value ();
347+ auto & free_srs_list = cells[cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .cell_index ].srs_res_offset_free_list ;
348348
349349 for (const auto & srs_res : ue_srs_cfg.srs_res_list ) {
350350 const unsigned offset_to_deallocate = srs_res.periodicity_and_offset .value ().offset ;
351351 free_srs_list.emplace_back (srs_res.id .cell_res_id , offset_to_deallocate);
352352
353353 // Update the used_not_full slot vector.
354- srsran_assert (cells[0 ].slot_resource_cnt [offset_to_deallocate] != 0 , " The offset is expected to be non-zero" );
355- --cells[0 ].slot_resource_cnt [offset_to_deallocate];
354+ srsran_assert (cells[primary_cell_index].slot_resource_cnt [offset_to_deallocate] != 0 ,
355+ " The offset is expected to be non-zero" );
356+ --cells[primary_cell_index].slot_resource_cnt [offset_to_deallocate];
356357 }
357358
358359 // Reset the SRS configuration in this UE. This makes sure the DU will exit this function immediately when it gets
359360 // called again for the same UE (upon destructor's call).
360- cell_grp_cfg.cells [0 ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
361+ cell_grp_cfg.cells [primary_cell_index ].serv_cell_cfg .ul_config ->init_ul_bwp .srs_cfg .reset ();
361362}
0 commit comments