Refactored PHY NR procedures for supporting DCI formats 0_1 and 1_1

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent bbea3dd6a1
commit a8e181971c

@ -93,11 +93,11 @@ struct phy_cfg_nr_t {
dci_cfg.enable_transform_precoding = false; dci_cfg.enable_transform_precoding = false;
dci_cfg.dynamic_dual_harq_ack_codebook = false; dci_cfg.dynamic_dual_harq_ack_codebook = false;
dci_cfg.pusch_tx_config_non_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_ptrs = false;
dci_cfg.pusch_dynamic_betas = false; dci_cfg.pusch_dynamic_betas = false;
dci_cfg.pusch_alloc_type = pusch.alloc; 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) // Format 1_1 specific configuration (for PDSCH only)
dci_cfg.nof_dl_bwp = 0; dci_cfg.nof_dl_bwp = 0;
@ -112,12 +112,12 @@ struct phy_cfg_nr_t {
dci_cfg.pdsch_rm_pattern2 = false; dci_cfg.pdsch_rm_pattern2 = false;
dci_cfg.pdsch_2cw = false; dci_cfg.pdsch_2cw = false;
dci_cfg.multiple_scell = 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_tci = false;
dci_cfg.pdsch_cbg_flush = false; dci_cfg.pdsch_cbg_flush = false;
dci_cfg.pdsch_dynamic_bundling = false; dci_cfg.pdsch_dynamic_bundling = false;
dci_cfg.pdsch_alloc_type = pdsch.alloc; 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; return dci_cfg;
}; };

@ -57,11 +57,11 @@ typedef struct SRSRAN_API {
bool enable_transform_precoding; ///< Set to true if PUSCH transform precoding is enabled 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 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_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_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 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_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) /// 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 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_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 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 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_tci; ///< Set to true if tci-PresentInDCI is enabled
bool pdsch_cbg_flush; ///< Set to true if codeBlockGroupFlushIndicator is true 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 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; } srsran_dci_cfg_nr_t;
/** /**

@ -184,10 +184,10 @@ typedef struct SRSRAN_API {
bool scrambling_id_present; bool scrambling_id_present;
uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023) 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 { struct {
srsran_dmrs_sch_type_t type;
srsran_dmrs_sch_add_pos_t additional_pos; srsran_dmrs_sch_add_pos_t additional_pos;
srsran_dmrs_sch_len_t length;
bool scrambling_id0_present; bool scrambling_id0_present;
uint32_t scrambling_id0; uint32_t scrambling_id0;
bool scrambling_id1_present; bool scrambling_id1_present;
@ -196,9 +196,7 @@ typedef struct SRSRAN_API {
} dmrs_typeA; } dmrs_typeA;
struct { struct {
srsran_dmrs_sch_type_t type;
srsran_dmrs_sch_add_pos_t additional_pos; srsran_dmrs_sch_add_pos_t additional_pos;
srsran_dmrs_sch_len_t length;
bool scrambling_id0_present; bool scrambling_id0_present;
uint32_t scrambling_id0; uint32_t scrambling_id0;
bool scrambling_id1_present; bool scrambling_id1_present;
@ -225,6 +223,7 @@ typedef struct SRSRAN_API {
/// PUSCH only /// 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. float scaling; /// Indicates a scaling factor to limit the number of resource elements assigned to UCI on PUSCH.
} srsran_sch_hl_cfg_nr_t; } srsran_sch_hl_cfg_nr_t;

@ -62,17 +62,32 @@ SRSRAN_API int srsran_ra_dl_nr_time(const srsran_sch_hl_cfg_nr_t* cfg,
*/ */
SRSRAN_API int 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); 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 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_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
* *
* @param cfg PDSCH-DMRS NR configuration by upper layers * @remark Defined by TS 38.214 V15.10.0 5.1.6.2 DM-RS reception procedure
* @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 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_format_1_0(const srsran_dmrs_sch_cfg_t* cfg, SRSRAN_API int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg,
srsran_sch_grant_nr_t* grant); 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. * @brief Calculates the PDSCH frequency resource allocation and stores it in the provided PDSCH NR grant.

@ -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); 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 * @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 cfg PUSCH NR configuration by upper layers
* @param[out] grant Provides grant pointer to fill * @param dci Provides PUSCH NR DCI
* @return Returns SRSRAN_SUCCESS if the provided data is valid, otherwise it returns SRSRAN_ERROR code * @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_API int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg,
srsran_sch_grant_nr_t* grant); const srsran_dci_ul_nr_t* dci,
uint32_t L);
/** /**
* @brief Calculates the ratio of PUSCH EPRE to DM-RS EPRE * @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. * @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 carrier Carrier information
* @param cfg PDSCH NR configuration by upper layers * @param cfg PDSCH NR configuration by upper layers
* @param dci_dl Unpacked DCI used to schedule the PDSCH grant * @param dci_dl Unpacked DCI used to schedule the PDSCH grant

@ -84,6 +84,65 @@ static uint32_t dci_nr_ptrs_size(const srsran_dci_cfg_nr_t* cfg)
return 2; 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) 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); 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 // Antenna ports
if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { count += dci_nr_ul_ports_size(cfg);
count += 3;
} else {
ERROR("Not implemented");
return 0;
}
// SRS request - 2 or 3 bits // SRS request - 2 or 3 bits
count += cfg->enable_sul ? 3 : 2; 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 // Antenna ports
if (!cfg->enable_transform_precoding && !cfg->pusch_dmrs_double) { srsran_bit_unpack(dci->ports, &y, dci_nr_ul_ports_size(cfg));
srsran_bit_unpack(dci->ports, &y, 3);
} else {
ERROR("Not implemented");
return 0;
}
// SRS request - 2 or 3 bits // SRS request - 2 or 3 bits
srsran_bit_unpack(dci->srs_request, &y, cfg->enable_sul ? 3 : 2); 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 // 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); dci->ports = srsran_bit_pack(&y, 3);
} else { } else {
ERROR("Not implemented"); 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 // 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); len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports);
} else {
ERROR("Not implemented");
return 0;
} }
// SRS request - 2 bits // SRS request - 2 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); count += (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack);
// Antenna port(s) 4, 5, or 6 bits // Antenna port(s) 4, 5, or 6 bits
count += 4; count += dci_nr_dl_ports_size(cfg);
if (cfg->pdsch_dmrs_type2) {
count++;
}
if (cfg->pdsch_dmrs_double) {
count++;
}
// Transmission configuration indication 0 or 3 bits // Transmission configuration indication 0 or 3 bits
if (cfg->pdsch_tci) { 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)); srsran_bit_unpack(dci->harq_feedback, &y, (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack));
// Antenna port(s) 4, 5, or 6 bits // Antenna port(s) 4, 5, or 6 bits
srsran_bit_unpack(dci->ports, &y, 4); srsran_bit_unpack(dci->ports, &y, dci_nr_dl_ports_size(cfg));
if (cfg->pdsch_dmrs_type2) {
y++;
}
if (cfg->pdsch_dmrs_double) {
y++;
}
// Transmission configuration indication 0 or 3 bits // Transmission configuration indication 0 or 3 bits
if (cfg->pdsch_tci) { 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)); dci->harq_feedback = srsran_bit_pack(&y, (int)CEIL_LOG2(cfg->nof_dl_to_ul_ack));
// Antenna port(s) 4, 5, or 6 bits // Antenna port(s) 4, 5, or 6 bits
dci->ports = srsran_bit_pack(&y, 4); dci->ports = srsran_bit_pack(&y, dci_nr_dl_ports_size(cfg));
if (cfg->pdsch_dmrs_type2) {
y++;
}
if (cfg->pdsch_dmrs_double) {
y++;
}
// Transmission configuration indication 0 or 3 bits // Transmission configuration indication 0 or 3 bits
if (cfg->pdsch_tci) { 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 // Antenna port(s) 4, 5, or 6 bits
if (dci_nr_dl_ports_size(cfg) > 0) {
len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports); len = srsran_print_check(str, str_len, len, "ports=%d ", dci->ports);
}
// Transmission configuration indication 0 or 3 bits // Transmission configuration indication 0 or 3 bits
if (cfg->pdsch_tci) { if (cfg->pdsch_tci) {

@ -189,69 +189,98 @@ int srsran_ra_dl_nr_time(const srsran_sch_hl_cfg_nr_t* cfg,
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srsran_dmrs_sch_cfg_t* cfg, int srsran_ra_dl_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg,
srsran_sch_grant_nr_t* grant) const srsran_dci_dl_nr_t* dci,
srsran_dmrs_sch_len_t* dmrs_duration)
{ {
if (cfg == NULL || grant == NULL) { // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1
return SRSRAN_ERROR_INVALID_INPUTS; // 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: // Table 7.3.1.2.2-2: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=2
* When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups without data if (cfg->dmrs_type == srsran_dmrs_sch_type_1 && cfg->dmrs_max_length == srsran_dmrs_sch_len_2) {
* is 1 which corresponds to CDM group 0 for the case of PDSCH with allocation duration of 2 symbols, and the UE // Only one codeword supported!
* shall assume that the number of DM-RS CDM groups without data is 2 which corresponds to CDM group {0,1} for all if (dci->ports < 12) {
* other cases. *dmrs_duration = srsran_dmrs_sch_len_1;
*/ return SRSRAN_SUCCESS;
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;
} }
if (dci->ports < 31) {
*dmrs_duration = srsran_dmrs_sch_len_2;
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
/* RBG size for type0 scheduling as in table 5.1.2.2.1-1 of 36.214 */ ERROR("reserved value for ports (%d)", dci->ports);
uint32_t srsran_ra_dl_nr_type0_P(uint32_t bwp_size, bool config_is_1) return SRSRAN_ERROR;
{ }
if (bwp_size <= 36) {
return config_is_1 ? 2 : 4; // Table 7.3.1.2.2-4: Antenna port(s) (1000 + DMRS port), dmrs-Type=2, maxLength=2
} else if (bwp_size <= 72) { if (cfg->dmrs_type == srsran_dmrs_sch_type_2 && cfg->dmrs_max_length == srsran_dmrs_sch_len_2) {
return config_is_1 ? 4 : 8; // Only one codeword supported!
} else if (bwp_size <= 144) { if (dci->ports < 3) {
return config_is_1 ? 8 : 16; *dmrs_duration = srsran_dmrs_sch_len_1;
} else { return SRSRAN_SUCCESS;
return 16; }
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;
} }
static int ra_freq_type0(const srsran_carrier_nr_t* carrier, int srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(const srsran_sch_hl_cfg_nr_t* cfg,
const srsran_sch_hl_cfg_nr_t* cfg, const srsran_dci_dl_nr_t* dci,
const srsran_dci_dl_nr_t* dci_dl, uint32_t L)
srsran_sch_grant_nr_t* grant)
{ {
uint32_t P = srsran_ra_dl_nr_type0_P(carrier->nof_prb, cfg->rbg_size_cfg_1); // According to TS 38.214 5.1.6.2 DM-RS reception procedure
switch (dci->ctx.format) {
uint32_t N_rbg = (int)ceilf((float)(carrier->nof_prb + (carrier->start % P)) / P); case srsran_dci_format_nr_1_0:
uint32_t rbg_offset = 0; // When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups
for (uint32_t i = 0; i < N_rbg; i++) { // without data is 1 which corresponds to CDM group 0 for the case of PDSCH with allocation duration of 2 symbols,
uint32_t rbg_size = P; // and the UE shall assume that the number of DM-RS CDM groups without data is 2 which corresponds to CDM group
if (i == 0) { // {0,1} for all other cases.
rbg_size -= (carrier->start % P); if (L == 2) {
} else if ((i == N_rbg - 1) && ((carrier->nof_prb + carrier->start) % P) > 0) { return 1;
rbg_size = (carrier->nof_prb + carrier->start) % P; } else {
return 2;
} }
if (dci_dl->freq_domain_assigment & (1 << (N_rbg - i - 1))) { return SRSRAN_SUCCESS;
for (uint32_t j = 0; j < rbg_size; j++) { case srsran_dci_format_nr_0_1:
if (rbg_offset + j < carrier->nof_prb) { // When receiving PDSCH scheduled by DCI format 1_1, the UE shall assume that the CDM groups indicated in the
grant->prb_idx[rbg_offset + j] = true; // 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
grant->nof_prb++; // 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;
} }
rbg_offset += rbg_size;
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, 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); 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"); ERROR("Only DCI Format 1_0 is supported");
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }

@ -14,8 +14,52 @@
#define SRSRAN_RA_HELPER_H #define SRSRAN_RA_HELPER_H
#include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/vector.h"
#include <stdint.h> #include <stdint.h>
/* 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) 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; uint32_t low = v % N;

@ -528,13 +528,13 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg,
return SRSRAN_SUCCESS; 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 = 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 (dci->ctx.format == srsran_dci_format_nr_1_0 || !dedicated_dmrs_present) {
if (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 // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig
cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2;
cfg->dmrs.type = srsran_dmrs_sch_type_1; 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; return SRSRAN_ERROR;
} }
} else { } 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.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_id0_present = false;
cfg->dmrs.scrambling_id1_present = false; cfg->dmrs.scrambling_id1_present = false;
} else { } else {
cfg->dmrs.additional_pos = hl_cfg->dmrs_typeB.additional_pos; 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_id0_present = false;
cfg->dmrs.scrambling_id1_present = false; cfg->dmrs.scrambling_id1_present = false;
} }
} }
// Set number of DMRS CDM groups without data // Set number of DMRS CDM groups without data
if (grant->dci_format == srsran_dci_format_nr_1_0) { int n = srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data(hl_cfg, dci, cfg->grant.L);
if (srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&cfg->dmrs, grant) < SRSRAN_SUCCESS) { if (n < SRSRAN_SUCCESS) {
ERROR("Error loading number of DMRS CDM groups"); ERROR("Error loading number of DMRS CDM groups");
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }
} else { cfg->grant.nof_dmrs_cdm_groups_without_data = (uint32_t)n;
ERROR("Invalid case");
return SRSRAN_ERROR;
}
// Set DMRS power offset Table 6.2.2-1: The ratio of PUSCH EPRE to DM-RS EPRE // 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"); ERROR("Error setting DMRS power offset");
return SRSRAN_ERROR; 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 // 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"); ERROR("Error selecting DMRS configuration");
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }
@ -697,15 +700,15 @@ int srsran_ra_dl_dci_to_grant_nr(const srsran_carrier_nr_t* carrier,
} }
static int 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_typeA.present
: pusch_hl_cfg->dmrs_typeB.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) { !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 // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig
cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2;
cfg->dmrs.type = srsran_dmrs_sch_type_1; 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; return SRSRAN_ERROR;
} }
} else { } 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.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_id0_present = false;
cfg->dmrs.scrambling_id1_present = false; cfg->dmrs.scrambling_id1_present = false;
} else { } else {
cfg->dmrs.additional_pos = pusch_hl_cfg->dmrs_typeB.additional_pos; 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_id0_present = false;
cfg->dmrs.scrambling_id1_present = false; cfg->dmrs.scrambling_id1_present = false;
} }
} }
// Set number of DMRS CDM groups without data // 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) { int n = srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data(pusch_hl_cfg, dci, cfg->grant.L);
if (srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(cfg, pusch_grant) < SRSRAN_SUCCESS) { if (n < SRSRAN_SUCCESS) {
ERROR("Error loading number of DMRS CDM groups"); ERROR("Error getting number of DMRS CDM groups without data");
return SRSRAN_ERROR;
}
} else {
ERROR("DCI format not implemented %s", srsran_dci_format_nr_string(pusch_grant->dci_format));
return SRSRAN_ERROR; 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 // 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"); ERROR("Error setting DMRS power offset");
return SRSRAN_ERROR; 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; pusch_grant->tb[0].ndi = dci_ul->ndi;
// 5.1.6.2 DM-RS reception procedure // 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"); ERROR("Error selecting DMRS configuration");
return SRSRAN_ERROR; return SRSRAN_ERROR;
} }

@ -196,31 +196,94 @@ int srsran_ra_ul_nr_time(const srsran_sch_hl_cfg_nr_t* cfg,
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
} }
int srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srsran_sch_cfg_nr_t* cfg, int srsran_ra_ul_nr_nof_front_load_symbols(const srsran_sch_hl_cfg_nr_t* cfg,
srsran_sch_grant_nr_t* grant) 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; return SRSRAN_ERROR_INVALID_INPUTS;
} }
/* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure: // Table 7.3.1.1.2-6: Antenna port(s), transform precoder is enabled, dmrs-Type=1, maxLength=1
* For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE // Table 7.3.1.1.2-8: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=1
* shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of // Table 7.3.1.1.2-9: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=2
* PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume // Table 7.3.1.1.2-10: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=3
* 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 // Table 7.3.1.1.2-11: Antenna port(s), transform precoder is disabled, dmrs-Type=1, maxLength=1, rank=4
* scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH // Table 7.3.1.1.2-16: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=1
* allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups // Table 7.3.1.1.2-17: Antenna port(s), transform precoder is disabled, dmrs-Type=2, maxLength=1, rank=2
* without data is 2 which corresponds to CDM group {0,1} for all other cases. // 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 (grant->L <= 2 && !cfg->enable_transform_precoder) { if (cfg->dmrs_max_length == srsran_dmrs_sch_len_1) {
grant->nof_dmrs_cdm_groups_without_data = 1; *dmrs_duration = srsran_dmrs_sch_len_1;
// } else if (grant->L > 2 && cfg->dmrs_cg.type == srsran_dmrs_sch_type_2){ return SRSRAN_SUCCESS;
// grant->nof_dmrs_cdm_groups_without_data = 3;
} else {
grant->nof_dmrs_cdm_groups_without_data = 2;
} }
// 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; 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 #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; return SRSRAN_ERROR_INVALID_INPUTS;
} }
// RA scheme // TS 38.213 PUSCH scheduled by RAR UL grant
if (dci_ul->ctx.format == srsran_dci_format_nr_0_0 || dci_ul->ctx.format == srsran_dci_format_nr_rar) { if (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.
return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant); 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; return SRSRAN_ERROR;
} }

@ -55,11 +55,11 @@ static int test_52prb_base()
cfg.enable_transform_precoding = false; cfg.enable_transform_precoding = false;
cfg.dynamic_dual_harq_ack_codebook = false; cfg.dynamic_dual_harq_ack_codebook = false;
cfg.pusch_tx_config_non_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_ptrs = false;
cfg.pusch_dynamic_betas = false; cfg.pusch_dynamic_betas = false;
cfg.pusch_alloc_type = srsran_resource_alloc_type1; 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 // DCI 1_1 parameters
cfg.nof_dl_bwp = 0; cfg.nof_dl_bwp = 0;
@ -72,12 +72,12 @@ static int test_52prb_base()
cfg.pdsch_rm_pattern2 = false; cfg.pdsch_rm_pattern2 = false;
cfg.pdsch_2cw = false; cfg.pdsch_2cw = false;
cfg.multiple_scell = false; cfg.multiple_scell = false;
cfg.pdsch_dmrs_type2 = false;
cfg.pdsch_dmrs_double = false;
cfg.pdsch_tci = false; cfg.pdsch_tci = false;
cfg.pdsch_cbg_flush = false; cfg.pdsch_cbg_flush = false;
cfg.pdsch_dynamic_bundling = false; cfg.pdsch_dynamic_bundling = false;
cfg.pdsch_alloc_type = srsran_resource_alloc_type1; 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 // Configure DCI
srsran_dci_nr_t dci = {}; srsran_dci_nr_t dci = {};

@ -160,12 +160,8 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
// Load number of DMRS CDM groups without data // Set PDSCH grant without considering any procedure
if (srsran_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg.dmrs, &pdsch_cfg.grant) < SRSRAN_SUCCESS) { pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO
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.nof_layers = carrier.max_mimo_layers;
pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0;
pdsch_cfg.grant.rnti = rnti; pdsch_cfg.grant.rnti = rnti;

@ -166,12 +166,8 @@ int main(int argc, char** argv)
goto clean_exit; goto clean_exit;
} }
// Load number of DMRS CDM groups without data // Set PDSCH grant without considering any procedure
if (srsran_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_cfg.grant) < SRSRAN_SUCCESS) { pusch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO
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.nof_layers = carrier.max_mimo_layers;
pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0;
pusch_cfg.grant.rnti = rnti; pusch_cfg.grant.rnti = rnti;

@ -179,12 +179,7 @@ int main(int argc, char** argv)
for (uint32_t n = 0; n < SRSRAN_MAX_PRB_NR; n++) { for (uint32_t n = 0; n < SRSRAN_MAX_PRB_NR; n++) {
pdsch_cfg.grant.prb_idx[n] = (n < n_prb); pdsch_cfg.grant.prb_idx[n] = (n < n_prb);
} }
pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO
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;
}
srsran_sch_tb_t tb = {}; srsran_sch_tb_t tb = {};
tb.rv = rv; tb.rv = rv;

Loading…
Cancel
Save