Commit ba73075c authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/ul-dl-bler' into integration_2022_wk21

parents d56f2c8e 3ca4cb70
...@@ -62,12 +62,15 @@ ...@@ -62,12 +62,15 @@
#define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres" #define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres"
#define CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER "dl_bler_target_upper" #define CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER "dl_bler_target_upper"
#define CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER "dl_bler_target_lower" #define CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER "dl_bler_target_lower"
#define CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD "dl_rd2_bler_threshold"
#define CONFIG_STRING_MACRLC_DL_MAX_MCS "dl_max_mcs" #define CONFIG_STRING_MACRLC_DL_MAX_MCS "dl_max_mcs"
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper"
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower"
#define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs"
#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max" #define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max"
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb" #define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs" #define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* MacRLC configuration parameters */ /* MacRLC configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */ /* optname helpstr paramflags XXXptr defXXXval type numelt */
...@@ -97,8 +100,10 @@ ...@@ -97,8 +100,10 @@
{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase DL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase DL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD, "Threshold of RD2/RETX2 BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.01, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_MAX_MCS, "Maximum DL MCS that should be used", 0, u8ptr:NULL, defintval:28, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_DL_MAX_MCS, "Maximum DL MCS that should be used", 0, u8ptr:NULL, defintval:28, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \ {CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \
...@@ -127,10 +132,13 @@ ...@@ -127,10 +132,13 @@
#define MACRLC_PUSCHFAILURETHRES_IDX 21 #define MACRLC_PUSCHFAILURETHRES_IDX 21
#define MACRLC_DL_BLER_TARGET_UPPER_IDX 22 #define MACRLC_DL_BLER_TARGET_UPPER_IDX 22
#define MACRLC_DL_BLER_TARGET_LOWER_IDX 23 #define MACRLC_DL_BLER_TARGET_LOWER_IDX 23
#define MACRLC_DL_RD2_BLER_THRESHOLD_IDX 24 #define MACRLC_DL_MAX_MCS_IDX 24
#define MACRLC_DL_MAX_MCS_IDX 25 #define MACRLC_UL_BLER_TARGET_UPPER_IDX 25
#define MACRLC_HARQ_ROUND_MAX_IDX 26 #define MACRLC_UL_BLER_TARGET_LOWER_IDX 26
#define MACRLC_MIN_GRANT_PRB_IDX 27 #define MACRLC_UL_MAX_MCS_IDX 27
#define MACRLC_MIN_GRANT_MCS_IDX 28 #define MACRLC_HARQ_ROUND_MAX_IDX 28
#define MACRLC_MIN_GRANT_PRB_IDX 29
#define MACRLC_MIN_GRANT_MCS_IDX 30
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif #endif
...@@ -873,10 +873,14 @@ void RCconfig_nr_macrlc() { ...@@ -873,10 +873,14 @@ void RCconfig_nr_macrlc() {
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
} }
RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr); RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr);
RC.nrmac[j]->dl_bler_target_upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); NR_bler_options_t *dl_bler_options = &RC.nrmac[j]->dl_bler;
RC.nrmac[j]->dl_bler_target_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
RC.nrmac[j]->dl_rd2_bler_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_RD2_BLER_THRESHOLD_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
RC.nrmac[j]->dl_max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr); dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler;
ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr);
ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr);
ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr);
RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr); RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr);
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr); RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
......
...@@ -1983,8 +1983,8 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram ...@@ -1983,8 +1983,8 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
if (harq->is_waiting == 0) { if (harq->is_waiting == 0) {
if (harq->round == 0) { if (harq->round == 0) {
if (stats->dlsch_errors == 0) { if (stats->dl.errors == 0) {
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti); LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
UE_info->active[UE_id] = true; UE_info->active[UE_id] = true;
UE_info->Msg4_ACKed[UE_id] = true; UE_info->Msg4_ACKed[UE_id] = true;
......
...@@ -397,81 +397,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, ...@@ -397,81 +397,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
return offset; return offset;
} }
#define BLER_UPDATE_FRAME 10
#define BLER_FILTER 0.9f
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table) {
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
int max_mcs = nrmac->dl_max_mcs;
if (nrmac->dl_max_mcs>max_allowed_mcs)
max_mcs = max_allowed_mcs;
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
/* first call: everything is zero. Initialize to sensible default */
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
bler_stats->last_frame_slot = frame * n + slot;
bler_stats->mcs = 9;
bler_stats->bler = (nrmac->dl_bler_target_lower + nrmac->dl_bler_target_upper) / 2;
bler_stats->rd2_bler = nrmac->dl_rd2_bler_threshold;
}
const int now = frame * n + slot;
int diff = now - bler_stats->last_frame_slot;
if (diff < 0) // wrap around
diff += 1024 * n;
const uint8_t old_mcs = bler_stats->mcs;
const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
// TODO put back this condition when relevant
/*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
if (dret3x > 0) {
if there is a third retransmission, decrease MCS for stabilization and
restart averaging window to stabilize transmission
bler_stats->last_frame_slot = now;
bler_stats->mcs = max(9, bler_stats->mcs - 1);
memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
LOG_D(MAC, "%4d.%2d: %d retx in 3rd round, setting MCS to %d and restarting window\n", frame, slot, dret3x, bler_stats->mcs);
return bler_stats->mcs;
}*/
if (diff < BLER_UPDATE_FRAME * n)
return old_mcs; // no update
// last update is longer than x frames ago
const int dtx = (int)(stats->dlsch_rounds[0] - bler_stats->dlsch_rounds[0]);
const int dretx = (int)(stats->dlsch_rounds[1] - bler_stats->dlsch_rounds[1]);
const int dretx2 = (int)(stats->dlsch_rounds[2] - bler_stats->dlsch_rounds[2]);
const float bler_window = dtx > 0 ? (float) dretx / dtx : bler_stats->bler;
const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
bler_stats->rd2_bler = BLER_FILTER / 4 * bler_stats->rd2_bler + (1 - BLER_FILTER / 4) * rd2_bler_wnd;
int new_mcs = old_mcs;
// TODO put back this condition when relevant
/* first ensure that number of 2nd retx is below threshold. If this is the
* case, use 1st retx to adjust faster
if (bler_stats->rd2_bler > nrmac->dl_rd2_bler_threshold && old_mcs > 6) {
new_mcs -= 2;
} else if (bler_stats->rd2_bler < nrmac->dl_rd2_bler_threshold) {*/
if (bler_stats->bler < nrmac->dl_bler_target_lower && old_mcs < max_mcs && dtx > 9)
new_mcs += 1;
else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
new_mcs -= 1;
// else we are within threshold boundaries
bler_stats->last_frame_slot = now;
bler_stats->mcs = new_mcs;
memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
LOG_D(MAC, "%4d.%2d MCS %d -> %d (dtx %d, dretx %d, BLER wnd %.3f avg %.6f, dretx2 %d, RD2 BLER wnd %.3f avg %.6f)\n",
frame, slot, old_mcs, new_mcs, dtx, dretx, bler_window, bler_stats->bler, dretx2, rd2_bler_wnd, bler_stats->rd2_bler);
return new_mcs;
}
void nr_store_dlsch_buffer(module_id_t module_id, void nr_store_dlsch_buffer(module_id_t module_id,
frame_t frame, frame_t frame,
sub_frame_t slot) { sub_frame_t slot) {
...@@ -742,6 +667,7 @@ void pf_dl(module_id_t module_id, ...@@ -742,6 +667,7 @@ void pf_dl(module_id_t module_id,
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
const NR_mac_dir_stats_t *stats = &UE_info->mac_stats[UE_id].dl;
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
...@@ -749,7 +675,7 @@ void pf_dl(module_id_t module_id, ...@@ -749,7 +675,7 @@ void pf_dl(module_id_t module_id,
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
/* Calculate Throughput */ /* Calculate Throughput */
const float a = 0.0005f; // corresponds to 200ms window const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes; const uint32_t b = stats->current_bytes;
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
/* retransmission */ /* retransmission */
...@@ -772,8 +698,10 @@ void pf_dl(module_id_t module_id, ...@@ -772,8 +698,10 @@ void pf_dl(module_id_t module_id,
continue; continue;
/* Calculate coeff */ /* Calculate coeff */
set_dl_mcs(sched_pdsch,sched_ctrl,&mac->dl_max_mcs,ps->mcsTableIdx); const NR_bler_options_t *bo = &mac->dl_bler;
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE_id, ps->mcsTableIdx); const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28;
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
layers[UE_id] = set_dl_nrOfLayers(sched_ctrl); layers[UE_id] = set_dl_nrOfLayers(sched_ctrl);
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
...@@ -1091,7 +1019,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1091,7 +1019,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0; UE_info->mac_stats[UE_id].dl.current_bytes = 0;
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id]; NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
NR_BWP_DownlinkDedicated_t *bwpd = NR_BWP_DownlinkDedicated_t *bwpd =
...@@ -1149,7 +1077,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1149,7 +1077,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
harq->feedback_frame = pucch->frame; harq->feedback_frame = pucch->frame;
harq->feedback_slot = pucch->ul_slot; harq->feedback_slot = pucch->ul_slot;
harq->is_waiting = true; harq->is_waiting = true;
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; UE_info->mac_stats[UE_id].dl.rounds[harq->round]++;
LOG_D(NR_MAC, LOG_D(NR_MAC,
"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", "%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
frame, frame,
...@@ -1483,7 +1411,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1483,7 +1411,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
lcid_bytes += len; lcid_bytes += len;
} }
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += lcid_bytes; UE_info->mac_stats[UE_id].dl.lc_bytes[lcid] += lcid_bytes;
} }
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { } else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
/* we will need the large header, phy-test typically allocates all /* we will need the large header, phy-test typically allocates all
...@@ -1521,8 +1449,10 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -1521,8 +1449,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
buf=bufEnd; buf=bufEnd;
} }
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; NR_mac_stats_t *mac_stats = &UE_info->mac_stats[UE_id];
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS; mac_stats->dl.total_bytes += TBS;
mac_stats->dl.current_bytes = TBS;
/* save retransmission information */ /* save retransmission information */
harq->sched_pdsch = *sched_pdsch; harq->sched_pdsch = *sched_pdsch;
/* save which time allocation has been used, to be used on /* save which time allocation has been used, to be used on
......
...@@ -145,7 +145,6 @@ uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl) { ...@@ -145,7 +145,6 @@ uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl) {
} }
uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl, uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
int layers, int layers,
int N1, int N2, int N1, int N2,
...@@ -169,20 +168,19 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl, ...@@ -169,20 +168,19 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
AssertFatal(1==0,"More than 2 antenna ports not yet supported\n"); AssertFatal(1==0,"More than 2 antenna ports not yet supported\n");
} }
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
{
if (cqi_idx <= 0) {
LOG_E(NR_MAC, "invalid cqi_idx %d, default to MCS 9\n", cqi_idx);
return 9;
}
void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch, if (mcs_table != cqi_table) {
NR_UE_sched_ctrl_t *sched_ctrl, LOG_E(NR_MAC, "indices of CQI (%d) and MCS (%d) tables don't correspond yet\n", cqi_table, mcs_table);
uint8_t *target_mcs, return 9;
uint8_t mcs_table_idx) { }
if (sched_ctrl->set_mcs) { uint16_t target_coderate, target_qm;
// TODO for wideband case and multiple TB
int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
uint16_t target_coderate,target_qm;
if (cqi_idx>0) {
int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table;
if (cqi_table != mcs_table_idx)
LOG_W(NR_MAC,"Indices of MCS tables don't correspond yet, cri_ri_li_pmi_cqi_report.cqi_table %d, mcs_table_index %d\n",cqi_table,mcs_table_idx);
switch (cqi_table) { switch (cqi_table) {
case 0: case 0:
target_qm = cqi_table1[cqi_idx][0]; target_qm = cqi_table1[cqi_idx][0];
...@@ -199,21 +197,16 @@ void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch, ...@@ -199,21 +197,16 @@ void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch,
default: default:
AssertFatal(1==0,"Invalid cqi table index %d\n",cqi_table); AssertFatal(1==0,"Invalid cqi table index %d\n",cqi_table);
} }
int max_mcs = 28; const int max_mcs = mcs_table == 1 ? 27 : 28;
int R,Qm; for (int i = 0; i <= max_mcs; i++) {
if (mcs_table_idx == 1) const int R = nr_get_code_rate_dl(i, mcs_table);
max_mcs = 27; const int Qm = nr_get_Qm_dl(i, mcs_table);
for (int i=0; i<=max_mcs; i++) { if (Qm == target_qm && target_coderate <= R)
R = nr_get_code_rate_dl(i, mcs_table_idx); return i;
Qm = nr_get_Qm_dl(i, mcs_table_idx);
if ((Qm == target_qm) && (target_coderate <= R)) {
*target_mcs = i;
break;
}
}
}
sched_ctrl->set_mcs = false;
} }
LOG_E(NR_MAC, "could not find maximum MCS from cqi_idx %d, default to 9\n", cqi_idx);
return 9;
} }
void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) { void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
...@@ -768,6 +761,51 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, ...@@ -768,6 +761,51 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
: num_dmrs_cdm_grps_no_data * 4; : num_dmrs_cdm_grps_no_data * 4;
} }
#define BLER_UPDATE_FRAME 10
#define BLER_FILTER 0.9f
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame)
{
/* first call: everything is zero. Initialize to sensible default */
if (bler_stats->last_frame == 0 && bler_stats->mcs == 0) {
bler_stats->last_frame = frame;
bler_stats->mcs = 9;
bler_stats->bler = (bler_options->lower + bler_options->upper) / 2.0f;
}
int diff = frame - bler_stats->last_frame;
if (diff < 0) // wrap around
diff += 1024;
max_mcs = min(max_mcs, bler_options->max_mcs);
const uint8_t old_mcs = min(bler_stats->mcs, max_mcs);
if (diff < BLER_UPDATE_FRAME)
return old_mcs; // no update
// last update is longer than x frames ago
const int dtx = (int)(stats->rounds[0] - bler_stats->rounds[0]);
const int dretx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
const float bler_window = dtx > 0 ? (float) dretx / dtx : bler_stats->bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
int new_mcs = old_mcs;
if (bler_stats->bler < bler_options->lower && old_mcs < max_mcs && dtx > 9)
new_mcs += 1;
else if ((bler_stats->bler > bler_options->upper && old_mcs > 6) // above threshold
|| (dtx <= 3 && old_mcs > 9)) // no activity
new_mcs -= 1;
// else we are within threshold boundaries
bler_stats->last_frame = frame;
bler_stats->mcs = new_mcs;
memcpy(bler_stats->rounds, stats->rounds, sizeof(stats->rounds));
LOG_D(MAC, "frame %4d MCS %d -> %d (dtx %d, dretx %d, BLER wnd %.3f avg %.6f)\n",
frame, old_mcs, new_mcs, dtx, dretx, bler_window, bler_stats->bler);
return new_mcs;
}
void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
nr_scs_e scs_common, nr_scs_e scs_common,
nr_scs_e pdcch_scs, nr_scs_e pdcch_scs,
...@@ -2359,7 +2397,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG ...@@ -2359,7 +2397,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP); compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
memset(sched_ctrl, 0, sizeof(*sched_ctrl)); memset(sched_ctrl, 0, sizeof(*sched_ctrl));
sched_ctrl->set_mcs = true; sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
sched_ctrl->set_pmi = false; sched_ctrl->set_pmi = false;
sched_ctrl->ta_frame = 0; sched_ctrl->ta_frame = 0;
sched_ctrl->ta_update = 31; sched_ctrl->ta_update = 31;
......
...@@ -838,8 +838,8 @@ static void handle_dl_harq(module_id_t mod_id, ...@@ -838,8 +838,8 @@ static void handle_dl_harq(module_id_t mod_id,
harq->round = 0; harq->round = 0;
harq->ndi ^= 1; harq->ndi ^= 1;
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
stats->dlsch_errors++; stats->dl.errors++;
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors); LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dl.errors);
} else { } else {
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id); LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
...@@ -1250,7 +1250,12 @@ void evaluate_cqi_report(uint8_t *payload, ...@@ -1250,7 +1250,12 @@ void evaluate_cqi_report(uint8_t *payload,
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_2tb = temp_cqi; sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_2tb = temp_cqi;
LOG_D(MAC,"Wide-band CQI for the second TB %d\n", temp_cqi); LOG_D(MAC,"Wide-band CQI for the second TB %d\n", temp_cqi);
} }
sched_ctrl->set_mcs = true;
// TODO for wideband case and multiple TB
const int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
const int mcs_table = sched_ctrl->pdsch_semi_static.mcsTableIdx;
const int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table;
sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_table, cqi_idx);
} }
......
...@@ -464,7 +464,7 @@ int nr_process_mac_pdu(module_id_t module_idP, ...@@ -464,7 +464,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
rx_lcid, rx_lcid,
module_idP, module_idP,
mac_len); mac_len);
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_len; UE_info->mac_stats[UE_id].ul.lc_bytes[rx_lcid] += mac_len;
mac_rlc_data_ind(module_idP, mac_rlc_data_ind(module_idP,
UE_info->rnti[UE_id], UE_info->rnti[UE_id],
...@@ -526,7 +526,7 @@ void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid) ...@@ -526,7 +526,7 @@ void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid)
harq->ndi ^= 1; harq->ndi ^= 1;
harq->round = 0; harq->round = 0;
UE_info->mac_stats[UE_id].ulsch_errors++; UE_info->mac_stats[UE_id].ul.errors++;
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
/* the transmission failed: the UE won't send the data we expected initially, /* the transmission failed: the UE won't send the data we expected initially,
...@@ -637,7 +637,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, ...@@ -637,7 +637,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid), T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid),
T_BUFFER(sduP, sdu_lenP)); T_BUFFER(sduP, sdu_lenP));
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; UE_info->mac_stats[UE_id].ul.total_bytes += sdu_lenP;
LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d TA %d sduP %p, rssi %d\n", LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d TA %d sduP %p, rssi %d\n",
gnb_mod_idP, gnb_mod_idP,
harq_pid, harq_pid,
...@@ -1174,10 +1174,11 @@ void pf_ul(module_id_t module_id, ...@@ -1174,10 +1174,11 @@ void pf_ul(module_id_t module_id,
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
const NR_mac_dir_stats_t *stats = &UE_info->mac_stats[UE_id].ul;
/* Calculate throughput */ /* Calculate throughput */
const float a = 0.0005f; // corresponds to 200ms window const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes; const uint32_t b = stats->current_bytes;
ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b; ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b;
/* Check if retransmission is necessary */ /* Check if retransmission is necessary */
...@@ -1209,6 +1210,10 @@ void pf_ul(module_id_t module_id, ...@@ -1209,6 +1210,10 @@ void pf_ul(module_id_t module_id,
continue; continue;
} }
const NR_bler_options_t *bo = &nrmac->ul_bler;
const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */
sched_pusch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->ul_bler_stats, max_mcs, frame);
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
* based on data to transmit) */ * based on data to transmit) */
if (B == 0 && do_sched) { if (B == 0 && do_sched) {
...@@ -1284,7 +1289,7 @@ void pf_ul(module_id_t module_id, ...@@ -1284,7 +1289,7 @@ void pf_ul(module_id_t module_id,
sched_ctrl->aggregation_level); sched_ctrl->aggregation_level);
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->mcs = nrmac->min_grant_mcs; sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs);
update_ul_ue_R_Qm(sched_pusch, ps); update_ul_ue_R_Qm(sched_pusch, ps);
sched_pusch->rbStart = rbStart; sched_pusch->rbStart = rbStart;
sched_pusch->rbSize = min_rb; sched_pusch->rbSize = min_rb;
...@@ -1310,7 +1315,6 @@ void pf_ul(module_id_t module_id, ...@@ -1310,7 +1315,6 @@ void pf_ul(module_id_t module_id,
add_tail_nr_list(&UE_sched, UE_id); add_tail_nr_list(&UE_sched, UE_id);
/* Calculate coefficient*/ /* Calculate coefficient*/
sched_pusch->mcs = nrmac->min_grant_mcs;
const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs]; const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id]; coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
...@@ -1652,7 +1656,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ...@@ -1652,7 +1656,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
UE_info->mac_stats[UE_id].ulsch_current_bytes = 0; NR_mac_stats_t *mac_stats = &UE_info->mac_stats[UE_id];
mac_stats->ul.current_bytes = 0;
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
* every TTI are pre-populated by the preprocessor and used below */ * every TTI are pre-populated by the preprocessor and used below */
...@@ -1696,10 +1701,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ...@@ -1696,10 +1701,10 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
/* Statistics */ /* Statistics */
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); AssertFatal(cur_harq->round < 8, "Indexing UL rounds[%d] is out of bounds\n", cur_harq->round);
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; mac_stats->ul.rounds[cur_harq->round]++;
if (cur_harq->round == 0) { if (cur_harq->round == 0) {
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size; mac_stats->ulsch_total_bytes_scheduled += sched_pusch->tb_size;
/* Save information on MCS, TBS etc for the current initial transmission /* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */ * so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch; cur_harq->sched_pusch = *sched_pusch;
...@@ -1719,7 +1724,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ...@@ -1719,7 +1724,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
cur_harq->round, cur_harq->round,
cur_harq->ndi); cur_harq->ndi);
} }
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; mac_stats->ul.current_bytes = sched_pusch->tb_size;
sched_ctrl->last_ul_frame = sched_pusch->frame; sched_ctrl->last_ul_frame = sched_pusch->frame;
sched_ctrl->last_ul_slot = sched_pusch->slot; sched_ctrl->last_ul_slot = sched_pusch->slot;
......
...@@ -507,10 +507,7 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl, ...@@ -507,10 +507,7 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
int xp_pdsch_antenna_ports, int xp_pdsch_antenna_ports,
int codebook_mode); int codebook_mode);
void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch, uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
NR_UE_sched_ctrl_t *sched_ctrl,
uint8_t *target_mcs,
uint8_t mcs_table_idx);
uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl); uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl);
...@@ -531,6 +528,12 @@ bool nr_find_nb_rb(uint16_t Qm, ...@@ -531,6 +528,12 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs, uint32_t *tbs,
uint16_t *nb_rb); uint16_t *nb_rb);
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame);
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp); void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
......
...@@ -102,9 +102,9 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp ...@@ -102,9 +102,9 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
UE_id, UE_id,
stats->dlsch_rounds[0], stats->dlsch_rounds[1], stats->dl.rounds[0], stats->dl.rounds[1],
stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dl.rounds[2], stats->dl.rounds[3],
stats->dlsch_errors, stats->dl.errors,
stats->pucch0_DTX, stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler, sched_ctrl->dl_bler_stats.bler,
sched_ctrl->dl_bler_stats.mcs); sched_ctrl->dl_bler_stats.mcs);
...@@ -112,25 +112,27 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp ...@@ -112,25 +112,27 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
stats->num_rsrp_meas = 0; stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0; stats->cumul_rsrp = 0;
} }
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dlsch_total_bytes); stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dl.total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n", stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
UE_id, UE_id,
stats->ulsch_rounds[0], stats->ulsch_rounds[1], stats->ul.rounds[0], stats->ul.rounds[1],
stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ul.rounds[2], stats->ul.rounds[3],
stats->ulsch_DTX, stats->ulsch_DTX,
stats->ulsch_errors); stats->ul.errors,
sched_ctrl->ul_bler_stats.bler,
sched_ctrl->ul_bler_stats.mcs);
stroff+=sprintf(output+stroff, stroff+=sprintf(output+stroff,
"UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", "UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
UE_id, UE_id,
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
for (int lc_id = 0; lc_id < 63; lc_id++) { for (int lc_id = 0; lc_id < 63; lc_id++) {
if (stats->lc_bytes_tx[lc_id] > 0) { if (stats->dl.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]);
} }
if (stats->lc_bytes_rx[lc_id] > 0) { if (stats->ul.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]);
} }
} }
} }
......
...@@ -459,13 +459,12 @@ typedef struct NR_UE_harq { ...@@ -459,13 +459,12 @@ typedef struct NR_UE_harq {
//! fixme : need to enhace for the multiple TB CQI report //! fixme : need to enhace for the multiple TB CQI report
typedef struct NR_DL_bler_stats { typedef struct NR_bler_stats {
frame_t last_frame_slot; frame_t last_frame;
float bler; float bler;
float rd2_bler;
uint8_t mcs; uint8_t mcs;
uint64_t dlsch_rounds[8]; uint64_t rounds[8];
} NR_DL_bler_stats_t; } NR_bler_stats_t;
// //
/*! As per spec 38.214 section 5.2.1.4.2 /*! As per spec 38.214 section 5.2.1.4.2
...@@ -613,6 +612,9 @@ typedef struct { ...@@ -613,6 +612,9 @@ typedef struct {
NR_pdsch_semi_static_t pdsch_semi_static; NR_pdsch_semi_static_t pdsch_semi_static;
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pdsch_t sched_pdsch; NR_sched_pdsch_t sched_pdsch;
/// UE-estimated maximum MCS (from CSI-RS)
uint8_t dl_max_mcs;
/// For UL synchronization: store last UL scheduling grant /// For UL synchronization: store last UL scheduling grant
frame_t last_ul_frame; frame_t last_ul_frame;
sub_frame_t last_ul_slot; sub_frame_t last_ul_slot;
...@@ -624,7 +626,8 @@ typedef struct { ...@@ -624,7 +626,8 @@ typedef struct {
mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID]; mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID];
/// Estimation of HARQ from BLER /// Estimation of HARQ from BLER
NR_DL_bler_stats_t dl_bler_stats; NR_bler_stats_t dl_bler_stats;
NR_bler_stats_t ul_bler_stats;
uint16_t ta_frame; uint16_t ta_frame;
int16_t ta_update; int16_t ta_update;
...@@ -641,7 +644,6 @@ typedef struct { ...@@ -641,7 +644,6 @@ typedef struct {
int ul_failure; int ul_failure;
struct CSI_Report CSI_report; struct CSI_Report CSI_report;
bool SR; bool SR;
bool set_mcs;
bool set_pmi; bool set_pmi;
/// information about every HARQ process /// information about every HARQ process
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
...@@ -674,24 +676,29 @@ typedef struct { ...@@ -674,24 +676,29 @@ typedef struct {
uicc_t *uicc; uicc_t *uicc;
} NRUEcontext_t; } NRUEcontext_t;
typedef struct { typedef struct NR_mac_dir_stats {
uint64_t lc_bytes_tx[64]; uint64_t lc_bytes[64];
uint64_t lc_bytes_rx[64]; uint64_t rounds[8];
uint64_t dlsch_rounds[8]; uint64_t errors;
uint64_t dlsch_errors; uint64_t total_bytes;
uint64_t dlsch_total_bytes; uint32_t current_bytes;
int dlsch_current_bytes; } NR_mac_dir_stats_t;
uint64_t ulsch_rounds[8];
uint64_t ulsch_errors; typedef struct NR_mac_stats {
NR_mac_dir_stats_t dl;
NR_mac_dir_stats_t ul;
uint32_t ulsch_DTX; uint32_t ulsch_DTX;
uint64_t ulsch_total_bytes_scheduled; uint64_t ulsch_total_bytes_scheduled;
uint64_t ulsch_total_bytes_rx;
int ulsch_current_bytes;
uint32_t pucch0_DTX; uint32_t pucch0_DTX;
int cumul_rsrp; int cumul_rsrp;
uint8_t num_rsrp_meas; uint8_t num_rsrp_meas;
} NR_mac_stats_t; } NR_mac_stats_t;
typedef struct NR_bler_options {
double upper;
double lower;
uint8_t max_mcs;
} NR_bler_options_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/ /*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48 #define MAX_CSI_REPORTCONFIG 48
...@@ -833,10 +840,8 @@ typedef struct gNB_MAC_INST_s { ...@@ -833,10 +840,8 @@ typedef struct gNB_MAC_INST_s {
int xp_pdsch_antenna_ports; int xp_pdsch_antenna_ports;
bool first_MIB; bool first_MIB;
double dl_bler_target_upper; NR_bler_options_t dl_bler;
double dl_bler_target_lower; NR_bler_options_t ul_bler;
double dl_rd2_bler_threshold;
uint8_t dl_max_mcs;
uint8_t harq_round_max; uint8_t harq_round_max;
uint8_t min_grant_prb; uint8_t min_grant_prb;
uint8_t min_grant_mcs; uint8_t min_grant_mcs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment