Merge remote-tracking branch 'origin/refactor-dlsch' into integration_2025_w44 (!3682)
Refactor DLSCH scheduler Refactor the DLSCH post processor similarly to what has been done in !3521 with the goal of saving an additional iteration through all UEs, hopefully making the DLSCH scheduler faster. It further includes changes to make working with and debugging multi-UE operation easier: - add some measurements in L1 (for total TX/RX time) - a new option MACRLCs.[0].stats_max_ue to limit the number of UEs in the periodic output (default: 8, 0=disable) - avoid stack overflow in the MAC - fix the writing of stats to nrMAC_stats.log and nrL1_stats.log when the written output reduces by truncating the files - avoid to schedule retransmission with 0 RBs.
This commit is contained in:
@@ -146,6 +146,7 @@ MACRLCs:
|
||||
tr_n_preference: local_RRC
|
||||
pusch_TargetSNRx10: 200
|
||||
pucch_TargetSNRx10: 200
|
||||
stats_max_ue: 17
|
||||
|
||||
L1s:
|
||||
- num_cc: 1
|
||||
|
||||
@@ -182,6 +182,7 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
stats_max_ue = 17;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -236,6 +236,9 @@ In the `MACRLCs` section of the gNB/DU configuration file:
|
||||
case RSSI reaches the threshold and prevents ADC railing. Unit depends on
|
||||
RSSI reporting config.
|
||||
* `pucch_RSSI_Threshold`: Same as above but for PUCCH
|
||||
* `stats_max_ue` (default 8): maximum number of UEs to show in periodical
|
||||
stats; beyond this number, periodical statistics will be disabled (it can
|
||||
still be seen in `nrMAC_stats.log`. Use `0` to disable periodical stats.
|
||||
|
||||
In the `gNBs` section of the gNB/DU configuration file: some of the parameters
|
||||
affect RRC configuration (CellGroupConfig) of a UE, and are therefore listed
|
||||
|
||||
+12
-1
@@ -150,7 +150,9 @@ void *L1_rx_thread(void *arg)
|
||||
if (res == NULL)
|
||||
break;
|
||||
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
|
||||
start_meas(&gNB->l1_rx_proc);
|
||||
rx_func(info);
|
||||
stop_meas(&gNB->l1_rx_proc);
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
return NULL;
|
||||
@@ -164,7 +166,9 @@ void *L1_tx_thread(void *arg) {
|
||||
if (res == NULL) // stopping condition, happens only when queue is freed
|
||||
break;
|
||||
processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
start_meas(&gNB->l1_tx_proc);
|
||||
tx_func(info);
|
||||
stop_meas(&gNB->l1_tx_proc);
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
return NULL;
|
||||
@@ -229,6 +233,8 @@ static void rx_func(processingData_L1_t *info)
|
||||
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
output += print_meas_log(&gNB->l1_tx_proc, "L1 Tx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->l1_rx_proc, "L1 Rx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_scrambling_stats, "DLSCH scrambling", NULL, NULL, output, end-output);
|
||||
@@ -293,6 +299,8 @@ void *nrL1_stats_thread(void *param) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reset_meas(&gNB->l1_tx_proc);
|
||||
reset_meas(&gNB->l1_rx_proc);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
@@ -309,13 +317,16 @@ void *nrL1_stats_thread(void *param) {
|
||||
reset_meas(&gNB->dlsch_precoding_stats);
|
||||
while (!oai_exit) {
|
||||
sleep(1);
|
||||
if (ftruncate(fileno(fd), 0) != 0 || fseek(fd, 0, SEEK_SET) != 0) {
|
||||
LOG_E(NR_MAC, "error while writing nrL1_stats.log: %d, %s\n", errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
dump_nr_I0_stats(fd,gNB);
|
||||
dump_pdsch_stats(fd,gNB);
|
||||
dump_pusch_stats(fd,gNB);
|
||||
dump_L1_meas_stats(gNB, ru, output, L1STATSSTRLEN);
|
||||
fprintf(fd,"%s\n",output);
|
||||
fflush(fd);
|
||||
fseek(fd,0,SEEK_SET);
|
||||
}
|
||||
fclose(fd);
|
||||
return(NULL);
|
||||
|
||||
@@ -464,6 +464,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
|
||||
bool enable_analog_das;
|
||||
|
||||
time_stats_t l1_tx_proc;
|
||||
time_stats_t l1_rx_proc;
|
||||
|
||||
time_stats_t phy_proc_tx;
|
||||
time_stats_t phy_proc_rx;
|
||||
time_stats_t rx_prach;
|
||||
|
||||
@@ -182,13 +182,13 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */
|
||||
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0;
|
||||
|
||||
void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
void nr_dlsim_preprocessor(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch)
|
||||
{
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
|
||||
NR_UE_info_t *UE_info = nr_mac->UE_info.connected_ue_list[0];
|
||||
AssertFatal(nr_mac->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
uint8_t nr_of_candidates = 0;
|
||||
if (g_mcsIndex < 4) {
|
||||
@@ -201,8 +201,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
}
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, pp_pdsch->slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
@@ -210,49 +210,55 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti);
|
||||
AssertFatal(CCEIndex >= 0,
|
||||
"%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n",
|
||||
pp_pdsch->frame,
|
||||
pp_pdsch->slot,
|
||||
0,
|
||||
UE_info->rnti);
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
sched_pdsch->rbStart = g_rbStart;
|
||||
sched_pdsch->rbSize = g_rbSize;
|
||||
sched_pdsch->bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info);
|
||||
sched_pdsch->mcs = g_mcsIndex;
|
||||
sched_pdsch->nrOfLayers = g_nrOfLayers;
|
||||
sched_pdsch->pm_index = g_pmi;
|
||||
NR_sched_pdsch_t sched_pdsch = {
|
||||
.rbStart = g_rbStart,
|
||||
.rbSize = g_rbSize,
|
||||
.bwp_info = get_pdsch_bwp_start_size(nr_mac, UE_info),
|
||||
.mcs = g_mcsIndex,
|
||||
.nrOfLayers = g_nrOfLayers,
|
||||
.pm_index = g_pmi,
|
||||
};
|
||||
/* the following might override the table that is mandated by RRC
|
||||
* configuration */
|
||||
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot);
|
||||
AssertFatal(sched_pdsch->time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
sched_pdsch.time_domain_allocation = get_dl_tda(nr_mac, pp_pdsch->slot);
|
||||
AssertFatal(sched_pdsch.time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
sched_pdsch->tda_info = get_dl_tda_info(current_BWP,
|
||||
sched_pdsch.tda_info = get_dl_tda_info(current_BWP,
|
||||
sched_ctrl->search_space->searchSpaceType->present,
|
||||
sched_pdsch->time_domain_allocation,
|
||||
sched_pdsch.time_domain_allocation,
|
||||
NR_MIB__dmrs_TypeA_Position_pos2,
|
||||
1,
|
||||
TYPE_C_RNTI_,
|
||||
sched_ctrl->coreset->controlResourceSetId,
|
||||
false);
|
||||
|
||||
sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc,
|
||||
sched_pdsch.dmrs_parms = get_dl_dmrs_params(scc,
|
||||
current_BWP,
|
||||
&sched_pdsch->tda_info,
|
||||
sched_pdsch->nrOfLayers);
|
||||
&sched_pdsch.tda_info,
|
||||
sched_pdsch.nrOfLayers);
|
||||
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx);
|
||||
sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
|
||||
sched_pdsch->R,
|
||||
sched_pdsch->rbSize,
|
||||
sched_pdsch->tda_info.nrOfSymbols,
|
||||
sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT,
|
||||
sched_pdsch.Qm = nr_get_Qm_dl(sched_pdsch.mcs, current_BWP->mcsTableIdx);
|
||||
sched_pdsch.R = nr_get_code_rate_dl(sched_pdsch.mcs, current_BWP->mcsTableIdx);
|
||||
sched_pdsch.tb_size = nr_compute_tbs(sched_pdsch.Qm,
|
||||
sched_pdsch.R,
|
||||
sched_pdsch.rbSize,
|
||||
sched_pdsch.tda_info.nrOfSymbols,
|
||||
sched_pdsch.dmrs_parms.N_PRB_DMRS * sched_pdsch.dmrs_parms.N_DMRS_SLOT,
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
sched_pdsch->nrOfLayers) >> 3;
|
||||
sched_pdsch.nrOfLayers) >> 3;
|
||||
|
||||
/* the simulator assumes the HARQ PID is equal to the slot number */
|
||||
sched_pdsch->dl_harq_pid = slot;
|
||||
sched_pdsch.dl_harq_pid = pp_pdsch->slot;
|
||||
|
||||
/* The scheduler uses lists to track whether a HARQ process is
|
||||
* free/busy/awaiting retransmission, and updates the HARQ process states.
|
||||
@@ -261,15 +267,17 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
* Therefore, below lines just "repair" everything so that the scheduler
|
||||
* won't remark that there is no HARQ feedback */
|
||||
sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process
|
||||
if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ...
|
||||
add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available
|
||||
if (sched_ctrl->harq_processes[pp_pdsch->slot].round == 0) // depending on round set in simulation ...
|
||||
add_front_nr_list(&sched_ctrl->available_dl_harq, pp_pdsch->slot); // ... make PID available
|
||||
else
|
||||
add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission
|
||||
sched_ctrl->harq_processes[slot].is_waiting = false;
|
||||
AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart);
|
||||
AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize);
|
||||
AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs);
|
||||
add_front_nr_list(&sched_ctrl->retrans_dl_harq, pp_pdsch->slot); // ... make PID retransmission
|
||||
sched_ctrl->harq_processes[pp_pdsch->slot].is_waiting = false;
|
||||
AssertFatal(sched_pdsch.rbStart >= 0, "invalid rbStart %d\n", sched_pdsch.rbStart);
|
||||
AssertFatal(sched_pdsch.rbSize > 0, "invalid rbSize %d\n", sched_pdsch.rbSize);
|
||||
AssertFatal(sched_pdsch.mcs >= 0, "invalid mcs %d\n", sched_pdsch.mcs);
|
||||
AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx);
|
||||
|
||||
post_process_dlsch(nr_mac, pp_pdsch, UE_info, &sched_pdsch);
|
||||
}
|
||||
|
||||
nrUE_params_t nrUE_params;
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#define CONFIG_STRING_MACRLC_BEAM_WEIGHTS_LIST "beam_weights"
|
||||
#define CONFIG_STRING_MACRLC_PUSCH_RSSI_THRESHOLD "pusch_RSSI_Threshold"
|
||||
#define CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD "pucch_RSSI_Threshold"
|
||||
#define CONFIG_STRING_MACRLC_STATS_MAX_UE "stats_max_ue"
|
||||
|
||||
#define HLP_MACRLC_UL_PRBBLACK "SNR threshold to decide whether a PRB will be blacklisted or not"
|
||||
#define HLP_MACRLC_DL_BLER_UP "Upper threshold of BLER to decrease DL MCS"
|
||||
@@ -98,6 +99,7 @@
|
||||
#define HLP_MACRLC_BEAMS_PERIOD "set of beams that can be simultaneously allocated in a period"
|
||||
#define HLP_MACRLC_PUSCH_RSSI_THRESHOLD "Limits PUSCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS"
|
||||
#define HLP_MACRLC_PUCCH_RSSI_THRESHOLD "Limits PUCCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS"
|
||||
#define HLP_MACRLC_STATS_MAX_UE "Maximum number of UEs before disabling periodical output (0 to disable)"
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* MacRLC configuration parameters */
|
||||
@@ -149,6 +151,7 @@
|
||||
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, \
|
||||
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
|
||||
{CONFIG_STRING_MACRLC_STATS_MAX_UE, HLP_MACRLC_STATS_MAX_UE, 0, .iptr=NULL, .defintval=8, TYPE_INT, 0}, \
|
||||
}
|
||||
// clang-format off
|
||||
|
||||
@@ -194,6 +197,7 @@
|
||||
#define MACRLC_BEAMWEIGHTS_IDX 39
|
||||
#define MACRLC_PUSCH_RSSI_THRES_IDX 40
|
||||
#define MACRLC_PUCCH_RSSI_THRES_IDX 41
|
||||
#define MACRLC_STATS_MAX_UE_IDX 42
|
||||
|
||||
#define MACRLCPARAMS_CHECK { \
|
||||
{ .s5 = { NULL } }, \
|
||||
@@ -238,6 +242,7 @@
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s2 = { config_check_intrange, {-1280, 0}} }, /* PUSCH RSSI threshold range */ \
|
||||
{ .s2 = { config_check_intrange, {-1280, 0}} }, /* PUCCH RSSI threshold range */ \
|
||||
{ .s5 = { NULL } }, \
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -1582,6 +1582,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
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]->stats_max_ue = *MacRLC_ParamList.paramarray[j][MACRLC_STATS_MAX_UE_IDX].iptr;
|
||||
RC.nrmac[j]->print_ue_stats = RC.nrmac[j]->stats_max_ue > 0;
|
||||
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);
|
||||
|
||||
@@ -195,10 +195,23 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo
|
||||
}
|
||||
|
||||
bool wait_prach_completed = gNB->num_scheduled_prach_rx >= NUM_PRACH_RX_FOR_NOISE_ESTIMATE;
|
||||
if ((wait_prach_completed || get_softmodem_params()->phy_test) && (slot == 0) && (frame & 127) == 0) {
|
||||
if (gNB->print_ue_stats && (wait_prach_completed || get_softmodem_params()->phy_test) && (slot == 0) && (frame & 127) == 0) {
|
||||
char stats_output[32656] = {0};
|
||||
dump_mac_stats(gNB, stats_output, sizeof(stats_output), true);
|
||||
LOG_I(NR_MAC, "Frame.Slot %d.%d\n%s\n", frame, slot, stats_output);
|
||||
|
||||
// TODO: this should be replaced with a size() operation on connected_ue_list
|
||||
int num_ue = 0;
|
||||
UE_iterator(gNB->UE_info.connected_ue_list, it) {
|
||||
(void) it; // not used
|
||||
num_ue++;
|
||||
}
|
||||
if (gNB->print_ue_stats && num_ue > gNB->stats_max_ue) {
|
||||
gNB->print_ue_stats = false;
|
||||
LOG_W(NR_MAC,
|
||||
"periodical UE stats deactivated after reaching %d UEs, please check nrMAC_stats.log, or increase MACRLCs.[0].stats_max_ue\n",
|
||||
gNB->stats_max_ue);
|
||||
}
|
||||
}
|
||||
|
||||
nr_measgap_scheduling(gNB, frame, slot);
|
||||
|
||||
@@ -2119,10 +2119,9 @@ static void nr_fill_rar(uint8_t Mod_idP, NR_UE_info_t *UE, uint8_t *dlsch_buffer
|
||||
* The corresponding function to add is add_new_UE_RA(). */
|
||||
void nr_release_ra_UE(gNB_MAC_INST *mac, rnti_t rnti)
|
||||
{
|
||||
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
|
||||
NR_UEs_t *UE_info = &mac->UE_info;
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
NR_UE_info_t *UE = remove_UE_from_list(NR_NB_RA_PROC_MAX, UE_info->access_ue_list, rnti);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
if (UE) {
|
||||
delete_nr_ue_data(UE, mac->common_channels, &UE_info->uid_allocator);
|
||||
} else {
|
||||
|
||||
@@ -274,35 +274,32 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_tbs_bch(NR_sched_pdsch_t *pdsch,
|
||||
uint32_t num_total_bytes,
|
||||
uint16_t *vrb_map)
|
||||
static void update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, uint16_t *vrb_map)
|
||||
{
|
||||
NR_tda_info_t *tda_info = &pdsch->tda_info;
|
||||
const NR_tda_info_t *tda_info = &pdsch->tda_info;
|
||||
|
||||
// Calculate number of PRB_DMRS
|
||||
uint8_t N_PRB_DMRS = pdsch->dmrs_parms.N_PRB_DMRS;
|
||||
LOG_D(MAC, "dlDmrsSymbPos %x\n", pdsch->dmrs_parms.dl_dmrs_symb_pos);
|
||||
int mcsTableIdx = 0;
|
||||
uint32_t TBS = 0;
|
||||
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
|
||||
int bwpSize = pdsch->bwp_info.bwpSize;
|
||||
int bwpStart = pdsch->bwp_info.bwpStart;
|
||||
int rbStop = bwpSize - 1;
|
||||
int rbStart = 0;
|
||||
uint16_t rbSize = 0;
|
||||
while (rbStart < rbStop) {
|
||||
if (vrb_map[rbStart + bwpStart] & slbitmap)
|
||||
rbStart++;
|
||||
while (pdsch->rbStart < rbStop) {
|
||||
if (vrb_map[pdsch->rbStart + bwpStart] & slbitmap)
|
||||
pdsch->rbStart++;
|
||||
else {
|
||||
int max_rbSize = 0;
|
||||
while (rbStart + max_rbSize <= rbStop && !(vrb_map[rbStart + max_rbSize + bwpStart] & slbitmap))
|
||||
while (pdsch->rbStart + max_rbSize <= rbStop && !(vrb_map[pdsch->rbStart + max_rbSize + bwpStart] & slbitmap))
|
||||
max_rbSize++;
|
||||
|
||||
bool res = false;
|
||||
while (res == false && pdsch->mcs < 10) {
|
||||
res = nr_find_nb_rb(nr_get_Qm_dl(pdsch->mcs, mcsTableIdx),
|
||||
nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx),
|
||||
pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx);
|
||||
pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx);
|
||||
res = nr_find_nb_rb(pdsch->Qm,
|
||||
pdsch->R,
|
||||
1, // no transform precoding for DL
|
||||
1, // single layer
|
||||
tda_info->nrOfSymbols,
|
||||
@@ -310,59 +307,56 @@ static uint32_t get_tbs_bch(NR_sched_pdsch_t *pdsch,
|
||||
num_total_bytes,
|
||||
1, // min_rbSize
|
||||
max_rbSize,
|
||||
&TBS,
|
||||
&rbSize);
|
||||
&pdsch->tb_size,
|
||||
&pdsch->rbSize);
|
||||
if (!res)
|
||||
pdsch->mcs++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(TBS >= num_total_bytes,
|
||||
AssertFatal(pdsch->tb_size >= num_total_bytes,
|
||||
"Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n",
|
||||
num_total_bytes,
|
||||
rbStart,
|
||||
rbSize,
|
||||
pdsch->rbStart,
|
||||
pdsch->rbSize,
|
||||
bwpSize);
|
||||
|
||||
pdsch->rbSize = rbSize;
|
||||
pdsch->rbStart = rbStart;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"mcs=%i, startSymbolIndex = %i, nrOfSymbols = %i, rbSize = %i, TBS = %i, dmrs_length %d, N_PRB_DMRS = %d, mappingtype = %d\n",
|
||||
pdsch->mcs,
|
||||
tda_info->startSymbolIndex,
|
||||
tda_info->nrOfSymbols,
|
||||
rbSize,
|
||||
TBS,
|
||||
pdsch->rbSize,
|
||||
pdsch->tb_size,
|
||||
pdsch->dmrs_parms.N_DMRS_SLOT,
|
||||
N_PRB_DMRS,
|
||||
tda_info->mapping_type);
|
||||
return TBS;
|
||||
}
|
||||
|
||||
static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
int CC_id,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
int time_domain_allocation,
|
||||
NR_pdsch_dmrs_t *dmrs_parms,
|
||||
NR_tda_info_t *tda_info,
|
||||
uint8_t candidate_idx,
|
||||
int beam,
|
||||
uint16_t num_total_bytes)
|
||||
static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
int CC_id,
|
||||
NR_sched_pdcch_t *pdcch,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
int time_domain_allocation,
|
||||
NR_pdsch_dmrs_t *dmrs_parms,
|
||||
NR_tda_info_t *tda_info,
|
||||
uint8_t candidate_idx,
|
||||
int beam,
|
||||
uint16_t num_total_bytes)
|
||||
{
|
||||
AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n");
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id];
|
||||
uint16_t *vrb_map = cc->vrb_map[beam];
|
||||
NR_sched_pdsch_t *pdsch = &gNB_mac->sched_ctrlCommon->sched_pdsch;
|
||||
pdsch->bwp_info = get_pdsch_bwp_start_size(gNB_mac, NULL);
|
||||
pdsch->time_domain_allocation = time_domain_allocation;
|
||||
pdsch->dmrs_parms = *dmrs_parms;
|
||||
pdsch->tda_info = *tda_info;
|
||||
pdsch->nrOfLayers = 1;
|
||||
pdsch->pm_index = 0;
|
||||
pdsch->mcs = 0; // starting from mcs 0
|
||||
NR_sched_pdsch_t pdsch = {
|
||||
.bwp_info = get_pdsch_bwp_start_size(gNB_mac, NULL),
|
||||
.time_domain_allocation = time_domain_allocation,
|
||||
.dmrs_parms = *dmrs_parms,
|
||||
.tda_info = *tda_info,
|
||||
.nrOfLayers = 1,
|
||||
.pm_index = 0,
|
||||
.mcs = 0, // starting from mcs 0
|
||||
};
|
||||
gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;
|
||||
|
||||
uint8_t nr_of_candidates = 0;
|
||||
@@ -383,12 +377,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
|
||||
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
|
||||
|
||||
uint32_t TBS = get_tbs_bch(&gNB_mac->sched_ctrlCommon->sched_pdsch,
|
||||
gNB_mac->sched_ctrlCommon->num_total_bytes,
|
||||
vrb_map);
|
||||
|
||||
pdsch->R = nr_get_code_rate_dl(pdsch->mcs, 0);
|
||||
pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, 0);
|
||||
update_rb_mcs_tbs(&pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
fill_pdcch_vrb_map(gNB_mac,
|
||||
@@ -397,10 +386,10 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac,
|
||||
gNB_mac->sched_ctrlCommon->cce_index,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
beam);
|
||||
for (int rb = 0; rb < pdsch->rbSize; rb++) {
|
||||
for (int rb = 0; rb < pdsch.rbSize; rb++) {
|
||||
vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
|
||||
}
|
||||
return TBS;
|
||||
return pdsch;
|
||||
}
|
||||
|
||||
static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac,
|
||||
@@ -578,22 +567,21 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
|
||||
NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0];
|
||||
// Configure sched_ctrlCommon for SIB1
|
||||
uint32_t TBS = schedule_control_sib1(gNB_mac,
|
||||
CC_id,
|
||||
&sched_pdcch,
|
||||
type0_PDCCH_CSS_config,
|
||||
time_domain_allocation,
|
||||
&dmrs_parms,
|
||||
&tda_info,
|
||||
candidate_idx,
|
||||
beam.idx,
|
||||
cc->sib1_bcch_length);
|
||||
NR_sched_pdsch_t sched_pdsch = schedule_control_sib1(gNB_mac,
|
||||
CC_id,
|
||||
&sched_pdcch,
|
||||
type0_PDCCH_CSS_config,
|
||||
time_domain_allocation,
|
||||
&dmrs_parms,
|
||||
&tda_info,
|
||||
candidate_idx,
|
||||
beam.idx,
|
||||
cc->sib1_bcch_length);
|
||||
|
||||
gNB_mac->sched_ctrlCommon->sched_pdsch.tb_size = TBS;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
int pdu_index = gNB_mac->pdu_index[0]++;
|
||||
nr_fill_nfapi_dl_SIB_pdu(gNB_mac,
|
||||
&gNB_mac->sched_ctrlCommon->sched_pdsch,
|
||||
&sched_pdsch,
|
||||
&sched_pdcch,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
@@ -609,11 +597,11 @@ void schedule_nr_sib1(module_id_t module_idP,
|
||||
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req];
|
||||
|
||||
// Data to be transmitted
|
||||
memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, TBS);
|
||||
memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, sched_pdsch.tb_size);
|
||||
|
||||
tx_req->PDU_index = pdu_index;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS;
|
||||
tx_req->TLVs[0].length = sched_pdsch.tb_size;
|
||||
tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length);
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->SFN = frameP;
|
||||
@@ -718,9 +706,7 @@ static void other_sib_sched_control(module_id_t module_idP,
|
||||
uint16_t *vrb_map = cc->vrb_map[beam.idx];
|
||||
uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx];
|
||||
int num_total_bytes = cc->other_sib_bcch_length[payload_idx];
|
||||
sched_pdsch_otherSI.tb_size = get_tbs_bch(&sched_pdsch_otherSI, num_total_bytes, vrb_map);
|
||||
sched_pdsch_otherSI.R = nr_get_code_rate_dl(sched_pdsch_otherSI.mcs, 0);
|
||||
sched_pdsch_otherSI.Qm = nr_get_Qm_dl(sched_pdsch_otherSI.mcs, 0);
|
||||
update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map);
|
||||
|
||||
for (int rb = 0; rb < sched_pdsch_otherSI.rbSize; rb++) {
|
||||
vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
@@ -747,10 +733,10 @@ static void other_sib_sched_control(module_id_t module_idP,
|
||||
// Data to be transmitted
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib_bcch_pdu, sched_pdsch_otherSI.tb_size);
|
||||
|
||||
tx_req->PDU_length = sched_pdsch_otherSI.tb_size;
|
||||
tx_req->PDU_index = pdu_index;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = sched_pdsch_otherSI.tb_size + 2;
|
||||
tx_req->TLVs[0].length = sched_pdsch_otherSI.tb_size;
|
||||
tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length);
|
||||
TX_req->Number_of_PDUs++;
|
||||
TX_req->SFN = frame;
|
||||
TX_req->Slot = slot;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,9 +55,11 @@ uint32_t target_dl_bw = 50;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
|
||||
/* schedules whole bandwidth for first user, all the time */
|
||||
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
frame_t frame = pp_pdsch->frame;
|
||||
slot_t slot = pp_pdsch->slot;
|
||||
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
int slot_period = slot % mac->frame_structure.numb_slots_period;
|
||||
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot_period))
|
||||
@@ -86,9 +88,6 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
if(!tda_info.valid_tda)
|
||||
return;
|
||||
|
||||
sched_ctrl->sched_pdsch.tda_info = tda_info;
|
||||
sched_ctrl->sched_pdsch.time_domain_allocation = tda;
|
||||
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = dl_bwp->BWPSize;
|
||||
const int BWPStart = dl_bwp->BWPStart;
|
||||
@@ -142,12 +141,11 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
0);
|
||||
AssertFatal(CCEIndex >= 0, "Could not find CCE for UE %04x\n", UE->rnti);
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
if (sched_pdsch->dl_harq_pid == -1)
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||
|
||||
int alloc = -1;
|
||||
if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) {
|
||||
int harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
if (harq_pid < 0)
|
||||
harq_pid = sched_ctrl->available_dl_harq.head;
|
||||
if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, harq_pid)) {
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex);
|
||||
alloc = nr_acknack_scheduling(mac, UE, frame, slot, 0, r_pucch, 0);
|
||||
if (alloc < 0) {
|
||||
@@ -165,42 +163,38 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
sched_ctrl->aggregation_level,
|
||||
beam);
|
||||
|
||||
//AssertFatal(alloc,
|
||||
// "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
|
||||
// rnti, frame, slot);
|
||||
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
sched_pdsch->rbStart = rbStart;
|
||||
sched_pdsch->rbSize = rbSize;
|
||||
sched_pdsch->bwp_info = get_pdsch_bwp_start_size(mac, UE);
|
||||
sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc,
|
||||
dl_bwp,
|
||||
&tda_info,
|
||||
target_dl_Nl);
|
||||
|
||||
sched_pdsch->mcs = target_dl_mcs;
|
||||
sched_pdsch->nrOfLayers = target_dl_Nl;
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx);
|
||||
NR_sched_pdsch_t sched_pdsch = {
|
||||
.rbSize = rbSize,
|
||||
.rbStart = rbStart,
|
||||
.mcs = target_dl_mcs,
|
||||
.R = nr_get_code_rate_dl(target_dl_mcs, dl_bwp->mcsTableIdx),
|
||||
.Qm = nr_get_Qm_dl(target_dl_mcs, dl_bwp->mcsTableIdx),
|
||||
// tbSize further below
|
||||
.dl_harq_pid = sched_ctrl->retrans_dl_harq.head, // PID of HARQ awaiting retransmission, or -1 otherwise
|
||||
.pucch_allocation = alloc,
|
||||
.pm_index = 0,
|
||||
.nrOfLayers = target_dl_Nl,
|
||||
.bwp_info = get_pdsch_bwp_start_size(mac, UE),
|
||||
.dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, target_dl_Nl),
|
||||
.time_domain_allocation = tda,
|
||||
.tda_info = tda_info,
|
||||
};
|
||||
sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */
|
||||
sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
|
||||
sched_pdsch->R,
|
||||
sched_pdsch->rbSize,
|
||||
tda_info.nrOfSymbols,
|
||||
sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT,
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
sched_pdsch->nrOfLayers)
|
||||
>> 3;
|
||||
sched_pdsch.tb_size = nr_compute_tbs(sched_pdsch.Qm,
|
||||
sched_pdsch.R,
|
||||
sched_pdsch.rbSize,
|
||||
tda_info.nrOfSymbols,
|
||||
sched_pdsch.dmrs_parms.N_PRB_DMRS * sched_pdsch.dmrs_parms.N_DMRS_SLOT,
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
target_dl_Nl)
|
||||
>> 3;
|
||||
|
||||
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
post_process_dlsch(mac, pp_pdsch, UE, &sched_pdsch);
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
|
||||
if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize);
|
||||
for (int rb = 0; rb < sched_pdsch.rbSize; rb++)
|
||||
vrb_map[rb + sched_pdsch.rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
|
||||
}
|
||||
|
||||
uint32_t target_ul_mcs = 9;
|
||||
|
||||
@@ -2974,9 +2974,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->ta_update = 31;
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->sched_pdsch.time_domain_allocation = -1;
|
||||
|
||||
/* Set default BWPs */
|
||||
AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp);
|
||||
|
||||
@@ -3033,18 +3030,17 @@ bool transition_ra_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
* To remove the UE, use mac_remove_nr_ue(). */
|
||||
bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
{
|
||||
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
|
||||
|
||||
LOG_I(NR_MAC, "Adding new UE context with RNTI 0x%04x\n", UE->rnti);
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
dump_nr_list(UE_info->connected_ue_list);
|
||||
AssertFatal(!UE->ra, "UE in connected cannot have RA process\n");
|
||||
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
|
||||
bool success = add_UE_to_list(MAX_MOBILES_PER_GNB, UE_info->connected_ue_list, UE);
|
||||
if (!success) {
|
||||
LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", UE->rnti);
|
||||
delete_nr_ue_data(UE, NULL, &UE_info->uid_allocator);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3057,7 +3053,6 @@ bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
init_bler_stats(&nr_mac->dl_bler, &sched_ctrl->dl_bler_stats, nr_mac->frame);
|
||||
init_bler_stats(&nr_mac->ul_bler, &sched_ctrl->ul_bler_stats, nr_mac->frame);
|
||||
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
dump_nr_list(UE_info->connected_ue_list);
|
||||
return true;
|
||||
}
|
||||
@@ -3110,9 +3105,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
|
||||
/* already mutex protected */
|
||||
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
NR_SCHED_LOCK(&UE_info->mutex);
|
||||
NR_UE_info_t *UE = remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, UE_info->connected_ue_list, rnti);
|
||||
NR_SCHED_UNLOCK(&UE_info->mutex);
|
||||
if (UE)
|
||||
delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator);
|
||||
else
|
||||
|
||||
@@ -678,6 +678,8 @@ static void evaluate_cqi_report(uint8_t *payload,
|
||||
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);
|
||||
|
||||
LOG_D(MAC, "Reported CQI = %d, dl_max_mcs %d\n", temp_cqi, sched_ctrl->dl_max_mcs);
|
||||
}
|
||||
|
||||
static uint8_t evaluate_pmi_report(uint8_t *payload,
|
||||
|
||||
@@ -1834,6 +1834,10 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols);
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap))
|
||||
rbStart++;
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot);
|
||||
return false;
|
||||
}
|
||||
int rbSize = 0;
|
||||
while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap))
|
||||
rbSize++;
|
||||
@@ -1909,7 +1913,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t ul_pf_tbs[5][29]; // pre-computed, approximate TBS values for PF coefficient
|
||||
typedef struct UEsched_s {
|
||||
float coef;
|
||||
bool sched_inactive;
|
||||
@@ -2065,8 +2068,8 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
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) {
|
||||
int nrOfLayers = get_ul_nrOfLayers(sched_ctrl, current_BWP->dci_format);
|
||||
selected_mcs = get_mcs_from_SINRx10(current_BWP->mcs_table, sched_ctrl->pusch_snrx10, nrOfLayers);
|
||||
selected_mcs = min(max_mcs, selected_mcs);
|
||||
selected_mcs = max(bo->min_mcs, selected_mcs);
|
||||
@@ -2078,7 +2081,17 @@ static int pf_ul(gNB_MAC_INST *nrmac,
|
||||
|
||||
/* Create UE_sched for UEs eligibale for new data transmission*/
|
||||
/* Calculate coefficient*/
|
||||
const uint32_t tbs = ul_pf_tbs[current_BWP->mcs_table][selected_mcs];
|
||||
const uint8_t Qm = nr_get_Qm_dl(selected_mcs, current_BWP->mcs_table);
|
||||
const uint16_t R = nr_get_code_rate_dl(selected_mcs, current_BWP->mcs_table);
|
||||
const uint32_t tbs = nr_compute_tbs(Qm,
|
||||
R,
|
||||
1, /* rbSize */
|
||||
10, /* hypothetical number of slots */
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
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",
|
||||
@@ -2703,32 +2716,6 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp
|
||||
|
||||
nr_pp_impl_ul nr_init_ulsch_preprocessor(int CC_id)
|
||||
{
|
||||
/* during initialization: no mutex needed */
|
||||
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
|
||||
* This would include the number of DMRS symbols, which in turn depends on
|
||||
* the time domain allocation. In case we are in a mixed slot, we do not want
|
||||
* to recalculate all these values, and therefore we provide a look-up table
|
||||
* which should approximately(!) give us the TBsize. In particular, the
|
||||
* number of symbols, the number of DMRS symbols, and the exact Qm and R, are
|
||||
* not correct*/
|
||||
for (int mcsTableIdx = 0; mcsTableIdx < 5; ++mcsTableIdx) {
|
||||
for (int mcs = 0; mcs < 29; ++mcs) {
|
||||
if (mcs > 27 && (mcsTableIdx == 1 || mcsTableIdx == 3 || mcsTableIdx == 4))
|
||||
continue;
|
||||
const uint8_t Qm = nr_get_Qm_ul(mcs, mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_ul(mcs, mcsTableIdx);
|
||||
/* note: we do not update R/Qm based on low MCS or pi2BPSK */
|
||||
ul_pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
|
||||
R,
|
||||
1, /* rbSize */
|
||||
10, /* hypothetical number of slots */
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
}
|
||||
}
|
||||
return nr_ulsch_preprocessor;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
|
||||
|
||||
/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all
|
||||
* freq resources */
|
||||
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot);
|
||||
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch);
|
||||
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
|
||||
* fixed set of resources */
|
||||
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
|
||||
@@ -504,5 +504,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac,
|
||||
|
||||
void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group);
|
||||
|
||||
void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch);
|
||||
void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch);
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -87,7 +87,6 @@ void *nrmac_stats_thread(void *arg) {
|
||||
char *p = output;
|
||||
NR_SCHED_LOCK(&gNB->sched_lock);
|
||||
p += dump_mac_stats(gNB, p, end - p, false);
|
||||
NR_SCHED_UNLOCK(&gNB->sched_lock);
|
||||
p += snprintf(p, end - p, "\n");
|
||||
p += print_meas_log(&gNB->gNB_scheduler, "gNB_scheduler", NULL, NULL, p, end - p);
|
||||
p += print_meas_log(&gNB->rx_ulsch_sdu, "rx_ulsch_sdu", NULL, NULL, p, end - p);
|
||||
@@ -97,10 +96,17 @@ void *nrmac_stats_thread(void *arg) {
|
||||
p += print_meas_log(&gNB->rlc_data_req, "rlc_data_req", NULL, NULL, p, end - p);
|
||||
p += print_meas_log(&gNB->nr_srs_ri_computation_timer, "UL-RI computation time", NULL, NULL, p, end - p);
|
||||
p += print_meas_log(&gNB->nr_srs_tpmi_computation_timer, "UL-TPMI computation time", NULL, NULL, p, end - p);
|
||||
fwrite(output, p - output, 1, file);
|
||||
fflush(file);
|
||||
NR_SCHED_UNLOCK(&gNB->sched_lock);
|
||||
size_t len = p - output;
|
||||
if (fwrite(output, len, 1, file) != 1 || fflush(file) != 0) {
|
||||
LOG_E(NR_MAC, "error while writing nrMAC_stats.log: %d, %s\n", errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
fseek(file,0,SEEK_SET);
|
||||
if (ftruncate(fileno(file), 0) != 0 || fseek(file, 0, SEEK_SET) != 0) {
|
||||
LOG_E(NR_MAC, "error while writing nrMAC_stats.log: %d, %s\n", errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
return NULL;
|
||||
@@ -112,6 +118,19 @@ void clear_mac_stats(gNB_MAC_INST *gNB) {
|
||||
}
|
||||
}
|
||||
|
||||
static char *st_append(char *start, const char *end, const char *format, ...)
|
||||
{
|
||||
size_t space = end - start;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
size_t written = vsnprintf(start, space, format, args);
|
||||
va_end(args);
|
||||
if (written <= space)
|
||||
return start + written;
|
||||
else
|
||||
return (char *)end;
|
||||
}
|
||||
|
||||
size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp)
|
||||
{
|
||||
const char *begin = output;
|
||||
@@ -121,46 +140,45 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
* scheduler to be locked*/
|
||||
NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock);
|
||||
|
||||
NR_SCHED_LOCK(&gNB->UE_info.mutex);
|
||||
UE_iterator(gNB->UE_info.connected_ue_list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
|
||||
const int avg_sinrx10 = stats->num_sinr_meas > 0 ? stats->cumul_sinrx10 / stats->num_sinr_meas : 0;
|
||||
|
||||
output += snprintf(output, end - output, "UE RNTI %04x CU-UE-ID ", UE->rnti);
|
||||
output = st_append(output, end, "UE RNTI %04x CU-UE-ID ", UE->rnti);
|
||||
if (du_exists_f1_ue_data(UE->rnti)) {
|
||||
f1_ue_data_t ued = du_get_f1_ue_data(UE->rnti);
|
||||
output += snprintf(output, end - output, "%d", ued.secondary_ue);
|
||||
output = st_append(output, end, "%d", ued.secondary_ue);
|
||||
} else {
|
||||
output += snprintf(output, end - output, "(none)");
|
||||
output = st_append(output, end, "(none)");
|
||||
}
|
||||
|
||||
bool in_sync = !sched_ctrl->ul_failure;
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
" %s PH %d dB PCMAX %d dBm",
|
||||
in_sync ? "in-sync" : "out-of-sync",
|
||||
sched_ctrl->ph,
|
||||
sched_ctrl->pcmax);
|
||||
|
||||
if (stats->num_rsrp_meas)
|
||||
output += snprintf(output, end - output, ", average RSRP %d (%d meas)", avg_rsrp, stats->num_rsrp_meas);
|
||||
output = st_append(output, end, ", average RSRP %d (%d meas)", avg_rsrp, stats->num_rsrp_meas);
|
||||
|
||||
if (stats->num_sinr_meas) {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
", average SINR %d.%d (%d meas)",
|
||||
avg_sinrx10 / 10,
|
||||
avg_sinrx10 % 10,
|
||||
stats->num_sinr_meas);
|
||||
}
|
||||
|
||||
output += snprintf(output, end - output, "\n");
|
||||
output = st_append(output, end, "\n");
|
||||
|
||||
if(sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report)
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
|
||||
UE->rnti,
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||
@@ -169,18 +187,18 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||
|
||||
if (stats->srs_stats[0] != '\0') {
|
||||
output += snprintf(output, end - output, "UE %04x: %s\n", UE->rnti, stats->srs_stats);
|
||||
output = st_append(output, end, "UE %04x: %s\n", UE->rnti, stats->srs_stats);
|
||||
}
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
"UE %04x: dlsch_rounds ", UE->rnti);
|
||||
output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]);
|
||||
output = st_append(output, end, "%"PRIu64, stats->dl.rounds[0]);
|
||||
for (int i = 1; i < gNB->dl_bler.harq_round_max; i++)
|
||||
output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]);
|
||||
output = st_append(output, end, "/%"PRIu64, stats->dl.rounds[i]);
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS (%d) %d CCE fail %d\n",
|
||||
stats->dl.errors,
|
||||
stats->pucch0_DTX,
|
||||
@@ -194,15 +212,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
stats->num_sinr_meas = 0;
|
||||
stats->cumul_sinrx10 = 0;
|
||||
}
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
"UE %04x: ulsch_rounds ", UE->rnti);
|
||||
output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]);
|
||||
output = st_append(output, end, "%"PRIu64, stats->ul.rounds[0]);
|
||||
for (int i = 1; i < gNB->ul_bler.harq_round_max; i++)
|
||||
output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]);
|
||||
output = st_append(output, end, "/%"PRIu64, stats->ul.rounds[i]);
|
||||
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
", ulsch_errors %"PRIu64", ulsch_DTX %d, BLER %.5f MCS (%d) %d (Qm %d deltaMCS %d dB) NPRB %d SNR %d.%d dB CCE fail %d\n",
|
||||
stats->ul.errors,
|
||||
stats->ulsch_DTX,
|
||||
@@ -215,15 +233,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
sched_ctrl->pusch_snrx10 / 10,
|
||||
sched_ctrl->pusch_snrx10 % 10,
|
||||
sched_ctrl->ul_cce_fail);
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
"UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
||||
UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes);
|
||||
|
||||
for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); i++) {
|
||||
const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i);
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
output = st_append(output,
|
||||
end,
|
||||
"UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n",
|
||||
UE->rnti,
|
||||
c->lcid,
|
||||
@@ -231,7 +249,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset
|
||||
stats->ul.lc_bytes[c->lcid]);
|
||||
}
|
||||
}
|
||||
NR_SCHED_UNLOCK(&gNB->UE_info.mutex);
|
||||
DevAssert(output <= end);
|
||||
return output - begin;
|
||||
}
|
||||
|
||||
@@ -296,9 +314,10 @@ void mac_top_init_gNB(ngran_node_t node_type,
|
||||
RC.nrmac[i]->cset0_bwp_start = 0;
|
||||
RC.nrmac[i]->cset0_bwp_size = 0;
|
||||
|
||||
RC.nrmac[i]->print_ue_stats = true;
|
||||
|
||||
pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL);
|
||||
|
||||
pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL);
|
||||
uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator);
|
||||
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
|
||||
@@ -639,8 +639,6 @@ typedef struct {
|
||||
/// PHR info: nominal UE transmit power levels (dBm)
|
||||
int pcmax;
|
||||
|
||||
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
|
||||
NR_sched_pdsch_t sched_pdsch;
|
||||
/// UE-estimated maximum MCS (from CSI-RS)
|
||||
uint8_t dl_max_mcs;
|
||||
|
||||
@@ -803,7 +801,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
/// scheduling control info
|
||||
// last element always NULL
|
||||
pthread_mutex_t mutex;
|
||||
NR_UE_info_t *connected_ue_list[MAX_MOBILES_PER_GNB + 1];
|
||||
NR_UE_info_t *access_ue_list[NR_NB_RA_PROC_MAX + 1];
|
||||
// bitmap of CSI-RS already scheduled in current slot
|
||||
@@ -826,7 +823,18 @@ typedef struct {
|
||||
nr_beam_mode_t beam_mode;
|
||||
} NR_beam_info_t;
|
||||
|
||||
#define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
|
||||
#define UE_iterator(BaSe, VaR) for (NR_UE_info_t **VaR##pptr=BaSe, *VaR=*VaR##pptr; VaR; VaR=*(++VaR##pptr))
|
||||
|
||||
typedef struct {
|
||||
/// current frame
|
||||
frame_t frame;
|
||||
/// current slot
|
||||
slot_t slot;
|
||||
/// FAPI DL req in which allocations are made
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req;
|
||||
/// TX_data request holds the actual data
|
||||
nfapi_nr_tx_data_request_t *TX_req;
|
||||
} post_process_pdsch_t;
|
||||
|
||||
typedef struct {
|
||||
/// current frame for DCI
|
||||
@@ -843,7 +851,7 @@ typedef struct {
|
||||
struct gNB_MAC_INST_s;
|
||||
typedef struct gNB_MAC_INST_s gNB_MAC_INST;
|
||||
|
||||
typedef void (*nr_pp_impl_dl)(module_id_t mod_id, frame_t frame, slot_t slot);
|
||||
typedef void (*nr_pp_impl_dl)(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch);
|
||||
typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
|
||||
|
||||
typedef struct f1_config_t {
|
||||
@@ -981,6 +989,11 @@ typedef struct gNB_MAC_INST_s {
|
||||
f1_config_t f1_config;
|
||||
int16_t frame;
|
||||
|
||||
/// number of UEs to exceed to disable stats
|
||||
int stats_max_ue;
|
||||
/// if stats are currently enabled
|
||||
bool print_ue_stats;
|
||||
|
||||
pthread_mutex_t sched_lock;
|
||||
|
||||
mac_stats_t mac_stats;
|
||||
|
||||
Reference in New Issue
Block a user