SRSUE: refactor carrier setting for accepting a dynamic carrier configuration

This commit is contained in:
Xavier Arteaga 2021-04-19 20:50:11 +02:00 committed by Andre Puschmann
parent 47523935f6
commit 407903e0d6
20 changed files with 243 additions and 171 deletions

View File

@ -33,13 +33,13 @@ struct phy_cfg_nr_t {
srsran_ue_dl_nr_harq_ack_cfg_t harq_ack = {};
srsran_csi_hl_cfg_t csi = {};
srsran_carrier_nr_t carrier = {};
phy_cfg_nr_t() {}
/**
* @param carrier
*/
srsran_dci_cfg_nr_t get_dci_cfg(const srsran_carrier_nr_t& carrier) const
srsran_dci_cfg_nr_t get_dci_cfg() const
{
srsran_dci_cfg_nr_t dci_cfg = {};

View File

@ -45,12 +45,12 @@ public:
} tb_action_dl_t;
typedef struct {
uint16_t rnti;
uint32_t tti;
uint8_t pid; // HARQ process ID
uint8_t rv; // Redundancy Version
uint8_t ndi; // Raw new data indicator extracted from DCI
uint32_t tbs; // Transport block size in Bytes
uint16_t rnti;
uint32_t tti;
uint8_t pid; // HARQ process ID
uint8_t rv; // Redundancy Version
uint8_t ndi; // Raw new data indicator extracted from DCI
uint32_t tbs; // Transport block size in Bytes
} mac_nr_grant_dl_t;
typedef struct {
@ -167,7 +167,7 @@ public:
struct phy_args_nr_t {
uint32_t nof_carriers = 1;
uint32_t nof_prb = 52;
uint32_t max_nof_prb = 106;
uint32_t nof_phy_threads = 3;
uint32_t worker_cpu_mask = 0;
srsran::phy_log_args_t log = {};
@ -179,11 +179,16 @@ struct phy_args_nr_t {
phy_args_nr_t()
{
dl.nof_rx_antennas = 1;
dl.nof_max_prb = 100;
dl.nof_max_prb = 106;
dl.pdsch.max_prb = 106;
dl.pdsch.max_layers = 1;
dl.pdsch.measure_evm = true;
dl.pdsch.measure_time = true;
dl.pdsch.sch.disable_simd = false;
ul.nof_max_prb = 100;
dl.pdsch.sch.max_nof_iter = 10;
ul.nof_max_prb = 106;
ul.pusch.max_prb = 106;
ul.pusch.max_layers = 1;
ul.pusch.measure_time = true;
ul.pusch.sch.disable_simd = false;

View File

@ -53,7 +53,7 @@ struct phy_args_t {
uint32_t nof_lte_carriers = 1;
uint32_t nof_nr_carriers = 0;
uint32_t nr_nof_prb = 50;
uint32_t nr_max_nof_prb = 106;
double nr_freq_hz = 2630e6;
uint32_t nof_rx_ant = 1;
std::string equalizer_mode = "mmse";

View File

@ -281,7 +281,7 @@ typedef struct SRSRAN_API {
uint32_t absolute_frequency_ssb;
uint32_t absolute_frequency_point_a;
srsran_subcarrier_spacing_t scs;
uint32_t nof_prb;
uint32_t nof_prb; ///< @brief See TS 38.101-1 Table 5.3.2-1 for more details
uint32_t start;
uint32_t max_mimo_layers; ///< @brief DL: Indicates the maximum number of MIMO layers to be used for PDSCH in all BWPs
///< of this serving cell. (see TS 38.212 [17], clause 5.4.2.1). UL: Indicates the maximum
@ -466,6 +466,8 @@ SRSRAN_API bool srsran_tdd_nr_is_dl(const srsran_tdd_config_nr_t* cfg, uint32_t
*/
SRSRAN_API bool srsran_tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx);
SRSRAN_API int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran_cell_t* cell);
#ifdef __cplusplus
}
#endif

View File

@ -37,6 +37,8 @@ typedef struct SRSRAN_API {
srsran_sch_nr_args_t sch;
bool measure_evm;
bool measure_time;
uint32_t max_prb;
uint32_t max_layers;
} srsran_pdsch_nr_args_t;
/**

View File

@ -31,6 +31,8 @@ typedef struct SRSRAN_API {
srsran_uci_nr_args_t uci;
bool measure_evm;
bool measure_time;
uint32_t max_layers;
uint32_t max_prb;
} srsran_pusch_nr_args_t;
/**

View File

@ -39,6 +39,11 @@
*/
#define DMRS_SCH_SMOOTH_FILTER_STDDEV 2
/**
* @brief Default number of PRB at initialization
*/
#define DMRS_SCH_MAX_NOF_PRB 106
int srsran_dmrs_sch_cfg_to_str(const srsran_dmrs_sch_cfg_t* cfg, char* msg, uint32_t max_len)
{
int type = (int)cfg->type + 1;
@ -517,6 +522,58 @@ static uint32_t srsran_dmrs_sch_seed(const srsran_carrier_nr_t* carrier,
(2UL * n_id + n_scid));
}
static int dmrs_sch_alloc(srsran_dmrs_sch_t* q, uint32_t max_nof_prb)
{
bool max_nof_prb_changed = q->max_nof_prb < max_nof_prb;
// Update maximum number of PRB
q->max_nof_prb = max_nof_prb;
// Resize/allocate temp for gNb and UE
if (max_nof_prb_changed) {
if (q->temp) {
free(q->temp);
}
q->temp = srsran_vec_cf_malloc(max_nof_prb * SRSRAN_NRE);
if (!q->temp) {
ERROR("malloc");
return SRSRAN_ERROR;
}
}
// If it is not UE, quit now
if (!q->is_rx) {
return SRSRAN_SUCCESS;
}
if (max_nof_prb_changed) {
// Resize interpolator only if the number of PRB has increased
srsran_interp_linear_free(&q->interpolator_type1);
srsran_interp_linear_free(&q->interpolator_type2);
if (srsran_interp_linear_init(&q->interpolator_type1, max_nof_prb * SRSRAN_NRE / 2, 2) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
if (srsran_interp_linear_init(&q->interpolator_type2, max_nof_prb * SRSRAN_NRE / 3, 6) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
if (q->pilot_estimates) {
free(q->pilot_estimates);
}
// The maximum number of pilots is for Type 1
q->pilot_estimates = srsran_vec_cf_malloc(SRSRAN_DMRS_SCH_MAX_SYMBOLS * max_nof_prb * SRSRAN_NRE / 2);
if (!q->pilot_estimates) {
ERROR("malloc");
return SRSRAN_ERROR;
}
}
return SRSRAN_SUCCESS;
}
int srsran_dmrs_sch_init(srsran_dmrs_sch_t* q, bool is_rx)
{
if (q == NULL) {
@ -539,6 +596,10 @@ int srsran_dmrs_sch_init(srsran_dmrs_sch_t* q, bool is_rx)
}
#endif // DMRS_SCH_SMOOTH_FILTER_LEN
if (dmrs_sch_alloc(q, DMRS_SCH_MAX_NOF_PRB) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
}
@ -565,52 +626,11 @@ void srsran_dmrs_sch_free(srsran_dmrs_sch_t* q)
int srsran_dmrs_sch_set_carrier(srsran_dmrs_sch_t* q, const srsran_carrier_nr_t* carrier)
{
bool max_nof_prb_changed = q->max_nof_prb < carrier->nof_prb;
// Set carrier
q->carrier = *carrier;
// Set carrier and update maximum number of PRB
q->carrier = *carrier;
q->max_nof_prb = SRSRAN_MAX(q->max_nof_prb, carrier->nof_prb);
// Resize/allocate temp for gNb and UE
if (max_nof_prb_changed) {
if (q->temp) {
free(q->temp);
}
q->temp = srsran_vec_cf_malloc(q->max_nof_prb * SRSRAN_NRE);
if (!q->temp) {
ERROR("malloc");
return SRSRAN_ERROR;
}
}
// If it is not UE, quit now
if (!q->is_rx) {
return SRSRAN_SUCCESS;
}
if (max_nof_prb_changed) {
// Resize interpolator only if the number of PRB has increased
srsran_interp_linear_free(&q->interpolator_type1);
srsran_interp_linear_free(&q->interpolator_type2);
if (srsran_interp_linear_init(&q->interpolator_type1, carrier->nof_prb * SRSRAN_NRE / 2, 2) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
if (srsran_interp_linear_init(&q->interpolator_type2, carrier->nof_prb * SRSRAN_NRE / 3, 6) != SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
if (q->pilot_estimates) {
free(q->pilot_estimates);
}
// The maximum number of pilots is for Type 1
q->pilot_estimates = srsran_vec_cf_malloc(SRSRAN_DMRS_SCH_MAX_SYMBOLS * q->max_nof_prb * SRSRAN_NRE / 2);
if (!q->pilot_estimates) {
ERROR("malloc");
return SRSRAN_ERROR;
}
if (dmrs_sch_alloc(q, carrier->nof_prb) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
@ -639,7 +659,7 @@ int srsran_dmrs_sch_put_sf(srsran_dmrs_sch_t* q,
// Iterate symbols
for (uint32_t i = 0; i < nof_symbols; i++) {
uint32_t l = symbols[i]; // Symbol index inside the slot
uint32_t l = symbols[i]; // Symbol index inside the slot
uint32_t slot_idx = SRSRAN_SLOT_NR_MOD(q->carrier.scs, slot_cfg->idx); // Slot index in the frame
uint32_t cinit = srsran_dmrs_sch_seed(&q->carrier, pdsch_cfg, grant, slot_idx, l);
@ -770,8 +790,7 @@ int srsran_dmrs_sch_estimate(srsran_dmrs_sch_t* q,
for (uint32_t i = 0; i < nof_symbols; i++) {
uint32_t l = symbols[i]; // Symbol index inside the slot
uint32_t cinit =
srsran_dmrs_sch_seed(&q->carrier, cfg, grant, SRSRAN_SLOT_NR_MOD(q->carrier.scs, slot->idx), l);
uint32_t cinit = srsran_dmrs_sch_seed(&q->carrier, cfg, grant, SRSRAN_SLOT_NR_MOD(q->carrier.scs, slot->idx), l);
nof_pilots_x_symbol = srsran_dmrs_sch_get_symbol(
q, cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l], &q->pilot_estimates[nof_pilots_x_symbol * i]);
@ -842,8 +861,7 @@ int srsran_dmrs_sch_estimate(srsran_dmrs_sch_t* q,
cf_t cfo_correction[SRSRAN_NSYMB_PER_SLOT_NR] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
if (isnormal(cfo_avg)) {
// Calculate phase of the first OFDM symbol (l = 0)
float arg0 =
cargf(corr[0]) - 2.0f * M_PI * srsran_symbol_distance_s(0, symbols[0], q->carrier.scs) * cfo_avg;
float arg0 = cargf(corr[0]) - 2.0f * M_PI * srsran_symbol_distance_s(0, symbols[0], q->carrier.scs) * cfo_avg;
// Calculate CFO corrections
for (uint32_t l = 0; l < SRSRAN_NSYMB_PER_SLOT_NR; l++) {

View File

@ -11,6 +11,7 @@
*/
#include "srsran/phy/common/phy_common_nr.h"
#include "srsran/phy/utils/vector.h"
#include <string.h>
const char* srsran_rnti_type_str(srsran_rnti_type_t rnti_type)
@ -236,3 +237,33 @@ bool srsran_tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology,
// Check UL boundaries
return (slot_idx_period > start_ul || (slot_idx_period == start_ul && pattern->nof_ul_symbols != 0));
}
int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran_cell_t* cell)
{
// Protect memory access
if (carrier == NULL || cell == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
// Ensure cell is initialised+
SRSRAN_MEM_ZERO(cell, srsran_cell_t, 1);
// Select number of PRB
if (carrier->nof_prb <= 25) {
cell->nof_prb = 25;
} else if (carrier->nof_prb <= 52) {
cell->nof_prb = 50;
} else if (carrier->nof_prb <= 79) {
cell->nof_prb = 75;
} else if (carrier->nof_prb <= 106) {
cell->nof_prb = 100;
} else {
return SRSRAN_ERROR_OUT_OF_BOUNDS;
}
// Set other parameters
cell->id = carrier->pci;
cell->nof_ports = carrier->max_mimo_layers;
return SRSRAN_SUCCESS;
}

View File

@ -17,6 +17,33 @@
#include "srsran/phy/mimo/precoding.h"
#include "srsran/phy/modem/demod_soft.h"
static int pdsch_nr_alloc(srsran_pdsch_nr_t* q, uint32_t max_mimo_layers, uint32_t max_prb)
{
// Reallocate symbols if necessary
if (q->max_layers < max_mimo_layers || q->max_prb < max_prb) {
q->max_layers = max_mimo_layers;
q->max_prb = max_prb;
// Free current allocations
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
if (q->x[i] != NULL) {
free(q->x[i]);
}
}
// Allocate for new sizes
for (uint32_t i = 0; i < q->max_layers; i++) {
q->x[i] = srsran_vec_cf_malloc(SRSRAN_SLOT_LEN_RE_NR(q->max_prb));
if (q->x[i] == NULL) {
ERROR("Malloc");
return SRSRAN_ERROR;
}
}
}
return SRSRAN_SUCCESS;
}
int pdsch_nr_init_common(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* args)
{
SRSRAN_MEM_ZERO(q, srsran_pdsch_nr_t, 1);
@ -31,6 +58,10 @@ int pdsch_nr_init_common(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* arg
}
}
if (pdsch_nr_alloc(q, args->max_layers, args->max_prb) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
return SRSRAN_SUCCESS;
}
@ -85,26 +116,8 @@ int srsran_pdsch_nr_set_carrier(srsran_pdsch_nr_t* q, const srsran_carrier_nr_t*
// Set carrier
q->carrier = *carrier;
// Reallocate symbols if necessary
if (q->max_layers < carrier->max_mimo_layers || q->max_prb < carrier->nof_prb) {
q->max_layers = carrier->max_mimo_layers;
q->max_prb = carrier->nof_prb;
// Free current allocations
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
if (q->x[i] != NULL) {
free(q->x[i]);
}
}
// Allocate for new sizes
for (uint32_t i = 0; i < q->max_layers; i++) {
q->x[i] = srsran_vec_cf_malloc(SRSRAN_SLOT_LEN_RE_NR(q->max_prb));
if (q->x[i] == NULL) {
ERROR("Malloc");
return SRSRAN_ERROR;
}
}
if (pdsch_nr_alloc(q, carrier->max_mimo_layers, carrier->nof_prb) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
// Allocate code words according to table 7.3.1.3-1

View File

@ -18,6 +18,33 @@
#include "srsran/phy/phch/ra_nr.h"
#include "srsran/phy/phch/uci_cfg.h"
static int pusch_nr_alloc(srsran_pusch_nr_t* q, uint32_t max_mimo_layers, uint32_t max_prb)
{
// Reallocate symbols if necessary
if (q->max_layers < max_mimo_layers || q->max_prb < max_prb) {
q->max_layers = max_mimo_layers;
q->max_prb = max_prb;
// Free current allocations
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
if (q->x[i] != NULL) {
free(q->x[i]);
}
}
// Allocate for new sizes
for (uint32_t i = 0; i < q->max_layers; i++) {
q->x[i] = srsran_vec_cf_malloc(SRSRAN_SLOT_LEN_RE_NR(q->max_prb));
if (q->x[i] == NULL) {
ERROR("Malloc");
return SRSRAN_ERROR;
}
}
}
return SRSRAN_SUCCESS;
}
int pusch_nr_init_common(srsran_pusch_nr_t* q, const srsran_pusch_nr_args_t* args)
{
for (srsran_mod_t mod = SRSRAN_MOD_BPSK; mod < SRSRAN_MOD_NITEMS; mod++) {
@ -30,6 +57,10 @@ int pusch_nr_init_common(srsran_pusch_nr_t* q, const srsran_pusch_nr_args_t* arg
}
}
if (pusch_nr_alloc(q, args->max_layers, args->max_prb) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
if (srsran_uci_nr_init(&q->uci, &args->uci) < SRSRAN_SUCCESS) {
ERROR("Initialising UCI");
return SRSRAN_ERROR;
@ -107,26 +138,8 @@ int srsran_pusch_nr_set_carrier(srsran_pusch_nr_t* q, const srsran_carrier_nr_t*
// Set carrier
q->carrier = *carrier;
// Reallocate symbols if necessary
if (q->max_layers < carrier->max_mimo_layers || q->max_prb < carrier->nof_prb) {
q->max_layers = carrier->max_mimo_layers;
q->max_prb = carrier->nof_prb;
// Free current allocations
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
if (q->x[i] != NULL) {
free(q->x[i]);
}
}
// Allocate for new sizes
for (uint32_t i = 0; i < q->max_layers; i++) {
q->x[i] = srsran_vec_cf_malloc(SRSRAN_SLOT_LEN_RE_NR(q->max_prb));
if (q->x[i] == NULL) {
ERROR("Malloc");
return SRSRAN_ERROR;
}
}
if (pusch_nr_alloc(q, carrier->max_mimo_layers, carrier->nof_prb) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
// Allocate code words according to table 7.3.1.3-1

View File

@ -87,7 +87,7 @@ int srsran_ue_dl_nr_init(srsran_ue_dl_nr_t* q, cf_t* input[SRSRAN_MAX_PORTS], co
srsran_ofdm_cfg_t fft_cfg = {};
fft_cfg.nof_prb = args->nof_max_prb;
fft_cfg.symbol_sz = srsran_symbol_sz(args->nof_max_prb);
fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(args->nof_max_prb);
fft_cfg.keep_dc = true;
fft_cfg.rx_window_offset = UE_DL_NR_FFT_WINDOW_OFFSET;

View File

@ -60,7 +60,7 @@ bool cc_worker::set_carrier(const srsran_carrier_nr_t* carrier)
coreset.freq_resources[0] = true; // Enable the bottom 6 PRB for PDCCH
coreset.duration = 2;
srsran_dci_cfg_nr_t dci_cfg = phy_state->cfg.get_dci_cfg(*carrier);
srsran_dci_cfg_nr_t dci_cfg = phy_state->cfg.get_dci_cfg();
if (srsran_enb_dl_nr_set_pdcch_config(&enb_dl, &phy_state->cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) {
ERROR("Error setting coreset");
return false;

View File

@ -25,7 +25,6 @@ public:
cc_worker(uint32_t cc_idx, srslog::basic_logger& log, state* phy_state_);
~cc_worker();
bool set_carrier(const srsran_carrier_nr_t* carrier);
bool update_cfg();
void set_tti(uint32_t tti);

View File

@ -34,7 +34,6 @@ public:
sf_worker(phy_common* phy, state* phy_state_, srslog::basic_logger& logger);
~sf_worker() = default;
bool set_carrier_unlocked(uint32_t cc_idx, const srsran_carrier_nr_t* carrier_);
bool update_cfg(uint32_t cc_idx);
/* Functions used by main PHY thread */

View File

@ -48,6 +48,7 @@ private:
srsran::circular_array<srsran_pdsch_ack_nr_t, TTIMOD_SZ> pending_ack = {};
mutable std::mutex pending_ack_mutex;
/// Metrics section
info_metrics_t info_metrics = {};
sync_metrics_t sync_metrics = {};
ch_metrics_t ch_metrics = {};
@ -70,8 +71,7 @@ private:
}
public:
mac_interface_phy_nr* stack = nullptr;
srsran_carrier_nr_t carrier = {};
mac_interface_phy_nr* stack = nullptr;
/// Physical layer user configuration
phy_args_nr_t args = {};
@ -86,12 +86,6 @@ public:
state()
{
carrier.pci = 500;
carrier.nof_prb = 100;
carrier.max_mimo_layers = 1;
info_metrics.pci = carrier.pci;
// Hard-coded values, this should be set when the measurements take place
csi_measurements[0].K_csi_rs = 1;
csi_measurements[0].nof_ports = 1;
@ -108,7 +102,7 @@ public:
{
// Convert UL DCI to grant
srsran_sch_cfg_nr_t pusch_cfg = {};
if (srsran_ra_ul_dci_to_grant_nr(&carrier, &cfg.pusch, &dci_ul, &pusch_cfg, &pusch_cfg.grant)) {
if (srsran_ra_ul_dci_to_grant_nr(&cfg.carrier, &cfg.pusch, &dci_ul, &pusch_cfg, &pusch_cfg.grant)) {
std::array<char, 512> str;
srsran_dci_ul_nr_to_str(&dci_ul, str.data(), str.size());
ERROR("Computing UL grant %s", str.data());
@ -167,7 +161,7 @@ public:
{
// Convert DL DCI to grant
srsran_sch_cfg_nr_t pdsch_cfg = {};
if (srsran_ra_dl_dci_to_grant_nr(&carrier, &slot, &cfg.pdsch, &dci_dl, &pdsch_cfg, &pdsch_cfg.grant)) {
if (srsran_ra_dl_dci_to_grant_nr(&cfg.carrier, &slot, &cfg.pdsch, &dci_dl, &pdsch_cfg, &pdsch_cfg.grant)) {
ERROR("Computing UL grant");
return;
}

View File

@ -119,7 +119,7 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
("rat.nr.dl_arfcn", bpo::value<string>(&args->phy.dl_nr_arfcn)->default_value("634240"), "Downlink NR-ARFCN list")
("rat.nr.dl_freq", bpo::value<double>(&args->phy.nr_freq_hz)->default_value(3513.6e6), "NR DL frequency")
("rat.nr.nof_carriers", bpo::value<uint32_t>(&args->phy.nof_nr_carriers)->default_value(0), "Number of NR carriers")
("rat.nr.nof_prb", bpo::value<uint32_t>(&args->phy.nr_nof_prb)->default_value(52), "NR carrier bandwidth")
("rat.nr.max_nof_prb", bpo::value<uint32_t>(&args->phy.nr_max_nof_prb)->default_value(106), "Maximum NR carrier bandwidth in PRB")
("rrc.feature_group", bpo::value<uint32_t>(&args->stack.rrc.feature_group)->default_value(0xe6041000), "Hex value of the featureGroupIndicators field in the"
"UECapabilityInformation message. Default 0xe6041000")

View File

@ -56,28 +56,19 @@ cc_worker::~cc_worker()
}
}
bool cc_worker::set_carrier(const srsran_carrier_nr_t* carrier)
{
if (srsran_ue_dl_nr_set_carrier(&ue_dl, carrier) < SRSRAN_SUCCESS) {
ERROR("Error setting carrier");
return false;
}
if (srsran_ue_ul_nr_set_carrier(&ue_ul, carrier) < SRSRAN_SUCCESS) {
ERROR("Error setting carrier");
return false;
}
// Set default PDSCH config
phy->cfg.pdsch.rbg_size_cfg_1 = false;
return true;
}
bool cc_worker::update_cfg()
{
srsran_dci_cfg_nr_t dci_cfg = phy->cfg.get_dci_cfg(phy->carrier);
if (srsran_ue_dl_nr_set_carrier(&ue_dl, &phy->cfg.carrier) < SRSRAN_SUCCESS) {
ERROR("Error setting carrier");
return false;
}
if (srsran_ue_ul_nr_set_carrier(&ue_ul, &phy->cfg.carrier) < SRSRAN_SUCCESS) {
ERROR("Error setting carrier");
return false;
}
srsran_dci_cfg_nr_t dci_cfg = phy->cfg.get_dci_cfg();
if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &phy->cfg.pdcch, &dci_cfg) < SRSRAN_SUCCESS) {
logger.error("Error setting NR PDCCH configuration");
return false;
@ -278,12 +269,8 @@ bool cc_worker::work_dl()
str.data(),
str_extra.data());
} else {
logger.info(pdsch_res.tb[0].payload,
pdsch_cfg.grant.tb[0].tbs / 8,
"PDSCH: cc=%d pid=%d %s",
cc_idx,
pid,
str.data());
logger.info(
pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d pid=%d %s", cc_idx, pid, str.data());
}
}
@ -391,7 +378,7 @@ bool cc_worker::work_ul()
}
// Set UCI configuration following procedures
srsran_ra_ul_set_grant_uci_nr(&phy->carrier, &phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
srsran_ra_ul_set_grant_uci_nr(&phy->cfg.carrier, &phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
// Assigning MAC provided values to PUSCH config structs
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;

View File

@ -36,15 +36,6 @@ sf_worker::sf_worker(phy_common* phy_, state* phy_state_, srslog::basic_logger&
}
}
bool sf_worker::set_carrier_unlocked(uint32_t cc_idx, const srsran_carrier_nr_t* carrier_)
{
if (cc_idx >= cc_workers.size()) {
return false;
}
return cc_workers.at(cc_idx)->set_carrier(carrier_);
}
bool sf_worker::update_cfg(uint32_t cc_idx)
{
if (cc_idx >= cc_workers.size()) {
@ -99,7 +90,7 @@ void sf_worker::work_imp()
// Notify MAC about PRACH transmission
phy_state->stack->prach_sent(TTI_TX(tti_rx),
srsran_prach_nr_start_symbol_fr1_unpaired(phy_state->cfg.prach.config_idx),
SRSRAN_SLOT_NR_MOD(phy_state->carrier.scs, TTI_TX(tti_rx)),
SRSRAN_SLOT_NR_MOD(phy_state->cfg.carrier.scs, TTI_TX(tti_rx)),
0,
0);

View File

@ -22,12 +22,15 @@ bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_inte
phy_state.args = args;
// Set carrier attributes
phy_state.carrier.pci = 500;
phy_state.carrier.nof_prb = args.nof_prb;
phy_state.cfg.carrier.pci = 500;
phy_state.cfg.carrier.nof_prb = args.max_nof_prb;
// Set NR arguments
phy_state.args.nof_carriers = args.nof_carriers;
phy_state.args.dl.nof_max_prb = args.nof_prb;
phy_state.args.nof_carriers = args.nof_carriers;
phy_state.args.dl.nof_max_prb = args.max_nof_prb;
phy_state.args.dl.pdsch.max_prb = args.max_nof_prb;
phy_state.args.ul.nof_max_prb = args.max_nof_prb;
phy_state.args.ul.pusch.max_prb = args.max_nof_prb;
// Skip init of workers if no NR carriers
if (phy_state.args.nof_carriers == 0) {
@ -43,10 +46,6 @@ bool worker_pool::init(const phy_args_nr_t& args, phy_common* common, stack_inte
auto w = new sf_worker(common, &phy_state, log);
pool.init_worker(i, w, prio, args.worker_cpu_mask);
workers.push_back(std::unique_ptr<sf_worker>(w));
if (not w->set_carrier_unlocked(0, &phy_state.carrier)) {
return false;
}
}
// Set PHY loglevel
@ -74,7 +73,7 @@ sf_worker* worker_pool::wait_worker(uint32_t tti)
sf_worker* worker = (sf_worker*)pool.wait_worker(tti);
// Generate PRACH if ready
if (prach_buffer->is_ready_to_send(tti, phy_state.carrier.pci)) {
if (prach_buffer->is_ready_to_send(tti, phy_state.cfg.carrier.pci)) {
uint32_t nof_prach_sf = 0;
float prach_target_power = 0.0f;
cf_t* prach_ptr = prach_buffer->generate(0.0f, &nof_prach_sf, &prach_target_power);
@ -128,12 +127,14 @@ bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg)
{
phy_state.cfg = cfg;
// Set PRACH hard-coded cell
logger.error(
"Setting new PHY configuration ARFCN=%d, PCI=%d", cfg.carrier.absolute_frequency_point_a, cfg.carrier.pci);
// Best effort to convert NR carrier into LTE cell
srsran_cell_t cell = {};
cell.nof_prb = 50;
cell.id = phy_state.carrier.pci;
if (not prach_buffer->set_cell(cell, phy_state.cfg.prach)) {
logger.error("Error setting PRACH cell");
int ret = srsran_carrier_to_cell(&phy_state.cfg.carrier, &cell);
if (ret < SRSRAN_SUCCESS) {
logger.error("Converting carrier to cell for PRACH (%d)", ret);
return false;
}
@ -144,6 +145,21 @@ bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg)
}
}
// Best effort to set up NR-PRACH config reused for NR
srsran_prach_cfg_t prach_cfg = cfg.prach;
uint32_t lte_nr_prach_offset = (phy_state.cfg.carrier.nof_prb - cell.nof_prb) / 2;
if (prach_cfg.freq_offset < lte_nr_prach_offset) {
logger.error("prach_cfg.freq_offset=%d is not compatible with LTE", prach_cfg.freq_offset);
return false;
}
prach_cfg.freq_offset -= lte_nr_prach_offset;
// Set the PRACH configuration
if (not prach_buffer->set_cell(cell, prach_cfg)) {
logger.error("Error setting PRACH cell");
return false;
}
return true;
}

View File

@ -93,7 +93,7 @@ int ue::init(const all_args_t& args_)
}
srsue::phy_args_nr_t phy_args_nr = {};
phy_args_nr.nof_prb = args.phy.nr_nof_prb;
phy_args_nr.max_nof_prb = args.phy.nr_max_nof_prb;
phy_args_nr.nof_carriers = args.phy.nof_nr_carriers;
phy_args_nr.nof_phy_threads = args.phy.nof_phy_threads;
phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask;
@ -209,8 +209,8 @@ int ue::parse_args(const all_args_t& args_)
}
// replicate some RF parameter to make them available to PHY
args.phy.nof_rx_ant = args.rf.nof_antennas;
args.phy.agc_enable = args.rf.rx_gain < 0.0f;
args.phy.nof_rx_ant = args.rf.nof_antennas;
args.phy.agc_enable = args.rf.rx_gain < 0.0f;
// populate DL EARFCN list
if (not args.phy.dl_earfcn.empty()) {