mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-15 13:40:29 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2837f1279 | ||
|
|
b5fdc16e17 | ||
|
|
fc488c0f55 | ||
|
|
d1af0775ee | ||
|
|
74003a9333 | ||
|
|
a9d1b78125 | ||
|
|
a2f2d41e39 | ||
|
|
4d1fd9c9ae |
@@ -373,6 +373,277 @@ uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) {
|
||||
}
|
||||
}
|
||||
|
||||
void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
LOG_D(MAC,
|
||||
"%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n",
|
||||
frame,
|
||||
slot,
|
||||
lcid,
|
||||
sched_ctrl->rlc_status[lcid].bytes_in_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool find_free_CCE(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
NR_UE_info_t *UE_info,
|
||||
int UE_id){
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id);
|
||||
return false;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allocate_retransmission(module_id_t module_id,
|
||||
uint8_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
NR_UE_info_t *UE_info,
|
||||
int UE_id){
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
|
||||
|
||||
/* ensure that there is a free place for RB allocation */
|
||||
int rbSize = 0;
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_E(MAC,
|
||||
"cannot allocate retransmission for UE %d/RNTI %04x: no resources\n",
|
||||
UE_id,
|
||||
rnti);
|
||||
return false;
|
||||
}
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& rballoc_mask[rbStart + rbSize]
|
||||
&& rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
sched_ctrl->rbSize = retInfo->rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
|
||||
/* MCS etc: just reuse from previous scheduling opportunity */
|
||||
sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
|
||||
sched_ctrl->mcs = retInfo->mcs;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
|
||||
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= sched_ctrl->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
|
||||
rballoc_mask[rb+sched_ctrl->rbStart] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
float thr_ue[MAX_MOBILES_PER_GNB];
|
||||
|
||||
void pf_dl(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
NR_UE_info_t *UE_info,
|
||||
int n_rb_sched,
|
||||
uint8_t *rballoc_mask,
|
||||
int max_num_ue) {
|
||||
|
||||
float coeff_ue[MAX_MOBILES_PER_GNB];
|
||||
NR_UE_list_t UE_sched; // UEs that could be scheduled
|
||||
int *uep = &UE_sched.head;
|
||||
|
||||
/* Loop UE_info->list to check retransmission */
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
|
||||
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
|
||||
|
||||
/* retransmission */
|
||||
if (harq->round != 0) {
|
||||
/* Find a free CCE */
|
||||
bool freeCCEE = find_free_CCE(module_id, slot, UE_info, UE_id);
|
||||
if (!freeCCEE)
|
||||
continue;
|
||||
/* Find PUCCH occasion */
|
||||
nr_acknack_scheduling(module_id,
|
||||
UE_id,
|
||||
frame,
|
||||
slot,
|
||||
num_slots_per_tdd,
|
||||
&sched_ctrl->pucch_sched_idx,
|
||||
&sched_ctrl->pucch_occ_idx);
|
||||
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
/* Allocate retransmission */
|
||||
bool r = allocate_retransmission(module_id, rballoc_mask, &n_rb_sched, UE_info, UE_id);
|
||||
} else {
|
||||
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
||||
if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
|
||||
continue;
|
||||
|
||||
/* Calculate coeff */
|
||||
sched_ctrl->time_domain_allocation = 2;
|
||||
sched_ctrl->mcsTableIdx = 0;
|
||||
sched_ctrl->mcs = 9;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = 1;
|
||||
uint8_t N_PRB_DMRS =
|
||||
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
|
||||
int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
|
||||
sched_ctrl->time_domain_allocation);
|
||||
uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
1, // rbSize
|
||||
nrOfSymbols,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the
|
||||
// number of dmrs symbols
|
||||
0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
|
||||
LOG_I(MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
|
||||
b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
|
||||
|
||||
/* Create UE_sched list for transmission*/
|
||||
*uep = UE_id;
|
||||
uep = &UE_sched.next[UE_id];
|
||||
}
|
||||
}
|
||||
*uep = -1;
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (max_num_ue > 0 && n_rb_sched > 0 && UE_sched.head >= 0) {
|
||||
|
||||
/* Find max coeff from UE_sched*/
|
||||
int *max = &UE_sched.head; /* assume head is max */
|
||||
int *p = &UE_sched.next[*max];
|
||||
while (*p >= 0) {
|
||||
/* if the current one has larger coeff, save for later */
|
||||
if (coeff_ue[*p] > coeff_ue[*max])
|
||||
max = p;
|
||||
p = &UE_sched.next[*p];
|
||||
}
|
||||
/* remove the max one */
|
||||
const int UE_id = *max;
|
||||
p = &UE_sched.next[*max];
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
/* Find a free CCE */
|
||||
bool freeCCEE = find_free_CCE(module_id, slot, UE_info, UE_id);
|
||||
if (!freeCCEE)
|
||||
continue;
|
||||
|
||||
max_num_ue--;
|
||||
|
||||
/* Find PUCCH occasion */
|
||||
nr_acknack_scheduling(module_id,
|
||||
UE_id,
|
||||
frame,
|
||||
slot,
|
||||
num_slots_per_tdd,
|
||||
&sched_ctrl->pucch_sched_idx,
|
||||
&sched_ctrl->pucch_occ_idx);
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
|
||||
/* Allocate transmission */
|
||||
// Time-domain allocation
|
||||
sched_ctrl->time_domain_allocation = 2;
|
||||
|
||||
// modulation scheme
|
||||
sched_ctrl->mcsTableIdx = 0;
|
||||
sched_ctrl->mcs = 9;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = 1;
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
|
||||
uint8_t N_PRB_DMRS =
|
||||
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
|
||||
int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
|
||||
sched_ctrl->time_domain_allocation);
|
||||
|
||||
int rbSize = 0;
|
||||
uint32_t TBS = 0;
|
||||
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
|
||||
+ 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
do {
|
||||
rbSize++;
|
||||
TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
rbSize,
|
||||
nrOfSymbols,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the
|
||||
// number of dmrs symbols
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
} while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh);
|
||||
sched_ctrl->rbSize = rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched -= sched_ctrl->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
|
||||
rballoc_mask[rb+sched_ctrl->rbStart] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
@@ -391,144 +662,28 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
if (sched_ctrl->num_total_bytes == 0
|
||||
&& !sched_ctrl->ta_apply) /* If TA should be applied, give at least one RB */
|
||||
return;
|
||||
LOG_D(MAC,
|
||||
"%d.%d, DTCH%d->DLSCH, RLC status %d bytes TA %d\n",
|
||||
frame,
|
||||
slot,
|
||||
lcid,
|
||||
sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
sched_ctrl->ta_apply);
|
||||
|
||||
/* Find a free CCE */
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id);
|
||||
return;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
/* Find PUCCH occasion */
|
||||
nr_acknack_scheduling(module_id,
|
||||
UE_id,
|
||||
frame,
|
||||
slot,
|
||||
num_slots_per_tdd,
|
||||
&sched_ctrl->pucch_sched_idx,
|
||||
&sched_ctrl->pucch_occ_idx);
|
||||
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
/* Calculate num of RBG and RBG size from UE_id=0 */
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
if (harq->round != 0) { /* retransmission */
|
||||
sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
|
||||
|
||||
/* ensure that there is a free place for RB allocation */
|
||||
int rbSize = 0;
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_E(MAC,
|
||||
"cannot allocate retransmission for UE %d/RNTI %04x: no resources\n",
|
||||
UE_id,
|
||||
rnti);
|
||||
return;
|
||||
}
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& !vrb_map[rbStart + rbSize]
|
||||
&& rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
sched_ctrl->rbSize = retInfo->rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
|
||||
/* MCS etc: just reuse from previous scheduling opportunity */
|
||||
sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
|
||||
sched_ctrl->mcs = retInfo->mcs;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
|
||||
} else {
|
||||
// Time-domain allocation
|
||||
sched_ctrl->time_domain_allocation = 2;
|
||||
|
||||
// modulation scheme
|
||||
sched_ctrl->mcsTableIdx = 0;
|
||||
sched_ctrl->mcs = 9;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = 1;
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
|
||||
|
||||
uint8_t N_PRB_DMRS =
|
||||
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
|
||||
int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
|
||||
sched_ctrl->time_domain_allocation);
|
||||
|
||||
int rbSize = 0;
|
||||
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
|
||||
+ 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
uint32_t TBS = 0;
|
||||
do {
|
||||
rbSize++;
|
||||
TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
rbSize,
|
||||
nrOfSymbols,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the
|
||||
// number of dmrs symbols
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
} while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh);
|
||||
sched_ctrl->rbSize = rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
uint8_t rballoc_mask[bwpSize];
|
||||
int n_rb_sched = 0;
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
// calculate mask: init with "NOT" vrb_map:
|
||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||
rballoc_mask[i] = !vrb_map[i];
|
||||
n_rb_sched += rballoc_mask[i];
|
||||
}
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
|
||||
vrb_map[rb + sched_ctrl->rbStart] = 1;
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
nr_store_dlsch_buffer(module_id, frame, slot);
|
||||
|
||||
/* proportional fair scheduling algorithm */
|
||||
pf_dl(module_id, frame, slot, num_slots_per_tdd,
|
||||
UE_info,
|
||||
n_rb_sched,
|
||||
rballoc_mask,
|
||||
2);
|
||||
}
|
||||
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
@@ -546,6 +701,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
NR_UE_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
|
||||
|
||||
/* update TA and set ta_apply every 10 frames.
|
||||
* Possible improvement: take the periodicity from input file.
|
||||
@@ -708,6 +864,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
|
||||
|
||||
const int post_padding = TBS > header_length_total + sdu_length_total + ta_len;
|
||||
|
||||
@@ -399,6 +399,7 @@ typedef struct {
|
||||
int dlsch_rounds[8];
|
||||
int dlsch_errors;
|
||||
int dlsch_total_bytes;
|
||||
int dlsch_current_bytes;
|
||||
int ulsch_rounds[8];
|
||||
int ulsch_errors;
|
||||
int ulsch_total_bytes_scheduled;
|
||||
|
||||
Reference in New Issue
Block a user