srsLTE/lib/src/common/phy_cfg_nr_default.cc

430 lines
15 KiB
C++
Raw Normal View History

2021-06-30 08:12:17 -07:00
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 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 "srsran/common/phy_cfg_nr_default.h"
#include "srsran/common/string_helpers.h"
2021-06-30 08:12:17 -07:00
#include "srsran/srsran.h"
#include <cctype>
#include <list>
2021-06-30 08:12:17 -07:00
namespace srsran {
template <typename T>
T inc(T v)
{
return static_cast<T>(static_cast<int>(v) + 1);
}
phy_cfg_nr_default_t::reference_cfg_t::reference_cfg_t(const std::string& args)
{
std::list<std::string> param_list = {};
string_parse_list(args, ',', param_list);
for (std::string& e : param_list) {
std::list<std::string> param = {};
string_parse_list(e, '=', param);
// Skip if size is invalid
if (param.size() != 2) {
srsran_terminate("Invalid reference argument '%s'", e.c_str());
}
2021-07-21 06:02:20 -07:00
if (param.front() == "carrier") {
for (carrier = R_CARRIER_CUSTOM_10MHZ; carrier < R_CARRIER_COUNT; carrier = inc(carrier)) {
if (R_CARRIER_STRING[carrier] == param.back()) {
break;
}
}
srsran_assert(carrier != R_CARRIER_COUNT, "Invalid carrier reference configuration '%s'", param.back().c_str());
2021-07-21 07:24:17 -07:00
} else if (param.front() == "tdd") {
for (tdd = R_TDD_CUSTOM_6_4; tdd < R_TDD_COUNT; tdd = inc(tdd)) {
if (R_TDD_STRING[tdd] == param.back()) {
break;
}
}
srsran_assert(tdd != R_TDD_COUNT, "Invalid TDD reference configuration '%s'", param.back().c_str());
2021-07-21 06:02:20 -07:00
} else if (param.front() == "pdsch") {
for (pdsch = R_PDSCH_DEFAULT; pdsch < R_PDSCH_COUNT; pdsch = inc(pdsch)) {
if (R_PDSCH_STRING[pdsch] == param.back()) {
break;
}
}
srsran_assert(pdsch != R_PDSCH_COUNT, "Invalid PDSCH reference configuration '%s'", param.back().c_str());
} else {
srsran_terminate("Invalid %s reference component", param.front().c_str());
}
}
}
2021-06-30 08:12:17 -07:00
void phy_cfg_nr_default_t::make_carrier_custom_10MHz(srsran_carrier_nr_t& carrier)
{
carrier.nof_prb = 52;
carrier.max_mimo_layers = 1;
carrier.pci = 500;
carrier.absolute_frequency_point_a = 633928;
carrier.absolute_frequency_ssb = 634176;
carrier.offset_to_carrier = 0;
carrier.scs = srsran_subcarrier_spacing_15kHz;
}
2021-07-21 06:02:20 -07:00
void phy_cfg_nr_default_t::make_carrier_custom_20MHz(srsran_carrier_nr_t& carrier)
{
carrier.nof_prb = 106;
carrier.max_mimo_layers = 1;
carrier.pci = 500;
carrier.absolute_frequency_point_a = 633928;
carrier.absolute_frequency_ssb = 634176;
carrier.offset_to_carrier = 0;
carrier.scs = srsran_subcarrier_spacing_15kHz;
}
2021-06-30 08:12:17 -07:00
void phy_cfg_nr_default_t::make_tdd_custom_6_4(srsran_tdd_config_nr_t& tdd)
{
tdd.pattern1.period_ms = 10;
tdd.pattern1.nof_dl_slots = 6;
tdd.pattern1.nof_dl_symbols = 0;
tdd.pattern1.nof_ul_slots = 4;
tdd.pattern1.nof_ul_symbols = 0;
// Disable pattern 2
tdd.pattern2.period_ms = 0;
}
2021-07-21 07:24:17 -07:00
void phy_cfg_nr_default_t::make_tdd_fr1_15_1(srsran_tdd_config_nr_t& tdd)
{
tdd.pattern1.period_ms = 5;
tdd.pattern1.nof_dl_slots = 3;
tdd.pattern1.nof_dl_symbols = 10;
tdd.pattern1.nof_ul_slots = 1;
tdd.pattern1.nof_ul_symbols = 2;
// Disable pattern 2
tdd.pattern2.period_ms = 0;
}
2021-06-30 08:12:17 -07:00
void phy_cfg_nr_default_t::make_pdcch_custom_common_ss(srsran_pdcch_cfg_nr_t& pdcch, const srsran_carrier_nr_t& carrier)
{
2021-06-30 09:33:23 -07:00
// Configure CORESET ID 1
pdcch.coreset_present[1] = true;
pdcch.coreset[1].id = 1;
2021-06-30 08:12:17 -07:00
pdcch.coreset[1].duration = 1;
pdcch.coreset[1].mapping_type = srsran_coreset_mapping_type_non_interleaved;
pdcch.coreset[1].precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle;
2021-06-30 09:33:23 -07:00
// Generate frequency resources for the full BW
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
pdcch.coreset[1].freq_resources[i] = i < SRSRAN_FLOOR(carrier.nof_prb, 6);
}
// Configure Search Space 1 as common
pdcch.search_space_present[1] = true;
pdcch.search_space[1].id = 1;
pdcch.search_space[1].coreset_id = 1;
pdcch.search_space[1].duration = 1;
pdcch.search_space[1].formats[0] = srsran_dci_format_nr_0_0; // DCI format for PUSCH
pdcch.search_space[1].formats[1] = srsran_dci_format_nr_1_0; // DCI format for PDSCH
pdcch.search_space[1].nof_formats = 2;
pdcch.search_space[1].type = srsran_search_space_type_common_3;
// Generate 1 candidate for each aggregation level if possible
for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) {
pdcch.search_space[1].nof_candidates[L] =
2021-07-06 06:26:00 -07:00
SRSRAN_MIN(2, srsran_pdcch_nr_max_candidates_coreset(&pdcch.coreset[1], L));
2021-06-30 09:33:23 -07:00
}
2021-06-30 08:12:17 -07:00
}
void phy_cfg_nr_default_t::make_pdsch_default(srsran_sch_hl_cfg_nr_t& pdsch)
{
// Select PDSCH time resource allocation
pdsch.common_time_ra[0].k = 0;
pdsch.common_time_ra[0].mapping_type = srsran_sch_mapping_type_A;
pdsch.common_time_ra[0].sliv = srsran_ra_type2_to_riv(SRSRAN_NSYMB_PER_SLOT_NR - 1, 1, SRSRAN_NSYMB_PER_SLOT_NR);
pdsch.nof_common_time_ra = 1;
// Setup PDSCH DMRS type A position
pdsch.typeA_pos = srsran_dmrs_sch_typeA_pos_2;
}
void make_nzp_csi_rs_ts38101_table_5_2_1(const srsran_carrier_nr_t& carrier, srsran_csi_rs_nzp_set_t& trs)
{
// Set defaults
trs = {};
trs.trs_info = true;
trs.count = 4;
srsran_csi_rs_nzp_resource_t& res1 = trs.data[0];
srsran_csi_rs_nzp_resource_t& res2 = trs.data[1];
srsran_csi_rs_nzp_resource_t& res3 = trs.data[2];
srsran_csi_rs_nzp_resource_t& res4 = trs.data[3];
res1.resource_mapping.frequency_domain_alloc[0] = true;
res2.resource_mapping.frequency_domain_alloc[0] = true;
res3.resource_mapping.frequency_domain_alloc[0] = true;
res4.resource_mapping.frequency_domain_alloc[0] = true;
res1.resource_mapping.first_symbol_idx = 6;
res2.resource_mapping.first_symbol_idx = 10;
res3.resource_mapping.first_symbol_idx = 6;
res4.resource_mapping.first_symbol_idx = 10;
res1.resource_mapping.nof_ports = 1;
res2.resource_mapping.nof_ports = 1;
res3.resource_mapping.nof_ports = 1;
res4.resource_mapping.nof_ports = 1;
res1.resource_mapping.cdm = srsran_csi_rs_cdm_nocdm;
res2.resource_mapping.cdm = srsran_csi_rs_cdm_nocdm;
res3.resource_mapping.cdm = srsran_csi_rs_cdm_nocdm;
res4.resource_mapping.cdm = srsran_csi_rs_cdm_nocdm;
res1.resource_mapping.density = srsran_csi_rs_resource_mapping_density_three;
res2.resource_mapping.density = srsran_csi_rs_resource_mapping_density_three;
res3.resource_mapping.density = srsran_csi_rs_resource_mapping_density_three;
res4.resource_mapping.density = srsran_csi_rs_resource_mapping_density_three;
if (carrier.scs == srsran_subcarrier_spacing_15kHz) {
res1.periodicity.period = 20;
res2.periodicity.period = 20;
res3.periodicity.period = 20;
res4.periodicity.period = 20;
res1.periodicity.offset = 10;
res2.periodicity.offset = 10;
res3.periodicity.offset = 11;
res4.periodicity.offset = 11;
} else if (carrier.scs == srsran_subcarrier_spacing_30kHz) {
res1.periodicity.period = 40;
res2.periodicity.period = 40;
res3.periodicity.period = 40;
res4.periodicity.period = 40;
res1.periodicity.offset = 20;
res2.periodicity.offset = 20;
res3.periodicity.offset = 21;
res4.periodicity.offset = 21;
} else {
srsran_terminate("Invalid subcarrier spacing %d kHz", 15U << (uint32_t)carrier.scs);
}
res1.resource_mapping.freq_band = {0, carrier.nof_prb};
res2.resource_mapping.freq_band = {0, carrier.nof_prb};
res3.resource_mapping.freq_band = {0, carrier.nof_prb};
res4.resource_mapping.freq_band = {0, carrier.nof_prb};
}
void phy_cfg_nr_default_t::make_pdsch_2_1_1_tdd(const srsran_carrier_nr_t& carrier, srsran_sch_hl_cfg_nr_t& pdsch)
{
// Select PDSCH time resource allocation
pdsch.common_time_ra[0].mapping_type = srsran_sch_mapping_type_A;
pdsch.common_time_ra[0].k = 0;
pdsch.common_time_ra[0].sliv = srsran_ra_type2_to_riv(SRSRAN_NSYMB_PER_SLOT_NR - 2, 2, SRSRAN_NSYMB_PER_SLOT_NR);
pdsch.nof_common_time_ra = 1;
// Setup PDSCH DMRS
pdsch.typeA_pos = srsran_dmrs_sch_typeA_pos_2;
pdsch.dmrs_typeA.present = true;
pdsch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos_2;
// Make default CSI-RS for tracking from TS38101 Table 5.2.1
make_nzp_csi_rs_ts38101_table_5_2_1(carrier, pdsch.nzp_csi_rs_sets[0]);
}
2021-06-30 08:12:17 -07:00
void phy_cfg_nr_default_t::make_pusch_default(srsran_sch_hl_cfg_nr_t& pusch)
{
// Select PUSCH time resource allocation
pusch.common_time_ra[0].k = 4;
pusch.common_time_ra[0].mapping_type = srsran_sch_mapping_type_A;
pusch.common_time_ra[0].sliv = srsran_ra_type2_to_riv(SRSRAN_NSYMB_PER_SLOT_NR, 0, SRSRAN_NSYMB_PER_SLOT_NR);
pusch.nof_common_time_ra = 1;
// Setup PUSCH DMRS type A position
pusch.typeA_pos = srsran_dmrs_sch_typeA_pos_2;
pusch.scaling = 1.0f;
pusch.beta_offsets.fix_ack = 12.625f;
pusch.beta_offsets.fix_csi1 = 2.25f;
pusch.beta_offsets.fix_csi2 = 2.25f;
2021-06-30 08:12:17 -07:00
}
void phy_cfg_nr_default_t::make_pucch_custom_one(srsran_pucch_nr_hl_cfg_t& pucch)
{
// PUCCH Resource for format 1
srsran_pucch_nr_resource_t resource_small = {};
resource_small.starting_prb = 0;
resource_small.format = SRSRAN_PUCCH_NR_FORMAT_1;
resource_small.initial_cyclic_shift = 0;
resource_small.nof_symbols = 14;
resource_small.start_symbol_idx = 0;
resource_small.time_domain_occ = 0;
// PUCCH Resource for format 2
srsran_pucch_nr_resource_t resource_big = {};
resource_big.starting_prb = 51;
resource_big.format = SRSRAN_PUCCH_NR_FORMAT_2;
resource_big.nof_prb = 1;
resource_big.nof_symbols = 2;
2021-07-21 07:24:17 -07:00
resource_big.start_symbol_idx = 12;
2021-06-30 08:12:17 -07:00
// Resource for SR
srsran_pucch_nr_resource_t resource_sr = {};
resource_sr.starting_prb = 51;
resource_sr.format = SRSRAN_PUCCH_NR_FORMAT_1;
resource_sr.initial_cyclic_shift = 0;
resource_sr.nof_symbols = 14;
resource_sr.start_symbol_idx = 0;
resource_sr.time_domain_occ = 0;
pucch.enabled = true;
// Set format 1 for 1-2 bits
pucch.sets[0].resources[0] = resource_small;
pucch.sets[0].resources[1] = resource_small;
pucch.sets[0].resources[2] = resource_small;
pucch.sets[0].resources[3] = resource_small;
pucch.sets[0].resources[4] = resource_small;
pucch.sets[0].resources[5] = resource_small;
pucch.sets[0].resources[6] = resource_small;
pucch.sets[0].resources[7] = resource_small;
pucch.sets[0].nof_resources = 8;
// Set format 2 for more bits
pucch.sets[1].resources[0] = resource_big;
pucch.sets[1].resources[1] = resource_big;
pucch.sets[1].resources[2] = resource_big;
pucch.sets[1].resources[3] = resource_big;
pucch.sets[1].resources[4] = resource_big;
pucch.sets[1].resources[5] = resource_big;
pucch.sets[1].resources[6] = resource_big;
pucch.sets[1].resources[7] = resource_big;
pucch.sets[1].nof_resources = 8;
// Configure scheduling request
pucch.sr_resources[1].configured = true;
pucch.sr_resources[1].sr_id = 0;
pucch.sr_resources[1].period = 40;
pucch.sr_resources[1].offset = 8;
pucch.sr_resources[1].resource = resource_sr;
}
2021-06-30 09:33:23 -07:00
void phy_cfg_nr_default_t::make_harq_auto(srsran_harq_ack_cfg_hl_t& harq,
const srsran_carrier_nr_t& carrier,
const srsran_tdd_config_nr_t& tdd_cfg)
2021-06-30 08:12:17 -07:00
{
2021-06-30 09:33:23 -07:00
// Generate as many entries as DL slots
harq.nof_dl_data_to_ul_ack = SRSRAN_MIN(tdd_cfg.pattern1.nof_dl_slots, SRSRAN_MAX_NOF_DL_DATA_TO_UL);
2021-07-21 07:24:17 -07:00
if (tdd_cfg.pattern1.nof_dl_symbols > 0) {
harq.nof_dl_data_to_ul_ack++;
}
2021-06-30 09:33:23 -07:00
// Set PDSCH to ACK timing delay to 4 or more
for (uint32_t n = 0; n < harq.nof_dl_data_to_ul_ack; n++) {
// Set the first slots into the first UL slot
2021-07-21 07:24:17 -07:00
if (harq.nof_dl_data_to_ul_ack >= 4 and n < (harq.nof_dl_data_to_ul_ack - 4)) {
2021-06-30 09:33:23 -07:00
harq.dl_data_to_ul_ack[n] = harq.nof_dl_data_to_ul_ack - n;
continue;
}
// After that try if n+4 is UL slot
if (srsran_tdd_nr_is_ul(&tdd_cfg, carrier.scs, n + 4)) {
harq.dl_data_to_ul_ack[n] = 4;
continue;
}
// Otherwise set delay to the first UL slot of the next TDD period
2021-07-21 07:24:17 -07:00
harq.dl_data_to_ul_ack[n] = (tdd_cfg.pattern1.period_ms + tdd_cfg.pattern1.nof_dl_slots) - n;
2021-06-30 08:12:17 -07:00
}
2021-06-30 09:33:23 -07:00
// Zero the rest
2021-06-30 08:12:17 -07:00
for (uint32_t i = harq.nof_dl_data_to_ul_ack; i < SRSRAN_MAX_NOF_DL_DATA_TO_UL; i++) {
harq.dl_data_to_ul_ack[i] = 0;
}
2021-06-30 09:33:23 -07:00
// Select dynamic HARQ-ACK codebook
harq.harq_ack_codebook = srsran_pdsch_harq_ack_codebook_dynamic;
2021-06-30 08:12:17 -07:00
}
void phy_cfg_nr_default_t::make_prach_default_lte(srsran_prach_cfg_t& prach)
{
prach.config_idx = 0;
2021-07-21 06:02:20 -07:00
prach.freq_offset = 4;
2021-06-30 08:12:17 -07:00
prach.root_seq_idx = 0;
prach.is_nr = true;
2021-06-30 08:12:17 -07:00
}
phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg)
{
switch (reference_cfg.carrier) {
case reference_cfg_t::R_CARRIER_CUSTOM_10MHZ:
make_carrier_custom_10MHz(carrier);
break;
2021-07-21 06:02:20 -07:00
case reference_cfg_t::R_CARRIER_CUSTOM_20MHZ:
make_carrier_custom_20MHz(carrier);
break;
case reference_cfg_t::R_CARRIER_COUNT:
srsran_terminate("Invalid carrier reference");
2021-06-30 08:12:17 -07:00
}
switch (reference_cfg.tdd) {
case reference_cfg_t::R_TDD_CUSTOM_6_4:
make_tdd_custom_6_4(tdd);
break;
2021-07-21 07:24:17 -07:00
case reference_cfg_t::R_TDD_FR1_15_1:
make_tdd_fr1_15_1(tdd);
break;
case reference_cfg_t::R_TDD_COUNT:
srsran_terminate("Invalid TDD reference");
2021-06-30 08:12:17 -07:00
}
switch (reference_cfg.pdcch) {
case reference_cfg_t::R_PDCCH_CUSTOM_COMMON_SS:
make_pdcch_custom_common_ss(pdcch, carrier);
break;
}
switch (reference_cfg.pdsch) {
case reference_cfg_t::R_PDSCH_DEFAULT:
make_pdsch_default(pdsch);
break;
2021-07-21 06:02:20 -07:00
case reference_cfg_t::R_PDSCH_TS38101_5_2_1:
make_pdsch_2_1_1_tdd(carrier, pdsch);
break;
case reference_cfg_t::R_PDSCH_COUNT:
srsran_terminate("Invalid PDSCH reference configuration");
2021-06-30 08:12:17 -07:00
}
switch (reference_cfg.pusch) {
case reference_cfg_t::R_PUSCH_DEFAULT:
make_pusch_default(pusch);
break;
}
switch (reference_cfg.pucch) {
case reference_cfg_t::R_PUCCH_CUSTOM_ONE:
make_pucch_custom_one(pucch);
2021-06-30 08:12:17 -07:00
break;
}
switch (reference_cfg.harq) {
case reference_cfg_t::R_HARQ_AUTO:
2021-06-30 09:33:23 -07:00
make_harq_auto(harq_ack, carrier, tdd);
2021-06-30 08:12:17 -07:00
break;
}
switch (reference_cfg.prach) {
case reference_cfg_t::R_PRACH_DEFAULT_LTE:
make_prach_default_lte(prach);
break;
}
}
} // namespace srsran