diff --git a/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h similarity index 66% rename from lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h rename to lib/include/srslte/phy/ch_estimation/dmrs_sch.h index 04221dfa9..56abf30a1 100644 --- a/lib/include/srslte/phy/ch_estimation/dmrs_pdsch.h +++ b/lib/include/srslte/phy/ch_estimation/dmrs_sch.h @@ -10,11 +10,11 @@ * */ -#ifndef SRSLTE_DMRS_PDSCH_H -#define SRSLTE_DMRS_PDSCH_H +#ifndef SRSLTE_DMRS_SCH_H +#define SRSLTE_DMRS_SCH_H #include "srslte/phy/common/phy_common_nr.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #include "srslte/srslte.h" #include @@ -22,18 +22,18 @@ extern "C" { #endif -#define SRSLTE_DMRS_PDSCH_MAX_SYMBOLS 4 +#define SRSLTE_DMRS_SCH_MAX_SYMBOLS 4 /** * @brief PDSCH DMRS estimator object * * @note The DMRS PDSCH object has to be initialised and the carrier parameters needs to be set. * - * @see srslte_dmrs_pdsch_init - * @see srslte_dmrs_pdsch_set_carrier - * @see srslte_dmrs_pdsch_free - * @see srslte_dmrs_pdsch_put_sf - * @see srslte_dmrs_pdsch_estimate + * @see srslte_dmrs_sch_init + * @see srslte_dmrs_sch_set_carrier + * @see srslte_dmrs_sch_free + * @see srslte_dmrs_sch_put_sf + * @see srslte_dmrs_sch_estimate */ typedef struct { bool is_ue; @@ -47,7 +47,7 @@ typedef struct { cf_t* pilot_estimates; /// Pilots least squares estimates cf_t* temp; /// Temporal data vector of size SRSLTE_NRE * carrier.nof_prb -} srslte_dmrs_pdsch_t; +} srslte_dmrs_sch_t; /** * @brief Computes the symbol indexes carrying DMRS and stores them in symbols_idx @@ -56,9 +56,9 @@ typedef struct { * @param symbols_idx is the destination pointer where the symbols indexes are stored * @return It returns the number of symbols if inputs are valid, otherwise, it returns SRSLTE_ERROR code. */ -SRSLTE_API int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t symbols_idx[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS]); +SRSLTE_API int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t symbols_idx[SRSLTE_DMRS_SCH_MAX_SYMBOLS]); /** * @brief Computes the sub-carrier indexes carrying DMRS @@ -69,7 +69,7 @@ SRSLTE_API int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* * * @return It returns the number of sub-carriers if inputs are valid, otherwise, it returns SRSLTE_ERROR code. */ -SRSLTE_API int srslte_dmrs_pdsch_get_sc_idx(const srslte_pdsch_dmrs_cfg_t* cfg, uint32_t max_count, uint32_t* sc_idx); +SRSLTE_API int srslte_dmrs_sch_get_sc_idx(const srslte_dmrs_sch_cfg_t* cfg, uint32_t max_count, uint32_t* sc_idx); /** * @brief Calculates the number of resource elements taken by a PDSCH-DMRS for a given PDSCH transmission @@ -77,7 +77,7 @@ SRSLTE_API int srslte_dmrs_pdsch_get_sc_idx(const srslte_pdsch_dmrs_cfg_t* cfg, * @param grant PDSCH information provided by a DCI * @return it returns the number of resource elements if the configuration is valid, otherwise it returns SRSLTE_ERROR */ -SRSLTE_API int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_pdsch_grant_nr_t* grant); +SRSLTE_API int srslte_dmrs_sch_get_N_prb(const srslte_sch_cfg_nr_t* cfg, const srslte_sch_grant_nr_t* grant); /** * @brief Stringifies the PDSCH DMRS configuration @@ -89,7 +89,7 @@ SRSLTE_API int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, con * @return It returns the number of characters written in the vector if no error occurs, otherwise it returns * SRSLTE_ERROR code */ -SRSLTE_API int srslte_dmrs_pdsch_cfg_to_str(const srslte_pdsch_dmrs_cfg_t* cfg, char* msg, uint32_t max_len); +SRSLTE_API int srslte_dmrs_sch_cfg_to_str(const srslte_dmrs_sch_cfg_t* cfg, char* msg, uint32_t max_len); /** * @brief Initialises DMRS PDSCH object @@ -98,14 +98,14 @@ SRSLTE_API int srslte_dmrs_pdsch_cfg_to_str(const srslte_pdsch_dmrs_cfg_t* cfg, * @param is_ue indicates whethe the object is for a UE (in this case, it shall initialise as an estimator) * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ -SRSLTE_API int srslte_dmrs_pdsch_init(srslte_dmrs_pdsch_t* q, bool is_ue); +SRSLTE_API int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue); /** * @brief Frees DMRS PDSCH object * * @param q DMRS PDSCH object */ -SRSLTE_API void srslte_dmrs_pdsch_free(srslte_dmrs_pdsch_t* q); +SRSLTE_API void srslte_dmrs_sch_free(srslte_dmrs_sch_t* q); /** * @brief Sets the carrier configuration. if the PDSCH DMRS object is configured as UE, it will resize internal buffers @@ -116,7 +116,7 @@ SRSLTE_API void srslte_dmrs_pdsch_free(srslte_dmrs_pdsch_t* q); * * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ -SRSLTE_API int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_nr_t* carrier); +SRSLTE_API int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t* carrier); /** * @brief Puts PDSCH DMRS into a given resource grid @@ -129,11 +129,11 @@ SRSLTE_API int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslt * * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ -SRSLTE_API int srslte_dmrs_pdsch_put_sf(srslte_dmrs_pdsch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* sf_symbols); +SRSLTE_API int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, + const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* sf_symbols); /** * @brief Estimates the channel for PDSCH from the DMRS @@ -149,15 +149,15 @@ SRSLTE_API int srslte_dmrs_pdsch_put_sf(srslte_dmrs_pdsch_t* q, * * @return it returns SRSLTE_ERROR code if an error occurs, otherwise it returns SRSLTE_SUCCESS */ -SRSLTE_API int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - const cf_t* sf_symbols, - srslte_chest_dl_res_t* chest_res); +SRSLTE_API int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, + const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + const cf_t* sf_symbols, + srslte_chest_dl_res_t* chest_res); #ifdef __cplusplus } #endif -#endif // SRSLTE_DMRS_PDSCH_H +#endif // SRSLTE_DMRS_SCH_H diff --git a/lib/include/srslte/phy/common/phy_common_nr.h b/lib/include/srslte/phy/common/phy_common_nr.h index 4fc47f6e6..3449f21f2 100644 --- a/lib/include/srslte/phy/common/phy_common_nr.h +++ b/lib/include/srslte/phy/common/phy_common_nr.h @@ -128,7 +128,7 @@ typedef enum SRSLTE_API { * @brief PDSCH mapping type * @remark Described in TS 38.331 V15.10.0 Section PDSCH-TimeDomainResourceAllocationList */ -typedef enum SRSLTE_API { srslte_pdsch_mapping_type_A = 0, srslte_pdsch_mapping_type_B } srslte_pdsch_mapping_type_t; +typedef enum SRSLTE_API { srslte_sch_mapping_type_A = 0, srslte_sch_mapping_type_B } srslte_sch_mapping_type_t; typedef enum SRSLTE_API { srslte_search_space_type_common = 0, @@ -155,6 +155,8 @@ typedef enum SRSLTE_API { srslte_rnti_type_ra, srslte_rnti_type_tc, srslte_rnti_type_cs, + srslte_rnti_type_sp_csi, + srslte_rnti_type_mcs_crnti, } srslte_rnti_type_t; /** @@ -170,7 +172,9 @@ typedef enum SRSLTE_API { srslte_dci_format_nr_2_1, ///< @brief Notifying a group of UEs of the PRB(s) and OFDM symbol(s) where UE may assume no ///< transmission is intended for the UE srslte_dci_format_nr_2_2, ///< @brief Transmission of TPC commands for PUCCH and PUSCH - srslte_dci_format_nr_2_3 ///< @brief Transmission of a group of TPC commands for SRS transmissions by one or more UEs + srslte_dci_format_nr_2_3, ///< @brief Transmission of a group of TPC commands for SRS transmissions by one or more UEs + srslte_dci_format_nr_rar, ///< @brief Scheduling a transmission of PUSCH from RAR + srslte_dci_format_nr_cg ///< @brief Scheduling of PUSCH using a configured grant } srslte_dci_format_nr_t; /** @@ -287,7 +291,7 @@ SRSLTE_API uint32_t srslte_coreset_get_sz(const srslte_coreset_t* coreset); * @param mapping_type Mapping type * @return Constant string with PDSCH mapping type */ -SRSLTE_API const char* srslte_pdsch_mapping_type_to_str(srslte_pdsch_mapping_type_t mapping_type); +SRSLTE_API const char* srslte_sch_mapping_type_to_str(srslte_sch_mapping_type_t mapping_type); /** * @brief Get the MCS table string diff --git a/lib/include/srslte/phy/enb/enb_dl_nr.h b/lib/include/srslte/phy/enb/enb_dl_nr.h index 45e28120c..6d37f2119 100644 --- a/lib/include/srslte/phy/enb/enb_dl_nr.h +++ b/lib/include/srslte/phy/enb/enb_dl_nr.h @@ -37,9 +37,9 @@ typedef struct SRSLTE_API { srslte_ofdm_t fft[SRSLTE_MAX_PORTS]; - cf_t* sf_symbols[SRSLTE_MAX_PORTS]; - srslte_pdsch_nr_t pdsch; - srslte_dmrs_pdsch_t dmrs; + cf_t* sf_symbols[SRSLTE_MAX_PORTS]; + srslte_pdsch_nr_t pdsch; + srslte_dmrs_sch_t dmrs; srslte_pdcch_nr_t pdcch; } srslte_enb_dl_nr_t; @@ -64,17 +64,17 @@ SRSLTE_API int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, const srslte_dci_location_t* dci_location, uint16_t rnti); -SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB]); - -SRSLTE_API int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - char* str, - uint32_t str_len); +SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, + const srslte_dl_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB]); + +SRSLTE_API int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len); #ifdef __cplusplus } diff --git a/lib/include/srslte/phy/phch/dci_nr.h b/lib/include/srslte/phy/phch/dci_nr.h index aa10c4416..d7fe44625 100644 --- a/lib/include/srslte/phy/phch/dci_nr.h +++ b/lib/include/srslte/phy/phch/dci_nr.h @@ -15,7 +15,7 @@ #include "dci.h" #include "srslte/phy/common/phy_common_nr.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" typedef struct SRSLTE_API { srslte_dci_location_t location; diff --git a/lib/include/srslte/phy/phch/pdsch_nr.h b/lib/include/srslte/phy/phch/pdsch_nr.h index 6c40b6567..a4b079f2e 100644 --- a/lib/include/srslte/phy/phch/pdsch_nr.h +++ b/lib/include/srslte/phy/phch/pdsch_nr.h @@ -18,12 +18,12 @@ * Reference: 3GPP TS 38.211 V15.8.0 Sec. 7.3.1 *****************************************************************************/ -#ifndef srslte_pdsch_nr_H -#define srslte_pdsch_nr_H +#ifndef SRSLTE_PDSCH_NR_H +#define SRSLTE_PDSCH_NR_H #include "srslte/config.h" -#include "srslte/phy/ch_estimation/dmrs_pdsch.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/ch_estimation/dmrs_sch.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #include "srslte/phy/phch/regs.h" #include "srslte/phy/phch/sch_nr.h" #include "srslte/phy/scrambling/scrambling.h" @@ -72,30 +72,30 @@ SRSLTE_API void srslte_pdsch_nr_free(srslte_pdsch_nr_t* q); SRSLTE_API int srslte_pdsch_nr_set_carrier(srslte_pdsch_nr_t* q, const srslte_carrier_nr_t* carrier); -SRSLTE_API int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB], - cf_t* sf_symbols[SRSLTE_MAX_PORTS]); +SRSLTE_API int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB], + cf_t* sf_symbols[SRSLTE_MAX_PORTS]); -SRSLTE_API int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - srslte_chest_dl_res_t* channel, - cf_t* sf_symbols[SRSLTE_MAX_PORTS], - srslte_pdsch_res_nr_t data[SRSLTE_MAX_TB]); +SRSLTE_API int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_chest_dl_res_t* channel, + cf_t* sf_symbols[SRSLTE_MAX_PORTS], + srslte_pdsch_res_nr_t data[SRSLTE_MAX_TB]); -SRSLTE_API uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - const srslte_pdsch_res_nr_t* res, - char* str, - uint32_t str_len); +SRSLTE_API uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pdsch_res_nr_t* res, + char* str, + uint32_t str_len); -SRSLTE_API uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - char* str, - uint32_t str_len); +SRSLTE_API uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len); -#endif // srslte_pdsch_nr_H +#endif // SRSLTE_PDSCH_NR_H diff --git a/lib/include/srslte/phy/phch/pdsch_cfg_nr.h b/lib/include/srslte/phy/phch/phch_cfg_nr.h similarity index 63% rename from lib/include/srslte/phy/phch/pdsch_cfg_nr.h rename to lib/include/srslte/phy/phch/phch_cfg_nr.h index a0ec54b04..5de15cea0 100644 --- a/lib/include/srslte/phy/phch/pdsch_cfg_nr.h +++ b/lib/include/srslte/phy/phch/phch_cfg_nr.h @@ -18,8 +18,8 @@ * Reference: *****************************************************************************/ -#ifndef SRSLTE_PDSCH_CFG_NR_H -#define SRSLTE_PDSCH_CFG_NR_H +#ifndef SRSLTE_PHCH_CFG_NR_H +#define SRSLTE_PHCH_CFG_NR_H #include "srslte/phy/common/phy_common_nr.h" #include "srslte/phy/phch/sch_cfg_nr.h" @@ -32,35 +32,35 @@ extern "C" { * @brief PDSCH DMRS type */ typedef enum { - srslte_dmrs_pdsch_type_1 = 0, // 1 pilot every 2 sub-carriers (default) - srslte_dmrs_pdsch_type_2 // 2 consecutive pilots every 6 sub-carriers -} srslte_dmrs_pdsch_type_t; + srslte_dmrs_sch_type_1 = 0, // 1 pilot every 2 sub-carriers (default) + srslte_dmrs_sch_type_2 // 2 consecutive pilots every 6 sub-carriers +} srslte_dmrs_sch_type_t; /** * @brief PDSCH DMRS length in symbols */ typedef enum { - srslte_dmrs_pdsch_len_1 = 0, // single, 1 symbol long (default) - srslte_dmrs_pdsch_len_2 // double, 2 symbol long -} srslte_dmrs_pdsch_len_t; + srslte_dmrs_sch_len_1 = 0, // single, 1 symbol long (default) + srslte_dmrs_sch_len_2 // double, 2 symbol long +} srslte_dmrs_sch_len_t; /** * @brief Determines whether the first pilot goes into symbol index 2 or 3 */ typedef enum { - srslte_dmrs_pdsch_typeA_pos_2 = 0, // Start in slot symbol index 2 (default) - srslte_dmrs_pdsch_typeA_pos_3 // Start in slot symbol index 3 -} srslte_dmrs_pdsch_typeA_pos_t; + srslte_dmrs_sch_typeA_pos_2 = 0, // Start in slot symbol index 2 (default) + srslte_dmrs_sch_typeA_pos_3 // Start in slot symbol index 3 +} srslte_dmrs_sch_typeA_pos_t; /** * @brief Determines additional symbols if possible to be added */ typedef enum { - srslte_dmrs_pdsch_add_pos_2 = 0, - srslte_dmrs_pdsch_add_pos_0, - srslte_dmrs_pdsch_add_pos_1, - srslte_dmrs_pdsch_add_pos_3 -} srslte_dmrs_pdsch_add_pos_t; + srslte_dmrs_sch_add_pos_2 = 0, + srslte_dmrs_sch_add_pos_0, + srslte_dmrs_sch_add_pos_1, + srslte_dmrs_sch_add_pos_3 +} srslte_dmrs_sch_add_pos_t; /** * @brief Provides PDSCH DMRS configuration from higher layers @@ -68,22 +68,22 @@ typedef enum { */ typedef struct { /// Parameters provided by IE DMRS-DownlinkConfig - srslte_dmrs_pdsch_type_t type; - srslte_dmrs_pdsch_add_pos_t additional_pos; - srslte_dmrs_pdsch_len_t length; - bool scrambling_id0_present; - uint32_t scrambling_id0; - bool scrambling_id1_present; - uint32_t scrambling_id1; + srslte_dmrs_sch_type_t type; + srslte_dmrs_sch_add_pos_t additional_pos; + srslte_dmrs_sch_len_t length; + bool scrambling_id0_present; + uint32_t scrambling_id0; + bool scrambling_id1_present; + uint32_t scrambling_id1; /// Parameters provided by ServingCellConfigCommon - srslte_dmrs_pdsch_typeA_pos_t typeA_pos; - bool lte_CRS_to_match_around; + srslte_dmrs_sch_typeA_pos_t typeA_pos; + bool lte_CRS_to_match_around; /// Parameters provided by FeatureSetDownlink-v1540 bool additional_DMRS_DL_Alt; -} srslte_pdsch_dmrs_cfg_t; +} srslte_dmrs_sch_cfg_t; /** * @brief flatten PDSCH time domain allocation parameters @@ -94,7 +94,7 @@ typedef struct SRSLTE_API { uint32_t k0; /// PDSCH mapping type - srslte_pdsch_mapping_type_t mapping_type; + srslte_sch_mapping_type_t mapping_type; /// An index giving valid combinations of start symbol and length (jointly encoded) as start and length indicator /// (SLIV). The network configures the field so that the allocation does not cross the slot boundary @@ -111,10 +111,11 @@ typedef struct SRSLTE_API { srslte_rnti_type_t rnti_type; /// Time domain resources - uint32_t k0; - uint32_t S; - uint32_t L; - srslte_pdsch_mapping_type_t mapping; + uint32_t k0; // PDSCH only + uint32_t k2; // PUSCH only + uint32_t S; + uint32_t L; + srslte_sch_mapping_type_t mapping; /// Frequency domain resources bool prb_idx[SRSLTE_MAX_PRB_NR]; @@ -138,25 +139,29 @@ typedef struct SRSLTE_API { /// .... srslte_sch_tb_t tb[SRSLTE_MAX_TB]; -} srslte_pdsch_grant_nr_t; +} srslte_sch_grant_nr_t; /** - * @brief flatten PDSCH configuration parameters provided by higher layers + * @brief flatten SCH configuration parameters provided by higher layers * @remark Described in TS 38.331 V15.10.0 Section PDSCH-Config + * @remark Described in TS 38.331 V15.10.0 Section PUSCH-Config */ typedef struct SRSLTE_API { bool scrambling_id_present; uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023) - srslte_pdsch_dmrs_cfg_t dmrs_cfg_typeA; - srslte_pdsch_dmrs_cfg_t dmrs_cfg_typeB; + srslte_dmrs_sch_cfg_t dmrs_typeA; + srslte_dmrs_sch_cfg_t dmrs_typeB; srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters -} srslte_pdsch_cfg_nr_t; + + /// Uplink params + bool enable_transform_precoder; +} srslte_sch_cfg_nr_t; #ifdef __cplusplus } #endif -#endif // SRSLTE_PDSCH_CFG_NR_H +#endif // SRSLTE_PHCH_CFG_NR_H diff --git a/lib/include/srslte/phy/phch/pusch_nr.h b/lib/include/srslte/phy/phch/pusch_nr.h new file mode 100644 index 000000000..64b99012e --- /dev/null +++ b/lib/include/srslte/phy/phch/pusch_nr.h @@ -0,0 +1,93 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSLTE_PUSCH_NR_H +#define SRSLTE_PUSCH_NR_H + +#include "srslte/config.h" +#include "srslte/phy/ch_estimation/dmrs_sch.h" +#include "srslte/phy/phch/phch_cfg_nr.h" +#include "srslte/phy/phch/regs.h" +#include "srslte/phy/phch/sch_nr.h" +#include "srslte/phy/scrambling/scrambling.h" + +/** + * @brief PUSCH encoder and decoder initialization arguments + */ +typedef struct SRSLTE_API { + srslte_sch_nr_args_t sch; + bool measure_evm; + bool measure_time; +} srslte_pusch_nr_args_t; + +/** + * @brief PDSCH NR object + */ +typedef struct SRSLTE_API { + uint32_t max_prb; ///< Maximum number of allocated prb + uint32_t max_layers; ///< Maximum number of allocated layers + uint32_t max_cw; ///< Maximum number of allocated code words + srslte_carrier_nr_t carrier; ///< NR carrier configuration + srslte_sch_nr_t sch; ///< SCH Encoder/Decoder Object + uint8_t* b[SRSLTE_MAX_CODEWORDS]; ///< SCH Encoded and scrambled data + cf_t* d[SRSLTE_MAX_CODEWORDS]; ///< PDSCH modulated bits + cf_t* x[SRSLTE_MAX_LAYERS_NR]; ///< PDSCH modulated bits + srslte_modem_table_t modem_tables[SRSLTE_MOD_NITEMS]; ///< Modulator tables + srslte_evm_buffer_t* evm_buffer; + bool meas_time_en; + uint32_t meas_time_us; +} srslte_pusch_nr_t; + +/** + * + */ +typedef struct { + uint8_t* payload; + bool crc; + float evm; +} 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_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args); + +SRSLTE_API void srslte_pusch_nr_free(srslte_pusch_nr_t* q); + +SRSLTE_API int srslte_pusch_nr_set_carrier(srslte_pusch_nr_t* q, const srslte_carrier_nr_t* carrier); + +SRSLTE_API int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB], + cf_t* sf_symbols[SRSLTE_MAX_PORTS]); + +SRSLTE_API int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_chest_dl_res_t* channel, + cf_t* sf_symbols[SRSLTE_MAX_PORTS], + srslte_pusch_res_nr_t data[SRSLTE_MAX_TB]); + +SRSLTE_API uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pusch_res_nr_t* res, + char* str, + uint32_t str_len); + +SRSLTE_API uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len); + +#endif // SRSLTE_PUSCH_NR_H diff --git a/lib/include/srslte/phy/phch/ra_nr.h b/lib/include/srslte/phy/phch/ra_nr.h index 91750f8a5..291cabec2 100644 --- a/lib/include/srslte/phy/phch/ra_nr.h +++ b/lib/include/srslte/phy/phch/ra_nr.h @@ -26,7 +26,7 @@ #include "srslte/config.h" #include "srslte/phy/common/phy_common_nr.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #ifdef __cplusplus extern "C" { @@ -68,8 +68,7 @@ SRSLTE_API srslte_mod_t srslte_ra_nr_mod_from_mcs(srslte_mcs_table_t mcs * @param grant The given PDSCH transmission grant * @return The number of resource elements if the provided configuration is valid, otherwise SRSLTE_ERROR code */ -SRSLTE_API int srslte_ra_dl_nr_slot_nof_re(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant); +SRSLTE_API int srslte_ra_dl_nr_slot_nof_re(const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant); /** * @brief Calculates shared channel TBS @@ -82,10 +81,10 @@ SRSLTE_API int srslte_ra_dl_nr_slot_nof_re(const srslte_pdsch_cfg_nr_t* pdsch_ */ SRSLTE_API uint32_t srslte_ra_nr_tbs(uint32_t N_re, double S, double R, uint32_t Qm, uint32_t nof_layers); -SRSLTE_API int srslte_ra_nr_fill_tb(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t mcs_idx, - srslte_sch_tb_t* tb); +SRSLTE_API int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t mcs_idx, + srslte_sch_tb_t* tb); #ifdef __cplusplus } diff --git a/lib/include/srslte/phy/phch/sch_nr.h b/lib/include/srslte/phy/phch/sch_nr.h index 3574b2e10..ce3cebbf3 100644 --- a/lib/include/srslte/phy/phch/sch_nr.h +++ b/lib/include/srslte/phy/phch/sch_nr.h @@ -27,7 +27,7 @@ #include "srslte/phy/fec/ldpc/ldpc_decoder.h" #include "srslte/phy/fec/ldpc/ldpc_encoder.h" #include "srslte/phy/fec/ldpc/ldpc_rm.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #define SRSLTE_SCH_NR_MAX_NOF_CB_LDPC \ ((SRSLTE_SLOT_MAX_NOF_BITS_NR + (SRSLTE_LDPC_BG2_MAX_LEN_CB - 1)) / SRSLTE_LDPC_BG2_MAX_LEN_CB) @@ -110,17 +110,39 @@ SRSLTE_API srslte_basegraph_t srslte_sch_nr_select_basegraph(uint32_t tbs, doubl * @param cfg SCH object * @return */ -SRSLTE_API int srslte_dlsch_nr_fill_cfg(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* sch_cfg, - const srslte_sch_tb_t* tb, - srslte_sch_nr_common_cfg_t* cfg); +SRSLTE_API int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + srslte_sch_nr_common_cfg_t* cfg); -SRSLTE_API int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* cfg); +/** + * @brief Initialises an SCH object as transmitter + * @param q Points ats the SCH object + * @param args Provides static configuration arguments + * @return SRSLTE_SUCCESS if the initialization is successful, SRSLTE_ERROR otherwise + */ +SRSLTE_API int srslte_sch_nr_init_tx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args); -SRSLTE_API int srslte_sch_nr_init_rx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* cfg); +/** + * @brief Initialises an SCH object as receiver + * @param q Points ats the SCH object + * @param args Provides static configuration arguments + * @return SRSLTE_SUCCESS if the initialization is successful, SRSLTE_ERROR otherwise + */ +SRSLTE_API int srslte_sch_nr_init_rx(srslte_sch_nr_t* q, const srslte_sch_nr_args_t* args); +/** + * @brief Sets SCH object carrier attribute + * @param q Points ats the SCH object + * @param carrier Provides the NR carrier object + * @return SRSLTE_SUCCESS if the setting is successful, SRSLTE_ERROR otherwise + */ SRSLTE_API int srslte_sch_nr_set_carrier(srslte_sch_nr_t* q, const srslte_carrier_nr_t* carrier); +/** + * @brief Free allocated resources used by an SCH intance + * @param q Points ats the SCH object + */ SRSLTE_API void srslte_sch_nr_free(srslte_sch_nr_t* q); SRSLTE_API int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, @@ -129,8 +151,6 @@ SRSLTE_API int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, const uint8_t* data, uint8_t* e_bits); -SRSLTE_API int srslte_sch_nr_decoder_set_carrier(srslte_sch_nr_t* q, const srslte_carrier_nr_t* carrier); - SRSLTE_API int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, const srslte_sch_cfg_t* sch_cfg, const srslte_sch_tb_t* tb, @@ -138,6 +158,19 @@ SRSLTE_API int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, uint8_t* data, bool* crc_ok); +SRSLTE_API int srslte_ulsch_nr_encode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint8_t* e_bits); + +SRSLTE_API int srslte_ulsch_nr_decode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + int8_t* e_bits, + uint8_t* data, + bool* crc_ok); + SRSLTE_API int srslte_sch_nr_tb_info(const srslte_sch_tb_t* tb, char* str, uint32_t str_len); #endif // SRSLTE_SCH_NR_H \ No newline at end of file diff --git a/lib/include/srslte/phy/ue/ue_dl_nr.h b/lib/include/srslte/phy/ue/ue_dl_nr.h index 960a649bc..3eadf2639 100644 --- a/lib/include/srslte/phy/ue/ue_dl_nr.h +++ b/lib/include/srslte/phy/ue/ue_dl_nr.h @@ -46,7 +46,7 @@ typedef struct SRSLTE_API { cf_t* sf_symbols[SRSLTE_MAX_PORTS]; srslte_chest_dl_res_t chest; srslte_pdsch_nr_t pdsch; - srslte_dmrs_pdsch_t dmrs_pdsch; + srslte_dmrs_sch_t dmrs_pdsch; srslte_dmrs_pdcch_estimator_t dmrs_pdcch; srslte_pdcch_nr_t pdcch; @@ -71,18 +71,18 @@ SRSLTE_API int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, srslte_dci_dl_nr_t* dci_dl_list, uint32_t nof_dci_msg); -SRSLTE_API int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - srslte_pdsch_res_nr_t* res); - -SRSLTE_API int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], - char* str, - uint32_t str_len); +SRSLTE_API int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, + const srslte_dl_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_pdsch_res_nr_t* res); + +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_grant_nr_t* grant, + const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], + char* str, + uint32_t str_len); #ifdef __cplusplus } diff --git a/lib/include/srslte/phy/ue/ue_dl_nr_data.h b/lib/include/srslte/phy/ue/ue_dl_nr_data.h index c70beea80..b4c2266e5 100644 --- a/lib/include/srslte/phy/ue/ue_dl_nr_data.h +++ b/lib/include/srslte/phy/ue/ue_dl_nr_data.h @@ -24,7 +24,7 @@ #define SRSLTE_UE_DL_NR_DATA_H #include "srslte/phy/common/phy_common_nr.h" -#include "srslte/phy/phch/pdsch_cfg_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" #ifdef __cplusplus extern "C" { @@ -41,7 +41,7 @@ extern "C" { * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code */ SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, - srslte_pdsch_grant_nr_t* grant); + srslte_sch_grant_nr_t* grant); /** * @brief Calculates the PDSCH time resource default A and stores it in the provided PDSCH NR grant. This can be used by @@ -55,9 +55,9 @@ SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocat * @param[out] grant PDSCH mapping type * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code */ -SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, - srslte_dmrs_pdsch_typeA_pos_t dmrs_typeA_pos, - srslte_pdsch_grant_nr_t* grant); +SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, + srslte_dmrs_sch_typeA_pos_t dmrs_typeA_pos, + srslte_sch_grant_nr_t* grant); /** * @brief Calculates the number of PDSCH-DMRS CDM groups without data for DCI format 1_0 * @@ -67,8 +67,8 @@ SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t * @param[out] grant Provides grant pointer to fill * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code */ -SRSLTE_API int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - srslte_pdsch_grant_nr_t* grant); +SRSLTE_API int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg, + srslte_sch_grant_nr_t* grant); #ifdef __cplusplus } diff --git a/lib/include/srslte/phy/ue/ue_ul_nr_data.h b/lib/include/srslte/phy/ue/ue_ul_nr_data.h new file mode 100644 index 000000000..fe25f47e7 --- /dev/null +++ b/lib/include/srslte/phy/ue/ue_ul_nr_data.h @@ -0,0 +1,61 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +/****************************************************************************** + * @file ue_dl_nr.h + * + * Description: NR UE uplink physical layer procedures for data + * + * This module is a frontend to all the uplink data channel processing modules. + * + * Reference: + *****************************************************************************/ + +#ifndef SRSLTE_UE_UL_DATA_H +#define SRSLTE_UE_UL_DATA_H + +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/phy/phch/phch_cfg_nr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Calculates the PUSCH time resource default A and stores it in the provided PUSCH NR grant. + * + * @remark Defined by TS 38.214 V15.10.0 Table 6.1.2.1.1-2: Default PUSCH time domain resource allocation A for normal + * CP + * + * @param m Time domain resource assignment field value m of the DCI + * @param[out] grant PUSCH grant + * @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant); + +/** + * @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0 + * + * @remark Defined by TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure + * + * @param cfg PUSCH NR configuration by upper layers + * @param[out] grant Provides grant pointer to fill + * @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code + */ +SRSLTE_API int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, + srslte_sch_grant_nr_t* grant); + +#ifdef __cplusplus +} +#endif + +#endif // SRSLTE_UE_UL_DATA_H diff --git a/lib/src/phy/ch_estimation/dmrs_pdsch.c b/lib/src/phy/ch_estimation/dmrs_sch.c similarity index 70% rename from lib/src/phy/ch_estimation/dmrs_pdsch.c rename to lib/src/phy/ch_estimation/dmrs_sch.c index 16b652dab..4bd0eddc7 100644 --- a/lib/src/phy/ch_estimation/dmrs_pdsch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -10,22 +10,22 @@ * */ -#include "srslte/phy/ch_estimation/dmrs_pdsch.h" +#include "srslte/phy/ch_estimation/dmrs_sch.h" #include -#define SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN 3 -#define SRSLTE_DMRS_PDSCH_TYPEA_DOUBLE_DURATION_MIN 4 +#define SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN 3 +#define SRSLTE_DMRS_SCH_TYPEA_DOUBLE_DURATION_MIN 4 -int srslte_dmrs_pdsch_cfg_to_str(const srslte_pdsch_dmrs_cfg_t* cfg, char* msg, uint32_t max_len) +int srslte_dmrs_sch_cfg_to_str(const srslte_dmrs_sch_cfg_t* cfg, char* msg, uint32_t max_len) { int type = (int)cfg->type + 1; int typeA_pos = (int)cfg->typeA_pos + 2; - int additional_pos = cfg->additional_pos == srslte_dmrs_pdsch_add_pos_0 + int additional_pos = cfg->additional_pos == srslte_dmrs_sch_add_pos_0 ? 0 - : cfg->additional_pos == srslte_dmrs_pdsch_add_pos_1 + : cfg->additional_pos == srslte_dmrs_sch_add_pos_1 ? 1 - : cfg->additional_pos == srslte_dmrs_pdsch_add_pos_2 ? 2 : 3; - const char* len = cfg->length == srslte_dmrs_pdsch_len_1 ? "single" : "double"; + : cfg->additional_pos == srslte_dmrs_sch_add_pos_2 ? 2 : 3; + const char* len = cfg->length == srslte_dmrs_sch_len_1 ? "single" : "double"; return srslte_print_check( msg, max_len, 0, "type=%d, typeA_pos=%d, add_pos=%d, len=%s", type, typeA_pos, additional_pos, len); @@ -63,9 +63,9 @@ srslte_dmrs_get_pilots_type2(uint32_t start_prb, uint32_t nof_prb, uint32_t delt return count; } -static uint32_t srslte_dmrs_get_lse(srslte_dmrs_pdsch_t* q, +static uint32_t srslte_dmrs_get_lse(srslte_dmrs_sch_t* q, srslte_sequence_state_t* sequence_state, - srslte_dmrs_pdsch_type_t dmrs_type, + srslte_dmrs_sch_type_t dmrs_type, uint32_t start_prb, uint32_t nof_prb, uint32_t delta, @@ -76,10 +76,10 @@ static uint32_t srslte_dmrs_get_lse(srslte_dmrs_pdsch_t* q, switch (dmrs_type) { - case srslte_dmrs_pdsch_type_1: + case srslte_dmrs_sch_type_1: count = srslte_dmrs_get_pilots_type1(start_prb, nof_prb, delta, symbols, least_square_estimates); break; - case srslte_dmrs_pdsch_type_2: + case srslte_dmrs_sch_type_2: count = srslte_dmrs_get_pilots_type2(start_prb, nof_prb, delta, symbols, least_square_estimates); break; default: @@ -127,25 +127,25 @@ srslte_dmrs_put_pilots_type2(uint32_t start_prb, uint32_t nof_prb, uint32_t delt return count; } -static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_pdsch_t* q, +static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_sch_t* q, srslte_sequence_state_t* sequence_state, - srslte_dmrs_pdsch_type_t dmrs_type, + srslte_dmrs_sch_type_t dmrs_type, uint32_t start_prb, uint32_t nof_prb, uint32_t delta, cf_t* symbols) { - uint32_t count = (dmrs_type == srslte_dmrs_pdsch_type_1) ? nof_prb * 6 : nof_prb * 4; + uint32_t count = (dmrs_type == srslte_dmrs_sch_type_1) ? nof_prb * 6 : nof_prb * 4; // Generate sequence for the given pilots srslte_sequence_state_gen_f(sequence_state, M_SQRT1_2, (float*)q->temp, count * 2); switch (dmrs_type) { - case srslte_dmrs_pdsch_type_1: + case srslte_dmrs_sch_type_1: count = srslte_dmrs_put_pilots_type1(start_prb, nof_prb, delta, symbols, q->temp); break; - case srslte_dmrs_pdsch_type_2: + case srslte_dmrs_sch_type_2: count = srslte_dmrs_put_pilots_type2(start_prb, nof_prb, delta, symbols, q->temp); break; default: @@ -155,19 +155,19 @@ static uint32_t srslte_dmrs_put_pilots(srslte_dmrs_pdsch_t* q, return count; } -static int srslte_dmrs_pdsch_put_symbol(srslte_dmrs_pdsch_t* q, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t cinit, - uint32_t delta, - cf_t* symbols) +static int srslte_dmrs_sch_put_symbol(srslte_dmrs_sch_t* q, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t cinit, + uint32_t delta, + cf_t* symbols) { - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &pdsch_cfg->dmrs_cfg_typeA : &pdsch_cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; uint32_t prb_count = 0; // Counts consecutive used PRB uint32_t prb_start = 0; // Start consecutive used PRB uint32_t prb_skip = 0; // Number of PRB to skip - uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_pdsch_type_1 ? 6 : 4; + uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4; uint32_t pilot_count = 0; // Initialise sequence @@ -216,19 +216,19 @@ static int srslte_dmrs_pdsch_put_symbol(srslte_dmrs_pdsch_t* q, } // Implements 3GPP 38.211 R.15 Table 7.4.1.1.2-3 PDSCH mapping type A Single -static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_pdsch_dmrs_cfg_t* dmrs_cfg, - uint32_t ld, - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS]) +static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_single(const srslte_dmrs_sch_cfg_t* dmrs_cfg, + uint32_t ld, + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS]) { int count = 0; - if (ld < SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN) { + if (ld < SRSLTE_DMRS_SCH_TYPEA_SINGLE_DURATION_MIN) { ERROR("Duration is below the minimum\n"); return SRSLTE_ERROR; } // l0 = 3 if the higher-layer parameter dmrs-TypeA-Position is equal to 'pos3' and l0 = 2 otherwise - int l0 = (dmrs_cfg->typeA_pos == srslte_dmrs_pdsch_typeA_pos_3) ? 3 : 2; + int l0 = (dmrs_cfg->typeA_pos == srslte_dmrs_sch_typeA_pos_3) ? 3 : 2; // For PDSCH mapping Type A single-symbol DM-RS, l1 = 11 except if all of the following conditions are fulfilled in // which case l1 = 12: @@ -236,15 +236,15 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_ // - the higher-layer parameters dmrs-AdditionalPosition is equal to 'pos1' and l0 = 3; and // - the UE has indicated it is capable of additionalDMRS-DL-Alt int l1 = 11; - if (dmrs_cfg->lte_CRS_to_match_around && dmrs_cfg->additional_pos == srslte_dmrs_pdsch_add_pos_1 && - dmrs_cfg->typeA_pos == srslte_dmrs_pdsch_typeA_pos_3 && dmrs_cfg->additional_DMRS_DL_Alt) { + if (dmrs_cfg->lte_CRS_to_match_around && dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_1 && + dmrs_cfg->typeA_pos == srslte_dmrs_sch_typeA_pos_3 && dmrs_cfg->additional_DMRS_DL_Alt) { l1 = 12; } symbols[count] = l0; count++; - if (ld < 8 || dmrs_cfg->additional_pos == srslte_dmrs_pdsch_add_pos_0) { + if (ld < 8 || dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_0) { return count; } @@ -252,7 +252,7 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_ symbols[count] = 7; count++; } else if (ld < 12) { - if (dmrs_cfg->additional_pos > srslte_dmrs_pdsch_add_pos_2) { + if (dmrs_cfg->additional_pos > srslte_dmrs_sch_add_pos_2) { symbols[count] = 6; count++; } @@ -262,11 +262,11 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_ } else if (ld == 12) { switch (dmrs_cfg->additional_pos) { - case srslte_dmrs_pdsch_add_pos_1: + case srslte_dmrs_sch_add_pos_1: symbols[count] = 9; count++; break; - case srslte_dmrs_pdsch_add_pos_2: + case srslte_dmrs_sch_add_pos_2: symbols[count] = 6; count++; symbols[count] = 9; @@ -282,11 +282,11 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_ } } else { switch (dmrs_cfg->additional_pos) { - case srslte_dmrs_pdsch_add_pos_1: + case srslte_dmrs_sch_add_pos_1: symbols[count] = l1; count++; break; - case srslte_dmrs_pdsch_add_pos_2: + case srslte_dmrs_sch_add_pos_2: symbols[count] = 7; count++; symbols[count] = 11; @@ -306,31 +306,31 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_ } // Implements 3GPP 38.211 R.15 Table 7.4.1.1.2-4 PDSCH mapping type A Double -static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_pdsch_dmrs_cfg_t* dmrs_cfg, - uint32_t ld, - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS]) +static int srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(const srslte_dmrs_sch_cfg_t* dmrs_cfg, + uint32_t ld, + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS]) { int count = 0; - if (ld < SRSLTE_DMRS_PDSCH_TYPEA_DOUBLE_DURATION_MIN) { + if (ld < SRSLTE_DMRS_SCH_TYPEA_DOUBLE_DURATION_MIN) { return SRSLTE_ERROR; } // According to Table 7.4.1.1.2-4, the additional position 3 is invalid. - if (dmrs_cfg->additional_pos == srslte_dmrs_pdsch_add_pos_3) { + if (dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_3) { ERROR("Invalid additional DMRS (%d)\n", dmrs_cfg->additional_pos); return SRSLTE_ERROR; } // l0 = 3 if the higher-layer parameter dmrs-TypeA-Position is equal to 'pos3' and l0 = 2 otherwise - int l0 = (dmrs_cfg->typeA_pos == srslte_dmrs_pdsch_typeA_pos_3) ? 3 : 2; + int l0 = (dmrs_cfg->typeA_pos == srslte_dmrs_sch_typeA_pos_3) ? 3 : 2; symbols[count] = l0; count++; symbols[count] = symbols[count - 1] + 1; count++; - if (ld < 10 || dmrs_cfg->additional_pos == srslte_dmrs_pdsch_add_pos_0) { + if (ld < 10 || dmrs_cfg->additional_pos == srslte_dmrs_sch_add_pos_0) { return count; } @@ -349,27 +349,26 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_ return count; } -int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS]) +int srslte_dmrs_sch_get_symbols_idx(const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS]) { // The position(s) of the DM-RS symbols is given by l and duration ld where // - for PDSCH mapping type A, ld is the duration between the first OFDM symbol of the slot and the last OFDM symbol // of the scheduled PDSCH resources in the slot // - for PDSCH mapping type B, ld is the duration of the scheduled PDSCH resources uint32_t ld = grant->L; - if (grant->mapping == srslte_pdsch_mapping_type_A) { + if (grant->mapping == srslte_sch_mapping_type_A) { ld = grant->S + grant->L; } - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; switch (grant->mapping) { - case srslte_pdsch_mapping_type_A: + case srslte_sch_mapping_type_A: // 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_pdsch_typeA_pos_2 && - dmrs_cfg->additional_pos == srslte_dmrs_pdsch_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 " "to 'pos2'\n"); return SRSLTE_ERROR; @@ -377,17 +376,17 @@ int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* cfg, // 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 - if ((ld == 3 || ld == 4) && dmrs_cfg->typeA_pos != srslte_dmrs_pdsch_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 " "is only applicable when dmrs-TypeA-Position is equal to 'pos2\n"); return SRSLTE_ERROR; } - if (dmrs_cfg->length == srslte_dmrs_pdsch_len_1) { - return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(dmrs_cfg, ld, symbols); + if (dmrs_cfg->length == srslte_dmrs_sch_len_1) { + return srslte_dmrs_sch_get_symbols_idx_mapping_type_A_single(dmrs_cfg, ld, symbols); } - return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(dmrs_cfg, ld, symbols); - case srslte_pdsch_mapping_type_B: + return srslte_dmrs_sch_get_symbols_idx_mapping_type_A_double(dmrs_cfg, ld, symbols); + case srslte_sch_mapping_type_B: ERROR("Error PDSCH mapping type B not supported\n"); return SRSLTE_ERROR; } @@ -395,12 +394,12 @@ int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* cfg, return SRSLTE_ERROR; } -int srslte_dmrs_pdsch_get_sc_idx(const srslte_pdsch_dmrs_cfg_t* cfg, uint32_t max_count, uint32_t* sc_idx) +int srslte_dmrs_sch_get_sc_idx(const srslte_dmrs_sch_cfg_t* cfg, uint32_t max_count, uint32_t* sc_idx) { int count = 0; uint32_t delta = 0; - if (cfg->type == srslte_dmrs_pdsch_type_1) { + if (cfg->type == srslte_dmrs_sch_type_1) { for (uint32_t n = 0; count < max_count; n += 4) { for (uint32_t k_prime = 0; k_prime < 2 && count < max_count; k_prime++) { sc_idx[count++] = n + 2 * k_prime + delta; @@ -417,10 +416,10 @@ int srslte_dmrs_pdsch_get_sc_idx(const srslte_pdsch_dmrs_cfg_t* cfg, uint32_t ma return count; } -int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_pdsch_grant_nr_t* grant) +int srslte_dmrs_sch_get_N_prb(const srslte_sch_cfg_nr_t* cfg, const srslte_sch_grant_nr_t* grant) { - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; 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", @@ -429,12 +428,12 @@ int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_p } // Get number of frequency domain resource elements used for DMRS - int nof_sc = SRSLTE_MIN( - SRSLTE_NRE, grant->nof_dmrs_cdm_groups_without_data * (dmrs_cfg->type == srslte_dmrs_pdsch_type_1 ? 6 : 4)); + int nof_sc = SRSLTE_MIN(SRSLTE_NRE, + grant->nof_dmrs_cdm_groups_without_data * (dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4)); // Get number of symbols used for DMRS - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {}; - int ret = srslte_dmrs_pdsch_get_symbols_idx(cfg, grant, symbols); + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + int ret = srslte_dmrs_sch_get_symbols_idx(cfg, grant, symbols); if (ret < SRSLTE_SUCCESS) { ERROR("Error getting PDSCH DMRS symbol indexes\n"); return SRSLTE_ERROR; @@ -443,14 +442,14 @@ int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_p return nof_sc * ret; } -static uint32_t srslte_dmrs_pdsch_seed(const srslte_carrier_nr_t* carrier, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t slot_idx, - uint32_t symbol_idx) +static uint32_t srslte_dmrs_sch_seed(const srslte_carrier_nr_t* carrier, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t slot_idx, + uint32_t symbol_idx) { - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; slot_idx = slot_idx % SRSLTE_NSLOTS_PER_FRAME_NR(carrier->numerology); @@ -470,7 +469,7 @@ static uint32_t srslte_dmrs_pdsch_seed(const srslte_carrier_nr_t* carrier, (uint64_t)INT32_MAX); } -int srslte_dmrs_pdsch_init(srslte_dmrs_pdsch_t* q, bool is_ue) +int srslte_dmrs_sch_init(srslte_dmrs_sch_t* q, bool is_ue) { if (q == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -483,7 +482,7 @@ int srslte_dmrs_pdsch_init(srslte_dmrs_pdsch_t* q, bool is_ue) return SRSLTE_SUCCESS; } -void srslte_dmrs_pdsch_free(srslte_dmrs_pdsch_t* q) +void srslte_dmrs_sch_free(srslte_dmrs_sch_t* q) { if (q == NULL) { return; @@ -498,10 +497,10 @@ void srslte_dmrs_pdsch_free(srslte_dmrs_pdsch_t* q) free(q->temp); } - SRSLTE_MEM_ZERO(q, srslte_dmrs_pdsch_t, 1); + SRSLTE_MEM_ZERO(q, srslte_dmrs_sch_t, 1); } -int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_nr_t* carrier) +int srslte_dmrs_sch_set_carrier(srslte_dmrs_sch_t* q, const srslte_carrier_nr_t* carrier) { bool max_nof_prb_changed = q->max_nof_prb < carrier->nof_prb; @@ -544,7 +543,7 @@ int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_n } // The maximum number of pilots is for Type 1 - q->pilot_estimates = srslte_vec_cf_malloc(SRSLTE_DMRS_PDSCH_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) { ERROR("malloc\n"); return SRSLTE_ERROR; @@ -554,11 +553,11 @@ int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_n return SRSLTE_SUCCESS; } -int srslte_dmrs_pdsch_put_sf(srslte_dmrs_pdsch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* sf_symbols) +int srslte_dmrs_sch_put_sf(srslte_dmrs_sch_t* q, + const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* sf_symbols) { uint32_t delta = 0; @@ -569,8 +568,8 @@ int srslte_dmrs_pdsch_put_sf(srslte_dmrs_pdsch_t* q, uint32_t symbol_sz = q->carrier.nof_prb * SRSLTE_NRE; // Symbol size in resource elements // Get symbols indexes - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_pdsch_get_symbols_idx(pdsch_cfg, grant, symbols); + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); if (nof_symbols < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -579,29 +578,29 @@ int srslte_dmrs_pdsch_put_sf(srslte_dmrs_pdsch_t* q, for (uint32_t i = 0; i < nof_symbols; i++) { uint32_t l = symbols[i]; // Symbol index inside the slot uint32_t slot_idx = slot_cfg->idx; // Slot index in the frame - uint32_t cinit = srslte_dmrs_pdsch_seed(&q->carrier, pdsch_cfg, grant, slot_idx, l); + uint32_t cinit = srslte_dmrs_sch_seed(&q->carrier, pdsch_cfg, grant, slot_idx, l); - srslte_dmrs_pdsch_put_symbol(q, pdsch_cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l]); + srslte_dmrs_sch_put_symbol(q, pdsch_cfg, grant, cinit, delta, &sf_symbols[symbol_sz * l]); } return SRSLTE_SUCCESS; } -static int srslte_dmrs_pdsch_get_symbol(srslte_dmrs_pdsch_t* q, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t cinit, - uint32_t delta, - const cf_t* symbols, - cf_t* least_square_estimates) +static int srslte_dmrs_sch_get_symbol(srslte_dmrs_sch_t* q, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t cinit, + uint32_t delta, + const cf_t* symbols, + cf_t* least_square_estimates) { - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &pdsch_cfg->dmrs_cfg_typeA : &pdsch_cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; uint32_t prb_count = 0; // Counts consecutive used PRB uint32_t prb_start = 0; // Start consecutive used PRB uint32_t prb_skip = 0; // Number of PRB to skip - uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_pdsch_type_1 ? 6 : 4; + uint32_t nof_pilots_x_prb = dmrs_cfg->type == srslte_dmrs_sch_type_1 ? 6 : 4; uint32_t pilot_count = 0; // Initialise sequence @@ -662,12 +661,12 @@ static int srslte_dmrs_pdsch_get_symbol(srslte_dmrs_pdsch_t* q, return pilot_count; } -int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, - const srslte_dl_slot_cfg_t* slot_cfg, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - const cf_t* sf_symbols, - srslte_chest_dl_res_t* chest_res) +int srslte_dmrs_sch_estimate(srslte_dmrs_sch_t* q, + const srslte_dl_slot_cfg_t* slot_cfg, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + const cf_t* sf_symbols, + srslte_chest_dl_res_t* chest_res) { const uint32_t delta = 0; @@ -675,15 +674,15 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, return SRSLTE_ERROR_INVALID_INPUTS; } - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &pdsch_cfg->dmrs_cfg_typeA : &pdsch_cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; cf_t* ce = q->temp; uint32_t symbol_sz = q->carrier.nof_prb * SRSLTE_NRE; // Symbol size in resource elements // Get symbols indexes - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_pdsch_get_symbols_idx(pdsch_cfg, grant, symbols); + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); if (nof_symbols <= SRSLTE_SUCCESS) { ERROR("Error getting symbol indexes\n"); return SRSLTE_ERROR; @@ -695,9 +694,9 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, for (uint32_t i = 0; i < nof_symbols; i++) { uint32_t l = symbols[i]; // Symbol index inside the slot - uint32_t cinit = srslte_dmrs_pdsch_seed(&q->carrier, pdsch_cfg, grant, slot_cfg->idx, l); + uint32_t cinit = srslte_dmrs_sch_seed(&q->carrier, pdsch_cfg, grant, slot_cfg->idx, l); - nof_pilots_x_symbol = srslte_dmrs_pdsch_get_symbol( + nof_pilots_x_symbol = srslte_dmrs_sch_get_symbol( 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) { @@ -720,8 +719,8 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, // Frequency domain interpolate uint32_t nof_re_x_symbol = - (dmrs_cfg->type == srslte_dmrs_pdsch_type_1) ? nof_pilots_x_symbol * 2 : nof_pilots_x_symbol * 3; - if (dmrs_cfg->type == srslte_dmrs_pdsch_type_1) { + (dmrs_cfg->type == srslte_dmrs_sch_type_1) ? nof_pilots_x_symbol * 2 : nof_pilots_x_symbol * 3; + if (dmrs_cfg->type == srslte_dmrs_sch_type_1) { // Prepare interpolator 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); @@ -753,7 +752,7 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, if (symbols[symbol_idx] == l) { switch (dmrs_cfg->type) { - case srslte_dmrs_pdsch_type_1: + case srslte_dmrs_sch_type_1: // Skip if there is no data to read if (grant->nof_dmrs_cdm_groups_without_data != 1) { continue; @@ -763,7 +762,7 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q, count++; } break; - case srslte_dmrs_pdsch_type_2: + case srslte_dmrs_sch_type_2: // Skip if there is no data to read if (grant->nof_dmrs_cdm_groups_without_data != 1 && grant->nof_dmrs_cdm_groups_without_data != 2) { continue; diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c index 4d5460f9d..00568a422 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c @@ -11,7 +11,7 @@ */ #include "srslte/common/test_common.h" -#include "srslte/phy/ch_estimation/dmrs_pdsch.h" +#include "srslte/phy/ch_estimation/dmrs_sch.h" #include "srslte/phy/ue/ue_dl_nr_data.h" #include "srslte/srslte.h" #include @@ -29,95 +29,95 @@ static srslte_carrier_nr_t carrier = { }; typedef struct { - srslte_pdsch_mapping_type_t mapping_type; - srslte_dmrs_pdsch_typeA_pos_t typeA_pos; - srslte_dmrs_pdsch_len_t max_length; - srslte_dmrs_pdsch_add_pos_t additional_pos; - srslte_dmrs_pdsch_type_t type; - uint32_t symbol_idx[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS]; - uint32_t nof_symbols; - uint32_t sc_idx[SRSLTE_NRE]; - uint32_t nof_sc; + srslte_sch_mapping_type_t mapping_type; + srslte_dmrs_sch_typeA_pos_t typeA_pos; + srslte_dmrs_sch_len_t max_length; + srslte_dmrs_sch_add_pos_t additional_pos; + srslte_dmrs_sch_type_t type; + uint32_t symbol_idx[SRSLTE_DMRS_SCH_MAX_SYMBOLS]; + uint32_t nof_symbols; + uint32_t sc_idx[SRSLTE_NRE]; + uint32_t nof_sc; } golden_t; // Golden values extracted from https://www.sharetechnote.com/html/5G/5G_PDSCH_DMRS.html -static const golden_t gold[] = {{.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_0, - .type = srslte_dmrs_pdsch_type_2, +static const golden_t gold[] = {{.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_0, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 1, .symbol_idx = {2}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_3, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_0, - .type = srslte_dmrs_pdsch_type_2, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_3, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_0, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 1, .symbol_idx = {3}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_2, - .additional_pos = srslte_dmrs_pdsch_add_pos_0, - .type = srslte_dmrs_pdsch_type_2, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_2, + .additional_pos = srslte_dmrs_sch_add_pos_0, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 2, .symbol_idx = {2, 3}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_1, - .type = srslte_dmrs_pdsch_type_2, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_1, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 2, .symbol_idx = {2, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_2, - .type = srslte_dmrs_pdsch_type_2, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_2, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 3, .symbol_idx = {2, 7, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_3, - .type = srslte_dmrs_pdsch_type_2, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_3, + .type = srslte_dmrs_sch_type_2, .nof_symbols = 4, .symbol_idx = {2, 5, 8, 11}, .nof_sc = 4, .sc_idx = {0, 1, 6, 7}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_0, - .type = srslte_dmrs_pdsch_type_1, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_0, + .type = srslte_dmrs_sch_type_1, .nof_symbols = 1, .symbol_idx = {2}, .nof_sc = 6, .sc_idx = {0, 2, 4, 6, 8, 10}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_2, - .additional_pos = srslte_dmrs_pdsch_add_pos_0, - .type = srslte_dmrs_pdsch_type_1, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_2, + .additional_pos = srslte_dmrs_sch_add_pos_0, + .type = srslte_dmrs_sch_type_1, .nof_symbols = 2, .symbol_idx = {2, 3}, .nof_sc = 6, .sc_idx = {0, 2, 4, 6, 8, 10}}, - {.mapping_type = srslte_pdsch_mapping_type_A, - .typeA_pos = srslte_dmrs_pdsch_typeA_pos_2, - .max_length = srslte_dmrs_pdsch_len_1, - .additional_pos = srslte_dmrs_pdsch_add_pos_3, - .type = srslte_dmrs_pdsch_type_1, + {.mapping_type = srslte_sch_mapping_type_A, + .typeA_pos = srslte_dmrs_sch_typeA_pos_2, + .max_length = srslte_dmrs_sch_len_1, + .additional_pos = srslte_dmrs_sch_add_pos_3, + .type = srslte_dmrs_sch_type_1, .nof_symbols = 4, .symbol_idx = {2, 5, 8, 11}, .nof_sc = 6, @@ -156,7 +156,7 @@ static void parse_args(int argc, char** argv) } } -static int assert_cfg(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch_grant_nr_t* grant) +static int assert_cfg(const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant) { for (uint32_t i = 0; gold[i].nof_sc != 0; i++) { // Gold examples are done for more than 12 symbols @@ -168,24 +168,24 @@ static int assert_cfg(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch continue; } - if (pdsch_cfg->dmrs_cfg_typeA.typeA_pos != gold[i].typeA_pos) { + if (pdsch_cfg->dmrs_typeA.typeA_pos != gold[i].typeA_pos) { continue; } - if (pdsch_cfg->dmrs_cfg_typeA.additional_pos != gold[i].additional_pos) { + if (pdsch_cfg->dmrs_typeA.additional_pos != gold[i].additional_pos) { continue; } - if (pdsch_cfg->dmrs_cfg_typeA.length != gold[i].max_length) { + if (pdsch_cfg->dmrs_typeA.length != gold[i].max_length) { continue; } - if (pdsch_cfg->dmrs_cfg_typeA.type != gold[i].type) { + if (pdsch_cfg->dmrs_typeA.type != gold[i].type) { continue; } - uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {}; - int nof_symbols = srslte_dmrs_pdsch_get_symbols_idx(pdsch_cfg, grant, symbols); + uint32_t symbols[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + int nof_symbols = srslte_dmrs_sch_get_symbols_idx(pdsch_cfg, grant, symbols); TESTASSERT(nof_symbols == gold[i].nof_symbols); @@ -194,7 +194,7 @@ static int assert_cfg(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch } uint32_t sc[SRSLTE_NRE] = {}; - srslte_dmrs_pdsch_get_sc_idx(&pdsch_cfg->dmrs_cfg_typeA, SRSLTE_NRE, sc); + srslte_dmrs_sch_get_sc_idx(&pdsch_cfg->dmrs_typeA, SRSLTE_NRE, sc); for (uint32_t j = 0; j < gold[i].nof_sc; j++) { TESTASSERT(sc[j] == gold[i].sc_idx[j]); @@ -206,19 +206,19 @@ static int assert_cfg(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch return SRSLTE_SUCCESS; } -static int run_test(srslte_dmrs_pdsch_t* dmrs_pdsch, - const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* sf_symbols, - srslte_chest_dl_res_t* chest_res) +static int run_test(srslte_dmrs_sch_t* dmrs_pdsch, + const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* sf_symbols, + srslte_chest_dl_res_t* chest_res) { TESTASSERT(assert_cfg(pdsch_cfg, grant) == SRSLTE_SUCCESS); srslte_dl_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++) { - TESTASSERT(srslte_dmrs_pdsch_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); - TESTASSERT(srslte_dmrs_pdsch_estimate(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols, chest_res) == + TESTASSERT(srslte_dmrs_sch_estimate(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols, chest_res) == SRSLTE_SUCCESS); float mse = 0.0f; @@ -241,10 +241,10 @@ int main(int argc, char** argv) parse_args(argc, argv); - srslte_dmrs_pdsch_t dmrs_pdsch = {}; - srslte_pdsch_cfg_nr_t pdsch_cfg = {}; - srslte_pdsch_grant_nr_t grant = {}; - srslte_chest_dl_res_t chest_dl_res = {}; + srslte_dmrs_sch_t dmrs_pdsch = {}; + srslte_sch_cfg_nr_t pdsch_cfg = {}; + srslte_sch_grant_nr_t grant = {}; + srslte_chest_dl_res_t chest_dl_res = {}; uint32_t nof_re = carrier.nof_prb * SRSLTE_NRE * SRSLTE_NOF_SLOTS_PER_SF * SRSLTE_MAX_NSYMB; cf_t* sf_symbols = srslte_vec_cf_malloc(nof_re); @@ -253,13 +253,13 @@ int main(int argc, char** argv) uint32_t test_passed = 0; // Initialise object DMRS for PDSCH - if (srslte_dmrs_pdsch_init(&dmrs_pdsch, true) != SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_init(&dmrs_pdsch, true) != SRSLTE_SUCCESS) { ERROR("Init\n"); goto clean_exit; } // Set carrier configuration - if (srslte_dmrs_pdsch_set_carrier(&dmrs_pdsch, &carrier) != SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_set_carrier(&dmrs_pdsch, &carrier) != SRSLTE_SUCCESS) { ERROR("Setting carrier\n"); goto clean_exit; } @@ -271,38 +271,36 @@ int main(int argc, char** argv) // For each DCI m param for (uint32_t m = 0; m < 16; m++) { - srslte_dmrs_pdsch_type_t type_begin = srslte_dmrs_pdsch_type_1; - srslte_dmrs_pdsch_type_t type_end = srslte_dmrs_pdsch_type_2; + srslte_dmrs_sch_type_t type_begin = srslte_dmrs_sch_type_1; + srslte_dmrs_sch_type_t type_end = srslte_dmrs_sch_type_2; - for (pdsch_cfg.dmrs_cfg_typeA.type = type_begin; pdsch_cfg.dmrs_cfg_typeA.type <= type_end; - pdsch_cfg.dmrs_cfg_typeA.type++) { - srslte_dmrs_pdsch_typeA_pos_t typeA_pos_begin = srslte_dmrs_pdsch_typeA_pos_2; - srslte_dmrs_pdsch_typeA_pos_t typeA_pos_end = srslte_dmrs_pdsch_typeA_pos_3; + for (pdsch_cfg.dmrs_typeA.type = type_begin; pdsch_cfg.dmrs_typeA.type <= type_end; pdsch_cfg.dmrs_typeA.type++) { + srslte_dmrs_sch_typeA_pos_t typeA_pos_begin = srslte_dmrs_sch_typeA_pos_2; + srslte_dmrs_sch_typeA_pos_t typeA_pos_end = srslte_dmrs_sch_typeA_pos_3; - for (pdsch_cfg.dmrs_cfg_typeA.typeA_pos = typeA_pos_begin; pdsch_cfg.dmrs_cfg_typeA.typeA_pos <= typeA_pos_end; - pdsch_cfg.dmrs_cfg_typeA.typeA_pos++) { - srslte_dmrs_pdsch_add_pos_t add_pos_begin = srslte_dmrs_pdsch_add_pos_2; - srslte_dmrs_pdsch_add_pos_t add_pos_end = srslte_dmrs_pdsch_add_pos_3; + for (pdsch_cfg.dmrs_typeA.typeA_pos = typeA_pos_begin; pdsch_cfg.dmrs_typeA.typeA_pos <= typeA_pos_end; + pdsch_cfg.dmrs_typeA.typeA_pos++) { + srslte_dmrs_sch_add_pos_t add_pos_begin = srslte_dmrs_sch_add_pos_2; + srslte_dmrs_sch_add_pos_t add_pos_end = srslte_dmrs_sch_add_pos_3; - if (pdsch_cfg.dmrs_cfg_typeA.typeA_pos == srslte_dmrs_pdsch_typeA_pos_3) { - add_pos_end = srslte_dmrs_pdsch_add_pos_1; + if (pdsch_cfg.dmrs_typeA.typeA_pos == srslte_dmrs_sch_typeA_pos_3) { + add_pos_end = srslte_dmrs_sch_add_pos_1; } - for (pdsch_cfg.dmrs_cfg_typeA.additional_pos = add_pos_begin; - pdsch_cfg.dmrs_cfg_typeA.additional_pos <= add_pos_end; - pdsch_cfg.dmrs_cfg_typeA.additional_pos++) { + for (pdsch_cfg.dmrs_typeA.additional_pos = add_pos_begin; pdsch_cfg.dmrs_typeA.additional_pos <= add_pos_end; + pdsch_cfg.dmrs_typeA.additional_pos++) { - srslte_dmrs_pdsch_len_t max_len_begin = srslte_dmrs_pdsch_len_1; - srslte_dmrs_pdsch_len_t max_len_end = srslte_dmrs_pdsch_len_2; + 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; // Only single DMRS symbols can have additional positions 2 and 3 - if (pdsch_cfg.dmrs_cfg_typeA.additional_pos == srslte_dmrs_pdsch_add_pos_2 || - pdsch_cfg.dmrs_cfg_typeA.additional_pos == srslte_dmrs_pdsch_add_pos_3) { - max_len_end = srslte_dmrs_pdsch_len_1; + if (pdsch_cfg.dmrs_typeA.additional_pos == srslte_dmrs_sch_add_pos_2 || + pdsch_cfg.dmrs_typeA.additional_pos == srslte_dmrs_sch_add_pos_3) { + max_len_end = srslte_dmrs_sch_len_1; } - for (pdsch_cfg.dmrs_cfg_typeA.length = max_len_begin; pdsch_cfg.dmrs_cfg_typeA.length <= max_len_end; - pdsch_cfg.dmrs_cfg_typeA.length++) { + for (pdsch_cfg.dmrs_typeA.length = max_len_begin; pdsch_cfg.dmrs_typeA.length <= max_len_end; + pdsch_cfg.dmrs_typeA.length++) { for (uint32_t bw = 1; bw <= carrier.nof_prb; bw++) { @@ -314,22 +312,21 @@ int main(int argc, char** argv) grant.nof_dmrs_cdm_groups_without_data++) { // Load default type A grant - srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &grant); + srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &grant); // Copy configuration - pdsch_cfg.dmrs_cfg_typeB = pdsch_cfg.dmrs_cfg_typeA; + pdsch_cfg.dmrs_typeB = pdsch_cfg.dmrs_typeA; int n = run_test(&dmrs_pdsch, &pdsch_cfg, &grant, sf_symbols, &chest_dl_res); if (n == SRSLTE_SUCCESS) { test_passed++; } else { - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = grant.mapping == srslte_pdsch_mapping_type_A - ? &pdsch_cfg.dmrs_cfg_typeA - : &pdsch_cfg.dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant.mapping == srslte_sch_mapping_type_A ? &pdsch_cfg.dmrs_typeA : &pdsch_cfg.dmrs_typeB; char str[64] = {}; - srslte_dmrs_pdsch_cfg_to_str(dmrs_cfg, str, 64); + srslte_dmrs_sch_cfg_to_str(dmrs_cfg, str, 64); ERROR("Test %d failed. %s.\n", test_counter, str); } @@ -349,7 +346,7 @@ clean_exit: free(sf_symbols); } srslte_chest_dl_res_free(&chest_dl_res); - srslte_dmrs_pdsch_free(&dmrs_pdsch); + srslte_dmrs_sch_free(&dmrs_pdsch); ret = test_passed == test_counter ? SRSLTE_SUCCESS : SRSLTE_ERROR; printf("%s, %d of %d test passed successfully.\n", ret ? "Failed" : "Passed", test_passed, test_counter); diff --git a/lib/src/phy/common/phy_common_nr.c b/lib/src/phy/common/phy_common_nr.c index 86e5b2c41..37cc6e51c 100644 --- a/lib/src/phy/common/phy_common_nr.c +++ b/lib/src/phy/common/phy_common_nr.c @@ -35,12 +35,12 @@ uint32_t srslte_coreset_get_sz(const srslte_coreset_t* coreset) return srslte_coreset_get_bw(coreset) * SRSLTE_NRE * coreset->duration; } -const char* srslte_pdsch_mapping_type_to_str(srslte_pdsch_mapping_type_t mapping_type) +const char* srslte_sch_mapping_type_to_str(srslte_sch_mapping_type_t mapping_type) { switch (mapping_type) { - case srslte_pdsch_mapping_type_A: + case srslte_sch_mapping_type_A: return "A"; - case srslte_pdsch_mapping_type_B: + case srslte_sch_mapping_type_B: return "B"; default: return "undefined"; diff --git a/lib/src/phy/enb/enb_dl_nr.c b/lib/src/phy/enb/enb_dl_nr.c index b16773e96..2f7a4a542 100644 --- a/lib/src/phy/enb/enb_dl_nr.c +++ b/lib/src/phy/enb/enb_dl_nr.c @@ -66,7 +66,7 @@ int srslte_enb_dl_nr_init(srslte_enb_dl_nr_t* q, cf_t* output[SRSLTE_MAX_PORTS], srslte_ofdm_tx_init_cfg(&q->fft[i], &fft_cfg); } - if (srslte_dmrs_pdsch_init(&q->dmrs, false) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_init(&q->dmrs, false) < SRSLTE_SUCCESS) { ERROR("Error DMRS\n"); return SRSLTE_ERROR; } @@ -94,7 +94,7 @@ void srslte_enb_dl_nr_free(srslte_enb_dl_nr_t* q) } srslte_pdsch_nr_free(&q->pdsch); - srslte_dmrs_pdsch_free(&q->dmrs); + srslte_dmrs_sch_free(&q->dmrs); srslte_pdcch_nr_free(&q->pdcch); @@ -107,7 +107,7 @@ int srslte_enb_dl_nr_set_carrier(srslte_enb_dl_nr_t* q, const srslte_carrier_nr_ return SRSLTE_ERROR; } - if (srslte_dmrs_pdsch_set_carrier(&q->dmrs, carrier) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_set_carrier(&q->dmrs, carrier) < SRSLTE_SUCCESS) { ERROR("Error DMRS\n"); return SRSLTE_ERROR; } @@ -213,14 +213,14 @@ int srslte_enb_dl_nr_pdcch_put(srslte_enb_dl_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB]) +int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, + const srslte_dl_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB]) { - if (srslte_dmrs_pdsch_put_sf(&q->dmrs, slot, cfg, grant, q->sf_symbols[0]) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_put_sf(&q->dmrs, slot, cfg, grant, q->sf_symbols[0]) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -231,11 +231,11 @@ int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - char* str, - uint32_t str_len) +int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len) { int len = 0; diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 35501f946..a6d79e926 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -198,11 +198,11 @@ static void srslte_pdsch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, * - 1, data is mapped in RE marked as 2 * - Otherwise, no data is mapped in this symbol */ -static uint32_t srslte_pdsch_nr_cp_dmrs_type1(const srslte_pdsch_nr_t* q, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols, - bool put) +static uint32_t srslte_pdsch_nr_cp_dmrs_type1(const srslte_pdsch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) { uint32_t count = 0; uint32_t delta = 0; @@ -239,11 +239,11 @@ static uint32_t srslte_pdsch_nr_cp_dmrs_type1(const srslte_pdsch_nr_t* q, * - 2, data is mapped in RE marked as 3 * - otherwise, no data is mapped in this symbol */ -static uint32_t srslte_pdsch_nr_cp_dmrs_type2(const srslte_pdsch_nr_t* q, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols, - bool put) +static uint32_t srslte_pdsch_nr_cp_dmrs_type2(const srslte_pdsch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) { uint32_t count = 0; @@ -269,23 +269,23 @@ static uint32_t srslte_pdsch_nr_cp_dmrs_type2(const srslte_pdsch_nr_t* q, return count; } -static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols, - bool put) +static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) { uint32_t count = 0; - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; switch (dmrs_cfg->type) { - case srslte_dmrs_pdsch_type_1: + case srslte_dmrs_sch_type_1: count = srslte_pdsch_nr_cp_dmrs_type1(q, grant, symbols, sf_symbols, put); break; - case srslte_dmrs_pdsch_type_2: + case srslte_dmrs_sch_type_2: count = srslte_pdsch_nr_cp_dmrs_type2(q, grant, symbols, sf_symbols, put); break; } @@ -293,11 +293,11 @@ static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q, return count; } -static uint32_t srslte_pdsch_nr_cp_clean(const srslte_pdsch_nr_t* q, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols, - bool put) +static uint32_t srslte_pdsch_nr_cp_clean(const srslte_pdsch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) { uint32_t count = 0; uint32_t start = 0; // Index of the start of continuous data @@ -339,19 +339,19 @@ static uint32_t srslte_pdsch_nr_cp_clean(const srslte_pdsch_nr_t* q, return count; } -static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols, - bool put) +static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) { - uint32_t count = 0; - uint32_t dmrs_l_idx[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {}; - uint32_t dmrs_l_count = 0; + uint32_t count = 0; + uint32_t dmrs_l_idx[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + uint32_t dmrs_l_count = 0; // Get symbol indexes carrying DMRS - int32_t nof_dmrs_symbols = srslte_dmrs_pdsch_get_symbols_idx(cfg, grant, dmrs_l_idx); + int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(cfg, grant, dmrs_l_idx); if (nof_dmrs_symbols < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -381,26 +381,26 @@ static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q, return count; } -static int srslte_pdsch_nr_put(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols) +static int srslte_pdsch_nr_put(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols) { return srslte_pdsch_nr_cp(q, cfg, grant, symbols, sf_symbols, true); } -static int srslte_pdsch_nr_get(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - cf_t* symbols, - cf_t* sf_symbols) +static int srslte_pdsch_nr_get(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols) { return srslte_pdsch_nr_cp(q, cfg, grant, symbols, sf_symbols, false); } static uint32_t -pdsch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_pdsch_cfg_nr_t* cfg, uint16_t rnti, uint32_t cw_idx) +pdsch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cfg, uint16_t rnti, uint32_t cw_idx) { uint32_t n_id = carrier->id; if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) { @@ -413,11 +413,11 @@ pdsch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_pdsch_cfg_nr_t* return cinit; } -static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_sch_tb_t* tb, - const uint8_t* data, - uint16_t rnti) +static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint16_t rnti) { // Early return if TB is not enabled if (!tb->enabled) { @@ -462,11 +462,11 @@ static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - uint8_t* data[SRSLTE_MAX_TB], - cf_t* sf_symbols[SRSLTE_MAX_PORTS]) +int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB], + cf_t* sf_symbols[SRSLTE_MAX_PORTS]) { // Check input pointers @@ -530,11 +530,11 @@ int srslte_pdsch_nr_encode(srslte_pdsch_nr_t* q, return SRSLTE_SUCCESS; } -static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_sch_tb_t* tb, - srslte_pdsch_res_nr_t* res, - uint16_t rnti) +static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_tb_t* tb, + srslte_pdsch_res_nr_t* res, + uint16_t rnti) { // Early return if TB is not enabled if (!tb->enabled) { @@ -591,12 +591,12 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - srslte_chest_dl_res_t* channel, - cf_t* sf_symbols[SRSLTE_MAX_PORTS], - srslte_pdsch_res_nr_t data[SRSLTE_MAX_TB]) +int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_chest_dl_res_t* channel, + cf_t* sf_symbols[SRSLTE_MAX_PORTS], + srslte_pdsch_res_nr_t data[SRSLTE_MAX_TB]) { // Check input pointers if (!q || !cfg || !grant || !data || !sf_symbols) { @@ -666,10 +666,10 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q, return SRSLTE_SUCCESS; } -static uint32_t srslte_pdsch_nr_grant_info(const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - char* str, - uint32_t str_len) +static uint32_t srslte_pdsch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len) { uint32_t len = 0; len = srslte_print_check(str, str_len, len, "rnti=0x%x", grant->rnti); @@ -682,7 +682,7 @@ static uint32_t srslte_pdsch_nr_grant_info(const srslte_pdsch_cfg_nr_t* cfg, grant->k0, grant->S, grant->L, - srslte_pdsch_mapping_type_to_str(grant->mapping)); + srslte_sch_mapping_type_to_str(grant->mapping)); // Skip frequency domain resources... // ... @@ -701,12 +701,12 @@ static uint32_t srslte_pdsch_nr_grant_info(const srslte_pdsch_cfg_nr_t* cfg, return len; } -uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], - char* str, - uint32_t str_len) +uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pdsch_res_nr_t res[SRSLTE_MAX_CODEWORDS], + char* str, + uint32_t str_len) { uint32_t len = 0; @@ -750,11 +750,11 @@ uint32_t srslte_pdsch_nr_rx_info(const srslte_pdsch_nr_t* q, return len; } -uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - char* str, - uint32_t str_len) +uint32_t srslte_pdsch_nr_tx_info(const srslte_pdsch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len) { uint32_t len = 0; diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c new file mode 100644 index 000000000..0d391d804 --- /dev/null +++ b/lib/src/phy/phch/pusch_nr.c @@ -0,0 +1,769 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srslte/phy/phch/pusch_nr.h" +#include "srslte/phy/common/phy_common_nr.h" +#include "srslte/phy/phch/ra_nr.h" + +int pusch_nr_init_common(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) +{ + for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) { + if (srslte_modem_table_lte(&q->modem_tables[mod], mod) < SRSLTE_SUCCESS) { + ERROR("Error initialising modem table for %s\n", srslte_mod_string(mod)); + return SRSLTE_ERROR; + } + if (args->measure_evm) { + srslte_modem_table_bytes(&q->modem_tables[mod]); + } + } + + return SRSLTE_SUCCESS; +} + +int srslte_pusch_nr_init_enb(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) +{ + if (q == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (pusch_nr_init_common(q, args) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + if (srslte_sch_nr_init_tx(&q->sch, &args->sch)) { + ERROR("Initialising SCH\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_pusch_nr_init_ue(srslte_pusch_nr_t* q, const srslte_pusch_nr_args_t* args) +{ + if (q == NULL || args == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (pusch_nr_init_common(q, args) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + if (srslte_sch_nr_init_rx(&q->sch, &args->sch)) { + ERROR("Initialising SCH\n"); + return SRSLTE_ERROR; + } + + if (args->measure_evm) { + q->evm_buffer = srslte_evm_buffer_alloc(8); + if (q->evm_buffer == NULL) { + ERROR("Initialising EVM\n"); + return SRSLTE_ERROR; + } + } + + q->meas_time_en = args->measure_time; + + return SRSLTE_SUCCESS; +} + +int srslte_pusch_nr_set_carrier(srslte_pusch_nr_t* q, const srslte_carrier_nr_t* carrier) +{ + // Set carrier + q->carrier = *carrier; + + // Reallocate symbols if necessary + if (q->max_layers < carrier->max_mimo_layers || q->max_prb < carrier->nof_prb) { + q->max_layers = carrier->max_mimo_layers; + q->max_prb = carrier->nof_prb; + + // Free current allocations + for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) { + if (q->x[i] != NULL) { + free(q->x[i]); + } + } + + // Allocate for new sizes + for (uint32_t i = 0; i < q->max_layers; i++) { + q->x[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(q->max_prb)); + if (q->x[i] == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + } + } + + // Allocate code words according to table 7.3.1.3-1 + uint32_t max_cw = (q->max_layers > 5) ? 2 : 1; + if (q->max_cw < max_cw) { + q->max_cw = max_cw; + + for (uint32_t i = 0; i < max_cw; i++) { + if (q->b[i] == NULL) { + q->b[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + if (q->b[i] == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + } + + if (q->d[i] == NULL) { + q->d[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_MAX_LEN_RE_NR); + if (q->d[i] == NULL) { + ERROR("Malloc"); + return SRSLTE_ERROR; + } + } + } + } + + // Set carrier in SCH + if (srslte_sch_nr_set_carrier(&q->sch, carrier) < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + if (q->evm_buffer != NULL) { + srslte_evm_buffer_resize(q->evm_buffer, SRSLTE_SLOT_LEN_RE_NR(q->max_prb) * SRSLTE_MAX_QM); + } + + return SRSLTE_SUCCESS; +} + +void srslte_pusch_nr_free(srslte_pusch_nr_t* q) +{ + if (q == NULL) { + return; + } + + for (uint32_t cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) { + if (q->b[cw]) { + free(q->b[cw]); + } + + if (q->d[cw]) { + free(q->d[cw]); + } + } + + srslte_sch_nr_free(&q->sch); + + for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) { + if (q->x[i]) { + free(q->x[i]); + } + } + + for (srslte_mod_t mod = SRSLTE_MOD_BPSK; mod < SRSLTE_MOD_NITEMS; mod++) { + srslte_modem_table_free(&q->modem_tables[mod]); + } + + if (q->evm_buffer != NULL) { + srslte_evm_free(q->evm_buffer); + } +} + +/** + * @brief copies a number of countiguous Resource Elements + * @param sf_symbols slot symbols in frequency domain + * @param symbols resource elements + * @param count number of resource elements to copy + * @param put Direction, symbols are copied into sf_symbols if put is true, otherwise sf_symbols are copied into symbols + */ +static void srslte_pusch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, bool put) +{ + if (put) { + srslte_vec_cf_copy(sf_symbols, symbols, count); + } else { + srslte_vec_cf_copy(symbols, sf_symbols, count); + } +} + +/* + * As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with group 2: + * + * +---+---+---+---+---+---+---+---+---+---+---+---+ + * | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | + * +---+---+---+---+---+---+---+---+---+---+---+---+ + * -- k --> + * + * If the number of DMRS CDM groups without data is set to: + * - 1, data is mapped in RE marked as 2 + * - Otherwise, no data is mapped in this symbol + */ +static uint32_t srslte_pusch_nr_cp_dmrs_type1(const srslte_pusch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) +{ + uint32_t count = 0; + uint32_t delta = 0; + + if (grant->nof_dmrs_cdm_groups_without_data != 1) { + return count; + } + + for (uint32_t i = 0; i < q->carrier.nof_prb; i++) { + if (grant->prb_idx[i]) { + for (uint32_t j = 0; j < SRSLTE_NRE; j += 2) { + if (put) { + sf_symbols[i * SRSLTE_NRE + delta + j + 1] = symbols[count++]; + } else { + symbols[count++] = sf_symbols[i * SRSLTE_NRE + delta + j + 1]; + } + } + } + } + + return count; +} + +/* + * As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with groups 2 and 3: + * + * +---+---+---+---+---+---+---+---+---+---+---+---+ + * | 1 | 1 | 2 | 2 | 3 | 3 | 1 | 1 | 2 | 2 | 3 | 3 | + * +---+---+---+---+---+---+---+---+---+---+---+---+ + * -- k --> + * + * If the number of DMRS CDM groups without data is set to: + * - 1, data is mapped in RE marked as 2 and 3 + * - 2, data is mapped in RE marked as 3 + * - otherwise, no data is mapped in this symbol + */ +static uint32_t srslte_pusch_nr_cp_dmrs_type2(const srslte_pusch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) +{ + uint32_t count = 0; + + if (grant->nof_dmrs_cdm_groups_without_data != 1 && grant->nof_dmrs_cdm_groups_without_data != 2) { + return count; + } + + uint32_t re_offset = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 2 : 4; + uint32_t re_count = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 4 : 2; + + for (uint32_t i = 0; i < q->carrier.nof_prb; i++) { + if (grant->prb_idx[i]) { + // Copy RE between pilot pairs + srslte_pusch_re_cp(&sf_symbols[i * SRSLTE_NRE + re_offset], &symbols[count], re_count, put); + count += re_count; + + // Copy RE after second pilot + srslte_pusch_re_cp(&sf_symbols[(i + 1) * SRSLTE_NRE - re_count], &symbols[count], re_count, put); + count += re_count; + } + } + + return count; +} + +static uint32_t srslte_pusch_nr_cp_dmrs(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) +{ + uint32_t count = 0; + + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &cfg->dmrs_typeA : &cfg->dmrs_typeB; + + switch (dmrs_cfg->type) { + case srslte_dmrs_sch_type_1: + count = srslte_pusch_nr_cp_dmrs_type1(q, grant, symbols, sf_symbols, put); + break; + case srslte_dmrs_sch_type_2: + count = srslte_pusch_nr_cp_dmrs_type2(q, grant, symbols, sf_symbols, put); + break; + } + + return count; +} + +static uint32_t srslte_pusch_nr_cp_clean(const srslte_pusch_nr_t* q, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) +{ + uint32_t count = 0; + uint32_t start = 0; // Index of the start of continuous data + uint32_t length = 0; // End of continuous RE + + for (uint32_t i = 0; i < q->carrier.nof_prb; i++) { + if (grant->prb_idx[i]) { + // If fist continuous block, save start + if (length == 0) { + start = i * SRSLTE_NRE; + } + length += SRSLTE_NRE; + } else { + // Consecutive block is finished + if (put) { + srslte_vec_cf_copy(&sf_symbols[start], &symbols[count], length); + } else { + srslte_vec_cf_copy(&symbols[count], &sf_symbols[start], length); + } + + // Increase RE count + count += length; + + // Reset consecutive block + length = 0; + } + } + + // Copy last contiguous block + if (length > 0) { + if (put) { + srslte_vec_cf_copy(&sf_symbols[start], &symbols[count], length); + } else { + srslte_vec_cf_copy(&symbols[count], &sf_symbols[start], length); + } + count += length; + } + + return count; +} + +static int srslte_pusch_nr_cp(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols, + bool put) +{ + uint32_t count = 0; + uint32_t dmrs_l_idx[SRSLTE_DMRS_SCH_MAX_SYMBOLS] = {}; + uint32_t dmrs_l_count = 0; + + // Get symbol indexes carrying DMRS + int32_t nof_dmrs_symbols = srslte_dmrs_sch_get_symbols_idx(cfg, grant, dmrs_l_idx); + if (nof_dmrs_symbols < SRSLTE_SUCCESS) { + return SRSLTE_ERROR; + } + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("dmrs_l_idx="); + srslte_vec_fprint_i(stdout, (int32_t*)dmrs_l_idx, nof_dmrs_symbols); + } + + for (uint32_t l = grant->S; l < grant->S + grant->L; l++) { + // Advance DMRS symbol counter until: + // - the current DMRS symbol index is greater or equal than current symbol l + // - no more DMRS symbols + while (dmrs_l_idx[dmrs_l_count] < l && dmrs_l_count < nof_dmrs_symbols) { + dmrs_l_count++; + } + + if (l == dmrs_l_idx[dmrs_l_count]) { + count += srslte_pusch_nr_cp_dmrs( + q, cfg, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put); + } else { + count += + srslte_pusch_nr_cp_clean(q, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put); + } + } + + return count; +} + +static int srslte_pusch_nr_put(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols) +{ + return srslte_pusch_nr_cp(q, cfg, grant, symbols, sf_symbols, true); +} + +static int srslte_pusch_nr_get(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + cf_t* symbols, + cf_t* sf_symbols) +{ + return srslte_pusch_nr_cp(q, cfg, grant, symbols, sf_symbols, false); +} + +static uint32_t +pusch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_sch_cfg_nr_t* cfg, uint16_t rnti, uint32_t cw_idx) +{ + uint32_t n_id = carrier->id; + if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) { + n_id = cfg->scambling_id; + } + uint32_t cinit = (((uint32_t)rnti) << 15U) + (cw_idx << 14U) + n_id; + + INFO("PUSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);\n", rnti, rnti, n_id, cinit, cinit); + + return cinit; +} + +static inline int pusch_nr_encode_codeword(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint16_t rnti) +{ + // Early return if TB is not enabled + if (!tb->enabled) { + return SRSLTE_SUCCESS; + } + + // Check codeword index + if (tb->cw_idx >= q->max_cw) { + ERROR("Unsupported codeword index %d\n", tb->cw_idx); + return SRSLTE_ERROR; + } + + // Check modulation + if (tb->mod >= SRSLTE_MOD_NITEMS) { + ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + return SRSLTE_ERROR_OUT_OF_BOUNDS; + } + + // Encode SCH + if (srslte_ulsch_nr_encode(&q->sch, &cfg->sch_cfg, tb, data, q->b[tb->cw_idx]) < SRSLTE_SUCCESS) { + ERROR("Error in DL-SCH encoding\n"); + return SRSLTE_ERROR; + } + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("b="); + srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits); + } + + // 7.3.1.1 Scrambling + uint32_t cinit = pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx); + srslte_sequence_apply_bit(q->b[tb->cw_idx], q->b[tb->cw_idx], tb->nof_bits, cinit); + + // 7.3.1.2 Modulation + srslte_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], tb->nof_bits); + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("d="); + srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re); + } + + return SRSLTE_SUCCESS; +} + +int srslte_pusch_nr_encode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + uint8_t* data[SRSLTE_MAX_TB], + cf_t* sf_symbols[SRSLTE_MAX_PORTS]) +{ + + // Check input pointers + if (!q || !cfg || !grant || !data || !sf_symbols) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + struct timeval t[3]; + if (q->meas_time_en) { + gettimeofday(&t[1], NULL); + } + + // Check number of layers + if (q->max_layers < grant->nof_layers) { + ERROR("Error number of layers (%d) exceeds configured maximum (%d)\n", grant->nof_layers, q->max_layers); + return SRSLTE_ERROR; + } + + // 7.3.1.1 and 7.3.1.2 + uint32_t nof_cw = 0; + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + nof_cw += grant->tb[tb].enabled ? 1 : 0; + + if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb], grant->rnti) < SRSLTE_SUCCESS) { + ERROR("Error encoding TB %d\n", tb); + return SRSLTE_ERROR; + } + } + + // 7.3.1.3 Layer mapping + cf_t** x = q->d; + if (grant->nof_layers > 1) { + x = q->x; + srslte_layermap_nr(q->d, nof_cw, x, grant->nof_layers, grant->nof_layers); + } + + // 7.3.1.4 Antenna port mapping + // ... Not implemented + + // 7.3.1.5 Mapping to virtual resource blocks + // ... Not implemented + + // 7.3.1.6 Mapping from virtual to physical resource blocks + int n = srslte_pusch_nr_put(q, cfg, grant, x[0], sf_symbols[0]); + if (n < SRSLTE_SUCCESS) { + ERROR("Putting NR PUSCH resources\n"); + return SRSLTE_ERROR; + } + + if (n != grant->tb[0].nof_re) { + ERROR("Unmatched number of RE (%d != %d)\n", n, grant->tb[0].nof_re); + return SRSLTE_ERROR; + } + + if (q->meas_time_en) { + gettimeofday(&t[2], NULL); + get_time_interval(t); + q->meas_time_us = (uint32_t)t[0].tv_usec; + } + + return SRSLTE_SUCCESS; +} + +static inline int pusch_nr_decode_codeword(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_tb_t* tb, + srslte_pusch_res_nr_t* res, + uint16_t rnti) +{ + // Early return if TB is not enabled + if (!tb->enabled) { + return SRSLTE_SUCCESS; + } + + // Check codeword index + if (tb->cw_idx >= q->max_cw) { + ERROR("Unsupported codeword index %d\n", tb->cw_idx); + return SRSLTE_ERROR; + } + + // Check modulation + if (tb->mod >= SRSLTE_MOD_NITEMS) { + ERROR("Invalid modulation %s\n", srslte_mod_string(tb->mod)); + return SRSLTE_ERROR_OUT_OF_BOUNDS; + } + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("d="); + srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re); + } + + // Demodulation + int8_t* llr = (int8_t*)q->b[tb->cw_idx]; + if (srslte_demod_soft_demodulate_b(tb->mod, q->d[tb->cw_idx], llr, tb->nof_re)) { + return SRSLTE_ERROR; + } + + // EVM + if (q->evm_buffer != NULL) { + res->evm = srslte_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); + } + + // Change LLR sign + for (uint32_t i = 0; i < tb->nof_bits; i++) { + llr[i] = -llr[i]; + } + + // Descrambling + srslte_sequence_apply_c(llr, llr, tb->nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx)); + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("b="); + srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits); + } + + // Decode SCH + if (srslte_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSLTE_SUCCESS) { + ERROR("Error in DL-SCH encoding\n"); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; +} + +int srslte_pusch_nr_decode(srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_chest_dl_res_t* channel, + cf_t* sf_symbols[SRSLTE_MAX_PORTS], + srslte_pusch_res_nr_t data[SRSLTE_MAX_TB]) +{ + // Check input pointers + if (!q || !cfg || !grant || !data || !sf_symbols) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + struct timeval t[3]; + if (q->meas_time_en) { + gettimeofday(&t[1], NULL); + } + + uint32_t nof_cw = 0; + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + nof_cw += grant->tb[tb].enabled ? 1 : 0; + } + + uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(cfg, grant); + + if (channel->nof_re != nof_re) { + ERROR("Inconsistent number of RE (%d!=%d)\n", channel->nof_re, nof_re); + return SRSLTE_ERROR; + } + + // Demapping from virtual to physical resource blocks + uint32_t nof_re_get = srslte_pusch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]); + if (nof_re_get != nof_re) { + ERROR("Inconsistent number of RE (%d!=%d)\n", nof_re_get, nof_re); + return SRSLTE_ERROR; + } + + if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) { + DEBUG("ce="); + srslte_vec_fprint_c(stdout, channel->ce[0][0], nof_re); + DEBUG("x="); + srslte_vec_fprint_c(stdout, q->x[0], nof_re); + } + + // Demapping to virtual resource blocks + // ... Not implemented + + // Antenna port demapping + // ... Not implemented + srslte_predecoding_type( + q->x, channel->ce, q->d, NULL, 1, 1, 1, 0, nof_re, SRSLTE_TXSCHEME_PORT0, 1.0f, channel->noise_estimate); + + // Layer demapping + if (grant->nof_layers > 1) { + srslte_layerdemap_nr(q->d, nof_cw, q->x, grant->nof_layers, nof_re); + } + + // SCH decode + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + nof_cw += grant->tb[tb].enabled ? 1 : 0; + + if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSLTE_SUCCESS) { + ERROR("Error encoding TB %d\n", tb); + return SRSLTE_ERROR; + } + } + + if (q->meas_time_en) { + gettimeofday(&t[2], NULL); + get_time_interval(t); + q->meas_time_us = (uint32_t)t[0].tv_usec; + } + + return SRSLTE_SUCCESS; +} + +static uint32_t srslte_pusch_nr_grant_info(const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len) +{ + uint32_t len = 0; + len = srslte_print_check(str, str_len, len, "rnti=0x%x", grant->rnti); + + // Append time-domain resource mapping + len = srslte_print_check(str, + str_len, + len, + ",k0=%d,S=%d,L=%d,mapping=%s", + grant->k0, + grant->S, + grant->L, + srslte_sch_mapping_type_to_str(grant->mapping)); + + // Skip frequency domain resources... + // ... + + // Append spatial resources + len = srslte_print_check(str, str_len, len, ",Nl=%d", grant->nof_layers); + + // Append scrambling ID + len = srslte_print_check(str, str_len, len, ",n_scid=%d,", grant->n_scid); + + // Append TB info + for (uint32_t i = 0; i < SRSLTE_MAX_TB; i++) { + len += srslte_sch_nr_tb_info(&grant->tb[i], &str[len], str_len - len); + } + + return len; +} + +uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pusch_res_nr_t res[SRSLTE_MAX_CODEWORDS], + char* str, + uint32_t str_len) +{ + + uint32_t len = 0; + + len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); + + if (q->evm_buffer != NULL) { + len = srslte_print_check(str, str_len, len, ",evm={", 0); + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant->tb[i].enabled && !isnan(res[i].evm)) { + len = srslte_print_check(str, str_len, len, "%.2f", res[i].evm); + if (i < SRSLTE_MAX_CODEWORDS - 1) { + if (grant->tb[i + 1].enabled) { + len = srslte_print_check(str, str_len, len, ",", 0); + } + } + } + } + len = srslte_print_check(str, str_len, len, "}", 0); + } + + if (res != NULL) { + len = srslte_print_check(str, str_len, len, ",crc={", 0); + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (grant->tb[i].enabled) { + len = srslte_print_check(str, str_len, len, "%s", res[i].crc ? "OK" : "KO"); + if (i < SRSLTE_MAX_CODEWORDS - 1) { + if (grant->tb[i + 1].enabled) { + len = srslte_print_check(str, str_len, len, ",", 0); + } + } + } + } + len = srslte_print_check(str, str_len, len, "}", 0); + } + + if (q->meas_time_en) { + len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + } + + return len; +} + +uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + char* str, + uint32_t str_len) +{ + + uint32_t len = 0; + + len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); + + if (q->meas_time_en) { + len = srslte_print_check(str, str_len, len, ", t=%d us\n", q->meas_time_us); + } + + return len; +} diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 0fe8a71e6..9ad8f5a37 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -108,10 +108,63 @@ static const uint32_t ra_nr_tbs_table[RA_NR_TBS_SIZE_TABLE] = { typedef enum { ra_nr_table_1 = 0, ra_nr_table_2, ra_nr_table_3 } ra_nr_table_t; -static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table, - srslte_dci_format_nr_t dci_format, - srslte_search_space_type_t search_space_type, - srslte_rnti_type_t rnti_type) +static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srslte_mcs_table_t mcs_table, + srslte_dci_format_nr_t dci_format, + srslte_search_space_type_t search_space_type, + srslte_rnti_type_t rnti_type) +{ + // Non-implemented parameters + bool mcs_c_rnti = false; + srslte_mcs_table_t configured_grant_table = srslte_mcs_table_64qam; + + // - if mcs-Table in pusch-Config is set to 'qam256', and + // - PUSCH is scheduled by a PDCCH with DCI format 0_1 with + // - CRC scrambled by C-RNTI or SP-CSI-RNTI, + if (mcs_table == srslte_mcs_table_256qam && dci_format == srslte_dci_format_nr_0_1 && + (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_sp_csi)) { + return ra_nr_table_2; + } + + // - the UE is not configured with MCS-C-RNTI, + // - mcs-Table in pusch-Config is set to 'qam64LowSE', and the + // - PUSCH is scheduled by a PDCCH in a UE-specific search space with + // - CRC scrambled by C-RNTI or SP-CSI-RNTI, + if (!mcs_c_rnti && mcs_table == srslte_mcs_table_qam64LowSE && dci_format != srslte_dci_format_nr_rar && + search_space_type == srslte_search_space_type_ue && + (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_sp_csi)) { + return ra_nr_table_3; + } + + // - the UE is configured with MCS-C-RNTI, and + // - the PUSCH is scheduled by a PDCCH with + // - CRC scrambled by MCS-C-RNTI, + if (mcs_c_rnti && dci_format != srslte_dci_format_nr_rar && rnti_type == srslte_rnti_type_mcs_crnti) { + return ra_nr_table_3; + } + + // - mcs-Table in configuredGrantConfig is set to 'qam256', + // - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or + // - if PUSCH is transmitted with configured grant + if (configured_grant_table == srslte_mcs_table_256qam && + (rnti_type == srslte_rnti_type_cs || dci_format == srslte_dci_format_nr_cg)) { + return ra_nr_table_2; + } + + // - mcs-Table in configuredGrantConfig is set to 'qam64LowSE' + // - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or + // - if PUSCH is transmitted with configured grant, + if (configured_grant_table == srslte_mcs_table_qam64LowSE && + (rnti_type == srslte_rnti_type_cs || dci_format == srslte_dci_format_nr_cg)) { + return ra_nr_table_3; + } + + return ra_nr_table_1; +} + +static ra_nr_table_t ra_nr_select_table_pdsch(srslte_mcs_table_t mcs_table, + srslte_dci_format_nr_t dci_format, + srslte_search_space_type_t search_space_type, + srslte_rnti_type_t rnti_type) { // Non-implemented parameters bool sps_config_mcs_table_present = false; @@ -156,6 +209,21 @@ static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table, return ra_nr_table_1; } +static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table, + srslte_dci_format_nr_t dci_format, + srslte_search_space_type_t search_space_type, + srslte_rnti_type_t rnti_type) +{ + + // Check if it is a PUSCH transmission + if (dci_format == srslte_dci_format_nr_0_0 || dci_format == srslte_dci_format_nr_0_1 || + dci_format == srslte_dci_format_nr_rar || dci_format == srslte_dci_format_nr_cg) { + return ra_nr_select_table_pusch_noprecoding(mcs_table, dci_format, search_space_type, rnti_type); + } + + return ra_nr_select_table_pdsch(mcs_table, dci_format, search_space_type, rnti_type); +} + double srslte_ra_nr_R_from_mcs(srslte_mcs_table_t mcs_table, srslte_dci_format_nr_t dci_format, srslte_search_space_type_t search_space_type, @@ -200,13 +268,13 @@ srslte_mod_t srslte_ra_nr_mod_from_mcs(srslte_mcs_table_t mcs_table, return SRSLTE_MOD_NITEMS; } -int srslte_ra_dl_nr_slot_nof_re(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch_grant_nr_t* grant) +int srslte_ra_dl_nr_slot_nof_re(const srslte_sch_cfg_nr_t* pdsch_cfg, const srslte_sch_grant_nr_t* grant) { // the number of symbols of the PDSCH allocation within the slot int n_sh_symb = grant->L; // the number of REs for DM-RS per PRB in the scheduled duration - int n_prb_dmrs = srslte_dmrs_pdsch_get_N_prb(pdsch_cfg, grant); + int n_prb_dmrs = srslte_dmrs_sch_get_N_prb(pdsch_cfg, grant); if (n_prb_dmrs < SRSLTE_SUCCESS) { ERROR("Invalid number of DMRS RE\n"); return SRSLTE_ERROR; @@ -319,10 +387,10 @@ uint32_t srslte_ra_nr_tbs(uint32_t N_re, double S, double R, uint32_t Qm, uint32 return ra_nr_tbs_from_n_info4(n_info, R); } -int srslte_ra_nr_fill_tb(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - const srslte_pdsch_grant_nr_t* grant, - uint32_t mcs_idx, - srslte_sch_tb_t* tb) +int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg, + const srslte_sch_grant_nr_t* grant, + uint32_t mcs_idx, + srslte_sch_tb_t* tb) { uint32_t cw_idx = 0; diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 848edb3c5..045df37c1 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -65,10 +65,10 @@ uint32_t sch_nr_n_prb_lbrm(uint32_t nof_prb) return 273; } -int srslte_dlsch_nr_fill_cfg(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* sch_cfg, - const srslte_sch_tb_t* tb, - srslte_sch_nr_common_cfg_t* cfg) +int srslte_sch_nr_fill_cfg(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + srslte_sch_nr_common_cfg_t* cfg) { if (!sch_cfg || !tb || !cfg) { @@ -357,14 +357,14 @@ void srslte_sch_nr_free(srslte_sch_nr_t* q) srslte_ldpc_rm_rx_free_c(&q->rx_rm); } -int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* pdsch_cfg, - const srslte_sch_tb_t* tb, - const uint8_t* data, - uint8_t* e_bits) +static inline int sch_nr_encode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint8_t* e_bits) { // Pointer protection - if (!q || !pdsch_cfg || !tb || !data || !e_bits) { + if (!q || !sch_cfg || !tb || !data || !e_bits) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -377,7 +377,7 @@ int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, uint8_t* output_ptr = e_bits; srslte_sch_nr_common_cfg_t cfg = {}; - if (srslte_dlsch_nr_fill_cfg(q, pdsch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -500,12 +500,12 @@ int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, - const srslte_sch_cfg_t* sch_cfg, - const srslte_sch_tb_t* tb, - int8_t* e_bits, - uint8_t* data, - bool* crc_ok) +int sch_nr_decode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + int8_t* e_bits, + uint8_t* data, + bool* crc_ok) { // Pointer protection if (!q || !sch_cfg || !tb || !data || !e_bits || !crc_ok) { @@ -515,7 +515,7 @@ int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, int8_t* input_ptr = e_bits; srslte_sch_nr_common_cfg_t cfg = {}; - if (srslte_dlsch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { + if (srslte_sch_nr_fill_cfg(q, sch_cfg, tb, &cfg) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -655,6 +655,44 @@ int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, return SRSLTE_SUCCESS; } +int srslte_dlsch_nr_encode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* pdsch_cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint8_t* e_bits) +{ + return sch_nr_encode(q, pdsch_cfg, tb, data, e_bits); +} + +int srslte_dlsch_nr_decode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + int8_t* e_bits, + uint8_t* data, + bool* crc_ok) +{ + return sch_nr_decode(q, sch_cfg, tb, e_bits, data, crc_ok); +} + +int srslte_ulsch_nr_encode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* pdsch_cfg, + const srslte_sch_tb_t* tb, + const uint8_t* data, + uint8_t* e_bits) +{ + return sch_nr_encode(q, pdsch_cfg, tb, data, e_bits); +} + +int srslte_ulsch_nr_decode(srslte_sch_nr_t* q, + const srslte_sch_cfg_t* sch_cfg, + const srslte_sch_tb_t* tb, + int8_t* e_bits, + uint8_t* data, + bool* crc_ok) +{ + return sch_nr_decode(q, sch_cfg, tb, e_bits, data, crc_ok); +} + int srslte_sch_nr_tb_info(const srslte_sch_tb_t* tb, char* str, uint32_t str_len) { int len = 0; diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index d19dd3608..646b637b2 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -614,14 +614,17 @@ endif(RF_FOUND) # NR ######################################################################## -add_executable(dlsch_nr_test dlsch_nr_test.c) -target_link_libraries(dlsch_nr_test srslte_phy) -add_test(dlsch_nr_test dlsch_nr_test -m 0 -p 1) +add_executable(sch_nr_test sch_nr_test.c) +target_link_libraries(sch_nr_test srslte_phy) +add_test(sch_nr_test sch_nr_test -m 0 -p 1) add_executable(pdsch_nr_test pdsch_nr_test.c) target_link_libraries(pdsch_nr_test srslte_phy) add_test(pdsch_nr_test pdsch_nr_test -p 6 -m 20) +add_executable(pusch_nr_test pusch_nr_test.c) +target_link_libraries(pusch_nr_test srslte_phy) +add_test(pusch_nr_test pusch_nr_test -p 6 -m 20) add_executable(pdcch_nr_test pdcch_nr_test.c) target_link_libraries(pdcch_nr_test srslte_phy) diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index 266c98711..ea6e2d9a2 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -26,11 +26,11 @@ static srslte_carrier_nr_t carrier = { 1 // max_mimo_layers }; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srslte_pdsch_cfg_nr_t pdsch_cfg = {}; -static srslte_pdsch_grant_nr_t pdsch_grant = {}; -static uint16_t rnti = 0x1234; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srslte_sch_cfg_nr_t pdsch_cfg = {}; +static srslte_sch_grant_nr_t pdsch_grant = {}; +static uint16_t rnti = 0x1234; void usage(char* prog) { @@ -151,8 +151,7 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < - SRSLTE_SUCCESS) { + if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant\n"); goto clean_exit; } diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c new file mode 100644 index 000000000..1002968de --- /dev/null +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -0,0 +1,301 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srslte/phy/phch/pusch_nr.h" +#include "srslte/phy/phch/ra_nr.h" +#include "srslte/phy/ue/ue_ul_nr_data.h" +#include "srslte/phy/utils/debug.h" +#include "srslte/phy/utils/random.h" +#include "srslte/phy/utils/vector.h" +#include + +static srslte_carrier_nr_t carrier = { + 1, // cell_id + 0, // numerology + SRSLTE_MAX_PRB_NR, // nof_prb + 0, // start + 1 // max_mimo_layers +}; + +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srslte_sch_cfg_nr_t pusch_cfg = {}; +static srslte_sch_grant_nr_t pusch_grant = {}; +static uint16_t rnti = 0x1234; + +void usage(char* prog) +{ + printf("Usage: %s [pTL] \n", prog); + printf("\t-p Number of grant PRB, set to 0 for steering [Default %d]\n", n_prb); + printf("\t-m MCS PRB, set to >28 for steering [Default %d]\n", mcs); + printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n", + srslte_mcs_table_to_str(pusch_cfg.sch_cfg.mcs_table)); + printf("\t-L Provide number of layers [Default %d]\n", carrier.max_mimo_layers); + printf("\t-v [set srslte_verbose to debug, default none]\n"); +} + +int parse_args(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "pmTLv")) != -1) { + switch (opt) { + case 'p': + n_prb = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'm': + mcs = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'T': + pusch_cfg.sch_cfg.mcs_table = srslte_mcs_table_from_str(argv[optind]); + break; + case 'L': + carrier.max_mimo_layers = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'v': + srslte_verbose++; + break; + default: + usage(argv[0]); + return SRSLTE_ERROR; + } + } + + return SRSLTE_SUCCESS; +} + +int main(int argc, char** argv) +{ + int ret = SRSLTE_ERROR; + srslte_pusch_nr_t pusch_tx = {}; + srslte_pusch_nr_t pusch_rx = {}; + srslte_chest_dl_res_t chest = {}; + srslte_pusch_res_nr_t pusch_res[SRSLTE_MAX_TB] = {}; + srslte_random_t rand_gen = srslte_random_init(1234); + + uint8_t* data_tx[SRSLTE_MAX_TB] = {}; + uint8_t* data_rx[SRSLTE_MAX_CODEWORDS] = {}; + cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {}; + + // Set default PUSCH configuration + pusch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam; + + if (parse_args(argc, argv) < SRSLTE_SUCCESS) { + goto clean_exit; + } + + srslte_pusch_nr_args_t pusch_args = {}; + pusch_args.sch.disable_simd = false; + pusch_args.measure_evm = true; + + if (srslte_pusch_nr_init_enb(&pusch_tx, &pusch_args) < SRSLTE_SUCCESS) { + ERROR("Error initiating PUSCH for Tx\n"); + goto clean_exit; + } + + if (srslte_pusch_nr_init_ue(&pusch_rx, &pusch_args) < SRSLTE_SUCCESS) { + ERROR("Error initiating SCH NR for Rx\n"); + goto clean_exit; + } + + if (srslte_pusch_nr_set_carrier(&pusch_tx, &carrier)) { + ERROR("Error setting SCH NR carrier\n"); + goto clean_exit; + } + + if (srslte_pusch_nr_set_carrier(&pusch_rx, &carrier)) { + ERROR("Error setting SCH NR carrier\n"); + goto clean_exit; + } + + for (uint32_t i = 0; i < carrier.max_mimo_layers; i++) { + sf_symbols[i] = srslte_vec_cf_malloc(SRSLTE_SLOT_LEN_RE_NR(carrier.nof_prb)); + if (sf_symbols[i] == NULL) { + ERROR("Error malloc\n"); + goto clean_exit; + } + } + + for (uint32_t i = 0; i < pusch_tx.max_cw; i++) { + data_tx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + data_rx[i] = srslte_vec_u8_malloc(SRSLTE_SLOT_MAX_NOF_BITS_NR); + if (data_tx[i] == NULL || data_rx[i] == NULL) { + ERROR("Error malloc\n"); + goto clean_exit; + } + + pusch_res[i].payload = data_rx[i]; + } + + srslte_softbuffer_tx_t softbuffer_tx = {}; + srslte_softbuffer_rx_t softbuffer_rx = {}; + + 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\n"); + goto clean_exit; + } + + if (srslte_softbuffer_rx_init_guru(&softbuffer_rx, SRSLTE_SCH_NR_MAX_NOF_CB_LDPC, SRSLTE_LDPC_MAX_LEN_ENCODED_CB) < + SRSLTE_SUCCESS) { + ERROR("Error init soft-buffer\n"); + goto clean_exit; + } + + // Use grant default A time resources with m=0 + if (srslte_ue_ul_nr_pdsch_time_resource_default_A(0, &pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading default grant\n"); + goto clean_exit; + } + + // Load number of DMRS CDM groups without data + if (srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups without data\n"); + goto clean_exit; + } + + pusch_grant.nof_layers = carrier.max_mimo_layers; + pusch_grant.dci_format = srslte_dci_format_nr_1_0; + pusch_grant.rnti = rnti; + + uint32_t n_prb_start = 1; + uint32_t n_prb_end = carrier.nof_prb + 1; + if (n_prb > 0) { + n_prb_start = SRSLTE_MIN(n_prb, n_prb_end - 1); + n_prb_end = SRSLTE_MIN(n_prb + 1, n_prb_end); + } + + uint32_t mcs_start = 0; + uint32_t mcs_end = pusch_cfg.sch_cfg.mcs_table == srslte_mcs_table_256qam ? 28 : 29; + if (mcs < mcs_end) { + mcs_start = SRSLTE_MIN(mcs, mcs_end - 1); + mcs_end = SRSLTE_MIN(mcs + 1, mcs_end); + } + + if (srslte_chest_dl_res_init(&chest, carrier.nof_prb) < SRSLTE_SUCCESS) { + ERROR("Initiating chest\n"); + goto clean_exit; + } + + for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) { + for (mcs = mcs_start; mcs < mcs_end; mcs++) { + + for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) { + pusch_grant.prb_idx[n] = (n < n_prb); + } + + pusch_grant.dci_format = srslte_dci_format_nr_0_0; + if (srslte_ra_nr_fill_tb(&pusch_cfg, &pusch_grant, mcs, &pusch_grant.tb[0]) < SRSLTE_SUCCESS) { + ERROR("Error filing tb\n"); + goto clean_exit; + } + + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + // Skip TB if no allocated + if (data_tx[tb] == NULL) { + continue; + } + + for (uint32_t i = 0; i < pusch_grant.tb[tb].tbs; i++) { + data_tx[tb][i] = (uint8_t)srslte_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); + } + pusch_grant.tb[tb].softbuffer.tx = &softbuffer_tx; + } + + if (srslte_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_grant, data_tx, sf_symbols) < SRSLTE_SUCCESS) { + ERROR("Error encoding\n"); + goto clean_exit; + } + + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + pusch_grant.tb[tb].softbuffer.rx = &softbuffer_rx; + srslte_softbuffer_rx_reset(pusch_grant.tb[tb].softbuffer.rx); + } + + for (uint32_t i = 0; i < pusch_grant.tb->nof_re; i++) { + chest.ce[0][0][i] = 1.0f; + } + chest.nof_re = pusch_grant.tb->nof_re; + + if (srslte_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_grant, &chest, sf_symbols, pusch_res) < SRSLTE_SUCCESS) { + ERROR("Error encoding\n"); + goto clean_exit; + } + + if (pusch_res->evm > 0.001f) { + ERROR("Error PUSCH EVM is too high %f\n", pusch_res->evm); + goto clean_exit; + } + + float mse = 0.0f; + uint32_t nof_re = srslte_ra_dl_nr_slot_nof_re(&pusch_cfg, &pusch_grant); + for (uint32_t i = 0; i < pusch_grant.nof_layers; i++) { + for (uint32_t j = 0; j < nof_re; j++) { + mse += cabsf(pusch_tx.d[i][j] - pusch_rx.d[i][j]); + } + } + if (nof_re * pusch_grant.nof_layers > 0) { + mse = mse / (nof_re * pusch_grant.nof_layers); + } + if (mse > 0.001) { + ERROR("MSE error (%f) is too high\n", mse); + for (uint32_t i = 0; i < pusch_grant.nof_layers; i++) { + printf("d_tx[%d]=", i); + srslte_vec_fprint_c(stdout, pusch_tx.d[i], nof_re); + printf("d_rx[%d]=", i); + srslte_vec_fprint_c(stdout, pusch_rx.d[i], nof_re); + } + goto clean_exit; + } + + if (!pusch_res[0].crc) { + ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pusch_grant.tb[0].tbs); + goto clean_exit; + } + + if (memcmp(data_tx[0], data_rx[0], pusch_grant.tb[0].tbs / 8) != 0) { + ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;\n", n_prb, mcs, pusch_grant.tb[0].tbs); + printf("Tx data: "); + srslte_vec_fprint_byte(stdout, data_tx[0], pusch_grant.tb[0].tbs / 8); + printf("Rx data: "); + srslte_vec_fprint_byte(stdout, data_rx[0], pusch_grant.tb[0].tbs / 8); + goto clean_exit; + } + + printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_grant.tb[0].tbs, pusch_res[0].evm); + } + } + + ret = SRSLTE_SUCCESS; + +clean_exit: + srslte_chest_dl_res_free(&chest); + srslte_random_free(rand_gen); + srslte_pusch_nr_free(&pusch_tx); + srslte_pusch_nr_free(&pusch_rx); + for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { + if (data_tx[i]) { + free(data_tx[i]); + } + if (data_rx[i]) { + free(data_rx[i]); + } + } + for (uint32_t i = 0; i < SRSLTE_MAX_LAYERS_NR; i++) { + if (sf_symbols[i]) { + free(sf_symbols[i]); + } + } + srslte_softbuffer_tx_free(&softbuffer_tx); + srslte_softbuffer_rx_free(&softbuffer_rx); + + return ret; +} diff --git a/lib/src/phy/phch/test/dlsch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c similarity index 94% rename from lib/src/phy/phch/test/dlsch_nr_test.c rename to lib/src/phy/phch/test/sch_nr_test.c index 10985956f..aa3221957 100644 --- a/lib/src/phy/phch/test/dlsch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -26,10 +26,10 @@ static srslte_carrier_nr_t carrier = { 1 // max_mimo_layers }; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srslte_pdsch_cfg_nr_t pdsch_cfg = {}; -static srslte_pdsch_grant_nr_t pdsch_grant = {}; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srslte_sch_cfg_nr_t pdsch_cfg = {}; +static srslte_sch_grant_nr_t pdsch_grant = {}; void usage(char* prog) { @@ -84,7 +84,7 @@ int main(int argc, char** argv) uint8_t* data_rx = srslte_vec_u8_malloc(1024 * 1024); // Set default PDSCH configuration - pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam; + pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam; if (parse_args(argc, argv) < SRSLTE_SUCCESS) { goto clean_exit; @@ -132,8 +132,7 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < - SRSLTE_SUCCESS) { + if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant\n"); goto clean_exit; } diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index 072e95d6b..4ebc7d21a 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -79,7 +79,7 @@ int srslte_ue_dl_nr_init(srslte_ue_dl_nr_t* q, cf_t* input[SRSLTE_MAX_PORTS], co srslte_ofdm_rx_init_cfg(&q->fft[i], &fft_cfg); } - if (srslte_dmrs_pdsch_init(&q->dmrs_pdsch, true) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_init(&q->dmrs_pdsch, true) < SRSLTE_SUCCESS) { ERROR("Error DMRS\n"); return SRSLTE_ERROR; } @@ -109,7 +109,7 @@ void srslte_ue_dl_nr_free(srslte_ue_dl_nr_t* q) srslte_chest_dl_res_free(&q->chest); srslte_pdsch_nr_free(&q->pdsch); - srslte_dmrs_pdsch_free(&q->dmrs_pdsch); + srslte_dmrs_sch_free(&q->dmrs_pdsch); srslte_dmrs_pdcch_estimator_free(&q->dmrs_pdcch); srslte_pdcch_nr_free(&q->pdcch); @@ -126,7 +126,7 @@ int srslte_ue_dl_nr_set_carrier(srslte_ue_dl_nr_t* q, const srslte_carrier_nr_t* return SRSLTE_ERROR; } - if (srslte_dmrs_pdsch_set_carrier(&q->dmrs_pdsch, carrier) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_set_carrier(&q->dmrs_pdsch, carrier) < SRSLTE_SUCCESS) { ERROR("Error DMRS\n"); return SRSLTE_ERROR; } @@ -305,14 +305,14 @@ int srslte_ue_dl_nr_find_dl_dci(srslte_ue_dl_nr_t* q, return (int)count; } -int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, - const srslte_dl_slot_cfg_t* slot, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - srslte_pdsch_res_nr_t* res) +int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, + const srslte_dl_slot_cfg_t* slot, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + srslte_pdsch_res_nr_t* res) { - if (srslte_dmrs_pdsch_estimate(&q->dmrs_pdsch, slot, cfg, grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) { + if (srslte_dmrs_sch_estimate(&q->dmrs_pdsch, slot, cfg, grant, q->sf_symbols[0], &q->chest) < SRSLTE_SUCCESS) { return SRSLTE_ERROR; } @@ -329,12 +329,12 @@ int srslte_ue_dl_nr_pdsch_get(srslte_ue_dl_nr_t* q, return SRSLTE_SUCCESS; } -int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, - const srslte_pdsch_cfg_nr_t* cfg, - const srslte_pdsch_grant_nr_t* grant, - const srslte_pdsch_res_nr_t* res, - char* str, - uint32_t str_len) +int srslte_ue_dl_nr_pdsch_info(const srslte_ue_dl_nr_t* q, + const srslte_sch_cfg_nr_t* cfg, + const srslte_sch_grant_nr_t* grant, + const srslte_pdsch_res_nr_t* res, + char* str, + uint32_t str_len) { int len = 0; diff --git a/lib/src/phy/ue/ue_dl_nr_data.c b/lib/src/phy/ue/ue_dl_nr_data.c index 60ef76b91..bb0e7bcf8 100644 --- a/lib/src/phy/ue/ue_dl_nr_data.c +++ b/lib/src/phy/ue/ue_dl_nr_data.c @@ -55,7 +55,7 @@ static int srslte_ue_dl_nr_pdsch_time_resource_hl_B(uint32_t sliv, uint32_t* S, return SRSLTE_ERROR; } -int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, srslte_pdsch_grant_nr_t* grant) +int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, srslte_sch_grant_nr_t* grant) { if (pdsch_alloc == NULL || grant == NULL) { @@ -65,16 +65,16 @@ int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsc grant->k0 = pdsch_alloc->k0; grant->mapping = pdsch_alloc->mapping_type; - if (pdsch_alloc->mapping_type == srslte_pdsch_mapping_type_A) { + if (pdsch_alloc->mapping_type == srslte_sch_mapping_type_A) { return srslte_ue_dl_nr_pdsch_time_resource_hl_A(pdsch_alloc->sliv, &grant->S, &grant->L); } return srslte_ue_dl_nr_pdsch_time_resource_hl_B(pdsch_alloc->sliv, &grant->S, &grant->L); } -int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, - srslte_dmrs_pdsch_typeA_pos_t dmrs_typeA_pos, - srslte_pdsch_grant_nr_t* grant) +int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m, + srslte_dmrs_sch_typeA_pos_t dmrs_typeA_pos, + srslte_sch_grant_nr_t* grant) { if (grant == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; @@ -89,23 +89,23 @@ int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t grant->k0 = 0; // Select PDSCH mapping - static srslte_pdsch_mapping_type_t pdsch_mapping_lut[16] = {srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_A, - srslte_pdsch_mapping_type_B, - srslte_pdsch_mapping_type_B}; - grant->mapping = pdsch_mapping_lut[m]; + static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_A, + srslte_sch_mapping_type_B, + srslte_sch_mapping_type_B}; + grant->mapping = pdsch_mapping_lut[m]; static uint32_t S_pos2[16] = {2, 2, 2, 2, 2, 9, 4, 5, 5, 9, 12, 1, 1, 2, 4, 8}; static uint32_t L_pos2[16] = {12, 10, 9, 7, 5, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4}; @@ -115,11 +115,11 @@ int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t // Select start symbol (S) and length (L) switch (dmrs_typeA_pos) { - case srslte_dmrs_pdsch_typeA_pos_2: + case srslte_dmrs_sch_typeA_pos_2: grant->S = S_pos2[m]; grant->L = L_pos2[m]; break; - case srslte_dmrs_pdsch_typeA_pos_3: + case srslte_dmrs_sch_typeA_pos_3: grant->S = S_pos3[m]; grant->L = L_pos3[m]; break; @@ -131,15 +131,15 @@ int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t return SRSLTE_SUCCESS; } -int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_pdsch_cfg_nr_t* pdsch_cfg, - srslte_pdsch_grant_nr_t* grant) +int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg, + srslte_sch_grant_nr_t* grant) { if (pdsch_cfg == NULL || grant == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } - const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = - grant->mapping == srslte_pdsch_mapping_type_A ? &pdsch_cfg->dmrs_cfg_typeA : &pdsch_cfg->dmrs_cfg_typeB; + const srslte_dmrs_sch_cfg_t* dmrs_cfg = + grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB; /* According to TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility: * When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups without data @@ -147,7 +147,7 @@ int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_pds * assume that the number of DM-RS CDM groups without data is 2 which corresponds to CDM group {0,1} for all other * cases. */ - if (dmrs_cfg->length == srslte_dmrs_pdsch_len_2) { + if (dmrs_cfg->length == srslte_dmrs_sch_len_2) { grant->nof_dmrs_cdm_groups_without_data = 1; } else { grant->nof_dmrs_cdm_groups_without_data = 2; diff --git a/lib/src/phy/ue/ue_ul_nr_data.c b/lib/src/phy/ue/ue_ul_nr_data.c new file mode 100644 index 000000000..eecb3394d --- /dev/null +++ b/lib/src/phy/ue/ue_ul_nr_data.c @@ -0,0 +1,84 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srslte/phy/ue/ue_ul_nr_data.h" +#include "srslte/phy/utils/debug.h" + +typedef struct { + srslte_sch_mapping_type_t mapping; + uint32_t K2; + uint32_t S; + uint32_t L; +} ue_ul_time_resource_t; + +static const ue_ul_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mapping_type_A, 0, 0, 14}, + {srslte_sch_mapping_type_A, 0, 0, 12}, + {srslte_sch_mapping_type_A, 0, 0, 10}, + {srslte_sch_mapping_type_B, 0, 2, 10}, + {srslte_sch_mapping_type_B, 0, 4, 10}, + {srslte_sch_mapping_type_B, 0, 4, 8}, + {srslte_sch_mapping_type_B, 0, 4, 6}, + {srslte_sch_mapping_type_A, 1, 0, 14}, + {srslte_sch_mapping_type_A, 1, 0, 12}, + {srslte_sch_mapping_type_A, 1, 0, 10}, + {srslte_sch_mapping_type_A, 2, 0, 14}, + {srslte_sch_mapping_type_A, 2, 0, 12}, + {srslte_sch_mapping_type_A, 2, 0, 10}, + {srslte_sch_mapping_type_B, 0, 8, 6}, + {srslte_sch_mapping_type_A, 3, 0, 14}, + {srslte_sch_mapping_type_A, 3, 0, 10}}; + +int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant) +{ + if (grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + if (m >= 16) { + ERROR("m (%d) is out-of-range\n", m); + return SRSLTE_ERROR_INVALID_INPUTS; + } + + // Select mapping + grant->mapping = ue_ul_default_A_lut[m].mapping; + grant->k2 = ue_ul_default_A_lut[m].K2; + grant->S = ue_ul_default_A_lut[m].S; + grant->L = ue_ul_default_A_lut[m].L; + + return SRSLTE_SUCCESS; +} + +int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg, + srslte_sch_grant_nr_t* grant) +{ + if (cfg == NULL || grant == NULL) { + return SRSLTE_ERROR_INVALID_INPUTS; + } + + /* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure: + * For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE + * shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of + * PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume + * that the number of DM-RS CDM groups without data is 3 which corresponds to CDM group {0,1,2} for the case of PUSCH + * scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH + * allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups + * without data is 2 which corresponds to CDM group {0,1} for all other cases. + */ + if (grant->L <= 2 && !cfg->enable_transform_precoder) { + grant->nof_dmrs_cdm_groups_without_data = 1; + // } else if (grant->L > 2 && cfg->dmrs_cg.type == srslte_dmrs_sch_type_2){ + // grant->nof_dmrs_cdm_groups_without_data = 3; + } else { + grant->nof_dmrs_cdm_groups_without_data = 2; + } + + return SRSLTE_SUCCESS; +} \ No newline at end of file diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index e790788d9..cd9186d90 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -28,12 +28,12 @@ static srslte_carrier_nr_t carrier = { }; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srslte_pdsch_cfg_nr_t pdsch_cfg = {}; -static srslte_pdsch_grant_nr_t pdsch_grant = {}; -static uint16_t rnti = 0x1234; -static uint32_t nof_slots = 10; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srslte_sch_cfg_nr_t pdsch_cfg = {}; +static srslte_sch_grant_nr_t pdsch_grant = {}; +static uint16_t rnti = 0x1234; +static uint32_t nof_slots = 10; void usage(char* prog) { @@ -254,8 +254,7 @@ int main(int argc, char** argv) } // Use grant default A time resources with m=0 - if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < - SRSLTE_SUCCESS) { + if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant\n"); goto clean_exit; } diff --git a/srsenb/hdr/phy/nr/cc_worker.h b/srsenb/hdr/phy/nr/cc_worker.h index db3a3c537..2b74a19d2 100644 --- a/srsenb/hdr/phy/nr/cc_worker.h +++ b/srsenb/hdr/phy/nr/cc_worker.h @@ -36,7 +36,7 @@ typedef struct { } phy_nr_args_t; typedef struct { - srslte_pdsch_cfg_nr_t pdsch; + srslte_sch_cfg_nr_t pdsch; } phy_nr_cfg_t; class phy_nr_state diff --git a/srsenb/src/phy/nr/cc_worker.cc b/srsenb/src/phy/nr/cc_worker.cc index b951c1055..73b64f00c 100644 --- a/srsenb/src/phy/nr/cc_worker.cc +++ b/srsenb/src/phy/nr/cc_worker.cc @@ -110,11 +110,10 @@ uint32_t cc_worker::get_buffer_len() bool cc_worker::work_dl() { - srslte_pdsch_grant_nr_t pdsch_grant = {}; - srslte_pdsch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; + srslte_sch_grant_nr_t pdsch_grant = {}; + srslte_sch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; // Use grant default A time resources with m=0 - if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < - SRSLTE_SUCCESS) { + if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant\n"); return false; } diff --git a/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index d3566b790..df3100ff7 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -37,7 +37,7 @@ typedef struct { } phy_nr_args_t; typedef struct { - srslte_pdsch_cfg_nr_t pdsch; + srslte_sch_cfg_nr_t pdsch; } phy_nr_cfg_t; class phy_nr_state diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index a380a8bbe..e7c4fb354 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -107,13 +107,12 @@ uint32_t cc_worker::get_buffer_len() bool cc_worker::work_dl() { - srslte_pdsch_grant_nr_t pdsch_grant = {}; - srslte_pdsch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; + srslte_sch_grant_nr_t pdsch_grant = {}; + srslte_sch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; std::array pdsch_res = {}; // Use grant default A time resources with m=0 - if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < - SRSLTE_SUCCESS) { + if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_typeA.typeA_pos, &pdsch_grant) < SRSLTE_SUCCESS) { ERROR("Error loading default grant\n"); return false; }