diff --git a/lib/include/srsran/phy/phch/sch_cfg_nr.h b/lib/include/srsran/phy/phch/sch_cfg_nr.h index 31c3f5af6..24abdc7cd 100644 --- a/lib/include/srsran/phy/phch/sch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/sch_cfg_nr.h @@ -19,8 +19,11 @@ typedef struct SRSRAN_API { srsran_mcs_table_t mcs_table; ///< @brief Indicates the MCS table the UE shall use for PDSCH and/or PUSCH without ///< transform precoding - srsran_xoverhead_t xoverhead; ///< Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE - ///< applies value xOh0 (see TS 38.214 [19], clause 5.1.3.2). + srsran_xoverhead_t xoverhead; ///< @brief Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the + ///< UE applies value xOh0 (see TS 38.214 [19], clause 5.1.3.2). + + bool limited_buffer_rm; ///< @brief Enables LBRM (Limited buffer rate-matching). Given by rateMatching parameter in + ///< PUSCH-ServingCellConfig or PDSCH-ServingCellConfig ASN1 sequences } srsran_sch_cfg_t; typedef struct SRSRAN_API { diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 5c899b4bf..003b381cd 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -87,7 +87,7 @@ static int sch_nr_Nref(uint32_t N_rb, srsran_mcs_table_t mcs_table, uint32_t max uint32_t N_re_lbrm = SRSRAN_MAX_NRE_NR * sch_nr_n_prb_lbrm(N_rb); double TCR_lbrm = 948.0 / 1024.0; uint32_t Qm_lbrm = (mcs_table == srsran_mcs_table_256qam) ? 8 : 6; - uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, max_mimo_layers); + uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, SRSRAN_MIN(4, max_mimo_layers)); double R = 2.0 / 3.0; srsran_basegraph_t bg = srsran_sch_nr_select_basegraph(TBS_LRBM, R); @@ -141,11 +141,15 @@ int srsran_sch_nr_fill_tb_info(const srsran_carrier_nr_t* carrier, cfg->Nl = tb->N_L; // Calculate Nref - int Nref = sch_nr_Nref(carrier->nof_prb, sch_cfg->mcs_table, carrier->max_mimo_layers); - if (Nref < SRSRAN_SUCCESS) { - ERROR("Error computing N_ref"); + if (sch_cfg->limited_buffer_rm) { + int Nref = sch_nr_Nref(carrier->nof_prb, sch_cfg->mcs_table, 4); + if (Nref < SRSRAN_SUCCESS) { + ERROR("Error computing N_ref"); + } + cfg->Nref = (uint32_t)Nref; + } else { + cfg->Nref = SRSRAN_LDPC_MAX_LEN_ENCODED_CB; } - cfg->Nref = (uint32_t)Nref; // Calculate number of code blocks after applying CBGTI... not implemented, activate all CB for (uint32_t r = 0; r < cbsegm.C; r++) { diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index 40fff8944..f478117d0 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -19,17 +19,18 @@ #include "srsran/phy/utils/vector.h" #include -static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; -static uint32_t n_prb = 0; // Set to 0 for steering -static uint32_t mcs = 30; // Set to 30 for steering -static srsran_sch_cfg_nr_t pdsch_cfg = {}; -static uint32_t nof_slots = 10; -static uint32_t rv_idx = 0; -static uint32_t delay_n = 0; // Integer delay -static float cfo_hz = 0.0f; // CFO Hz -static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1; -static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2; -static bool interleaved_pdcch = false; +static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; +static uint32_t n_prb = 0; // Set to 0 for steering +static uint32_t mcs = 30; // Set to 30 for steering +static srsran_sch_cfg_nr_t pdsch_cfg = {}; +static uint32_t nof_slots = 10; +static uint32_t rv_idx = 0; +static uint32_t delay_n = 0; // Integer delay +static float cfo_hz = 0.0f; // CFO Hz +static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1; +static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2; +static bool interleaved_pdcch = false; +static uint32_t nof_dmrs_cdm_groups_without_data = 1; static void usage(char* prog) { @@ -79,7 +80,7 @@ static int parse_args(int argc, char** argv) dmrs_type = srsran_dmrs_sch_type_2; break; } - switch (strtol(argv[optind], NULL, 10)) { + switch (strtol(argv[optind++], NULL, 10)) { case 0: dmrs_add_pos = srsran_dmrs_sch_add_pos_0; break; @@ -93,6 +94,7 @@ static int parse_args(int argc, char** argv) dmrs_add_pos = srsran_dmrs_sch_add_pos_3; break; } + nof_dmrs_cdm_groups_without_data = (uint32_t)strtol(argv[optind], NULL, 10); break; case 'T': pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_from_str(argv[optind]); @@ -357,7 +359,7 @@ int main(int argc, char** argv) pdsch_cfg.grant.L = 13; pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers; pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; - pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; + pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = nof_dmrs_cdm_groups_without_data; pdsch_cfg.grant.beta_dmrs = srsran_convert_dB_to_amplitude(3); pdsch_cfg.grant.rnti_type = srsran_rnti_type_c; pdsch_cfg.grant.rnti = 0x4601;