mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 12:40:28 +00:00
Compare commits
17 Commits
pre-commit
...
mac-estima
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33cc7906ee | ||
|
|
7345553f74 | ||
|
|
514062c56d | ||
|
|
cf4d860278 | ||
|
|
72dc2a3315 | ||
|
|
6bf52fc134 | ||
|
|
851302ef24 | ||
|
|
48dbae5cbb | ||
|
|
7d38fa3028 | ||
|
|
3b97eef384 | ||
|
|
95a56c1a1c | ||
|
|
96afcdef68 | ||
|
|
f8a1c3bea0 | ||
|
|
a1ab29d1b0 | ||
|
|
8b23d2449e | ||
|
|
4b6e87071c | ||
|
|
e714eb3876 |
@@ -23,7 +23,7 @@ gNBs =
|
||||
nr_cellid = 12345678L
|
||||
|
||||
////////// Physical parameters:
|
||||
uess_agg_levels = [2, 2, 2, 0, 0];
|
||||
uess_agg_levels = [4, 2, 2, 0, 0];
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
|
||||
@@ -90,8 +90,7 @@
|
||||
|
||||
<testCase>
|
||||
<class>Iperf</class>
|
||||
<desc>Optional iperf (DL/700Mbps/UDP)(30 sec)</desc>
|
||||
<may_fail>true</may_fail>
|
||||
<desc>Iperf (DL/700Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 700M -t 30 -R</iperf_args>
|
||||
<id>up2-fhi72</id>
|
||||
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
||||
#define OPENAIRINTERFACE5G_LIMITS_H_
|
||||
|
||||
# define MAX_MOBILES_PER_GNB 16
|
||||
# define MAX_MOBILES_PER_GNB 128
|
||||
# define NUMBER_OF_eNB_MAX 1
|
||||
# define NUMBER_OF_gNB_MAX 1
|
||||
# define NUMBER_OF_RU_MAX 2
|
||||
|
||||
@@ -22,16 +22,17 @@ UEs with retransmissions are allocated first; similarly, UEs that have not been
|
||||
scheduled for some time in UL are scheduled automatically in UL and have
|
||||
therefore priority over data with "normal" traffic.
|
||||
|
||||
The MCS selection is done in `get_mcs_from_bler()` in file
|
||||
The MCS selection is done in `estimate_next_mcs()` in file
|
||||
[`gNB_scheduler_primitives.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c).
|
||||
It consider two thresholds for a "BLER" that is computed from the number of
|
||||
first-round retransmissions over total transmissions in the last window (50ms).
|
||||
If that ratio is higher than an "upper" threshold (see
|
||||
`dl/ul_bler_target_upper` in the configuration section below), it is
|
||||
interpreted as "bad channel" and MCS is decremented by 1. If the ratio is
|
||||
lower than a "lower" threshold (see `dl/ul_bler_target_lower`), it is
|
||||
On UE inactivity (low traffic), it returns an estimated MCS (from CQI, SINR,
|
||||
...). On UE activity (UE with active traffic), it calculates the MCS from BLER
|
||||
computed from the number of first-round retransmissions over total
|
||||
transmissions in the last window (50ms). If that ratio is higher than an
|
||||
"upper" threshold (see `dl/ul_bler_target_upper` in the configuration section
|
||||
below), it is interpreted as "bad channel" and MCS is decremented by 1. If the
|
||||
ratio is lower than a "lower" threshold (see `dl/ul_bler_target_lower`), it is
|
||||
interpreted as "good channel" and MCS is incremented by 1. This happens each
|
||||
window.
|
||||
window of 10 frames.
|
||||
|
||||
The actual scheduler implementation can be found in functions `pf_dl()` and
|
||||
`pf_ul()` in files
|
||||
|
||||
@@ -411,7 +411,10 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int
|
||||
}
|
||||
#endif
|
||||
|
||||
DevAssert(UL_INFO->crc_ind.number_crcs == UL_INFO->rx_ind.number_of_pdus);
|
||||
DevAssert(UL_INFO->crc_ind.number_crcs < sizeofArray(UL_INFO->crc_pdu_list));
|
||||
nfapi_nr_crc_t *crc = &UL_INFO->crc_ind.crc_list[UL_INFO->crc_ind.number_crcs++];
|
||||
DevAssert(UL_INFO->rx_ind.number_of_pdus < sizeofArray(UL_INFO->rx_pdu_list));
|
||||
nfapi_nr_rx_data_pdu_t *pdu = &UL_INFO->rx_ind.pdu_list[UL_INFO->rx_ind.number_of_pdus++];
|
||||
if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !pusch->DTX) {
|
||||
LOG_D(NR_PHY,
|
||||
@@ -1051,7 +1054,10 @@ static bool handle_pusch_decode_trigger(PHY_VARS_gNB *gNB, NR_gNB_PUSCH *pusch_v
|
||||
if (!get_softmodem_params()->phy_test) {
|
||||
/* in case of phy_test mode, we still want to decode to measure execution time.
|
||||
Therefore, we don't yet call nr_fill_indication, it will be called later */
|
||||
DevAssert(UL_INFO->crc_ind.number_crcs == UL_INFO->rx_ind.number_of_pdus);
|
||||
DevAssert(UL_INFO->crc_ind.number_crcs < sizeofArray(UL_INFO->crc_pdu_list));
|
||||
nfapi_nr_crc_t *crc = &UL_INFO->crc_ind.crc_list[UL_INFO->crc_ind.number_crcs++];
|
||||
DevAssert(UL_INFO->rx_ind.number_of_pdus < sizeofArray(UL_INFO->rx_pdu_list));
|
||||
nfapi_nr_rx_data_pdu_t *rx = &UL_INFO->rx_ind.pdu_list[UL_INFO->rx_ind.number_of_pdus++];
|
||||
nr_fill_indication(gNB, ulsch->frame, ulsch->slot, pusch_vars, pdu, stats, NULL, 1, crc, rx);
|
||||
(*pusch_DTX)++;
|
||||
|
||||
@@ -607,6 +607,15 @@ static int comparator(const void *p, const void *q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t get_est_mcs(const dl_est_mcs_t *est_mcs)
|
||||
{
|
||||
if (est_mcs->from_csirs_cqi)
|
||||
return est_mcs->from_csirs_cqi;
|
||||
if (est_mcs->from_ssb_sinr)
|
||||
return est_mcs->from_ssb_sinr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pf_dl(gNB_MAC_INST *mac,
|
||||
post_process_pdsch_t *pp_pdsch,
|
||||
NR_UE_info_t **UE_list,
|
||||
@@ -640,7 +649,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
int harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.01f;
|
||||
const float a = 0.05f;
|
||||
const uint32_t b = stats->current_bytes;
|
||||
UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
|
||||
|
||||
@@ -692,14 +701,12 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
/* Calculate coeff */
|
||||
const NR_bler_options_t *bo = &mac->dl_bler;
|
||||
const int max_mcs_table = current_BWP->mcsTableIdx == 1 ? 27 : 28;
|
||||
const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table);
|
||||
int selected_mcs;
|
||||
if (bo->harq_round_max == 1) {
|
||||
int new_mcs = min(bo->max_mcs, max_mcs);
|
||||
selected_mcs = max(bo->min_mcs, new_mcs);
|
||||
sched_ctrl->dl_bler_stats.mcs = selected_mcs;
|
||||
} else
|
||||
selected_mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame);
|
||||
// UE is active if there is some traffic over time (more 1 Kb/s),
|
||||
// or sudden burst
|
||||
bool ue_is_active = UE->dl_thr_ue > 1000 || sched_ctrl->num_total_bytes >= 300;
|
||||
const int est_mcs = get_est_mcs(&sched_ctrl->dl_est_mcs);
|
||||
int selected_mcs = estimate_next_mcs(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs_table, est_mcs, frame, ue_is_active);
|
||||
LOG_D(NR_MAC, "%d.%d UE %04x mcs %d bler %f\n", frame, slot, UE->rnti, selected_mcs, sched_ctrl->dl_bler_stats.bler);
|
||||
int l = get_dl_nrOfLayers(sched_ctrl, current_BWP->dci_format);
|
||||
const uint8_t Qm = nr_get_Qm_dl(selected_mcs, current_BWP->mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(selected_mcs, current_BWP->mcsTableIdx);
|
||||
@@ -732,6 +739,10 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
UEsched_t *iterator = UE_sched;
|
||||
|
||||
const int min_rbSize = 5;
|
||||
const int UEperTTI = 4;
|
||||
const int schedUE = max(1, min(UEperTTI, numUE));
|
||||
DevAssert(num_beams == 1);
|
||||
const int rbPerUE = n_rb_sched[0] / schedUE;
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (iterator->UE != NULL) {
|
||||
@@ -788,7 +799,7 @@ static void pf_dl(gNB_MAC_INST *mac,
|
||||
int bwp_size = bwp_info.bwpSize;
|
||||
// Freq-demain allocation
|
||||
int max_rbSize = 0;
|
||||
if (!get_rb_alloc(min_rbSize, bwp_size, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &max_rbSize)) {
|
||||
if (!get_rb_alloc(min_rbSize, rbPerUE, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &max_rbSize)) {
|
||||
LOG_D(NR_MAC,
|
||||
"(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d\n",
|
||||
frame,
|
||||
@@ -905,8 +916,7 @@ static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pd
|
||||
for (int i = 0; i < num_beams; i++)
|
||||
n_rb_sched[i] = bw;
|
||||
|
||||
int average_agg_level = 4; // TODO find a better estimation
|
||||
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
|
||||
int max_sched_ues = 10;
|
||||
|
||||
// FAPI cannot handle more than MAX_DCI_CORESET DCIs
|
||||
max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET);
|
||||
|
||||
@@ -228,9 +228,9 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
|
||||
// command line: nr_dlsim -n 10000 -m 0 -R 25 -b 25 -e MCS -s START_SNR -t 99.99
|
||||
// SNR Thresholds for MCS=[0,...,28]; START_SNR=chosen values with a resolution of 0.2dB to maintain a BLER of 10^-3
|
||||
static const int SINRx10_MCS_mapping[29] = {
|
||||
-10, -4, 6, 16, 24, 34, 42, 50, 56, 62, // 0..9
|
||||
86, 92, 98, 104, 112, 118, 124, 140, 146, 154, // 10..19
|
||||
162, 170, 178, 186, 194, 202, 212, 220, 245 // 20..28
|
||||
-16, -8, 2, 12, 22, 32, 40, 48, 52, 60, // 0..9
|
||||
82, 86, 94, 100, 110, 116, 122, 136, 142, 150, // 10..19
|
||||
160, 164, 174, 182, 192, 200, 212, 216, 242 // 20..28
|
||||
};
|
||||
|
||||
int get_mcs_from_SINRx10(int mcs_table, int SINRx10, int Nl)
|
||||
@@ -811,40 +811,61 @@ NR_pusch_dmrs_t get_ul_dmrs_params(const NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
#define BLER_UPDATE_FRAME 10
|
||||
#define BLER_FILTER 0.9f
|
||||
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
|
||||
#define MAX_BLER_EST_MCS_DIFF 10
|
||||
#define MAX_FRAMES_ACTIVE 100
|
||||
int estimate_next_mcs(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)
|
||||
int est_mcs,
|
||||
frame_t frame,
|
||||
bool ue_is_active)
|
||||
{
|
||||
int diff = frame - bler_stats->last_frame;
|
||||
if (diff < 0) // wrap around
|
||||
diff += 1024;
|
||||
|
||||
bler_stats->frames_inactive = ue_is_active ? 0 : bler_stats->frames_inactive + diff;
|
||||
|
||||
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
|
||||
int new_mcs = bler_stats->mcs;
|
||||
if (bler_stats->frames_inactive >= MAX_FRAMES_ACTIVE || bler_options->harq_round_max == 1) {
|
||||
// if UE is inactive, return MCS estimation (or previous if no estimation)
|
||||
// or if there is no HARQ => no retransmission => no BLER
|
||||
if (est_mcs > 0) {
|
||||
// bound the estimation between user configured min/max MCS and current
|
||||
// MCS table max
|
||||
est_mcs = min(est_mcs, max_mcs);
|
||||
new_mcs = max(est_mcs, bler_options->min_mcs);
|
||||
}
|
||||
} else if (est_mcs > 0 && abs(bler_stats->mcs - est_mcs) >= MAX_BLER_EST_MCS_DIFF) {
|
||||
// there is a big difference between MCS from BLER and what is estimated,
|
||||
// correct this quickly
|
||||
LOG_D(NR_MAC, "correct MCS %d => %d\n", bler_stats->mcs, est_mcs);
|
||||
est_mcs = min(est_mcs, max_mcs);
|
||||
new_mcs = max(est_mcs, bler_options->min_mcs);
|
||||
} else {
|
||||
if (diff < BLER_UPDATE_FRAME)
|
||||
return bler_stats->mcs; // no update
|
||||
|
||||
// last update is longer than x frames ago
|
||||
const int num_dl_sched = (int)(stats->rounds[0] - bler_stats->rounds[0]);
|
||||
const int num_dl_retx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
|
||||
const float bler_window = num_dl_sched > 0 ? (float) num_dl_retx / num_dl_sched : bler_stats->bler;
|
||||
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
|
||||
// last update is longer than x frames ago
|
||||
const int num_dl_sched = (int)(stats->rounds[0] - bler_stats->rounds[0]);
|
||||
const int num_dl_retx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
|
||||
const float bler_window = num_dl_sched > 0 ? (float) num_dl_retx / num_dl_sched : 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 && num_dl_sched > 3)
|
||||
new_mcs += 1;
|
||||
else if (bler_stats->bler > bler_options->upper || num_dl_sched <= 3) // above threshold or no activity
|
||||
new_mcs -= 1;
|
||||
// else we are within threshold boundaries
|
||||
if (bler_stats->bler < bler_options->lower && new_mcs < max_mcs)
|
||||
new_mcs += 1;
|
||||
else if (bler_stats->bler > bler_options->upper && new_mcs > bler_options->min_mcs)
|
||||
new_mcs -= 1;
|
||||
// else we are within threshold boundaries or at limits
|
||||
LOG_D(MAC, "frame %4d MCS %d -> %d (num_dl_sched %d, num_dl_retx %d, BLER wnd %.3f avg %.6f)\n",
|
||||
frame, bler_stats->mcs, new_mcs, num_dl_sched, num_dl_retx, bler_window, bler_stats->bler);
|
||||
}
|
||||
|
||||
new_mcs = max(new_mcs, bler_options->min_mcs);
|
||||
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 (num_dl_sched %d, num_dl_retx %d, BLER wnd %.3f avg %.6f)\n",
|
||||
frame, old_mcs, new_mcs, num_dl_sched, num_dl_retx, bler_window, bler_stats->bler);
|
||||
return new_mcs;
|
||||
}
|
||||
|
||||
@@ -3074,7 +3095,6 @@ bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
}
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
|
||||
sched_ctrl->pdcch_cl_adjust = 0;
|
||||
reset_srs_stats(UE);
|
||||
|
||||
|
||||
@@ -498,9 +498,10 @@ static void evaluate_sinr_report(NR_UE_info_t *UE,
|
||||
|
||||
const int mcs_table = UE->current_DL_BWP.mcsTableIdx;
|
||||
const int nrOfLayers = get_dl_nrOfLayers(sched_ctrl, UE->current_DL_BWP.dci_format);
|
||||
sched_ctrl->dl_max_mcs = get_mcs_from_SINRx10(mcs_table, sinr_report->r[0].SINRx10, nrOfLayers);
|
||||
int est_mcs = get_mcs_from_SINRx10(mcs_table, sinr_report->r[0].SINRx10, nrOfLayers);
|
||||
sched_ctrl->dl_est_mcs.from_ssb_sinr = est_mcs;
|
||||
|
||||
LOG_D(MAC, "Reported SSB-SINR = %01f, dl_max_mcs %d\n", sinr_report->r[0].SINRx10 / 10.0, sched_ctrl->dl_max_mcs);
|
||||
LOG_D(MAC, "Reported SSB-SINR = %.1f, est_mcs %d\n", (float) sinr_report->r[0].SINRx10 / 10.f, est_mcs);
|
||||
}
|
||||
|
||||
static void evaluate_rsrp_report(NR_UE_info_t *UE,
|
||||
@@ -639,9 +640,10 @@ static void evaluate_cqi_report(uint8_t *payload,
|
||||
// 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 = UE->current_DL_BWP.mcsTableIdx;
|
||||
sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_Table, cqi_idx);
|
||||
int est_mcs = get_mcs_from_cqi(mcs_table, cqi_Table, cqi_idx);
|
||||
sched_ctrl->dl_est_mcs.from_csirs_cqi = est_mcs;
|
||||
|
||||
LOG_D(MAC, "Reported CQI = %d, dl_max_mcs %d\n", temp_cqi, sched_ctrl->dl_max_mcs);
|
||||
LOG_D(MAC, "Reported CQI = %d, est_mcs %d\n", temp_cqi, est_mcs);
|
||||
}
|
||||
|
||||
static uint8_t evaluate_pmi_report(uint8_t *payload,
|
||||
|
||||
@@ -1915,7 +1915,7 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
|
||||
|
||||
/* Calculate throughput */
|
||||
const float a = 0.01f;
|
||||
const float a = 0.05f;
|
||||
const uint32_t b = stats->current_bytes;
|
||||
UE->ul_thr_ue = (1 - a) * UE->ul_thr_ue + a * b;
|
||||
|
||||
@@ -2001,18 +2001,11 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
|
||||
const NR_bler_options_t *bo = &nrmac->ul_bler;
|
||||
const int max_mcs_table = (current_BWP->mcs_table == 0 || current_BWP->mcs_table == 2) ? 28 : 27;
|
||||
const int max_mcs = min(bo->max_mcs, max_mcs_table); /* no per-user maximum MCS yet */
|
||||
int selected_mcs;
|
||||
int nrOfLayers = get_ul_nrOfLayers(sched_ctrl, current_BWP->dci_format);
|
||||
if (bo->harq_round_max == 1) {
|
||||
selected_mcs = get_mcs_from_SINRx10(current_BWP->mcs_table, sched_ctrl->pusch_pc.avg_snr * 10, nrOfLayers);
|
||||
selected_mcs = min(max_mcs, selected_mcs);
|
||||
selected_mcs = max(bo->min_mcs, selected_mcs);
|
||||
sched_ctrl->ul_bler_stats.mcs = selected_mcs;
|
||||
} else {
|
||||
selected_mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->ul_bler_stats, max_mcs, frame);
|
||||
LOG_D(NR_MAC, "%d.%d starting mcs %d bler %f\n", frame, slot, selected_mcs, sched_ctrl->ul_bler_stats.bler);
|
||||
}
|
||||
bool sched_inactive = B == 0 && do_sched;
|
||||
const int est_mcs = get_mcs_from_SINRx10(current_BWP->mcs_table, sched_ctrl->pusch_pc.avg_snr * 10, nrOfLayers);
|
||||
int selected_mcs = estimate_next_mcs(bo, stats, &sched_ctrl->ul_bler_stats, max_mcs_table, est_mcs, frame, !sched_inactive);
|
||||
LOG_D(NR_MAC, "%d.%d UE %04x mcs %d bler %f\n", frame, slot, UE->rnti, selected_mcs, sched_ctrl->ul_bler_stats.bler);
|
||||
|
||||
/* Create UE_sched for UEs eligibale for new data transmission*/
|
||||
/* Calculate coefficient*/
|
||||
@@ -2028,7 +2021,6 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
nrOfLayers)
|
||||
>> 3;
|
||||
float coeff_ue = (float) tbs / UE->ul_thr_ue;
|
||||
bool sched_inactive = B == 0 && do_sched;
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] b %d, ul_thr_ue %f, tbs %d, coeff_ue %f, sched_inactive %d\n",
|
||||
UE->rnti,
|
||||
frame,
|
||||
|
||||
@@ -434,11 +434,13 @@ bool get_rb_alloc(int rbSize_min,
|
||||
int *rbStart_ptr,
|
||||
int *rbSize_ptr);
|
||||
|
||||
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
|
||||
int estimate_next_mcs(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);
|
||||
int est_mcs,
|
||||
frame_t frame,
|
||||
bool ue_is_active);
|
||||
|
||||
int ul_buffer_index(int frame, int slot, int slots_per_frame, int size);
|
||||
void UL_tti_req_ahead_initialization(gNB_MAC_INST *gNB, int n, int CCid, frame_t frameP, int slotP);
|
||||
|
||||
@@ -523,6 +523,7 @@ typedef struct NR_bler_stats {
|
||||
float bler;
|
||||
uint8_t mcs;
|
||||
uint64_t rounds[8];
|
||||
int frames_inactive;
|
||||
} NR_bler_stats_t;
|
||||
|
||||
//
|
||||
@@ -607,6 +608,11 @@ typedef struct nr_power_control {
|
||||
float tpc_in_flight; /// TPCs applied by UE but not yet in average SNR
|
||||
} nr_power_control_t;
|
||||
|
||||
typedef struct dl_est_mcs {
|
||||
uint8_t from_csirs_cqi;
|
||||
uint8_t from_ssb_sinr;
|
||||
} dl_est_mcs_t;
|
||||
|
||||
/*! \brief scheduling control information set through an API */
|
||||
typedef struct {
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
@@ -637,8 +643,7 @@ typedef struct {
|
||||
/// PHR info: nominal UE transmit power levels (dBm)
|
||||
int pcmax;
|
||||
|
||||
/// UE-estimated maximum MCS (from CSI-RS)
|
||||
uint8_t dl_max_mcs;
|
||||
dl_est_mcs_t dl_est_mcs;
|
||||
|
||||
/// For UL synchronization: store last UL scheduling grant
|
||||
frame_t last_ul_frame;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define MAX_NUM_TX_REQUEST_PDU 100
|
||||
|
||||
#define MAX_NUM_NR_RX_RACH_PDUS 4
|
||||
#define MAX_UL_PDUS_PER_SLOT 8
|
||||
#define MAX_UL_PDUS_PER_SLOT 16
|
||||
#define MAX_NUM_NR_SRS_PDUS 8
|
||||
#define MAX_NUM_NR_UCI_PDUS MAX_MOBILES_PER_GNB
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user