Refactored NR PHY configuration to accept multiple CORESETs/SearchSpaces

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent a85d79c6b7
commit b652cd68a5

@ -242,8 +242,9 @@ typedef struct SRSLTE_API {
* @brief CORESET parameters as defined in TS 38.331 V15.10.0 - ControlResourceSet * @brief CORESET parameters as defined in TS 38.331 V15.10.0 - ControlResourceSet
*/ */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_coreset_mapping_type_t mapping_type;
uint32_t id; uint32_t id;
uint32_t coreset_id;
srslte_coreset_mapping_type_t mapping_type;
uint32_t duration; uint32_t duration;
bool freq_resources[SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE]; bool freq_resources[SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE];
srslte_coreset_bundle_size_t interleaver_size; srslte_coreset_bundle_size_t interleaver_size;
@ -261,6 +262,7 @@ typedef struct SRSLTE_API {
*/ */
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t id; uint32_t id;
uint32_t coreset_id;
uint32_t duration; // in slots uint32_t duration; // in slots
srslte_search_space_type_t type; srslte_search_space_type_t type;
uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR]; uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR];

@ -104,6 +104,14 @@ SRSLTE_API int srslte_pdcch_nr_init_rx(srslte_pdcch_nr_t* q, const srslte_pdcch_
SRSLTE_API void srslte_pdcch_nr_free(srslte_pdcch_nr_t* q); SRSLTE_API void srslte_pdcch_nr_free(srslte_pdcch_nr_t* q);
/**
* @brief Sets carrier and CORESET configuration for a given PDCCH object
* @note This function shall not allocate, free memory or perform any heavy computations
* @param[in,out] q PDCCH encoder/decoder object
* @param[in] carrier New carrier configuration
* @param[in] coreset New CORESET configuration
* @return SRSLTE_SUCCESS if the configurations are valid, otherwise it returns an SRSLTE_ERROR code
*/
SRSLTE_API int SRSLTE_API int
srslte_pdcch_nr_set_carrier(srslte_pdcch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset); srslte_pdcch_nr_set_carrier(srslte_pdcch_nr_t* q, const srslte_carrier_nr_t* carrier, const srslte_coreset_t* coreset);

@ -20,22 +20,47 @@
#include "srslte/phy/phch/pdcch_nr.h" #include "srslte/phy/phch/pdcch_nr.h"
#include "srslte/phy/phch/pdsch_nr.h" #include "srslte/phy/phch/pdsch_nr.h"
/**
* Maximum number of CORESET
* @remark Defined in TS 38.331 by maxNrofControlResourceSets-1
*/
#define SRSLTE_UE_DL_NR_MAX_NOF_CORESET 12
/**
* Maximum number of Search spaces
* @remark Defined in TS 38.331 by maxNrofSearchSpaces-1
*/
#define SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE 40
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_pdsch_nr_args_t pdsch; srslte_pdsch_nr_args_t pdsch;
srslte_pdcch_nr_args_t pdcch; srslte_pdcch_nr_args_t pdcch;
uint32_t nof_rx_antennas; uint32_t nof_rx_antennas;
uint32_t nof_max_prb; uint32_t nof_max_prb;
float pdcch_dmrs_corr_thr; float pdcch_dmrs_corr_thr;
float pdcch_dmrs_epre_thr;
} srslte_ue_dl_nr_args_t; } srslte_ue_dl_nr_args_t;
typedef struct SRSLTE_API {
srslte_coreset_t coreset[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; ///< PDCCH Control resource sets (CORESET) collection
bool coreset_present[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; ///< CORESET present flags
srslte_search_space_t search_space[SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE];
bool search_space_present[SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE];
uint32_t ra_rnti; ///< Deduced from the PRACH configuration
uint32_t ra_search_space_id;
uint32_t ra_search_space_present;
} srslte_ue_dl_nr_pdcch_cfg_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t max_prb; uint32_t max_prb;
uint32_t nof_rx_antennas; uint32_t nof_rx_antennas;
float pdcch_dmrs_corr_thr; float pdcch_dmrs_corr_thr;
float pdcch_dmrs_epre_thr; float pdcch_dmrs_epre_thr;
srslte_carrier_nr_t carrier; srslte_carrier_nr_t carrier;
srslte_coreset_t coreset; srslte_ue_dl_nr_pdcch_cfg_t cfg;
srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
@ -44,7 +69,7 @@ typedef struct SRSLTE_API {
srslte_pdsch_nr_t pdsch; srslte_pdsch_nr_t pdsch;
srslte_dmrs_sch_t dmrs_pdsch; srslte_dmrs_sch_t dmrs_pdsch;
srslte_dmrs_pdcch_estimator_t dmrs_pdcch; srslte_dmrs_pdcch_estimator_t dmrs_pdcch[SRSLTE_UE_DL_NR_MAX_NOF_CORESET];
srslte_pdcch_nr_t pdcch; srslte_pdcch_nr_t pdcch;
srslte_dmrs_pdcch_ce_t* pdcch_ce; srslte_dmrs_pdcch_ce_t* pdcch_ce;
} srslte_ue_dl_nr_t; } srslte_ue_dl_nr_t;
@ -54,29 +79,27 @@ srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], const
SRSLTE_API int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier); SRSLTE_API int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier);
SRSLTE_API int srslte_ue_dl_nr_set_coreset(srslte_ue_dl_nr_t* q, const srslte_coreset_t* coreset); SRSLTE_API int srslte_ue_dl_nr_set_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_pdcch_cfg_t* cfg);
SRSLTE_API void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q); SRSLTE_API void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q);
SRSLTE_API void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg); SRSLTE_API void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg);
SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
const srslte_search_space_t* search_space, const srslte_dl_slot_cfg_t* slot_cfg,
const srslte_dl_slot_cfg_t* slot_cfg, uint16_t rnti,
uint16_t rnti, srslte_dci_dl_nr_t* dci_dl_list,
srslte_dci_dl_nr_t* dci_dl_list, uint32_t nof_dci_msg);
uint32_t nof_dci_msg);
SRSLTE_API int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, SRSLTE_API int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_dl_slot_cfg_t* slot,
const srslte_sch_cfg_nr_t* cfg, const srslte_sch_cfg_nr_t* cfg,
srslte_pdsch_res_nr_t* res); srslte_pdsch_res_nr_t* res);
SRSLTE_API int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, SRSLTE_API int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q,
const srslte_sch_cfg_nr_t* cfg, const srslte_sch_cfg_nr_t* cfg,
const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS],
char* str, char* str,
uint32_t str_len); uint32_t str_len);
#endif // SRSLTE_UE_DL_NR_H #endif // SRSLTE_UE_DL_NR_H

@ -187,6 +187,7 @@ int main(int argc, char** argv)
// Init MSG // Init MSG
srslte_dci_msg_nr_t dci_msg = {}; srslte_dci_msg_nr_t dci_msg = {};
dci_msg.format = srslte_dci_format_nr_1_0;
dci_msg.rnti_type = srslte_rnti_type_c; dci_msg.rnti_type = srslte_rnti_type_c;
dci_msg.location.L = aggregation_level; dci_msg.location.L = aggregation_level;
dci_msg.location.ncce = dci_locations[ncce_idx]; dci_msg.location.ncce = dci_locations[ncce_idx];

@ -52,8 +52,17 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
q->nof_rx_antennas = args->nof_rx_antennas; q->nof_rx_antennas = args->nof_rx_antennas;
q->pdcch_dmrs_corr_thr = args->pdcch_dmrs_corr_thr; if (isnormal(args->pdcch_dmrs_corr_thr)) {
q->pdcch_dmrs_corr_thr = args->pdcch_dmrs_corr_thr;
} else {
q->pdcch_dmrs_corr_thr = UE_DL_NR_PDCCH_CORR_DEFAULT_THR;
}
if (isnormal(args->pdcch_dmrs_epre_thr)) {
q->pdcch_dmrs_epre_thr = args->pdcch_dmrs_epre_thr;
} else {
q->pdcch_dmrs_epre_thr = UE_DL_NR_PDCCH_EPRE_DEFAULT_THR;
}
if (srslte_pdsch_nr_init_ue(&q->pdsch, &args->pdsch) < SRSLTE_SUCCESS) { if (srslte_pdsch_nr_init_ue(&q->pdsch, &args->pdsch) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -110,14 +119,17 @@ void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q)
srslte_chest_dl_res_free(&q->chest); srslte_chest_dl_res_free(&q->chest);
srslte_pdsch_nr_free(&q->pdsch); srslte_pdsch_nr_free(&q->pdsch);
srslte_dmrs_sch_free(&q->dmrs_pdsch); srslte_dmrs_sch_free(&q->dmrs_pdsch);
srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch);
for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) {
srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch[i]);
}
srslte_pdcch_nr_free(&q->pdcch); srslte_pdcch_nr_free(&q->pdcch);
if (q->pdcch_ce) { if (q->pdcch_ce) {
free(q->pdcch_ce); free(q->pdcch_ce);
} }
memset(q, 0, sizeof(srslte_ue_dl_nr_t)); SRSLTE_MEM_ZERO(q, srslte_ue_dl_nr_t, 1);
} }
int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier) int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* carrier)
@ -151,20 +163,22 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t*
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_ue_dl_nr_set_coreset(srslte_ue_dl_nr_t* q, const srslte_coreset_t* coreset) int srslte_ue_dl_nr_set_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_pdcch_cfg_t* cfg)
{ {
if (q == NULL || coreset == NULL) { if (q == NULL || cfg == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
q->coreset = *coreset; // Copy new configuration
q->cfg = *cfg;
if (srslte_dmrs_pdcch_estimator_init(&q->dmrs_pdcch, &q->carrier, &q->coreset) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
if (srslte_pdcch_nr_set_carrier(&q->pdcch, &q->carrier, &q->coreset) < SRSLTE_SUCCESS) { // iterate over all possible CORESET and initialise/update the present ones
return SRSLTE_ERROR; for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) {
if (cfg->coreset_present[i]) {
if (srslte_dmrs_pdcch_estimator_init(&q->dmrs_pdcch[i], &q->carrier, &cfg->coreset[i]) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
}
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -181,15 +195,23 @@ void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg
srslte_ofdm_rx_sf(&q->fft[i]); srslte_ofdm_rx_sf(&q->fft[i]);
} }
// Estimate PDCCH channel // Estimate PDCCH channel for every configured CORESET
srslte_dmrs_pdcch_estimate(&q->dmrs_pdcch, slot_cfg, q->sf_symbols[0]); for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_CORESET; i++) {
if (q->cfg.coreset_present[i]) {
srslte_dmrs_pdcch_estimate(&q->dmrs_pdcch[i], slot_cfg, q->sf_symbols[0]);
}
}
} }
static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q, srslte_dci_msg_nr_t* dci_msg, srslte_pdcch_nr_res_t* pdcch_res) static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q,
srslte_dci_msg_nr_t* dci_msg,
srslte_pdcch_nr_res_t* pdcch_res,
uint32_t coreset_id)
{ {
srslte_dmrs_pdcch_measure_t m = {}; srslte_dmrs_pdcch_measure_t m = {};
if (srslte_dmrs_pdcch_get_measure(&q->dmrs_pdcch, &dci_msg->location, &m) < SRSLTE_SUCCESS) { // Measures the PDCCH transmission DMRS
if (srslte_dmrs_pdcch_get_measure(&q->dmrs_pdcch[coreset_id], &dci_msg->location, &m) < SRSLTE_SUCCESS) {
ERROR("Error getting measure location L=%d, ncce=%d\n", dci_msg->location.L, dci_msg->location.ncce); ERROR("Error getting measure location L=%d, ncce=%d\n", dci_msg->location.L, dci_msg->location.ncce);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -201,39 +223,29 @@ static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q, srslte_dci_msg_nr_t* dci
} }
// Compare EPRE with threshold // Compare EPRE with threshold
{ if (m.epre_dBfs < q->pdcch_dmrs_epre_thr) {
float thr = q->pdcch_dmrs_epre_thr; INFO("Discarded PDCCH candidate L=%d;ncce=%d; EPRE is too weak (%.1f<%.1f);\n",
if (!isnormal(thr)) { dci_msg->location.L,
thr = UE_DL_NR_PDCCH_EPRE_DEFAULT_THR; //< Load default threshold if not provided dci_msg->location.ncce,
} m.epre_dBfs,
if (m.epre_dBfs < thr) { q->pdcch_dmrs_epre_thr);
INFO("Discarded PDCCH candidate L=%d;ncce=%d; EPRE is too weak (%.1f<%.1f);\n", return SRSLTE_SUCCESS;
dci_msg->location.L,
dci_msg->location.ncce,
m.epre_dBfs,
thr);
return SRSLTE_SUCCESS;
}
} }
// Compare DMRS correlation with threshold // Compare DMRS correlation with threshold
{ if (m.norm_corr < q->pdcch_dmrs_corr_thr) {
float thr = q->pdcch_dmrs_corr_thr; INFO("Discarded PDCCH candidate L=%d;ncce=%d; Correlation is too low (%.1f<%.1f); EPRE=%+.2f; RSRP=%+.2f;\n",
if (!isnormal(thr)) { dci_msg->location.L,
thr = UE_DL_NR_PDCCH_CORR_DEFAULT_THR; //< Load default threshold if not provided dci_msg->location.ncce,
} m.norm_corr,
if (m.norm_corr < thr) { q->pdcch_dmrs_corr_thr,
INFO("Discarded PDCCH candidate L=%d;ncce=%d; Correlation is too low (%.1f<%.1f);\n", m.epre_dBfs,
dci_msg->location.L, m.rsrp_dBfs);
dci_msg->location.ncce, return SRSLTE_SUCCESS;
m.norm_corr,
thr);
return SRSLTE_SUCCESS;
}
} }
// Extract PDCCH channel estimates // Extract PDCCH channel estimates
if (srslte_dmrs_pdcch_get_ce(&q->dmrs_pdcch, &dci_msg->location, q->pdcch_ce) < SRSLTE_SUCCESS) { if (srslte_dmrs_pdcch_get_ce(&q->dmrs_pdcch[coreset_id], &dci_msg->location, q->pdcch_ce) < SRSLTE_SUCCESS) {
ERROR("Error extracting PDCCH DMRS\n"); ERROR("Error extracting PDCCH DMRS\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -247,21 +259,43 @@ static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q, srslte_dci_msg_nr_t* dci
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q,
const srslte_search_space_t* search_space, const srslte_dl_slot_cfg_t* slot_cfg,
const srslte_dl_slot_cfg_t* slot_cfg, uint32_t search_space_id,
uint16_t rnti, uint16_t rnti,
srslte_dci_dl_nr_t* dci_dl_list, srslte_rnti_type_t rnti_type,
uint32_t nof_dci_msg) srslte_dci_dl_nr_t* dci_dl_list,
uint32_t nof_dci_msg)
{ {
// Check inputs
if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Select Search space
srslte_search_space_t* search_space = &q->cfg.search_space[search_space_id];
// Select CORESET
uint32_t coreset_id = search_space->coreset_id;
if (coreset_id >= SRSLTE_UE_DL_NR_MAX_NOF_CORESET || !q->cfg.coreset_present[coreset_id]) {
ERROR("CORESET %d is not present in search space %d\n", search_space->coreset_id, search_space->id);
return SRSLTE_ERROR;
}
srslte_coreset_t* coreset = &q->cfg.coreset[search_space->coreset_id];
// Set CORESET in PDCCH decoder
if (srslte_pdcch_nr_set_carrier(&q->pdcch, &q->carrier, coreset) < SRSLTE_SUCCESS) {
ERROR("Setting carrier and CORESETºn");
return SRSLTE_ERROR;
}
uint32_t count = 0; uint32_t count = 0;
// Hard-coded values // Hard-coded values
srslte_dci_format_nr_t dci_format = srslte_dci_format_nr_1_0; srslte_dci_format_nr_t dci_format = srslte_dci_format_nr_1_0;
srslte_rnti_type_t rnti_type = srslte_rnti_type_c;
// Calculate number of DCI bits // Calculate number of DCI bits
int dci_nof_bits = srslte_dci_nr_format_1_0_sizeof(&q->carrier, &q->coreset, rnti_type); int dci_nof_bits = srslte_dci_nr_format_1_0_sizeof(&q->carrier, coreset, rnti_type);
if (dci_nof_bits <= SRSLTE_SUCCESS) { if (dci_nof_bits <= SRSLTE_SUCCESS) {
ERROR("Error DCI size\n"); ERROR("Error DCI size\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -271,8 +305,7 @@ int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR && count < nof_dci_msg; L++) { for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR && count < nof_dci_msg; L++) {
// Calculate possible PDCCH DCI candidates // Calculate possible PDCCH DCI candidates
uint32_t candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; uint32_t candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {};
int nof_candidates = int nof_candidates = srslte_pdcch_nr_locations_coreset(coreset, search_space, rnti, L, slot_cfg->idx, candidates);
srslte_pdcch_nr_locations_coreset(&q->coreset, search_space, rnti, L, slot_cfg->idx, candidates);
if (nof_candidates < SRSLTE_SUCCESS) { if (nof_candidates < SRSLTE_SUCCESS) {
ERROR("Error calculating DCI candidate location\n"); ERROR("Error calculating DCI candidate location\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -290,12 +323,12 @@ int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
dci_msg.nof_bits = (uint32_t)dci_nof_bits; dci_msg.nof_bits = (uint32_t)dci_nof_bits;
srslte_pdcch_nr_res_t res = {}; srslte_pdcch_nr_res_t res = {};
if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res) < SRSLTE_SUCCESS) { if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res, coreset_id) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (res.crc) { if (res.crc) {
if (srslte_dci_nr_format_1_0_unpack(&q->carrier, &q->coreset, &dci_msg, &dci_dl_list[count]) < SRSLTE_SUCCESS) { if (srslte_dci_nr_format_1_0_unpack(&q->carrier, coreset, &dci_msg, &dci_dl_list[count]) < SRSLTE_SUCCESS) {
ERROR("Error unpacking DCI\n"); ERROR("Error unpacking DCI\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -309,6 +342,55 @@ int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
return (int)count; return (int)count;
} }
int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg,
uint16_t rnti,
srslte_dci_dl_nr_t* dci_dl_list,
uint32_t nof_dci_msg)
{
int count = 0;
// Check inputs
if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// If the UE looks for a RAR and RA search space is provided, search for it
if (q->cfg.ra_search_space_present && rnti == q->cfg.ra_rnti) {
// Check if the RA search space is valid
uint32_t ra_ss_id = q->cfg.ra_search_space_id;
if (ra_ss_id >= SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE || !q->cfg.search_space_present[ra_ss_id]) {
ERROR("Invalid RA Search Space ID (%d)", ra_ss_id);
return SRSLTE_ERROR;
}
// Find DCIs in the RA search space
return ue_dl_nr_find_dl_dci_ss(
q, slot_cfg, ra_ss_id, rnti, srslte_rnti_type_ra, &dci_dl_list[count], nof_dci_msg - count);
}
// Iterate all possible search spaces
for (uint32_t i = 0; i < SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE && count < nof_dci_msg; i++) {
// Skip search space if not present
if (!q->cfg.search_space_present[i]) {
continue;
}
// Find DCIs in the selected search space
int ret =
ue_dl_nr_find_dl_dci_ss(q, slot_cfg, i, rnti, srslte_rnti_type_c, &dci_dl_list[count], nof_dci_msg - count);
if (ret < SRSLTE_SUCCESS) {
ERROR("Error searching DCI");
return SRSLTE_ERROR;
}
// Count the found DCIs
count += ret;
}
return count;
}
int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_dl_slot_cfg_t* slot,
const srslte_sch_cfg_nr_t* cfg, const srslte_sch_cfg_nr_t* cfg,

@ -35,7 +35,7 @@ static srslte_sch_grant_nr_t pdsch_grant = {};
static uint16_t rnti = 0x1234; static uint16_t rnti = 0x1234;
static uint32_t nof_slots = 10; static uint32_t nof_slots = 10;
void usage(char* prog) static void usage(char* prog)
{ {
printf("Usage: %s [pTL] \n", prog); printf("Usage: %s [pTL] \n", prog);
printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb); printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb);
@ -48,7 +48,7 @@ void usage(char* prog)
printf("\t-v [set srslte_verbose to debug, default none]\n"); printf("\t-v [set srslte_verbose to debug, default none]\n");
} }
int parse_args(int argc, char** argv) static int parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "PpmnTLv")) != -1) { while ((opt = getopt(argc, argv, "PpmnTLv")) != -1) {
@ -83,12 +83,12 @@ int parse_args(int argc, char** argv)
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl, static int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl,
srslte_dl_slot_cfg_t* slot, srslte_dl_slot_cfg_t* slot,
srslte_search_space_t* search_space, srslte_search_space_t* search_space,
srslte_dci_dl_nr_t* dci_dl, srslte_dci_dl_nr_t* dci_dl,
srslte_dci_location_t* dci_location, srslte_dci_location_t* dci_location,
uint8_t** data_tx) uint8_t** data_tx)
{ {
if (srslte_enb_dl_nr_base_zero(enb_dl) < SRSLTE_SUCCESS) { if (srslte_enb_dl_nr_base_zero(enb_dl) < SRSLTE_SUCCESS) {
ERROR("Error setting base to zero\n"); ERROR("Error setting base to zero\n");
@ -120,15 +120,12 @@ int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl,
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int work_ue_dl(srslte_ue_dl_nr_t* ue_dl, static int work_ue_dl(srslte_ue_dl_nr_t* ue_dl, srslte_dl_slot_cfg_t* slot, srslte_pdsch_res_nr_t* pdsch_res)
srslte_dl_slot_cfg_t* slot,
srslte_search_space_t* search_space,
srslte_pdsch_res_nr_t* pdsch_res)
{ {
srslte_ue_dl_nr_estimate_fft(ue_dl, slot); srslte_ue_dl_nr_estimate_fft(ue_dl, slot);
srslte_dci_dl_nr_t dci_dl_rx = {}; srslte_dci_dl_nr_t dci_dl_rx = {};
int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(ue_dl, search_space, slot, rnti, &dci_dl_rx, 1); int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(ue_dl, slot, rnti, &dci_dl_rx, 1);
if (nof_found_dci < SRSLTE_SUCCESS) { if (nof_found_dci < SRSLTE_SUCCESS) {
ERROR("Error decoding\n"); ERROR("Error decoding\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -192,18 +189,22 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
srslte_ue_dl_nr_pdcch_cfg_t pdcch_cfg = {};
// Configure CORESET // Configure CORESET
srslte_coreset_t coreset = {}; srslte_coreset_t* coreset = &pdcch_cfg.coreset[0];
coreset.duration = 2; pdcch_cfg.coreset_present[0] = true;
coreset->duration = 2;
for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
coreset.freq_resources[i] = i < carrier.nof_prb / 6; coreset->freq_resources[i] = i < carrier.nof_prb / 6;
} }
// Configure Search Space // Configure Search Space
srslte_search_space_t search_space = {}; srslte_search_space_t* search_space = &pdcch_cfg.search_space[0];
search_space.type = srslte_search_space_type_ue; pdcch_cfg.search_space_present[0] = true;
search_space->type = srslte_search_space_type_ue;
for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) {
search_space.nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(&coreset, L); search_space->nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(coreset, L);
} }
if (srslte_ue_dl_nr_init(&ue_dl, &buffer, &ue_dl_args)) { if (srslte_ue_dl_nr_init(&ue_dl, &buffer, &ue_dl_args)) {
@ -221,7 +222,7 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
if (srslte_ue_dl_nr_set_coreset(&ue_dl, &coreset)) { if (srslte_ue_dl_nr_set_config(&ue_dl, &pdcch_cfg)) {
ERROR("Error setting CORESET\n"); ERROR("Error setting CORESET\n");
goto clean_exit; goto clean_exit;
} }
@ -231,7 +232,7 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
if (srslte_enb_dl_nr_set_coreset(&enb_dl, &coreset)) { if (srslte_enb_dl_nr_set_coreset(&enb_dl, coreset)) {
ERROR("Error setting CORESET\n"); ERROR("Error setting CORESET\n");
goto clean_exit; goto clean_exit;
} }
@ -315,7 +316,7 @@ int main(int argc, char** argv)
uint32_t L = 0; uint32_t L = 0;
uint32_t ncce_candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {}; uint32_t ncce_candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {};
int nof_candidates = int nof_candidates =
srslte_pdcch_nr_locations_coreset(&coreset, &search_space, rnti, L, slot.idx, ncce_candidates); srslte_pdcch_nr_locations_coreset(coreset, search_space, rnti, L, slot.idx, ncce_candidates);
if (nof_candidates < SRSLTE_SUCCESS) { if (nof_candidates < SRSLTE_SUCCESS) {
ERROR("Error getting PDCCH candidates\n"); ERROR("Error getting PDCCH candidates\n");
goto clean_exit; goto clean_exit;
@ -330,7 +331,7 @@ int main(int argc, char** argv)
srslte_dci_dl_nr_t dci_dl = {}; srslte_dci_dl_nr_t dci_dl = {};
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
if (work_gnb_dl(&enb_dl, &slot, &search_space, &dci_dl, &dci_location, data_tx) < SRSLTE_ERROR) { if (work_gnb_dl(&enb_dl, &slot, search_space, &dci_dl, &dci_location, data_tx) < SRSLTE_ERROR) {
ERROR("Error running eNb DL\n"); ERROR("Error running eNb DL\n");
goto clean_exit; goto clean_exit;
} }
@ -344,7 +345,7 @@ int main(int argc, char** argv)
} }
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
if (work_ue_dl(&ue_dl, &slot, &search_space, pdsch_res) < SRSLTE_SUCCESS) { if (work_ue_dl(&ue_dl, &slot, pdsch_res) < SRSLTE_SUCCESS) {
ERROR("Error running UE DL\n"); ERROR("Error running UE DL\n");
goto clean_exit; goto clean_exit;
} }

@ -37,8 +37,9 @@ typedef struct {
} phy_nr_args_t; } phy_nr_args_t;
typedef struct { typedef struct {
srslte_sch_cfg_nr_t pdsch; srslte_sch_cfg_nr_t pdsch;
srslte_prach_cfg_t prach; srslte_prach_cfg_t prach;
srslte_ue_dl_nr_pdcch_cfg_t pdcch;
} phy_nr_cfg_t; } phy_nr_cfg_t;
class phy_nr_state class phy_nr_state
@ -50,7 +51,7 @@ public:
phy_nr_state() phy_nr_state()
{ {
carrier.id = 0; carrier.id = 500;
carrier.nof_prb = 100; carrier.nof_prb = 100;
carrier.max_mimo_layers = 1; carrier.max_mimo_layers = 1;
@ -73,6 +74,52 @@ public:
cfg.prach.zero_corr_zone = 0; cfg.prach.zero_corr_zone = 0;
cfg.prach.num_ra_preambles = 64; cfg.prach.num_ra_preambles = 64;
cfg.prach.hs_flag = false; cfg.prach.hs_flag = false;
// commonControlResourceSet
// controlResourceSetId: 1
// frequencyDomainResources: ff0000000000
// duration: 1
// cce-REG-MappingType: nonInterleaved (1)
// nonInterleaved: NULL
// precoderGranularity: sameAsREG-bundle (0)
cfg.pdcch.coreset[1].coreset_id = 1;
cfg.pdcch.coreset[1].precoder_granularity = srslte_coreset_precoder_granularity_reg_bundle;
cfg.pdcch.coreset[1].duration = 1;
cfg.pdcch.coreset[1].mapping_type = srslte_coreset_mapping_type_non_interleaved;
for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
cfg.pdcch.coreset[1].freq_resources[i] = (i < 8);
}
cfg.pdcch.coreset_present[1] = true;
// SearchSpace
// searchSpaceId: 1
// controlResourceSetId: 1
// monitoringSlotPeriodicityAndOffset: sl1 (0)
// sl1: NULL
// monitoringSymbolsWithinSlot: 8000 [bit length 14, 2 LSB pad bits, 1000 0000 0000 00.. decimal value 8192]
// nrofCandidates
// aggregationLevel1: n0 (0)
// aggregationLevel2: n0 (0)
// aggregationLevel4: n1 (1)
// aggregationLevel8: n0 (0)
// aggregationLevel16: n0 (0)
// searchSpaceType: common (0)
// common
// dci-Format0-0-AndFormat1-0
cfg.pdcch.search_space[1].id = 1;
cfg.pdcch.search_space[1].coreset_id = 1;
cfg.pdcch.search_space[1].nof_candidates[0] = 0;
cfg.pdcch.search_space[1].nof_candidates[1] = 0;
cfg.pdcch.search_space[1].nof_candidates[2] = 1;
cfg.pdcch.search_space[1].nof_candidates[3] = 0;
cfg.pdcch.search_space[1].nof_candidates[4] = 0;
cfg.pdcch.search_space[1].type = srslte_search_space_type_common;
cfg.pdcch.search_space_present[1] = true;
// ra-SearchSpace: 1
cfg.pdcch.ra_rnti = 0x16; //< Supposed to be deduced from PRACH configuration
cfg.pdcch.ra_search_space_id = 1;
cfg.pdcch.ra_search_space_present = true;
} }
}; };
@ -108,10 +155,6 @@ private:
// Current rnti // Current rnti
uint16_t rnti = 0; uint16_t rnti = 0;
// Current coreset and search space
srslte_coreset_t coreset = {};
srslte_search_space_t search_space = {};
}; };
} // namespace nr } // namespace nr

@ -73,10 +73,7 @@ bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier)
return false; return false;
} }
coreset.freq_resources[0] = true; // Enable the bottom 6 PRB for PDCCH if (srslte_ue_dl_nr_set_config(&ue_dl, &phy_state->cfg.pdcch) < SRSLTE_SUCCESS) {
coreset.duration = 2;
if (srslte_ue_dl_nr_set_coreset(&ue_dl, &coreset) < SRSLTE_SUCCESS) {
ERROR("Error setting carrier"); ERROR("Error setting carrier");
return false; return false;
} }
@ -117,16 +114,14 @@ bool cc_worker::work_dl()
srslte_ue_dl_nr_estimate_fft(&ue_dl, &dl_slot_cfg); srslte_ue_dl_nr_estimate_fft(&ue_dl, &dl_slot_cfg);
// Set rnti // Set rnti
rnti = 0x1234; rnti = phy_state->cfg.pdcch.ra_rnti;
// Configure Search space // if (dl_slot_cfg.idx % 10 ==1) {
search_space.type = srslte_search_space_type_ue; // printf("a=");srslte_vec_fprint_c(stdout, rx_buffer[0], 512);
for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { // }
search_space.nof_candidates[L] = srslte_pdcch_nr_max_candidates_coreset(&coreset, L);
}
srslte_dci_dl_nr_t dci_dl_rx = {}; srslte_dci_dl_nr_t dci_dl_rx = {};
int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(&ue_dl, &search_space, &dl_slot_cfg, rnti, &dci_dl_rx, 1); int nof_found_dci = srslte_ue_dl_nr_find_dl_dci(&ue_dl, &dl_slot_cfg, rnti, &dci_dl_rx, 1);
if (nof_found_dci < SRSLTE_SUCCESS) { if (nof_found_dci < SRSLTE_SUCCESS) {
ERROR("Error decoding"); ERROR("Error decoding");
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -137,6 +132,12 @@ bool cc_worker::work_dl()
return true; return true;
} }
if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) {
char str[512];
srslte_dci_nr_to_str(&dci_dl_rx, str, sizeof(str));
log_h->info("PDCCH: cc=%d, %s", cc_idx, str);
}
dci_dl.rnti = 0x1234; dci_dl.rnti = 0x1234;
dci_dl.format = srslte_dci_format_nr_1_0; dci_dl.format = srslte_dci_format_nr_1_0;

@ -28,7 +28,7 @@ worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers) {}
bool worker_pool::init(phy_common* common, srslte::logger* logger, int prio) bool worker_pool::init(phy_common* common, srslte::logger* logger, int prio)
{ {
// Set carrier attributes // Set carrier attributes
phy_state.carrier.id = 0; phy_state.carrier.id = 500;
phy_state.carrier.nof_prb = common->args->nr_nof_prb; phy_state.carrier.nof_prb = common->args->nr_nof_prb;
// Set NR arguments // Set NR arguments

Loading…
Cancel
Save