|
|
|
@ -0,0 +1,348 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright 2013-2020 Software Radio Systems Limited
|
|
|
|
|
*
|
|
|
|
|
* This file is part of srsLTE.
|
|
|
|
|
*
|
|
|
|
|
* srsLTE is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
|
* published by the Free Software Foundation, either version 3 of
|
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* srsLTE is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
|
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "srslte/phy/phch/ra_nr.h"
|
|
|
|
|
#include "srslte/phy/phch/pdsch_nr.h"
|
|
|
|
|
#include "srslte/phy/utils/debug.h"
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
srslte_mod_t modulation;
|
|
|
|
|
double R; // Target code Rate R x [1024]
|
|
|
|
|
double S; // Spectral efficiency
|
|
|
|
|
} mcs_entry_t;
|
|
|
|
|
|
|
|
|
|
#define RA_NR_MCS_SIZE_TABLE1 29
|
|
|
|
|
#define RA_NR_MCS_SIZE_TABLE2 28
|
|
|
|
|
#define RA_NR_MCS_SIZE_TABLE3 29
|
|
|
|
|
#define RA_NR_TBS_SIZE_TABLE 93
|
|
|
|
|
|
|
|
|
|
#define RA_NR_READ_TABLE(N) \
|
|
|
|
|
static double srslte_ra_nr_R_from_mcs_table##N(uint32_t mcs_idx) \
|
|
|
|
|
{ \
|
|
|
|
|
if (mcs_idx >= RA_NR_MCS_SIZE_TABLE##N) { \
|
|
|
|
|
return NAN; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
return ra_nr_table##N[mcs_idx].R; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
static srslte_mod_t srslte_ra_nr_modulation_from_mcs_table##N(uint32_t mcs_idx) \
|
|
|
|
|
{ \
|
|
|
|
|
if (mcs_idx >= RA_NR_MCS_SIZE_TABLE##N) { \
|
|
|
|
|
return SRSLTE_MOD_NITEMS; \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
return ra_nr_table##N[mcs_idx].modulation; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TS 38.214 V15.10.0 Table 5.1.3.1-1: MCS index table 1 for PDSCH
|
|
|
|
|
*/
|
|
|
|
|
static const mcs_entry_t ra_nr_table1[RA_NR_MCS_SIZE_TABLE1] = {
|
|
|
|
|
{SRSLTE_MOD_QPSK, 120, 0.2344}, {SRSLTE_MOD_QPSK, 157, 0.3066}, {SRSLTE_MOD_QPSK, 193, 0.3770},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 251, 0.4902}, {SRSLTE_MOD_QPSK, 308, 0.6016}, {SRSLTE_MOD_QPSK, 379, 0.7402},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 449, 0.8770}, {SRSLTE_MOD_QPSK, 526, 1.0273}, {SRSLTE_MOD_QPSK, 602, 1.1758},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 679, 1.3262}, {SRSLTE_MOD_16QAM, 340, 1.3281}, {SRSLTE_MOD_16QAM, 378, 1.4766},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 434, 1.6953}, {SRSLTE_MOD_16QAM, 490, 1.9141}, {SRSLTE_MOD_16QAM, 553, 2.1602},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 616, 2.4063}, {SRSLTE_MOD_16QAM, 658, 2.5703}, {SRSLTE_MOD_64QAM, 438, 2.5664},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 466, 2.7305}, {SRSLTE_MOD_64QAM, 517, 3.0293}, {SRSLTE_MOD_64QAM, 567, 3.3223},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 616, 3.6094}, {SRSLTE_MOD_64QAM, 666, 3.9023}, {SRSLTE_MOD_64QAM, 719, 4.2129},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 772, 4.5234}, {SRSLTE_MOD_64QAM, 822, 4.8164}, {SRSLTE_MOD_64QAM, 873, 5.1152},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 910, 5.3320}, {SRSLTE_MOD_64QAM, 948, 5.5547}};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TS 38.214 V15.10.0 Table 5.1.3.1-2: MCS index table 2 for PDSCH
|
|
|
|
|
*/
|
|
|
|
|
static const mcs_entry_t ra_nr_table2[RA_NR_MCS_SIZE_TABLE2] = {
|
|
|
|
|
{SRSLTE_MOD_QPSK, 120, 0.2344}, {SRSLTE_MOD_QPSK, 193, 0.3770}, {SRSLTE_MOD_QPSK, 308, 0.6016},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 449, 0.8770}, {SRSLTE_MOD_QPSK, 602, 1.1758}, {SRSLTE_MOD_16QAM, 378, 1.4766},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 434, 1.6953}, {SRSLTE_MOD_16QAM, 490, 1.9141}, {SRSLTE_MOD_16QAM, 553, 2.1602},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 616, 2.4063}, {SRSLTE_MOD_16QAM, 658, 2.5703}, {SRSLTE_MOD_64QAM, 466, 2.7305},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 517, 3.0293}, {SRSLTE_MOD_64QAM, 567, 3.3223}, {SRSLTE_MOD_64QAM, 616, 3.6094},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 666, 3.9023}, {SRSLTE_MOD_64QAM, 719, 4.2129}, {SRSLTE_MOD_64QAM, 772, 4.5234},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 822, 4.8164}, {SRSLTE_MOD_64QAM, 873, 5.1152}, {SRSLTE_MOD_256QAM, 682.5, 5.3320},
|
|
|
|
|
{SRSLTE_MOD_256QAM, 711, 5.5547}, {SRSLTE_MOD_256QAM, 754, 5.8906}, {SRSLTE_MOD_256QAM, 797, 6.2266},
|
|
|
|
|
{SRSLTE_MOD_256QAM, 841, 6.5703}, {SRSLTE_MOD_256QAM, 885, 6.9141}, {SRSLTE_MOD_256QAM, 916.5, 7.1602},
|
|
|
|
|
{SRSLTE_MOD_256QAM, 948, 7.4063}};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TS 38.214 V15.10.0 Table 5.1.3.1-2: MCS index table 2 for PDSCH
|
|
|
|
|
*/
|
|
|
|
|
static const mcs_entry_t ra_nr_table3[RA_NR_MCS_SIZE_TABLE3] = {
|
|
|
|
|
{SRSLTE_MOD_QPSK, 30, 0.0586}, {SRSLTE_MOD_QPSK, 40, 0.0781}, {SRSLTE_MOD_QPSK, 50, 0.0977},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 64, 0.1250}, {SRSLTE_MOD_QPSK, 78, 0.1523}, {SRSLTE_MOD_QPSK, 99, 0.1934},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 120, 0.2344}, {SRSLTE_MOD_QPSK, 157, 0.3066}, {SRSLTE_MOD_QPSK, 193, 0.3770},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 251, 0.4902}, {SRSLTE_MOD_QPSK, 308, 0.6016}, {SRSLTE_MOD_QPSK, 379, 0.7402},
|
|
|
|
|
{SRSLTE_MOD_QPSK, 449, 0.8770}, {SRSLTE_MOD_QPSK, 526, 1.0273}, {SRSLTE_MOD_QPSK, 602, 1.1758},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 340, 1.3281}, {SRSLTE_MOD_16QAM, 378, 1.4766}, {SRSLTE_MOD_16QAM, 434, 1.6953},
|
|
|
|
|
{SRSLTE_MOD_16QAM, 490, 1.9141}, {SRSLTE_MOD_16QAM, 553, 2.1602}, {SRSLTE_MOD_16QAM, 616, 2.4063},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 438, 2.5664}, {SRSLTE_MOD_64QAM, 466, 2.7305}, {SRSLTE_MOD_64QAM, 517, 3.0293},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 567, 3.3223}, {SRSLTE_MOD_64QAM, 616, 3.6094}, {SRSLTE_MOD_64QAM, 666, 3.9023},
|
|
|
|
|
{SRSLTE_MOD_64QAM, 719, 4.2129}, {SRSLTE_MOD_64QAM, 772, 4.5234}};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate MCS table access functions
|
|
|
|
|
*/
|
|
|
|
|
RA_NR_READ_TABLE(1)
|
|
|
|
|
RA_NR_READ_TABLE(2)
|
|
|
|
|
RA_NR_READ_TABLE(3)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TS 38.214 V15.10.0 Table 5.1.3.2-1: TBS for N inf o ≤ 3824
|
|
|
|
|
*/
|
|
|
|
|
static const uint32_t ra_nr_tbs_table[RA_NR_TBS_SIZE_TABLE] = {
|
|
|
|
|
24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168,
|
|
|
|
|
176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 408, 432, 456, 480,
|
|
|
|
|
504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160,
|
|
|
|
|
1192, 1224, 1256, 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216,
|
|
|
|
|
2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, 3104, 3240, 3368, 3496, 3624, 3752, 3824};
|
|
|
|
|
|
|
|
|
|
typedef enum { ra_nr_table_1 = 0, ra_nr_table_2, ra_nr_table_3 } ra_nr_table_t;
|
|
|
|
|
|
|
|
|
|
static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table,
|
|
|
|
|
srslte_dci_format_nr_t dci_format,
|
|
|
|
|
srslte_search_space_type_t search_space_type,
|
|
|
|
|
uint16_t rnti)
|
|
|
|
|
{
|
|
|
|
|
// Non-implemented parameters
|
|
|
|
|
bool sps_config_mcs_table_present = false;
|
|
|
|
|
srslte_mcs_table_t sps_config_mcs_table = srslte_mcs_table_64qam;
|
|
|
|
|
bool is_cs_rnti = false;
|
|
|
|
|
bool is_pdcch_sps = false;
|
|
|
|
|
|
|
|
|
|
// - the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam256', and
|
|
|
|
|
// - the PDSCH is scheduled by a PDCCH with DCI format 1_1 with
|
|
|
|
|
// - CRC scrambled by C-RNTI
|
|
|
|
|
if (mcs_table == srslte_mcs_table_256qam && dci_format == srslte_dci_format_nr_1_1 && SRSLTE_RNTI_ISUSER(rnti)) {
|
|
|
|
|
return ra_nr_table_1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the UE is not configured with MCS-C-RNTI,
|
|
|
|
|
// the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam64LowSE', and
|
|
|
|
|
// the PDSCH is scheduled by a PDCCH in a UE-specific search space with
|
|
|
|
|
// CRC scrambled by C - RNTI
|
|
|
|
|
if (mcs_table == srslte_mcs_table_qam64LowSE && search_space_type == srslte_search_space_type_ue &&
|
|
|
|
|
SRSLTE_RNTI_ISUSER(rnti)) {
|
|
|
|
|
return ra_nr_table_3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// - the UE is not configured with the higher layer parameter mcs-Table given by SPS-Config,
|
|
|
|
|
// - the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam256',
|
|
|
|
|
// - if the PDSCH is scheduled by a PDCCH with DCI format 1_1 with CRC scrambled by CS-RNTI or
|
|
|
|
|
// - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config,
|
|
|
|
|
if (!sps_config_mcs_table_present && mcs_table == srslte_mcs_table_256qam &&
|
|
|
|
|
((dci_format == srslte_dci_format_nr_1_1 && is_cs_rnti) || (!is_pdcch_sps))) {
|
|
|
|
|
return ra_nr_table_2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// - the UE is configured with the higher layer parameter mcs-Table given by SPS-Config set to 'qam64LowSE'
|
|
|
|
|
// - if the PDSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or
|
|
|
|
|
// - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config,
|
|
|
|
|
if (sps_config_mcs_table_present && sps_config_mcs_table == srslte_mcs_table_qam64LowSE &&
|
|
|
|
|
(is_cs_rnti || is_pdcch_sps)) {
|
|
|
|
|
return ra_nr_table_3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// else
|
|
|
|
|
return ra_nr_table_1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double srslte_ra_nr_R_from_mcs(srslte_mcs_table_t mcs_table,
|
|
|
|
|
srslte_dci_format_nr_t dci_format,
|
|
|
|
|
srslte_search_space_type_t search_space_type,
|
|
|
|
|
uint16_t rnti,
|
|
|
|
|
uint32_t mcs_idx)
|
|
|
|
|
{
|
|
|
|
|
ra_nr_table_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti);
|
|
|
|
|
|
|
|
|
|
switch (table) {
|
|
|
|
|
case ra_nr_table_1:
|
|
|
|
|
return srslte_ra_nr_R_from_mcs_table1(mcs_idx) / 1024.0;
|
|
|
|
|
case ra_nr_table_2:
|
|
|
|
|
return srslte_ra_nr_R_from_mcs_table2(mcs_idx) / 1024.0;
|
|
|
|
|
case ra_nr_table_3:
|
|
|
|
|
return srslte_ra_nr_R_from_mcs_table3(mcs_idx) / 1024.0;
|
|
|
|
|
default:
|
|
|
|
|
ERROR("Invalid table %d\n", table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NAN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
srslte_mod_t srslte_ra_nr_mod_from_mcs(srslte_mcs_table_t mcs_table,
|
|
|
|
|
srslte_dci_format_nr_t dci_format,
|
|
|
|
|
srslte_search_space_type_t search_space_type,
|
|
|
|
|
uint16_t rnti,
|
|
|
|
|
uint32_t mcs_idx)
|
|
|
|
|
{
|
|
|
|
|
ra_nr_table_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti);
|
|
|
|
|
|
|
|
|
|
switch (table) {
|
|
|
|
|
case ra_nr_table_1:
|
|
|
|
|
return srslte_ra_nr_modulation_from_mcs_table1(mcs_idx);
|
|
|
|
|
case ra_nr_table_2:
|
|
|
|
|
return srslte_ra_nr_modulation_from_mcs_table2(mcs_idx);
|
|
|
|
|
case ra_nr_table_3:
|
|
|
|
|
return srslte_ra_nr_modulation_from_mcs_table3(mcs_idx);
|
|
|
|
|
default:
|
|
|
|
|
ERROR("Invalid table %d\n", table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SRSLTE_MOD_NITEMS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ra_nr_determine_N_re(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch_grant_nr_t* grant)
|
|
|
|
|
{
|
|
|
|
|
// the number of symbols of the PDSCH allocation within the slot
|
|
|
|
|
int n_sh_symb = grant->L;
|
|
|
|
|
|
|
|
|
|
// the number of REs for DM-RS per PRB in the scheduled duration
|
|
|
|
|
int n_prb_dmrs = srslte_dmrs_pdsch_get_N_prb(pdsch_cfg, grant);
|
|
|
|
|
if (n_prb_dmrs < SRSLTE_SUCCESS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the overhead configured by higher layer parameter xOverhead in PDSCH-ServingCellConfig
|
|
|
|
|
uint32_t n_prb_oh = 0;
|
|
|
|
|
|
|
|
|
|
// Compute total number of n_re used for PDSCH
|
|
|
|
|
uint32_t n_re_prime = SRSLTE_NRE * n_sh_symb - n_prb_dmrs - n_prb_oh;
|
|
|
|
|
|
|
|
|
|
uint32_t n_prb = 0;
|
|
|
|
|
for (uint32_t i = 0; i < SRSLTE_MAX_PRB_NR; i++) {
|
|
|
|
|
n_prb += (uint32_t)grant->prb_idx[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return the number of resource elements for PDSCH
|
|
|
|
|
return SRSLTE_MIN(SRSLTE_MAX_NRE_NR, n_re_prime) * n_prb;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define CEIL(NUM, DEN) (((NUM) + ((DEN)-1)) / (DEN))
|
|
|
|
|
#define FLOOR(NUM, DEN) ((NUM) / (DEN))
|
|
|
|
|
#define ROUND(NUM, DEN) ((uint32_t)round((NUM) / (DEN)))
|
|
|
|
|
#define POW2(N) (1U << (N))
|
|
|
|
|
|
|
|
|
|
static uint32_t ra_nr_tbs_from_n_info3(uint32_t n_info)
|
|
|
|
|
{
|
|
|
|
|
// quantized intermediate number of information bits
|
|
|
|
|
uint32_t n = (uint32_t)SRSLTE_MAX(3.0, floor(log2(n_info)) - 6.0);
|
|
|
|
|
uint32_t n_info_prime = SRSLTE_MAX(ra_nr_tbs_table[0], POW2(n) * FLOOR(n_info, POW2(n)));
|
|
|
|
|
|
|
|
|
|
// use Table 5.1.3.2-1 find the closest TBS that is not less than n_info_prime
|
|
|
|
|
for (uint32_t i = 0; i < RA_NR_TBS_SIZE_TABLE; i++) {
|
|
|
|
|
if (n_info_prime <= ra_nr_tbs_table[i]) {
|
|
|
|
|
return ra_nr_tbs_table[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ra_nr_tbs_table[RA_NR_TBS_SIZE_TABLE - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t ra_nr_tbs_from_n_info4(uint32_t n_info, double R)
|
|
|
|
|
{
|
|
|
|
|
// quantized intermediate number of information bits
|
|
|
|
|
uint32_t n = (uint32_t)(floor(log2(n_info - 24.0)) - 5.0);
|
|
|
|
|
uint32_t n_info_prime = SRSLTE_MAX(3840, POW2(n) * ROUND(n_info - 24.0, POW2(n)));
|
|
|
|
|
|
|
|
|
|
if (R <= 0.25) {
|
|
|
|
|
uint32_t C = CEIL(n_info_prime + 24U, 3816U);
|
|
|
|
|
return 8U * C * CEIL(n_info_prime + 24U, 8U * C) - 24U;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (n_info_prime > 8424) {
|
|
|
|
|
uint32_t C = CEIL(n_info_prime + 24U, 8424U);
|
|
|
|
|
return 8U * C * CEIL(n_info_prime + 24U, 8U * C) - 24U;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 8U * CEIL(n_info_prime + 24U, 8U) - 24U;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Implements TS 38.214 V15.10.0 Table 5.1.3.2-2 Scaling factor of N_info for P-RNTI and RA-RNTI
|
|
|
|
|
* @param tb_scaling_field provided by the grant
|
|
|
|
|
* @return It returns the value if the field is in range, otherwise it returns NAN
|
|
|
|
|
*/
|
|
|
|
|
static double ra_nr_get_scaling(uint32_t tb_scaling_field)
|
|
|
|
|
{
|
|
|
|
|
static const double tb_scaling[4] = {1.0, 0.5, 0.25, NAN};
|
|
|
|
|
|
|
|
|
|
if (tb_scaling_field < 4) {
|
|
|
|
|
return tb_scaling[tb_scaling_field];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NAN;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int srslte_ra_nr_tbs(const srslte_pdsch_cfg_nr_t* pdsch_cfg, const srslte_pdsch_grant_nr_t* grant, uint32_t mcs_idx)
|
|
|
|
|
{
|
|
|
|
|
// Get target Rate
|
|
|
|
|
double R =
|
|
|
|
|
srslte_ra_nr_R_from_mcs(pdsch_cfg->mcs_table, grant->dci_format, grant->dci_search_space, grant->rnti, mcs_idx);
|
|
|
|
|
if (!isnormal(R)) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get modulation
|
|
|
|
|
srslte_mod_t m =
|
|
|
|
|
srslte_ra_nr_mod_from_mcs(pdsch_cfg->mcs_table, grant->dci_format, grant->dci_search_space, grant->rnti, mcs_idx);
|
|
|
|
|
if (m >= SRSLTE_MOD_NITEMS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get modulation order
|
|
|
|
|
uint32_t Qm = srslte_mod_bits_x_symbol(m);
|
|
|
|
|
if (Qm == 0) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For the PDSCH assigned by a
|
|
|
|
|
// - PDCCH with DCI format 1_0 with
|
|
|
|
|
// - CRC scrambled by P-RNTI, or RA-RNTI,
|
|
|
|
|
double S = 1.0;
|
|
|
|
|
if ((SRSLTE_RNTI_ISRAR(grant->rnti) || SRSLTE_RNTI_ISPA(grant->rnti)) &&
|
|
|
|
|
grant->dci_format == srslte_dci_format_nr_1_0) {
|
|
|
|
|
// where the scaling factor S is determined based on the TB scaling
|
|
|
|
|
// field in the DCI as in Table 5.1.3.2-2.
|
|
|
|
|
S = ra_nr_get_scaling(grant->tb_scaling_field);
|
|
|
|
|
|
|
|
|
|
// If the scaling is invalid return error
|
|
|
|
|
if (!isnormal(S)) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1) The UE shall first determine the number of REs (N RE ) within the slot.
|
|
|
|
|
int n_re = ra_nr_determine_N_re(pdsch_cfg, grant);
|
|
|
|
|
if (n_re < SRSLTE_SUCCESS) {
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 * grant->nof_layers);
|
|
|
|
|
|
|
|
|
|
// 3) When n_info ≤ 3824
|
|
|
|
|
if (n_info <= 3824) {
|
|
|
|
|
return (int)ra_nr_tbs_from_n_info3(n_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4) When n_info > 3824
|
|
|
|
|
return (int)ra_nr_tbs_from_n_info4(n_info, R);
|
|
|
|
|
}
|