mirror of https://github.com/PentHertz/srsLTE.git
Sepparate CSI report configuration from quantification and integrate in nr_phy_test with assertions
This commit is contained in:
parent
a9c65bd369
commit
d5b34696b4
|
@ -31,18 +31,26 @@ srsran_csi_new_nzp_csi_rs_measurement(const srsran_csi_hl_resource_cfg_t csi_res
|
|||
uint32_t nzp_csi_rs_id);
|
||||
|
||||
/**
|
||||
* @brief Generates CSI report configuration and values from the higher layer configuration and a list of measurements
|
||||
* @brief Generates CSI report configuration from the higher layer configuration for a given slot
|
||||
* @param cfg Higher layer report configuration
|
||||
* @param slot_idx Slot index within the radio frame
|
||||
* @param measurements Filtered CSI measurements
|
||||
* @param[out] report_cfg Report configuration re
|
||||
* @param slot_cfg Current slot configuration
|
||||
* @param[out] report_cfg Report configuration for the given slot
|
||||
* @return The number CSI reports for transmission if the provided data is valid, SRSRAN_ERROR code otherwise
|
||||
*/
|
||||
SRSRAN_API int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg,
|
||||
const srsran_slot_cfg_t* slot_cfg,
|
||||
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT]);
|
||||
|
||||
/**
|
||||
* @brief Quantifies a given set of CSI reports from the given set of measurements
|
||||
* @param reports Set of report configuration
|
||||
* @param measurements Set of measurements to quantify
|
||||
* @param report_value Set of report values
|
||||
* @return The number CSI reports for transmission if the provided data is valid, SRSRAN_ERROR code otherwise
|
||||
*/
|
||||
SRSRAN_API int
|
||||
srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg,
|
||||
uint32_t slot_idx,
|
||||
srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT],
|
||||
const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES],
|
||||
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT],
|
||||
srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]);
|
||||
|
||||
/**
|
||||
|
|
|
@ -162,12 +162,10 @@ typedef struct SRSRAN_API {
|
|||
|
||||
/**
|
||||
* @brief CSI report configuration
|
||||
* @note An unset report is marked with `cfg.type = SRSRAN_CSI_REPORT_TYPE_NONE`
|
||||
*/
|
||||
typedef struct SRSRAN_API {
|
||||
srsran_csi_report_type_t type; ///< CSI report type (none, periodic, semiPersistentOnPUCCH, ...)
|
||||
srsran_csi_report_quantity_t quantity; ///< Report quantity
|
||||
srsran_pucch_nr_resource_t pucch_resource; ///< PUCCH resource to use for periodic reporting
|
||||
srsran_csi_report_freq_t freq_cfg; ///< Determine whether it is wideband or subband
|
||||
srsran_csi_hl_report_cfg_t cfg; ///< Higher layer CSI report configuration
|
||||
|
||||
// Resource set context
|
||||
uint32_t nof_ports; ///< Number of antenna ports
|
||||
|
@ -193,7 +191,6 @@ typedef struct SRSRAN_API {
|
|||
void* none;
|
||||
srsran_csi_report_wideband_cri_ri_pmi_cqi_t wideband_cri_ri_pmi_cqi;
|
||||
};
|
||||
bool valid; ///< Used by receiver only
|
||||
} srsran_csi_report_value_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -307,7 +307,10 @@ bool phy_cfg_nr_t::get_uci_cfg(const srsran_slot_cfg_t& slot_cfg,
|
|||
}
|
||||
|
||||
// Generate configuration for CSI reports
|
||||
// ...
|
||||
n = srsran_csi_reports_generate(&csi, &slot_cfg, uci_cfg.csi);
|
||||
if (n > SRSRAN_SUCCESS) {
|
||||
uci_cfg.nof_csi = (uint32_t)n;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -472,6 +472,24 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg)
|
|||
}
|
||||
|
||||
prach.tdd_config.configured = (duplex.mode == SRSRAN_DUPLEX_MODE_TDD);
|
||||
|
||||
// Make default CSI report configuration always
|
||||
csi.reports[0].channel_meas_id = 0;
|
||||
csi.reports[0].type = SRSRAN_CSI_REPORT_TYPE_PERIODIC;
|
||||
csi.reports[0].periodic.period = 20;
|
||||
csi.reports[0].periodic.offset = 9;
|
||||
csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2;
|
||||
csi.reports[0].periodic.resource.starting_prb = 51;
|
||||
csi.reports[0].periodic.resource.format = SRSRAN_PUCCH_NR_FORMAT_2;
|
||||
csi.reports[0].periodic.resource.nof_prb = 1;
|
||||
csi.reports[0].periodic.resource.nof_symbols = 2;
|
||||
csi.reports[0].periodic.resource.start_symbol_idx = 10;
|
||||
csi.reports[0].quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI;
|
||||
csi.reports[0].cqi_table = SRSRAN_CSI_CQI_TABLE_1;
|
||||
csi.reports[0].freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND;
|
||||
csi.csi_resources[0].type = srsran_csi_hl_resource_cfg_t::SRSRAN_CSI_HL_RESOURCE_CFG_TYPE_NZP_CSI_RS_SSB;
|
||||
csi.csi_resources[0].nzp_csi_rs_ssb.nzp_csi_rs_resource_set_id_list[0] = 0;
|
||||
csi.csi_resources[0].nzp_csi_rs_ssb.nzp_csi_rs_resource_set_id_list_count = 1;
|
||||
}
|
||||
|
||||
} // namespace srsran
|
||||
|
|
|
@ -39,7 +39,6 @@ static bool csi_report_trigger(const srsran_csi_hl_report_cfg_t* cfg, uint32_t s
|
|||
static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_t* cfg,
|
||||
const srsran_csi_channel_measurements_t* channel_meas,
|
||||
const srsran_csi_channel_measurements_t* interf_meas,
|
||||
srsran_csi_report_cfg_t* report_cfg,
|
||||
srsran_csi_report_value_t* report_value)
|
||||
{
|
||||
// Take SNR by default
|
||||
|
@ -50,18 +49,6 @@ static void csi_wideband_cri_ri_pmi_cqi_quantify(const srsran_csi_hl_report_cfg_
|
|||
wideband_sinr_db = channel_meas->wideband_rsrp_dBm - interf_meas->wideband_epre_dBm;
|
||||
}
|
||||
|
||||
// Fill report configuration
|
||||
report_cfg->type = cfg->type;
|
||||
report_cfg->quantity = SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI;
|
||||
report_cfg->freq_cfg = SRSRAN_CSI_REPORT_FREQ_WIDEBAND;
|
||||
report_cfg->nof_ports = channel_meas->nof_ports;
|
||||
report_cfg->K_csi_rs = channel_meas->K_csi_rs;
|
||||
|
||||
// Save PUCCH resource only if periodic type
|
||||
if (cfg->type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
|
||||
report_cfg->pucch_resource = cfg->periodic.resource;
|
||||
}
|
||||
|
||||
// Fill quantified values
|
||||
report_value->wideband_cri_ri_pmi_cqi.cqi = csi_snri_db_to_cqi(cfg->cqi_table, wideband_sinr_db);
|
||||
report_value->wideband_cri_ri_pmi_cqi.ri = 0;
|
||||
|
@ -190,48 +177,79 @@ int srsran_csi_new_nzp_csi_rs_measurement(
|
|||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
int srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg,
|
||||
uint32_t slot_idx,
|
||||
int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg,
|
||||
const srsran_slot_cfg_t* slot_cfg,
|
||||
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT])
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
// Check inputs
|
||||
if (cfg == NULL || report_cfg == NULL) {
|
||||
return SRSRAN_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Make sure report configuration is initialised to zero
|
||||
SRSRAN_MEM_ZERO(report_cfg, srsran_csi_report_cfg_t, SRSRAN_CSI_MAX_NOF_REPORT);
|
||||
|
||||
// Iterate every possible configured CSI report
|
||||
for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) {
|
||||
// Skip if report is not configured or triggered
|
||||
if (!csi_report_trigger(&cfg->reports[i], slot_cfg->idx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Configure report
|
||||
report_cfg[count].cfg = cfg->reports[i];
|
||||
report_cfg[count].nof_ports = 1;
|
||||
report_cfg[count].K_csi_rs = 1;
|
||||
report_cfg[count].has_part2 = false;
|
||||
count++;
|
||||
}
|
||||
|
||||
return (int)count;
|
||||
}
|
||||
|
||||
int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT],
|
||||
const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES],
|
||||
srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT],
|
||||
srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT])
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
// Check inputs
|
||||
if (cfg == NULL || measurements == NULL || report_cfg == NULL || report_value == NULL) {
|
||||
if (reports == NULL || measurements == NULL || report_value == NULL) {
|
||||
return SRSRAN_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Iterate every possible configured CSI report
|
||||
for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) {
|
||||
// Skip if report is not configured or triggered
|
||||
if (!csi_report_trigger(&cfg->reports[i], slot_idx)) {
|
||||
continue;
|
||||
// If the report is the last one, break
|
||||
if (reports->cfg.type == SRSRAN_CSI_REPORT_TYPE_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Select channel measurement
|
||||
if (cfg->reports->channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
||||
ERROR("Channel measurement ID (%d) is out of range", cfg->reports->channel_meas_id);
|
||||
uint32_t channel_meas_id = reports[i].cfg.channel_meas_id;
|
||||
if (channel_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
||||
ERROR("Channel measurement ID (%d) is out of range", channel_meas_id);
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
const srsran_csi_channel_measurements_t* channel_meas = &measurements[cfg->reports->channel_meas_id];
|
||||
const srsran_csi_channel_measurements_t* channel_meas = &measurements[channel_meas_id];
|
||||
|
||||
// Select interference measurement
|
||||
const srsran_csi_channel_measurements_t* interf_meas = NULL;
|
||||
if (cfg->reports->interf_meas_present) {
|
||||
if (cfg->reports->interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
||||
ERROR("Interference measurement ID (%d) is out of range", cfg->reports->interf_meas_id);
|
||||
if (reports[i].cfg.interf_meas_present) {
|
||||
uint32_t interf_meas_id = reports[i].cfg.interf_meas_id;
|
||||
if (interf_meas_id >= SRSRAN_CSI_MAX_NOF_RESOURCES) {
|
||||
ERROR("Interference measurement ID (%d) is out of range", interf_meas_id);
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
interf_meas = &measurements[cfg->reports->interf_meas_id];
|
||||
interf_meas = &measurements[interf_meas_id];
|
||||
}
|
||||
|
||||
// Quantify measurements according to frequency and quantity configuration
|
||||
if (cfg->reports->freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
cfg->reports->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
csi_wideband_cri_ri_pmi_cqi_quantify(
|
||||
&cfg->reports[i], channel_meas, interf_meas, &report_cfg[count], &report_value[count]);
|
||||
if (reports[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
reports[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
csi_wideband_cri_ri_pmi_cqi_quantify(&reports[i].cfg, channel_meas, interf_meas, &report_value[count]);
|
||||
count++;
|
||||
} else {
|
||||
; // Ignore other types
|
||||
|
@ -253,9 +271,9 @@ int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32
|
|||
// Iterate all report configurations
|
||||
for (uint32_t i = 0; i < nof_reports; i++) {
|
||||
const srsran_csi_report_cfg_t* report = &report_list[i];
|
||||
if (report->quantity && report->quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
if (report->cfg.quantity && report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
count += csi_wideband_cri_ri_pmi_cqi_nof_bits(report);
|
||||
} else if (report->quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
} else if (report->cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
count += csi_none_nof_bits(report);
|
||||
}
|
||||
}
|
||||
|
@ -308,15 +326,15 @@ int srsran_csi_part1_pack(const srsran_csi_report_cfg_t* report_cfg,
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
||||
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
count += csi_wideband_cri_ri_pmi_cqi_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
||||
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
count += csi_none_pack(&report_cfg[i], &report_value[i], &o_csi1[count]);
|
||||
} else {
|
||||
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
||||
report_cfg[i].freq_cfg,
|
||||
report_cfg[i].quantity);
|
||||
report_cfg[i].cfg.freq_cfg,
|
||||
report_cfg[i].cfg.quantity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,15 +360,15 @@ int srsran_csi_part1_unpack(const srsran_csi_report_cfg_t* report_cfg,
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < nof_reports && count < max_o_csi1; i++) {
|
||||
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
count += csi_wideband_cri_ri_pmi_cqi_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
||||
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
count += csi_none_unpack(&report_cfg[i], &o_csi1[count], &report_value[i]);
|
||||
} else {
|
||||
ERROR("CSI frequency (%d) and quantity (%d) combination is not implemented",
|
||||
report_cfg[i].freq_cfg,
|
||||
report_cfg[i].quantity);
|
||||
report_cfg[i].cfg.freq_cfg,
|
||||
report_cfg[i].cfg.quantity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,10 +383,10 @@ uint32_t srsran_csi_str(const srsran_csi_report_cfg_t* report_cfg,
|
|||
{
|
||||
uint32_t len = 0;
|
||||
for (uint32_t i = 0; i < nof_reports; i++) {
|
||||
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
if (report_cfg[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
|
||||
report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
|
||||
len = srsran_print_check(str, str_len, len, "cqi=%d ", report_value[i].wideband_cri_ri_pmi_cqi.cqi);
|
||||
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
} else if (report_cfg[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
|
||||
char tmp[20] = {};
|
||||
srsran_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs);
|
||||
len = srsran_print_check(str, str_len, len, "csi=%s ", tmp);
|
||||
|
|
|
@ -614,8 +614,8 @@ int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg,
|
|||
// - Irrelevant SR opportunities
|
||||
// - No HARQ-ACK
|
||||
// - Single periodic CSI report
|
||||
if (uci_cfg->ack.count == 0 && uci_cfg->nof_csi == 1 && uci_cfg->csi[0].type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
|
||||
*resource = uci_cfg->csi[0].pucch_resource;
|
||||
if (uci_cfg->ack.count == 0 && uci_cfg->nof_csi == 1 && uci_cfg->csi[0].cfg.type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) {
|
||||
*resource = uci_cfg->csi[0].cfg.periodic.resource;
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ int main(int argc, char** argv)
|
|||
uint8_t csi_report_tx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {};
|
||||
uint8_t csi_report_rx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {};
|
||||
if (nof_csi_bits > 0) {
|
||||
pusch_cfg.uci.csi[0].quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE;
|
||||
pusch_cfg.uci.csi[0].cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE;
|
||||
pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits;
|
||||
pusch_cfg.uci.nof_csi = 1;
|
||||
data_tx.uci.csi[0].none = csi_report_tx;
|
||||
|
|
|
@ -299,8 +299,7 @@ static int uci_nr_A(const srsran_uci_cfg_nr_t* cfg)
|
|||
}
|
||||
|
||||
// 6.3.1.1.3 HARQ-ACK/SR and CSI
|
||||
ERROR("HARQ-ACK/SR and CSI encoding are not implemented");
|
||||
return SRSRAN_ERROR;
|
||||
return cfg->ack.count + cfg->o_sr + o_csi;
|
||||
}
|
||||
|
||||
static int uci_nr_pack_pucch(const srsran_uci_cfg_nr_t* cfg, const srsran_uci_value_nr_t* value, uint8_t* sequence)
|
||||
|
@ -332,8 +331,7 @@ static int uci_nr_unpack_pucch(const srsran_uci_cfg_nr_t* cfg, uint8_t* sequence
|
|||
|
||||
// 6.3.1.1.2 CSI only
|
||||
if (cfg->ack.count == 0 && cfg->o_sr == 0) {
|
||||
ERROR("CSI only are not implemented");
|
||||
return SRSRAN_ERROR;
|
||||
return srsran_csi_part1_unpack(cfg->csi, cfg->nof_csi, sequence, SRSRAN_UCI_NR_MAX_NOF_BITS, value->csi);
|
||||
}
|
||||
|
||||
// 6.3.1.1.3 HARQ-ACK/SR and CSI
|
||||
|
|
|
@ -344,14 +344,21 @@ public:
|
|||
uci_data.value.sr = sr_count_positive;
|
||||
}
|
||||
|
||||
void get_periodic_csi(const uint32_t& tti, srsran_uci_data_nr_t& uci_data)
|
||||
void get_periodic_csi(const srsran_slot_cfg_t& slot_cfg, srsran_uci_data_nr_t& uci_data)
|
||||
{
|
||||
int n = srsran_csi_generate_reports(&cfg.csi, tti, csi_measurements.data(), uci_data.cfg.csi, uci_data.value.csi);
|
||||
// Generate report configurations
|
||||
int n = srsran_csi_reports_generate(&cfg.csi, &slot_cfg, uci_data.cfg.csi);
|
||||
if (n > SRSRAN_SUCCESS) {
|
||||
uci_data.cfg.nof_csi = n;
|
||||
}
|
||||
|
||||
uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id;
|
||||
// Quantify reports from measurements
|
||||
n = srsran_csi_reports_quantify(uci_data.cfg.csi, csi_measurements.data(), uci_data.value.csi);
|
||||
if (n > SRSRAN_SUCCESS) {
|
||||
uci_data.cfg.nof_csi = n;
|
||||
}
|
||||
|
||||
uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(slot_cfg.idx).id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -590,7 +590,7 @@ bool cc_worker::work_ul()
|
|||
}
|
||||
|
||||
// Add CSI reports to UCI data if available
|
||||
phy.get_periodic_csi(ul_slot_cfg.idx, uci_data);
|
||||
phy.get_periodic_csi(ul_slot_cfg, uci_data);
|
||||
|
||||
// Setup frequency offset
|
||||
srsran_ue_ul_nr_set_freq_offset(&ue_ul, phy.get_ul_cfo());
|
||||
|
|
|
@ -40,7 +40,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
|
|||
foreach (NR_PHY_TEST_BW "10MHz" "20MHz")
|
||||
# For each supported frame structure
|
||||
foreach (NR_PHY_TEST_DUPLEX "FDD" "6D+4U" "FR1.15-1")
|
||||
set(NR_PHY_TEST_DURATION_MS 20)
|
||||
set(NR_PHY_TEST_DURATION_MS 50)
|
||||
|
||||
# DL flooding only
|
||||
foreach (NR_PHY_TEST_PDSCH "default" "ts38101/5.2-1")
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
std::map<uint32_t, prach_metrics_t> prach = {}; ///< PRACH metrics indexed with premable index
|
||||
srsenb::mac_ue_metrics_t mac = {}; ///< MAC metrics
|
||||
uint32_t sr_count = 0; ///< SR counter
|
||||
uint32_t cqi_count = 0; ///< CQI opportunity counter
|
||||
uint32_t cqi_valid_count = 0; ///< Valid CQI counter
|
||||
pucch_metrics_t pucch = {};
|
||||
};
|
||||
|
||||
|
@ -304,6 +306,23 @@ private:
|
|||
metrics.sr_count++;
|
||||
}
|
||||
|
||||
// Process CQI
|
||||
for (uint32_t i = 0; i < cfg.nof_csi; i++) {
|
||||
// Increment CQI opportunity
|
||||
metrics.cqi_count++;
|
||||
|
||||
// Skip if invalid or not supported CSI report
|
||||
if (not value.valid or cfg.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or
|
||||
cfg.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add statistics
|
||||
metrics.mac.dl_cqi =
|
||||
SRSRAN_VEC_SAFE_CMA(value.csi->wideband_cri_ri_pmi_cqi.cqi, metrics.mac.dl_cqi, metrics.cqi_count);
|
||||
metrics.cqi_valid_count++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
// shorten boost program options namespace
|
||||
namespace bpo = boost::program_options;
|
||||
|
||||
static double assert_sr_detection_min = 1.000;
|
||||
static double assert_cqi_detection_min = 1.000;
|
||||
static double assert_pusch_bler_max = 0.000;
|
||||
static double assert_pdsch_bler_max = 0.000;
|
||||
|
||||
test_bench::args_t::args_t(int argc, char** argv)
|
||||
{
|
||||
std::string reference_cfg_str = "";
|
||||
|
@ -29,6 +34,7 @@ test_bench::args_t::args_t(int argc, char** argv)
|
|||
bpo::options_description options_gnb_phy("gNb PHY related options");
|
||||
bpo::options_description options_ue_stack("UE stack options");
|
||||
bpo::options_description options_ue_phy("UE stack options");
|
||||
bpo::options_description options_assertion("Test assertions");
|
||||
|
||||
uint16_t rnti = 17921;
|
||||
|
||||
|
@ -80,6 +86,13 @@ test_bench::args_t::args_t(int argc, char** argv)
|
|||
("ue.stack.prach.preamble", bpo::value<uint32_t>(&ue_stack.prach_preamble)->default_value(ue_stack.prach_preamble), "PRACH preamble. Set 0 to disable and 1 for all.")
|
||||
;
|
||||
|
||||
options_assertion.add_options()
|
||||
("assert.sr.detection.min", bpo::value<double>(&assert_sr_detection_min)->default_value(assert_sr_detection_min), "Scheduling request minimum detection threshold")
|
||||
("assert.cqi.detection.min", bpo::value<double>(&assert_cqi_detection_min)->default_value(assert_cqi_detection_min), "CQI report minimum detection threshold")
|
||||
("assert.pusch.bler.max", bpo::value<double>(&assert_pusch_bler_max)->default_value(assert_pusch_bler_max), "PUSCH maximum BLER threshold")
|
||||
("assert.pdsch.bler.max", bpo::value<double>(&assert_pdsch_bler_max)->default_value(assert_pdsch_bler_max), "PDSCH maximum BLER threshold")
|
||||
;
|
||||
|
||||
options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options()
|
||||
("help", "Show this message")
|
||||
;
|
||||
|
@ -164,9 +177,9 @@ int main(int argc, char** argv)
|
|||
test_bench::metrics_t metrics = tb.get_gnb_metrics();
|
||||
|
||||
// Print PDSCH metrics if scheduled
|
||||
double pdsch_bler = 0.0;
|
||||
if (metrics.gnb_stack.mac.tx_pkts > 0) {
|
||||
float pdsch_bler = 0.0f;
|
||||
pdsch_bler = (float)metrics.gnb_stack.mac.tx_errors / (float)metrics.gnb_stack.mac.tx_pkts;
|
||||
pdsch_bler = (double)metrics.gnb_stack.mac.tx_errors / (double)metrics.gnb_stack.mac.tx_pkts;
|
||||
|
||||
float pdsch_shed_rate = 0.0f;
|
||||
pdsch_shed_rate = (float)metrics.gnb_stack.mac.tx_brate / (float)metrics.gnb_stack.mac.tx_pkts / 1000.0f;
|
||||
|
@ -181,10 +194,10 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
// Print PUSCH metrics if scheduled
|
||||
double pusch_bler = 0.0;
|
||||
if (metrics.gnb_stack.mac.rx_pkts > 0) {
|
||||
float pusch_bler = 0.0f;
|
||||
if (metrics.gnb_stack.mac.rx_pkts != 0) {
|
||||
pusch_bler = (float)metrics.gnb_stack.mac.rx_errors / (float)metrics.gnb_stack.mac.rx_pkts;
|
||||
pusch_bler = (double)metrics.gnb_stack.mac.rx_errors / (double)metrics.gnb_stack.mac.rx_pkts;
|
||||
}
|
||||
|
||||
float pusch_shed_rate = 0.0f;
|
||||
|
@ -261,23 +274,54 @@ int main(int argc, char** argv)
|
|||
srsran::console(" +------------+------------+------------+------------+\n");
|
||||
}
|
||||
|
||||
srsran::console("UCI stats:\n");
|
||||
srsran::console(" +------------+------------+------------+------------+------------+\n");
|
||||
srsran::console(
|
||||
" | %10s | %10s | %10s | %10s | %10s |\n", "Field", "Transmit'd", "Received", "Detection", "Avg. Val.");
|
||||
srsran::console(" +------------+------------+------------+------------+------------+\n");
|
||||
|
||||
// Print SR
|
||||
double sr_detection = 0.0;
|
||||
if (metrics.ue_stack.sr_count > 0) {
|
||||
srsran::console("SR:\n");
|
||||
srsran::console(" +------------+------------+------------+\n");
|
||||
srsran::console(" | %10s | %10s | %10s |\n", "Transmit'd", "Received", "Detection");
|
||||
srsran::console(" +------------+------------+------------+\n");
|
||||
srsran::console(" | %10d | %10d | %10.5f |\n",
|
||||
sr_detection = (double)metrics.gnb_stack.sr_count / (double)metrics.ue_stack.sr_count;
|
||||
srsran::console(" | %10s | %10d | %10d | %10.5f | %10s |\n",
|
||||
"SR",
|
||||
metrics.ue_stack.sr_count,
|
||||
metrics.gnb_stack.sr_count,
|
||||
(double)metrics.gnb_stack.sr_count / (double)metrics.ue_stack.sr_count);
|
||||
srsran::console(" +------------+------------+------------+\n");
|
||||
sr_detection,
|
||||
"-");
|
||||
}
|
||||
|
||||
// Print SR
|
||||
double cqi_detection = 0.0;
|
||||
if (metrics.gnb_stack.cqi_count > 0) {
|
||||
cqi_detection = (double)metrics.gnb_stack.cqi_valid_count / (double)metrics.gnb_stack.cqi_count;
|
||||
srsran::console(" | %10s | %10d | %10d | %10.5f | %10.5f |\n",
|
||||
"CQI",
|
||||
metrics.gnb_stack.cqi_count,
|
||||
metrics.gnb_stack.cqi_valid_count,
|
||||
cqi_detection,
|
||||
metrics.gnb_stack.mac.dl_cqi);
|
||||
}
|
||||
srsran::console(" +------------+------------+------------+------------+------------+\n");
|
||||
|
||||
// Assert metrics
|
||||
TESTASSERT_EQ(0, metrics.gnb_stack.mac.tx_errors);
|
||||
TESTASSERT_EQ(0, metrics.gnb_stack.mac.rx_errors);
|
||||
TESTASSERT(metrics.ue_stack.sr_count == metrics.gnb_stack.sr_count);
|
||||
srsran_assert(metrics.gnb_stack.mac.tx_pkts == 0 or pdsch_bler <= assert_pdsch_bler_max,
|
||||
"PDSCH BLER (%f) exceeds the assertion maximum (%f)",
|
||||
pdsch_bler,
|
||||
assert_pusch_bler_max);
|
||||
srsran_assert(metrics.gnb_stack.mac.rx_pkts == 0 or pusch_bler <= assert_pusch_bler_max,
|
||||
"PUSCH BLER (%f) exceeds the assertion maximum (%f)",
|
||||
pusch_bler,
|
||||
assert_pusch_bler_max);
|
||||
srsran_assert(metrics.ue_stack.sr_count == 0 or sr_detection >= assert_sr_detection_min,
|
||||
"SR detection probability (%f) did not reach the assertion minimum (%f)",
|
||||
sr_detection,
|
||||
assert_sr_detection_min);
|
||||
srsran_assert(metrics.gnb_stack.cqi_count == 0 or cqi_detection >= assert_cqi_detection_min,
|
||||
"CQI report detection probability (%f) did not reach the assertion minimum (%f)",
|
||||
cqi_detection,
|
||||
assert_sr_detection_min);
|
||||
|
||||
// If reached here, the test is successful
|
||||
return SRSRAN_SUCCESS;
|
||||
|
|
Loading…
Reference in New Issue