Compare commits

...

20 Commits

Author SHA1 Message Date
ChiehChun
15bc7f17db Find max coeff & Decrease n_rb_sched 2020-12-14 15:29:07 +01:00
ChiehChun
8e553e242e Check BSR & Create UE_sched for new transmission 2020-12-14 15:29:07 +01:00
ChiehChun
b92aa08410 Calculate coefficient 2020-12-14 15:29:07 +01:00
ChiehChun
b7a0c5b9fa Calculate throughput & Initial static TBS 2020-12-14 15:29:07 +01:00
ChiehChun
edf88b61fa Create find_CCE (same as dl_pf) 2020-12-14 15:29:07 +01:00
ChiehChun
f8753c515c Find the largest contiguos region 2020-12-14 15:29:07 +01:00
ChiehChun
9f17c2d95f Add pf_ul & pseduo code 2020-12-14 15:29:07 +01:00
ChiehChun
fdd8a99fbd Change vrb_map_UL to rballoc_mask 2020-12-14 15:29:07 +01:00
ChiehChun
46d2e6988a Verify the same K2 2020-12-14 15:29:07 +01:00
ChiehChun
30df8203f1 Change pre_precessor_ul type to bool
- To check the current slot is the scheduled slot(UL slot - K2) and
  only execute the post processor in scheduled slot.
2020-12-14 15:29:04 +01:00
ChiehChun
ae8c8cf54a Check slot is DL slot to pre-schedule UL data 2020-12-14 15:28:38 +01:00
ChiehChun
2a70fcea00 Calculate rbSize from estimated buffer 2020-12-14 10:44:05 +01:00
ChiehChun
9e6b73999c Add sched_ul_bytes/static TBS & Update in rx_sdu/schedule_ulsch 2020-12-14 10:44:05 +01:00
ChiehChun
e4674b885f Add estimated_ul_buffer & Update in DTCH 2020-12-14 10:44:04 +01:00
ChiehChun
7d3623a691 Log lcid default case & pirntout MAC PDU 2020-12-14 10:43:50 +01:00
ChiehChun
95c20b7326 Fix NR_BSR_LONG 2020-12-12 17:24:53 +01:00
ChiehChun
8ff9015347 Add short/long BSR Table & Log the BS value 2020-12-12 17:24:53 +01:00
ChiehChun
cbff1c56aa Log short/long BSR status 2020-12-12 17:24:29 +01:00
ChiehChun
1a68dbd8da Fix case of truncated BSR 2020-12-12 17:24:29 +01:00
ChiehChun
6a5df2bdd3 Add CE & BSR pointer 2020-12-12 17:23:35 +01:00
6 changed files with 375 additions and 128 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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__*/

View File

@@ -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,