Added SRSUE NR-PUSCH initial procedures

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 19e9c25d1d
commit a19671802e

@ -98,15 +98,15 @@ typedef struct SRSLTE_API {
} srslte_csi_rs_nzp_resource_t; } srslte_csi_rs_nzp_resource_t;
SRSLTE_API int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
cf_t* grid); cf_t* grid);
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
float rsrp; float rsrp;
float rsrp_dB; float rsrp_dB;
float epre; float epre;
float epre_dB; float epre_dB;
float n0; float n0;
float n0_dB; float n0_dB;
float snr_dB; float snr_dB;
@ -114,7 +114,7 @@ typedef struct SRSLTE_API {
} srslte_csi_rs_measure_t; } srslte_csi_rs_measure_t;
SRSLTE_API int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
const cf_t* grid, const cf_t* grid,
srslte_csi_rs_measure_t* measure); srslte_csi_rs_measure_t* measure);

@ -34,7 +34,7 @@
*/ */
SRSLTE_API int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_dci_location_t* dci_location, const srslte_dci_location_t* dci_location,
cf_t* sf_symbols); cf_t* sf_symbols);
@ -110,9 +110,8 @@ SRSLTE_API void srslte_dmrs_pdcch_estimator_free(srslte_dmrs_pdcch_estimator_t*
* @param[in] sf_symbols Received resource grid. * @param[in] sf_symbols Received resource grid.
* @return SRSLTE_SUCCESS if the configurations are valid, otherwise it returns an SRSLTE_ERROR code * @return SRSLTE_SUCCESS if the configurations are valid, otherwise it returns an SRSLTE_ERROR code
*/ */
SRSLTE_API int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, SRSLTE_API int
const srslte_dl_slot_cfg_t* slot_cfg, srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, const srslte_slot_cfg_t* slot_cfg, const cf_t* sf_symbols);
const cf_t* sf_symbols);
/** /**
* @brief PDSCH DMRS measurement results * @brief PDSCH DMRS measurement results

@ -42,7 +42,7 @@ SRSLTE_API int srslte_dmrs_pucch_format_3_4_get_symbol_idx(const srslte_pucch_nr
SRSLTE_API int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, SRSLTE_API int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
cf_t* slot_symbols); cf_t* slot_symbols);
@ -60,7 +60,7 @@ SRSLTE_API int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t*
SRSLTE_API int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, SRSLTE_API int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const cf_t* slot_symbols, const cf_t* slot_symbols,
srslte_chest_ul_res_t* res); srslte_chest_ul_res_t* res);
@ -78,7 +78,7 @@ SRSLTE_API int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t*
int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
cf_t* slot_symbols); cf_t* slot_symbols);
@ -96,7 +96,7 @@ int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q,
int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const cf_t* slot_symbols, const cf_t* slot_symbols,
srslte_chest_ul_res_t* res); srslte_chest_ul_res_t* res);

@ -32,7 +32,7 @@
* @see srslte_dmrs_sch_estimate * @see srslte_dmrs_sch_estimate
*/ */
typedef struct { typedef struct {
bool is_ue; bool is_rx;
srslte_carrier_nr_t carrier; srslte_carrier_nr_t carrier;
@ -91,10 +91,10 @@ SRSLTE_API int srslte_dmrs_sch_cfg_to_str(const srslte_dmrs_sch_cfg_t* cfg, char
* @brief Initialises DMRS PDSCH object * @brief Initialises DMRS PDSCH object
* *
* @param q DMRS PDSCH object * @param q DMRS PDSCH object
* @param is_ue indicates whethe the object is for a UE (in this case, it shall initialise as an estimator) * @param is_rx indicates whethe the object is used as receiver (in this case, it shall initialise as an estimator)
* @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS
*/ */
SRSLTE_API int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue); SRSLTE_API int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_rx);
/** /**
* @brief Frees DMRS PDSCH object * @brief Frees DMRS PDSCH object
@ -126,7 +126,7 @@ SRSLTE_API int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_ca
* @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS
*/ */
SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg,
const srslte_sch_grant_nr_t* grant, const srslte_sch_grant_nr_t* grant,
cf_t* sf_symbols); cf_t* sf_symbols);
@ -146,7 +146,7 @@ SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q,
* @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS
*/ */
SRSLTE_API int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, SRSLTE_API int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg,
const srslte_sch_grant_nr_t* grant, const srslte_sch_grant_nr_t* grant,
const cf_t* sf_symbols, const cf_t* sf_symbols,

@ -228,7 +228,7 @@ typedef struct SRSLTE_API {
/// Left for future parameters /// Left for future parameters
/// ... /// ...
} srslte_dl_slot_cfg_t; } srslte_slot_cfg_t;
/** /**
* @brief Min number of OFDM symbols in a control resource set. * @brief Min number of OFDM symbols in a control resource set.
@ -280,6 +280,13 @@ typedef struct SRSLTE_API {
uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR]; uint32_t nof_candidates[SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR];
} srslte_search_space_t; } srslte_search_space_t;
/**
* @brief Get the RNTI type name for NR
* @param rnti_type RNTI type name
* @return Constant string with the RNTI type name
*/
SRSLTE_API const char* srslte_rnti_type_str(srslte_rnti_type_t rnti_type);
/** /**
* @brief Calculates the bandwidth of a given CORESET in physical resource blocks (PRB) . This function uses the * @brief Calculates the bandwidth of a given CORESET in physical resource blocks (PRB) . This function uses the
* frequency domain resources bit-map for counting the number of PRB. * frequency domain resources bit-map for counting the number of PRB.

@ -53,17 +53,15 @@ SRSLTE_API int srslte_enb_dl_nr_base_zero(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, SRSLTE_API int
const srslte_dl_slot_cfg_t* slot_cfg, srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, const srslte_slot_cfg_t* slot_cfg, const srslte_dci_dl_nr_t* dci_dl);
const srslte_dci_dl_nr_t* dci_dl);
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_slot_cfg_t* slot,
const srslte_sch_cfg_nr_t* cfg, const srslte_sch_cfg_nr_t* cfg,
uint8_t* data[SRSLTE_MAX_TB]); uint8_t* data[SRSLTE_MAX_TB]);
SRSLTE_API int SRSLTE_API int
srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len); srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len);
#endif // SRSLTE_ENB_DL_NR_H #endif // SRSLTE_ENB_DL_NR_H

@ -91,6 +91,14 @@ typedef struct SRSLTE_API {
} srslte_dci_ul_nr_t; } srslte_dci_ul_nr_t;
/**
* @brief Indicates whether the provided DCI message format bit indicator belongs to DCI format 1_0 according according
* to the RNTI type. If invalid, the DCI message is likely to be format 0_0
* @param dci_msg Provides DCI format 1_0 message
* @return true if the DCI message is format 1_0, false otherwise
*/
SRSLTE_API bool srslte_dci_nr_format_1_0_valid(const srslte_dci_msg_nr_t* dci_msg);
SRSLTE_API int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
const srslte_dci_dl_nr_t* dci, const srslte_dci_dl_nr_t* dci,
@ -100,9 +108,19 @@ SRSLTE_API int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrie
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
srslte_rnti_type_t rnti_type); srslte_rnti_type_t rnti_type);
SRSLTE_API SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset0,
srslte_rnti_type_t rnti_type); const srslte_dci_ul_nr_t* dci,
srslte_dci_msg_nr_t* msg);
SRSLTE_API int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_dci_msg_nr_t* msg,
srslte_dci_ul_nr_t* dci);
SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset,
srslte_rnti_type_t rnti_type);
SRSLTE_API int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
@ -114,6 +132,8 @@ SRSLTE_API int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrie
srslte_dci_msg_nr_t* msg, srslte_dci_msg_nr_t* msg,
srslte_dci_dl_nr_t* dci); srslte_dci_dl_nr_t* dci);
SRSLTE_API int srslte_dci_ul_nr_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len);
SRSLTE_API int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len); SRSLTE_API int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len);
#endif // SRSLTE_DCI_NR_H #endif // SRSLTE_DCI_NR_H

@ -109,8 +109,7 @@ typedef struct SRSLTE_API {
srslte_rnti_type_t rnti_type; srslte_rnti_type_t rnti_type;
/// Time domain resources /// Time domain resources
uint32_t k0; // PDSCH only uint32_t k; // k0 for PDSCH, k2 for PUSCH
uint32_t k2; // PUSCH only
uint32_t S; uint32_t S;
uint32_t L; uint32_t L;
srslte_sch_mapping_type_t mapping; srslte_sch_mapping_type_t mapping;

@ -93,7 +93,7 @@ SRSLTE_API int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t*
*/ */
SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier, SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
uint32_t l, uint32_t l,
uint32_t l_prime, uint32_t l_prime,
uint32_t m0, uint32_t m0,
@ -115,7 +115,7 @@ SRSLTE_API int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* car
SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
srslte_pucch_nr_resource_t* resource, srslte_pucch_nr_resource_t* resource,
uint32_t m_cs, uint32_t m_cs,
cf_t* slot_symbols); cf_t* slot_symbols);
@ -135,7 +135,7 @@ SRSLTE_API int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t*
SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
srslte_pucch_nr_resource_t* resource, srslte_pucch_nr_resource_t* resource,
uint32_t m_cs, uint32_t m_cs,
const cf_t* slot_symbols, const cf_t* slot_symbols,
@ -168,7 +168,7 @@ SRSLTE_API cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n
SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
uint8_t* b, uint8_t* b,
uint32_t nof_bits, uint32_t nof_bits,
@ -190,7 +190,7 @@ SRSLTE_API int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t*
SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols, cf_t* slot_symbols,
@ -212,7 +212,7 @@ SRSLTE_API int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t*
SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_cfg_nr_t* uci_cfg,
const srslte_uci_value_nr_t* uci_value, const srslte_uci_value_nr_t* uci_value,
@ -234,7 +234,7 @@ SRSLTE_API int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t*
SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, SRSLTE_API int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_cfg_nr_t* uci_cfg,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,

@ -58,7 +58,7 @@ typedef struct {
float evm; float evm;
} srslte_pusch_res_nr_t; } srslte_pusch_res_nr_t;
SRSLTE_API int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); SRSLTE_API int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args);
SRSLTE_API int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); SRSLTE_API int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args);

@ -101,4 +101,24 @@ SRSLTE_API int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrie
srslte_sch_cfg_nr_t* cfg, srslte_sch_cfg_nr_t* cfg,
srslte_sch_grant_nr_t* pdsch_grant); srslte_sch_grant_nr_t* pdsch_grant);
/**
* @brief Converts an unpacked UL DCI message to a PUSCH grant structure.
* Implements the procedures defined in Section 6 of 38.214 to compute the resource allocation (6.1.2)
* and modulation order, target rate, redundancy version and TBS (6.1.4)
*
* Note: Only TypeA PUSCH mapping type is supported
*
* @param carrier Carrier information struct
* @param pusch_hl_cfg PUSCH configuration provided by higher layers
* @param dci_ul DCI uplink (format 0_0 or 0_1)
* @param pusch_cfg PUSCH configuration after applying the procedure
* @param pusch_grant Generated PUSCH grant
* @return 0 on success, -1 on error
*/
SRSLTE_API int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg,
const srslte_dci_ul_nr_t* dci_ul,
srslte_sch_cfg_nr_t* pusch_cfg,
srslte_sch_grant_nr_t* pusch_grant);
#endif // SRSLTE_RA_NR_H #endif // SRSLTE_RA_NR_H

@ -32,6 +32,11 @@
*/ */
#define SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE 40 #define SRSLTE_UE_DL_NR_MAX_NOF_SEARCH_SPACE 40
/**
* Maximum number of DCI messages to receive
*/
#define SRSLTE_MAX_DCI_MSG_NR 4
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;
@ -51,7 +56,7 @@ typedef struct SRSLTE_API {
uint16_t ra_rnti; ///< Needs to be deduced from the PRACH configuration uint16_t ra_rnti; ///< Needs to be deduced from the PRACH configuration
srslte_search_space_t ra_search_space; srslte_search_space_t ra_search_space;
bool ra_search_space_present; bool ra_search_space_present;
} srslte_ue_dl_nr_cfg_t; } srslte_ue_dl_nr_pdcch_cfg_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t max_prb; uint32_t max_prb;
@ -59,8 +64,8 @@ typedef struct SRSLTE_API {
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_ue_dl_nr_cfg_t cfg; srslte_ue_dl_nr_pdcch_cfg_t cfg;
srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; srslte_ofdm_t fft[SRSLTE_MAX_PORTS];
@ -72,6 +77,9 @@ typedef struct SRSLTE_API {
srslte_dmrs_pdcch_estimator_t dmrs_pdcch[SRSLTE_UE_DL_NR_MAX_NOF_CORESET]; 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_dci_msg_nr_t pending_ul_dci_msg[SRSLTE_MAX_DCI_MSG_NR];
uint32_t pending_ul_dci_count;
} srslte_ue_dl_nr_t; } srslte_ue_dl_nr_t;
SRSLTE_API int SRSLTE_API int
@ -79,22 +87,28 @@ 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_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_cfg_t* cfg); SRSLTE_API int srslte_ue_dl_nr_set_pdcch_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_slot_cfg_t* slot_cfg);
SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
const srslte_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_find_dl_dci(srslte_ue_dl_nr_t* q, SRSLTE_API int srslte_ue_dl_nr_find_ul_dci(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
uint16_t rnti, uint16_t rnti,
srslte_dci_dl_nr_t* dci_dl_list, srslte_dci_ul_nr_t* dci_ul_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_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,

@ -23,7 +23,42 @@
#ifndef SRSLTE_UE_UL_DATA_H #ifndef SRSLTE_UE_UL_DATA_H
#define SRSLTE_UE_UL_DATA_H #define SRSLTE_UE_UL_DATA_H
#include "srslte/phy/ch_estimation/dmrs_sch.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/phch/phch_cfg_nr.h" #include "srslte/phy/phch/phch_cfg_nr.h"
#include "srslte/phy/phch/pusch_nr.h"
typedef struct SRSLTE_API {
srslte_pusch_nr_args_t pusch;
uint32_t nof_max_prb;
} srslte_ue_ul_nr_args_t;
typedef struct SRSLTE_API {
uint32_t max_prb;
srslte_carrier_nr_t carrier;
srslte_ofdm_t ifft;
cf_t* sf_symbols[SRSLTE_MAX_PORTS];
srslte_pusch_nr_t pusch;
srslte_dmrs_sch_t dmrs;
} srslte_ue_ul_nr_t;
SRSLTE_API int srslte_ue_ul_nr_init(srslte_ue_ul_nr_t* q, cf_t* output, const srslte_ue_ul_nr_args_t* args);
SRSLTE_API int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* carrier);
SRSLTE_API int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pusch_cfg,
uint8_t* data_);
SRSLTE_API void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q);
SRSLTE_API int
srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len);
#endif // SRSLTE_UE_UL_DATA_H #endif // SRSLTE_UE_UL_DATA_H

@ -108,6 +108,7 @@ extern "C" {
#include "srslte/phy/ue/ue_mib.h" #include "srslte/phy/ue/ue_mib.h"
#include "srslte/phy/ue/ue_sync.h" #include "srslte/phy/ue/ue_sync.h"
#include "srslte/phy/ue/ue_ul.h" #include "srslte/phy/ue/ue_ul.h"
#include "srslte/phy/ue/ue_ul_nr.h"
#include "srslte/phy/enb/enb_dl.h" #include "srslte/phy/enb/enb_dl.h"
#include "srslte/phy/enb/enb_dl_nr.h" #include "srslte/phy/enb/enb_dl_nr.h"

@ -108,7 +108,7 @@ static int csi_rs_location_get_l_list(const srslte_csi_rs_resource_mapping_t* re
} }
uint32_t csi_rs_cinit(const srslte_carrier_nr_t* carrier, uint32_t csi_rs_cinit(const srslte_carrier_nr_t* carrier,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
uint32_t l) uint32_t l)
{ {
@ -118,7 +118,7 @@ uint32_t csi_rs_cinit(const srslte_carrier_nr_t* carrier,
return ((SRSLTE_NSYMB_PER_SLOT_NR * n + l + 1UL) * (2UL * n_id) << 10UL) + n_id; return ((SRSLTE_NSYMB_PER_SLOT_NR * n + l + 1UL) * (2UL * n_id) << 10UL) + n_id;
} }
bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const srslte_dl_slot_cfg_t* slot_cfg) bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const srslte_slot_cfg_t* slot_cfg)
{ {
if (periodicity == NULL || slot_cfg == NULL) { if (periodicity == NULL || slot_cfg == NULL) {
return false; return false;
@ -136,7 +136,6 @@ bool srslte_csi_send(const srslte_csi_rs_period_and_offset_t* periodicity, const
uint32_t csi_rs_count(srslte_csi_rs_density_t density, uint32_t nprb) uint32_t csi_rs_count(srslte_csi_rs_density_t density, uint32_t nprb)
{ {
switch (density) { switch (density) {
case srslte_csi_rs_resource_mapping_density_three: case srslte_csi_rs_resource_mapping_density_three:
return nprb * 3; return nprb * 3;
case srslte_csi_rs_resource_mapping_density_dot5_even: case srslte_csi_rs_resource_mapping_density_dot5_even:
@ -183,7 +182,7 @@ uint32_t csi_rs_rb_stride(const srslte_csi_rs_resource_mapping_t* m)
} }
int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier, int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
cf_t* grid) cf_t* grid)
{ {
@ -253,7 +252,7 @@ int srslte_csi_rs_nzp_put(const srslte_carrier_nr_t* carrier,
} }
int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier, int srslte_csi_rs_nzp_measure(const srslte_carrier_nr_t* carrier,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
const cf_t* grid, const cf_t* grid,
srslte_csi_rs_measure_t* measure) srslte_csi_rs_measure_t* measure)

@ -116,7 +116,7 @@ static void dmrs_pdcch_put_symbol_noninterleaved(const srslte_carrier_nr_t* ca
int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier, int srslte_dmrs_pdcch_put(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_dci_location_t* dci_location, const srslte_dci_location_t* dci_location,
cf_t* sf_symbols) cf_t* sf_symbols)
{ {
@ -326,7 +326,7 @@ srslte_dmrs_pdcch_extract(srslte_dmrs_pdcch_estimator_t* q, uint32_t cinit, cons
} }
int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q, int srslte_dmrs_pdcch_estimate(srslte_dmrs_pdcch_estimator_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const cf_t* sf_symbols) const cf_t* sf_symbols)
{ {
if (q == NULL || sf_symbols == NULL) { if (q == NULL || sf_symbols == NULL) {

@ -88,11 +88,10 @@ static uint32_t dmrs_pucch_format1_n_pucch(const srslte_pucch_nr_resource_t* res
int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
cf_t* slot_symbols) cf_t* slot_symbols)
{ {
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) { if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
@ -155,12 +154,11 @@ int srslte_dmrs_pucch_format1_put(const srslte_pucch_nr_t* q,
int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const cf_t* slot_symbols, const cf_t* slot_symbols,
srslte_chest_ul_res_t* res) srslte_chest_ul_res_t* res)
{ {
if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL || if (q == NULL || carrier == NULL || cfg == NULL || slot == NULL || resource == NULL || slot_symbols == NULL ||
res == NULL) { res == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -288,7 +286,7 @@ int srslte_dmrs_pucch_format1_estimate(const srslte_pucch_nr_t* q,
static uint32_t dmrs_pucch_format2_cinit(const srslte_carrier_nr_t* carrier, static uint32_t dmrs_pucch_format2_cinit(const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
uint32_t l) uint32_t l)
{ {
uint32_t n = SRSLTE_SLOT_NR_MOD(slot->idx, carrier->numerology); uint32_t n = SRSLTE_SLOT_NR_MOD(slot->idx, carrier->numerology);
@ -300,7 +298,7 @@ static uint32_t dmrs_pucch_format2_cinit(const srslte_carrier_nr_t* car
int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
cf_t* slot_symbols) cf_t* slot_symbols)
{ {
@ -341,7 +339,7 @@ int srslte_dmrs_pucch_format2_put(const srslte_pucch_nr_t* q,
int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q, int srslte_dmrs_pucch_format2_estimate(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const cf_t* slot_symbols, const cf_t* slot_symbols,
srslte_chest_ul_res_t* res) srslte_chest_ul_res_t* res)

@ -77,7 +77,6 @@ static uint32_t srslte_dmrs_get_lse(srslte_dmrs_sch_t* q,
uint32_t count = 0; uint32_t count = 0;
switch (dmrs_type) { switch (dmrs_type) {
case srslte_dmrs_sch_type_1: case srslte_dmrs_sch_type_1:
count = srslte_dmrs_get_pilots_type1(start_prb, nof_prb, delta, symbols, least_square_estimates); count = srslte_dmrs_get_pilots_type1(start_prb, nof_prb, delta, symbols, least_square_estimates);
break; break;
@ -85,7 +84,7 @@ static uint32_t srslte_dmrs_get_lse(srslte_dmrs_sch_t* q,
count = srslte_dmrs_get_pilots_type2(start_prb, nof_prb, delta, symbols, least_square_estimates); count = srslte_dmrs_get_pilots_type2(start_prb, nof_prb, delta, symbols, least_square_estimates);
break; break;
default: default:
ERROR("Unknown DMRS type.\n"); ERROR("Unknown DMRS type.");
} }
// Generate sequence for the given pilots // Generate sequence for the given pilots
@ -143,7 +142,6 @@ static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_sch_t* q,
srslte_sequence_state_gen_f(sequence_state, M_SQRT1_2, (float*)q->temp, count * 2); srslte_sequence_state_gen_f(sequence_state, M_SQRT1_2, (float*)q->temp, count * 2);
switch (dmrs_type) { switch (dmrs_type) {
case srslte_dmrs_sch_type_1: case srslte_dmrs_sch_type_1:
count = srslte_dmrs_put_pilots_type1(start_prb, nof_prb, delta, symbols, q->temp); count = srslte_dmrs_put_pilots_type1(start_prb, nof_prb, delta, symbols, q->temp);
break; break;
@ -151,7 +149,7 @@ static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_sch_t* q,
count = srslte_dmrs_put_pilots_type2(start_prb, nof_prb, delta, symbols, q->temp); count = srslte_dmrs_put_pilots_type2(start_prb, nof_prb, delta, symbols, q->temp);
break; break;
default: default:
ERROR("Unknown DMRS type.\n"); ERROR("Unknown DMRS type.");
} }
return count; return count;
@ -223,7 +221,7 @@ static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_single(const srslte_dm
int count = 0; int count = 0;
if (ld < SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN) { if (ld < SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN) {
ERROR("Duration is below the minimum\n"); ERROR("Duration is below the minimum");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -318,7 +316,7 @@ static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(const srslte_dm
// According to Table 7.4.1.1.2-4, the additional position 3 is invalid. // According to Table 7.4.1.1.2-4, the additional position 3 is invalid.
if (dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) { if (dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) {
ERROR("Invalid additional DMRS (%d)\n", dmrs_cfg->additional_pos); ERROR("Invalid additional DMRS (%d)", dmrs_cfg->additional_pos);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -367,7 +365,7 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_dmrs_sch_cfg_t* dmrs_cfg,
// The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal to 'pos2' // The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal to 'pos2'
if (dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2 && dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) { if (dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2 && dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) {
ERROR("The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal " ERROR("The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal "
"to 'pos2'\n"); "to 'pos2'");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -375,7 +373,7 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_dmrs_sch_cfg_t* dmrs_cfg,
// applicable when dmrs-TypeA-Position is equal to 'pos2 // applicable when dmrs-TypeA-Position is equal to 'pos2
if ((ld == 3 || ld == 4) && dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2) { if ((ld == 3 || ld == 4) && dmrs_cfg->typeA_pos != srslte_dmrs_sch_typeA_pos_2) {
ERROR("For PDSCH mapping type A, ld = 3 and ld = 4 symbols in Tables 7.4.1.1.2-3 and 7.4.1.1.2-4 respectively " ERROR("For PDSCH mapping type A, ld = 3 and ld = 4 symbols in Tables 7.4.1.1.2-3 and 7.4.1.1.2-4 respectively "
"is only applicable when dmrs-TypeA-Position is equal to 'pos2\n"); "is only applicable when dmrs-TypeA-Position is equal to 'pos2");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -384,7 +382,7 @@ int srslte_dmrs_sch_get_symbols_idx(const srslte_dmrs_sch_cfg_t* dmrs_cfg,
} }
return srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(dmrs_cfg, ld, symbols); return srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(dmrs_cfg, ld, symbols);
case srslte_sch_mapping_type_B: case srslte_sch_mapping_type_B:
ERROR("Error PDSCH mapping type B not supported\n"); ERROR("Error PDSCH mapping type B not supported");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -416,7 +414,7 @@ int srslte_dmrs_sch_get_sc_idx(const srslte_dmrs_sch_cfg_t* cfg, uint32_t max_co
int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant) int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslte_sch_grant_nr_t* grant)
{ {
if (grant->nof_dmrs_cdm_groups_without_data < 1 || grant->nof_dmrs_cdm_groups_without_data > 3) { if (grant->nof_dmrs_cdm_groups_without_data < 1 || grant->nof_dmrs_cdm_groups_without_data > 3) {
ERROR("Invalid number if DMRS CDM groups without data (%d). Valid values: 1, 2 , 3\n", ERROR("Invalid number if DMRS CDM groups without data (%d). Valid values: 1, 2 , 3",
grant->nof_dmrs_cdm_groups_without_data); grant->nof_dmrs_cdm_groups_without_data);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -429,7 +427,7 @@ int srslte_dmrs_sch_get_N_prb(const srslte_dmrs_sch_cfg_t* dmrs_cfg, const srslt
uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {};
int ret = srslte_dmrs_sch_get_symbols_idx(dmrs_cfg, grant, symbols); int ret = srslte_dmrs_sch_get_symbols_idx(dmrs_cfg, grant, symbols);
if (ret < SRSLTE_SUCCESS) { if (ret < SRSLTE_SUCCESS) {
ERROR("Error getting PDSCH DMRS symbol indexes\n"); ERROR("Error getting PDSCH DMRS symbol indexes");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -462,14 +460,14 @@ static uint32_t srslte_dmrs_sch_seed(const srslte_carrier_nr_t* carrier,
(uint64_t)INT32_MAX); (uint64_t)INT32_MAX);
} }
int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue) int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_rx)
{ {
if (q == NULL) { if (q == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
if (is_ue) { if (is_rx) {
q->is_ue = true; q->is_rx = true;
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -509,13 +507,13 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t*
q->temp = srslte_vec_cf_malloc(q->max_nof_prb * SRSLTE_NRE); q->temp = srslte_vec_cf_malloc(q->max_nof_prb * SRSLTE_NRE);
if (!q->temp) { if (!q->temp) {
ERROR("malloc\n"); ERROR("malloc");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
// If it is not UE, quit now // If it is not UE, quit now
if (!q->is_ue) { if (!q->is_rx) {
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -538,7 +536,7 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t*
// The maximum number of pilots is for Type 1 // The maximum number of pilots is for Type 1
q->pilot_estimates = srslte_vec_cf_malloc(SRSLTE_DMRS_SCH_MAX_SYMBOLS * q->max_nof_prb * SRSLTE_NRE / 2); q->pilot_estimates = srslte_vec_cf_malloc(SRSLTE_DMRS_SCH_MAX_SYMBOLS * q->max_nof_prb * SRSLTE_NRE / 2);
if (!q->pilot_estimates) { if (!q->pilot_estimates) {
ERROR("malloc\n"); ERROR("malloc");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
@ -547,7 +545,7 @@ int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t*
} }
int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg,
const srslte_sch_grant_nr_t* grant, const srslte_sch_grant_nr_t* grant,
cf_t* sf_symbols) cf_t* sf_symbols)
@ -642,7 +640,7 @@ static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q,
} }
int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_cfg_nr_t* pdsch_cfg,
const srslte_sch_grant_nr_t* grant, const srslte_sch_grant_nr_t* grant,
const cf_t* sf_symbols, const cf_t* sf_symbols,
@ -663,7 +661,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {};
int nof_symbols = srslte_dmrs_sch_get_symbols_idx(&pdsch_cfg->dmrs, grant, symbols); int nof_symbols = srslte_dmrs_sch_get_symbols_idx(&pdsch_cfg->dmrs, grant, symbols);
if (nof_symbols <= SRSLTE_SUCCESS) { if (nof_symbols <= SRSLTE_SUCCESS) {
ERROR("Error getting symbol indexes\n"); ERROR("Error getting symbol indexes");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -679,7 +677,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
q, pdsch_cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l], &q->pilot_estimates[nof_pilots_x_symbol * i]); q, pdsch_cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l], &q->pilot_estimates[nof_pilots_x_symbol * i]);
if (nof_pilots_x_symbol == 0) { if (nof_pilots_x_symbol == 0) {
ERROR("Error, no pilots extracted (i=%d, l=%d)\n", i, l); ERROR("Error, no pilots extracted (i=%d, l=%d)", i, l);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
@ -733,7 +731,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
if (dmrs_cfg->type == srslte_dmrs_sch_type_1) { if (dmrs_cfg->type == srslte_dmrs_sch_type_1) {
// Prepare interpolator // Prepare interpolator
if (srslte_interp_linear_resize(&q->interpolator_type1, nof_pilots_x_symbol, 2) < SRSLTE_SUCCESS) { if (srslte_interp_linear_resize(&q->interpolator_type1, nof_pilots_x_symbol, 2) < SRSLTE_SUCCESS) {
ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;\n", nof_pilots_x_symbol, 2); ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;", nof_pilots_x_symbol, 2);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -743,7 +741,7 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
} else { } else {
// Prepare interpolator // Prepare interpolator
if (srslte_interp_linear_resize(&q->interpolator_type2, nof_pilots_x_symbol, 3) < SRSLTE_SUCCESS) { if (srslte_interp_linear_resize(&q->interpolator_type2, nof_pilots_x_symbol, 3) < SRSLTE_SUCCESS) {
ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;\n", nof_pilots_x_symbol, 3); ERROR("Resizing interpolator nof_pilots_x_symbol=%d; M=%d;", nof_pilots_x_symbol, 3);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -761,7 +759,6 @@ int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q,
if (symbols[symbol_idx] == l) { if (symbols[symbol_idx] == l) {
switch (dmrs_cfg->type) { switch (dmrs_cfg->type) {
case srslte_dmrs_sch_type_1: case srslte_dmrs_sch_type_1:
// Skip if there is no data to read // Skip if there is no data to read
if (grant->nof_dmrs_cdm_groups_without_data != 1) { if (grant->nof_dmrs_cdm_groups_without_data != 1) {

@ -31,7 +31,7 @@ static uint32_t start_rb = UINT32_MAX;
static uint32_t nof_rb = UINT32_MAX; static uint32_t nof_rb = UINT32_MAX;
static uint32_t first_symbol = UINT32_MAX; static uint32_t first_symbol = UINT32_MAX;
static int test(const srslte_dl_slot_cfg_t* slot_cfg, static int test(const srslte_slot_cfg_t* slot_cfg,
const srslte_csi_rs_nzp_resource_t* resource, const srslte_csi_rs_nzp_resource_t* resource,
srslte_channel_awgn_t* awgn, srslte_channel_awgn_t* awgn,
cf_t* grid) cf_t* grid)
@ -118,7 +118,7 @@ static void parse_args(int argc, char** argv)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
srslte_dl_slot_cfg_t slot_cfg = {}; srslte_slot_cfg_t slot_cfg = {};
srslte_csi_rs_nzp_resource_t resource = {}; srslte_csi_rs_nzp_resource_t resource = {};
srslte_channel_awgn_t awgn = {}; srslte_channel_awgn_t awgn = {};
@ -149,21 +149,18 @@ int main(int argc, char** argv)
for (resource.resource_mapping.first_symbol_idx = first_symbol_begin; for (resource.resource_mapping.first_symbol_idx = first_symbol_begin;
resource.resource_mapping.first_symbol_idx <= first_symbol_end; resource.resource_mapping.first_symbol_idx <= first_symbol_end;
resource.resource_mapping.first_symbol_idx++) { resource.resource_mapping.first_symbol_idx++) {
// Iterate over possible power control offset // Iterate over possible power control offset
float power_control_offset_begin = isnormal(power_control_offset) ? power_control_offset : -8.0f; float power_control_offset_begin = isnormal(power_control_offset) ? power_control_offset : -8.0f;
float power_control_offset_end = isnormal(power_control_offset) ? power_control_offset : 15.0f; float power_control_offset_end = isnormal(power_control_offset) ? power_control_offset : 15.0f;
for (resource.power_control_offset = power_control_offset_begin; for (resource.power_control_offset = power_control_offset_begin;
resource.power_control_offset <= power_control_offset_end; resource.power_control_offset <= power_control_offset_end;
resource.power_control_offset += 1.0f) { resource.power_control_offset += 1.0f) {
// Iterate over all possible starting number of PRB // Iterate over all possible starting number of PRB
uint32_t start_rb_begin = (start_rb != UINT32_MAX) ? start_rb : 0; uint32_t start_rb_begin = (start_rb != UINT32_MAX) ? start_rb : 0;
uint32_t start_rb_end = (start_rb != UINT32_MAX) ? start_rb : carrier.nof_prb - 24; uint32_t start_rb_end = (start_rb != UINT32_MAX) ? start_rb : carrier.nof_prb - 24;
for (resource.resource_mapping.freq_band.start_rb = start_rb_begin; for (resource.resource_mapping.freq_band.start_rb = start_rb_begin;
resource.resource_mapping.freq_band.start_rb <= start_rb_end; resource.resource_mapping.freq_band.start_rb <= start_rb_end;
resource.resource_mapping.freq_band.start_rb += 4) { resource.resource_mapping.freq_band.start_rb += 4) {
// Iterate over all possible number of PRB // Iterate over all possible number of PRB
uint32_t nof_rb_begin = (nof_rb != UINT32_MAX) ? nof_rb : 24; uint32_t nof_rb_begin = (nof_rb != UINT32_MAX) ? nof_rb : 24;
uint32_t nof_rb_end = uint32_t nof_rb_end =
@ -171,7 +168,6 @@ int main(int argc, char** argv)
for (resource.resource_mapping.freq_band.nof_rb = nof_rb_begin; for (resource.resource_mapping.freq_band.nof_rb = nof_rb_begin;
resource.resource_mapping.freq_band.nof_rb <= nof_rb_end; resource.resource_mapping.freq_band.nof_rb <= nof_rb_end;
resource.resource_mapping.freq_band.nof_rb += 4) { resource.resource_mapping.freq_band.nof_rb += 4) {
// Iterate for all slot numbers // Iterate for all slot numbers
for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot_cfg.idx++) { for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot_cfg.idx++) {
// Steer Frequency allocation // Steer Frequency allocation

@ -63,7 +63,7 @@ static int run_test(srslte_dmrs_pdcch_estimator_t* estimator,
cf_t* sf_symbols, cf_t* sf_symbols,
srslte_dmrs_pdcch_ce_t* ce) srslte_dmrs_pdcch_ce_t* ce)
{ {
srslte_dl_slot_cfg_t slot_cfg = {}; srslte_slot_cfg_t slot_cfg = {};
srslte_dci_location_t dci_location = {}; srslte_dci_location_t dci_location = {};
dci_location.L = aggregation_level; dci_location.L = aggregation_level;
@ -142,10 +142,8 @@ int main(int argc, char** argv)
} }
for (coreset.duration = 1; coreset.duration <= 3; coreset.duration++) { for (coreset.duration = 1; coreset.duration <= 3; coreset.duration++) {
for (search_space.type = srslte_search_space_type_common_0; search_space.type <= srslte_search_space_type_ue; for (search_space.type = srslte_search_space_type_common_0; search_space.type <= srslte_search_space_type_ue;
search_space.type++) { search_space.type++) {
for (uint32_t i = 0; i < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; i++) { for (uint32_t i = 0; i < SRSLTE_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; i++) {
uint32_t L = 1U << i; uint32_t L = 1U << i;
uint32_t nof_reg = coreset.duration * nof_freq_resources * 6; uint32_t nof_reg = coreset.duration * nof_freq_resources * 6;
@ -155,7 +153,6 @@ int main(int argc, char** argv)
for (uint32_t aggregation_level = 0; 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++) { aggregation_level++) {
srslte_dmrs_pdcch_estimator_init(&estimator, &carrier, &coreset); srslte_dmrs_pdcch_estimator_init(&estimator, &carrier, &coreset);
if (run_test(&estimator, &coreset, &search_space, aggregation_level, sf_symbols, &pdcch_ce)) { if (run_test(&estimator, &coreset, &search_space, aggregation_level, sf_symbols, &pdcch_ce)) {

@ -214,7 +214,7 @@ static int run_test(srslte_dmrs_sch_t* dmrs_pdsch,
{ {
TESTASSERT(assert_cfg(pdsch_cfg, grant) == SRSLTE_SUCCESS); TESTASSERT(assert_cfg(pdsch_cfg, grant) == SRSLTE_SUCCESS);
srslte_dl_slot_cfg_t slot_cfg = {}; srslte_slot_cfg_t slot_cfg = {};
for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(dmrs_pdsch->carrier.numerology); slot_cfg.idx++) { for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(dmrs_pdsch->carrier.numerology); slot_cfg.idx++) {
TESTASSERT(srslte_dmrs_sch_put_sf(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols) == SRSLTE_SUCCESS); TESTASSERT(srslte_dmrs_sch_put_sf(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols) == SRSLTE_SUCCESS);
@ -289,7 +289,6 @@ int main(int argc, char** argv)
for (pdsch_cfg.dmrs.additional_pos = add_pos_begin; pdsch_cfg.dmrs.additional_pos <= add_pos_end; for (pdsch_cfg.dmrs.additional_pos = add_pos_begin; pdsch_cfg.dmrs.additional_pos <= add_pos_end;
pdsch_cfg.dmrs.additional_pos++) { pdsch_cfg.dmrs.additional_pos++) {
srslte_dmrs_sch_len_t max_len_begin = srslte_dmrs_sch_len_1; srslte_dmrs_sch_len_t max_len_begin = srslte_dmrs_sch_len_1;
srslte_dmrs_sch_len_t max_len_end = srslte_dmrs_sch_len_2; srslte_dmrs_sch_len_t max_len_end = srslte_dmrs_sch_len_2;
@ -300,16 +299,13 @@ int main(int argc, char** argv)
} }
for (pdsch_cfg.dmrs.length = max_len_begin; pdsch_cfg.dmrs.length <= max_len_end; pdsch_cfg.dmrs.length++) { for (pdsch_cfg.dmrs.length = max_len_begin; pdsch_cfg.dmrs.length <= max_len_end; pdsch_cfg.dmrs.length++) {
for (uint32_t bw = 1; bw <= carrier.nof_prb; bw++) { for (uint32_t bw = 1; bw <= carrier.nof_prb; bw++) {
for (uint32_t i = 0; i < carrier.nof_prb; i++) { for (uint32_t i = 0; i < carrier.nof_prb; i++) {
grant.prb_idx[i] = (i < bw); grant.prb_idx[i] = (i < bw);
} }
for (grant.nof_dmrs_cdm_groups_without_data = 1; grant.nof_dmrs_cdm_groups_without_data <= 3; for (grant.nof_dmrs_cdm_groups_without_data = 1; grant.nof_dmrs_cdm_groups_without_data <= 3;
grant.nof_dmrs_cdm_groups_without_data++) { grant.nof_dmrs_cdm_groups_without_data++) {
// Load default type A grant // Load default type A grant
srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &grant); srslte_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &grant);

@ -13,6 +13,30 @@
#include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/common/phy_common_nr.h"
#include <string.h> #include <string.h>
const char* srslte_rnti_type_str(srslte_rnti_type_t rnti_type)
{
switch (rnti_type) {
case srslte_rnti_type_c:
return "C-RNTI";
case srslte_rnti_type_p:
return "P-RNTI";
case srslte_rnti_type_si:
return "SI-RNTI";
case srslte_rnti_type_ra:
return "RA-RNTI";
case srslte_rnti_type_tc:
return "TC-RNTI";
case srslte_rnti_type_cs:
return "CS-RNTI";
case srslte_rnti_type_sp_csi:
return "SP-CSI-RNTI";
case srslte_rnti_type_mcs_c:
return "MCS-C-RNTI";
default:; // Do nothing
}
return "unknown";
}
uint32_t srslte_coreset_get_bw(const srslte_coreset_t* coreset) uint32_t srslte_coreset_get_bw(const srslte_coreset_t* coreset)
{ {
uint32_t prb_count = 0; uint32_t prb_count = 0;

@ -185,9 +185,9 @@ int srslte_enb_dl_nr_base_zero(srslte_enb_dl_nr_t* q)
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_enb_dl_nr_pdcch_put(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_slot_cfg_t* slot_cfg,
const srslte_dci_dl_nr_t* dci_dl) const srslte_dci_dl_nr_t* dci_dl)
{ {
if (q == NULL || slot_cfg == NULL || dci_dl == NULL) { if (q == NULL || slot_cfg == NULL || dci_dl == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -217,12 +217,11 @@ int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q,
return SRSLTE_SUCCESS; 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_slot_cfg_t* slot,
const srslte_sch_cfg_nr_t* cfg, const srslte_sch_cfg_nr_t* cfg,
uint8_t* data[SRSLTE_MAX_TB]) uint8_t* data[SRSLTE_MAX_TB])
{ {
if (srslte_dmrs_sch_put_sf(&q->dmrs, slot, cfg, &cfg->grant, q->sf_symbols[0]) < SRSLTE_SUCCESS) { if (srslte_dmrs_sch_put_sf(&q->dmrs, slot, cfg, &cfg->grant, q->sf_symbols[0]) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

@ -44,6 +44,27 @@ static int dci_nr_format_1_0_freq_resource_size(const srslte_carrier_nr_t* carri
return (int)ceil(log2(N_DL_BWP_RB * (N_DL_BWP_RB + 1) / 2.0)); return (int)ceil(log2(N_DL_BWP_RB * (N_DL_BWP_RB + 1) / 2.0));
} }
bool srslte_dci_nr_format_1_0_valid(const srslte_dci_msg_nr_t* dci)
{
// Check pointer
if (dci == NULL) {
return false;
}
// Wrong format
if (dci->format != srslte_dci_format_nr_1_0) {
return false;
}
// The format bit is only present for these RNTI
if (dci->rnti_type == srslte_rnti_type_c || dci->rnti_type == srslte_rnti_type_tc) {
return dci->payload[0] == 1;
}
// Otherwise, the message might be format 1_0
return true;
}
int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier, int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier,
const srslte_coreset_t* coreset, const srslte_coreset_t* coreset,
const srslte_dci_dl_nr_t* dci, const srslte_dci_dl_nr_t* dci,
@ -61,12 +82,12 @@ int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier,
switch (msg->format) { switch (msg->format) {
case srslte_dci_format_nr_1_0: case srslte_dci_format_nr_1_0:
if (srslte_dci_nr_format_1_0_pack(carrier, coreset, dci, msg) < SRSLTE_SUCCESS) { if (srslte_dci_nr_format_1_0_pack(carrier, coreset, dci, msg) < SRSLTE_SUCCESS) {
ERROR("Error packing DL DCI\n"); ERROR("Error packing DL DCI");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
break; break;
default: default:
ERROR("Unsupported DCI format %d\n", msg->format); ERROR("Unsupported DCI format %d", msg->format);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -80,7 +101,7 @@ int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier,
{ {
uint32_t trim = 0; // hard-coded bit trimming uint32_t trim = 0; // hard-coded bit trimming
bool enable_hopping = false; // hard-coded PUSCH hopping bool enable_hopping = false; // hard-coded PUSCH hopping
uint32_t padding = 0; // Hard-coded padding uint32_t padding = 8; // Hard-coded padding
bool supplementary_uplink = false; // Hard-coded supplementary Uplink bool supplementary_uplink = false; // Hard-coded supplementary Uplink
uint8_t* y = msg->payload; uint8_t* y = msg->payload;
srslte_rnti_type_t rnti_type = msg->rnti_type; srslte_rnti_type_t rnti_type = msg->rnti_type;
@ -142,7 +163,7 @@ int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier,
msg->nof_bits = srslte_dci_nr_format_0_0_sizeof(carrier, coreset0, rnti_type); msg->nof_bits = srslte_dci_nr_format_0_0_sizeof(carrier, coreset0, rnti_type);
if (msg->nof_bits != y - msg->payload) { if (msg->nof_bits != y - msg->payload) {
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload)); ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload));
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -156,22 +177,31 @@ int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier,
{ {
uint32_t trim = 0; // hard-coded bit trimming uint32_t trim = 0; // hard-coded bit trimming
bool enable_hopping = false; // hard-coded PUSCH hopping bool enable_hopping = false; // hard-coded PUSCH hopping
uint32_t padding = 0; // Hard-coded padding uint32_t padding = 8; // Hard-coded padding
bool supplementary_uplink = false; // Hard-coded supplementary Uplink bool supplementary_uplink = false; // Hard-coded supplementary Uplink
uint8_t* y = msg->payload; uint8_t* y = msg->payload;
srslte_rnti_type_t rnti_type = msg->rnti_type; srslte_rnti_type_t rnti_type = msg->rnti_type;
// Copy DCI MSG fields
dci->location = msg->location;
dci->search_space = msg->search_space;
dci->coreset_id = msg->coreset_id;
dci->rnti_type = msg->rnti_type;
dci->rnti = msg->rnti;
dci->format = msg->format;
if (carrier == NULL) { if (carrier == NULL) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// Check RNTI type // Check RNTI type
if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) { if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) {
ERROR("Unsupported %s", srslte_rnti_type_str(rnti_type));
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (msg->nof_bits != srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)) { if (msg->nof_bits != srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)) {
ERROR("Invalid number of bits %d, expected %d\n", ERROR("Invalid number of bits %d, expected %d",
msg->nof_bits, msg->nof_bits,
srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)); srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type));
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -179,7 +209,7 @@ int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier,
// Identifier for DCI formats 1 bits // Identifier for DCI formats 1 bits
if (*(y++) != 0) { if (*(y++) != 0) {
ERROR("Wrond DCI format\n"); ERROR("Wrond DCI format");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -234,7 +264,7 @@ int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier,
{ {
uint32_t trim = 0; // hard-coded bit trimming uint32_t trim = 0; // hard-coded bit trimming
bool enable_hopping = false; // hard-coded PUSCH hopping bool enable_hopping = false; // hard-coded PUSCH hopping
uint32_t padding = 0; // Hard-coded padding uint32_t padding = 8; // Hard-coded padding
bool supplementary_uplink = false; // Hard-coded supplementary Uplink bool supplementary_uplink = false; // Hard-coded supplementary Uplink
int count = 0; int count = 0;
@ -286,7 +316,37 @@ int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier,
static int dci_nr_format_0_0_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len) static int dci_nr_format_0_0_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len)
{ {
return SRSLTE_ERROR; uint32_t len = 0;
// Print format
len = srslte_print_check(
str, str_len, len, "rnti=%04x L=%d cce=%d dci=0_0 ", dci->rnti, dci->location.L, dci->location.ncce);
// Frequency domain resource assignment
len = srslte_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment);
// Time domain resource assignment 4 bits
len = srslte_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment);
// Frequency hopping flag 1 bit
len = srslte_print_check(str, str_len, len, "hop=%c ", dci->freq_hopping_flag == 0 ? 'n' : 'y');
// Modulation and coding scheme 5 bits
len = srslte_print_check(str, str_len, len, "mcs=%d ", dci->mcs);
// New data indicator 1 bit
len = srslte_print_check(str, str_len, len, "ndi=%d ", dci->ndi);
// Redundancy version 2 bits
len = srslte_print_check(str, str_len, len, "rv=%d ", dci->rv);
// HARQ process number 4 bits
len = srslte_print_check(str, str_len, len, "harq_id=%d ", dci->harq_feedback);
// TPC command for scheduled PUSCH 2 bits
len = srslte_print_check(str, str_len, len, "tpc=%d ", dci->tpc);
return len;
} }
int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier, int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
@ -390,7 +450,7 @@ int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
msg->nof_bits = srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type); msg->nof_bits = srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type);
if (msg->nof_bits != y - msg->payload) { if (msg->nof_bits != y - msg->payload) {
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload)); ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload));
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -414,7 +474,7 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
dci->format = msg->format; dci->format = msg->format;
if (msg->nof_bits != srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)) { if (msg->nof_bits != srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)) {
ERROR("Invalid number of bits %d, expected %d\n", ERROR("Invalid number of bits %d, expected %d",
msg->nof_bits, msg->nof_bits,
srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type)); srslte_dci_nr_format_1_0_sizeof(carrier, coreset, rnti_type));
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -424,7 +484,7 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) { if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
// The value of this bit field is always set to 1, indicating a DL DCI format // The value of this bit field is always set to 1, indicating a DL DCI format
if (*(y++) != 1) { if (*(y++) != 1) {
ERROR("Wrond DCI format\n"); ERROR("Wrond DCI format");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
@ -511,7 +571,7 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
} }
if (msg->nof_bits != y - msg->payload) { if (msg->nof_bits != y - msg->payload) {
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload)); ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)", msg->nof_bits, (int)(y - msg->payload));
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -618,7 +678,8 @@ static int dci_nr_format_1_0_to_str(const srslte_dci_dl_nr_t* dci, char* str, ui
uint32_t len = 0; uint32_t len = 0;
// Print format // Print format
len = srslte_print_check(str, str_len, len, "L=%d cce=%d dci=1_0 ", dci->location.L, dci->location.ncce); len = srslte_print_check(
str, str_len, len, "rnti=%04x L=%d cce=%d dci=1_0 ", dci->rnti, dci->location.L, dci->location.ncce);
if (dci->rnti_type == srslte_rnti_type_p) { if (dci->rnti_type == srslte_rnti_type_p) {
len = srslte_print_check(str, str_len, len, "smi=%d sm=%d ", dci->smi, dci->sm); len = srslte_print_check(str, str_len, len, "smi=%d sm=%d ", dci->smi, dci->sm);

@ -471,7 +471,6 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q,
uint8_t* data[SRSLTE_MAX_TB], uint8_t* data[SRSLTE_MAX_TB],
cf_t* sf_symbols[SRSLTE_MAX_PORTS]) cf_t* sf_symbols[SRSLTE_MAX_PORTS])
{ {
// Check input pointers // Check input pointers
if (!q || !cfg || !grant || !data || !sf_symbols) { if (!q || !cfg || !grant || !data || !sf_symbols) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -692,7 +691,7 @@ static uint32_t srslte_pdsch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg,
str_len, str_len,
len, len,
",k0=%d,freq=%s,symb=%d:%d,mapping=%s", ",k0=%d,freq=%s,symb=%d:%d,mapping=%s",
grant->k0, grant->k,
freq_str, freq_str,
grant->S, grant->S,
grant->L, grant->L,
@ -722,7 +721,6 @@ uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q,
char* str, char* str,
uint32_t str_len) uint32_t str_len)
{ {
uint32_t len = 0; uint32_t len = 0;
len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len); len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len);
@ -770,7 +768,6 @@ uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q,
char* str, char* str,
uint32_t str_len) uint32_t str_len)
{ {
uint32_t len = 0; uint32_t len = 0;
len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len); len += srslte_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len);

@ -31,7 +31,6 @@ int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* carrier,
uint32_t n_id = cfg->hopping_id_present ? cfg->hopping_id : carrier->id; uint32_t n_id = cfg->hopping_id_present ? cfg->hopping_id : carrier->id;
switch (cfg->group_hopping) { switch (cfg->group_hopping) {
case SRSLTE_PUCCH_NR_GROUP_HOPPING_NEITHER: case SRSLTE_PUCCH_NR_GROUP_HOPPING_NEITHER:
f_ss = n_id % SRSLTE_ZC_SEQUENCE_NOF_GROUPS; f_ss = n_id % SRSLTE_ZC_SEQUENCE_NOF_GROUPS;
break; break;
@ -60,7 +59,7 @@ int srslte_pucch_nr_group_sequence(const srslte_carrier_nr_t* carrier,
// Implements TS 38.211 clause 6.3.2.2.2 Cyclic shift hopping // Implements TS 38.211 clause 6.3.2.2.2 Cyclic shift hopping
int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier, int srslte_pucch_nr_alpha_idx(const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
uint32_t l, uint32_t l,
uint32_t l_prime, uint32_t l_prime,
uint32_t m0, uint32_t m0,
@ -204,7 +203,7 @@ void srslte_pucch_nr_free(srslte_pucch_nr_t* q)
int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q, int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
srslte_pucch_nr_resource_t* resource, srslte_pucch_nr_resource_t* resource,
uint32_t m_cs, uint32_t m_cs,
cf_t* slot_symbols) cf_t* slot_symbols)
@ -254,7 +253,7 @@ int srslte_pucch_nr_format0_encode(const srslte_pucch_nr_t* q,
int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q, int srslte_pucch_nr_format0_measure(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
srslte_pucch_nr_resource_t* resource, srslte_pucch_nr_resource_t* resource,
uint32_t m_cs, uint32_t m_cs,
const cf_t* slot_symbols, const cf_t* slot_symbols,
@ -363,7 +362,7 @@ cf_t srslte_pucch_nr_format1_w(const srslte_pucch_nr_t* q, uint32_t n_pucch, uin
int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q, int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
uint8_t* b, uint8_t* b,
uint32_t nof_bits, uint32_t nof_bits,
@ -444,7 +443,7 @@ int srslte_pucch_nr_format1_encode(const srslte_pucch_nr_t* q,
int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q, int srslte_pucch_nr_format1_decode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols, cf_t* slot_symbols,
@ -633,7 +632,7 @@ static int pucch_nr_format2_decode(srslte_pucch_nr_t* q,
int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q, int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_cfg_nr_t* uci_cfg,
const srslte_uci_value_nr_t* uci_value, const srslte_uci_value_nr_t* uci_value,
@ -670,7 +669,7 @@ int srslte_pucch_nr_format_2_3_4_encode(srslte_pucch_nr_t* q,
int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q, int srslte_pucch_nr_format_2_3_4_decode(srslte_pucch_nr_t* q,
const srslte_carrier_nr_t* carrier, const srslte_carrier_nr_t* carrier,
const srslte_pucch_nr_common_cfg_t* cfg, const srslte_pucch_nr_common_cfg_t* cfg,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot,
const srslte_pucch_nr_resource_t* resource, const srslte_pucch_nr_resource_t* resource,
const srslte_uci_cfg_nr_t* uci_cfg, const srslte_uci_cfg_nr_t* uci_cfg,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,

@ -31,7 +31,7 @@ int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* arg
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args)
{ {
if (q == NULL) { if (q == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -49,7 +49,7 @@ int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t*
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) int srslte_pusch_nr_init_gnb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args)
{ {
if (q == NULL || args == NULL) { if (q == NULL || args == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -470,7 +470,6 @@ int srslte_pusch_nr_encode(srslte_pusch_nr_t* q,
uint8_t* data[SRSLTE_MAX_TB], uint8_t* data[SRSLTE_MAX_TB],
cf_t* sf_symbols[SRSLTE_MAX_PORTS]) cf_t* sf_symbols[SRSLTE_MAX_PORTS])
{ {
// Check input pointers // Check input pointers
if (!q || !cfg || !grant || !data || !sf_symbols) { if (!q || !cfg || !grant || !data || !sf_symbols) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -680,8 +679,8 @@ static uint32_t srslte_pusch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg,
len = srslte_print_check(str, len = srslte_print_check(str,
str_len, str_len,
len, len,
",k0=%d,S=%d,L=%d,mapping=%s", ",k2=%d,S=%d,L=%d,mapping=%s",
grant->k0, grant->k,
grant->S, grant->S,
grant->L, grant->L,
srslte_sch_mapping_type_to_str(grant->mapping)); srslte_sch_mapping_type_to_str(grant->mapping));
@ -710,7 +709,6 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q,
char* str, char* str,
uint32_t str_len) uint32_t str_len)
{ {
uint32_t len = 0; uint32_t len = 0;
len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len);
@ -758,7 +756,6 @@ uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q,
char* str, char* str,
uint32_t str_len) uint32_t str_len)
{ {
uint32_t len = 0; uint32_t len = 0;
len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len);

@ -68,7 +68,7 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_
} }
// Select k0 // Select k0
grant->k0 = 0; grant->k = 0;
// Select PDSCH mapping // Select PDSCH mapping
static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A, static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A,
@ -117,7 +117,7 @@ static void ra_dl_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_g
// Compute S and L from SLIV from higher layers // Compute S and L from SLIV from higher layers
ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L); ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L);
grant->k0 = hl_ra_cfg->k; grant->k = hl_ra_cfg->k;
grant->mapping = hl_ra_cfg->mapping_type; grant->mapping = hl_ra_cfg->mapping_type;
} }

@ -241,7 +241,7 @@ double srslte_ra_nr_R_from_mcs(srslte_mcs_table_t mcs_table,
case ra_nr_table_3: case ra_nr_table_3:
return srslte_ra_nr_R_from_mcs_table3(mcs_idx) / 1024.0; return srslte_ra_nr_R_from_mcs_table3(mcs_idx) / 1024.0;
default: default:
ERROR("Invalid table %d\n", table); ERROR("Invalid table %d", table);
} }
return NAN; return NAN;
@ -263,7 +263,7 @@ srslte_mod_t srslte_ra_nr_mod_from_mcs(srslte_mcs_table_t mcs_table,
case ra_nr_table_3: case ra_nr_table_3:
return srslte_ra_nr_modulation_from_mcs_table3(mcs_idx); return srslte_ra_nr_modulation_from_mcs_table3(mcs_idx);
default: default:
ERROR("Invalid table %d\n", table); ERROR("Invalid table %d", table);
} }
return SRSLTE_MOD_NITEMS; return SRSLTE_MOD_NITEMS;
@ -277,7 +277,7 @@ int srslte_ra_dl_nr_slot_nof_re(const srslte_sch_cfg_nr_t* pdsch_cfg, const srsl
// the number of REs for DM-RS per PRB in the scheduled duration // the number of REs for DM-RS per PRB in the scheduled duration
int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(&pdsch_cfg->dmrs, grant); int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(&pdsch_cfg->dmrs, grant);
if (n_prb_dmrs < SRSLTE_SUCCESS) { if (n_prb_dmrs < SRSLTE_SUCCESS) {
ERROR("Invalid number of DMRS RE\n"); ERROR("Invalid number of DMRS RE");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -373,7 +373,7 @@ uint32_t srslte_ra_nr_tbs(uint32_t N_re, double S, double R, uint32_t Qm, uint32
} }
if (nof_layers == 0) { if (nof_layers == 0) {
ERROR("Incorrect number of layers (%d). Setting to 1.\n", nof_layers); ERROR("Incorrect number of layers (%d). Setting to 1.", nof_layers);
nof_layers = 1; nof_layers = 1;
} }
@ -434,7 +434,7 @@ int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg,
// 1) The UE shall first determine the number of REs (N RE ) within the slot. // 1) The UE shall first determine the number of REs (N RE ) within the slot.
int N_re = srslte_ra_dl_nr_slot_nof_re(pdsch_cfg, grant); int N_re = srslte_ra_dl_nr_slot_nof_re(pdsch_cfg, grant);
if (N_re <= SRSLTE_SUCCESS) { if (N_re <= SRSLTE_SUCCESS) {
ERROR("Invalid number of RE\n"); ERROR("Invalid number of RE");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -477,12 +477,15 @@ static int ra_dl_dmrs(const srslte_sch_hl_cfg_nr_t* pdsch_hl_cfg,
ERROR("Error loading number of DMRS CDM groups\n"); ERROR("Error loading number of DMRS CDM groups\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} else {
ERROR("Invalid case");
return SRSLTE_ERROR;
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
ERROR("Unsupported configuration\n"); ERROR("Unsupported configuration");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -502,13 +505,13 @@ int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
dci_dl->coreset_id, dci_dl->coreset_id,
dci_dl->time_domain_assigment, dci_dl->time_domain_assigment,
pdsch_grant) < SRSLTE_SUCCESS) { pdsch_grant) < SRSLTE_SUCCESS) {
ERROR("Error computing time domain resource allocation\n"); ERROR("Error computing time domain resource allocation");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// 5.1.2.2 Resource allocation in frequency domain // 5.1.2.2 Resource allocation in frequency domain
if (srslte_ra_dl_nr_freq(carrier, pdsch_hl_cfg, dci_dl, pdsch_grant) < SRSLTE_SUCCESS) { if (srslte_ra_dl_nr_freq(carrier, pdsch_hl_cfg, dci_dl, pdsch_grant) < SRSLTE_SUCCESS) {
ERROR("Error computing frequency domain resource allocation\n"); ERROR("Error computing frequency domain resource allocation");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -528,13 +531,63 @@ int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
// 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination // 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination
if (srslte_ra_nr_fill_tb(pdsch_cfg, pdsch_grant, dci_dl->mcs, &pdsch_grant->tb[0]) < SRSLTE_SUCCESS) { if (srslte_ra_nr_fill_tb(pdsch_cfg, pdsch_grant, dci_dl->mcs, &pdsch_grant->tb[0]) < SRSLTE_SUCCESS) {
ERROR("Error filing tb\n"); ERROR("Error filing tb");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
static int
ra_ul_dmrs(const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg, srslte_sch_grant_nr_t* pusch_grant, srslte_sch_cfg_nr_t* cfg)
{
const bool dedicated_dmrs_present = (pusch_grant->mapping == srslte_sch_mapping_type_A)
? pusch_hl_cfg->dmrs_typeA.present
: pusch_hl_cfg->dmrs_typeB.present;
if (pusch_grant->dci_format == srslte_dci_format_nr_0_0 || !dedicated_dmrs_present) {
if (pusch_grant->mapping == srslte_sch_mapping_type_A) {
// Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig
cfg->dmrs.additional_pos = srslte_dmrs_sch_add_pos_2;
cfg->dmrs.type = srslte_dmrs_sch_type_1;
cfg->dmrs.length = srslte_dmrs_sch_len_1;
cfg->dmrs.scrambling_id0_present = false;
cfg->dmrs.scrambling_id1_present = false;
if (pusch_grant->dci_format == srslte_dci_format_nr_0_0) {
if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(cfg, pusch_grant) < SRSLTE_SUCCESS) {
ERROR("Error loading number of DMRS CDM groups\n");
return SRSLTE_ERROR;
}
} else {
ERROR("Invalid case\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
ERROR("Unsupported configuration");
return SRSLTE_ERROR;
}
if (pusch_grant->mapping == srslte_sch_mapping_type_A) {
cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeA.additional_pos;
cfg->dmrs.type = pusch_hl_cfg->dmrs_typeA.type;
cfg->dmrs.length = pusch_hl_cfg->dmrs_typeA.length;
cfg->dmrs.scrambling_id0_present = false;
cfg->dmrs.scrambling_id1_present = false;
} else {
cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeB.additional_pos;
cfg->dmrs.type = pusch_hl_cfg->dmrs_typeB.type;
cfg->dmrs.length = pusch_hl_cfg->dmrs_typeB.length;
cfg->dmrs.scrambling_id0_present = false;
cfg->dmrs.scrambling_id1_present = false;
}
return SRSLTE_SUCCESS;
}
int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier, int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg, const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg,
const srslte_dci_ul_nr_t* dci_ul, const srslte_dci_ul_nr_t* dci_ul,
@ -548,13 +601,13 @@ int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
dci_ul->coreset_id, dci_ul->coreset_id,
dci_ul->time_domain_assigment, dci_ul->time_domain_assigment,
pusch_grant) < SRSLTE_SUCCESS) { pusch_grant) < SRSLTE_SUCCESS) {
ERROR("Error computing time domain resource allocation\n"); ERROR("Error computing time domain resource allocation");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// 5.1.2.2 Resource allocation in frequency domain // 5.1.2.2 Resource allocation in frequency domain
if (srslte_ra_ul_nr_freq(carrier, pusch_hl_cfg, dci_ul, pusch_grant) < SRSLTE_SUCCESS) { if (srslte_ra_ul_nr_freq(carrier, pusch_hl_cfg, dci_ul, pusch_grant) < SRSLTE_SUCCESS) {
ERROR("Error computing frequency domain resource allocation\n"); ERROR("Error computing frequency domain resource allocation");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -567,14 +620,14 @@ int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
pusch_grant->rnti_type = dci_ul->rnti_type; pusch_grant->rnti_type = dci_ul->rnti_type;
// 5.1.6.2 DM-RS reception procedure // 5.1.6.2 DM-RS reception procedure
if (ra_dl_dmrs(pusch_hl_cfg, pusch_grant, &pusch_cfg->dmrs) < SRSLTE_SUCCESS) { if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSLTE_SUCCESS) {
ERROR("Error selecting DMRS configuration"); ERROR("Error selecting DMRS configuration");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination // 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination
if (srslte_ra_nr_fill_tb(pusch_cfg, pusch_grant, dci_ul->mcs, &pusch_grant->tb[0]) < SRSLTE_SUCCESS) { if (srslte_ra_nr_fill_tb(pusch_cfg, pusch_grant, dci_ul->mcs, &pusch_grant->tb[0]) < SRSLTE_SUCCESS) {
ERROR("Error filing tb\n"); ERROR("Error filing tb");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

@ -60,7 +60,7 @@ int srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m,
// Select mapping // Select mapping
grant->mapping = ue_ul_default_A_lut[m].mapping; grant->mapping = ue_ul_default_A_lut[m].mapping;
grant->k2 = ue_ul_default_A_lut[m].K2 + j[scs_cfg]; grant->k = ue_ul_default_A_lut[m].K2 + j[scs_cfg];
grant->S = ue_ul_default_A_lut[m].S; grant->S = ue_ul_default_A_lut[m].S;
grant->L = ue_ul_default_A_lut[m].L; grant->L = ue_ul_default_A_lut[m].L;
@ -72,7 +72,7 @@ static void ra_ul_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_g
// Compute S and L from SLIV from higher layers // Compute S and L from SLIV from higher layers
ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L); ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L);
grant->k2 = hl_ra_cfg->k; grant->k = hl_ra_cfg->k;
grant->mapping = hl_ra_cfg->mapping_type; grant->mapping = hl_ra_cfg->mapping_type;
} }
@ -177,7 +177,7 @@ int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
ERROR("Invalid numerology"); ERROR("Invalid numerology");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
grant->k2 += delta[cfg->scs_cfg]; grant->k += delta[cfg->scs_cfg];
} }
// Validate S and L parameters // Validate S and L parameters

@ -70,7 +70,6 @@ int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q,
const srslte_sch_tb_t* tb, const srslte_sch_tb_t* tb,
srslte_sch_nr_common_cfg_t* cfg) srslte_sch_nr_common_cfg_t* cfg)
{ {
if (!sch_cfg || !tb || !cfg) { if (!sch_cfg || !tb || !cfg) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
@ -383,7 +382,7 @@ static inline int sch_nr_encode(srslte_sch_nr_t* q,
// Check encoder // Check encoder
if (cfg.encoder == NULL) { if (cfg.encoder == NULL) {
ERROR("Error: encoder for lifting size Z=%d not found\n", cfg.Z); ERROR("Error: encoder for lifting size Z=%d not found (tbs=%d)\n", cfg.Z, tb->tbs);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

@ -39,7 +39,7 @@ static srslte_channel_awgn_t awgn = {};
static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_common_cfg_t* cfg, cf_t* slot_symbols) static int test_pucch_format0(srslte_pucch_nr_t* pucch, const srslte_pucch_nr_common_cfg_t* cfg, cf_t* slot_symbols)
{ {
srslte_dl_slot_cfg_t slot = {}; srslte_slot_cfg_t slot = {};
srslte_pucch_nr_resource_t resource = {}; srslte_pucch_nr_resource_t resource = {};
resource.format = SRSLTE_PUCCH_NR_FORMAT_0; resource.format = SRSLTE_PUCCH_NR_FORMAT_0;
@ -88,7 +88,7 @@ static int test_pucch_format1(srslte_pucch_nr_t* pucch,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols) cf_t* slot_symbols)
{ {
srslte_dl_slot_cfg_t slot = {}; srslte_slot_cfg_t slot = {};
srslte_pucch_nr_resource_t resource = {}; srslte_pucch_nr_resource_t resource = {};
resource.format = SRSLTE_PUCCH_NR_FORMAT_1; resource.format = SRSLTE_PUCCH_NR_FORMAT_1;
@ -161,21 +161,18 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch,
srslte_chest_ul_res_t* chest_res, srslte_chest_ul_res_t* chest_res,
cf_t* slot_symbols) cf_t* slot_symbols)
{ {
srslte_dl_slot_cfg_t slot = {}; srslte_slot_cfg_t slot = {};
srslte_pucch_nr_resource_t resource = {}; srslte_pucch_nr_resource_t resource = {};
resource.format = SRSLTE_PUCCH_NR_FORMAT_2; resource.format = SRSLTE_PUCCH_NR_FORMAT_2;
for (slot.idx = 0; slot.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot.idx++) { for (slot.idx = 0; slot.idx < SRSLTE_NSLOTS_PER_FRAME_NR(carrier.numerology); slot.idx++) {
for (resource.nof_symbols = SRSLTE_PUCCH_NR_FORMAT2_MIN_NSYMB; for (resource.nof_symbols = SRSLTE_PUCCH_NR_FORMAT2_MIN_NSYMB;
resource.nof_symbols <= SRSLTE_PUCCH_NR_FORMAT2_MAX_NSYMB; resource.nof_symbols <= SRSLTE_PUCCH_NR_FORMAT2_MAX_NSYMB;
resource.nof_symbols++) { resource.nof_symbols++) {
for (resource.start_symbol_idx = 0; for (resource.start_symbol_idx = 0;
resource.start_symbol_idx <= resource.start_symbol_idx <=
SRSLTE_MIN(SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB, SRSLTE_NSYMB_PER_SLOT_NR - resource.nof_symbols); SRSLTE_MIN(SRSLTE_PUCCH_NR_FORMAT2_MAX_STARTSYMB, SRSLTE_NSYMB_PER_SLOT_NR - resource.nof_symbols);
resource.start_symbol_idx += starting_symbol_stride) { resource.start_symbol_idx += starting_symbol_stride) {
srslte_uci_cfg_nr_t uci_cfg = {}; srslte_uci_cfg_nr_t uci_cfg = {};
for (uci_cfg.o_ack = SRSLTE_PUCCH_NR_FORMAT2_MIN_NOF_BITS; uci_cfg.o_ack <= SRSLTE_UCI_NR_MAX_ACK_BITS; for (uci_cfg.o_ack = SRSLTE_PUCCH_NR_FORMAT2_MIN_NOF_BITS; uci_cfg.o_ack <= SRSLTE_UCI_NR_MAX_ACK_BITS;
@ -189,7 +186,6 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch,
} }
for (resource.max_code_rate = 0; resource.max_code_rate < max_code_rate_end; resource.max_code_rate++) { for (resource.max_code_rate = 0; resource.max_code_rate < max_code_rate_end; resource.max_code_rate++) {
// Skip case if not enough PRB are used // Skip case if not enough PRB are used
int min_nof_prb = srslte_ra_ul_nr_pucch_format_2_3_min_prb(&resource, &uci_cfg); int min_nof_prb = srslte_ra_ul_nr_pucch_format_2_3_min_prb(&resource, &uci_cfg);
TESTASSERT(min_nof_prb > SRSLTE_SUCCESS); TESTASSERT(min_nof_prb > SRSLTE_SUCCESS);
@ -197,10 +193,8 @@ static int test_pucch_format2(srslte_pucch_nr_t* pucch,
for (resource.nof_prb = min_nof_prb; for (resource.nof_prb = min_nof_prb;
resource.nof_prb < SRSLTE_MIN(carrier.nof_prb, SRSLTE_PUCCH_NR_FORMAT2_MAX_NPRB); resource.nof_prb < SRSLTE_MIN(carrier.nof_prb, SRSLTE_PUCCH_NR_FORMAT2_MAX_NPRB);
resource.nof_prb++) { resource.nof_prb++) {
for (resource.starting_prb = 0; resource.starting_prb < (carrier.nof_prb - resource.nof_prb); for (resource.starting_prb = 0; resource.starting_prb < (carrier.nof_prb - resource.nof_prb);
resource.starting_prb += starting_prb_stride) { resource.starting_prb += starting_prb_stride) {
// Generate ACKs // Generate ACKs
for (uint32_t i = 0; i < uci_cfg.o_ack; i++) { for (uint32_t i = 0; i < uci_cfg.o_ack; i++) {
uci_value.ack[i] = (uint8_t)srslte_random_uniform_int_dist(random_gen, 0, 1); uci_value.ack[i] = (uint8_t)srslte_random_uniform_int_dist(random_gen, 0, 1);

@ -97,12 +97,12 @@ int main(int argc, char** argv)
pusch_args.sch.disable_simd = false; pusch_args.sch.disable_simd = false;
pusch_args.measure_evm = true; pusch_args.measure_evm = true;
if (srslte_pusch_nr_init_enb(&pusch_tx, &pusch_args) < SRSLTE_SUCCESS) { if (srslte_pusch_nr_init_ue(&pusch_tx, &pusch_args) < SRSLTE_SUCCESS) {
ERROR("Error initiating PUSCH for Tx\n"); ERROR("Error initiating PUSCH for Tx\n");
goto clean_exit; goto clean_exit;
} }
if (srslte_pusch_nr_init_ue(&pusch_rx, &pusch_args) < SRSLTE_SUCCESS) { if (srslte_pusch_nr_init_gnb(&pusch_rx, &pusch_args) < SRSLTE_SUCCESS) {
ERROR("Error initiating SCH NR for Rx\n"); ERROR("Error initiating SCH NR for Rx\n");
goto clean_exit; goto clean_exit;
} }

@ -165,7 +165,7 @@ 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_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_cfg_t* cfg) int srslte_ue_dl_nr_set_pdcch_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_pdcch_cfg_t* cfg)
{ {
if (q == NULL || cfg == NULL) { if (q == NULL || cfg == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
@ -186,7 +186,7 @@ int srslte_ue_dl_nr_set_config(srslte_ue_dl_nr_t* q, const srslte_ue_dl_nr_cfg_t
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_dl_slot_cfg_t* slot_cfg) void srslte_ue_dl_nr_estimate_fft(srslte_ue_dl_nr_t* q, const srslte_slot_cfg_t* slot_cfg)
{ {
if (q == NULL || slot_cfg == NULL) { if (q == NULL || slot_cfg == NULL) {
return; return;
@ -272,16 +272,32 @@ static int ue_dl_nr_find_dci_ncce(srslte_ue_dl_nr_t* q,
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
static bool find_dci_msg(srslte_dci_msg_nr_t* dci_msg, uint32_t nof_dci_msg, srslte_dci_msg_nr_t* match)
{
bool found = false;
uint32_t nof_bits = match->nof_bits;
for (int k = 0; k < nof_dci_msg && !found; k++) {
if (dci_msg[k].nof_bits == nof_bits) {
if (memcmp(dci_msg[k].payload, match->payload, nof_bits) == 0) {
found = true;
}
}
}
return found;
}
static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q, static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_slot_cfg_t* slot_cfg,
const srslte_search_space_t* search_space, const srslte_search_space_t* search_space,
uint16_t rnti, uint16_t rnti,
srslte_rnti_type_t rnti_type, srslte_rnti_type_t rnti_type,
srslte_dci_dl_nr_t* dci_dl_list, srslte_dci_msg_nr_t* dci_msg_list,
uint32_t nof_dci_msg) uint32_t nof_dci_msg)
{ {
// Check inputs // Check inputs
if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) { if (q == NULL || slot_cfg == NULL || dci_msg_list == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
@ -323,6 +339,7 @@ static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q,
// Iterate over the candidates // Iterate over the candidates
for (int ncce_idx = 0; ncce_idx < nof_candidates && count < nof_dci_msg; ncce_idx++) { for (int ncce_idx = 0; ncce_idx < nof_candidates && count < nof_dci_msg; ncce_idx++) {
// Set DCI context
srslte_dci_msg_nr_t dci_msg = {}; srslte_dci_msg_nr_t dci_msg = {};
dci_msg.location.L = L; dci_msg.location.L = L;
dci_msg.location.ncce = candidates[ncce_idx]; dci_msg.location.ncce = candidates[ncce_idx];
@ -333,74 +350,143 @@ static int ue_dl_nr_find_dl_dci_ss(srslte_ue_dl_nr_t* q,
dci_msg.format = dci_format; dci_msg.format = dci_format;
dci_msg.nof_bits = (uint32_t)dci_nof_bits; dci_msg.nof_bits = (uint32_t)dci_nof_bits;
// Find and decode PDCCH transmission in the given ncce
srslte_pdcch_nr_res_t res = {}; srslte_pdcch_nr_res_t res = {};
if (ue_dl_nr_find_dci_ncce(q, &dci_msg, &res, coreset_id) < 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 the CRC was not match, move to next candidate
if (srslte_dci_nr_format_1_0_unpack(&q->carrier, coreset, &dci_msg, &dci_dl_list[count]) < SRSLTE_SUCCESS) { if (!res.crc) {
ERROR("Error unpacking DCI\n"); continue;
return SRSLTE_ERROR; }
// Detect if the DCI was a format 0_0
if (!srslte_dci_nr_format_1_0_valid(&dci_msg)) {
// Change grant format to 0_0
dci_msg.format = srslte_dci_format_nr_0_0;
// If the pending UL grant list is full or has the dci message, keep moving
if (q->pending_ul_dci_count >= SRSLTE_MAX_DCI_MSG_NR ||
find_dci_msg(q->pending_ul_dci_msg, q->pending_ul_dci_count, &dci_msg)) {
continue;
} }
INFO("Found DCI in L=%d,ncce=%d\n", dci_msg.location.L, dci_msg.location.ncce); // Save the grant in the pending UL grant list
count++; q->pending_ul_dci_msg[q->pending_ul_dci_count] = dci_msg;
q->pending_ul_dci_count++;
// Move to next candidate
continue;
}
// Check if the grant exists already in the message list
if (find_dci_msg(dci_msg_list, count, &dci_msg)) {
// The same DCI is in the list, keep moving
continue;
} }
INFO("Found DCI in L=%d,ncce=%d\n", dci_msg.location.L, dci_msg.location.ncce);
// Append DCI message into the list
dci_msg_list[count] = dci_msg;
count++;
} }
} }
return (int)count; return (int)count;
} }
int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot_cfg, const srslte_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)
{ {
int count = 0; int count = 0;
srslte_dci_msg_nr_t dci_msg_list[SRSLTE_MAX_DCI_MSG_NR] = {};
// Check inputs // Check inputs
if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) { if (q == NULL || slot_cfg == NULL || dci_dl_list == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
// Limit maximum number of DCI messages to find
nof_dci_msg = SRSLTE_MIN(nof_dci_msg, SRSLTE_MAX_DCI_MSG_NR);
// If the UE looks for a RAR and RA search space is provided, search for it // 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) { if (q->cfg.ra_search_space_present && rnti == q->cfg.ra_rnti) {
// Find DCIs in the RA search space // Find DCIs in the RA search space
return ue_dl_nr_find_dl_dci_ss(
q, slot_cfg, &q->cfg.ra_search_space, 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( int ret = ue_dl_nr_find_dl_dci_ss(
q, slot_cfg, &q->cfg.search_space[i], rnti, srslte_rnti_type_c, &dci_dl_list[count], nof_dci_msg - count); q, slot_cfg, &q->cfg.ra_search_space, rnti, srslte_rnti_type_ra, &dci_msg_list[count], nof_dci_msg - count);
if (ret < SRSLTE_SUCCESS) { if (ret < SRSLTE_SUCCESS) {
ERROR("Error searching DCI"); ERROR("Error searching RAR DCI");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} else {
// 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, &q->cfg.search_space[i], rnti, srslte_rnti_type_c, &dci_msg_list[count], nof_dci_msg - count);
if (ret < SRSLTE_SUCCESS) {
ERROR("Error searching DCI");
return SRSLTE_ERROR;
}
// Count the found DCIs // Count the found DCIs
count += ret; count += ret;
}
}
// Convert found DCI messages into DL grants
for (uint32_t i = 0; i < count; i++) {
const srslte_coreset_t* coreset = &q->cfg.coreset[dci_msg_list[i].coreset_id];
srslte_dci_nr_format_1_0_unpack(&q->carrier, coreset, &dci_msg_list[i], &dci_dl_list[i]);
} }
return count; return count;
} }
int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q, int srslte_ue_dl_nr_find_ul_dci(srslte_ue_dl_nr_t* q,
const srslte_dl_slot_cfg_t* slot, const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* cfg, uint16_t rnti,
srslte_pdsch_res_nr_t* res) srslte_dci_ul_nr_t* dci_ul_list,
uint32_t nof_dci_msg)
{ {
int count = 0;
// Check inputs
if (q == NULL || slot_cfg == NULL || dci_ul_list == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Get DCI messages from the pending list
for (uint32_t i = 0; i < q->pending_ul_dci_count && count < nof_dci_msg; i++) {
srslte_dci_msg_nr_t* dci_msg = &q->pending_ul_dci_msg[i];
const srslte_coreset_t* coreset = &q->cfg.coreset[dci_msg->coreset_id];
if (srslte_dci_nr_format_0_0_unpack(&q->carrier, coreset, dci_msg, &dci_ul_list[count]) < SRSLTE_SUCCESS) {
ERROR("Unpacking DCI 0_0");
continue;
}
count++;
}
// Reset pending UL grant list
q->pending_ul_dci_count = 0;
return count;
}
int srslte_ue_dl_nr_decode_pdsch(srslte_ue_dl_nr_t* q,
const srslte_slot_cfg_t* slot,
const srslte_sch_cfg_nr_t* cfg,
srslte_pdsch_res_nr_t* res)
{
if (srslte_dmrs_sch_estimate(&q->dmrs_pdsch, slot, cfg, &cfg->grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) { if (srslte_dmrs_sch_estimate(&q->dmrs_pdsch, slot, cfg, &cfg->grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

@ -11,3 +11,128 @@
*/ */
#include "srslte/phy/ue/ue_ul_nr.h" #include "srslte/phy/ue/ue_ul_nr.h"
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
int srslte_ue_ul_nr_init(srslte_ue_ul_nr_t* q, cf_t* output, const srslte_ue_ul_nr_args_t* args)
{
if (q == NULL || output == NULL || args == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Initialise memory
SRSLTE_MEM_ZERO(q, srslte_ue_ul_nr_t, 1);
q->max_prb = args->nof_max_prb;
q->sf_symbols[0] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(q->max_prb));
if (q->sf_symbols[0] == NULL) {
ERROR("Malloc");
return SRSLTE_ERROR;
}
if (srslte_pusch_nr_init_ue(&q->pusch, &args->pusch) < SRSLTE_SUCCESS) {
ERROR("Initiating PUSCH");
return SRSLTE_ERROR;
}
srslte_ofdm_cfg_t fft_cfg = {};
fft_cfg.nof_prb = args->nof_max_prb;
fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(args->nof_max_prb);
fft_cfg.keep_dc = true;
fft_cfg.in_buffer = q->sf_symbols[0];
fft_cfg.out_buffer = output;
if (srslte_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSLTE_SUCCESS) {
ERROR("Initiating OFDM");
return SRSLTE_ERROR;
}
if (srslte_dmrs_sch_init(&q->dmrs, false) < SRSLTE_SUCCESS) {
ERROR("Error DMRS\n");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int srslte_ue_ul_nr_set_carrier(srslte_ue_ul_nr_t* q, const srslte_carrier_nr_t* carrier)
{
if (q == NULL || carrier == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
q->carrier = *carrier;
srslte_ofdm_cfg_t fft_cfg = {};
fft_cfg.nof_prb = carrier->nof_prb;
fft_cfg.symbol_sz = srslte_min_symbol_sz_rb(carrier->nof_prb);
fft_cfg.keep_dc = true;
if (srslte_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSLTE_SUCCESS) {
ERROR("Initiating OFDM");
return SRSLTE_ERROR;
}
if (srslte_pusch_nr_set_carrier(&q->pusch, carrier) < SRSLTE_SUCCESS) {
ERROR("Setting PUSCH carrier");
return SRSLTE_ERROR;
}
if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier)) {
ERROR("Setting DMRS carrier");
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int srslte_ue_ul_nr_encode_pusch(srslte_ue_ul_nr_t* q,
const srslte_slot_cfg_t* slot_cfg,
const srslte_sch_cfg_nr_t* pusch_cfg,
uint8_t* data_)
{
uint8_t* data[SRSLTE_MAX_TB] = {};
data[0] = data_;
// Check inputs
if (q == NULL || pusch_cfg == NULL || data_ == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Encode PUSCH
if (srslte_pusch_nr_encode(&q->pusch, pusch_cfg, &pusch_cfg->grant, data, q->sf_symbols) < SRSLTE_SUCCESS) {
ERROR("Encoding PUSCH");
return SRSLTE_ERROR;
}
// Put DMRS
if (srslte_dmrs_sch_put_sf(&q->dmrs, slot_cfg, pusch_cfg, &pusch_cfg->grant, q->sf_symbols[0])) {
ERROR("Putting DMRS");
return SRSLTE_ERROR;
}
// Generate signal
srslte_ofdm_tx_sf(&q->ifft);
return SRSLTE_SUCCESS;
}
void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q)
{
if (q == NULL) {
return;
}
srslte_ofdm_tx_free(&q->ifft);
if (q->sf_symbols[0] != NULL) {
free(q->sf_symbols[0]);
}
srslte_pusch_nr_free(&q->pusch);
srslte_dmrs_sch_free(&q->dmrs);
}
int srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len)
{
int len = 0;
// Append PDSCH info
len += srslte_pusch_nr_tx_info(&q->pusch, cfg, &cfg->grant, &str[len], str_len - len);
return len;
}

@ -84,7 +84,7 @@ static int parse_args(int argc, char** argv)
} }
static 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_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,
@ -120,7 +120,7 @@ static int work_gnb_dl(srslte_enb_dl_nr_t* enb_dl,
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
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) static int work_ue_dl(srslte_ue_dl_nr_t* ue_dl, srslte_slot_cfg_t* slot, 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);
@ -152,7 +152,7 @@ int main(int argc, char** argv)
srslte_ue_dl_nr_t ue_dl = {}; srslte_ue_dl_nr_t ue_dl = {};
srslte_pdsch_res_nr_t pdsch_res[SRSLTE_MAX_TB] = {}; srslte_pdsch_res_nr_t pdsch_res[SRSLTE_MAX_TB] = {};
srslte_random_t rand_gen = srslte_random_init(1234); srslte_random_t rand_gen = srslte_random_init(1234);
srslte_dl_slot_cfg_t slot = {}; srslte_slot_cfg_t slot = {};
struct timeval t[3] = {}; struct timeval t[3] = {};
uint64_t pdsch_encode_us = 0; uint64_t pdsch_encode_us = 0;
uint64_t pdsch_decode_us = 0; uint64_t pdsch_decode_us = 0;
@ -189,7 +189,7 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
srslte_ue_dl_nr_cfg_t pdcch_cfg = {}; srslte_ue_dl_nr_pdcch_cfg_t pdcch_cfg = {};
// Configure CORESET // Configure CORESET
srslte_coreset_t* coreset = &pdcch_cfg.coreset[0]; srslte_coreset_t* coreset = &pdcch_cfg.coreset[0];
@ -222,7 +222,7 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
if (srslte_ue_dl_nr_set_config(&ue_dl, &pdcch_cfg)) { if (srslte_ue_dl_nr_set_pdcch_config(&ue_dl, &pdcch_cfg)) {
ERROR("Error setting CORESET\n"); ERROR("Error setting CORESET\n");
goto clean_exit; goto clean_exit;
} }
@ -290,7 +290,6 @@ int main(int argc, char** argv)
for (slot.idx = 0; slot.idx < nof_slots; slot.idx++) { for (slot.idx = 0; slot.idx < nof_slots; slot.idx++) {
for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) {
for (mcs = mcs_start; mcs < mcs_end; mcs++, slot_count++) { for (mcs = mcs_start; mcs < mcs_end; mcs++, slot_count++) {
for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) {
pdsch_grant.prb_idx[n] = (n < n_prb); pdsch_grant.prb_idx[n] = (n < n_prb);
} }

@ -63,13 +63,13 @@ public:
cf_t* get_rx_buffer(uint32_t antenna_idx); cf_t* get_rx_buffer(uint32_t antenna_idx);
uint32_t get_buffer_len(); uint32_t get_buffer_len();
bool work_dl(const srslte_dl_slot_cfg_t& dl_slot_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants); bool work_dl(const srslte_slot_cfg_t& dl_slot_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants);
private: private:
int encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants); int encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants);
int encode_pdcch_dl(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants); int encode_pdcch_dl(stack_interface_phy_nr::dl_sched_grant_t* grants, uint32_t nof_grants);
srslte_dl_slot_cfg_t dl_slot_cfg = {}; srslte_slot_cfg_t dl_slot_cfg = {};
uint32_t cc_idx = 0; uint32_t cc_idx = 0;
std::array<cf_t*, SRSLTE_MAX_PORTS> tx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> tx_buffer = {};
std::array<cf_t*, SRSLTE_MAX_PORTS> rx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> rx_buffer = {};

@ -122,7 +122,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, ui
// Get PHY config for UE // Get PHY config for UE
// ... // ...
srslte_sch_hl_cfg_nr_t pdsch_hl_cfg = {}; srslte_sch_hl_cfg_nr_t pdsch_hl_cfg = {};
srslte_sch_cfg_nr_t pdsch_cfg = {}; srslte_sch_cfg_nr_t pdsch_cfg = {};
// Compute DL grant // Compute DL grant
if (srslte_ra_dl_dci_to_grant_nr(&enb_dl.carrier, &pdsch_hl_cfg, &grants[i].dci, &pdsch_cfg, &pdsch_cfg.grant)) { if (srslte_ra_dl_dci_to_grant_nr(&enb_dl.carrier, &pdsch_hl_cfg, &grants[i].dci, &pdsch_cfg, &pdsch_cfg.grant)) {
@ -150,7 +150,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, ui
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
bool cc_worker::work_dl(const srslte_dl_slot_cfg_t& dl_sf_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants) bool cc_worker::work_dl(const srslte_slot_cfg_t& dl_sf_cfg, stack_interface_phy_nr::dl_sched_t& dl_grants)
{ {
// Reset resource grid // Reset resource grid
if (srslte_enb_dl_nr_base_zero(&enb_dl) < SRSLTE_SUCCESS) { if (srslte_enb_dl_nr_base_zero(&enb_dl) < SRSLTE_SUCCESS) {

@ -92,7 +92,7 @@ void sf_worker::work_imp()
phy_state->cfg.pdsch.rbg_size_cfg_1 = false; phy_state->cfg.pdsch.rbg_size_cfg_1 = false;
// Fill grant (this comes from the scheduler) // Fill grant (this comes from the scheduler)
srslte_dl_slot_cfg_t dl_cfg = {}; srslte_slot_cfg_t dl_cfg = {};
stack_interface_phy_nr::dl_sched_t grants = {}; stack_interface_phy_nr::dl_sched_t grants = {};
grants.nof_grants = 1; grants.nof_grants = 1;

@ -30,24 +30,30 @@ public:
void set_tti(uint32_t tti); void set_tti(uint32_t tti);
cf_t* get_rx_buffer(uint32_t antenna_idx); cf_t* get_rx_buffer(uint32_t antenna_idx);
cf_t* get_tx_buffer(uint32_t antenna_idx);
uint32_t get_buffer_len(); uint32_t get_buffer_len();
bool work_dl(); bool work_dl();
bool work_ul();
int read_pdsch_d(cf_t* pdsch_d); int read_pdsch_d(cf_t* pdsch_d);
private: private:
srslte_dl_slot_cfg_t dl_slot_cfg = {}; srslte_slot_cfg_t dl_slot_cfg = {};
srslte_slot_cfg_t ul_slot_cfg = {};
uint32_t cc_idx = 0; uint32_t cc_idx = 0;
std::array<cf_t*, SRSLTE_MAX_PORTS> rx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> rx_buffer = {};
std::array<cf_t*, SRSLTE_MAX_PORTS> tx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> tx_buffer = {};
uint32_t buffer_sz = 0; uint32_t buffer_sz = 0;
state* phy = nullptr; state* phy = nullptr;
srslte_ue_dl_nr_t ue_dl = {}; srslte_ue_dl_nr_t ue_dl = {};
srslte_ue_ul_nr_t ue_ul = {};
srslog::basic_logger& logger; srslog::basic_logger& logger;
// Temporal attributes // Temporal attributes
srslte_softbuffer_tx_t softbuffer_tx = {};
srslte_softbuffer_rx_t softbuffer_rx = {}; srslte_softbuffer_rx_t softbuffer_rx = {};
std::vector<uint8_t> tx_data;
}; };
} // namespace nr } // namespace nr

@ -27,17 +27,27 @@ namespace nr {
typedef struct { typedef struct {
uint32_t nof_carriers; uint32_t nof_carriers;
srslte_ue_dl_nr_args_t dl; srslte_ue_dl_nr_args_t dl;
srslte_ue_ul_nr_args_t ul;
} phy_nr_args_t; } phy_nr_args_t;
typedef struct { typedef struct {
srslte_sch_hl_cfg_nr_t pdsch; srslte_sch_hl_cfg_nr_t pdsch;
srslte_sch_hl_cfg_nr_t pusch; srslte_sch_hl_cfg_nr_t pusch;
srslte_prach_cfg_t prach; srslte_prach_cfg_t prach;
srslte_ue_dl_nr_cfg_t pdcch; srslte_ue_dl_nr_pdcch_cfg_t pdcch;
} phy_nr_cfg_t; } phy_nr_cfg_t;
class state class state
{ {
private:
struct pending_grant_t {
bool enable;
uint32_t pid;
srslte_sch_cfg_nr_t sch_cfg;
};
srslte::circular_array<pending_grant_t, TTIMOD_SZ> pending_ul_grant = {};
mutable std::mutex pending_ul_grant_mutex;
public: public:
mac_interface_phy_nr* stack = nullptr; mac_interface_phy_nr* stack = nullptr;
srslte_carrier_nr_t carrier = {}; srslte_carrier_nr_t carrier = {};
@ -58,6 +68,9 @@ public:
args.dl.pdsch.measure_evm = true; args.dl.pdsch.measure_evm = true;
args.dl.pdsch.measure_time = true; args.dl.pdsch.measure_time = true;
args.dl.pdsch.sch.disable_simd = false; args.dl.pdsch.sch.disable_simd = false;
args.ul.nof_max_prb = 100;
args.ul.pusch.measure_time = true;
args.ul.pusch.sch.disable_simd = false;
// Default PDSCH configuration // Default PDSCH configuration
cfg.pdsch.sch_cfg.mcs_table = srslte_mcs_table_256qam; cfg.pdsch.sch_cfg.mcs_table = srslte_mcs_table_256qam;
@ -160,6 +173,106 @@ public:
cfg.pusch.common_time_ra[1].sliv = 27; cfg.pusch.common_time_ra[1].sliv = 27;
cfg.pusch.common_time_ra[1].k = 5; cfg.pusch.common_time_ra[1].k = 5;
cfg.pusch.nof_common_time_ra = 2; cfg.pusch.nof_common_time_ra = 2;
// pusch-Config: setup (1)
// setup
// dmrs-UplinkForPUSCH-MappingTypeA: setup (1)
// setup
// dmrs-AdditionalPosition: pos1 (1)
// transformPrecodingDisabled
cfg.pusch.dmrs_typeA.additional_pos = srslte_dmrs_sch_add_pos_1;
cfg.pusch.dmrs_typeA.present = true;
// pusch-PowerControl
// msg3-Alpha: alpha1 (7)
// p0-NominalWithoutGrant: -90dBm
// p0-AlphaSets: 1 item
// Item 0
// P0-PUSCH-AlphaSet
// p0-PUSCH-AlphaSetId: 0
// p0: 0dB
// alpha: alpha1 (7)
// pathlossReferenceRSToAddModList: 1 item
// Item 0
// PUSCH-PathlossReferenceRS
// pusch-PathlossReferenceRS-Id: 0
// referenceSignal: ssb-Index (0)
// ssb-Index: 0
// sri-PUSCH-MappingToAddModList: 1 item
// Item 0
// SRI-PUSCH-PowerControl
// sri-PUSCH-PowerControlId: 0
// sri-PUSCH-PathlossReferenceRS-Id: 0
// sri-P0-PUSCH-AlphaSetId: 0
// sri-PUSCH-ClosedLoopIndex: i0 (0)
// resourceAllocation: resourceAllocationType1 (1)
// uci-OnPUSCH: setup (1)
// setup
// betaOffsets: semiStatic (1)
// semiStatic
// betaOffsetACK-Index1: 9
// betaOffsetACK-Index2: 9
// betaOffsetACK-Index3: 9
// betaOffsetCSI-Part1-Index1: 6
// betaOffsetCSI-Part1-Index2: 6
// betaOffsetCSI-Part2-Index1: 6
// betaOffsetCSI-Part2-Index2: 6
// scaling: f1 (3)
}
/**
* @brief Stores a received UL DCI into the pending UL grant list
* @param tti_rx The TTI in which the grant was received
* @param dci_ul The UL DCI message to store
*/
void set_ul_pending_grant(uint32_t tti_rx, const srslte_dci_ul_nr_t& dci_ul)
{
// Convert UL DCI to grant
srslte_sch_cfg_nr_t pusch_cfg = {};
if (srslte_ra_ul_dci_to_grant_nr(&carrier, &cfg.pusch, &dci_ul, &pusch_cfg, &pusch_cfg.grant)) {
ERROR("Computing UL grant");
return;
}
// Calculate Transmit TTI
uint32_t tti_tx = TTI_ADD(tti_rx, pusch_cfg.grant.k);
// Scope mutex to protect read/write the list
std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
// Save entry
pending_grant_t& pending_grant = pending_ul_grant[tti_tx];
pending_grant.sch_cfg = pusch_cfg;
pending_grant.pid = dci_ul.pid;
pending_grant.enable = true;
}
/**
* @brief Checks the UL pending grant list if there is any grant to transmit for the given transmit TTI
* @param tti_tx Current transmit TTI
* @param sch_cfg Provides the Shared Channel configuration for the PUSCH transmission
* @param pid Provides the HARQ process identifier
* @return true if there is a pending grant for the given TX tti, false otherwise
*/
bool get_ul_pending_grant(uint32_t tti_tx, srslte_sch_cfg_nr_t& pusch_cfg, uint32_t& pid)
{
// Scope mutex to protect read/write the list
std::lock_guard<std::mutex> lock(pending_ul_grant_mutex);
// Select entry
pending_grant_t& pending_grant = pending_ul_grant[tti_tx];
// If the entry is not active, just return
if (!pending_grant.enable) {
return false;
}
// Load shared channel configuration
pusch_cfg = pending_grant.sch_cfg;
// Reset entry
pending_grant.enable = false;
return true;
} }
}; };
} // namespace nr } // namespace nr

@ -18,31 +18,49 @@ namespace nr {
cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state* phy_state_) : cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state* phy_state_) :
cc_idx(cc_idx_), phy(phy_state_), logger(log) cc_idx(cc_idx_), phy(phy_state_), logger(log)
{ {
cf_t* buffer_c[SRSLTE_MAX_PORTS] = {}; cf_t* rx_buffer_c[SRSLTE_MAX_PORTS] = {};
// Allocate buffers // Allocate buffers
buffer_sz = SRSLTE_SF_LEN_PRB(phy->args.dl.nof_max_prb) * 5; buffer_sz = SRSLTE_SF_LEN_PRB(phy->args.dl.nof_max_prb) * 5;
for (uint32_t i = 0; i < phy_state_->args.dl.nof_rx_antennas; i++) { for (uint32_t i = 0; i < phy_state_->args.dl.nof_rx_antennas; i++) {
rx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); rx_buffer[i] = srslte_vec_cf_malloc(buffer_sz);
tx_buffer[i] = srslte_vec_cf_malloc(buffer_sz); rx_buffer_c[i] = rx_buffer[i];
buffer_c[i] = rx_buffer[i]; tx_buffer[i] = srslte_vec_cf_malloc(buffer_sz);
} }
if (srslte_ue_dl_nr_init(&ue_dl, buffer_c, &phy_state_->args.dl) < SRSLTE_SUCCESS) { if (srslte_ue_dl_nr_init(&ue_dl, rx_buffer.data(), &phy_state_->args.dl) < SRSLTE_SUCCESS) {
ERROR("Error initiating UE DL NR"); ERROR("Error initiating UE DL NR");
return; return;
} }
if (srslte_ue_ul_nr_init(&ue_ul, tx_buffer[0], &phy_state_->args.ul) < SRSLTE_SUCCESS) {
ERROR("Error initiating UE DL NR");
return;
}
if (srslte_softbuffer_tx_init_guru(&softbuffer_tx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) <
SRSLTE_SUCCESS) {
ERROR("Error init soft-buffer");
return;
}
if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) <
SRSLTE_SUCCESS) { SRSLTE_SUCCESS) {
ERROR("Error init soft-buffer"); ERROR("Error init soft-buffer");
return; return;
} }
// Initialise data with numbers
tx_data.resize(SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8);
for (uint32_t i = 0; i < SRSLTE_SCH_NR_MAX_NOF_CB_LDPC * SRSLTE_LDPC_MAX_LEN_ENCODED_CB / 8; i++) {
tx_data[i] = i % 8;
}
} }
cc_worker::~cc_worker() cc_worker::~cc_worker()
{ {
srslte_ue_dl_nr_free(&ue_dl); srslte_ue_dl_nr_free(&ue_dl);
srslte_ue_ul_nr_free(&ue_ul);
srslte_softbuffer_rx_free(&softbuffer_rx); srslte_softbuffer_rx_free(&softbuffer_rx);
for (cf_t* p : rx_buffer) { for (cf_t* p : rx_buffer) {
if (p != nullptr) { if (p != nullptr) {
@ -63,7 +81,12 @@ bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier)
return false; return false;
} }
if (srslte_ue_dl_nr_set_config(&ue_dl, &phy->cfg.pdcch) < SRSLTE_SUCCESS) { if (srslte_ue_dl_nr_set_pdcch_config(&ue_dl, &phy->cfg.pdcch) < SRSLTE_SUCCESS) {
ERROR("Error setting carrier");
return false;
}
if (srslte_ue_ul_nr_set_carrier(&ue_ul, carrier) < SRSLTE_SUCCESS) {
ERROR("Error setting carrier"); ERROR("Error setting carrier");
return false; return false;
} }
@ -77,6 +100,7 @@ bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier)
void cc_worker::set_tti(uint32_t tti) void cc_worker::set_tti(uint32_t tti)
{ {
dl_slot_cfg.idx = tti; dl_slot_cfg.idx = tti;
ul_slot_cfg.idx = TTI_TX(tti);
} }
cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
@ -88,6 +112,15 @@ cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
return rx_buffer.at(antenna_idx); return rx_buffer.at(antenna_idx);
} }
cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx)
{
if (antenna_idx >= phy->args.dl.nof_rx_antennas) {
return nullptr;
}
return tx_buffer.at(antenna_idx);
}
uint32_t cc_worker::get_buffer_len() uint32_t cc_worker::get_buffer_len()
{ {
return buffer_sz; return buffer_sz;
@ -99,42 +132,67 @@ 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);
// Initialise grants // Initialise grants
std::array<srslte_dci_dl_nr_t, 5> dci_dl_rx = {}; std::array<srslte_dci_dl_nr_t, 5> dci_dl_rx = {};
uint32_t nof_found_dci = 0; std::array<srslte_dci_ul_nr_t, 5> dci_ul_rx = {};
uint32_t nof_found_dci_dl = 0;
uint32_t nof_found_dci_ul = 0;
// Search for RA DCI // Search for RA DCI
if (phy->cfg.pdcch.ra_search_space_present) { if (phy->cfg.pdcch.ra_search_space_present) {
int n_ra = srslte_ue_dl_nr_find_dl_dci(&ue_dl, int n_ra = srslte_ue_dl_nr_find_dl_dci(&ue_dl,
&dl_slot_cfg, &dl_slot_cfg,
phy->cfg.pdcch.ra_rnti, phy->cfg.pdcch.ra_rnti,
&dci_dl_rx[nof_found_dci], &dci_dl_rx[nof_found_dci_dl],
(uint32_t)dci_dl_rx.size() - nof_found_dci); (uint32_t)dci_dl_rx.size() - nof_found_dci_dl);
if (n_ra < SRSLTE_SUCCESS) { if (n_ra < SRSLTE_SUCCESS) {
ERROR("Error decoding"); ERROR("Error decoding");
return false; return false;
} }
nof_found_dci += n_ra; nof_found_dci_dl += n_ra;
} }
// Search for test RNTI // Search for test RNTI
if (phy->test_rnti > 0) { if (phy->test_rnti > 0) {
int n_test = srslte_ue_dl_nr_find_dl_dci(&ue_dl, // Search for test DL grants
&dl_slot_cfg, int n_dl = srslte_ue_dl_nr_find_dl_dci(&ue_dl,
(uint16_t)phy->test_rnti, &dl_slot_cfg,
&dci_dl_rx[nof_found_dci], (uint16_t)phy->test_rnti,
(uint32_t)dci_dl_rx.size() - nof_found_dci); &dci_dl_rx[nof_found_dci_dl],
if (n_test < SRSLTE_SUCCESS) { (uint32_t)dci_dl_rx.size() - nof_found_dci_dl);
if (n_dl < SRSLTE_SUCCESS) {
ERROR("Error decoding");
return false;
}
nof_found_dci_dl += n_dl;
// Search for test UL grants
int n_ul = srslte_ue_dl_nr_find_ul_dci(&ue_dl,
&dl_slot_cfg,
(uint16_t)phy->test_rnti,
&dci_ul_rx[nof_found_dci_ul],
(uint32_t)dci_ul_rx.size() - nof_found_dci_ul);
if (n_ul < SRSLTE_SUCCESS) {
ERROR("Error decoding"); ERROR("Error decoding");
return false; return false;
} }
nof_found_dci += n_test; nof_found_dci_ul += n_ul;
} }
// Iterate over all received grants // Iterate over all UL received grants
for (uint32_t i = 0; i < nof_found_dci; i++) { for (uint32_t i = 0; i < nof_found_dci_ul; i++) {
// Select Received DCI // Log found DCI
const srslte_dci_dl_nr_t* dci_dl = &dci_dl_rx[i]; if (logger.info.enabled()) {
std::array<char, 512> str;
srslte_dci_ul_nr_to_str(&dci_ul_rx[i], str.data(), str.size());
logger.info("PDCCH: cc=%d, %s", cc_idx, str.data());
}
// Enqueue UL grants
phy->set_ul_pending_grant(dl_slot_cfg.idx, dci_ul_rx[i]);
}
// Iterate over all DL received grants
for (uint32_t i = 0; i < nof_found_dci_dl; i++) {
// Notify MAC about PDCCH found grant // Notify MAC about PDCCH found grant
// ... At the moment reset softbuffer locally // ... At the moment reset softbuffer locally
srslte_softbuffer_rx_reset(&softbuffer_rx); srslte_softbuffer_rx_reset(&softbuffer_rx);
@ -142,13 +200,13 @@ bool cc_worker::work_dl()
// Log found DCI // Log found DCI
if (logger.info.enabled()) { if (logger.info.enabled()) {
std::array<char, 512> str; std::array<char, 512> str;
srslte_dci_dl_nr_to_str(dci_dl, str.data(), str.size()); srslte_dci_dl_nr_to_str(&dci_dl_rx[i], str.data(), str.size());
logger.info("PDCCH: cc=%d, %s", cc_idx, str.data()); logger.info("PDCCH: cc=%d, %s", cc_idx, str.data());
} }
// Compute DL grant // Compute DL grant
srslte_sch_cfg_nr_t pdsch_cfg = {}; srslte_sch_cfg_nr_t pdsch_cfg = {};
if (srslte_ra_dl_dci_to_grant_nr(&ue_dl.carrier, &phy->cfg.pdsch, dci_dl, &pdsch_cfg, &pdsch_cfg.grant)) { if (srslte_ra_dl_dci_to_grant_nr(&ue_dl.carrier, &phy->cfg.pdsch, &dci_dl_rx[i], &pdsch_cfg, &pdsch_cfg.grant)) {
ERROR("Computing DL grant"); ERROR("Computing DL grant");
return false; return false;
} }
@ -180,8 +238,8 @@ bool cc_worker::work_dl()
// Prepare grant // Prepare grant
mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {}; mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {};
mac_nr_grant.tb[0] = std::move(data); mac_nr_grant.tb[0] = std::move(data);
mac_nr_grant.pid = dci_dl->pid; mac_nr_grant.pid = dci_dl_rx[i].pid;
mac_nr_grant.rnti = dci_dl->rnti; mac_nr_grant.rnti = dci_dl_rx[i].rnti;
mac_nr_grant.tti = dl_slot_cfg.idx; mac_nr_grant.tti = dl_slot_cfg.idx;
// Send data to MAC // Send data to MAC
@ -192,6 +250,42 @@ bool cc_worker::work_dl()
return true; return true;
} }
bool cc_worker::work_ul()
{
srslte_sch_cfg_nr_t pusch_cfg = {};
uint32_t pid = 0;
// Request grant to PHY state for this transmit TTI
if (not phy->get_ul_pending_grant(ul_slot_cfg.idx, pusch_cfg, pid)) {
// If no grant, return earlier
return true;
}
// Notify MAC about PUSCH found grant
// ...
pusch_cfg.grant.tb[0].softbuffer.tx = &softbuffer_tx;
// Encode PUSCH transmission
if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, tx_data.data()) < SRSLTE_SUCCESS) {
ERROR("Encoding PUSCH");
return false;
}
// Logging
if (logger.info.enabled()) {
std::array<char, 512> str;
srslte_ue_ul_nr_pusch_info(&ue_ul, &pusch_cfg, str.data(), str.size());
logger.info(tx_data.data(),
pusch_cfg.grant.tb[0].tbs / 8,
"PUSCH: cc=%d, %s, tti_tx=%d",
cc_idx,
str.data(),
ul_slot_cfg.idx);
}
return true;
}
int cc_worker::read_pdsch_d(cf_t* pdsch_d) int cc_worker::read_pdsch_d(cf_t* pdsch_d)
{ {
uint32_t nof_re = ue_dl.carrier.nof_prb * SRSLTE_NRE * 12; uint32_t nof_re = ue_dl.carrier.nof_prb * SRSLTE_NRE * 12;

@ -91,7 +91,14 @@ void sf_worker::work_imp()
} }
// Perform UL processing // Perform UL processing
// ... for (auto& w : cc_workers) {
w->work_ul();
}
// Set Tx buffers
for (uint32_t i = 0; i < (uint32_t)cc_workers.size(); i++) {
tx_buffer.set(i, cc_workers[i]->get_tx_buffer(0));
}
// Always call worker_end before returning // Always call worker_end before returning
phy->worker_end(this, false, tx_buffer, dummy_ts, true); phy->worker_end(this, false, tx_buffer, dummy_ts, true);

Loading…
Cancel
Save