1515#include " srsran/ran/pucch/pucch_mapping.h"
1616#include " srsran/ran/resource_allocation/ofdm_symbol_range.h"
1717#include " srsran/ran/resource_allocation/rb_interval.h"
18+ #include < algorithm>
1819
1920using namespace srsran ;
2021
@@ -133,8 +134,44 @@ struct resource_info {
133134 }
134135};
135136
137+ // / \brief Represents a multiplexing region of PUCCH resources.
138+ // / Contains parameters that all resources in the region have in common.
139+ struct mux_region {
140+ // / Time-frequency grants of the region.
141+ time_freq_grants grants;
142+ // / PUCCH format of the region.
143+ pucch_format format;
144+
145+ // / Check if a a given resource belongs to this multiplexing region.
146+ bool does_resource_belong (const resource_info& res) const { return res.format == format and res.grants == grants; }
147+ };
148+
136149} // namespace
137150
151+ // / Collects all PUCCH resources (common + dedicated) from the cell configuration.
152+ static static_vector<resource_info, pucch_collision_manager::max_nof_cell_resources>
153+ get_all_resources (const cell_configuration& cell_cfg)
154+ {
155+ // Get the parameter N_bwp_size, which is the Initial UL BWP size in PRBs, as per TS 38.213, Section 9.2.1.
156+ const unsigned size_ul_bwp = cell_cfg.ul_cfg_common .init_ul_bwp .generic_params .crbs .length ();
157+
158+ // Get PUCCH common resource config from Table 9.2.1-1, TS 38.213.
159+ const pucch_default_resource common_default_res = get_pucch_default_resource (
160+ cell_cfg.ul_cfg_common .init_ul_bwp .pucch_cfg_common ->pucch_resource_common , size_ul_bwp);
161+
162+ // Collect all resources (common + dedicated).
163+ static_vector<resource_info, pucch_collision_manager::max_nof_cell_resources> all_resources;
164+ for (unsigned r_pucch = 0 ; r_pucch != pucch_collision_manager::nof_common_res; ++r_pucch) {
165+ all_resources.push_back (resource_info (common_default_res, r_pucch, size_ul_bwp));
166+ }
167+ for (const auto & res : cell_cfg.ded_pucch_resources ) {
168+ all_resources.push_back (resource_info (res));
169+ }
170+
171+ return all_resources;
172+ }
173+
174+ // / Checks if two PUCCH resources collide.
138175static bool do_resources_collide (const resource_info& res1, const resource_info& res2)
139176{
140177 if (not res1.grants .overlaps (res2.grants )) {
@@ -160,6 +197,7 @@ static bool do_resources_collide(const resource_info& res1, const resource_info&
160197pucch_collision_manager::pucch_collision_manager (const cell_configuration& cell_cfg_) :
161198 cell_cfg(cell_cfg_),
162199 collision_matrix(compute_collisions(cell_cfg)),
200+ mux_matrix(compute_mux_regions(cell_cfg)),
163201 slots_ctx({bounded_bitset<max_nof_cell_resources>(nof_common_res + cell_cfg.ded_pucch_resources .size ())})
164202{
165203}
@@ -272,33 +310,19 @@ void pucch_collision_manager::free_ded(slot_point sl, unsigned cell_res_id)
272310pucch_collision_manager::collision_matrix_t
273311pucch_collision_manager::compute_collisions (const cell_configuration& cell_cfg)
274312{
275- collision_matrix_t matrix (
276- nof_common_res + cell_cfg.ded_pucch_resources .size (),
277- bounded_bitset<max_nof_cell_resources>(nof_common_res + cell_cfg.ded_pucch_resources .size ()));
278-
279- // Get the parameter N_bwp_size, which is the Initial UL BWP size in PRBs, as per TS 38.213, Section 9.2.1.
280- const unsigned size_ul_bwp = cell_cfg.ul_cfg_common .init_ul_bwp .generic_params .crbs .length ();
281-
282- // Get PUCCH common resource config from Table 9.2.1-1, TS 38.213.
283- const pucch_default_resource common_default_res = get_pucch_default_resource (
284- cell_cfg.ul_cfg_common .init_ul_bwp .pucch_cfg_common ->pucch_resource_common , size_ul_bwp);
313+ const unsigned nof_res = nof_common_res + cell_cfg.ded_pucch_resources .size ();
314+ collision_matrix_t matrix (nof_res, bounded_bitset<max_nof_cell_resources>(nof_res));
285315
286316 // Collect all resources (common + dedicated).
287- static_vector<resource_info, max_nof_cell_resources> all_resources;
288- for (unsigned r_pucch = 0 ; r_pucch != nof_common_res; ++r_pucch) {
289- all_resources.push_back (resource_info (common_default_res, r_pucch, size_ul_bwp));
290- }
291- for (const auto & res : cell_cfg.ded_pucch_resources ) {
292- all_resources.push_back (resource_info (res));
293- }
317+ static_vector<resource_info, max_nof_cell_resources> all_resources = get_all_resources (cell_cfg);
294318
295319 // Precompute the collision matrix.
296- for (size_t i = 0 ; i != all_resources. size () ; ++i) {
320+ for (size_t i = 0 ; i != nof_res ; ++i) {
297321 // A resource always collides with itself.
298322 matrix[i].set (i);
299323
300324 // Note: The collision matrix is symmetric.
301- for (size_t j = i + 1 ; j != all_resources. size () ; ++j) {
325+ for (size_t j = i + 1 ; j != nof_res ; ++j) {
302326 if (do_resources_collide (all_resources[i], all_resources[j])) {
303327 matrix[i].set (j);
304328 matrix[j].set (i);
@@ -308,3 +332,52 @@ pucch_collision_manager::compute_collisions(const cell_configuration& cell_cfg)
308332
309333 return matrix;
310334}
335+
336+ pucch_collision_manager::mux_regions_matrix_t
337+ pucch_collision_manager::compute_mux_regions (const cell_configuration& cell_cfg)
338+ {
339+ unsigned nof_res = nof_common_res + cell_cfg.ded_pucch_resources .size ();
340+ mux_regions_matrix_t mux_regions;
341+
342+ // Collect all resources (common + dedicated).
343+ static_vector<resource_info, max_nof_cell_resources> all_resources = get_all_resources (cell_cfg);
344+
345+ // Helper structure to keep track of multiplexing regions and their members.
346+ struct region_record {
347+ mux_region region;
348+ bounded_bitset<max_nof_cell_resources> members;
349+ };
350+ static_vector<region_record, max_nof_cell_resources> tmp_regions;
351+
352+ for (size_t i = 0 ; i != nof_res; ++i) {
353+ const auto & res = all_resources[i];
354+
355+ // Find if the resource belongs to an existing multiplexing region.
356+ auto * region_it = std::find_if (tmp_regions.begin (), tmp_regions.end (), [&res](const region_record& record) {
357+ return record.region .does_resource_belong (res);
358+ });
359+
360+ if (region_it == tmp_regions.end ()) {
361+ // If the multiplexing region does not exist yet, create it.
362+ region_it = &tmp_regions.emplace_back (region_record{mux_region{
363+ .grants = res.grants ,
364+ .format = res.format ,
365+ },
366+ bounded_bitset<max_nof_cell_resources>(nof_res)});
367+ }
368+
369+ // Add the resource to the multiplexing region.
370+ region_it->members .set (i);
371+ }
372+
373+ // Return only multiplexing regions with more than one resource.
374+ for (const auto & record : tmp_regions) {
375+ if (record.members .count () < 2 ) {
376+ continue ;
377+ }
378+
379+ mux_regions.push_back (record.members );
380+ }
381+
382+ return mux_regions;
383+ }
0 commit comments