|
| 1 | +/* |
| 2 | + * |
| 3 | + * Copyright 2021-2024 Software Radio Systems Limited |
| 4 | + * |
| 5 | + * By using this file, you agree to the terms and conditions set |
| 6 | + * forth in the LICENSE file which can be found at the top level of |
| 7 | + * the distribution. |
| 8 | + * |
| 9 | + */ |
| 10 | + |
| 11 | +#include "srs_resource_generator.h" |
| 12 | + |
| 13 | +using namespace srsran; |
| 14 | +using namespace srs_du; |
| 15 | + |
| 16 | +std::vector<du_srs_resource> srsran::srs_du::generate_cell_srs_list(const du_cell_config& du_cell_cfg) |
| 17 | +{ |
| 18 | + std::vector<du_srs_resource> srs_res_list; |
| 19 | + // Compute the available TX comb offsets. \ref tx_comb_cyclic_shift, in \c srs_config::srs_resource::tx_comb_params. |
| 20 | + std::vector<unsigned> tx_comb_offsets = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 |
| 21 | + ? std::vector<unsigned>{0U, 1U} |
| 22 | + : std::vector<unsigned>{0U, 1U, 2U, 3U}; |
| 23 | + |
| 24 | + // Compute the available Cyclic Shifts. |
| 25 | + const unsigned max_cs = du_cell_cfg.srs_cfg.tx_comb == srsran::tx_comb_size::n2 ? 8U : 12U; |
| 26 | + const unsigned cs_step = max_cs / static_cast<unsigned>(du_cell_cfg.srs_cfg.cyclic_shift_reuse_factor); |
| 27 | + std::vector<unsigned> cs_values; |
| 28 | + for (unsigned cs = 0; cs < max_cs; cs += cs_step) { |
| 29 | + cs_values.push_back(cs); |
| 30 | + } |
| 31 | + |
| 32 | + // Compute the available Sequence IDs. |
| 33 | + // NOTE: we only consider the number of orthogonal sequences that can be generated, as per TS 38.211, |
| 34 | + // Section 6.4.1.4.2, which is 30. |
| 35 | + constexpr unsigned max_seq_id_values = 30U; |
| 36 | + const unsigned seq_id_step = max_seq_id_values / static_cast<unsigned>(du_cell_cfg.srs_cfg.sequence_id_reuse_factor); |
| 37 | + std::vector<unsigned> seq_id_values; |
| 38 | + for (unsigned seq_id = 0; seq_id < max_seq_id_values; seq_id += seq_id_step) { |
| 39 | + seq_id_values.push_back(static_cast<unsigned>(du_cell_cfg.pci) + seq_id); |
| 40 | + } |
| 41 | + |
| 42 | + // Find the first symbol within the UL slot (considering all options FDD, TDD pattern 1 and TDD pattern 2) where the |
| 43 | + // SRS resource can be placed. |
| 44 | + unsigned starting_sym = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.to_uint(); |
| 45 | + if (du_cell_cfg.tdd_ul_dl_cfg_common.has_value()) { |
| 46 | + const auto& tdd_cfg = du_cell_cfg.tdd_ul_dl_cfg_common.value(); |
| 47 | + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern1.nof_ul_symbols); |
| 48 | + if (tdd_cfg.pattern2.has_value()) { |
| 49 | + starting_sym = std::min(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - tdd_cfg.pattern2.value().nof_ul_symbols); |
| 50 | + } |
| 51 | + } |
| 52 | + // The number of SRS symbols cannot be larger than 6. |
| 53 | + starting_sym = std::max(starting_sym, NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - du_cell_cfg.srs_cfg.max_nof_symbols.max()); |
| 54 | + |
| 55 | + // We use the counter to define the cell resource ID. |
| 56 | + unsigned srs_res_cnt = 0; |
| 57 | + for (unsigned sym_start = NOF_OFDM_SYM_PER_SLOT_NORMAL_CP - static_cast<unsigned>(du_cell_cfg.srs_cfg.nof_symbols); |
| 58 | + sym_start >= starting_sym; |
| 59 | + sym_start -= static_cast<unsigned>(du_cell_cfg.srs_cfg.nof_symbols)) { |
| 60 | + const ofdm_symbol_range srs_res_symbols{sym_start, |
| 61 | + sym_start + static_cast<unsigned>(du_cell_cfg.srs_cfg.nof_symbols)}; |
| 62 | + for (auto tx_comb_offset : tx_comb_offsets) { |
| 63 | + for (auto cs : cs_values) { |
| 64 | + for (auto seq_id : seq_id_values) { |
| 65 | + du_srs_resource srs_res; |
| 66 | + srs_res.cell_res_id = srs_res_cnt; |
| 67 | + srs_res.tx_comb_offset = tx_comb_offset; |
| 68 | + srs_res.symbols = srs_res_symbols; |
| 69 | + srs_res.sequence_id = seq_id; |
| 70 | + srs_res.cs = cs; |
| 71 | + srs_res_list.push_back(srs_res); |
| 72 | + ++srs_res_cnt; |
| 73 | + } |
| 74 | + } |
| 75 | + } |
| 76 | + } |
| 77 | + return srs_res_list; |
| 78 | +} |
0 commit comments