From a8e181971c562ed32684a7748413e089c16167cb Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 22 Apr 2021 18:22:56 +0200 Subject: [PATCH] Refactored PHY NR procedures for supporting DCI formats 0_1 and 1_1 --- .../interfaces/rrc_nr_interface_types.h | 8 +- lib/include/srsran/phy/phch/dci_nr.h | 11 +- lib/include/srsran/phy/phch/phch_cfg_nr.h | 9 +- lib/include/srsran/phy/phch/ra_dl_nr.h | 31 +++- lib/include/srsran/phy/phch/ra_ul_nr.h | 28 +++- lib/src/phy/phch/dci_nr.c | 116 ++++++++------ lib/src/phy/phch/ra_dl_nr.c | 145 +++++++++++------- lib/src/phy/phch/ra_helper.h | 44 ++++++ lib/src/phy/phch/ra_nr.c | 77 +++++----- lib/src/phy/phch/ra_ul_nr.c | 131 +++++++++++++--- lib/src/phy/phch/test/dci_nr_test.c | 8 +- lib/src/phy/phch/test/pdsch_nr_test.c | 14 +- lib/src/phy/phch/test/pusch_nr_test.c | 14 +- lib/src/phy/phch/test/sch_nr_test.c | 7 +- 14 files changed, 426 insertions(+), 217 deletions(-) diff --git a/lib/include/srsran/interfaces/rrc_nr_interface_types.h b/lib/include/srsran/interfaces/rrc_nr_interface_types.h index 6f4c520a0..01eacc809 100644 --- a/lib/include/srsran/interfaces/rrc_nr_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_nr_interface_types.h @@ -93,11 +93,11 @@ struct phy_cfg_nr_t { dci_cfg.enable_transform_precoding = false; dci_cfg.dynamic_dual_harq_ack_codebook = false; dci_cfg.pusch_tx_config_non_codebook = false; - dci_cfg.pusch_dmrs_type2 = false; - dci_cfg.pusch_dmrs_double = false; dci_cfg.pusch_ptrs = false; dci_cfg.pusch_dynamic_betas = false; dci_cfg.pusch_alloc_type = pusch.alloc; + dci_cfg.pusch_dmrs_type = pusch.dmrs_type; + dci_cfg.pusch_dmrs_max_len = pusch.dmrs_max_length; // Format 1_1 specific configuration (for PDSCH only) dci_cfg.nof_dl_bwp = 0; @@ -112,12 +112,12 @@ struct phy_cfg_nr_t { dci_cfg.pdsch_rm_pattern2 = false; dci_cfg.pdsch_2cw = false; dci_cfg.multiple_scell = false; - dci_cfg.pdsch_dmrs_type2 = false; - dci_cfg.pdsch_dmrs_double = false; dci_cfg.pdsch_tci = false; dci_cfg.pdsch_cbg_flush = false; dci_cfg.pdsch_dynamic_bundling = false; dci_cfg.pdsch_alloc_type = pdsch.alloc; + dci_cfg.pdsch_dmrs_type = pdsch.dmrs_type; + dci_cfg.pdsch_dmrs_max_len = pdsch.dmrs_max_length; return dci_cfg; }; diff --git a/lib/include/srsran/phy/phch/dci_nr.h b/lib/include/srsran/phy/phch/dci_nr.h index 0cbaf099e..92986c1a8 100644 --- a/lib/include/srsran/phy/phch/dci_nr.h +++ b/lib/include/srsran/phy/phch/dci_nr.h @@ -57,11 +57,11 @@ typedef struct SRSRAN_API { bool enable_transform_precoding; ///< Set to true if PUSCH transform precoding is enabled bool dynamic_dual_harq_ack_codebook; ///< Set to true if HARQ-ACK codebook is set to dynamic with 2 sub-codebooks bool pusch_tx_config_non_codebook; ///< Set to true if PUSCH txConfig is set to non-codebook - bool pusch_dmrs_type2; ///< Set to true if PUSCH DMRS are type 2 - bool pusch_dmrs_double; ///< Set to true if PUSCH DMRS are 2 symbol long bool pusch_ptrs; ///< Set to true if PT-RS are enabled for PUSCH transmission bool pusch_dynamic_betas; ///< Set to true if beta offsets operation is not semi-static srsran_resource_alloc_t pusch_alloc_type; ///< PUSCH resource allocation type + srsran_dmrs_sch_type_t pusch_dmrs_type; ///< PUSCH DMRS type + srsran_dmrs_sch_len_t pusch_dmrs_max_len; ///< PUSCH DMRS maximum length /// Format 1_1 specific configuration (for PDSCH only) uint32_t nof_dl_bwp; ///< Number of DL BWPs excluding the initial UL BWP, mentioned in the TS as N_BWP_RRC @@ -74,13 +74,12 @@ typedef struct SRSRAN_API { bool pdsch_rm_pattern2; ///< Set to true if rateMatchPatternGroup2 is configured bool pdsch_2cw; ///< Set to true if maxNrofCodeWordsScheduledByDCI is set to 2 in any BWP bool multiple_scell; ///< Set to true if configured with multiple serving cell - bool pdsch_dmrs_type2; ///< Set to true if PDSCH DMRS are type 2 - bool pdsch_dmrs_double; ///< Set to true if PDSCH DMRS are 2 symbol long bool pdsch_tci; ///< Set to true if tci-PresentInDCI is enabled bool pdsch_cbg_flush; ///< Set to true if codeBlockGroupFlushIndicator is true bool pdsch_dynamic_bundling; ///< Set to true if prb-BundlingType is set to dynamicBundling - srsran_resource_alloc_t pdsch_alloc_type; ///< PDSCH resource allocation type, set to 0 for default - + srsran_resource_alloc_t pdsch_alloc_type; ///< PDSCH resource allocation type, set to 0 for default + srsran_dmrs_sch_type_t pdsch_dmrs_type; ///< PDSCH DMRS type + srsran_dmrs_sch_len_t pdsch_dmrs_max_len; ///< PDSCH DMRS maximum length } srsran_dci_cfg_nr_t; /** diff --git a/lib/include/srsran/phy/phch/phch_cfg_nr.h b/lib/include/srsran/phy/phch/phch_cfg_nr.h index 99d028bfe..57a02f21b 100644 --- a/lib/include/srsran/phy/phch/phch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/phch_cfg_nr.h @@ -184,10 +184,10 @@ typedef struct SRSRAN_API { bool scrambling_id_present; uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023) + srsran_dmrs_sch_type_t dmrs_type; + srsran_dmrs_sch_len_t dmrs_max_length; struct { - srsran_dmrs_sch_type_t type; srsran_dmrs_sch_add_pos_t additional_pos; - srsran_dmrs_sch_len_t length; bool scrambling_id0_present; uint32_t scrambling_id0; bool scrambling_id1_present; @@ -196,9 +196,7 @@ typedef struct SRSRAN_API { } dmrs_typeA; struct { - srsran_dmrs_sch_type_t type; srsran_dmrs_sch_add_pos_t additional_pos; - srsran_dmrs_sch_len_t length; bool scrambling_id0_present; uint32_t scrambling_id0; bool scrambling_id1_present; @@ -224,7 +222,8 @@ typedef struct SRSRAN_API { srsran_csi_rs_nzp_set_t nzp_csi_rs_sets[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_SETS]; /// PUSCH only - srsran_beta_offsets_t beta_offsets; /// Semi-static only. + srsran_beta_offsets_t beta_offsets; /// Semi-static only. + bool enable_transform_precoder; /// Enables transform precoding float scaling; /// Indicates a scaling factor to limit the number of resource elements assigned to UCI on PUSCH. } srsran_sch_hl_cfg_nr_t; diff --git a/lib/include/srsran/phy/phch/ra_dl_nr.h b/lib/include/srsran/phy/phch/ra_dl_nr.h index ecc628f9d..90f6b20cd 100644 --- a/lib/include/srsran/phy/phch/ra_dl_nr.h +++ b/lib/include/srsran/phy/phch/ra_dl_nr.h @@ -62,17 +62,32 @@ SRSRAN_API int srsran_ra_dl_nr_time(const srsran_sch_hl_cfg_nr_t* cfg, */ SRSRAN_API int srsran_ra_dl_nr_time_default_A(uint32_t m, srsran_dmrs_sch_typeA_pos_t dmrs_typeA_pos, srsran_sch_grant_nr_t* grant); + /** - * @brief Calculates the number of PDSCH-DMRS CDM groups without data for DCI format 1_0 + * @brief Calculates the number of front load symbols * - * @remark Defined by TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility - * - * @param cfg PDSCH-DMRS NR configuration by upper layers - * @param[out] grant Provides grant pointer to fill - * @return Returns SRSRAN_SUCCESS if the provided data is valid, otherwise it returns SRSRAN_ERROR code + * @param cfg PDSCH NR configuration by upper layers + * @param dci Provides PDSCH NR DCI + * @param[out] dmrs_duration + * @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise */ -SRSRAN_API int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srsran_dmrs_sch_cfg_t* cfg, - srsran_sch_grant_nr_t* grant); +SRSRAN_API int srsran_ra_dl_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_dl_nr_t* dci, + srsran_dmrs_sch_len_t* dmrs_duration); + +/** + * @brief Calculates the number of DMRS CDM groups without data + * + * @remark Defined by TS 38.214 V15.10.0 5.1.6.2 DM-RS reception procedure + * + * @param cfg PDSCH NR configuration by upper layers + * @param dci Provides PUSCH NR DCI + * @return The number of DMRS CDM groups without data if the provided data is valid, otherwise it returns SRSRAN_ERROR + * code + */ +SRSRAN_API int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_dl_nr_t* dci, + uint32_t L); /** * @brief Calculates the PDSCH frequency resource allocation and stores it in the provided PDSCH NR grant. diff --git a/lib/include/srsran/phy/phch/ra_ul_nr.h b/lib/include/srsran/phy/phch/ra_ul_nr.h index 4fb80dce7..958579257 100644 --- a/lib/include/srsran/phy/phch/ra_ul_nr.h +++ b/lib/include/srsran/phy/phch/ra_ul_nr.h @@ -55,16 +55,30 @@ SRSRAN_API int srsran_ra_ul_nr_pusch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srsran_sch_grant_nr_t* grant); /** - * @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0 + * @brief Calculates the number of front load symbols + * + * @param cfg PUSCH NR configuration by upper layers + * @param dci Provides PUSCH NR DCI + * @param[out] dmrs_duration + * @return SRSRAN_SUCCESS if provided arguments are valid, SRSRAN_ERROR code otherwise + */ +SRSRAN_API int srsran_ra_ul_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_ul_nr_t* dci, + srsran_dmrs_sch_len_t* dmrs_duration); + +/** + * @brief Calculates the number of DMRS CDM groups without data * * @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 SRSRAN_SUCCESS if the provided data is valid, otherwise it returns SRSRAN_ERROR code + * @param dci Provides PUSCH NR DCI + * @return The number of DMRS CDM groups without data if the provided data is valid, otherwise it returns SRSRAN_ERROR + * code */ -SRSRAN_API int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srsran_sch_cfg_nr_t* cfg, - srsran_sch_grant_nr_t* grant); +SRSRAN_API int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_ul_nr_t* dci, + uint32_t L); /** * @brief Calculates the ratio of PUSCH EPRE to DM-RS EPRE @@ -87,7 +101,9 @@ SRSRAN_API int srsran_ra_ul_nr_pucch_format_2_3_min_prb(const srsran_pucch_nr_re /** * @brief Calculates the PUSCH frequency resource allocation and stores it in the provided PUSCH NR grant. * - * @remark Defined by TS 38.214 V15.10.0 section 5.1.2.2 + * @remark Defined by TS 38.214 V15.10.0 section 6.1.2.2 Resource allocation in frequency domain (for DCI formats 0_0 + * and 0_1) + * @remark Defined by TS 38.213 V15.10.0 section 8.3 for PUSCH scheduled by RAR UL grant * @param carrier Carrier information * @param cfg PDSCH NR configuration by upper layers * @param dci_dl Unpacked DCI used to schedule the PDSCH grant diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index 89643791e..ad5265b37 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -84,6 +84,65 @@ static uint32_t dci_nr_ptrs_size(const srsran_dci_cfg_nr_t* cfg) return 2; } +static uint32_t dci_nr_dl_ports_size(const srsran_dci_cfg_nr_t* cfg) +{ + uint32_t ret = 4; + + if (cfg->pdsch_dmrs_type == srsran_dmrs_sch_type_2) { + ret++; + } + if (cfg->pdsch_dmrs_max_len == srsran_dmrs_sch_len_2) { + ret++; + } + + return ret; +} + +static uint32_t dci_nr_ul_ports_size(const srsran_dci_cfg_nr_t* cfg) +{ + // 2 bits as defined by Tables 7.3.1.1.2-6, if transform precoder is enabled, dmrs-Type=1, and maxLength=1; + if (cfg->enable_transform_precoding == true && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_1 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_1) { + return 2; + } + + // 4 bits as defined by Tables 7.3.1.1.2-7, if transform precoder is enabled, dmrs-Type=1, and maxLength=2; + if (cfg->enable_transform_precoding == true && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_1 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_2) { + return 4; + } + + // 3 bits as defined by Tables 7.3.1.1.2-8/9/10/11, if transform precoder is disabled, dmrs-Type=1, and maxLength=1 + if (cfg->enable_transform_precoding == false && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_1 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_1) { + return 3; + } + + // 4 bits as defined by Tables 7.3.1.1.2-12/13/14/15, if transform precoder is disabled, dmrs-Type=1, and + // maxLength=2 + if (cfg->enable_transform_precoding == false && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_1 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_2) { + return 4; + } + + // 4 bits as defined by Tables 7.3.1.1.2-16/17/18/19, if transform precoder is disabled, dmrs-Type=2, and + // maxLength=1 + if (cfg->enable_transform_precoding == false && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_2 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_1) { + return 4; + } + + // 5 bits as defined by Tables 7.3.1.1.2-20/21/22/23, if transform precoder is disabled, dmrs-Type=2, and + // maxLength=2 + if (cfg->enable_transform_precoding == false && cfg->pusch_dmrs_type == srsran_dmrs_sch_type_2 && + cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_2) { + return 5; + } + + ERROR("Unhandled configuration"); + return 0; +} + static uint32_t dci_nr_srs_id_size(const srsran_dci_cfg_nr_t* cfg) { uint32_t N_srs = SRSRAN_MIN(1, cfg->nof_srs); @@ -393,12 +452,7 @@ static uint32_t dci_nr_format_0_1_sizeof(const srsran_dci_cfg_nr_t* cfg, srsran_ } // Antenna ports - if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { - count += 3; - } else { - ERROR("Not implemented"); - return 0; - } + count += dci_nr_ul_ports_size(cfg); // SRS request - 2 or 3 bits count += cfg->enable_sul ? 3 : 2; @@ -502,12 +556,7 @@ static int dci_nr_format_0_1_pack(const srsran_dci_nr_t* q, const srsran_dci_ul_ } // Antenna ports - if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { - srsran_bit_unpack(dci->ports, &y, 3); - } else { - ERROR("Not implemented"); - return 0; - } + srsran_bit_unpack(dci->ports, &y, dci_nr_ul_ports_size(cfg)); // SRS request - 2 or 3 bits srsran_bit_unpack(dci->srs_request, &y, cfg->enable_sul ? 3 : 2); @@ -619,7 +668,7 @@ static int dci_nr_format_0_1_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_ } // Antenna ports - if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { + if (!cfg->enable_transform_precoding && cfg->pusch_dmrs_max_len == srsran_dmrs_sch_len_1) { dci->ports = srsran_bit_pack(&y, 3); } else { ERROR("Not implemented"); @@ -726,11 +775,8 @@ dci_nr_format_0_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci } // Antenna ports - if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { + if (dci_nr_ul_ports_size(cfg)) { len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports); - } else { - ERROR("Not implemented"); - return 0; } // SRS request - 2 bits @@ -866,8 +912,8 @@ static int dci_nr_format_1_0_pack(const srsran_dci_nr_t* q, const srsran_dci_dl_ srsran_rnti_type_t rnti_type = msg->ctx.rnti_type; srsran_search_space_type_t ss_type = dci->ctx.ss_type; uint32_t N_DL_BWP_RB = SRSRAN_SEARCH_SPACE_IS_COMMON(ss_type) - ? (q->cfg.coreset0_bw == 0) ? q->cfg.bwp_dl_initial_bw : q->cfg.coreset0_bw - : q->cfg.bwp_dl_active_bw; + ? (q->cfg.coreset0_bw == 0) ? q->cfg.bwp_dl_initial_bw : q->cfg.coreset0_bw + : q->cfg.bwp_dl_active_bw; // Identifier for DCI formats – 1 bits if (rnti_type == srsran_rnti_type_c || rnti_type == srsran_rnti_type_tc) { @@ -972,8 +1018,8 @@ static int dci_nr_format_1_0_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_ srsran_rnti_type_t rnti_type = msg->ctx.rnti_type; srsran_search_space_type_t ss_type = msg->ctx.ss_type; uint32_t N_DL_BWP_RB = SRSRAN_SEARCH_SPACE_IS_COMMON(ss_type) - ? (q->cfg.coreset0_bw == 0) ? q->cfg.bwp_dl_initial_bw : q->cfg.coreset0_bw - : q->cfg.bwp_dl_active_bw; + ? (q->cfg.coreset0_bw == 0) ? q->cfg.bwp_dl_initial_bw : q->cfg.coreset0_bw + : q->cfg.bwp_dl_active_bw; uint32_t nof_bits = srsran_dci_nr_size(q, ss_type, srsran_dci_format_nr_1_0); if (msg->nof_bits != nof_bits) { @@ -1240,13 +1286,7 @@ static uint32_t dci_nr_format_1_1_sizeof(const srsran_dci_cfg_nr_t* cfg, srsran_ count += (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack); // Antenna port(s) – 4, 5, or 6 bits - count += 4; - if (cfg->pdsch_dmrs_type2) { - count++; - } - if (cfg->pdsch_dmrs_double) { - count++; - } + count += dci_nr_dl_ports_size(cfg); // Transmission configuration indication – 0 or 3 bits if (cfg->pdsch_tci) { @@ -1362,13 +1402,7 @@ static int dci_nr_format_1_1_pack(const srsran_dci_nr_t* q, const srsran_dci_dl_ srsran_bit_unpack(dci->harq_feedback, &y, (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack)); // Antenna port(s) – 4, 5, or 6 bits - srsran_bit_unpack(dci->ports, &y, 4); - if (cfg->pdsch_dmrs_type2) { - y++; - } - if (cfg->pdsch_dmrs_double) { - y++; - } + srsran_bit_unpack(dci->ports, &y, dci_nr_dl_ports_size(cfg)); // Transmission configuration indication – 0 or 3 bits if (cfg->pdsch_tci) { @@ -1498,13 +1532,7 @@ static int dci_nr_format_1_1_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_ dci->harq_feedback = srsran_bit_pack(&y, (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack)); // Antenna port(s) – 4, 5, or 6 bits - dci->ports = srsran_bit_pack(&y, 4); - if (cfg->pdsch_dmrs_type2) { - y++; - } - if (cfg->pdsch_dmrs_double) { - y++; - } + dci->ports = srsran_bit_pack(&y, dci_nr_dl_ports_size(cfg)); // Transmission configuration indication – 0 or 3 bits if (cfg->pdsch_tci) { @@ -1619,7 +1647,9 @@ dci_nr_format_1_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci } // Antenna port(s) – 4, 5, or 6 bits - len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports); + if (dci_nr_dl_ports_size(cfg) > 0) { + len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports); + } // Transmission configuration indication – 0 or 3 bits if (cfg->pdsch_tci) { diff --git a/lib/src/phy/phch/ra_dl_nr.c b/lib/src/phy/phch/ra_dl_nr.c index cbc52d656..987afd591 100644 --- a/lib/src/phy/phch/ra_dl_nr.c +++ b/lib/src/phy/phch/ra_dl_nr.c @@ -189,69 +189,98 @@ int srsran_ra_dl_nr_time(const srsran_sch_hl_cfg_nr_t* cfg, return SRSRAN_SUCCESS; } -int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srsran_dmrs_sch_cfg_t* cfg, - srsran_sch_grant_nr_t* grant) +int srsran_ra_dl_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_dl_nr_t* dci, + srsran_dmrs_sch_len_t* dmrs_duration) { - if (cfg == NULL || grant == NULL) { - return SRSRAN_ERROR_INVALID_INPUTS; + // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1 + // Table 7.3.1.2.2-3: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=1 + if (cfg->dmrs_max_length == srsran_dmrs_sch_len_1) { + *dmrs_duration = srsran_dmrs_sch_len_1; + return SRSRAN_SUCCESS; } - /* 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 - * is 1 which corresponds to CDM group 0 for the case of PDSCH with allocation duration of 2 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 (cfg->length == srsran_dmrs_sch_len_2) { - grant->nof_dmrs_cdm_groups_without_data = 1; - } else { - grant->nof_dmrs_cdm_groups_without_data = 2; - } - - return SRSRAN_SUCCESS; -} - -/* RBG size for type0 scheduling as in table 5.1.2.2.1-1 of 36.214 */ -uint32_t srsran_ra_dl_nr_type0_P(uint32_t bwp_size, bool config_is_1) -{ - if (bwp_size <= 36) { - return config_is_1 ? 2 : 4; - } else if (bwp_size <= 72) { - return config_is_1 ? 4 : 8; - } else if (bwp_size <= 144) { - return config_is_1 ? 8 : 16; - } else { - return 16; - } -} - -static int ra_freq_type0(const srsran_carrier_nr_t* carrier, - const srsran_sch_hl_cfg_nr_t* cfg, - const srsran_dci_dl_nr_t* dci_dl, - srsran_sch_grant_nr_t* grant) -{ - uint32_t P = srsran_ra_dl_nr_type0_P(carrier->nof_prb, cfg->rbg_size_cfg_1); - - uint32_t N_rbg = (int)ceilf((float)(carrier->nof_prb + (carrier->start % P)) / P); - uint32_t rbg_offset = 0; - for (uint32_t i = 0; i < N_rbg; i++) { - uint32_t rbg_size = P; - if (i == 0) { - rbg_size -= (carrier->start % P); - } else if ((i == N_rbg - 1) && ((carrier->nof_prb + carrier->start) % P) > 0) { - rbg_size = (carrier->nof_prb + carrier->start) % P; + // Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2 + if (cfg->dmrs_type == srsran_dmrs_sch_type_1 && cfg->dmrs_max_length == srsran_dmrs_sch_len_2) { + // Only one codeword supported! + if (dci->ports < 12) { + *dmrs_duration = srsran_dmrs_sch_len_1; + return SRSRAN_SUCCESS; } - if (dci_dl->freq_domain_assigment & (1 << (N_rbg - i - 1))) { - for (uint32_t j = 0; j < rbg_size; j++) { - if (rbg_offset + j < carrier->nof_prb) { - grant->prb_idx[rbg_offset + j] = true; - grant->nof_prb++; - } + + if (dci->ports < 31) { + *dmrs_duration = srsran_dmrs_sch_len_2; + return SRSRAN_SUCCESS; + } + + ERROR("reserved value for ports (%d)", dci->ports); + return SRSRAN_ERROR; + } + + // Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2 + if (cfg->dmrs_type == srsran_dmrs_sch_type_2 && cfg->dmrs_max_length == srsran_dmrs_sch_len_2) { + // Only one codeword supported! + if (dci->ports < 3) { + *dmrs_duration = srsran_dmrs_sch_len_1; + return SRSRAN_SUCCESS; + } + + if (dci->ports < 24) { + *dmrs_duration = srsran_dmrs_sch_len_2; + return SRSRAN_SUCCESS; + } + + ERROR("reserved value for ports (%d)", dci->ports); + return SRSRAN_ERROR; + } + + ERROR("Unhandled case"); + return SRSRAN_ERROR; +} + +int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_dl_nr_t* dci, + uint32_t L) +{ + // According to TS 38.214 5.1.6.2 DM-RS reception procedure + switch (dci->ctx.format) { + case srsran_dci_format_nr_1_0: + // When receiving PDSCH scheduled by DCI format 1_0, 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 PDSCH with allocation duration of 2 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 (L == 2) { + return 1; + } else { + return 2; } - } - rbg_offset += rbg_size; + return SRSRAN_SUCCESS; + case srsran_dci_format_nr_0_1: + // When receiving PDSCH scheduled by DCI format 1_1, the UE shall assume that the CDM groups indicated in the + // configured index from Tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of [5, TS. 38.212] contain + // potential co- scheduled downlink DM-RS and are not used for data transmission, where "1", "2" and "3" for the + // number of DM-RS CDM group(s) in Tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of [5, TS. 38.212] + // correspond to CDM group 0, {0,1}, {0,1,2}, respectively. + + // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1 + if (cfg->dmrs_type == srsran_dmrs_sch_type_1 && cfg->dmrs_max_length == srsran_dmrs_sch_len_1) { + if (dci->ports < 3) { + return 1; + } + if (dci->ports < 12) { + return 2; + } + ERROR("Invalid ports=%d;", dci->ports); + return SRSRAN_ERROR; + } + + ERROR("Unhandled case (%d, %d)", cfg->dmrs_type, cfg->dmrs_max_length); + return SRSRAN_ERROR; + default: + ERROR("Invalid UL DCI format %s", srsran_dci_format_nr_string(dci->ctx.format)); } - return 0; + + return SRSRAN_ERROR; } int srsran_ra_dl_nr_freq(const srsran_carrier_nr_t* carrier, @@ -269,7 +298,7 @@ int srsran_ra_dl_nr_freq(const srsran_carrier_nr_t* carrier, return ra_helper_freq_type1(carrier->nof_prb, dci_dl->freq_domain_assigment, grant); } - ra_freq_type0(carrier, cfg, dci_dl, grant); + ra_helper_freq_type0(carrier, cfg, dci_dl->freq_domain_assigment, grant); ERROR("Only DCI Format 1_0 is supported"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/ra_helper.h b/lib/src/phy/phch/ra_helper.h index bdb0c45a0..029bb6ad6 100644 --- a/lib/src/phy/phch/ra_helper.h +++ b/lib/src/phy/phch/ra_helper.h @@ -14,8 +14,52 @@ #define SRSRAN_RA_HELPER_H #include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/vector.h" #include +/* RBG size for type0 scheduling as in table 5.1.2.2.1-1 of 36.214 */ +static uint32_t ra_helper_type0_P(uint32_t bwp_size, bool config_is_1) +{ + if (bwp_size <= 36) { + return config_is_1 ? 2 : 4; + } else if (bwp_size <= 72) { + return config_is_1 ? 4 : 8; + } else if (bwp_size <= 144) { + return config_is_1 ? 8 : 16; + } else { + return 16; + } +} + +static int ra_helper_freq_type0(const srsran_carrier_nr_t* carrier, + const srsran_sch_hl_cfg_nr_t* cfg, + uint32_t riv, + srsran_sch_grant_nr_t* grant) +{ + uint32_t P = ra_helper_type0_P(carrier->nof_prb, cfg->rbg_size_cfg_1); + + uint32_t N_rbg = (int)ceilf((float)(carrier->nof_prb + (carrier->start % P)) / P); + uint32_t rbg_offset = 0; + for (uint32_t i = 0; i < N_rbg; i++) { + uint32_t rbg_size = P; + if (i == 0) { + rbg_size -= (carrier->start % P); + } else if ((i == N_rbg - 1) && ((carrier->nof_prb + carrier->start) % P) > 0) { + rbg_size = (carrier->nof_prb + carrier->start) % P; + } + if (riv & (1 << (N_rbg - i - 1))) { + for (uint32_t j = 0; j < rbg_size; j++) { + if (rbg_offset + j < carrier->nof_prb) { + grant->prb_idx[rbg_offset + j] = true; + grant->nof_prb++; + } + } + } + rbg_offset += rbg_size; + } + return 0; +} + static inline void ra_helper_compute_s_and_l(uint32_t N, uint32_t v, uint32_t* S, uint32_t* L) { uint32_t low = v % N; diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 8a34ab4f7..0f4a87f04 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -528,13 +528,13 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, return SRSRAN_SUCCESS; } -static int ra_dl_dmrs(const srsran_sch_hl_cfg_nr_t* hl_cfg, srsran_sch_grant_nr_t* grant, srsran_sch_cfg_nr_t* cfg) +static int ra_dl_dmrs(const srsran_sch_hl_cfg_nr_t* hl_cfg, const srsran_dci_dl_nr_t* dci, srsran_sch_cfg_nr_t* cfg) { const bool dedicated_dmrs_present = - (grant->mapping == srsran_sch_mapping_type_A) ? hl_cfg->dmrs_typeA.present : hl_cfg->dmrs_typeB.present; + (cfg->grant.mapping == srsran_sch_mapping_type_A) ? hl_cfg->dmrs_typeA.present : hl_cfg->dmrs_typeB.present; - if (grant->dci_format == srsran_dci_format_nr_1_0 || !dedicated_dmrs_present) { - if (grant->mapping == srsran_sch_mapping_type_A) { + if (dci->ctx.format == srsran_dci_format_nr_1_0 || !dedicated_dmrs_present) { + if (cfg->grant.mapping == srsran_sch_mapping_type_A) { // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; cfg->dmrs.type = srsran_dmrs_sch_type_1; @@ -546,34 +546,37 @@ static int ra_dl_dmrs(const srsran_sch_hl_cfg_nr_t* hl_cfg, srsran_sch_grant_nr_ return SRSRAN_ERROR; } } else { - if (grant->mapping == srsran_sch_mapping_type_A) { + // Load DMRS duration + if (srsran_ra_dl_nr_nof_front_load_symbols(hl_cfg, dci, &cfg->dmrs.length) < SRSRAN_SUCCESS) { + ERROR("Loading number of front-load symbols"); + return SRSRAN_ERROR; + } + + // DMRS Type + cfg->dmrs.type = hl_cfg->dmrs_type; + + // Other DMRS configuration + if (cfg->grant.mapping == srsran_sch_mapping_type_A) { cfg->dmrs.additional_pos = hl_cfg->dmrs_typeA.additional_pos; - cfg->dmrs.type = hl_cfg->dmrs_typeA.type; - cfg->dmrs.length = hl_cfg->dmrs_typeA.length; cfg->dmrs.scrambling_id0_present = false; cfg->dmrs.scrambling_id1_present = false; } else { cfg->dmrs.additional_pos = hl_cfg->dmrs_typeB.additional_pos; - cfg->dmrs.type = hl_cfg->dmrs_typeB.type; - cfg->dmrs.length = hl_cfg->dmrs_typeB.length; cfg->dmrs.scrambling_id0_present = false; cfg->dmrs.scrambling_id1_present = false; } } // Set number of DMRS CDM groups without data - if (grant->dci_format == srsran_dci_format_nr_1_0) { - if (srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&cfg->dmrs, grant) < SRSRAN_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups"); - return SRSRAN_ERROR; - } - } else { - ERROR("Invalid case"); + int n = srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(hl_cfg, dci, cfg->grant.L); + if (n < SRSRAN_SUCCESS) { + ERROR("Error loading number of DMRS CDM groups"); return SRSRAN_ERROR; } + cfg->grant.nof_dmrs_cdm_groups_without_data = (uint32_t)n; // Set DMRS power offset Table 6.2.2-1: The ratio of PUSCH EPRE to DM-RS EPRE - if (ra_nr_dmrs_power_offset(grant) < SRSRAN_SUCCESS) { + if (ra_nr_dmrs_power_offset(&cfg->grant) < SRSRAN_SUCCESS) { ERROR("Error setting DMRS power offset"); return SRSRAN_ERROR; } @@ -682,7 +685,7 @@ int srsran_ra_dl_dci_to_grant_nr(const srsran_carrier_nr_t* carrier, } // 5.1.6.2 DM-RS reception procedure - if (ra_dl_dmrs(pdsch_hl_cfg, pdsch_grant, pdsch_cfg) < SRSRAN_SUCCESS) { + if (ra_dl_dmrs(pdsch_hl_cfg, dci_dl, pdsch_cfg) < SRSRAN_SUCCESS) { ERROR("Error selecting DMRS configuration"); return SRSRAN_ERROR; } @@ -697,15 +700,15 @@ int srsran_ra_dl_dci_to_grant_nr(const srsran_carrier_nr_t* carrier, } static int -ra_ul_dmrs(const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg, srsran_sch_grant_nr_t* pusch_grant, srsran_sch_cfg_nr_t* cfg) +ra_ul_dmrs(const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg, const srsran_dci_ul_nr_t* dci, srsran_sch_cfg_nr_t* cfg) { - const bool dedicated_dmrs_present = (pusch_grant->mapping == srsran_sch_mapping_type_A) + const bool dedicated_dmrs_present = (cfg->grant.mapping == srsran_sch_mapping_type_A) ? pusch_hl_cfg->dmrs_typeA.present : pusch_hl_cfg->dmrs_typeB.present; - if (pusch_grant->dci_format == srsran_dci_format_nr_0_0 || pusch_grant->dci_format == srsran_dci_format_nr_rar || + if (dci->ctx.format == srsran_dci_format_nr_0_0 || dci->ctx.format == srsran_dci_format_nr_rar || !dedicated_dmrs_present) { - if (pusch_grant->mapping == srsran_sch_mapping_type_A) { + if (cfg->grant.mapping == srsran_sch_mapping_type_A) { // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; cfg->dmrs.type = srsran_dmrs_sch_type_1; @@ -717,34 +720,36 @@ ra_ul_dmrs(const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg, srsran_sch_grant_nr_t* pu return SRSRAN_ERROR; } } else { - if (pusch_grant->mapping == srsran_sch_mapping_type_A) { + // DMRS duration + if (srsran_ra_ul_nr_nof_front_load_symbols(pusch_hl_cfg, dci, &cfg->dmrs.length) < SRSRAN_SUCCESS) { + ERROR("Loading number of front-load symbols"); + return SRSRAN_ERROR; + } + + // DMRS type + cfg->dmrs.type = pusch_hl_cfg->dmrs_type; + + if (cfg->grant.mapping == srsran_sch_mapping_type_A) { cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeA.additional_pos; - cfg->dmrs.type = pusch_hl_cfg->dmrs_typeA.type; - cfg->dmrs.length = pusch_hl_cfg->dmrs_typeA.length; cfg->dmrs.scrambling_id0_present = false; cfg->dmrs.scrambling_id1_present = false; } else { cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeB.additional_pos; - cfg->dmrs.type = pusch_hl_cfg->dmrs_typeB.type; - cfg->dmrs.length = pusch_hl_cfg->dmrs_typeB.length; cfg->dmrs.scrambling_id0_present = false; cfg->dmrs.scrambling_id1_present = false; } } // Set number of DMRS CDM groups without data - if (pusch_grant->dci_format == srsran_dci_format_nr_0_0 || pusch_grant->dci_format == srsran_dci_format_nr_rar) { - if (srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(cfg, pusch_grant) < SRSRAN_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups"); - return SRSRAN_ERROR; - } - } else { - ERROR("DCI format not implemented %s", srsran_dci_format_nr_string(pusch_grant->dci_format)); + int n = srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data(pusch_hl_cfg, dci, cfg->grant.L); + if (n < SRSRAN_SUCCESS) { + ERROR("Error getting number of DMRS CDM groups without data"); return SRSRAN_ERROR; } + cfg->grant.nof_dmrs_cdm_groups_without_data = (uint32_t)n; // Set DMRS power offset Table 6.2.2-1: The ratio of PUSCH EPRE to DM-RS EPRE - if (ra_nr_dmrs_power_offset(pusch_grant) < SRSRAN_SUCCESS) { + if (ra_nr_dmrs_power_offset(&cfg->grant) < SRSRAN_SUCCESS) { ERROR("Error setting DMRS power offset"); return SRSRAN_ERROR; } @@ -787,7 +792,7 @@ int srsran_ra_ul_dci_to_grant_nr(const srsran_carrier_nr_t* carrier, pusch_grant->tb[0].ndi = dci_ul->ndi; // 5.1.6.2 DM-RS reception procedure - if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSRAN_SUCCESS) { + if (ra_ul_dmrs(pusch_hl_cfg, dci_ul, pusch_cfg) < SRSRAN_SUCCESS) { ERROR("Error selecting DMRS configuration"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index 5be5f7681..ea425ab24 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -196,31 +196,94 @@ int srsran_ra_ul_nr_time(const srsran_sch_hl_cfg_nr_t* cfg, return SRSRAN_SUCCESS; } -int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srsran_sch_cfg_nr_t* cfg, - srsran_sch_grant_nr_t* grant) +int srsran_ra_ul_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_ul_nr_t* dci, + srsran_dmrs_sch_len_t* dmrs_duration) { - if (cfg == NULL || grant == NULL) { + if (cfg == NULL || dci == NULL || dmrs_duration == NULL) { return SRSRAN_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 == srsran_dmrs_sch_type_2){ - // grant->nof_dmrs_cdm_groups_without_data = 3; - } else { - grant->nof_dmrs_cdm_groups_without_data = 2; + // Table 7.3.1.1.2-6: Antenna port(s), transform precoder is enabled, dmrs-Type=1, maxLength=1 + // Table 7.3.1.1.2-8: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=1 + // Table 7.3.1.1.2-9: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=2 + // Table 7.3.1.1.2-10: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=3 + // Table 7.3.1.1.2-11: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=4 + // Table 7.3.1.1.2-16: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=1 + // Table 7.3.1.1.2-17: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=2 + // Table 7.3.1.1.2-18: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=3 + // Table 7.3.1.1.2-19: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=4 + if (cfg->dmrs_max_length == srsran_dmrs_sch_len_1) { + *dmrs_duration = srsran_dmrs_sch_len_1; + return SRSRAN_SUCCESS; } - return SRSRAN_SUCCESS; + // Other tables are not implemented + ERROR("Unhandled case"); + return SRSRAN_ERROR; +} + +int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg, + const srsran_dci_ul_nr_t* dci, + uint32_t L) +{ + if (cfg == NULL || dci == NULL || L == 0) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + uint32_t rank = 1; // No other supported + + // According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure: + switch (dci->ctx.format) { + case srsran_dci_format_nr_0_0: + // 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 (L <= 2 && !cfg->enable_transform_precoder) { + return 1; + } else if (L > 2 && cfg->dmrs_type == srsran_dmrs_sch_type_2 && dci->ctx.format == srsran_dci_format_nr_cg) { + return 3; + } else { + return 2; + } + return SRSRAN_SUCCESS; + case srsran_dci_format_nr_0_1: + // For PUSCH scheduled by DCI format 0_1, by activation DCI format 0_1 with CRC scrambled by CS-RNTI, or + // configured by configured grant Type 1 configuration, the UE shall assume the DM-RS CDM groups indicated in + // Tables 7.3.1.1.2-6 to 7.3.1.1.2-23 of Clause 7.3.1.1 of [5, TS38.212] are not used for data transmission, where + // "1", "2" and "3" for the number of DM-RS CDM group(s) correspond to CDM group 0, {0,1}, {0,1,2}, respectively. + + // Table 7.3.1.1.2-6: Antenna port(s), transform precoder is enabled, dmrs-Type=1, maxLength=1 + if (cfg->enable_transform_precoder && cfg->dmrs_type == srsran_dmrs_sch_type_1 && + cfg->dmrs_max_length == srsran_dmrs_sch_len_1 && rank == 1) { + return 2; + } + + // Table 7.3.1.1.2-8: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank= 1 + if (!cfg->enable_transform_precoder && cfg->dmrs_type == srsran_dmrs_sch_type_1 && + cfg->dmrs_max_length == srsran_dmrs_sch_len_1 && rank == 1) { + if (dci->ports < 2) { + return 1; + } + + if (dci->ports < 6) { + return 2; + } + + ERROR("Invalid ports (%d)", dci->ports); + return SRSRAN_ERROR; + } + + ERROR("Unhandled configuration"); + return SRSRAN_ERROR; + default: + ERROR("Invalid UL DCI format %s", srsran_dci_format_nr_string(dci->ctx.format)); + } + + return SRSRAN_ERROR; } #define RA_UL_PUCCH_CODE_RATE_N 8 @@ -374,13 +437,35 @@ int srsran_ra_ul_nr_freq(const srsran_carrier_nr_t* carrier, return SRSRAN_ERROR_INVALID_INPUTS; } - // RA scheme - if (dci_ul->ctx.format == srsran_dci_format_nr_0_0 || dci_ul->ctx.format == srsran_dci_format_nr_rar) { - // when the scheduling grant is received with DCI format 1_0 , then downlink resource allocation type 1 is used. + // TS 38.213 PUSCH scheduled by RAR UL grant + if (dci_ul->ctx.format == srsran_dci_format_nr_rar) { return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant); } - ERROR("Unhandled DCI Format %s", srsran_dci_format_nr_string(dci_ul->ctx.format)); + // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource + // allocation type 1 is used. + if (dci_ul->ctx.format == srsran_dci_format_nr_0_0) { + return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant); + } + + // If the scheduling DCI is configured to indicate the uplink resource allocation type as part of the Frequency domain + // resource assignment field by setting a higher layer parameter resourceAllocation in pusch-Config to 'dynamicSwitch' + if (cfg->alloc == srsran_resource_alloc_dynamic) { + ERROR("Unsupported dynamic resource allocation"); + return SRSRAN_ERROR; + } + + // Otherwise the UE shall use the uplink frequency resource allocation type as defined by the higher layer parameter + // resourceAllocation. + if (cfg->alloc == srsran_resource_alloc_type1) { + return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant); + } + + if (cfg->alloc == srsran_resource_alloc_type0) { + return ra_helper_freq_type0(carrier, cfg, dci_ul->freq_domain_assigment, grant); + } + + ERROR("Unhandled case"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/test/dci_nr_test.c b/lib/src/phy/phch/test/dci_nr_test.c index 6283a4e82..d808cf597 100644 --- a/lib/src/phy/phch/test/dci_nr_test.c +++ b/lib/src/phy/phch/test/dci_nr_test.c @@ -55,11 +55,11 @@ static int test_52prb_base() cfg.enable_transform_precoding = false; cfg.dynamic_dual_harq_ack_codebook = false; cfg.pusch_tx_config_non_codebook = false; - cfg.pusch_dmrs_type2 = false; - cfg.pusch_dmrs_double = false; cfg.pusch_ptrs = false; cfg.pusch_dynamic_betas = false; cfg.pusch_alloc_type = srsran_resource_alloc_type1; + cfg.pusch_dmrs_type = srsran_dmrs_sch_type_1; + cfg.pusch_dmrs_max_len = srsran_dmrs_sch_len_1; // DCI 1_1 parameters cfg.nof_dl_bwp = 0; @@ -72,12 +72,12 @@ static int test_52prb_base() cfg.pdsch_rm_pattern2 = false; cfg.pdsch_2cw = false; cfg.multiple_scell = false; - cfg.pdsch_dmrs_type2 = false; - cfg.pdsch_dmrs_double = false; cfg.pdsch_tci = false; cfg.pdsch_cbg_flush = false; cfg.pdsch_dynamic_bundling = false; cfg.pdsch_alloc_type = srsran_resource_alloc_type1; + cfg.pdsch_dmrs_type = srsran_dmrs_sch_type_1; + cfg.pdsch_dmrs_max_len = srsran_dmrs_sch_len_1; // Configure DCI srsran_dci_nr_t dci = {}; diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index 93a6ed094..f353cf3f8 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -160,15 +160,11 @@ int main(int argc, char** argv) goto clean_exit; } - // Load number of DMRS CDM groups without data - if (srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg.dmrs, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups without data"); - goto clean_exit; - } - - pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; - pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; - pdsch_cfg.grant.rnti = rnti; + // Set PDSCH grant without considering any procedure + pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO + pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; + pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; + pdsch_cfg.grant.rnti = rnti; uint32_t n_prb_start = 1; uint32_t n_prb_end = carrier.nof_prb + 1; diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index 2ccdb2286..f88e1b938 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -166,15 +166,11 @@ int main(int argc, char** argv) goto clean_exit; } - // Load number of DMRS CDM groups without data - if (srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_cfg.grant) < SRSRAN_SUCCESS) { - ERROR("Error loading number of DMRS CDM groups without data"); - goto clean_exit; - } - - pusch_cfg.grant.nof_layers = carrier.max_mimo_layers; - pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; - pusch_cfg.grant.rnti = rnti; + // Set PDSCH grant without considering any procedure + pusch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO + pusch_cfg.grant.nof_layers = carrier.max_mimo_layers; + pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; + pusch_cfg.grant.rnti = rnti; uint32_t n_prb_start = 1; uint32_t n_prb_end = carrier.nof_prb + 1; diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index 5913604c0..2e633febd 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -179,12 +179,7 @@ int main(int argc, char** argv) for (uint32_t n = 0; n < SRSRAN_MAX_PRB_NR; n++) { pdsch_cfg.grant.prb_idx[n] = (n < n_prb); } - - if (srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg.dmrs, &pdsch_cfg.grant) < - SRSRAN_SUCCESS) { - ERROR("Error calculating number of DMRS CDM groups"); - goto clean_exit; - } + pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO srsran_sch_tb_t tb = {}; tb.rv = rv;