diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 020be61fb1a7b72428a60332f7138668aed889b0..a16b1450396e56bb007c6049b75960846cf62fb7 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -757,7 +757,11 @@ typedef struct { uint32_t pusch_tpc_tx_subframe; uint32_t pucch_tpc_tx_frame; uint32_t pucch_tpc_tx_subframe; - + + /// stores the frame where the last bler was calculated + uint32_t pusch_bler_calc_frame; + uint32_t pusch_bler_calc_subframe; + #ifdef LOCALIZATION eNB_UE_estimated_distances distance; #endif @@ -833,6 +837,12 @@ typedef struct { uint8_t pusch_snr[NFAPI_CC_MAX]; uint8_t pusch_snr_avg[NFAPI_CC_MAX]; uint8_t pusch_snr_amc[NFAPI_CC_MAX]; + uint64_t pusch_rx_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_num_old[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num_old[NFAPI_CC_MAX]; + double pusch_bler[NFAPI_CC_MAX]; + uint8_t mcs_offset[NFAPI_CC_MAX]; uint16_t feedback_cnt[NFAPI_CC_MAX]; uint16_t timing_advance; uint16_t timing_advance_r9; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 13d02f94070ffb5e57f919df3b73ff60d7fda9b4..774fac80eb4e4acf4ea3a9650161369252f5c780 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -2570,9 +2570,11 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, uint8_t total_rbs=0; uint8_t average_rbs; uint16_t first_rb[MAX_NUM_CCs]; - uint8_t mcs; + int8_t mcs; uint8_t snr; - uint8_t snr2mcs_offset = 0; + uint8_t snr2mcs_offset = 3; + double bler_filter=0.9; + double bler; uint8_t rb_table_index; uint8_t num_pucch_rb; uint32_t tbs; @@ -2666,16 +2668,61 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, } else { UE_template = &UE_info->UE_template[CC_id][UE_id]; + int32_t framex10psubframe = UE_template->pusch_bler_calc_frame*10+UE_template->pusch_bler_calc_subframe; + int pusch_bler_interval=100; + double total_bler; + + if(UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id] == 0 && UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] == 0) { + total_bler = 0; + } + else { + total_bler = (double)UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] / (double)(UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id]) * 100; + } + + if (((framex10psubframe+pusch_bler_interval)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=pusch_bler_interval)))) { //frame wrap-around + + UE_template->pusch_bler_calc_frame=frameP; + UE_template->pusch_bler_calc_subframe=subframeP; + + int pusch_rx_num_diff = UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id] - UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[CC_id]; + int pusch_rx_error_num_diff = UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] - UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[CC_id]; + + if((pusch_rx_num_diff == 0) && (pusch_rx_error_num_diff == 0)) { /* first rx case or no rx among interval time */ + bler = UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id]; + } + else { + bler = (double)pusch_rx_error_num_diff / (double)(pusch_rx_num_diff + pusch_rx_error_num_diff) * 100; + } + UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id] * bler_filter + bler * (1.0-bler_filter); + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id]; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id]; + + if(bler < 0.5) { + if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] !=0) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]--; + } + } + if(bler >= 2) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]++; + if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] >= 20) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]=20; + } + } + } + if ( UE_info->UE_sched_ctrl[UE_id].phr_received == 1 ) { snr = (5 * UE_info->UE_sched_ctrl[UE_id].pusch_snr_amc[CC_id] - 640) / 10; - if((snr + snr2mcs_offset) >= 20) { + mcs = snr - snr2mcs_offset; + if(mcs > 20) { mcs = 20; } - else if((snr + snr2mcs_offset) < 3) { - mcs = 3; + + if(mcs - UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] < 6) { + mcs = 6; } - else { - mcs = snr + snr2mcs_offset; + else { + mcs = mcs - UE_list->UE_sched_ctrl[UE_id].mcs_offset[CC_id]; } } else { mcs = 10; @@ -2689,19 +2736,13 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) { rb_table_index = 2; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); - - while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) { - mcs--; - tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); - } + tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100); while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100); } if ( rb_table[rb_table_index]<3 ) { @@ -2731,6 +2772,11 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } + + LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d snr %d mcs %d mcs_offset %d bler %lf total_bler %lf ( %d %d ) rb_num %d phr_info %d tx_power %d bsr %d\n", + module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id, snr, mcs, UE_list->UE_sched_ctrl[UE_id].mcs_offset[CC_id], UE_list->UE_sched_ctrl[UE_id].pusch_bler[CC_id], + total_bler, UE_list->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id], UE_list->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id], rb_table[rb_table_index-1], UE_template->phr_info, tx_power, bytes_to_schedule); + } else { if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { // assigne RBS( 6 RBs) @@ -3207,8 +3253,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, nfapi_hi_dci0_request_t *nfapi_hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP]; nfapi_hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! nfapi_hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,UE_template->mcs_UL[harq_pid],first_rb[CC_id],rb_table[rb_table_index],0); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d mcs %d sinr %d bler %lf\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,UE_template->mcs_UL[harq_pid],first_rb[CC_id],rb_table[rb_table_index],0,UE_template->mcs_UL[harq_pid],(5 * UE_sched_ctrl->pusch_snr_amc[CC_id] - 640) / 10,UE_sched_ctrl->pusch_bler[CC_id]); ul_req_index = 0; dlsch_flag = 0; @@ -3358,8 +3404,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; hi_dci0_req->number_of_dci++; // Add UL_config PDUs - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,mcs_rv,ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb,ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb,UE_sched_ctrl->round_UL[CC_id][harq_pid]); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d mcs %d sinr %d bler %lf\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,mcs_rv,ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb,ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb,UE_sched_ctrl->round_UL[CC_id][harq_pid],UE_template->mcs_UL[harq_pid],(5 * UE_sched_ctrl->pusch_snr_amc[CC_id] - 640) / 10,UE_sched_ctrl->pusch_bler[CC_id]); + ul_req_index = 0; dlsch_flag = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 95a5b48598ae1d77d472de84b7351d3dc642e9b1..82b640e7d06543d5d0667d9c938841889e93af79 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2219,6 +2219,13 @@ add_new_ue(module_id_t mod_idP, UE_info->UE_sched_ctrl[UE_id].pusch_snr[cc_idP] = 0; UE_info->UE_sched_ctrl[UE_id].pusch_snr_avg[cc_idP] = 0; UE_info->UE_sched_ctrl[UE_id].pusch_snr_amc[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_bler[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].mcs_offset[cc_idP] = 0; + for (j = 0; j < 8; j++) { UE_info->UE_template[cc_idP][UE_id].oldNDI[j] = 0; UE_info->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index d8a8983ac1f1f8b35b122bafb6bbc3e05bb6a5c6..73e3465817f47572d6d5622a68aadede6d5bbbef 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -160,6 +160,8 @@ rx_sdu(const module_id_t enb_mod_idP, UE_scheduling_control->ul_inactivity_timer = 0; UE_scheduling_control->ul_failure_timer = 0; UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->pusch_rx_num[CC_idP]++; + /* Update with smoothing: 3/4 of old value and 1/4 of new. * This is the logic that was done in the function * lte_est_timing_advance_pusch, maybe it's not necessary? @@ -199,6 +201,7 @@ rx_sdu(const module_id_t enb_mod_idP, UE_template_ptr->scheduled_ul_bytes = 0; } } else { // sduP == NULL => error + UE_scheduling_control->pusch_rx_error_num[CC_idP]++; LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n", enb_mod_idP, harq_pid, diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 3c15bd5ac9c71213cb33b5a242e612a57db0aed0..09edd00a80928f018417b9579c34896565b8e691 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -906,6 +906,11 @@ typedef struct { uint32_t pucch_tpc_tx_frame; uint32_t pucch_tpc_tx_subframe; + /// stores the frame where the last bler was calculated + uint32_t pusch_bler_calc_frame; + uint32_t pusch_bler_calc_subframe; + + uint8_t rach_resource_type; uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; @@ -963,6 +968,12 @@ typedef struct { uint8_t pusch_snr[NFAPI_CC_MAX]; uint8_t pusch_snr_avg[NFAPI_CC_MAX]; uint8_t pusch_snr_amc[NFAPI_CC_MAX]; + uint64_t pusch_rx_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_num_old[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num_old[NFAPI_CC_MAX]; + double pusch_bler[NFAPI_CC_MAX]; + uint8_t mcs_offset[NFAPI_CC_MAX]; uint16_t feedback_cnt[NFAPI_CC_MAX]; uint16_t timing_advance; uint16_t timing_advance_r9;