mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 05:00:31 +00:00
Compare commits
20 Commits
pre-commit
...
nr_ul_pf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15bc7f17db | ||
|
|
8e553e242e | ||
|
|
b92aa08410 | ||
|
|
b7a0c5b9fa | ||
|
|
edf88b61fa | ||
|
|
f8753c515c | ||
|
|
9f17c2d95f | ||
|
|
fdd8a99fbd | ||
|
|
46d2e6988a | ||
|
|
30df8203f1 | ||
|
|
ae8c8cf54a | ||
|
|
2a70fcea00 | ||
|
|
9e6b73999c | ||
|
|
e4674b885f | ||
|
|
7d3623a691 | ||
|
|
95c20b7326 | ||
|
|
8ff9015347 | ||
|
|
cbff1c56aa | ||
|
|
1a68dbd8da | ||
|
|
6a5df2bdd3 |
@@ -102,22 +102,22 @@ typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
|
||||
|
||||
// Long BSR for all logical channel group ID
|
||||
typedef struct {
|
||||
uint8_t Buffer_size7: 8;
|
||||
uint8_t Buffer_size6: 8;
|
||||
uint8_t Buffer_size5: 8;
|
||||
uint8_t Buffer_size4: 8;
|
||||
uint8_t Buffer_size3: 8;
|
||||
uint8_t Buffer_size2: 8;
|
||||
uint8_t Buffer_size1: 8;
|
||||
uint8_t Buffer_size0: 8;
|
||||
uint8_t LcgID0: 1;
|
||||
uint8_t LcgID1: 1;
|
||||
uint8_t LcgID2: 1;
|
||||
uint8_t LcgID3: 1;
|
||||
uint8_t LcgID4: 1;
|
||||
uint8_t LcgID5: 1;
|
||||
uint8_t LcgID6: 1;
|
||||
uint8_t LcgID7: 1;
|
||||
uint8_t LcgID0: 1; // octet 1 [0]
|
||||
uint8_t LcgID1: 1; // octet 1 [1]
|
||||
uint8_t LcgID2: 1; // octet 1 [2]
|
||||
uint8_t LcgID3: 1; // octet 1 [3]
|
||||
uint8_t LcgID4: 1; // octet 1 [4]
|
||||
uint8_t LcgID5: 1; // octet 1 [5]
|
||||
uint8_t LcgID6: 1; // octet 1 [6]
|
||||
uint8_t LcgID7: 1; // octet 1 [7]
|
||||
uint8_t Buffer_size0: 8; // octet 2 [7:0]
|
||||
uint8_t Buffer_size1: 8; // octet 3 [7:0]
|
||||
uint8_t Buffer_size2: 8; // octet 4 [7:0]
|
||||
uint8_t Buffer_size3: 8; // octet 5 [7:0]
|
||||
uint8_t Buffer_size4: 8; // octet 6 [7:0]
|
||||
uint8_t Buffer_size5: 8; // octet 7 [7:0]
|
||||
uint8_t Buffer_size6: 8; // octet 8 [7:0]
|
||||
uint8_t Buffer_size7: 8; // octet 9 [7:0]
|
||||
} __attribute__ ((__packed__)) NR_BSR_LONG;
|
||||
|
||||
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
|
||||
|
||||
@@ -350,7 +350,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
vrb_map[rb + sched_ctrl->rbStart] = 1;
|
||||
}
|
||||
|
||||
void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
bool nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
@@ -366,7 +366,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
__func__,
|
||||
UE_info->num_UEs);
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
@@ -387,7 +387,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
* limitations). Note that if K2 or the TDD configuration is changed, below
|
||||
* conditions might exclude each other and never be true */
|
||||
if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
|
||||
return;
|
||||
return false;
|
||||
|
||||
const uint16_t rbStart = 0;
|
||||
const uint16_t rbSize = 50; /* due to OAI UE limitations */
|
||||
@@ -401,7 +401,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
frame,
|
||||
slot,
|
||||
i);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
@@ -477,4 +477,5 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
|
||||
vrb_map_UL[rb] = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2019,6 +2019,36 @@ void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg,
|
||||
nfapi_nr_coreset_t *coreset,
|
||||
|
||||
@@ -33,6 +33,33 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
//38.321 Table 6.1.3.1-1
|
||||
const uint32_t NR_SHORT_BSR_TABLE[32] = {
|
||||
0, 10, 14, 20, 28, 38, 53, 74,
|
||||
102, 142, 198, 276, 384, 535, 745, 1038,
|
||||
1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726,
|
||||
20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000
|
||||
};
|
||||
|
||||
//38.321 Table 6.1.3.1-2
|
||||
const uint32_t NR_LONG_BSR_TABLE[256] ={
|
||||
0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
|
||||
28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71,
|
||||
75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193,
|
||||
205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526,
|
||||
560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439,
|
||||
1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934,
|
||||
4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760,
|
||||
11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431,
|
||||
31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505,
|
||||
85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209,
|
||||
234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350,
|
||||
641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644,
|
||||
1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902,
|
||||
4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006,
|
||||
13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553,
|
||||
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
|
||||
};
|
||||
|
||||
void nr_process_mac_pdu(
|
||||
module_id_t module_idP,
|
||||
@@ -51,6 +78,13 @@ void nr_process_mac_pdu(
|
||||
uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len;
|
||||
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
int UE_id = find_nr_UE_id(module_idP, rnti);
|
||||
if (UE_id == -1) {
|
||||
LOG_E(MAC, "%s() UE_id == -1\n",__func__);
|
||||
return;
|
||||
}
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
// For both DL/UL-SCH
|
||||
// Except:
|
||||
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
|
||||
@@ -84,6 +118,9 @@ void nr_process_mac_pdu(
|
||||
|
||||
LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid);
|
||||
|
||||
unsigned char *ce_ptr;
|
||||
int n_Lcg = 0;
|
||||
|
||||
switch(rx_lcid){
|
||||
// MAC CE
|
||||
|
||||
@@ -97,32 +134,25 @@ void nr_process_mac_pdu(
|
||||
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
||||
// 38.321 Ch6.1.3.7
|
||||
break;
|
||||
case UL_SCH_LCID_S_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//fixed length
|
||||
mac_ce_len =1;
|
||||
/* Extract short BSR value */
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_S_BSR:
|
||||
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//fixed length
|
||||
mac_ce_len =1;
|
||||
/* Extract short truncated BSR value */
|
||||
/* Extract short BSR value */
|
||||
ce_ptr = &pdu_ptr[mac_subheader_len];
|
||||
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size];
|
||||
LOG_D(MAC, "SHORT BSR, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
|
||||
bsr_s->LcgID,
|
||||
bsr_s->Buffer_size,
|
||||
NR_SHORT_BSR_TABLE[bsr_s->Buffer_size],
|
||||
sched_ctrl->estimated_ul_buffer);
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_L_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//variable length
|
||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
|
||||
mac_subheader_len = 2;
|
||||
if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
/* Extract long BSR value */
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_L_TRUNCATED_BSR:
|
||||
//38.321 section 6.1.3.1
|
||||
//variable length
|
||||
@@ -132,9 +162,27 @@ void nr_process_mac_pdu(
|
||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
|
||||
mac_subheader_len = 3;
|
||||
}
|
||||
/* Extract long truncated BSR value */
|
||||
break;
|
||||
/* Extract long BSR value */
|
||||
ce_ptr = &pdu_ptr[mac_subheader_len];
|
||||
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
|
||||
n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 +
|
||||
bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0;
|
||||
|
||||
LOG_D(MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
|
||||
bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4,
|
||||
bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0);
|
||||
|
||||
for (int n = 0; n < n_Lcg; n++){
|
||||
LOG_D(MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
|
||||
n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n],
|
||||
NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]);
|
||||
sched_ctrl->estimated_ul_buffer +=
|
||||
NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UL_SCH_LCID_C_RNTI:
|
||||
//38.321 section 6.1.3.2
|
||||
@@ -244,18 +292,28 @@ void nr_process_mac_pdu(
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Updated estimated buffer when receiving data */
|
||||
if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
|
||||
sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
|
||||
else
|
||||
sched_ctrl->estimated_ul_buffer = 0;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
LOG_E(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
||||
|
||||
if (pdu_len < 0) {
|
||||
LOG_E(MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len);
|
||||
LOG_E(MAC, "MAC PDU ");
|
||||
for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes
|
||||
printf("%02x ", pdu_ptr[i]);
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -385,10 +443,21 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
if (sduP != NULL){
|
||||
LOG_D(MAC, "Received PDU at MAC gNB \n");
|
||||
|
||||
UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
|
||||
if (UE_scheduling_control->sched_ul_bytes < 0)
|
||||
UE_scheduling_control->sched_ul_bytes = 0;
|
||||
|
||||
nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP);
|
||||
}
|
||||
else {
|
||||
|
||||
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
|
||||
/* reduce sched_ul_bytes when cur_harq->round == 3 */
|
||||
if (cur_harq->round == 3){
|
||||
UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
|
||||
if (UE_scheduling_control->sched_ul_bytes < 0)
|
||||
UE_scheduling_control->sched_ul_bytes = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!sduP) // check that CRC passed
|
||||
@@ -483,7 +552,177 @@ int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
float ul_thr_ue[MAX_MOBILES_PER_GNB];
|
||||
|
||||
void pf_ul(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
NR_UE_list_t *UE_list,
|
||||
int n_rb_sched,
|
||||
uint8_t *rballoc_mask,
|
||||
int max_num_ue) {
|
||||
|
||||
const int CC_id = 0;
|
||||
const int tda = 1;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
float coeff_ue[MAX_MOBILES_PER_GNB];
|
||||
NR_UE_list_t UE_sched;
|
||||
int *uep = &UE_sched.head;
|
||||
|
||||
/* Loop UE_list to calculate throughput and coeff */
|
||||
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];
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
|
||||
/* Calculate throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes;
|
||||
ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b;
|
||||
LOG_D(MAC,"%4d.%2d %s() static TBS %d, ul_thr_ue[%d] %f\n",
|
||||
frame, slot, __func__, b, UE_id, ul_thr_ue[UE_id]);
|
||||
|
||||
/* RETRANSMISSION: Check retransmission */
|
||||
|
||||
/* RETRANSMISSION: Find free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_info, UE_id);
|
||||
if (!freeCCE) continue;
|
||||
|
||||
/* RETRANSMISSION: Allocate retransmission*/
|
||||
|
||||
/* Save PUSCH filed */
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
* every TTI if we can save it, so check whether dci_format, TDA, or
|
||||
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
|
||||
sched_ctrl->sched_pusch.time_domain_allocation = tda;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_save_pusch_fields(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
|
||||
/* Calculate TBS from MCS */
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
const int mcs = 9;
|
||||
sched_pusch->mcs = mcs;
|
||||
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
|
||||
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
|
||||
if (ps->pusch_Config->tp_pi2BPSK
|
||||
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
|
||||
sched_pusch->R >>= 1;
|
||||
sched_pusch->Qm <<= 1;
|
||||
}
|
||||
|
||||
uint32_t tbs = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
1, // rbSize
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
/* Check BSR */
|
||||
if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) {
|
||||
/* if no data, pre-allocate 5RB */
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
sched_pusch->rbStart = rbStart;
|
||||
sched_pusch->rbSize = 5;
|
||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
sched_pusch->rbSize,
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create UE_sched for new data transmission*/
|
||||
*uep = UE_id;
|
||||
uep = &UE_sched.next[UE_id];
|
||||
|
||||
/* Calculate coefficient*/
|
||||
coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
|
||||
|
||||
}
|
||||
*uep = -1;
|
||||
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (UE_sched.head >= 0 && max_num_ue> 0 && n_rb_sched > 0) {
|
||||
/* Find max coeff */
|
||||
int *max = &UE_sched.head; /* Find max coeff: assume head is max */
|
||||
int *p = &UE_sched.next[*max];
|
||||
while (*p >= 0) {
|
||||
/* Find max coeff: if the current one has larger coeff, save for later */
|
||||
if (coeff_ue[*p] > coeff_ue[*max])
|
||||
max = p;
|
||||
p = &UE_sched.next[*p];
|
||||
}
|
||||
/* Find max coeff: remove the max one */
|
||||
const int UE_id = *max;
|
||||
p = &UE_sched.next[*max];
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
|
||||
/* Find free CCE */
|
||||
bool freeCCE = find_free_CCE(module_id, slot, UE_info, UE_id);
|
||||
if (!freeCCE) return;
|
||||
|
||||
max_num_ue--;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
|
||||
|
||||
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
|
||||
sched_pusch->rbStart = rbStart;
|
||||
|
||||
/* Calculate the current scheduling bytes */
|
||||
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
|
||||
uint16_t rbSize = 4;
|
||||
do {
|
||||
rbSize++;
|
||||
sched_pusch->rbSize = rbSize;
|
||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
sched_pusch->rbSize,
|
||||
sched_ctrl->pusch_save.nrOfSymbols,
|
||||
sched_ctrl->pusch_save.N_PRB_DMRS * sched_ctrl->pusch_save.num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
} while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] &&
|
||||
sched_pusch->tb_size < B);
|
||||
LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
|
||||
rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
@@ -499,12 +738,12 @@ void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
__func__,
|
||||
UE_info->num_UEs);
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
/* NOT support different K2 in here, Get the K2 for first UE */
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];
|
||||
const int tda = 1;
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
@@ -512,94 +751,54 @@ void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
"time domain assignment %d >= %d\n",
|
||||
tda,
|
||||
tdaList->list.count);
|
||||
|
||||
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
|
||||
const int sched_slot = (slot + K2) % num_slots_per_tdd;
|
||||
if (!is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot))
|
||||
return;
|
||||
|
||||
/* get first, largest unallocated region */
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
|
||||
uint16_t rbStart = 0;
|
||||
while (vrb_map_UL[rbStart]) rbStart++;
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
uint16_t rbSize = 1;
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart+rbSize])
|
||||
rbSize++;
|
||||
return false;
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
|
||||
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 */);
|
||||
const 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(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
return;
|
||||
/* Confirm all the UE have same K2 as the first UE */
|
||||
for (int UE_id = UE_info->list.next[UE_id]; 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];
|
||||
AssertFatal(K2 == get_K2(sched_ctrl->active_ubwp, tda, mu),
|
||||
"Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(sched_ctrl->active_ubwp, tda, mu), UE_id);
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
sched_ctrl->sched_pusch.time_domain_allocation = tda;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
* every TTI if we can save it, so check whether dci_format, TDA, or
|
||||
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
|
||||
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_save_pusch_fields(scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
|
||||
const int mcs = 9;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
sched_pusch->mcs = mcs;
|
||||
sched_pusch->rbStart = rbStart;
|
||||
sched_pusch->rbSize = rbSize;
|
||||
|
||||
/* Calculate TBS from MCS */
|
||||
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
|
||||
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
|
||||
if (ps->pusch_Config->tp_pi2BPSK
|
||||
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
|
||||
sched_pusch->R >>= 1;
|
||||
sched_pusch->Qm <<= 1;
|
||||
/* Change vrb_map_UL to rballoc_mask */
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
int st = 0, e = 0, len = 0;
|
||||
for (int i = 0; i < bwpSize; i++) {
|
||||
while (vrb_map_UL[i] == 1)
|
||||
i++;
|
||||
st = i;
|
||||
while (vrb_map_UL[i] == 0)
|
||||
i++;
|
||||
if (i - st > len) {
|
||||
len = i - st;
|
||||
e = i - 1;
|
||||
}
|
||||
}
|
||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
sched_pusch->rbSize,
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
st = e - len + 1;
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
vrb_map_UL[rb + sched_ctrl->sched_pusch.rbStart] = 1;
|
||||
uint8_t rballoc_mask[bwpSize];
|
||||
|
||||
/* Calculate mask: if any RB in vrb_map_UL is blocked (1), the current RB will be 0 */
|
||||
for (int i = 0; i < bwpSize; i++)
|
||||
rballoc_mask[i] = i >= st && i <= e;
|
||||
|
||||
/* proportional fair scheduling algorithm */
|
||||
pf_ul(module_id, frame, slot, num_slots_per_tdd,
|
||||
&UE_info->list,
|
||||
len,
|
||||
rballoc_mask,
|
||||
2);
|
||||
return true;
|
||||
}
|
||||
|
||||
void nr_schedule_ulsch(module_id_t module_id,
|
||||
@@ -608,14 +807,21 @@ void nr_schedule_ulsch(module_id_t module_id,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
RC.nrmac[module_id]->pre_processor_ul(
|
||||
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot % num_slots_per_tdd)) {
|
||||
LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
|
||||
return;
|
||||
}
|
||||
bool do_sched = RC.nrmac[module_id]->pre_processor_ul(
|
||||
module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap);
|
||||
if (!do_sched)
|
||||
return;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const 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].ulsch_current_bytes = 0;
|
||||
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
|
||||
* every TTI are pre-populated by the preprocessor and used below */
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
@@ -757,6 +963,9 @@ void nr_schedule_ulsch(module_id_t module_id,
|
||||
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
||||
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
||||
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
|
||||
sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
|
||||
|
||||
/* PUSCH PTRS */
|
||||
if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
|
||||
// TODO to be fixed from RRC config
|
||||
|
||||
@@ -96,7 +96,7 @@ void nr_schedule_ulsch(module_id_t module_id,
|
||||
int ul_slots,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
bool nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
@@ -154,7 +154,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
int num_slots_per_tdd);
|
||||
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
|
||||
* fixed set of resources */
|
||||
void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
bool nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
@@ -432,4 +432,5 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
|
||||
|
||||
void find_SSB_and_RO_available(module_id_t module_idP);
|
||||
|
||||
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, NR_UE_info_t *UE_info, int UE_id);
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -402,6 +402,11 @@ typedef struct {
|
||||
uint16_t rbSize;
|
||||
uint16_t rbStart;
|
||||
|
||||
/// uplink bytes that are currently scheduled
|
||||
int sched_ul_bytes;
|
||||
/// estimation of the UL buffer size
|
||||
int estimated_ul_buffer;
|
||||
|
||||
// time-domain allocation for scheduled RBs
|
||||
int time_domain_allocation;
|
||||
|
||||
@@ -440,6 +445,7 @@ typedef struct {
|
||||
int ulsch_errors;
|
||||
int ulsch_total_bytes_scheduled;
|
||||
int ulsch_total_bytes_rx;
|
||||
int ulsch_current_bytes;
|
||||
} NR_mac_stats_t;
|
||||
|
||||
|
||||
@@ -477,7 +483,7 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
typedef void (*nr_pp_impl_ul)(module_id_t mod_id,
|
||||
typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
|
||||
Reference in New Issue
Block a user