Initial NR DCI blind-search

master
Xavier Arteaga 4 years ago committed by Andre Puschmann
parent 85d5026e38
commit c635b1e467

@ -13,14 +13,14 @@
#ifndef SRSLTE_DMRS_PDCCH_H #ifndef SRSLTE_DMRS_PDCCH_H
#define SRSLTE_DMRS_PDCCH_H #define SRSLTE_DMRS_PDCCH_H
#ifdef __cplusplus
extern "C" {
#endif
#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/resampling/resampler.h" #include "srslte/phy/resampling/resampler.h"
#include "srslte/srslte.h" #include "srslte/srslte.h"
#ifdef __cplusplus
extern "C" {
#endif
/** /**
* @brief Puts in the resource grid the DeModulation Reference Signals for decoding PDCCH. * @brief Puts in the resource grid the DeModulation Reference Signals for decoding PDCCH.
* *

@ -104,8 +104,8 @@ extern "C" {
#define SRSLTE_MAX_NOF_DL_ALLOCATION 16 #define SRSLTE_MAX_NOF_DL_ALLOCATION 16
typedef enum SRSLTE_API { typedef enum SRSLTE_API {
srslte_coreset_mapping_type_interleaved = 0, srslte_coreset_mapping_type_non_interleaved = 0,
srslte_coreset_mapping_type_non_interleaved, srslte_coreset_mapping_type_interleaved,
} srslte_coreset_mapping_type_t; } srslte_coreset_mapping_type_t;
typedef enum SRSLTE_API { typedef enum SRSLTE_API {

@ -15,6 +15,7 @@
#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/dft/ofdm.h" #include "srslte/phy/dft/ofdm.h"
#include "srslte/phy/phch/pdcch_nr.h"
#include "srslte/phy/phch/pdsch_nr.h" #include "srslte/phy/phch/pdsch_nr.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -22,7 +23,8 @@ extern "C" {
#endif #endif
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_pdsch_args_t pdsch; srslte_pdsch_nr_args_t pdsch;
srslte_pdcch_nr_args_t pdcch;
uint32_t nof_tx_antennas; uint32_t nof_tx_antennas;
uint32_t nof_max_prb; uint32_t nof_max_prb;
} srslte_enb_dl_nr_args_t; } srslte_enb_dl_nr_args_t;
@ -31,12 +33,15 @@ typedef struct SRSLTE_API {
uint32_t max_prb; uint32_t max_prb;
uint32_t nof_tx_antennas; uint32_t nof_tx_antennas;
srslte_carrier_nr_t carrier; srslte_carrier_nr_t carrier;
srslte_coreset_t coreset;
srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
cf_t* sf_symbols[SRSLTE_MAX_PORTS]; cf_t* sf_symbols[SRSLTE_MAX_PORTS];
srslte_pdsch_nr_t pdsch; srslte_pdsch_nr_t pdsch;
srslte_dmrs_pdsch_t dmrs; srslte_dmrs_pdsch_t dmrs;
srslte_pdcch_nr_t pdcch;
} srslte_enb_dl_nr_t; } srslte_enb_dl_nr_t;
SRSLTE_API int SRSLTE_API int
@ -44,10 +49,19 @@ srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS], con
SRSLTE_API int srslte_enb_dl_nr_set_carrier(srslte_enb_dl_nr_t* q, const srslte_carrier_nr_t* carrier); SRSLTE_API int srslte_enb_dl_nr_set_carrier(srslte_enb_dl_nr_t* q, const srslte_carrier_nr_t* carrier);
SRSLTE_API int srslte_enb_dl_nr_set_coreset(srslte_enb_dl_nr_t* q, const srslte_coreset_t* coreset);
SRSLTE_API void srslte_enb_dl_nr_free(srslte_enb_dl_nr_t* q); SRSLTE_API void srslte_enb_dl_nr_free(srslte_enb_dl_nr_t* q);
SRSLTE_API void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q); SRSLTE_API void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q);
SRSLTE_API int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg,
const srslte_search_space_t* search_space,
const srslte_dci_dl_nr_t* dci_dl,
const srslte_dci_location_t* dci_location,
uint16_t rnti);
SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_dl_slot_cfg_t* slot,
const srslte_pdsch_cfg_nr_t* cfg, const srslte_pdsch_cfg_nr_t* cfg,

@ -95,6 +95,8 @@ int srslte_pdcch_nr_locations_coreset(const srslte_coreset_t* coreset,
uint32_t slot_idx, uint32_t slot_idx,
uint32_t locations[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR]); uint32_t locations[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR]);
SRSLTE_API int srslte_pdcch_nr_max_candidates_coreset(const srslte_coreset_t* coreset, uint32_t aggregation_level);
SRSLTE_API int srslte_pdcch_nr_init_tx(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args); SRSLTE_API int srslte_pdcch_nr_init_tx(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args);
SRSLTE_API int srslte_pdcch_nr_init_rx(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args); SRSLTE_API int srslte_pdcch_nr_init_rx(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args);

@ -35,7 +35,7 @@ typedef struct SRSLTE_API {
srslte_sch_nr_args_t sch; srslte_sch_nr_args_t sch;
bool measure_evm; bool measure_evm;
bool measure_time; bool measure_time;
} srslte_pdsch_args_t; } srslte_pdsch_nr_args_t;
/** /**
* @brief PDSCH NR object * @brief PDSCH NR object
@ -64,9 +64,9 @@ typedef struct {
float evm; float evm;
} srslte_pdsch_res_nr_t; } srslte_pdsch_res_nr_t;
SRSLTE_API int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args); SRSLTE_API int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* args);
SRSLTE_API int srslte_pdsch_nr_init_ue(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args); SRSLTE_API int srslte_pdsch_nr_init_ue(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* args);
SRSLTE_API void srslte_pdsch_nr_free(srslte_pdsch_nr_t* q); SRSLTE_API void srslte_pdsch_nr_free(srslte_pdsch_nr_t* q);

@ -13,8 +13,11 @@
#ifndef SRSLTE_UE_DL_NR_H #ifndef SRSLTE_UE_DL_NR_H
#define SRSLTE_UE_DL_NR_H #define SRSLTE_UE_DL_NR_H
#include "srslte/phy/ch_estimation/dmrs_pdcch.h"
#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/dft/ofdm.h" #include "srslte/phy/dft/ofdm.h"
#include "srslte/phy/phch/dci_nr.h"
#include "srslte/phy/phch/pdcch_nr.h"
#include "srslte/phy/phch/pdsch_nr.h" #include "srslte/phy/phch/pdsch_nr.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -22,22 +25,31 @@ extern "C" {
#endif #endif
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_pdsch_args_t pdsch; srslte_pdsch_nr_args_t pdsch;
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;
} srslte_ue_dl_nr_args_t; } srslte_ue_dl_nr_args_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;
srslte_carrier_nr_t carrier; srslte_carrier_nr_t carrier;
srslte_coreset_t coreset;
srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
cf_t* sf_symbols[SRSLTE_MAX_PORTS]; cf_t* sf_symbols[SRSLTE_MAX_PORTS];
srslte_chest_dl_res_t chest; srslte_chest_dl_res_t chest;
srslte_pdsch_nr_t pdsch; srslte_pdsch_nr_t pdsch;
srslte_dmrs_pdsch_t dmrs; srslte_dmrs_pdsch_t dmrs_pdsch;
srslte_dmrs_pdcch_estimator_t dmrs_pdcch;
srslte_pdcch_nr_t pdcch;
srslte_dmrs_pdcch_ce_t* pdcch_ce;
} srslte_ue_dl_nr_t; } srslte_ue_dl_nr_t;
SRSLTE_API int SRSLTE_API int
@ -45,9 +57,18 @@ 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 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); 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,
const srslte_search_space_t* search_space,
const srslte_dl_slot_cfg_t* slot_cfg,
uint16_t rnti,
srslte_dci_dl_nr_t* dci_dl_list,
uint32_t nof_dci_msg);
SRSLTE_API int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, SRSLTE_API int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_dl_slot_cfg_t* slot,

@ -71,6 +71,11 @@ int srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS],
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (srslte_pdcch_nr_init_tx(&q->pdcch, &args->pdcch) < SRSLTE_SUCCESS) {
ERROR("Error PDCCH\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -91,6 +96,8 @@ void srslte_enb_dl_nr_free(srslte_enb_dl_nr_t* q)
srslte_pdsch_nr_free(&q->pdsch); srslte_pdsch_nr_free(&q->pdsch);
srslte_dmrs_pdsch_free(&q->dmrs); srslte_dmrs_pdsch_free(&q->dmrs);
srslte_pdcch_nr_free(&q->pdcch);
memset(q, 0, sizeof(srslte_enb_dl_nr_t)); memset(q, 0, sizeof(srslte_enb_dl_nr_t));
} }
@ -121,6 +128,21 @@ int srslte_enb_dl_nr_set_carrier(srslte_enb_dl_nr_t* q, const srslte_carrier_nr_
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_enb_dl_nr_set_coreset(srslte_enb_dl_nr_t* q, const srslte_coreset_t* coreset)
{
if (q == NULL || coreset == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
q->coreset = *coreset;
if (srslte_pdcch_nr_set_carrier(&q->pdcch, &q->carrier, &q->coreset) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q) void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q)
{ {
if (q == NULL) { if (q == NULL) {
@ -132,6 +154,50 @@ void srslte_enb_dl_nr_gen_signal(srslte_enb_dl_nr_t* q)
} }
} }
int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg,
const srslte_search_space_t* search_space,
const srslte_dci_dl_nr_t* dci_dl,
const srslte_dci_location_t* dci_location,
uint16_t rnti)
{
if (q == NULL || search_space == NULL || slot_cfg == NULL || dci_dl == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Hard-coded values
srslte_dci_format_nr_t dci_format = srslte_dci_format_nr_1_0;
srslte_rnti_type_t rnti_type = srslte_rnti_type_c;
// Put DMRS
if (srslte_dmrs_pdcch_put(&q->carrier, &q->coreset, slot_cfg, dci_location, q->sf_symbols[0]) < SRSLTE_SUCCESS) {
ERROR("Error putting PDCCH DMRS\n");
return SRSLTE_ERROR;
}
// Initialise DCI MSG fields
srslte_dci_msg_nr_t dci_msg = {};
dci_msg.location = *dci_location;
dci_msg.search_space = search_space->type;
dci_msg.rnti_type = rnti_type;
dci_msg.rnti = rnti;
dci_msg.format = dci_format;
// Pack DCI
if (srslte_dci_nr_format_1_0_pack(&q->carrier, &q->coreset, dci_dl, &dci_msg) < SRSLTE_SUCCESS) {
ERROR("Error packing DL DCI\n");
return SRSLTE_ERROR;
}
// PDCCH Encode
if (srslte_pdcch_nr_encode(&q->pdcch, &dci_msg, q->sf_symbols[0]) < SRSLTE_SUCCESS) {
ERROR("Error encoding PDCCH\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_dl_slot_cfg_t* slot,
const srslte_pdsch_cfg_nr_t* cfg, const srslte_pdsch_cfg_nr_t* cfg,

@ -140,7 +140,7 @@ int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SRSLTE_ERROR; return SRSLTE_SUCCESS;
} }
int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier, int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
@ -254,7 +254,7 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SRSLTE_ERROR; return SRSLTE_SUCCESS;
} }
int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,

@ -104,6 +104,21 @@ int srslte_pdcch_nr_locations_coreset(const srslte_coreset_t* coreset,
return nof_candidates; return nof_candidates;
} }
int srslte_pdcch_nr_max_candidates_coreset(const srslte_coreset_t* coreset, uint32_t aggregation_level)
{
if (coreset == NULL) {
return SRSLTE_ERROR;
}
uint32_t coreset_bw = srslte_coreset_get_bw(coreset);
uint32_t nof_cce = (coreset_bw * coreset->duration) / 6;
uint32_t L = 1U << aggregation_level;
uint32_t nof_candidates = nof_cce / L;
return SRSLTE_MIN(nof_candidates, SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR);
}
static int pdcch_nr_init_common(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args) static int pdcch_nr_init_common(srslte_pdcch_nr_t* q, const srslte_pdcch_nr_args_t* args)
{ {
if (q == NULL || args == NULL) { if (q == NULL || args == NULL) {

@ -13,7 +13,7 @@
#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/common/phy_common_nr.h"
#include "srslte/phy/phch/ra_nr.h" #include "srslte/phy/phch/ra_nr.h"
int pdsch_nr_init_common(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args) int pdsch_nr_init_common(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* args)
{ {
for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) { for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) {
if (srslte_modem_table_lte(&q->modem_tables[mod], mod) < SRSLTE_SUCCESS) { if (srslte_modem_table_lte(&q->modem_tables[mod], mod) < SRSLTE_SUCCESS) {
@ -28,7 +28,7 @@ int pdsch_nr_init_common(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args)
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args) int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* args)
{ {
if (q == NULL) { if (q == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -46,7 +46,7 @@ int srslte_pdsch_nr_init_enb(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* ar
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_pdsch_nr_init_ue(srslte_pdsch_nr_t* q, const srslte_pdsch_args_t* args) int srslte_pdsch_nr_init_ue(srslte_pdsch_nr_t* q, const srslte_pdsch_nr_args_t* args)
{ {
if (q == NULL || args == NULL) { if (q == NULL || args == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;

@ -27,7 +27,8 @@ static srslte_carrier_nr_t carrier = {
0, // cell_id 0, // cell_id
0, // numerology 0, // numerology
50, // nof_prb 50, // nof_prb
0 // start 0, // start
1 // max_mimo_layers
}; };
static uint16_t rnti = 0x1234; static uint16_t rnti = 0x1234;
@ -163,25 +164,15 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
uint32_t coreset_bw = srslte_coreset_get_bw(&coreset);
uint32_t nof_cce = (coreset_bw * coreset.duration) / 6;
uint32_t max_aggregation_level = (uint32_t)floor(log2(nof_cce));
max_aggregation_level = SRSLTE_MIN(max_aggregation_level + 1, SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR);
// Fill search space maximum number of candidates // Fill search space maximum number of candidates
for (uint32_t aggregation_level = 0; aggregation_level < max_aggregation_level; aggregation_level++) { for (uint32_t aggregation_level = 0; aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR;
uint32_t L = 1U << aggregation_level;
uint32_t nof_candidates = nof_cce / L;
nof_candidates = SRSLTE_MIN(nof_candidates, SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR);
search_space.nof_candidates[aggregation_level] = nof_candidates;
}
for (uint32_t aggregation_level = max_aggregation_level;
aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR;
aggregation_level++) { aggregation_level++) {
search_space.nof_candidates[aggregation_level] = 0; search_space.nof_candidates[aggregation_level] =
srslte_pdcch_nr_max_candidates_coreset(&coreset, aggregation_level);
} }
for (uint32_t aggregation_level = 0; aggregation_level < max_aggregation_level; aggregation_level++) { for (uint32_t aggregation_level = 0; aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR;
aggregation_level++) {
uint32_t L = 1U << aggregation_level; uint32_t L = 1U << aggregation_level;
for (uint32_t slot_idx = 0; slot_idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot_idx++) { for (uint32_t slot_idx = 0; slot_idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot_idx++) {
@ -194,9 +185,10 @@ int main(int argc, char** argv)
ERROR("Error calculating locations in CORESET\n"); ERROR("Error calculating locations in CORESET\n");
goto clean_exit; goto clean_exit;
} }
// Skip if no candidates
if (n == 0) { if (n == 0) {
ERROR("Invalid number of locations (%d)\n", n); continue;
goto clean_exit;
} }
for (uint32_t ncce_idx = 0; ncce_idx < n; ncce_idx++) { for (uint32_t ncce_idx = 0; ncce_idx < n; ncce_idx++) {

@ -91,7 +91,7 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
srslte_pdsch_args_t pdsch_args = {}; srslte_pdsch_nr_args_t pdsch_args = {};
pdsch_args.sch.disable_simd = true; pdsch_args.sch.disable_simd = true;
pdsch_args.measure_evm = true; pdsch_args.measure_evm = true;

@ -12,7 +12,9 @@
#include "srslte/phy/ue/ue_dl_nr.h" #include "srslte/phy/ue/ue_dl_nr.h"
static int ue_dl_alloc_prb(srslte_ue_dl_nr_t* q, uint32_t new_nof_prb) #define UE_DL_NR_PDCCH_CORR_DEFAULT_THR 0.5f
static int ue_dl_nr_alloc_prb(srslte_ue_dl_nr_t* q, uint32_t new_nof_prb)
{ {
if (q->max_prb < new_nof_prb) { if (q->max_prb < new_nof_prb) {
q->max_prb = new_nof_prb; q->max_prb = new_nof_prb;
@ -50,12 +52,17 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co
} }
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 (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;
} }
if (ue_dl_alloc_prb(q, args->nof_max_prb)) { if (srslte_pdcch_nr_init_rx(&q->pdcch, &args->pdcch)) {
return SRSLTE_ERROR;
}
if (ue_dl_nr_alloc_prb(q, args->nof_max_prb)) {
ERROR("Error allocating\n"); ERROR("Error allocating\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -71,11 +78,17 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co
srslte_ofdm_rx_init_cfg(&q->fft[i], &fft_cfg); srslte_ofdm_rx_init_cfg(&q->fft[i], &fft_cfg);
} }
if (srslte_dmrs_pdsch_init(&q->dmrs, true) < SRSLTE_SUCCESS) { if (srslte_dmrs_pdsch_init(&q->dmrs_pdsch, true) < SRSLTE_SUCCESS) {
ERROR("Error DMRS\n"); ERROR("Error DMRS\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
q->pdcch_ce = SRSLTE_MEM_ALLOC(srslte_dmrs_pdcch_ce_t, 1);
if (q->pdcch_ce == NULL) {
ERROR("Error alloc\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -95,7 +108,13 @@ 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_pdsch_free(&q->dmrs); srslte_dmrs_pdsch_free(&q->dmrs_pdsch);
srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch);
srslte_pdcch_nr_free(&q->pdcch);
if (q->pdcch_ce) {
free(q->pdcch_ce);
}
memset(q, 0, sizeof(srslte_ue_dl_nr_t)); memset(q, 0, sizeof(srslte_ue_dl_nr_t));
} }
@ -106,12 +125,12 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t*
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (srslte_dmrs_pdsch_set_carrier(&q->dmrs, carrier) < SRSLTE_SUCCESS) { if (srslte_dmrs_pdsch_set_carrier(&q->dmrs_pdsch, carrier) < SRSLTE_SUCCESS) {
ERROR("Error DMRS\n"); ERROR("Error DMRS\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (ue_dl_alloc_prb(q, carrier->nof_prb)) { if (ue_dl_nr_alloc_prb(q, carrier->nof_prb)) {
ERROR("Error allocating\n"); ERROR("Error allocating\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -127,15 +146,138 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t*
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q) int srslte_ue_dl_nr_set_coreset(srslte_ue_dl_nr_t* q, const srslte_coreset_t* coreset)
{ {
if (q == NULL) { if (q == NULL || coreset == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
q->coreset = *coreset;
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) {
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg)
{
if (q == NULL || slot_cfg == NULL) {
return; return;
} }
// OFDM demodulation
for (uint32_t i = 0; i < q->nof_rx_antennas; i++) { for (uint32_t i = 0; i < q->nof_rx_antennas; i++) {
srslte_ofdm_rx_sf(&q->fft[i]); srslte_ofdm_rx_sf(&q->fft[i]);
} }
// Estimate PDCCH channel
srslte_dmrs_pdcch_estimate(&q->dmrs_pdcch, 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)
{
srslte_dmrs_pdcch_measure_t m = {};
if (srslte_dmrs_pdcch_get_measure(&q->dmrs_pdcch, &dci_msg->location, &m) < SRSLTE_SUCCESS) {
ERROR("Error getting measure location L=%d, ncce=%d\n", dci_msg->location.L, dci_msg->location.ncce);
return SRSLTE_ERROR;
}
// If measured RSRP and EPRE is invalid, early return
if (!isnormal(m.rsrp) || !isnormal(m.epre)) {
return SRSLTE_SUCCESS;
}
// Compare DMRS correlation with threshold
float thr = q->pdcch_dmrs_corr_thr;
if (!isnormal(thr)) {
thr = UE_DL_NR_PDCCH_CORR_DEFAULT_THR; //< Load default threshold if not provided
}
if (m.rsrp / m.epre < thr) {
return SRSLTE_SUCCESS;
}
// Extract PDCCH channel estimates
if (srslte_dmrs_pdcch_get_ce(&q->dmrs_pdcch, &dci_msg->location, q->pdcch_ce) < SRSLTE_SUCCESS) {
ERROR("Error extracting PDCCH DMRS\n");
return SRSLTE_ERROR;
}
// Decode PDCCH
if (srslte_pdcch_nr_decode(&q->pdcch, q->sf_symbols[0], q->pdcch_ce, dci_msg, pdcch_res) < SRSLTE_SUCCESS) {
ERROR("Error decoding PDCCH\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
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,
uint16_t rnti,
srslte_dci_dl_nr_t* dci_dl_list,
uint32_t nof_dci_msg)
{
uint32_t count = 0;
// Hard-coded values
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
int dci_nof_bits = srslte_dci_nr_format_1_0_sizeof(&q->carrier, &q->coreset, rnti_type);
if (dci_nof_bits <= SRSLTE_SUCCESS) {
ERROR("Error DCI size\n");
return SRSLTE_ERROR;
}
// Iterate all possible aggregation levels
for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR && count < nof_dci_msg; L++) {
// Calculate possible PDCCH DCI candidates
uint32_t candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {};
int nof_candidates =
srslte_pdcch_nr_locations_coreset(&q->coreset, search_space, rnti, L, slot_cfg->idx, candidates);
if (nof_candidates < SRSLTE_SUCCESS) {
ERROR("Error calculating DCI candidate location\n");
return SRSLTE_ERROR;
}
// Iterate over the candidates
for (int ncce_idx = 0; ncce_idx < nof_candidates && count < nof_dci_msg; ncce_idx++) {
srslte_dci_msg_nr_t dci_msg = {};
dci_msg.location.L = L;
dci_msg.location.ncce = candidates[ncce_idx];
dci_msg.search_space = search_space->type;
dci_msg.rnti_type = rnti_type;
dci_msg.rnti = rnti;
dci_msg.format = dci_format;
dci_msg.nof_bits = (uint32_t)dci_nof_bits;
srslte_pdcch_nr_res_t res = {};
if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
if (res.crc) {
if (srslte_dci_nr_format_1_0_unpack(&q->carrier, &q->coreset, &dci_msg, &dci_dl_list[count]) < SRSLTE_SUCCESS) {
ERROR("Error unpacking DCI\n");
return SRSLTE_ERROR;
}
INFO("Found DCI in L=%d,ncce=%d\n", dci_msg.location.L, dci_msg.location.ncce);
count++;
}
}
}
return (int)count;
} }
int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q,
@ -145,7 +287,7 @@ int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q,
srslte_pdsch_res_nr_t* res) srslte_pdsch_res_nr_t* res)
{ {
if (srslte_dmrs_pdsch_estimate(&q->dmrs, slot, cfg, grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) { if (srslte_dmrs_pdsch_estimate(&q->dmrs_pdsch, slot, cfg, grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

@ -34,6 +34,7 @@ static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering static uint32_t mcs = 30; // Set to 30 for steering
static srslte_pdsch_cfg_nr_t pdsch_cfg = {}; static srslte_pdsch_cfg_nr_t pdsch_cfg = {};
static srslte_pdsch_grant_nr_t pdsch_grant = {}; static srslte_pdsch_grant_nr_t pdsch_grant = {};
static uint16_t rnti = 0x1234;
void usage(char* prog) void usage(char* prog)
{ {
@ -108,11 +109,28 @@ int main(int argc, char** argv)
// Set default PDSCH configuration // Set default PDSCH configuration
pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam; pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam;
if (parse_args(argc, argv) < SRSLTE_SUCCESS) { if (parse_args(argc, argv) < SRSLTE_SUCCESS) {
goto clean_exit; goto clean_exit;
} }
srslte_pdsch_nr_args_t pdsch_args = {};
pdsch_args.sch.disable_simd = true;
pdsch_args.measure_evm = true;
// Configure CORESET
srslte_coreset_t coreset = {};
coreset.duration = 2;
for (uint32_t i = 0; i < SRSLTE_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
coreset.freq_resources[i] = i < carrier.nof_prb;
}
// Configure Search Space
srslte_search_space_t search_space = {};
search_space.type = srslte_search_space_type_ue;
for (uint32_t L = 0; L < SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR; 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)) {
ERROR("Error UE DL\n"); ERROR("Error UE DL\n");
goto clean_exit; goto clean_exit;
@ -128,11 +146,21 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
if (srslte_ue_dl_nr_set_coreset(&ue_dl, &coreset)) {
ERROR("Error setting CORESET\n");
goto clean_exit;
}
if (srslte_enb_dl_nr_set_carrier(&enb_dl, &carrier)) { if (srslte_enb_dl_nr_set_carrier(&enb_dl, &carrier)) {
ERROR("Error setting SCH NR carrier\n"); ERROR("Error setting SCH NR carrier\n");
goto clean_exit; goto clean_exit;
} }
if (srslte_enb_dl_nr_set_coreset(&enb_dl, &coreset)) {
ERROR("Error setting CORESET\n");
goto clean_exit;
}
for (uint32_t i = 0; i < 1; i++) { for (uint32_t i = 0; i < 1; i++) {
data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR);
@ -206,8 +234,33 @@ int main(int argc, char** argv)
pdsch_grant.tb[tb].softbuffer.tx = &softbuffer_tx; pdsch_grant.tb[tb].softbuffer.tx = &softbuffer_tx;
} }
// Compute PDCCH candidate locations
uint32_t L = 0;
uint32_t ncce_candidates[SRSLTE_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {};
int nof_candidates =
srslte_pdcch_nr_locations_coreset(&coreset, &search_space, rnti, L, slot.idx, ncce_candidates);
if (nof_candidates < SRSLTE_SUCCESS) {
ERROR("Error getting PDCCH candidates\n");
goto clean_exit;
}
// Setup DCI location
srslte_dci_location_t dci_location = {};
dci_location.ncce = ncce_candidates[0];
dci_location.L = L;
// Setup DCI
srslte_dci_dl_nr_t dci_dl = {};
// Put actual DCI
if (srslte_enb_dl_nr_pdcch_put(&enb_dl, &slot, &search_space, &dci_dl, &dci_location, rnti) < SRSLTE_SUCCESS) {
ERROR("Error putting PDCCH\n");
goto clean_exit;
}
// Put PDSCH transmission
if (srslte_enb_dl_nr_pdsch_put(&enb_dl, &slot, &pdsch_cfg, &pdsch_grant, data_tx) < SRSLTE_SUCCESS) { if (srslte_enb_dl_nr_pdsch_put(&enb_dl, &slot, &pdsch_cfg, &pdsch_grant, data_tx) < SRSLTE_SUCCESS) {
ERROR("Error encoding\n"); ERROR("Error putting PDSCH\n");
goto clean_exit; goto clean_exit;
} }
@ -218,7 +271,19 @@ int main(int argc, char** argv)
srslte_softbuffer_rx_reset(pdsch_grant.tb[tb].softbuffer.rx); srslte_softbuffer_rx_reset(pdsch_grant.tb[tb].softbuffer.rx);
} }
srslte_ue_dl_nr_estimate_fft(&ue_dl); srslte_ue_dl_nr_estimate_fft(&ue_dl, &slot);
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);
if (nof_found_dci < SRSLTE_SUCCESS) {
ERROR("Error decoding\n");
goto clean_exit;
}
if (nof_found_dci < 1) {
ERROR("Error DCI not found\n");
goto clean_exit;
}
if (srslte_ue_dl_nr_pdsch_get(&ue_dl, &slot, &pdsch_cfg, &pdsch_grant, pdsch_res) < SRSLTE_SUCCESS) { if (srslte_ue_dl_nr_pdsch_get(&ue_dl, &slot, &pdsch_cfg, &pdsch_grant, pdsch_res) < SRSLTE_SUCCESS) {
ERROR("Error decoding\n"); ERROR("Error decoding\n");

@ -125,7 +125,7 @@ bool cc_worker::work_dl()
pdsch_grant.tb[0].softbuffer.rx = &softbuffer_rx; pdsch_grant.tb[0].softbuffer.rx = &softbuffer_rx;
srslte_softbuffer_rx_reset(pdsch_grant.tb[0].softbuffer.rx); srslte_softbuffer_rx_reset(pdsch_grant.tb[0].softbuffer.rx);
srslte_ue_dl_nr_estimate_fft(&ue_dl); srslte_ue_dl_nr_estimate_fft(&ue_dl, &dl_slot_cfg);
if (srslte_ue_dl_nr_pdsch_get(&ue_dl, &dl_slot_cfg, &pdsch_cfg, &pdsch_grant, pdsch_res.data()) < SRSLTE_SUCCESS) { if (srslte_ue_dl_nr_pdsch_get(&ue_dl, &dl_slot_cfg, &pdsch_cfg, &pdsch_grant, pdsch_res.data()) < SRSLTE_SUCCESS) {
ERROR("Error decoding PDSCH\n"); ERROR("Error decoding PDSCH\n");

Loading…
Cancel
Save