rrc,gnb: remove phy flat pdcch cfg struct from rrc nr cfg

This commit is contained in:
Francisco Paisana 2022-02-04 18:10:45 +00:00
parent 88a95e8e57
commit 532a4b54e7
11 changed files with 223 additions and 169 deletions

View File

@ -129,6 +129,9 @@ bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier
phy_cfg_nr_t::ssb_cfg_t* out_ssb);
void fill_ssb_pos_in_burst(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& ssb_pos,
phy_cfg_nr_t::ssb_cfg_t* out_ssb);
bool fill_ssb_pattern_scs(const srsran_carrier_nr_t& carrier,
srsran_ssb_patern_t* pattern,
srsran_subcarrier_spacing_t* ssb_scs);
bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier,
const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg,
srsran_ssb_cfg_t* out_ssb);
@ -140,7 +143,7 @@ bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_
bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl);
bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell,
srsran_duplex_config_nr_t* duplex_cfg);
void fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch);
bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch);
bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch);
bool fill_phy_pdsch_cfg_common(const asn1::rrc_nr::pdsch_cfg_common_s& pdsch_cfg, srsran_sch_hl_cfg_nr_t* pdsch);
void fill_phy_pucch_cfg_common(const asn1::rrc_nr::pucch_cfg_common_s& pucch_cfg, srsran_pucch_nr_common_cfg_t* pucch);

View File

@ -1775,7 +1775,7 @@ bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch
return true;
}
void fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch)
bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch)
{
if (pdcch_cfg.common_ctrl_res_set_present) {
pdcch->coreset_present[pdcch_cfg.common_ctrl_res_set.ctrl_res_set_id] = true;
@ -1783,7 +1783,10 @@ void fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg
}
for (const search_space_s& ss : pdcch_cfg.common_search_space_list) {
pdcch->search_space_present[ss.search_space_id] = true;
make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]);
if (not make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id])) {
asn1::log_error("Failed to convert SearchSpace Configuration");
return false;
}
if (pdcch_cfg.ra_search_space_present and pdcch_cfg.ra_search_space == ss.search_space_id) {
pdcch->ra_search_space_present = true;
pdcch->ra_search_space = pdcch->search_space[ss.search_space_id];
@ -1792,6 +1795,7 @@ void fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg
pdcch->ra_search_space.formats[1] = srsran_dci_format_nr_1_0;
}
}
return true;
}
void fill_phy_pucch_cfg_common(const asn1::rrc_nr::pucch_cfg_common_s& pucch_cfg, srsran_pucch_nr_common_cfg_t* pucch)

View File

@ -27,7 +27,6 @@ struct phy_cell_cfg_nr_t {
uint32_t root_seq_idx;
uint32_t num_ra_preambles;
float gain_db;
srsran_pdcch_cfg_nr_t pdcch = {}; ///< Common CORESET and Search Space configuration
srsran_pdsch_cfg_t pdsch = {};
srsran_prach_cfg_t prach = {};
bool dl_measure;

View File

@ -23,19 +23,21 @@ namespace srsenb {
// Cell/Sector configuration for NR cells
struct rrc_cell_cfg_nr_t {
phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.)
uint32_t tac; // Tracking area code
uint32_t dl_arfcn; // DL freq already included in phy_cell
uint32_t ul_arfcn; // UL freq also in phy_cell
uint32_t dl_absolute_freq_point_a; // derived from DL ARFCN
uint32_t ul_absolute_freq_point_a; // derived from UL ARFCN
uint32_t band;
uint32_t coreset0_idx; // Table 13-{1,...15} row index
srsran_duplex_mode_t duplex_mode;
double ssb_freq_hz;
uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn)
srsran_subcarrier_spacing_t ssb_scs;
srsran_ssb_patern_t ssb_pattern;
phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.)
uint32_t tac; // Tracking area code
uint32_t dl_arfcn; // DL freq already included in phy_cell
uint32_t ul_arfcn; // UL freq also in phy_cell
uint32_t dl_absolute_freq_point_a; // derived from DL ARFCN
uint32_t ul_absolute_freq_point_a; // derived from UL ARFCN
uint32_t band;
uint32_t coreset0_idx; // Table 13-{1,...15} row index
srsran_duplex_mode_t duplex_mode;
double ssb_freq_hz;
uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn)
srsran_subcarrier_spacing_t ssb_scs;
srsran_ssb_patern_t ssb_pattern;
asn1::rrc_nr::pdcch_cfg_common_s pdcch_cfg_common;
asn1::rrc_nr::pdcch_cfg_s pdcch_cfg_ded;
};
typedef std::vector<rrc_cell_cfg_nr_t> rrc_cell_list_nr_t;

View File

@ -31,6 +31,11 @@ public:
asn1::rrc_nr::sib1_s sib1;
srsran::unique_byte_buffer_t packed_sib1;
asn1::rrc_nr::subcarrier_spacing_e ssb_scs;
srsran_ssb_patern_t ssb_pattern;
double ssb_center_freq_hz;
double dl_freq_hz;
const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg_common() const
{
return sib1.serving_cell_cfg_common;
@ -63,6 +68,8 @@ private:
std::vector<std::unique_ptr<du_cell_config> > cells;
};
void fill_phy_pdcch_cfg_common(const du_cell_config& cell, srsran_pdcch_cfg_nr_t* pdcch);
} // namespace srsenb
#endif // SRSRAN_RRC_NR_DU_MANAGER_H

View File

@ -499,32 +499,6 @@ int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas
return SRSRAN_SUCCESS;
}
/// Fill InitDlBwp with gNB config
int fill_pdcch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_s& pdcch_cfg)
{
auto& cell_cfg = cfg.cell_list.at(cc);
for (uint32_t ss_idx = 1; ss_idx < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ss_idx++) {
if (cell_cfg.phy_cell.pdcch.search_space_present[ss_idx]) {
auto& search_space_cfg = cell_cfg.phy_cell.pdcch.search_space[ss_idx];
if (search_space_cfg.type != srsran_search_space_type_ue) {
// Only add UE-specific search spaces at this stage
continue;
}
// Add UE-specific SearchSpace
pdcch_cfg.search_spaces_to_add_mod_list.push_back({});
set_search_space_from_phy_cfg(search_space_cfg, pdcch_cfg.search_spaces_to_add_mod_list.back());
// Add CORESET associated with SearchSpace
uint32_t coreset_id = search_space_cfg.coreset_id;
auto& coreset_cfg = cell_cfg.phy_cell.pdcch.coreset[coreset_id];
pdcch_cfg.ctrl_res_set_to_add_mod_list.push_back({});
set_coreset_from_phy_cfg(coreset_cfg, pdcch_cfg.ctrl_res_set_to_add_mod_list.back());
}
}
return SRSRAN_SUCCESS;
}
void fill_pdsch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdsch_cfg_s& out)
{
out.dmrs_dl_for_pdsch_map_type_a_present = true;
@ -571,8 +545,8 @@ void fill_pdsch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdsch_cfg
/// Fill InitDlBwp with gNB config
int fill_init_dl_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_ded_s& init_dl_bwp)
{
init_dl_bwp.pdcch_cfg_present = true;
HANDLE_ERROR(fill_pdcch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdcch_cfg.set_setup()));
init_dl_bwp.pdcch_cfg_present = true;
init_dl_bwp.pdcch_cfg.set_setup() = cfg.cell_list[cc].pdcch_cfg_ded;
init_dl_bwp.pdsch_cfg_present = true;
fill_pdsch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdsch_cfg.set_setup());
@ -1070,7 +1044,7 @@ int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s
return SRSRAN_SUCCESS;
}
// Called for SA
// Called for SA and NSA
void fill_pdcch_cfg_common(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_common_s& out)
{
auto& cell_cfg = cfg.cell_list[cc];
@ -1078,13 +1052,9 @@ void fill_pdcch_cfg_common(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_commo
out.ctrl_res_set_zero_present = false;
out.search_space_zero_present = false;
if (not cfg.is_standalone) {
// In NSA, Common CORESET is passed in RRC Reconfiguration
out.common_ctrl_res_set_present = true;
set_coreset_from_phy_cfg(cfg.cell_list[cc].phy_cell.pdcch.coreset[1], out.common_ctrl_res_set);
}
out.common_search_space_list.resize(1);
set_search_space_from_phy_cfg(cell_cfg.phy_cell.pdcch.search_space[1], out.common_search_space_list.back());
out.common_ctrl_res_set_present = cell_cfg.pdcch_cfg_common.common_ctrl_res_set_present;
out.common_ctrl_res_set = cell_cfg.pdcch_cfg_common.common_ctrl_res_set;
out.common_search_space_list = cell_cfg.pdcch_cfg_ded.search_spaces_to_add_mod_list;
out.search_space_sib1_present = true;
out.search_space_sib1 = 0;

View File

@ -273,10 +273,13 @@ void rrc_nr::config_phy()
{
srsenb::phy_interface_rrc_nr::common_cfg_t common_cfg = {};
common_cfg.carrier = cfg.cell_list[0].phy_cell.carrier;
common_cfg.pdcch = cfg.cell_list[0].phy_cell.pdcch;
common_cfg.prach = cfg.cell_list[0].phy_cell.prach;
common_cfg.duplex_mode = cfg.cell_list[0].duplex_mode;
bool ret = srsran::fill_phy_ssb_cfg(
fill_phy_pdcch_cfg_common(du_cfg->cell(0), &common_cfg.pdcch);
bool ret = srsran::fill_phy_pdcch_cfg(
cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &common_cfg.pdcch);
srsran_assert(ret, "Failed to generate Dedicated PDCCH config");
common_cfg.prach = cfg.cell_list[0].phy_cell.prach;
common_cfg.duplex_mode = cfg.cell_list[0].duplex_mode;
ret = srsran::fill_phy_ssb_cfg(
cfg.cell_list[0].phy_cell.carrier, du_cfg->cell(0).serv_cell_cfg_common(), &common_cfg.ssb);
srsran_assert(ret, "Failed to generate PHY config");
if (phy->set_common_cfg(common_cfg) < SRSRAN_SUCCESS) {
@ -298,7 +301,10 @@ void rrc_nr::config_mac()
sched_nr_cell_cfg_t& cell = sched_cells_cfg[cc];
// Derive cell config from rrc_nr_cfg_t
cell.bwps[0].pdcch = cfg.cell_list[cc].phy_cell.pdcch;
fill_phy_pdcch_cfg_common(du_cfg->cell(cc), &cell.bwps[0].pdcch);
bool ret = srsran::fill_phy_pdcch_cfg(
cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &cell.bwps[0].pdcch);
srsran_assert(ret, "Failed to generate Dedicated PDCCH config");
cell.pci = cfg.cell_list[cc].phy_cell.carrier.pci;
cell.nof_layers = cfg.cell_list[cc].phy_cell.carrier.max_mimo_layers;
cell.dl_cell_nof_prb = cfg.cell_list[cc].phy_cell.carrier.nof_prb;

View File

@ -30,6 +30,33 @@
namespace srsenb {
uint32_t coreset_get_bw(const asn1::rrc_nr::ctrl_res_set_s& coreset)
{
uint32_t prb_count = 0;
// Iterate all the frequency domain resources bit-map...
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
// ... and count 6 PRB for every frequency domain resource that it is enabled
if (coreset.freq_domain_res.get(i)) {
prb_count += 6;
}
}
// Return the total count of physical resource blocks
return prb_count;
}
int coreset_get_pdcch_nr_max_candidates(const asn1::rrc_nr::ctrl_res_set_s& coreset, uint32_t aggregation_level)
{
uint32_t coreset_bw = coreset_get_bw(coreset);
uint32_t nof_cce = (coreset_bw * coreset.dur) / 6;
uint32_t L = 1U << aggregation_level;
uint32_t nof_candidates = nof_cce / L;
return SRSRAN_MIN(nof_candidates, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR);
}
/// Generate default phy cell configuration
void generate_default_nr_phy_cell(phy_cell_cfg_nr_t& phy_cell)
{
@ -50,35 +77,9 @@ void generate_default_nr_phy_cell(phy_cell_cfg_nr_t& phy_cell)
phy_cell.prach.freq_offset = 1; // msg1-FrequencyStart (zero not supported with current PRACH implementation)
phy_cell.prach.zero_corr_zone = 0;
phy_cell.prach.num_ra_preambles = phy_cell.num_ra_preambles;
phy_cell.prach.hs_flag = false;
phy_cell.prach.hs_flag = false;
phy_cell.prach.tdd_config.configured = false;
// PDCCH
// - Add CORESET#2 as UE-specific
phy_cell.pdcch.coreset_present[2] = true;
phy_cell.pdcch.coreset[2].id = 2;
phy_cell.pdcch.coreset[2].duration = 1;
phy_cell.pdcch.coreset[2].mapping_type = srsran_coreset_mapping_type_non_interleaved;
phy_cell.pdcch.coreset[2].precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
// Generate frequency resources for the full BW
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
phy_cell.pdcch.coreset[2].freq_resources[i] = i < SRSRAN_FLOOR(phy_cell.carrier.nof_prb, 6);
}
// - Add SearchSpace#2 as UE-specific
phy_cell.pdcch.search_space_present[2] = true;
phy_cell.pdcch.search_space[2].id = 2;
phy_cell.pdcch.search_space[2].coreset_id = 2;
phy_cell.pdcch.search_space[2].type = srsran_search_space_type_ue;
// Generate frequency resources for the full BW
for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) {
phy_cell.pdcch.search_space[2].nof_candidates[L] =
SRSRAN_MIN(2, srsran_pdcch_nr_max_candidates_coreset(&phy_cell.pdcch.coreset[2], L));
}
phy_cell.pdcch.search_space[2].nof_formats = 2;
phy_cell.pdcch.search_space[2].formats[0] = srsran_dci_format_nr_0_0; // DCI format for PUSCH
phy_cell.pdcch.search_space[2].formats[1] = srsran_dci_format_nr_1_0; // DCI format for PDSCH
phy_cell.pdcch.search_space[2].duration = 1;
// PDSCH
phy_cell.pdsch.rs_power = 0;
phy_cell.pdsch.p_b = 0;
@ -91,29 +92,45 @@ void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell)
cell.coreset0_idx = 6;
cell.ssb_absolute_freq_point = 0; // auto derived
generate_default_nr_phy_cell(cell.phy_cell);
}
/// Generate CORESET#0 and SSB absolute frequency (if not specified)
int derive_coreset0_params(rrc_cell_cfg_nr_t& cell)
{
// Generate CORESET#0
cell.phy_cell.pdcch.coreset_present[0] = true;
// Get pointA and SSB absolute frequencies
double pointA_abs_freq_Hz =
cell.phy_cell.carrier.dl_center_frequency_hz -
cell.phy_cell.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(cell.phy_cell.carrier.scs) / 2;
double ssb_abs_freq_Hz = cell.phy_cell.carrier.ssb_center_freq_hz;
// Calculate integer SSB to pointA frequency offset in Hz
uint32_t ssb_pointA_freq_offset_Hz =
(ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0;
int ret = srsran_coreset_zero(cell.phy_cell.carrier.pci,
ssb_pointA_freq_offset_Hz,
cell.ssb_scs,
cell.phy_cell.carrier.scs,
cell.coreset0_idx,
&cell.phy_cell.pdcch.coreset[0]);
ERROR_IF_NOT(ret == SRSRAN_SUCCESS, "Failed to generate CORESET#0");
return SRSRAN_SUCCESS;
// PDCCH
// - Add CORESET#2 as UE-specific
cell.pdcch_cfg_ded.ctrl_res_set_to_add_mod_list.resize(1);
auto& coreset2 = cell.pdcch_cfg_ded.ctrl_res_set_to_add_mod_list[0];
coreset2.ctrl_res_set_id = 2;
// Generate frequency resources for the full BW
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
coreset2.freq_domain_res.set(i, i < SRSRAN_FLOOR(cell.phy_cell.carrier.nof_prb, 6));
}
coreset2.dur = 1;
coreset2.cce_reg_map_type.set_non_interleaved();
coreset2.precoder_granularity.value = asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle;
// - Add SearchSpace#2 as UE-specific -> CORESET#2
cell.pdcch_cfg_ded.search_spaces_to_add_mod_list.resize(1);
auto& ss2 = cell.pdcch_cfg_ded.search_spaces_to_add_mod_list[0];
ss2.search_space_id = 2;
ss2.ctrl_res_set_id_present = true;
ss2.ctrl_res_set_id = coreset2.ctrl_res_set_id;
ss2.dur_present = false; // false for duration=1
ss2.monitoring_slot_periodicity_and_offset_present = true;
ss2.monitoring_slot_periodicity_and_offset.set_sl1();
ss2.monitoring_symbols_within_slot_present = true;
ss2.monitoring_symbols_within_slot.from_number(0b10000000000000);
ss2.search_space_type_present = true;
ss2.search_space_type.set_ue_specific().dci_formats.value = asn1::rrc_nr::search_space_s::search_space_type_c_::
ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0;
ss2.nrof_candidates_present = true;
uint32_t nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset2, 0), 2);
asn1::number_to_enum(ss2.nrof_candidates.aggregation_level1, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset2, 1), 2);
asn1::number_to_enum(ss2.nrof_candidates.aggregation_level2, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset2, 2), 2);
asn1::number_to_enum(ss2.nrof_candidates.aggregation_level4, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset2, 3), 2);
asn1::number_to_enum(ss2.nrof_candidates.aggregation_level8, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset2, 4), 2);
asn1::number_to_enum(ss2.nrof_candidates.aggregation_level16, nof_cand);
}
int derive_ssb_params(bool is_sa,
@ -243,66 +260,65 @@ int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell)
cell.ssb_absolute_freq_point = band_helper.freq_to_nr_arfcn(cell.ssb_freq_hz);
// Derive remaining config params
cell.pdcch_cfg_common.common_search_space_list.resize(1); // SearchSpace#1
auto& ss1 = cell.pdcch_cfg_common.common_search_space_list[0];
ss1.search_space_id = 1;
ss1.dur_present = false; // false for duration=1
ss1.monitoring_slot_periodicity_and_offset_present = true;
ss1.monitoring_slot_periodicity_and_offset.set_sl1();
ss1.monitoring_symbols_within_slot_present = true;
ss1.monitoring_symbols_within_slot.from_number(0b10000000000000);
ss1.nrof_candidates_present = true;
ss1.search_space_type_present = true;
ss1.search_space_type.set_common().dci_format0_minus0_and_format1_minus0_present = true;
cell.pdcch_cfg_common.ra_search_space_present = true;
cell.pdcch_cfg_common.ra_search_space = cell.pdcch_cfg_common.common_search_space_list[0].search_space_id;
if (is_sa) {
derive_coreset0_params(cell);
cell.phy_cell.pdcch.search_space_present[0] = true;
cell.phy_cell.pdcch.search_space[0].id = 0;
cell.phy_cell.pdcch.search_space[0].coreset_id = 0;
cell.phy_cell.pdcch.search_space[0].type = srsran_search_space_type_common_0;
cell.phy_cell.pdcch.search_space[0].nof_candidates[0] = 1;
cell.phy_cell.pdcch.search_space[0].nof_candidates[1] = 1;
cell.phy_cell.pdcch.search_space[0].nof_candidates[2] = 1;
cell.phy_cell.pdcch.search_space[0].nof_candidates[3] = 0;
cell.phy_cell.pdcch.search_space[0].nof_candidates[4] = 0;
cell.phy_cell.pdcch.search_space[0].nof_formats = 1;
cell.phy_cell.pdcch.search_space[0].formats[0] = srsran_dci_format_nr_1_0;
cell.phy_cell.pdcch.search_space[0].duration = 1;
cell.phy_cell.pdcch.search_space_present[1] = true;
cell.phy_cell.pdcch.search_space[1].id = 1;
cell.phy_cell.pdcch.search_space[1].coreset_id = 0;
cell.phy_cell.pdcch.search_space[1].type = srsran_search_space_type_common_1;
cell.phy_cell.pdcch.search_space[1].nof_candidates[0] = 0;
cell.phy_cell.pdcch.search_space[1].nof_candidates[1] = 0;
cell.phy_cell.pdcch.search_space[1].nof_candidates[2] = 1;
cell.phy_cell.pdcch.search_space[1].nof_candidates[3] = 0;
cell.phy_cell.pdcch.search_space[1].nof_candidates[4] = 0;
cell.phy_cell.pdcch.search_space[1].nof_formats = 2;
cell.phy_cell.pdcch.search_space[1].formats[0] = srsran_dci_format_nr_0_0; // DCI format for PUSCH
cell.phy_cell.pdcch.search_space[1].formats[1] = srsran_dci_format_nr_1_0; // DCI format for PDSCH
cell.phy_cell.pdcch.search_space[1].duration = 1;
// Configure SearchSpace#1 -> CORESET#0
ss1.ctrl_res_set_id_present = true;
ss1.ctrl_res_set_id = 0;
ss1.nrof_candidates.aggregation_level1.value =
asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0;
ss1.nrof_candidates.aggregation_level2.value =
asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n0;
ss1.nrof_candidates.aggregation_level4.value =
asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1;
ss1.nrof_candidates.aggregation_level8.value =
asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0;
ss1.nrof_candidates.aggregation_level16.value =
asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0;
} else {
// Configure CORESET#1
cell.phy_cell.pdcch.coreset_present[1] = true;
cell.phy_cell.pdcch.coreset[1].id = 1;
cell.phy_cell.pdcch.coreset[1].duration = 1;
cell.phy_cell.pdcch.coreset[1].mapping_type = srsran_coreset_mapping_type_non_interleaved;
cell.phy_cell.pdcch.coreset[1].precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
// Note: In NSA, Common CORESET is passed in RRC Reconfiguration
cell.pdcch_cfg_common.common_ctrl_res_set_present = true;
auto& coreset1 = cell.pdcch_cfg_common.common_ctrl_res_set;
coreset1.ctrl_res_set_id = 1;
// Generate frequency resources for the full BW
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
cell.phy_cell.pdcch.coreset[1].freq_resources[i] = i < SRSRAN_FLOOR(cell.phy_cell.carrier.nof_prb, 6);
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; ++i) {
coreset1.freq_domain_res.set(i, i < SRSRAN_FLOOR(cell.phy_cell.carrier.nof_prb, 6));
}
coreset1.dur = 1;
coreset1.cce_reg_map_type.set_non_interleaved();
coreset1.precoder_granularity.value = asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle;
// Configure SearchSpace#1 -> CORESET#1
cell.phy_cell.pdcch.search_space_present[1] = true;
cell.phy_cell.pdcch.search_space[1].id = 1;
cell.phy_cell.pdcch.search_space[1].coreset_id = 1;
cell.phy_cell.pdcch.search_space[1].type = srsran_search_space_type_common_3;
// Generate frequency resources for the full BW
for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) {
cell.phy_cell.pdcch.search_space[1].nof_candidates[L] =
SRSRAN_MIN(2, srsran_pdcch_nr_max_candidates_coreset(&cell.phy_cell.pdcch.coreset[1], L));
}
cell.phy_cell.pdcch.search_space[1].nof_formats = 2;
cell.phy_cell.pdcch.search_space[1].formats[0] = srsran_dci_format_nr_0_0; // DCI format for PUSCH
cell.phy_cell.pdcch.search_space[1].formats[1] = srsran_dci_format_nr_1_0; // DCI format for PDSCH
cell.phy_cell.pdcch.search_space[1].duration = 1;
ss1.ctrl_res_set_id_present = true;
ss1.ctrl_res_set_id = coreset1.ctrl_res_set_id;
uint32_t nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset1, 0), 2);
asn1::number_to_enum(ss1.nrof_candidates.aggregation_level1, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset1, 1), 2);
asn1::number_to_enum(ss1.nrof_candidates.aggregation_level2, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset1, 2), 2);
asn1::number_to_enum(ss1.nrof_candidates.aggregation_level4, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset1, 3), 2);
asn1::number_to_enum(ss1.nrof_candidates.aggregation_level8, nof_cand);
nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(coreset1, 4), 2);
asn1::number_to_enum(ss1.nrof_candidates.aggregation_level16, nof_cand);
ss1.search_space_type_present = true;
ss1.search_space_type.set_common().dci_format0_minus0_and_format1_minus0_present = true;
// cell.phy_cell.pdcch.search_space[1].type = srsran_search_space_type_common_3;
}
cell.phy_cell.pdcch.ra_search_space_present = true;
cell.phy_cell.pdcch.ra_search_space = cell.phy_cell.pdcch.search_space[1];
cell.phy_cell.pdcch.ra_search_space.type = srsran_search_space_type_common_1;
// Derive remaining PHY cell params
cell.phy_cell.prach.num_ra_preambles = cell.phy_cell.num_ra_preambles;
cell.phy_cell.prach.tdd_config.configured = (cell.duplex_mode == SRSRAN_DUPLEX_MODE_TDD);
@ -327,16 +343,11 @@ int check_nr_cell_cfg_valid(const rrc_cell_cfg_nr_t& cell, bool is_sa)
// verify SSB params are consistent
HANDLE_ERROR(check_nr_phy_cell_cfg_valid(cell.phy_cell));
if (is_sa) {
ERROR_IF_NOT(cell.phy_cell.pdcch.coreset_present[0], "CORESET#0 must be defined in Standalone mode");
}
return SRSRAN_SUCCESS;
}
int check_nr_phy_cell_cfg_valid(const phy_cell_cfg_nr_t& phy_cell)
{
HANDLE_ERROR(check_nr_pdcch_cfg_valid(phy_cell.pdcch));
return SRSRAN_SUCCESS;
}

View File

@ -12,6 +12,7 @@
#include "srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h"
#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h"
#include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/common/string_helpers.h"
using namespace asn1::rrc_nr;
@ -89,8 +90,60 @@ int du_config_manager::add_cell()
cell.sib1.to_json(js);
logger.info("SIB1 content: %s", js.to_string().c_str());
// Generate SSB SCS
srsran_subcarrier_spacing_t ssb_scs;
if (not srsran::fill_ssb_pattern_scs(cfg.cell_list[cell.cc].phy_cell.carrier, &cell.ssb_pattern, &ssb_scs)) {
return SRSRAN_ERROR;
}
cell.ssb_scs.value = (subcarrier_spacing_e::options)ssb_scs;
cell.ssb_center_freq_hz = cfg.cell_list[cell.cc].ssb_freq_hz;
cell.dl_freq_hz = cfg.cell_list[cell.cc].phy_cell.carrier.dl_center_frequency_hz;
cells.push_back(std::move(obj));
return SRSRAN_SUCCESS;
}
void fill_phy_pdcch_cfg_common(const du_cell_config& cell, srsran_pdcch_cfg_nr_t* pdcch)
{
const serving_cell_cfg_common_sib_s& serv_cell = cell.serv_cell_cfg_common();
const pdcch_cfg_common_s& pdcch_common = serv_cell.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup();
bool is_sa = pdcch_common.ctrl_res_set_zero_present;
uint8_t coreset0_idx = pdcch_common.ctrl_res_set_zero;
auto scs = (srsran_subcarrier_spacing_t)serv_cell.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value;
auto ssb_scs = (srsran_subcarrier_spacing_t)cell.ssb_scs.value;
uint32_t nof_prb = serv_cell.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw;
if (is_sa) {
// Generate CORESET#0
pdcch->coreset_present[0] = true;
// Get pointA and SSB absolute frequencies
double pointA_abs_freq_Hz = cell.dl_freq_hz - nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(scs) / 2;
double ssb_abs_freq_Hz = cell.ssb_center_freq_hz;
// Calculate integer SSB to pointA frequency offset in Hz
uint32_t ssb_pointA_freq_offset_Hz =
(ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0;
int ret = srsran_coreset_zero(cell.pci, ssb_pointA_freq_offset_Hz, ssb_scs, scs, coreset0_idx, &pdcch->coreset[0]);
srsran_assert(ret == SRSRAN_SUCCESS, "Failed to generate CORESET#0");
// Generate SearchSpace#0
pdcch->search_space_present[0] = true;
pdcch->search_space[0].id = 0;
pdcch->search_space[0].coreset_id = 0;
pdcch->search_space[0].type = srsran_search_space_type_common_0;
pdcch->search_space[0].nof_candidates[0] = 1;
pdcch->search_space[0].nof_candidates[1] = 1;
pdcch->search_space[0].nof_candidates[2] = 1;
pdcch->search_space[0].nof_candidates[3] = 0;
pdcch->search_space[0].nof_candidates[4] = 0;
pdcch->search_space[0].nof_formats = 1;
pdcch->search_space[0].formats[0] = srsran_dci_format_nr_1_0;
pdcch->search_space[0].duration = 1;
}
// Generate Common CORESETs and Search Spaces
bool ret = srsran::fill_phy_pdcch_cfg_common(pdcch_common, pdcch);
srsran_assert(ret, "PDCCH Config Common");
}
} // namespace srsenb

View File

@ -39,7 +39,9 @@ rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, uint32_t pcell_cc_idx, bool star
if (not parent->cfg.is_standalone) {
// Add the final PDCCH config in case of NSA
uecfg.phy_cfg.pdcch = parent->cfg.cell_list[0].phy_cell.pdcch;
srsran::fill_phy_pdcch_cfg(
parent->cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(),
&uecfg.phy_cfg.pdcch);
} else {
cell_group_cfg = *parent->cell_ctxt->master_cell_group;
next_cell_group_cfg = cell_group_cfg;
@ -1479,13 +1481,11 @@ int rrc_nr::ue::update_mac(const cell_group_cfg_s& cell_group_config, bool is_co
auto& pdcch = cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup();
for (auto& ss : pdcch.search_spaces_to_add_mod_list) {
uecfg.phy_cfg.pdcch.search_space_present[ss.search_space_id] = true;
uecfg.phy_cfg.pdcch.search_space[ss.search_space_id] =
parent->cfg.cell_list[0].phy_cell.pdcch.search_space[ss.search_space_id];
srsran::make_phy_search_space_cfg(ss, &uecfg.phy_cfg.pdcch.search_space[ss.search_space_id]);
}
for (auto& cs : pdcch.ctrl_res_set_to_add_mod_list) {
uecfg.phy_cfg.pdcch.coreset_present[cs.ctrl_res_set_id] = true;
uecfg.phy_cfg.pdcch.coreset[cs.ctrl_res_set_id] =
parent->cfg.cell_list[0].phy_cell.pdcch.coreset[cs.ctrl_res_set_id];
srsran::make_phy_coreset_cfg(cs, &uecfg.phy_cfg.pdcch.coreset[cs.ctrl_res_set_id]);
}
}

View File

@ -185,7 +185,6 @@ test_bench::args_t::args_t(int argc, char** argv)
cell_list[0].carrier = phy_cfg.carrier;
cell_list[0].rf_port = 0;
cell_list[0].cell_id = 0;
cell_list[0].pdcch = phy_cfg.pdcch;
ue_stack.rnti = rnti;