srsgnb: derive SSB frequency and ssb_offset based on user provided coreset0 index configuration. Added extra configuration validators

This commit is contained in:
Ismael Gomez 2022-07-06 10:36:36 +02:00 committed by Andre Puschmann
parent fef61554b2
commit a6a9274203
10 changed files with 79 additions and 63 deletions

View File

@ -142,6 +142,21 @@ public:
return ret;
}
double get_ssb_freq_hz(uint32_t cc_idx)
{
double ret = 0.0;
if (cc_idx < cell_list_lte.size()) {
ret = cell_list_lte[cc_idx].dl_freq_hz;
}
cc_idx -= cell_list_lte.size();
if (cc_idx < cell_list_nr.size()) {
ret = cell_list_nr[cc_idx].carrier.ssb_center_freq_hz;
}
return ret;
}
uint32_t get_rf_port(uint32_t cc_idx)
{
uint32_t ret = 0;

View File

@ -1519,6 +1519,7 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf
parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port");
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci"));
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.cell_id, cellroot, "cell_id"));
HANDLEPARSERCODE(parse_required_field(cell_cfg.coreset0_idx, cellroot, "coreset0_idx"));
HANDLEPARSERCODE(parse_required_field(cell_cfg.prach_root_seq_idx, cellroot, "root_seq_idx"));
HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac"));
@ -2140,54 +2141,11 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t*
ERROR("Only 10 MHz bandwidth supported.");
return SRSRAN_ERROR;
}
if (rrc_nr_cfg_->is_standalone) {
if (is_valid_arfcn(cfg.band, cfg.dl_arfcn) == false) {
ERROR("DL-ARFCN %d in band n%d not supported with coreset0 config.", cfg.dl_arfcn, cfg.band);
ERROR("Valid ARFCNs for band n%d are: %s", cfg.band, valid_arfcns_to_string(cfg.band).c_str());
return SRSRAN_ERROR;
}
if (cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) {
ERROR("Only FDD duplex supported in SA mode.");
return SRSRAN_ERROR;
}
}
}
return SRSRAN_SUCCESS;
}
// List of selected ARFCNs in band n3, n7 and n20 that match the coreset0 config
using arfcn_list_t = std::list<uint32_t>;
std::map<uint32_t, arfcn_list_t> valid_arfcn = {{3, {363500, 368500, 369500, 374500, 375000}},
{7, {525000, 526200, 531000}},
{20, {159000, 160200}}};
std::string valid_arfcns_to_string(uint32_t band)
{
std::string band_string;
if (valid_arfcn.find(band) != valid_arfcn.end()) {
for (const auto& arfcn : valid_arfcn.at(band)) {
band_string += std::to_string(arfcn);
band_string += ", ";
}
}
return band_string;
}
bool is_valid_arfcn(uint32_t band, uint32_t dl_arfcn)
{
if (valid_arfcn.find(band) == valid_arfcn.end()) {
return false;
}
const auto& arfcn_list = valid_arfcn.at(band);
for (const auto& arfcn : arfcn_list) {
if (arfcn == dl_arfcn) {
return true;
}
}
return false;
}
} // namespace enb_conf_sections
namespace sib_sections {

View File

@ -12,11 +12,11 @@
#include <unistd.h>
#include "srsenb/hdr/phy/txrx.h"
#include "srsran/common/band_helper.h"
#include "srsran/common/threads.h"
#include "srsran/srsran.h"
#include "srsenb/hdr/phy/txrx.h"
#define Error(fmt, ...) \
if (SRSRAN_DEBUG_ENABLED) \
logger.error(fmt, ##__VA_ARGS__)
@ -85,6 +85,8 @@ void txrx::run_thread()
float samp_rate = srsran_sampling_freq_hz(worker_com->get_nof_prb(0));
srsran::srsran_band_helper band_helper;
// Configure radio
radio_h->set_rx_srate(samp_rate);
radio_h->set_tx_srate(samp_rate);
@ -94,11 +96,14 @@ void txrx::run_thread()
double tx_freq_hz = worker_com->get_dl_freq_hz(cc_idx);
double rx_freq_hz = worker_com->get_ul_freq_hz(cc_idx);
uint32_t rf_port = worker_com->get_rf_port(cc_idx);
srsran::console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz for cc_idx=%d nof_prb=%d\n",
tx_freq_hz / 1e6f,
rx_freq_hz / 1e6f,
cc_idx,
worker_com->get_nof_prb(cc_idx));
srsran::console(
"Setting frequency: DL=%.1f Mhz, DL_SSB=%.2f Mhz (SSB-ARFCN=%d), UL=%.1f MHz for cc_idx=%d nof_prb=%d\n",
tx_freq_hz / 1e6f,
worker_com->get_ssb_freq_hz(cc_idx) / 1e6f,
band_helper.freq_to_nr_arfcn(worker_com->get_ssb_freq_hz(cc_idx)),
rx_freq_hz / 1e6f,
cc_idx,
worker_com->get_nof_prb(cc_idx));
radio_h->set_tx_freq(rf_port, tx_freq_hz);
radio_h->set_rx_freq(rf_port, rx_freq_hz);
}

View File

@ -80,6 +80,7 @@ struct sched_nr_cell_cfg_t {
uint32_t nof_layers;
uint32_t pci;
uint32_t ssb_offset;
uint32_t dl_cell_nof_prb;
uint32_t ul_cell_nof_prb;
asn1::rrc_nr::dl_cfg_common_sib_s dl_cfg_common;

View File

@ -36,6 +36,7 @@ struct rrc_cell_cfg_nr_t {
srsran_duplex_mode_t duplex_mode;
double ssb_freq_hz;
uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn)
uint32_t ssb_offset;
srsran_subcarrier_spacing_t ssb_scs;
srsran_ssb_pattern_t ssb_pattern;
asn1::rrc_nr::pdcch_cfg_common_s pdcch_cfg_common;

View File

@ -27,7 +27,7 @@ void make_mib_cfg(const sched_nr_cell_cfg_t& cfg, srsran_mib_nr_t* mib)
{
*mib = {};
mib->scs_common = (srsran_subcarrier_spacing_t)cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value;
mib->ssb_offset = 6; // TODO
mib->ssb_offset = cfg.ssb_offset;
mib->dmrs_typeA_pos = (srsran_dmrs_sch_typeA_pos_t)cfg.dmrs_type_a_position.value;
mib->coreset0_idx = cfg.pdcch_cfg_sib1.ctrl_res_set_zero;
mib->ss0_idx = cfg.pdcch_cfg_sib1.search_space_zero;

View File

@ -71,7 +71,7 @@ inline sched_nr_cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& phy_
// TODO: phy_cfg.ssb_positions_in_burst.group_presence_present
cell_cfg.dmrs_type_a_position.value = asn1::rrc_nr::mib_s::dmrs_type_a_position_opts::pos2;
cell_cfg.ssb_scs.value = (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.ssb.scs;
cell_cfg.pdcch_cfg_sib1.ctrl_res_set_zero = 6;
cell_cfg.pdcch_cfg_sib1.ctrl_res_set_zero = 0;
cell_cfg.pdcch_cfg_sib1.search_space_zero = 0;
cell_cfg.bwps.resize(1);

View File

@ -1089,7 +1089,7 @@ int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s
default:
srsran_terminate("Invalid carrier SCS=%d Hz", SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs));
}
mib.ssb_subcarrier_offset = 6; // TODO: currently hard-coded
mib.ssb_subcarrier_offset = cell_cfg.ssb_offset;
mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2;
mib.pdcch_cfg_sib1.search_space_zero = 0;
mib.pdcch_cfg_sib1.ctrl_res_set_zero = cell_cfg.coreset0_idx;

View File

@ -338,6 +338,7 @@ void rrc_nr::config_mac()
cell.ssb_positions_in_burst = du_cfg->cell(cc).serv_cell_cfg_common().ssb_positions_in_burst;
cell.ssb_periodicity_ms = du_cfg->cell(cc).serv_cell_cfg_common().ssb_periodicity_serving_cell.to_number();
cell.ssb_scs.value = (subcarrier_spacing_e::options)cfg.cell_list[0].phy_cell.carrier.scs;
cell.ssb_offset = du_cfg->cell(cc).mib.ssb_subcarrier_offset;
if (not cfg.is_standalone) {
const serving_cell_cfg_common_s& serv_cell =
cell_ctxt->master_cell_group->sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common;

View File

@ -115,7 +115,7 @@ void generate_default_nr_phy_cell(phy_cell_cfg_nr_t& phy_cell)
void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell)
{
cell = {};
cell.coreset0_idx = 6;
cell.coreset0_idx = 7;
cell.ssb_absolute_freq_point = 0; // auto derived
cell.num_ra_preambles = 8;
generate_default_nr_phy_cell(cell.phy_cell);
@ -187,7 +187,41 @@ int derive_ssb_params(bool is_sa,
band);
// Convert to frequency for PHY
cell.ssb_freq_hz = band_helper.nr_arfcn_to_freq(ssb_abs_freq_point);
cell.ssb_absolute_freq_point = ssb_abs_freq_point;
cell.ssb_freq_hz = band_helper.nr_arfcn_to_freq(ssb_abs_freq_point);
double pointA_abs_freq_Hz = dl_freq_hz - nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(pdcch_scs) / 2;
uint32_t ssb_pointA_freq_offset_Hz =
(cell.ssb_freq_hz > pointA_abs_freq_Hz) ? (uint32_t)(cell.ssb_freq_hz - pointA_abs_freq_Hz) : 0;
cell.ssb_offset = (uint32_t)(ssb_pointA_freq_offset_Hz / SRSRAN_SUBC_SPACING_NR(pdcch_scs)) % SRSRAN_NRE;
// Validate Coreset0 has space
srsran_coreset_t coreset0 = {};
ERROR_IF_NOT(
srsran_coreset_zero(
cell.phy_cell.cell_id, ssb_pointA_freq_offset_Hz, cell.ssb_scs, pdcch_scs, coreset0_idx, &coreset0) == 0,
"Deriving parameters for coreset0: index=%d, ssb_pointA_offset=%d kHz\n",
coreset0_idx,
ssb_pointA_freq_offset_Hz / 1000);
ERROR_IF_NOT(srsran_coreset_start_rb(&coreset0) + srsran_coreset_get_bw(&coreset0) <= cell.phy_cell.carrier.nof_prb,
"Coreset0 index=%d is not compatible with DL ARFCN %d in band %d\n",
coreset0_idx,
cell.dl_arfcn,
cell.band);
// Validate Coreset0 has less than 3 symbols
ERROR_IF_NOT(coreset0.duration < 3,
"Coreset0 index=%d is not supported due to overlap with SSB. Select a coreset0 index from 38.213 Table "
"13-1 such that N_symb_coreset < 3\n",
coreset0_idx);
// Validate Coreset0 has more than 24 RB
ERROR_IF_NOT(srsran_coreset_get_bw(&coreset0) > 24,
"Coreset0 configuration index=%d has only %d RB. A coreset0 index >= 6 is required such as N_rb >= 48\n",
srsran_coreset_get_bw(&coreset0),
coreset0_idx);
return SRSRAN_SUCCESS;
}
@ -246,15 +280,16 @@ int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell)
derive_phy_cell_freq_params(cell.dl_arfcn, cell.ul_arfcn, cell.phy_cell);
// Derive SSB params
derive_ssb_params(is_sa,
cell.dl_arfcn,
cell.band,
cell.phy_cell.carrier.scs,
cell.coreset0_idx,
cell.phy_cell.carrier.nof_prb,
cell);
ERROR_IF_NOT(derive_ssb_params(is_sa,
cell.dl_arfcn,
cell.band,
cell.phy_cell.carrier.scs,
cell.coreset0_idx,
cell.phy_cell.carrier.nof_prb,
cell) == 0,
"Deriving SSB parameters\n");
cell.phy_cell.carrier.ssb_center_freq_hz = cell.ssb_freq_hz;
cell.ssb_absolute_freq_point = band_helper.freq_to_nr_arfcn(cell.ssb_freq_hz);
// Derive remaining config params
if (not is_sa) {