mirror of https://github.com/PentHertz/srsLTE.git
Initial NR DCI blind-search
This commit is contained in:
parent
85d5026e38
commit
c635b1e467
|
@ -13,14 +13,14 @@
|
|||
#ifndef 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/resampling/resampler.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
srslte_coreset_mapping_type_interleaved = 0,
|
||||
srslte_coreset_mapping_type_non_interleaved,
|
||||
srslte_coreset_mapping_type_non_interleaved = 0,
|
||||
srslte_coreset_mapping_type_interleaved,
|
||||
} srslte_coreset_mapping_type_t;
|
||||
|
||||
typedef enum SRSLTE_API {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "srslte/phy/common/phy_common_nr.h"
|
||||
#include "srslte/phy/dft/ofdm.h"
|
||||
#include "srslte/phy/phch/pdcch_nr.h"
|
||||
#include "srslte/phy/phch/pdsch_nr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -22,21 +23,25 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_pdsch_args_t pdsch;
|
||||
uint32_t nof_tx_antennas;
|
||||
uint32_t nof_max_prb;
|
||||
srslte_pdsch_nr_args_t pdsch;
|
||||
srslte_pdcch_nr_args_t pdcch;
|
||||
uint32_t nof_tx_antennas;
|
||||
uint32_t nof_max_prb;
|
||||
} srslte_enb_dl_nr_args_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_prb;
|
||||
uint32_t nof_tx_antennas;
|
||||
srslte_carrier_nr_t carrier;
|
||||
srslte_coreset_t coreset;
|
||||
|
||||
srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
|
||||
|
||||
cf_t* sf_symbols[SRSLTE_MAX_PORTS];
|
||||
srslte_pdsch_nr_t pdsch;
|
||||
srslte_dmrs_pdsch_t dmrs;
|
||||
|
||||
srslte_pdcch_nr_t pdcch;
|
||||
} srslte_enb_dl_nr_t;
|
||||
|
||||
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_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_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,
|
||||
const srslte_dl_slot_cfg_t* slot,
|
||||
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 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_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;
|
||||
bool measure_evm;
|
||||
bool measure_time;
|
||||
} srslte_pdsch_args_t;
|
||||
} srslte_pdsch_nr_args_t;
|
||||
|
||||
/**
|
||||
* @brief PDSCH NR object
|
||||
|
@ -64,9 +64,9 @@ typedef struct {
|
|||
float evm;
|
||||
} 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);
|
||||
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
#ifndef 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/dft/ofdm.h"
|
||||
#include "srslte/phy/phch/dci_nr.h"
|
||||
#include "srslte/phy/phch/pdcch_nr.h"
|
||||
#include "srslte/phy/phch/pdsch_nr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -22,22 +25,31 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
srslte_pdsch_args_t pdsch;
|
||||
uint32_t nof_rx_antennas;
|
||||
uint32_t nof_max_prb;
|
||||
srslte_pdsch_nr_args_t pdsch;
|
||||
srslte_pdcch_nr_args_t pdcch;
|
||||
uint32_t nof_rx_antennas;
|
||||
uint32_t nof_max_prb;
|
||||
float pdcch_dmrs_corr_thr;
|
||||
} srslte_ue_dl_nr_args_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t max_prb;
|
||||
uint32_t nof_rx_antennas;
|
||||
uint32_t max_prb;
|
||||
uint32_t nof_rx_antennas;
|
||||
float pdcch_dmrs_corr_thr;
|
||||
|
||||
srslte_carrier_nr_t carrier;
|
||||
srslte_coreset_t coreset;
|
||||
|
||||
srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
|
||||
|
||||
cf_t* sf_symbols[SRSLTE_MAX_PORTS];
|
||||
srslte_chest_dl_res_t chest;
|
||||
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_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_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_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,
|
||||
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;
|
||||
}
|
||||
|
||||
if (srslte_pdcch_nr_init_tx(&q->pdcch, &args->pdcch) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error PDCCH\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
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_dmrs_pdsch_free(&q->dmrs);
|
||||
|
||||
srslte_pdcch_nr_free(&q->pdcch);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
const srslte_dl_slot_cfg_t* slot,
|
||||
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_SUCCESS;
|
||||
}
|
||||
|
||||
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_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (q == NULL || args == NULL) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "srslte/phy/common/phy_common_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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
|
|
|
@ -27,7 +27,8 @@ static srslte_carrier_nr_t carrier = {
|
|||
0, // cell_id
|
||||
0, // numerology
|
||||
50, // nof_prb
|
||||
0 // start
|
||||
0, // start
|
||||
1 // max_mimo_layers
|
||||
};
|
||||
|
||||
static uint16_t rnti = 0x1234;
|
||||
|
@ -163,25 +164,15 @@ int main(int argc, char** argv)
|
|||
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
|
||||
for (uint32_t aggregation_level = 0; aggregation_level < max_aggregation_level; aggregation_level++) {
|
||||
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;
|
||||
for (uint32_t aggregation_level = 0; aggregation_level < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR;
|
||||
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;
|
||||
|
||||
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");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
// Skip if no candidates
|
||||
if (n == 0) {
|
||||
ERROR("Invalid number of locations (%d)\n", n);
|
||||
goto clean_exit;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t ncce_idx = 0; ncce_idx < n; ncce_idx++) {
|
||||
|
|
|
@ -91,9 +91,9 @@ int main(int argc, char** argv)
|
|||
goto clean_exit;
|
||||
}
|
||||
|
||||
srslte_pdsch_args_t pdsch_args = {};
|
||||
pdsch_args.sch.disable_simd = true;
|
||||
pdsch_args.measure_evm = true;
|
||||
srslte_pdsch_nr_args_t pdsch_args = {};
|
||||
pdsch_args.sch.disable_simd = true;
|
||||
pdsch_args.measure_evm = true;
|
||||
|
||||
if (srslte_pdsch_nr_init_enb(&pdsch_tx, &pdsch_args) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error initiating PDSCH for Tx\n");
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
|
||||
#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) {
|
||||
q->max_prb = new_nof_prb;
|
||||
|
@ -49,13 +51,18 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co
|
|||
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 (srslte_pdsch_nr_init_ue(&q->pdsch, &args->pdsch) < SRSLTE_SUCCESS) {
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -95,7 +108,13 @@ void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q)
|
|||
|
||||
srslte_chest_dl_res_free(&q->chest);
|
||||
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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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");
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// OFDM demodulation
|
||||
for (uint32_t i = 0; i < q->nof_rx_antennas; 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,
|
||||
|
@ -145,7 +287,7 @@ int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 srslte_pdsch_cfg_nr_t pdsch_cfg = {};
|
||||
static srslte_pdsch_grant_nr_t pdsch_grant = {};
|
||||
static uint16_t rnti = 0x1234;
|
||||
|
||||
void usage(char* prog)
|
||||
{
|
||||
|
@ -107,12 +108,29 @@ int main(int argc, char** argv)
|
|||
enb_dl_args.pdsch.sch.disable_simd = true;
|
||||
|
||||
// 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) {
|
||||
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)) {
|
||||
ERROR("Error UE DL\n");
|
||||
goto clean_exit;
|
||||
|
@ -128,11 +146,21 @@ int main(int argc, char** argv)
|
|||
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)) {
|
||||
ERROR("Error setting SCH NR carrier\n");
|
||||
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++) {
|
||||
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);
|
||||
|
@ -206,8 +234,33 @@ int main(int argc, char** argv)
|
|||
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) {
|
||||
ERROR("Error encoding\n");
|
||||
ERROR("Error putting PDSCH\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
|
@ -218,7 +271,19 @@ int main(int argc, char** argv)
|
|||
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) {
|
||||
ERROR("Error decoding\n");
|
||||
|
|
|
@ -125,7 +125,7 @@ bool cc_worker::work_dl()
|
|||
pdsch_grant.tb[0].softbuffer.rx = &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) {
|
||||
ERROR("Error decoding PDSCH\n");
|
||||
|
|
Loading…
Reference in New Issue