Added number of DMRS CDM groups without data to NR grant

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent d413c1aaec
commit 13443c3f8c

@ -119,6 +119,10 @@ typedef struct SRSLTE_API {
/// Frequency domain resources
bool prb_idx[SRSLTE_MAX_PRB_NR];
/// Number of DMRS groups without data
/// Described in TS 38.214 Section 5.1.6.2
uint32_t nof_dmrs_cdm_groups_without_data;
/// Spatial resources
uint32_t nof_layers;

@ -58,6 +58,17 @@ SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocat
SRSLTE_API int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m,
srslte_dmrs_pdsch_typeA_pos_t dmrs_typeA_pos,
srslte_pdsch_grant_nr_t* grant);
/**
* @brief Calculates the number of PDSCH-DMRS CDM groups without data for DCI format 1_0
*
* @remark Defined by TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility
*
* @param pdsch_cfg PDSCH NR configuration by upper layers
* @param[out] grant Provides grant pointer to fill
* @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code
*/
SRSLTE_API int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_pdsch_cfg_nr_t* pdsch_cfg,
srslte_pdsch_grant_nr_t* grant);
#ifdef __cplusplus
}

@ -201,8 +201,7 @@ static int srslte_dmrs_pdsch_put_symbol(srslte_dmrs_pdsch_t* q,
}
// Get contiguous pilots
pilot_count += srslte_dmrs_put_pilots(
q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, &symbols[prb_start * SRSLTE_NRE]);
pilot_count += srslte_dmrs_put_pilots(q, &sequence_state, dmrs_cfg->type, prb_start, prb_count, delta, symbols);
// Reset counter
prb_count = 0;
@ -317,6 +316,12 @@ static int srslte_dmrs_pdsch_get_symbols_idx_mapping_type_A_double(const srslte_
return SRSLTE_ERROR;
}
// According to Table 7.4.1.1.2-4, the additional position 3 is invalid.
if (dmrs_cfg->additional_pos == srslte_dmrs_pdsch_add_pos_3) {
ERROR("Invalid additional DMRS (%d)\n", dmrs_cfg->additional_pos);
return SRSLTE_ERROR;
}
// l0 = 3 if the higher-layer parameter dmrs-TypeA-Position is equal to 'pos3' and l0 = 2 otherwise
int l0 = (dmrs_cfg->typeA_pos == srslte_dmrs_pdsch_typeA_pos_3) ? 3 : 2;
@ -414,6 +419,19 @@ int srslte_dmrs_pdsch_get_sc_idx(const srslte_pdsch_dmrs_cfg_t* cfg, uint32_t ma
int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_pdsch_grant_nr_t* grant)
{
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg =
grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB;
if (grant->nof_dmrs_cdm_groups_without_data < 1 || grant->nof_dmrs_cdm_groups_without_data > 3) {
ERROR("Invalid number if DMRS CDM groups without data (%d). Valid values: 1, 2 , 3\n",
grant->nof_dmrs_cdm_groups_without_data);
return SRSLTE_ERROR;
}
// Get number of frequency domain resource elements used for DMRS
int nof_sc = SRSLTE_MIN(
SRSLTE_NRE, grant->nof_dmrs_cdm_groups_without_data * (dmrs_cfg->type == srslte_dmrs_pdsch_type_1 ? 6 : 4));
// Get number of symbols used for DMRS
uint32_t symbols[SRSLTE_DMRS_PDSCH_MAX_SYMBOLS] = {};
int ret = srslte_dmrs_pdsch_get_symbols_idx(cfg, grant, symbols);
@ -422,7 +440,7 @@ int srslte_dmrs_pdsch_get_N_prb(const srslte_pdsch_cfg_nr_t* cfg, const srslte_p
return SRSLTE_ERROR;
}
return SRSLTE_NRE * ret;
return nof_sc * ret;
}
static uint32_t srslte_dmrs_pdsch_seed(const srslte_carrier_nr_t* carrier,
@ -733,11 +751,34 @@ int srslte_dmrs_pdsch_estimate(srslte_dmrs_pdsch_t* q,
}
if (symbols[symbol_idx] == l) {
continue;
switch (dmrs_cfg->type) {
case srslte_dmrs_pdsch_type_1:
// Skip if there is no data to read
if (grant->nof_dmrs_cdm_groups_without_data != 1) {
continue;
}
for (uint32_t i = 1; i < nof_re_x_symbol; i += 2) {
chest_res->ce[0][0][count] = ce[i];
count++;
}
break;
case srslte_dmrs_pdsch_type_2:
// Skip if there is no data to read
if (grant->nof_dmrs_cdm_groups_without_data != 1 && grant->nof_dmrs_cdm_groups_without_data != 2) {
continue;
}
for (uint32_t i = grant->nof_dmrs_cdm_groups_without_data * 2; i < nof_re_x_symbol; i += 6) {
uint32_t nof_re = (3 - grant->nof_dmrs_cdm_groups_without_data) * 2;
srslte_vec_cf_copy(&chest_res->ce[0][0][count], &ce[i], nof_re);
count += nof_re;
}
break;
}
} else {
srslte_vec_cf_copy(&chest_res->ce[0][0][count], ce, nof_re_x_symbol);
count += nof_re_x_symbol;
}
srslte_vec_cf_copy(&chest_res->ce[0][0][count], ce, nof_re_x_symbol);
count += nof_re_x_symbol;
}
// Set other values in the estimation result
chest_res->nof_re = count;

@ -216,9 +216,10 @@ static int run_test(srslte_dmrs_pdsch_t* dmrs_pdsch,
srslte_dl_slot_cfg_t slot_cfg = {};
for (slot_cfg.idx = 0; slot_cfg.idx < SRSLTE_NSLOTS_PER_FRAME_NR(dmrs_pdsch->carrier.numerology); slot_cfg.idx++) {
srslte_dmrs_pdsch_put_sf(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols);
TESTASSERT(srslte_dmrs_pdsch_put_sf(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols) == SRSLTE_SUCCESS);
srslte_dmrs_pdsch_estimate(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols, chest_res);
TESTASSERT(srslte_dmrs_pdsch_estimate(dmrs_pdsch, &slot_cfg, pdsch_cfg, grant, sf_symbols, chest_res) ==
SRSLTE_SUCCESS);
float mse = 0.0f;
for (uint32_t i = 0; i < chest_res->nof_re; i++) {
@ -294,6 +295,12 @@ int main(int argc, char** argv)
srslte_dmrs_pdsch_len_t max_len_begin = srslte_dmrs_pdsch_len_1;
srslte_dmrs_pdsch_len_t max_len_end = srslte_dmrs_pdsch_len_2;
// Only single DMRS symbols can have additional positions 2 and 3
if (pdsch_cfg.dmrs_cfg_typeA.additional_pos == srslte_dmrs_pdsch_add_pos_2 ||
pdsch_cfg.dmrs_cfg_typeA.additional_pos == srslte_dmrs_pdsch_add_pos_3) {
max_len_end = srslte_dmrs_pdsch_len_1;
}
for (pdsch_cfg.dmrs_cfg_typeA.length = max_len_begin; pdsch_cfg.dmrs_cfg_typeA.length <= max_len_end;
pdsch_cfg.dmrs_cfg_typeA.length++) {
@ -303,28 +310,32 @@ int main(int argc, char** argv)
grant.prb_idx[i] = (i < bw);
}
// Load default type A grant
srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &grant);
for (grant.nof_dmrs_cdm_groups_without_data = 1; grant.nof_dmrs_cdm_groups_without_data <= 3;
grant.nof_dmrs_cdm_groups_without_data++) {
// Copy configuration
pdsch_cfg.dmrs_cfg_typeB = pdsch_cfg.dmrs_cfg_typeA;
// Load default type A grant
srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &grant);
int n = run_test(&dmrs_pdsch, &pdsch_cfg, &grant, sf_symbols, &chest_dl_res);
// Copy configuration
pdsch_cfg.dmrs_cfg_typeB = pdsch_cfg.dmrs_cfg_typeA;
if (n == SRSLTE_SUCCESS) {
test_passed++;
} else {
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = grant.mapping == srslte_pdsch_mapping_type_A
? &pdsch_cfg.dmrs_cfg_typeA
: &pdsch_cfg.dmrs_cfg_typeB;
int n = run_test(&dmrs_pdsch, &pdsch_cfg, &grant, sf_symbols, &chest_dl_res);
char str[64] = {};
srslte_dmrs_pdsch_cfg_to_str(dmrs_cfg, str, 64);
if (n == SRSLTE_SUCCESS) {
test_passed++;
} else {
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg = grant.mapping == srslte_pdsch_mapping_type_A
? &pdsch_cfg.dmrs_cfg_typeA
: &pdsch_cfg.dmrs_cfg_typeB;
ERROR("Test %d failed. %s.\n", test_counter, str);
}
char str[64] = {};
srslte_dmrs_pdsch_cfg_to_str(dmrs_cfg, str, 64);
test_counter++;
ERROR("Test %d failed. %s.\n", test_counter, str);
}
test_counter++;
}
}
}
}

@ -168,9 +168,129 @@ void srslte_pdsch_nr_free(srslte_pdsch_nr_t* q)
if (q->evm_buffer != NULL) {
srslte_evm_free(q->evm_buffer);
}
}
/**
* @brief copies a number of countiguous Resource Elements
* @param sf_symbols slot symbols in frequency domain
* @param symbols resource elements
* @param count number of resource elements to copy
* @param put Direction, symbols are copied into sf_symbols if put is true, otherwise sf_symbols are copied into symbols
*/
static void srslte_pdsch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, bool put)
{
if (put) {
srslte_vec_cf_copy(sf_symbols, symbols, count);
} else {
srslte_vec_cf_copy(symbols, sf_symbols, count);
}
}
/*
* As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with group 2:
*
* +---+---+---+---+---+---+---+---+---+---+---+---+
* | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 |
* +---+---+---+---+---+---+---+---+---+---+---+---+
* -- k -->
*
* If the number of DMRS CDM groups without data is set to:
* - 1, data is mapped in RE marked as 2
* - Otherwise, no data is mapped in this symbol
*/
static uint32_t srslte_pdsch_nr_cp_dmrs_type1(const srslte_pdsch_nr_t* q,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
uint32_t delta = 0;
if (grant->nof_dmrs_cdm_groups_without_data != 1) {
return count;
}
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
if (grant->prb_idx[i]) {
for (uint32_t j = 0; j < SRSLTE_NRE; j += 2) {
if (put) {
sf_symbols[i * SRSLTE_NRE + delta + j + 1] = symbols[count++];
} else {
symbols[count++] = sf_symbols[i * SRSLTE_NRE + delta + j + 1];
}
}
}
}
// Make sure whole structure is fill with zeros
SRSLTE_MEM_ZERO(q, srslte_pdsch_nr_t, 1);
return count;
}
/*
* As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with groups 2 and 3:
*
* +---+---+---+---+---+---+---+---+---+---+---+---+
* | 1 | 1 | 2 | 2 | 3 | 3 | 1 | 1 | 2 | 2 | 3 | 3 |
* +---+---+---+---+---+---+---+---+---+---+---+---+
* -- k -->
*
* If the number of DMRS CDM groups without data is set to:
* - 1, data is mapped in RE marked as 2 and 3
* - 2, data is mapped in RE marked as 3
* - otherwise, no data is mapped in this symbol
*/
static uint32_t srslte_pdsch_nr_cp_dmrs_type2(const srslte_pdsch_nr_t* q,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
if (grant->nof_dmrs_cdm_groups_without_data != 1 && grant->nof_dmrs_cdm_groups_without_data != 2) {
return count;
}
uint32_t re_offset = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 2 : 4;
uint32_t re_count = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 4 : 2;
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
if (grant->prb_idx[i]) {
// Copy RE between pilot pairs
srslte_pdsch_re_cp(&sf_symbols[i * SRSLTE_NRE + re_offset], &symbols[count], re_count, put);
count += re_count;
// Copy RE after second pilot
srslte_pdsch_re_cp(&sf_symbols[(i + 1) * SRSLTE_NRE - re_count], &symbols[count], re_count, put);
count += re_count;
}
}
return count;
}
static uint32_t srslte_pdsch_nr_cp_dmrs(const srslte_pdsch_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg =
grant->mapping == srslte_pdsch_mapping_type_A ? &cfg->dmrs_cfg_typeA : &cfg->dmrs_cfg_typeB;
switch (dmrs_cfg->type) {
case srslte_dmrs_pdsch_type_1:
count = srslte_pdsch_nr_cp_dmrs_type1(q, grant, symbols, sf_symbols, put);
break;
case srslte_dmrs_pdsch_type_2:
count = srslte_pdsch_nr_cp_dmrs_type2(q, grant, symbols, sf_symbols, put);
break;
}
return count;
}
static uint32_t srslte_pdsch_nr_cp_clean(const srslte_pdsch_nr_t* q,
@ -236,8 +356,8 @@ static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q,
return SRSLTE_ERROR;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("dmrs_l_idx=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("dmrs_l_idx=");
srslte_vec_fprint_i(stdout, (int32_t*)dmrs_l_idx, nof_dmrs_symbols);
}
@ -249,12 +369,13 @@ static int srslte_pdsch_nr_cp(const srslte_pdsch_nr_t* q,
dmrs_l_count++;
}
// Skip DMRS symbol
if (l == dmrs_l_idx[dmrs_l_count]) {
continue;
count += srslte_pdsch_nr_cp_dmrs(
q, cfg, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put);
} else {
count +=
srslte_pdsch_nr_cp_clean(q, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put);
}
count += srslte_pdsch_nr_cp_clean(q, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSLTE_NRE], put);
}
return count;
@ -278,6 +399,20 @@ static int srslte_pdsch_nr_get(const srslte_pdsch_nr_t* q,
return srslte_pdsch_nr_cp(q, cfg, grant, symbols, sf_symbols, false);
}
static uint32_t
pdsch_nr_cinit(const srslte_carrier_nr_t* carrier, const srslte_pdsch_cfg_nr_t* cfg, uint16_t rnti, uint32_t cw_idx)
{
uint32_t n_id = carrier->id;
if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) {
n_id = cfg->scambling_id;
}
uint32_t cinit = (((uint32_t)rnti) << 15U) + (cw_idx << 14U) + n_id;
INFO("PDSCH: RNTI=%d (0x%x); nid=%d; cinit=%d (0x%x);\n", rnti, rnti, n_id, cinit, cinit);
return cinit;
}
static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_sch_tb_t* tb,
@ -307,24 +442,20 @@ static inline int pdsch_nr_encode_codeword(srslte_pdsch_nr_t* q,
return SRSLTE_ERROR;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
INFO("b=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("b=");
srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits);
}
// 7.3.1.1 Scrambling
uint32_t n_id = q->carrier.id;
if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) {
n_id = cfg->scambling_id;
}
uint32_t cinit = ((uint32_t)rnti << 15U) + (tb->cw_idx << 14U) + n_id;
uint32_t cinit = pdsch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx);
srslte_sequence_apply_bit(q->b[tb->cw_idx], q->b[tb->cw_idx], tb->nof_bits, cinit);
// 7.3.1.2 Modulation
srslte_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], tb->nof_bits);
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
INFO("d=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("d=");
srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
}
@ -422,8 +553,8 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q,
return SRSLTE_ERROR_OUT_OF_BOUNDS;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("d=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("d=");
srslte_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
}
@ -444,15 +575,10 @@ static inline int pdsch_nr_decode_codeword(srslte_pdsch_nr_t* q,
}
// Descrambling
uint32_t n_id = q->carrier.id;
if (cfg->scrambling_id_present && SRSLTE_RNTI_ISUSER(rnti)) {
n_id = cfg->scambling_id;
}
uint32_t cinit = ((uint32_t)rnti << 15U) + (tb->cw_idx << 14U) + n_id;
srslte_sequence_apply_c(llr, llr, tb->nof_bits, cinit);
srslte_sequence_apply_c(llr, llr, tb->nof_bits, pdsch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx));
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
printf("b=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("b=");
srslte_vec_fprint_b(stdout, q->b[tb->cw_idx], tb->nof_bits);
}
@ -501,10 +627,10 @@ int srslte_pdsch_nr_decode(srslte_pdsch_nr_t* q,
return SRSLTE_ERROR;
}
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
INFO("ce=");
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG && !handler_registered) {
DEBUG("ce=");
srslte_vec_fprint_c(stdout, channel->ce[0][0], nof_re);
INFO("x=");
DEBUG("x=");
srslte_vec_fprint_c(stdout, q->x[0], nof_re);
}

@ -303,6 +303,11 @@ uint32_t srslte_ra_nr_tbs(uint32_t N_re, double S, double R, uint32_t Qm, uint32
S = 1.0;
}
if (nof_layers == 0) {
ERROR("Incorrect number of layers (%d). Setting to 1.\n", nof_layers);
nof_layers = 1;
}
// 2) Intermediate number of information bits (N info ) is obtained by N inf o = N RE · R · Q m · υ .
uint32_t n_info = (uint32_t)(N_re * S * R * Qm * nof_layers);

@ -19,7 +19,7 @@
#include <getopt.h>
static srslte_carrier_nr_t carrier = {
0, // cell_id
1, // cell_id
0, // numerology
SRSLTE_MAX_PRB_NR, // nof_prb
0, // start
@ -30,6 +30,7 @@ static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering
static srslte_pdsch_cfg_nr_t pdsch_cfg = {};
static srslte_pdsch_grant_nr_t pdsch_grant = {};
static uint16_t rnti = 0x1234;
void usage(char* prog)
{
@ -85,14 +86,14 @@ int main(int argc, char** argv)
cf_t* sf_symbols[SRSLTE_MAX_LAYERS_NR] = {};
// Set default PDSCH configuration
pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam;
pdsch_cfg.sch_cfg.mcs_table = srslte_mcs_table_64qam;
if (parse_args(argc, argv) < SRSLTE_SUCCESS) {
goto clean_exit;
}
srslte_pdsch_nr_args_t pdsch_args = {};
pdsch_args.sch.disable_simd = true;
pdsch_args.sch.disable_simd = false;
pdsch_args.measure_evm = true;
if (srslte_pdsch_nr_init_enb(&pdsch_tx, &pdsch_args) < SRSLTE_SUCCESS) {
@ -155,8 +156,16 @@ int main(int argc, char** argv)
ERROR("Error loading default grant\n");
goto clean_exit;
}
// Load number of DMRS CDM groups without data
if (srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(&pdsch_cfg, &pdsch_grant) < SRSLTE_SUCCESS) {
ERROR("Error loading number of DMRS CDM groups without data\n");
goto clean_exit;
}
pdsch_grant.nof_layers = carrier.max_mimo_layers;
pdsch_grant.dci_format = srslte_dci_format_nr_1_0;
pdsch_grant.rnti = rnti;
uint32_t n_prb_start = 1;
uint32_t n_prb_end = carrier.nof_prb + 1;

@ -128,5 +128,30 @@ int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_pdsch_cfg_nr_t* pdsch_cfg,
srslte_pdsch_grant_nr_t* grant)
{
if (pdsch_cfg == NULL || grant == NULL) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
const srslte_pdsch_dmrs_cfg_t* dmrs_cfg =
grant->mapping == srslte_pdsch_mapping_type_A ? &pdsch_cfg->dmrs_cfg_typeA : &pdsch_cfg->dmrs_cfg_typeB;
/* 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 (dmrs_cfg->length == srslte_dmrs_pdsch_len_2) {
grant->nof_dmrs_cdm_groups_without_data = 1;
} else {
grant->nof_dmrs_cdm_groups_without_data = 2;
}
return SRSLTE_SUCCESS;
}

@ -259,8 +259,9 @@ int main(int argc, char** argv)
ERROR("Error loading default grant\n");
goto clean_exit;
}
pdsch_grant.nof_layers = carrier.max_mimo_layers;
pdsch_grant.dci_format = srslte_dci_format_nr_1_0;
pdsch_grant.nof_layers = carrier.max_mimo_layers;
pdsch_grant.dci_format = srslte_dci_format_nr_1_0;
pdsch_grant.nof_dmrs_cdm_groups_without_data = 1;
uint32_t n_prb_start = 1;
uint32_t n_prb_end = carrier.nof_prb + 1;

Loading…
Cancel
Save