mirror of https://github.com/pvnis/srsRAN_4G.git
Refactor NR RA files and fix header includes all over library (#2162)
* Refactor NR resource allocation classes. Use DCI instead of grant for dummy PDSCH UE/eNB test * Minor refactors in NR workers and ue_dl * Fix include issues * fix compilation issuesmaster
parent
8a3d70f6da
commit
a6423442c2
@ -0,0 +1,256 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
#include "srslte/phy/phch/ra_dl_nr.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
static void sliv_to_s_and_l(uint32_t sliv, uint32_t* S, uint32_t* L)
|
||||
{
|
||||
// S values can be 0 to 3
|
||||
uint32_t low = sliv % 14;
|
||||
if (low < 7) {
|
||||
*S = low;
|
||||
*L = sliv / 14 + 1;
|
||||
} else {
|
||||
*S = 14 - 1 - low;
|
||||
*L = 14 - sliv / 14 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate S and L combination for TypeA time domain resource allocation
|
||||
static bool check_time_ra_typeA(uint32_t* S, uint32_t* L)
|
||||
{
|
||||
// Check values using Table 5.1.2.1-1
|
||||
if (*S > 3) {
|
||||
ERROR("S (%d) is out-of-range {0,1,2,3}\n", *S);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*L < 3 || *L > 14) {
|
||||
ERROR("L (%d) is out-of-range {3,...,14}\n", *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t sum = *S + *L;
|
||||
if (sum < 3) {
|
||||
ERROR("The sum of S (%d) and L (%d) is lower than 3\n", *S, *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sum > 14) {
|
||||
ERROR("The sum of S (%d) and L (%d) is greater than 14\n", *S, *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_time_ra_typeB(uint32_t* S, uint32_t* L)
|
||||
{
|
||||
ERROR("Not implemented\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool srslte_ra_dl_nr_time_validate(srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (grant->mapping == srslte_sch_mapping_type_A) {
|
||||
return check_time_ra_typeA(&grant->S, &grant->L);
|
||||
} else {
|
||||
return check_time_ra_typeB(&grant->S, &grant->L);
|
||||
}
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_typeA_pos, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) {
|
||||
ERROR("m (%d) is out-of-range\n", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Select k0
|
||||
grant->k0 = 0;
|
||||
|
||||
// Select PDSCH mapping
|
||||
static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B};
|
||||
grant->mapping = pdsch_mapping_lut[m];
|
||||
|
||||
static uint32_t S_pos2[SRSLTE_MAX_NOF_DL_ALLOCATION] = {2, 2, 2, 2, 2, 9, 4, 5, 5, 9, 12, 1, 1, 2, 4, 8};
|
||||
static uint32_t L_pos2[SRSLTE_MAX_NOF_DL_ALLOCATION] = {12, 10, 9, 7, 5, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4};
|
||||
static uint32_t S_pos3[SRSLTE_MAX_NOF_DL_ALLOCATION] = {3, 3, 3, 3, 3, 10, 6, 5, 5, 9, 12, 1, 1, 2, 4, 8};
|
||||
static uint32_t L_pos3[SRSLTE_MAX_NOF_DL_ALLOCATION] = {11, 9, 8, 6, 4, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4};
|
||||
|
||||
// Select start symbol (S) and length (L)
|
||||
switch (dmrs_typeA_pos) {
|
||||
|
||||
case srslte_dmrs_sch_typeA_pos_2:
|
||||
grant->S = S_pos2[m];
|
||||
grant->L = L_pos2[m];
|
||||
break;
|
||||
case srslte_dmrs_sch_typeA_pos_3:
|
||||
grant->S = S_pos3[m];
|
||||
grant->L = L_pos3[m];
|
||||
break;
|
||||
default:
|
||||
ERROR("Undefined case (%d)\n", dmrs_typeA_pos);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
void srslte_ra_dl_nr_time_hl(const srslte_pdsch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
// Compute S and L from SLIV from higher layers
|
||||
sliv_to_s_and_l(hl_ra_cfg->sliv, &grant->S, &grant->L);
|
||||
grant->k0 = hl_ra_cfg->k0;
|
||||
grant->mapping = hl_ra_cfg->mapping_type;
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_time(const srslte_sch_cfg_nr_t* cfg,
|
||||
const srslte_rnti_type_t rnti_type,
|
||||
const srslte_search_space_type_t ss_type,
|
||||
const uint8_t m,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
if (cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) {
|
||||
ERROR("m (%d) is out-of-range\n", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Determine which PDSCH Time domain RA configuration to apply (Table 5.1.2.1.1-1)
|
||||
if (cfg->pdsch_time_is_default) {
|
||||
// Note: Only Default A is supported, which corresponds SS/PBCH block and coreset mux pattern 1
|
||||
srslte_ra_dl_nr_time_default_A(m, cfg->dmrs_typeA.typeA_pos, grant);
|
||||
} else {
|
||||
srslte_ra_dl_nr_time_hl(&cfg->pdsch_time_ra[m], grant);
|
||||
}
|
||||
|
||||
// Validate S and L parameters
|
||||
if (!srslte_ra_dl_nr_time_validate(grant)) {
|
||||
ERROR("Invalid Time RA\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (pdsch_cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
const srslte_dmrs_sch_cfg_t* dmrs_cfg =
|
||||
grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB;
|
||||
|
||||
/* According to TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility:
|
||||
* When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups without data
|
||||
* 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_sch_len_2) {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 1;
|
||||
} else {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 2;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* RBG size for type0 scheduling as in table 5.1.2.2.1-1 of 36.214 */
|
||||
uint32_t srslte_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 srslte_carrier_nr_t* carrier,
|
||||
const srslte_sch_cfg_nr_t* cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
uint32_t P = srslte_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;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
rbg_offset += rbg_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_sch_cfg_nr_t* cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
if (cfg == NULL || grant == NULL || dci_dl == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// RA scheme
|
||||
if (dci_dl->format == srslte_dci_format_nr_1_0) {
|
||||
ra_freq_type0(carrier, cfg, dci_dl, grant);
|
||||
} else {
|
||||
ERROR("Only DCI Format 1_0 is supported\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "srslte/common/test_common.h"
|
||||
#include "srslte/phy/phch/ra_dl_nr.h"
|
||||
#include "srslte/phy/phch/ra_nr.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include "srslte/phy/utils/random.h"
|
||||
#include <getopt.h>
|
||||
|
||||
static srslte_carrier_nr_t carrier = {
|
||||
1, // cell_id
|
||||
0, // numerology
|
||||
SRSLTE_MAX_PRB_NR, // nof_prb
|
||||
0, // start
|
||||
1 // max_mimo_layers
|
||||
};
|
||||
|
||||
int test_type0_multiple()
|
||||
{
|
||||
srslte_sch_cfg_nr_t sch_cfg = {};
|
||||
srslte_dci_dl_nr_t dci_dl = {};
|
||||
srslte_sch_grant_nr_t grant = {};
|
||||
|
||||
carrier.nof_prb = 32;
|
||||
carrier.start = 48;
|
||||
|
||||
sch_cfg.rbg_size_cfg_1 = false;
|
||||
dci_dl.format = srslte_dci_format_nr_1_0;
|
||||
|
||||
dci_dl.freq_domain_assigment = 0xC0; // RBG 0 and 1
|
||||
|
||||
TESTASSERT(srslte_ra_dl_nr_freq(&carrier, &sch_cfg, &dci_dl, &grant) == SRSLTE_SUCCESS);
|
||||
|
||||
TESTASSERT(grant.nof_prb == 8); // P * 2 RBG
|
||||
for (uint32_t i = 0; i < grant.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == true);
|
||||
}
|
||||
for (uint32_t i = grant.nof_prb; i < carrier.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == false);
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int test_type0_not_multiple()
|
||||
{
|
||||
srslte_sch_cfg_nr_t sch_cfg = {};
|
||||
srslte_dci_dl_nr_t dci_dl = {};
|
||||
srslte_sch_grant_nr_t grant = {};
|
||||
|
||||
carrier.nof_prb = 33;
|
||||
carrier.start = 49;
|
||||
|
||||
sch_cfg.rbg_size_cfg_1 = false;
|
||||
dci_dl.format = srslte_dci_format_nr_1_0;
|
||||
|
||||
dci_dl.freq_domain_assigment = 0x1C0; // RBG 0, 1 and 2
|
||||
|
||||
TESTASSERT(srslte_ra_dl_nr_freq(&carrier, &sch_cfg, &dci_dl, &grant) == SRSLTE_SUCCESS);
|
||||
|
||||
TESTASSERT(grant.nof_prb == 11); // P + (P-1) RBG
|
||||
for (uint32_t i = 0; i < grant.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == true);
|
||||
}
|
||||
for (uint32_t i = grant.nof_prb; i < carrier.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == false);
|
||||
}
|
||||
|
||||
bzero(&grant, sizeof(srslte_sch_grant_nr_t));
|
||||
|
||||
dci_dl.freq_domain_assigment = 0x3; // RBG 8 and 9
|
||||
|
||||
TESTASSERT(srslte_ra_dl_nr_freq(&carrier, &sch_cfg, &dci_dl, &grant) == SRSLTE_SUCCESS);
|
||||
|
||||
TESTASSERT(grant.nof_prb == 6); // P + (P-1) RBG
|
||||
for (uint32_t i = 0; i < carrier.nof_prb - grant.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == false);
|
||||
}
|
||||
for (uint32_t i = carrier.nof_prb - grant.nof_prb; i < carrier.nof_prb; i++) {
|
||||
TESTASSERT(grant.prb_idx[i] == true);
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// TESTASSERT(test_type0_multiple() == SRSLTE_SUCCESS);
|
||||
TESTASSERT(test_type0_not_multiple() == SRSLTE_SUCCESS);
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 Software Radio Systems Limited
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the distribution.
|
||||
*
|
||||
*/
|
||||
#include "srslte/phy/ue/ue_dl_nr_data.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
static int srslte_ue_dl_nr_pdsch_time_resource_hl_A(uint32_t sliv, uint32_t* S, uint32_t* L)
|
||||
{
|
||||
// S values can be 0 to 3
|
||||
uint32_t low = sliv % 14;
|
||||
if (low < 7) {
|
||||
*S = low;
|
||||
*L = sliv / 14 + 1;
|
||||
} else {
|
||||
*S = 14 - 1 - low;
|
||||
*L = 14 - sliv / 14 + 1;
|
||||
}
|
||||
|
||||
// Check values using Table 5.1.2.1-1
|
||||
if (*S > 3) {
|
||||
ERROR("Invalid SLIV %d. S (%d) is out-of-range {0,1,2,3}\n", sliv, *S);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (*L < 3 || *L > 14) {
|
||||
ERROR("Invalid SLIV %d. L (%d) is out-of-range {3,...,14}\n", sliv, *L);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
uint32_t sum = *S + *L;
|
||||
if (sum < 3) {
|
||||
ERROR("Invalid SLIV %d. The sum of S (%d) and L (%d) is lower than 3\n", sliv, *S, *L);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (sum > 14) {
|
||||
ERROR("Invalid SLIV %d. The sum of S (%d) and L (%d) is greater than 14\n", sliv, *S, *L);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int srslte_ue_dl_nr_pdsch_time_resource_hl_B(uint32_t sliv, uint32_t* S, uint32_t* L)
|
||||
{
|
||||
ERROR("Not implemented\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
int srslte_ue_dl_nr_pdsch_time_resource_hl(const srslte_pdsch_allocation_t* pdsch_alloc, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
if (pdsch_alloc == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
grant->k0 = pdsch_alloc->k0;
|
||||
grant->mapping = pdsch_alloc->mapping_type;
|
||||
|
||||
if (pdsch_alloc->mapping_type == srslte_sch_mapping_type_A) {
|
||||
return srslte_ue_dl_nr_pdsch_time_resource_hl_A(pdsch_alloc->sliv, &grant->S, &grant->L);
|
||||
}
|
||||
|
||||
return srslte_ue_dl_nr_pdsch_time_resource_hl_B(pdsch_alloc->sliv, &grant->S, &grant->L);
|
||||
}
|
||||
|
||||
int srslte_ue_dl_nr_pdsch_time_resource_default_A(uint32_t m,
|
||||
srslte_dmrs_sch_typeA_pos_t dmrs_typeA_pos,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (m >= 16) {
|
||||
ERROR("m (%d) is out-of-range\n", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Select k0
|
||||
grant->k0 = 0;
|
||||
|
||||
// Select PDSCH mapping
|
||||
static srslte_sch_mapping_type_t pdsch_mapping_lut[16] = {srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_A,
|
||||
srslte_sch_mapping_type_B,
|
||||
srslte_sch_mapping_type_B};
|
||||
grant->mapping = pdsch_mapping_lut[m];
|
||||
|
||||
static uint32_t S_pos2[16] = {2, 2, 2, 2, 2, 9, 4, 5, 5, 9, 12, 1, 1, 2, 4, 8};
|
||||
static uint32_t L_pos2[16] = {12, 10, 9, 7, 5, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4};
|
||||
static uint32_t S_pos3[16] = {3, 3, 3, 3, 3, 10, 6, 5, 5, 9, 12, 1, 1, 2, 4, 8};
|
||||
static uint32_t L_pos3[16] = {11, 9, 8, 6, 4, 4, 4, 7, 2, 2, 2, 13, 6, 4, 7, 4};
|
||||
|
||||
// Select start symbol (S) and length (L)
|
||||
switch (dmrs_typeA_pos) {
|
||||
|
||||
case srslte_dmrs_sch_typeA_pos_2:
|
||||
grant->S = S_pos2[m];
|
||||
grant->L = L_pos2[m];
|
||||
break;
|
||||
case srslte_dmrs_sch_typeA_pos_3:
|
||||
grant->S = S_pos3[m];
|
||||
grant->L = L_pos3[m];
|
||||
break;
|
||||
default:
|
||||
ERROR("Undefined case (%d)\n", dmrs_typeA_pos);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ue_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const srslte_sch_cfg_nr_t* pdsch_cfg,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (pdsch_cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
const srslte_dmrs_sch_cfg_t* dmrs_cfg =
|
||||
grant->mapping == srslte_sch_mapping_type_A ? &pdsch_cfg->dmrs_typeA : &pdsch_cfg->dmrs_typeB;
|
||||
|
||||
/* According to TS 38.214 V15.10.0 5.1.6.1.3 CSI-RS for mobility:
|
||||
* When receiving PDSCH scheduled by DCI format 1_0, the UE shall assume the number of DM-RS CDM groups without data
|
||||
* 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_sch_len_2) {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 1;
|
||||
} else {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 2;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue