Commit 17cbc4db authored by Robert Schmidt's avatar Robert Schmidt

Generalize get_mcs_from_bler()

parent 26c2c0ad
......@@ -62,7 +62,6 @@
#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_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_HARQ_ROUND_MAX "harq_round_max"
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
......@@ -97,7 +96,6 @@
{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_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_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}, \
......@@ -127,10 +125,10 @@
#define MACRLC_PUSCHFAILURETHRES_IDX 21
#define MACRLC_DL_BLER_TARGET_UPPER_IDX 22
#define MACRLC_DL_BLER_TARGET_LOWER_IDX 23
#define MACRLC_DL_RD2_BLER_THRESHOLD_IDX 24
#define MACRLC_DL_MAX_MCS_IDX 25
#define MACRLC_HARQ_ROUND_MAX_IDX 26
#define MACRLC_MIN_GRANT_PRB_IDX 27
#define MACRLC_MIN_GRANT_MCS_IDX 28
#define MACRLC_DL_MAX_MCS_IDX 24
#define MACRLC_HARQ_ROUND_MAX_IDX 25
#define MACRLC_MIN_GRANT_PRB_IDX 26
#define MACRLC_MIN_GRANT_MCS_IDX 27
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
......@@ -873,10 +873,10 @@ 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));
}
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);
RC.nrmac[j]->dl_bler_target_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
RC.nrmac[j]->dl_rd2_bler_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_RD2_BLER_THRESHOLD_IDX].dblptr);
RC.nrmac[j]->dl_max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
NR_bler_options_t *dl_bler_options = &RC.nrmac[j]->dl_bler;
dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_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_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
......
......@@ -397,79 +397,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
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;
NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
NR_DL_bler_stats_t *bler_stats = &sched_ctrl->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->dl.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->dl.rounds, sizeof(stats->dl.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->dl.rounds[0] - bler_stats->dlsch_rounds[0]);
const int dretx = (int)(stats->dl.rounds[1] - bler_stats->dlsch_rounds[1]);
const int dretx2 = (int)(stats->dl.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) {*/
const int max_mcs = min(max_allowed_mcs, min(sched_ctrl->dl_max_mcs, nrmac->dl_max_mcs));
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) // above threshold
|| (dtx <= 3 && old_mcs > 9)) // no activity
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->dl.rounds, sizeof(stats->dl.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,
frame_t frame,
sub_frame_t slot) {
......@@ -740,6 +667,7 @@ void pf_dl(module_id_t module_id,
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_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
......@@ -747,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
/* Calculate Throughput */
const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = UE_info->mac_stats[UE_id].dl.current_bytes;
const uint32_t b = stats->current_bytes;
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
/* retransmission */
......@@ -770,7 +698,10 @@ void pf_dl(module_id_t module_id,
continue;
/* Calculate coeff */
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE_id, ps->mcsTableIdx);
const NR_bler_options_t *bo = &mac->dl_bler;
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);
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);
......
......@@ -761,6 +761,51 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
: 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,
nr_scs_e scs_common,
nr_scs_e pdcch_scs,
......
......@@ -535,6 +535,12 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs,
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 dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
......
......@@ -459,13 +459,12 @@ typedef struct NR_UE_harq {
//! fixme : need to enhace for the multiple TB CQI report
typedef struct NR_DL_bler_stats {
frame_t last_frame_slot;
typedef struct NR_bler_stats {
frame_t last_frame;
float bler;
float rd2_bler;
uint8_t mcs;
uint64_t dlsch_rounds[8];
} NR_DL_bler_stats_t;
uint64_t rounds[8];
} NR_bler_stats_t;
//
/*! As per spec 38.214 section 5.2.1.4.2
......@@ -627,7 +626,7 @@ typedef struct {
mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID];
/// Estimation of HARQ from BLER
NR_DL_bler_stats_t dl_bler_stats;
NR_bler_stats_t dl_bler_stats;
uint16_t ta_frame;
int16_t ta_update;
......@@ -694,6 +693,11 @@ typedef struct NR_mac_stats {
uint8_t num_rsrp_meas;
} 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*/
#define MAX_CSI_REPORTCONFIG 48
......@@ -835,10 +839,7 @@ typedef struct gNB_MAC_INST_s {
int xp_pdsch_antenna_ports;
bool first_MIB;
double dl_bler_target_upper;
double dl_bler_target_lower;
double dl_rd2_bler_threshold;
uint8_t dl_max_mcs;
NR_bler_options_t dl_bler;
uint8_t harq_round_max;
uint8_t min_grant_prb;
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