mirror of https://github.com/PentHertz/srsLTE.git
Packed NR TDD config in duplex configuration and created test case for FDD
This commit is contained in:
parent
53bf29a540
commit
0324806d6c
|
@ -73,7 +73,7 @@ void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg);
|
|||
bool make_phy_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* prach_cfg);
|
||||
|
||||
bool make_phy_tdd_cfg(const asn1::rrc_nr::tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common,
|
||||
srsran_tdd_config_nr_t* srsran_tdd_config_nr);
|
||||
srsran_duplex_config_nr_t* srsran_duplex_config_nr);
|
||||
bool make_phy_harq_ack_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg,
|
||||
srsran_harq_ack_cfg_hl_t* srsran_ue_dl_nr_harq_ack_cfg);
|
||||
bool make_phy_coreset_cfg(const asn1::rrc_nr::ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* srsran_coreset);
|
||||
|
|
|
@ -35,16 +35,16 @@ struct phy_cfg_nr_t {
|
|||
srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_30kHz;
|
||||
};
|
||||
|
||||
srsran_tdd_config_nr_t tdd = {};
|
||||
srsran_sch_hl_cfg_nr_t pdsch = {};
|
||||
srsran_sch_hl_cfg_nr_t pusch = {};
|
||||
srsran_pucch_nr_hl_cfg_t pucch = {};
|
||||
srsran_prach_cfg_t prach = {};
|
||||
srsran_pdcch_cfg_nr_t pdcch = {};
|
||||
srsran_harq_ack_cfg_hl_t harq_ack = {};
|
||||
srsran_csi_hl_cfg_t csi = {};
|
||||
srsran_carrier_nr_t carrier = {};
|
||||
ssb_cfg_t ssb;
|
||||
srsran_duplex_config_nr_t duplex = {};
|
||||
srsran_sch_hl_cfg_nr_t pdsch = {};
|
||||
srsran_sch_hl_cfg_nr_t pusch = {};
|
||||
srsran_pucch_nr_hl_cfg_t pucch = {};
|
||||
srsran_prach_cfg_t prach = {};
|
||||
srsran_pdcch_cfg_nr_t pdcch = {};
|
||||
srsran_harq_ack_cfg_hl_t harq_ack = {};
|
||||
srsran_csi_hl_cfg_t csi = {};
|
||||
srsran_carrier_nr_t carrier = {};
|
||||
ssb_cfg_t ssb;
|
||||
|
||||
phy_cfg_nr_t() {}
|
||||
|
||||
|
|
|
@ -43,18 +43,23 @@ public:
|
|||
const std::array<std::string, R_CARRIER_COUNT> R_CARRIER_STRING = {{"10MHz", "20MHz"}};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* @brief FDD, all slots for DL and UL
|
||||
*/
|
||||
R_DUPLEX_FDD = 0,
|
||||
|
||||
/**
|
||||
* @brief TDD custom reference 5 slot DL and 5 slot UL
|
||||
*/
|
||||
R_TDD_CUSTOM_6_4 = 0,
|
||||
R_DUPLEX_TDD_CUSTOM_6_4,
|
||||
|
||||
/**
|
||||
* @brief TDD pattern FR1.15-1 defined in TS38.101-4 Table A.1.2-1
|
||||
*/
|
||||
R_TDD_FR1_15_1,
|
||||
R_TDD_COUNT,
|
||||
} tdd = R_TDD_CUSTOM_6_4;
|
||||
const std::array<std::string, R_TDD_COUNT> R_TDD_STRING = {{"6D+4U", "FR1.15-1"}};
|
||||
R_DUPLEX_TDD_FR1_15_1,
|
||||
R_DUPLEX_COUNT,
|
||||
} duplex = R_DUPLEX_TDD_CUSTOM_6_4;
|
||||
const std::array<std::string, R_DUPLEX_COUNT> R_DUPLEX_STRING = {{"FDD", "6D+4U", "FR1.15-1"}};
|
||||
|
||||
enum {
|
||||
/**
|
||||
|
@ -144,8 +149,8 @@ private:
|
|||
/**
|
||||
* TDD make helper methods
|
||||
*/
|
||||
static void make_tdd_custom_6_4(srsran_tdd_config_nr_t& tdd);
|
||||
static void make_tdd_fr1_15_1(srsran_tdd_config_nr_t& tdd);
|
||||
static void make_tdd_custom_6_4(srsran_duplex_config_nr_t& duplex);
|
||||
static void make_tdd_fr1_15_1(srsran_duplex_config_nr_t& duplex);
|
||||
|
||||
/**
|
||||
* PDCCH make helper methods
|
||||
|
@ -171,9 +176,9 @@ private:
|
|||
/**
|
||||
* HARQ make helper methods
|
||||
*/
|
||||
static void make_harq_auto(srsran_harq_ack_cfg_hl_t& harq,
|
||||
const srsran_carrier_nr_t& carrier,
|
||||
const srsran_tdd_config_nr_t& tdd_cfg);
|
||||
static void make_harq_auto(srsran_harq_ack_cfg_hl_t& harq,
|
||||
const srsran_carrier_nr_t& carrier,
|
||||
const srsran_duplex_config_nr_t& duplex_cfg);
|
||||
|
||||
/**
|
||||
* PRACH make helper methods
|
||||
|
|
|
@ -458,6 +458,17 @@ typedef struct SRSRAN_API {
|
|||
srsran_tdd_pattern_t pattern2;
|
||||
} srsran_tdd_config_nr_t;
|
||||
|
||||
/**
|
||||
* @brief Describes duplex configuration
|
||||
*/
|
||||
typedef struct SRSRAN_API {
|
||||
srsran_duplex_mode_t mode;
|
||||
union {
|
||||
srsran_tdd_config_nr_t tdd; ///< TDD configuration
|
||||
// ... add here other mode parameters
|
||||
};
|
||||
} srsran_duplex_config_nr_t;
|
||||
|
||||
/**
|
||||
* @brief Describes a measurement based on NZP-CSI-RS or SSB-CSI
|
||||
* @note Used for tracking RSRP, SNR, CFO, SFO, and so on
|
||||
|
@ -593,21 +604,21 @@ SRSRAN_API float srsran_symbol_distance_s(uint32_t l0, uint32_t l1, srsran_subca
|
|||
|
||||
/**
|
||||
* @brief Decides whether a given slot is configured as Downlink
|
||||
* @param cfg Provides TDD configuration
|
||||
* @param cfg Provides the carrier duplex configuration
|
||||
* @param numerology Provides BWP numerology
|
||||
* @param slot_idx Slot index in the frame for the given numerology
|
||||
* @return true if the provided slot index is configured for Downlink
|
||||
*/
|
||||
SRSRAN_API bool srsran_tdd_nr_is_dl(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx);
|
||||
SRSRAN_API bool srsran_duplex_nr_is_dl(const srsran_duplex_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx);
|
||||
|
||||
/**
|
||||
* @brief Decides whether a given slot is configured as Uplink
|
||||
* @param cfg Provides TDD configuration
|
||||
* @param cfg Provides the carrier duplex configuration
|
||||
* @param numerology Provides BWP numerology
|
||||
* @param slot_idx Slot index in the frame for the given numerology
|
||||
* @return true if the provided slot index is configured for Uplink
|
||||
*/
|
||||
SRSRAN_API bool srsran_tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx);
|
||||
SRSRAN_API bool srsran_duplex_nr_is_ul(const srsran_duplex_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx);
|
||||
|
||||
SRSRAN_API int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran_cell_t* cell);
|
||||
|
||||
|
|
|
@ -271,21 +271,21 @@ bool make_phy_rach_cfg(const rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* p
|
|||
};
|
||||
|
||||
bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common,
|
||||
srsran_tdd_config_nr_t* in_srsran_tdd_config_nr)
|
||||
srsran_duplex_config_nr_t* in_srsran_duplex_config_nr)
|
||||
{
|
||||
srsran_tdd_config_nr_t srsran_tdd_config_nr = {};
|
||||
srsran_duplex_config_nr_t srsran_duplex_config_nr = {};
|
||||
switch (tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity) {
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1:
|
||||
srsran_tdd_config_nr.pattern1.period_ms = 1;
|
||||
srsran_duplex_config_nr.tdd.pattern1.period_ms = 1;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2:
|
||||
srsran_tdd_config_nr.pattern1.period_ms = 2;
|
||||
srsran_duplex_config_nr.tdd.pattern1.period_ms = 2;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5:
|
||||
srsran_tdd_config_nr.pattern1.period_ms = 5;
|
||||
srsran_duplex_config_nr.tdd.pattern1.period_ms = 5;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10:
|
||||
srsran_tdd_config_nr.pattern1.period_ms = 10;
|
||||
srsran_duplex_config_nr.tdd.pattern1.period_ms = 10;
|
||||
break;
|
||||
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1p25:
|
||||
|
@ -297,12 +297,12 @@ bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common,
|
|||
tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity.to_string());
|
||||
return false;
|
||||
}
|
||||
srsran_tdd_config_nr.pattern1.nof_dl_slots = tdd_ul_dl_cfg_common.pattern1.nrof_dl_slots;
|
||||
srsran_tdd_config_nr.pattern1.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_dl_symbols;
|
||||
srsran_tdd_config_nr.pattern1.nof_ul_slots = tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots;
|
||||
srsran_tdd_config_nr.pattern1.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols;
|
||||
srsran_duplex_config_nr.tdd.pattern1.nof_dl_slots = tdd_ul_dl_cfg_common.pattern1.nrof_dl_slots;
|
||||
srsran_duplex_config_nr.tdd.pattern1.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_dl_symbols;
|
||||
srsran_duplex_config_nr.tdd.pattern1.nof_ul_slots = tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots;
|
||||
srsran_duplex_config_nr.tdd.pattern1.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols;
|
||||
// Copy and return struct
|
||||
*in_srsran_tdd_config_nr = srsran_tdd_config_nr;
|
||||
*in_srsran_duplex_config_nr = srsran_duplex_config_nr;
|
||||
|
||||
if (not tdd_ul_dl_cfg_common.pattern2_present) {
|
||||
return true;
|
||||
|
@ -310,16 +310,16 @@ bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common,
|
|||
|
||||
switch (tdd_ul_dl_cfg_common.pattern2.dl_ul_tx_periodicity) {
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1:
|
||||
srsran_tdd_config_nr.pattern2.period_ms = 1;
|
||||
srsran_duplex_config_nr.tdd.pattern2.period_ms = 1;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2:
|
||||
srsran_tdd_config_nr.pattern2.period_ms = 2;
|
||||
srsran_duplex_config_nr.tdd.pattern2.period_ms = 2;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5:
|
||||
srsran_tdd_config_nr.pattern2.period_ms = 5;
|
||||
srsran_duplex_config_nr.tdd.pattern2.period_ms = 5;
|
||||
break;
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10:
|
||||
srsran_tdd_config_nr.pattern2.period_ms = 10;
|
||||
srsran_duplex_config_nr.tdd.pattern2.period_ms = 10;
|
||||
break;
|
||||
|
||||
case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1p25:
|
||||
|
@ -332,12 +332,12 @@ bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common,
|
|||
return false;
|
||||
}
|
||||
|
||||
srsran_tdd_config_nr.pattern2.nof_dl_slots = tdd_ul_dl_cfg_common.pattern2.nrof_dl_slots;
|
||||
srsran_tdd_config_nr.pattern2.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_dl_symbols;
|
||||
srsran_tdd_config_nr.pattern2.nof_ul_slots = tdd_ul_dl_cfg_common.pattern2.nrof_ul_slots;
|
||||
srsran_tdd_config_nr.pattern2.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_ul_symbols;
|
||||
srsran_duplex_config_nr.tdd.pattern2.nof_dl_slots = tdd_ul_dl_cfg_common.pattern2.nrof_dl_slots;
|
||||
srsran_duplex_config_nr.tdd.pattern2.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_dl_symbols;
|
||||
srsran_duplex_config_nr.tdd.pattern2.nof_ul_slots = tdd_ul_dl_cfg_common.pattern2.nrof_ul_slots;
|
||||
srsran_duplex_config_nr.tdd.pattern2.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_ul_symbols;
|
||||
// Copy and return struct
|
||||
*in_srsran_tdd_config_nr = srsran_tdd_config_nr;
|
||||
*in_srsran_duplex_config_nr = srsran_duplex_config_nr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -44,13 +44,13 @@ phy_cfg_nr_default_t::reference_cfg_t::reference_cfg_t(const std::string& args)
|
|||
}
|
||||
}
|
||||
srsran_assert(carrier != R_CARRIER_COUNT, "Invalid carrier reference configuration '%s'", param.back().c_str());
|
||||
} 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()) {
|
||||
} else if (param.front() == "duplex") {
|
||||
for (duplex = R_DUPLEX_FDD; duplex < R_DUPLEX_COUNT; duplex = inc(duplex)) {
|
||||
if (R_DUPLEX_STRING[duplex] == param.back()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
srsran_assert(tdd != R_TDD_COUNT, "Invalid TDD reference configuration '%s'", param.back().c_str());
|
||||
srsran_assert(duplex != R_DUPLEX_COUNT, "Invalid duplex reference configuration '%s'", param.back().c_str());
|
||||
} else if (param.front() == "pdsch") {
|
||||
for (pdsch = R_PDSCH_DEFAULT; pdsch < R_PDSCH_COUNT; pdsch = inc(pdsch)) {
|
||||
if (R_PDSCH_STRING[pdsch] == param.back()) {
|
||||
|
@ -86,8 +86,18 @@ void phy_cfg_nr_default_t::make_carrier_custom_20MHz(srsran_carrier_nr_t& carrie
|
|||
carrier.scs = srsran_subcarrier_spacing_15kHz;
|
||||
}
|
||||
|
||||
void phy_cfg_nr_default_t::make_tdd_custom_6_4(srsran_tdd_config_nr_t& tdd)
|
||||
void phy_cfg_nr_default_t::make_tdd_custom_6_4(srsran_duplex_config_nr_t& conf)
|
||||
{
|
||||
// Set the duplex mode to TDD
|
||||
conf.mode = SRSRAN_DUPLEX_MODE_TDD;
|
||||
|
||||
// Select TDD config
|
||||
srsran_tdd_config_nr_t& tdd = conf.tdd;
|
||||
|
||||
// Initialise pattern
|
||||
tdd = {};
|
||||
|
||||
// Enable pattern 1
|
||||
tdd.pattern1.period_ms = 10;
|
||||
tdd.pattern1.nof_dl_slots = 6;
|
||||
tdd.pattern1.nof_dl_symbols = 0;
|
||||
|
@ -98,8 +108,17 @@ void phy_cfg_nr_default_t::make_tdd_custom_6_4(srsran_tdd_config_nr_t& tdd)
|
|||
tdd.pattern2.period_ms = 0;
|
||||
}
|
||||
|
||||
void phy_cfg_nr_default_t::make_tdd_fr1_15_1(srsran_tdd_config_nr_t& tdd)
|
||||
{
|
||||
void phy_cfg_nr_default_t::make_tdd_fr1_15_1(srsran_duplex_config_nr_t& conf)
|
||||
{ // Set the duplex mode to TDD
|
||||
conf.mode = SRSRAN_DUPLEX_MODE_TDD;
|
||||
|
||||
// Select TDD config
|
||||
srsran_tdd_config_nr_t& tdd = conf.tdd;
|
||||
|
||||
// Initialise pattern
|
||||
tdd = {};
|
||||
|
||||
// Enable pattern 1
|
||||
tdd.pattern1.period_ms = 5;
|
||||
tdd.pattern1.nof_dl_slots = 3;
|
||||
tdd.pattern1.nof_dl_symbols = 10;
|
||||
|
@ -319,32 +338,39 @@ void phy_cfg_nr_default_t::make_pucch_custom_one(srsran_pucch_nr_hl_cfg_t& pucch
|
|||
pucch.sr_resources[1].resource = resource_sr;
|
||||
}
|
||||
|
||||
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)
|
||||
void phy_cfg_nr_default_t::make_harq_auto(srsran_harq_ack_cfg_hl_t& harq,
|
||||
const srsran_carrier_nr_t& carrier,
|
||||
const srsran_duplex_config_nr_t& duplex_cfg)
|
||||
{
|
||||
// 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);
|
||||
if (tdd_cfg.pattern1.nof_dl_symbols > 0) {
|
||||
harq.nof_dl_data_to_ul_ack++;
|
||||
}
|
||||
if (duplex_cfg.mode == SRSRAN_DUPLEX_MODE_TDD) {
|
||||
const srsran_tdd_config_nr_t& tdd_cfg = duplex_cfg.tdd;
|
||||
|
||||
// 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
|
||||
if (harq.nof_dl_data_to_ul_ack >= 4 and n < (harq.nof_dl_data_to_ul_ack - 4)) {
|
||||
harq.dl_data_to_ul_ack[n] = harq.nof_dl_data_to_ul_ack - n;
|
||||
continue;
|
||||
// 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);
|
||||
if (tdd_cfg.pattern1.nof_dl_symbols > 0) {
|
||||
harq.nof_dl_data_to_ul_ack++;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
// 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
|
||||
if (harq.nof_dl_data_to_ul_ack >= 4 and n < (harq.nof_dl_data_to_ul_ack - 4)) {
|
||||
harq.dl_data_to_ul_ack[n] = harq.nof_dl_data_to_ul_ack - n;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise set delay to the first UL slot of the next TDD period
|
||||
harq.dl_data_to_ul_ack[n] = (tdd_cfg.pattern1.period_ms + tdd_cfg.pattern1.nof_dl_slots) - n;
|
||||
// After that try if n+4 is UL slot
|
||||
if (srsran_duplex_nr_is_ul(&duplex_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
|
||||
harq.dl_data_to_ul_ack[n] = (tdd_cfg.pattern1.period_ms + tdd_cfg.pattern1.nof_dl_slots) - n;
|
||||
}
|
||||
} else {
|
||||
harq.dl_data_to_ul_ack[0] = 4;
|
||||
harq.nof_dl_data_to_ul_ack = 1;
|
||||
}
|
||||
|
||||
// Zero the rest
|
||||
|
@ -377,14 +403,17 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg)
|
|||
srsran_assertion_failure("Invalid carrier reference");
|
||||
}
|
||||
|
||||
switch (reference_cfg.tdd) {
|
||||
case reference_cfg_t::R_TDD_CUSTOM_6_4:
|
||||
make_tdd_custom_6_4(tdd);
|
||||
switch (reference_cfg.duplex) {
|
||||
case reference_cfg_t::R_DUPLEX_FDD:
|
||||
duplex.mode = SRSRAN_DUPLEX_MODE_FDD;
|
||||
break;
|
||||
case reference_cfg_t::R_TDD_FR1_15_1:
|
||||
make_tdd_fr1_15_1(tdd);
|
||||
case reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4:
|
||||
make_tdd_custom_6_4(duplex);
|
||||
break;
|
||||
case reference_cfg_t::R_TDD_COUNT:
|
||||
case reference_cfg_t::R_DUPLEX_TDD_FR1_15_1:
|
||||
make_tdd_fr1_15_1(duplex);
|
||||
break;
|
||||
case reference_cfg_t::R_DUPLEX_COUNT:
|
||||
srsran_assertion_failure("Invalid TDD reference");
|
||||
}
|
||||
|
||||
|
@ -419,7 +448,7 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg)
|
|||
|
||||
switch (reference_cfg.harq) {
|
||||
case reference_cfg_t::R_HARQ_AUTO:
|
||||
make_harq_auto(harq_ack, carrier, tdd);
|
||||
make_harq_auto(harq_ack, carrier, duplex);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -283,13 +283,8 @@ float srsran_symbol_distance_s(uint32_t l0, uint32_t l1, srsran_subcarrier_spaci
|
|||
return srsran_symbol_offset_s(l1, scs) - srsran_symbol_offset_s(l0, scs);
|
||||
}
|
||||
|
||||
bool srsran_tdd_nr_is_dl(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
static bool tdd_nr_is_dl(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
{
|
||||
// Protect NULL pointer access
|
||||
if (cfg == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent zero division
|
||||
if (cfg->pattern1.period_ms == 0 && cfg->pattern2.period_ms == 0) {
|
||||
return false;
|
||||
|
@ -312,13 +307,24 @@ bool srsran_tdd_nr_is_dl(const srsran_tdd_config_nr_t* cfg, uint32_t numerology,
|
|||
(slot_idx_period == pattern->nof_dl_slots && pattern->nof_dl_symbols != 0));
|
||||
}
|
||||
|
||||
bool srsran_tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
bool srsran_duplex_nr_is_dl(const srsran_duplex_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
|
||||
{
|
||||
// Protect NULL pointer access
|
||||
if (cfg == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In case of TDD
|
||||
if (cfg->mode == SRSRAN_DUPLEX_MODE_TDD) {
|
||||
return tdd_nr_is_dl(&cfg->tdd, numerology, slot_idx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
{
|
||||
// Prevent zero division
|
||||
if (cfg->pattern1.period_ms == 0 && cfg->pattern2.period_ms == 0) {
|
||||
return false;
|
||||
|
@ -343,6 +349,21 @@ bool srsran_tdd_nr_is_ul(const srsran_tdd_config_nr_t* cfg, uint32_t numerology,
|
|||
return (slot_idx_period > start_ul || (slot_idx_period == start_ul && pattern->nof_ul_symbols != 0));
|
||||
}
|
||||
|
||||
bool srsran_duplex_nr_is_ul(const srsran_duplex_config_nr_t* cfg, uint32_t numerology, uint32_t slot_idx)
|
||||
{
|
||||
// Protect NULL pointer access
|
||||
if (cfg == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// In case of TDD
|
||||
if (cfg->mode == SRSRAN_DUPLEX_MODE_TDD) {
|
||||
return tdd_nr_is_ul(&cfg->tdd, numerology, slot_idx);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int srsran_carrier_to_cell(const srsran_carrier_nr_t* carrier, srsran_cell_t* cell)
|
||||
{
|
||||
// Protect memory access
|
||||
|
|
|
@ -88,15 +88,15 @@ int make_phy_tdd_cfg_test()
|
|||
tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots = 2;
|
||||
tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols = 4;
|
||||
|
||||
srsran_tdd_config_nr_t srsran_tdd_config_nr;
|
||||
TESTASSERT(make_phy_tdd_cfg(tdd_ul_dl_cfg_common, &srsran_tdd_config_nr) == true);
|
||||
srsran_duplex_config_nr_t srsran_duplex_config_nr;
|
||||
TESTASSERT(make_phy_tdd_cfg(tdd_ul_dl_cfg_common, &srsran_duplex_config_nr) == true);
|
||||
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern1.period_ms == 10);
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern1.nof_dl_slots == 7);
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern1.nof_dl_symbols == 6);
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern1.nof_ul_slots == 2);
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern1.nof_ul_symbols == 4);
|
||||
TESTASSERT(srsran_tdd_config_nr.pattern2.period_ms == 0);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern1.period_ms == 10);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern1.nof_dl_slots == 7);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern1.nof_dl_symbols == 6);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern1.nof_ul_slots == 2);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern1.nof_ul_symbols == 4);
|
||||
TESTASSERT(srsran_duplex_config_nr.tdd.pattern2.period_ms == 0);
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
|
||||
struct cell_cfg_t {
|
||||
srsran_carrier_nr_t carrier = {};
|
||||
srsran_tdd_config_nr_t tdd = {};
|
||||
srsran_duplex_config_nr_t duplex = {};
|
||||
srsran::phy_cfg_nr_t::ssb_cfg_t ssb = {};
|
||||
srsran::bounded_vector<bwp_cfg_t, SCHED_NR_MAX_BWP_PER_CELL> bwps{1}; // idx0 for BWP-common
|
||||
};
|
||||
|
|
|
@ -37,8 +37,8 @@ bwp_params::bwp_params(const cell_cfg_t& cell, const sched_cfg_t& sched_cfg_, ui
|
|||
uint32_t nof_slots = SRSRAN_NSLOTS_PER_FRAME_NR(cfg.numerology_idx);
|
||||
for (size_t sl = 0; sl < nof_slots; ++sl) {
|
||||
slot_cfg sl_cfg{};
|
||||
sl_cfg.is_dl = srsran_tdd_nr_is_dl(&cell_cfg.tdd, cfg.numerology_idx, sl);
|
||||
sl_cfg.is_ul = srsran_tdd_nr_is_ul(&cell_cfg.tdd, cfg.numerology_idx, sl);
|
||||
sl_cfg.is_dl = srsran_duplex_nr_is_dl(&cell_cfg.duplex, cfg.numerology_idx, sl);
|
||||
sl_cfg.is_ul = srsran_duplex_nr_is_ul(&cell_cfg.duplex, cfg.numerology_idx, sl);
|
||||
slots.push_back(sl_cfg);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,15 +61,15 @@ slot_ue ue_carrier::try_reserve(slot_point pdcch_slot,
|
|||
sfu.dl_pending_bytes = dl_pending_bytes;
|
||||
sfu.ul_pending_bytes = ul_pending_bytes;
|
||||
|
||||
const srsran_tdd_config_nr_t& tdd_cfg = cell_params.cell_cfg.tdd;
|
||||
if (srsran_tdd_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) {
|
||||
const srsran_duplex_config_nr_t& tdd_cfg = cell_params.cell_cfg.duplex;
|
||||
if (srsran_duplex_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) {
|
||||
// If DL enabled
|
||||
sfu.h_dl = harq_ent.find_pending_dl_retx();
|
||||
if (sfu.h_dl == nullptr and sfu.dl_pending_bytes > 0) {
|
||||
sfu.h_dl = harq_ent.find_empty_dl_harq();
|
||||
}
|
||||
}
|
||||
if (srsran_tdd_nr_is_ul(&tdd_cfg, 0, sfu.pusch_slot.slot_idx())) {
|
||||
if (srsran_duplex_nr_is_ul(&tdd_cfg, 0, sfu.pusch_slot.slot_idx())) {
|
||||
// If UL enabled
|
||||
sfu.h_ul = harq_ent.find_pending_ul_retx();
|
||||
if (sfu.h_ul == nullptr and sfu.ul_pending_bytes > 0) {
|
||||
|
|
|
@ -36,7 +36,7 @@ inline sched_nr_interface::cell_cfg_t get_default_cell_cfg(
|
|||
sched_nr_interface::cell_cfg_t cell_cfg{};
|
||||
|
||||
cell_cfg.carrier = phy_cfg.carrier;
|
||||
cell_cfg.tdd = phy_cfg.tdd;
|
||||
cell_cfg.duplex = phy_cfg.duplex;
|
||||
|
||||
cell_cfg.bwps.resize(1);
|
||||
cell_cfg.bwps[0].pdcch = phy_cfg.pdcch;
|
||||
|
|
|
@ -82,7 +82,7 @@ void sched_nr_cfg_serialized_test()
|
|||
uint32_t max_nof_ttis = 1000, nof_sectors = 4;
|
||||
task_job_manager tasks;
|
||||
|
||||
sched_nr_interface::sched_cfg_t cfg;
|
||||
sched_nr_interface::sched_cfg_t cfg;
|
||||
cfg.auto_refill_buffer = true;
|
||||
|
||||
std::vector<sched_nr_interface::cell_cfg_t> cells_cfg = get_default_cells_cfg(nof_sectors);
|
||||
|
@ -111,7 +111,7 @@ void sched_nr_cfg_serialized_test()
|
|||
sched_nr_cc_output_res_t out{slot_tx, cc, &dl_res, &ul_res};
|
||||
sched_tester.update(out);
|
||||
tasks.finish_cc(slot_rx, dl_res, ul_res);
|
||||
TESTASSERT(not srsran_tdd_nr_is_dl(&cells_cfg[cc].tdd, 0, (slot_tx).slot_idx()) or
|
||||
TESTASSERT(not srsran_duplex_nr_is_dl(&cells_cfg[cc].duplex, 0, (slot_tx).slot_idx()) or
|
||||
dl_res.dl_sched.pdcch_dl.size() == 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ bool cc_worker::work_dl()
|
|||
}
|
||||
|
||||
// Check if it is a DL slot, if not skip
|
||||
if (!srsran_tdd_nr_is_dl(&phy.cfg.tdd, 0, dl_slot_cfg.idx)) {
|
||||
if (!srsran_duplex_nr_is_dl(&phy.cfg.duplex, 0, dl_slot_cfg.idx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -523,7 +523,7 @@ bool cc_worker::work_ul()
|
|||
bool has_ul_ack = phy.get_pending_ack(ul_slot_cfg.idx, pdsch_ack);
|
||||
|
||||
// Check if it is a UL slot, if not skip
|
||||
if (!srsran_tdd_nr_is_ul(&phy.cfg.tdd, 0, ul_slot_cfg.idx)) {
|
||||
if (!srsran_duplex_nr_is_ul(&phy.cfg.duplex, 0, ul_slot_cfg.idx)) {
|
||||
// No NR signal shall be transmitted
|
||||
srsran_vec_cf_zero(tx_buffer[0], ue_ul.ifft.sf_sz);
|
||||
|
||||
|
|
|
@ -1193,11 +1193,11 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
|
|||
}
|
||||
|
||||
if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) {
|
||||
srsran_tdd_config_nr_t tdd;
|
||||
if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &tdd) == true) {
|
||||
phy_cfg.tdd = tdd;
|
||||
srsran_duplex_config_nr_t duplex;
|
||||
if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &duplex) == true) {
|
||||
phy_cfg.duplex = duplex;
|
||||
} else {
|
||||
logger.warning("Warning while building tdd structure");
|
||||
logger.warning("Warning while building duplex structure");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -25,15 +25,18 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
|
|||
${Boost_LIBRARIES}
|
||||
${ATOMIC_LIBS})
|
||||
|
||||
# For each supported bandwidth
|
||||
foreach (NR_PHY_TEST_BW "10MHz" "20MHz")
|
||||
foreach (NR_PHY_TEST_TDD "6D+4U" "FR1.15-1")
|
||||
# For each supported frame structure
|
||||
foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1")
|
||||
set(NR_PHY_TEST_DURATION_MS 20)
|
||||
|
||||
# DL flooding only
|
||||
foreach (NR_PHY_TEST_PDSCH "default" "ts38101/5.2-1")
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_TDD}_dl_${NR_PHY_TEST_PDSCH} nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},tdd=${NR_PHY_TEST_TDD},pdsch=${NR_PHY_TEST_PDSCH}
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_dl_${NR_PHY_TEST_PDSCH} nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX},pdsch=${NR_PHY_TEST_PDSCH}
|
||||
--duration=${NR_PHY_TEST_DURATION_MS}
|
||||
--gnb.stack.pdsch.slots=0,1,2,3,4,5 # All possible DL slots
|
||||
--gnb.stack.pdsch.slots=all
|
||||
--gnb.stack.pdsch.start=0 # Start at RB 0
|
||||
--gnb.stack.pdsch.length=52 # Full 10 MHz BW
|
||||
--gnb.stack.pdsch.mcs=27 # Maximum MCS
|
||||
|
@ -43,11 +46,12 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
|
|||
)
|
||||
endforeach ()
|
||||
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_TDD}_ul_only nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},tdd=${NR_PHY_TEST_TDD}
|
||||
# UL flooding
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_ul_only nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX}
|
||||
--duration=${NR_PHY_TEST_DURATION_MS}
|
||||
--gnb.stack.pdsch.slots=6 # No PDSCH
|
||||
--gnb.stack.pusch.slots=6,7,8,9 # All possible UL slots
|
||||
--gnb.stack.pdsch.slots=none
|
||||
--gnb.stack.pusch.slots=all
|
||||
--gnb.stack.pusch.start=0 # Start at RB 0
|
||||
--gnb.stack.pusch.length=52 # Full 10 MHz BW
|
||||
--gnb.stack.pusch.mcs=28 # Maximum MCS
|
||||
|
@ -55,14 +59,15 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
|
|||
--ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS}
|
||||
)
|
||||
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_TDD}_bidir nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},tdd=${NR_PHY_TEST_TDD}
|
||||
# DL and UL flooding
|
||||
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_${NR_PHY_TEST_DUPLEX}_bidir nr_phy_test
|
||||
--reference=carrier=${NR_PHY_TEST_BW},duplex=${NR_PHY_TEST_DUPLEX}
|
||||
--duration=${NR_PHY_TEST_DURATION_MS}
|
||||
--gnb.stack.pdsch.slots=0,1,2,3,4,5 # All possible DL slots
|
||||
--gnb.stack.pdsch.slots=all
|
||||
--gnb.stack.pdsch.start=0 # Start at RB 0
|
||||
--gnb.stack.pdsch.length=52 # Full 10 MHz BW
|
||||
--gnb.stack.pdsch.mcs=28 # Maximum MCS
|
||||
--gnb.stack.pusch.slots=6,7,8,9 # All possible UL slots
|
||||
--gnb.stack.pusch.slots=all
|
||||
--gnb.stack.pusch.start=0 # Start at RB 0
|
||||
--gnb.stack.pusch.length=52 # Full 10 MHz BW
|
||||
--gnb.stack.pusch.mcs=28 # Maximum MCS
|
||||
|
|
|
@ -360,10 +360,22 @@ public:
|
|||
ul.mcs = args.pusch.mcs;
|
||||
|
||||
if (args.pdsch.slots != "none" and not args.pdsch.slots.empty()) {
|
||||
srsran::string_parse_list(args.pdsch.slots, ',', dl.slots);
|
||||
if (args.pdsch.slots == "all") {
|
||||
for (uint32_t n = 0; n < SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs); n++) {
|
||||
dl.slots.insert(n);
|
||||
}
|
||||
} else {
|
||||
srsran::string_parse_list(args.pdsch.slots, ',', dl.slots);
|
||||
}
|
||||
}
|
||||
if (args.pusch.slots != "none" and not args.pusch.slots.empty()) {
|
||||
srsran::string_parse_list(args.pusch.slots, ',', ul.slots);
|
||||
if (args.pusch.slots == "all") {
|
||||
for (uint32_t n = 0; n < SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs); n++) {
|
||||
ul.slots.insert(n);
|
||||
}
|
||||
} else {
|
||||
srsran::string_parse_list(args.pusch.slots, ',', ul.slots);
|
||||
}
|
||||
}
|
||||
|
||||
// Select DCI locations
|
||||
|
@ -405,7 +417,11 @@ public:
|
|||
|
||||
// Setup DL Data to ACK timing
|
||||
for (uint32_t i = 0; i < SRSRAN_NOF_SF_X_FRAME; i++) {
|
||||
dl_data_to_ul_ack[i] = args.phy_cfg.harq_ack.dl_data_to_ul_ack[i % args.phy_cfg.tdd.pattern1.period_ms];
|
||||
if (args.phy_cfg.duplex.mode == SRSRAN_DUPLEX_MODE_TDD) {
|
||||
dl_data_to_ul_ack[i] = args.phy_cfg.harq_ack.dl_data_to_ul_ack[i % args.phy_cfg.duplex.tdd.pattern1.period_ms];
|
||||
} else {
|
||||
dl_data_to_ul_ack[i] = args.phy_cfg.harq_ack.dl_data_to_ul_ack[i % args.phy_cfg.harq_ack.nof_dl_data_to_ul_ack];
|
||||
}
|
||||
}
|
||||
|
||||
// If reached this point the configuration is valid
|
||||
|
@ -441,7 +457,7 @@ public:
|
|||
}
|
||||
|
||||
// Check if it is TDD DL slot and PDSCH mask, if no PDSCH shall be scheduled, do not set any grant and skip
|
||||
if (not srsran_tdd_nr_is_dl(&phy_cfg.tdd, phy_cfg.carrier.scs, slot_cfg.idx)) {
|
||||
if (not srsran_duplex_nr_is_dl(&phy_cfg.duplex, phy_cfg.carrier.scs, slot_cfg.idx)) {
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -451,7 +467,7 @@ public:
|
|||
}
|
||||
|
||||
// Check if the UL slot is valid, if not skip UL scheduling
|
||||
if (not srsran_tdd_nr_is_ul(&phy_cfg.tdd, phy_cfg.carrier.scs, TTI_TX(slot_cfg.idx))) {
|
||||
if (not srsran_duplex_nr_is_ul(&phy_cfg.duplex, phy_cfg.carrier.scs, TTI_TX(slot_cfg.idx))) {
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue