Fix PDSCH-DMRS symbol index

This commit is contained in:
Xavier Arteaga 2020-10-20 11:05:11 +02:00 committed by Xavier Arteaga
parent 275cbafe6e
commit 30d8e05d50
3 changed files with 46 additions and 32 deletions

View File

@ -32,8 +32,6 @@ extern "C" {
#include <stdint.h>
#define SRSLTE_DMRS_PDSCH_MAX_SYMBOLS 4
#define SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN 3
#define SRSLTE_DMRS_PDSCH_TYPEA_DOUBLE_DURATION_MIN 4
/**
* @brief PDSCH DMRS estimator object

View File

@ -78,13 +78,13 @@ typedef struct {
srslte_dmrs_pdsch_type_t type;
srslte_dmrs_pdsch_add_pos_t additional_pos;
srslte_dmrs_pdsch_len_t length;
srslte_dmrs_pdsch_typeA_pos_t typeA_pos;
bool scrambling_id0_present;
uint32_t scrambling_id0;
bool scrambling_id1_present;
uint32_t scrambling_id1;
/// Parameters provided by ServingCellConfig
/// Parameters provided by ServingCellConfigCommon
srslte_dmrs_pdsch_typeA_pos_t typeA_pos;
bool lte_CRS_to_match_around;
/// Parameters provided by FeatureSetDownlink-v1540

View File

@ -22,6 +22,9 @@
#include "srslte/phy/ch_estimation/dmrs_pdsch.h"
#include <srslte/phy/utils/debug.h>
#define SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN 3
#define SRSLTE_DMRS_PDSCH_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 type = (int)cfg->type + 1;
@ -221,11 +224,12 @@ 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_cfg_nr_t* cfg,
uint32_t ld,
uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS])
{
int count = 0;
if (cfg->grant.L < SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN) {
if (ld < SRSLTE_DMRS_PDSCH_TYPEA_SINGLE_DURATION_MIN) {
ERROR("Duration is below the minimum\n");
return SRSLTE_ERROR;
}
@ -247,14 +251,14 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_
symbols[count] = l0;
count++;
if (cfg->grant.L < 8 || cfg->dmrs_cfg.additional_pos == srslte_dmrs_pdsch_add_pos_0) {
if (ld < 8 || cfg->dmrs_cfg.additional_pos == srslte_dmrs_pdsch_add_pos_0) {
return count;
}
if (cfg->grant.L < 10) {
if (ld < 10) {
symbols[count] = 7;
count++;
} else if (cfg->grant.L < 12) {
} else if (ld < 12) {
if (cfg->dmrs_cfg.additional_pos > srslte_dmrs_pdsch_add_pos_2) {
symbols[count] = 6;
count++;
@ -263,7 +267,7 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(const srslte_
symbols[count] = 9;
count++;
} else if (cfg->grant.L == 12) {
} else if (ld == 12) {
switch (cfg->dmrs_cfg.additional_pos) {
case srslte_dmrs_pdsch_add_pos_1:
symbols[count] = 9;
@ -310,11 +314,12 @@ 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_cfg_nr_t* cfg,
uint32_t ld,
uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS])
{
int count = 0;
if (cfg->grant.L < SRSLTE_DMRS_PDSCH_TYPEA_DOUBLE_DURATION_MIN) {
if (ld < SRSLTE_DMRS_PDSCH_TYPEA_DOUBLE_DURATION_MIN) {
return SRSLTE_ERROR;
}
@ -326,11 +331,11 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_
symbols[count] = symbols[count - 1] + 1;
count++;
if (cfg->grant.L < 10 || cfg->dmrs_cfg.additional_pos == srslte_dmrs_pdsch_add_pos_0) {
if (ld < 10 || cfg->dmrs_cfg.additional_pos == srslte_dmrs_pdsch_add_pos_0) {
return count;
}
if (cfg->grant.L < 13) {
if (ld < 13) {
symbols[count] = 8;
count++;
symbols[count] = symbols[count - 1] + 1;
@ -347,6 +352,15 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_
int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* cfg, uint32_t symbols[SRSLTE_DMRS_PDSCH_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 = cfg->grant.L;
if (cfg->grant.mapping == srslte_pdsch_mapping_type_A) {
ld = cfg->grant.S + cfg->grant.L;
}
switch (cfg->grant.mapping) {
case srslte_pdsch_mapping_type_A:
// The case dmrs-AdditionalPosition equals to 'pos3' is only supported when dmrs-TypeA-Position is equal to 'pos2'
@ -359,16 +373,16 @@ int srslte_dmrs_pdsch_get_symbols_idx(const srslte_pdsch_cfg_nr_t* cfg, uint32_t
// 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 ((cfg->grant.L == 3 || cfg->grant.L == 4) && cfg->dmrs_cfg.typeA_pos != srslte_dmrs_pdsch_typeA_pos_2) {
if ((ld == 3 || ld == 4) && cfg->dmrs_cfg.typeA_pos != srslte_dmrs_pdsch_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 (cfg->dmrs_cfg.length == srslte_dmrs_pdsch_len_1) {
return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(cfg, symbols);
return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_single(cfg, ld, symbols);
}
return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(cfg, symbols);
return srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(cfg, ld, symbols);
case srslte_pdsch_mapping_type_B:
ERROR("Error PDSCH mapping type B not supported\n");
return SRSLTE_ERROR;
@ -451,17 +465,32 @@ void srslte_dmrs_pdsch_free(srslte_dmrs_pdsch_t* q)
int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_nr_t* carrier)
{
bool nof_prb_changed = q->carrier.nof_prb != carrier->nof_prb;
bool max_nof_prb_changed = q->max_nof_prb < carrier->nof_prb;
// Set carrier
// Set carrier and update maximum number of PRB
q->carrier = *carrier;
q->max_nof_prb = SRSLTE_MAX(q->max_nof_prb, carrier->nof_prb);
// Resize/allocate temp for gNb and UE
if (max_nof_prb_changed) {
if (q->temp) {
free(q->temp);
}
q->temp = srslte_vec_cf_malloc(q->max_nof_prb * SRSLTE_NRE);
if (!q->temp) {
ERROR("malloc\n");
return SRSLTE_ERROR;
}
}
// If it is not UE, quit now
if (!q->is_ue) {
return SRSLTE_SUCCESS;
}
// Free interpolator
if (nof_prb_changed) {
if (max_nof_prb_changed) {
// Resize interpolator only if the number of PRB has increased
srslte_interp_linear_free(&q->interpolator_type1);
srslte_interp_linear_free(&q->interpolator_type2);
@ -471,10 +500,7 @@ int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_n
if (srslte_interp_linear_init(&q->interpolator_type2, carrier->nof_prb * SRSLTE_NRE / 3, 6) != SRSLTE_SUCCESS) {
return SRSLTE_ERROR;
}
}
if (q->max_nof_prb < carrier->nof_prb) {
q->max_nof_prb = carrier->nof_prb;
if (q->pilot_estimates) {
free(q->pilot_estimates);
}
@ -485,16 +511,6 @@ int srslte_dmrs_pdsch_set_carrier(srslte_dmrs_pdsch_t* q, const srslte_carrier_n
ERROR("malloc\n");
return SRSLTE_ERROR;
}
if (q->temp) {
free(q->temp);
}
q->temp = srslte_vec_cf_malloc(q->max_nof_prb * SRSLTE_NRE);
if (!q->temp) {
ERROR("malloc\n");
return SRSLTE_ERROR;
}
}
return SRSLTE_SUCCESS;