From bd1c609ca89b551ee0805525fd085b75c459be21 Mon Sep 17 00:00:00 2001 From: laurent <laurent.thomas@open-cells.com> Date: Fri, 12 Oct 2018 18:17:57 +0200 Subject: [PATCH] issue 359 dlsim CPU measurements --- cmake_targets/lte-simulators/CMakeLists.txt | 1 + openair1/PHY/defs_UE.h | 1 + openair1/PHY/defs_eNB.h | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 2 + openair1/SCHED_UE/phy_procedures_lte_ue.c | 54 +- openair1/SIMULATION/LTE_PHY/common_sim.h | 164 ++++ openair1/SIMULATION/LTE_PHY/dlsim.c | 791 +++++++------------- openair1/SIMULATION/LTE_PHY/ulsim.c | 356 ++++----- 8 files changed, 614 insertions(+), 757 deletions(-) create mode 100644 openair1/SIMULATION/LTE_PHY/common_sim.h diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index b7e83a92a03..1bfac2b20d6 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -9,4 +9,5 @@ set(MU_RECIEVER False) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) set(RRC_ASN1_VERSION "Rel14") +set (UE_TIMING_TRACE True) include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 55f8c9639ab..a303902b079 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -847,6 +847,7 @@ typedef struct { time_stats_t pdsch_procedures_stat[RX_NB_TH]; time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; time_stats_t dlsch_procedures_stat[RX_NB_TH]; + time_stats_t crnti_procedures_stats; time_stats_t ofdm_demod_stats; time_stats_t dlsch_rx_pdcch_stats; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index f23485cad84..e62c4d766fc 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -1074,12 +1074,12 @@ typedef struct PHY_VARS_eNB_s { int hw_timing_advance; - time_stats_t phy_proc; time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; time_stats_t rx_prach; time_stats_t ofdm_mod_stats; + time_stats_t dlsch_common_and_dci; time_stats_t dlsch_encoding_stats; time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 276006ec3be..f5d5334850e 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -484,6 +484,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),1); if (do_meas==1) start_meas(&eNB->phy_proc_tx); + if (do_meas==1) start_meas(&eNB->dlsch_common_and_dci); // clear the transmit data array for the current subframe for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) { @@ -578,6 +579,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, subframe); } + if (do_meas==1) stop_meas(&eNB->dlsch_common_and_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index b7d05ba0062..3b4d60230c6 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1715,7 +1715,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->phy_proc_tx); - LOG_UI(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); + LOG_I(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); stop_meas(&ue->ulsch_encoding_stats); } @@ -3369,7 +3369,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC if(m >= ue->frame_parms.symbols_per_tti>>1) slot = 1; stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); - LOG_UI(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); } @@ -3604,9 +3604,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW0 %5.3f\n", + LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); } @@ -3661,9 +3661,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW1 %5.3f\n", + LOG_I(PHY, " --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); } @@ -4005,7 +4005,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } @@ -4099,7 +4099,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } @@ -4319,7 +4319,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } //proc->dci_slot0_available = 1; @@ -4328,7 +4328,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr //proc->dci_slot0_available=1; if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } } @@ -4337,7 +4337,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } //wait until slot1 FE is done @@ -4350,7 +4350,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } /**** End Subframe FE Processing ****/ @@ -4439,7 +4439,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } @@ -4455,7 +4455,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } @@ -4526,7 +4526,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING) stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } // duplicate harq structure @@ -4589,7 +4589,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); @@ -4632,7 +4632,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if(LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->generic_stat); + start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); } pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; @@ -4757,15 +4757,17 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->generic_stat); + start_meas(&ue->crnti_procedures_stats); } + // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); @@ -4782,12 +4784,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->crnti_procedures_stats); + } LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, eNB_id, SI_PDSCH, @@ -4870,7 +4874,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, } // not an S-subframe if(LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); } LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); @@ -4915,8 +4919,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, abstraction_flag); if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - LOG_UI(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -5059,14 +5063,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->generic_stat); - LOG_UI(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_I(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); if ( LOG_DEBUGFLAG(UE_TIMING) ) { stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h new file mode 100644 index 00000000000..46f4cdf1611 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -0,0 +1,164 @@ + +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} + +double median(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); +} + +double q1(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/4)*input->atomSize); +} + +double q3(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(3*input->size/4)*input->atomSize); +} + +void dumpVarArray(varArray_t *input) { + double *ptr=dataArray(input); + printf("dumping size=%ld\n", input->size); + + for (int i=0; i < input->size; i++) + printf("%.1f:", *ptr++); + + printf("\n"); +} +void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) { + reset_meas(res); + for (int i=0; i<RX_NB_TH; i++) { + res->diff+=src[i].diff; + res->diff_square+=src[i].diff_square; + res->trials+=src[i].trials; + if (src[i].max > res->max) + res->max=src[i].max; + } + res->p_time=src[lastActive].p_time; +} +void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastActive) { + reset_meas(res); + for (int i=0; i<RX_NB_TH; i++) { + res->diff+=src[i][0].diff+src[i][1].diff; + res->diff_square+=src[i][0].diff_square+src[i][1].diff_square; + res->trials+=src[i][0].trials+src[i][1].trials; + if (src[i][0].max > res->max) + res->max=src[i][0].max; + if (src[i][1].max > res->max) + res->max=src[i][1].max;} + int last=src[lastActive][0].in < src[lastActive][1].in? 1 : 0 ; + res->p_time=src[lastActive][last].p_time; +} + +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-50s %.2f us (%d trials)\n", + txt, + ptr->trials?inMicroS(ptr->diff/ptr->trials):0, + ptr->trials); +} + +void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { + double timeBase=1/(1000*cpu_freq_GHz); + printf(" |__ %-45s %.2f us (cycles/block %ld, %5d trials)\n", + txt, + ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, + turbo_iter?(uint64_t)round(((double)ptr->diff)/turbo_iter):0, + ptr->trials); +} + +double squareRoot(time_stats_t *ptr) { + double timeBase=1/(1000*cpu_freq_GHz); + return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - + pow((double)ptr->diff/ptr->trials*timeBase,2)); +} + +void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { + double timeBase=1/(1000*cpu_freq_GHz); + printf("%-50s :%.2f us (%d trials)\n", + txt, + (double)ptr->diff/ptr->trials*timeBase, + ptr->trials); + printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", + squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); +} + +void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { + fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(ptr), + (double)ptr->max, *(double*)dataArray(sortedList), + median(sortedList),q1(sortedList),q3(sortedList), + dropped); +} + +struct option * parse_oai_options(paramdef_t *options) { + int l; + + for(l=0; options[l].optname[0]!=0; l++) {}; + + struct option *long_options=calloc(sizeof(struct option),l); + + for(int i=0; options[i].optname[0]!=0; i++) { + long_options[i].name=options[i].optname; + long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; + + if ( options[i].voidptr) + switch (options[i].type) { + case TYPE_INT: + *options[i].iptr=options[i].defintval; + break; + + case TYPE_DOUBLE: + *options[i].dblptr=options[i].defdblval; + break; + + case TYPE_UINT8: + *options[i].u8ptr=options[i].defintval; + break; + + case TYPE_UINT16: + *options[i].u16ptr=options[i].defintval; + break; + + default: + printf("not parsed type for default value %s\n", options[i].optname ); + exit(1); + } + + continue; + }; + return long_options; +} + +void display_options_values(paramdef_t *options, int verbose) { + for(paramdef_t * ptr=options; ptr->optname[0]!=0; ptr++) { + char varText[256]="need specific display"; + + if (ptr->voidptr != NULL) { + if ( (ptr->paramflags & PARAMFLAG_BOOL) ) + strcpy(varText, *(bool *)ptr->iptr ? "True": "False" ); + else switch (ptr->type) { + case TYPE_INT: + sprintf(varText,"%d",*ptr->iptr); + break; + + case TYPE_DOUBLE: + sprintf(varText,"%.2f",*ptr->dblptr); + break; + + case TYPE_UINT8: + sprintf(varText,"%d",(int)*ptr->u8ptr); + break; + + case TYPE_UINT16: + sprintf(varText,"%d",(int)*ptr->u16ptr); + break; + + default: + printf("not decoded type\n"); + exit(1); + } + } + + printf("--%-20s set to %s\n",ptr->optname, varText); + if (verbose) printf("%s\n",ptr->helpstr); + } +} diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3583c0f25ea..0f4655eb2c7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -72,6 +72,9 @@ void feptx_ofdm(RU_t *ru); void feptx_prec(RU_t *ru); double cpuf; +#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +//#define MCS_COUNT 23//added for PHY abstraction +#include <openair1/SIMULATION/LTE_PHY/common_sim.h> int otg_enabled=0; /*the following parameters are used to control the processing times calculations*/ @@ -535,23 +538,42 @@ void fill_DCI(PHY_VARS_eNB *eNB, } int n_users = 1; -sub_frame_t subframe=7; +int subframe=7; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; uint16_t n_rnti=0x1234; - int nfapi_mode=0; +int nfapi_mode=0; +int abstx=0; +int Nid_cell=0; +int N_RB_DL=25; +int tdd_config=3; +int dci_flag=0; +int threequarter_fs=0; +double snr_step=1,input_snr_step=1, snr_int=30; +double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel +int test_perf=0; +int n_frames; +int n_ch_rlz = 1; +int rx_sample_offset = 0; +int xforms=0; +int dump_table=0; +int loglvl=OAILOG_WARNING; +int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0; +int two_thread_flag=0; +int num_rounds = 4;//,fix_rounds=0; +int perfect_ce = 0; +int extended_prefix_flag=0; +int verbose=0, help=0; +double SNR,snr0=-2.0,snr1,rate = 0; +int print_perf=0; int main(int argc, char **argv) { - int c; int k,i,j,aa; int re; - int loglvl=OAILOG_DEBUG; int s,Kr,Kr_bytes; - double SNR,snr0=-2.0,snr1,rate = 0; - double snr_step=1,input_snr_step=1, snr_int=30; LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; @@ -560,17 +582,14 @@ int main(int argc, char **argv) double *s_im[2]={s_im0,s_im1}; double *r_re[2]={r_re0,r_re1}; double *r_im[2]={r_im0,r_im1}; - double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel - uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; - uint16_t Nid_cell=0; + uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; int eNB_id = 0; - unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round; + unsigned char round; unsigned char i_mod = 2; unsigned short NB_RB; - uint16_t tdd_config=3; SCM_t channel_model=Rayleigh1; @@ -602,18 +621,13 @@ int main(int argc, char **argv) FILE *input_fd=NULL; unsigned char input_file=0; - int n_frames; - int n_ch_rlz = 1; channel_desc_t *eNB2UE[4]; //uint8_t num_pdcch_symbols_2=0; - uint8_t rx_sample_offset = 0; //char stats_buffer[4096]; //int len; - uint8_t num_rounds = 4;//,fix_rounds=0; //int u; int n=0; - int abstx=0; //int iii; int ch_realization; @@ -625,9 +639,8 @@ int main(int argc, char **argv) // int bler; double blerr[4]; short *uncoded_ber_bit=NULL; - uint8_t N_RB_DL=25,osf=1; + int osf=1; frame_t frame_type = FDD; - int xforms=0; FD_lte_phy_scope_ue *form_ue = NULL; char title[255]; @@ -640,16 +653,12 @@ int main(int argc, char **argv) // time_stats_t ts;//,sts,usts; int avg_iter,iter_trials; int rballocset=0; - int print_perf=0; - int test_perf=0; int test_passed=0; - int dump_table=0; double effective_rate=0.0; char channel_model_input[10]="I"; int TB0_active = 1; - uint32_t perfect_ce = 0; // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; @@ -657,20 +666,11 @@ int main(int argc, char **argv) uint8_t ue_category=4; uint32_t Nsoft; int sf; - - - int CCE_table[800]; - - int threequarter_fs=0; - - opp_enabled=1; // to enable the time meas FILE *csv_fd=NULL; - char csv_fname[32]; - int dci_flag=0; - int two_thread_flag=0; + char csv_fname[FILENAME_MAX]; int DLSCH_RB_ALLOC = 0; int dci_received; @@ -726,36 +726,95 @@ int main(int argc, char **argv) snr0 = 0; // num_layers = 1; perfect_ce = 0; + static paramdef_t options[] = { + { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "Abstx", "Turns on calibration mode for abstraction.", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, + { "bTDD", "Set the tdd configuration mode",0, iptr:&tdd_config, defintval:3, TYPE_INT, 0 }, + { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, + { "cPdcch", "Number of PDCCH symbols",0, iptr:&num_pdcch_symbols, defintval:1, TYPE_INT, 0 }, + { "CnidCell", "The cell id ",0, iptr:&Nid_cell, defintval:0, TYPE_INT, 0 }, + { "dciFlag", "Transmit the DCI and compute its error statistics", PARAMFLAG_BOOL, iptr:&dci_flag, defintval:0, TYPE_INT, 0 }, + { "Dtdd", "Enable tdd", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "eRounds", "Number of rounds",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 }, + { "f_snr_step", "step size of SNR, default value is 1.",0, dblptr:&input_snr_step, defdblval:1, TYPE_DOUBLE, 0 }, + { "Forgetting", "forgetting factor (0 new channel every trial, 1 channel constant)",0, dblptr:&forgetting_factor, defdblval:0.0, TYPE_DOUBLE, 0 }, + { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Input_file_trch", " Input filename for TrCH data (binary)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "WtwoThreads", "two_thread_flag", PARAMFLAG_BOOL, iptr:&two_thread_flag, defintval:0, TYPE_INT, 0 }, + { "lMuMimo", "offset_mumimo_llr_drange_fix",0, u8ptr:&offset_mumimo_llr_drange_fix, defintval:0, TYPE_UINT8, 0 }, + { "mcs1", "The MCS for TB 1", 0, iptr:&mcs1, defintval:0, TYPE_INT, 0 }, + { "Mcs2", "The MCS for TB 2", 0, iptr:&mcs2, defintval:0, TYPE_INT, 0 }, + { "Operf", "Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "tmcs_i", "MCS of interfering UE",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, + { "offsetRxSample", "Sample offset for receiver", 0, iptr:&rx_sample_offset, defintval:0, TYPE_INT, 0 }, + { "rballocset", "ressource block allocation (see section 7.1.6.3 in 36.213)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "snr", "Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated", dblptr:&snr0, defdblval:-2.0, TYPE_DOUBLE, 0 }, + { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, + { "N_ch_rlzN0", "Determines the number of Channel Realizations in Abstraction mode. Default value is 1",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, + { "prefix_extended","Enable extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 }, + { "RNumRound", "Number of HARQ rounds (fixed)",0, iptr:&num_rounds, defintval:4, TYPE_INT, 0 }, + { "Subframe", "subframe ",0, iptr:&subframe, defintval:7, TYPE_INT, 0 }, + { "Trnti", "rnti",0, u16ptr:&n_rnti, defuintval:0x1234, TYPE_UINT16, 0 }, + { "vi_mod", "i_mod",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:&print_perf, defintval:0, TYPE_INT, 0 }, + { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, + { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 }, + { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, + { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 }, + { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 }, + { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, + { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, + { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + }; - while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXYL:")) != -1) { - switch (c) { - case 'a': - awgn_flag = 1; - channel_model = AWGN; - break; - - case 'A': - abstx = 1; - break; - - case 'b': - tdd_config=atoi(optarg); - break; - - case 'B': - N_RB_DL=atoi(optarg); - break; + + struct option * long_options = parse_oai_options(options); + - case 'c': - num_pdcch_symbols=atoi(optarg); - break; + int option_index; + + int res; + + while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { + if (options[option_index].voidptr != NULL ) { + if (long_options[option_index].has_arg==no_argument) + *(bool *)options[option_index].iptr=1; + else switch (options[option_index].type) { + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; + + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); + } - case 'C': - Nid_cell = atoi(optarg); - break; + continue; + } - case 'd': - dci_flag = 1; + switch (long_options[option_index].name[0]) { + case 'a': + awgn_flag = 1; + channel_model = AWGN; break; case 'D': @@ -768,18 +827,6 @@ int main(int argc, char **argv) TPC = atoi(optarg); break; - case 'E': - threequarter_fs=1; - break; - - case 'f': - input_snr_step= atof(optarg); - break; - - case 'F': - forgetting_factor = atof(optarg); - break; - case 'i': input_fd = fopen(optarg,"r"); input_file=1; @@ -791,138 +838,50 @@ int main(int argc, char **argv) input_trch_file=1; break; - case 'W': - two_thread_flag = 1; - break; - case 'l': - offset_mumimo_llr_drange_fix=atoi(optarg); - break; - - case 'm': - mcs1 = atoi(optarg); - break; - - case 'M': - mcs2 = atoi(optarg); - break; - - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; - case 't': mcs_i = atoi(optarg); i_mod = get_Qm(mcs_i); break; - case 'n': - n_frames = atoi(optarg); - break; - - - case 'o': - rx_sample_offset = atoi(optarg); - break; - case 'r': DLSCH_RB_ALLOC = atoi(optarg); rballocset = 1; break; - case 's': - snr0 = atof(optarg); - break; - - case 'w': - snr_int = atof(optarg); - break; - - - case 'N': - n_ch_rlz= atof(optarg); - break; - - case 'p': - extended_prefix_flag=1; - break; - case 'g': - memcpy(channel_model_input,optarg,10); - - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; - break; - - case 'B': - channel_model=SCM_B; - break; - - case 'C': - channel_model=SCM_C; - break; - - case 'D': - channel_model=SCM_D; - break; - - case 'E': - channel_model=EPA; - break; - - case 'F': - channel_model=EVA; - break; - - case 'G': - channel_model=ETU; - break; - - case 'H': - channel_model=Rayleigh8; - break; - - case 'I': - channel_model=Rayleigh1; - break; - - case 'J': - channel_model=Rayleigh1_corr; - break; - - case 'K': - channel_model=Rayleigh1_anticorr; - break; - - case 'L': - channel_model=Rice8; - break; - - case 'M': - channel_model=Rice1; - break; + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'F',EVA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + break; + } - case 'N': - channel_model=AWGN; + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - default: - printf("Unsupported channel model!\n"); - exit(-1); - } - - break; - case 'R': - num_rounds=atoi(optarg); - break; - - case 'S': - subframe=atoi(optarg); - break; - - case 'T': - n_rnti=atoi(optarg); - break; case 'u': dual_stream_UE=1; @@ -945,10 +904,6 @@ int main(int argc, char **argv) break; - case 'P': - print_perf=1; - break; - case 'q': n_tx_port=atoi(optarg); @@ -999,15 +954,6 @@ int main(int argc, char **argv) } break; - break; - - case 'X': - xforms=1; - break; - - case 'Y': - perfect_ce=1; - break; case 'z': n_rx=atoi(optarg); @@ -1019,51 +965,23 @@ int main(int argc, char **argv) break; - case 'Z': - dump_table=1; - break; - - case 'L': - loglvl = atoi(optarg); - break; - - case 'h': default: - printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-c Number of PDCCH symbols\n"); - printf("-m MCS1 for TB 1\n"); - printf("-M MCS2 for TB 2\n"); - printf("-d Transmit the DCI and compute its error statistics\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-o Sample offset for receiver\n"); - printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); - printf("-f step size of SNR, default value is 1.\n"); - printf("-C cell id\n"); - printf("-S subframe\n"); - printf("-D use TDD mode\n"); - printf("-b TDD config\n"); - printf("-B bandwidth configuration (in number of ressource blocks): 6, 25, 50, 100\n"); - printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n"); - printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); - printf("-x Transmission mode (1,2,6,7 for the moment)\n"); - printf("-q Number of TX antennas ports used in eNB\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-t MCS of interfering UE\n"); - printf("-R Number of HARQ rounds (fixed)\n"); - printf("-A Turns on calibration mode for abstraction.\n"); - printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); - printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); - printf("-I Input filename for TrCH data (binary)\n"); - printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n"); + printf("Wrong option: %s\n",long_options[option_index].name); exit(1); break; } } + + if ( res != -1 ) { + printf("A wrong option has been found\n"); + exit(1); + } + + if (help || verbose ) + display_options_values(options, true); + if (help) + exit(0); + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_worker_conf("WORKER_ENABLE"); @@ -1073,8 +991,10 @@ int main(int argc, char **argv) AssertFatal(load_configmodule(argc,argv) != NULL, "cannot load configuration module, exiting\n"); logInit(); + set_glog_onlinelog(true); // enable these lines if you need debug info set_glog(loglvl); + SET_LOG_DEBUG(UE_TIMING); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt @@ -1522,9 +1442,17 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_interleaving_stats); reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - - reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx + for (int i=0; i<RX_NB_TH; i++) { + reset_meas(&UE->phy_proc_rx[i]); // total UE rx + reset_meas(&UE->ue_front_end_stat[i]); + reset_meas(&UE->pdsch_procedures_stat[i]); + reset_meas(&UE->dlsch_procedures_stat[i]); + reset_meas(&UE->dlsch_decoding_stats[i]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]); + } reset_meas(&UE->ofdm_demod_stats); + reset_meas(&UE->crnti_procedures_stats); reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); reset_meas(&UE->rx_dft_stats); @@ -1541,25 +1469,21 @@ int main(int argc, char **argv) reset_meas(&UE->dlsch_tc_intl1_stats); reset_meas(&UE->dlsch_tc_intl2_stats); // initialization - struct list time_vector_tx; - initialize(&time_vector_tx); - struct list time_vector_tx_ifft; - initialize(&time_vector_tx_ifft); - struct list time_vector_tx_mod; - initialize(&time_vector_tx_mod); - struct list time_vector_tx_enc; - initialize(&time_vector_tx_enc); - - struct list time_vector_rx; - initialize(&time_vector_rx); - struct list time_vector_rx_fft; - initialize(&time_vector_rx_fft); - struct list time_vector_rx_demod; - initialize(&time_vector_rx_demod); - struct list time_vector_rx_dec; - initialize(&time_vector_rx_dec); - - + // initialization + varArray_t *table_tx=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_mod=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_enc=initVarArray(1000,sizeof(double)); + varArray_t *table_rx=initVarArray(1000,sizeof(double)); + time_stats_t phy_proc_rx_tot; + time_stats_t pdsch_procedures_tot; + time_stats_t dlsch_procedures_tot; + time_stats_t dlsch_decoding_tot; + time_stats_t dlsch_llr_tot; + time_stats_t ue_front_end_tot; + varArray_t *table_rx_fft=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_demod=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_dec=initVarArray(1000,sizeof(double)); for (trials = 0; trials<n_frames; trials++) { //printf("Trial %d\n",trials); @@ -2004,120 +1928,53 @@ int main(int argc, char **argv) /* calculate the total processing time for each packet, * get the max, min, and number of packets that exceed t>2000us */ - double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0; - - if (t_tx > t_tx_max) - t_tx_max = t_tx; - - if (t_tx < t_tx_min) - t_tx_min = t_tx; - - if (t_rx > t_rx_max) - t_rx_max = t_rx; - - if (t_rx < t_rx_min) - t_rx_min = t_rx; - - if (t_tx > 2000) + double t_tx = inMicroS(eNB->phy_proc_tx.p_time); + double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time); + double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time); + sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]); + sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]); + sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]); + sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]); + + + double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time); + double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time); + double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time); + + if (t_tx > 2000 )// 2ms is too much time for a subframe n_tx_dropped++; - - if (t_rx > 2000) + + if (t_rx > 2000 ) n_rx_dropped++; - - push_front(&time_vector_tx, t_tx); - push_front(&time_vector_tx_ifft, t_tx_ifft); - push_front(&time_vector_tx_mod, t_tx_mod); - push_front(&time_vector_tx_enc, t_tx_enc); - - push_front(&time_vector_rx, t_rx); - push_front(&time_vector_rx_fft, t_rx_fft); - push_front(&time_vector_rx_demod, t_rx_demod); - push_front(&time_vector_rx_dec, t_rx_dec); - + + appendVarArray(table_tx, &t_tx); + appendVarArray(table_tx_ifft, &t_tx_ifft); + appendVarArray(table_rx, &t_rx ); + appendVarArray(table_rx_fft, &t_rx_fft ); + appendVarArray(table_rx_demod, &t_rx_demod ); + appendVarArray(table_rx_dec, &t_rx_dec ); } //trials // round_trials[0]: number of code word : goodput the protocol - double table_tx[time_vector_tx.size]; - totable(table_tx, &time_vector_tx); - double table_tx_ifft[time_vector_tx_ifft.size]; - totable(table_tx_ifft, &time_vector_tx_ifft); - double table_tx_mod[time_vector_tx_mod.size]; - totable(table_tx_mod, &time_vector_tx_mod); - double table_tx_enc[time_vector_tx_enc.size]; - totable(table_tx_enc, &time_vector_tx_enc); - - double table_rx[time_vector_rx.size]; - totable(table_rx, &time_vector_rx); - double table_rx_fft[time_vector_rx_fft.size]; - totable(table_rx_fft, &time_vector_rx_fft); - double table_rx_demod[time_vector_rx_demod.size]; - totable(table_rx_demod, &time_vector_rx_demod); - double table_rx_dec[time_vector_rx_dec.size]; - totable(table_rx_dec, &time_vector_rx_dec); - - // sort table - qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); - qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); + qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble); + qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble); + qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble); + qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble); + qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble); + qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble); + qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble); + qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble); if (dump_table == 1 ) { set_component_filelog(SIM); // file located in /tmp/usim.txt - LOG_UDUMPMSG(SIM,table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); - LOG_UDUMPMSG(SIM,table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); + LOG_UDUMPMSG(SIM,table_tx,table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,table_rx,table_rx->size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); } - double tx_median = table_tx[time_vector_tx.size/2]; - double tx_q1 = table_tx[time_vector_tx.size/4]; - double tx_q3 = table_tx[3*time_vector_tx.size/4]; - - double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2]; - double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4]; - double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4]; - - double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2]; - double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4]; - double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4]; - - double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2]; - double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4]; - double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4]; - - double rx_median = table_rx[time_vector_rx.size/2]; - double rx_q1 = table_rx[time_vector_rx.size/4]; - double rx_q3 = table_rx[3*time_vector_rx.size/4]; - - double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2]; - double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4]; - double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4]; - - double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2]; - double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4]; - double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4]; - - double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2]; - double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4]; - double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4]; - - double std_phy_proc_tx=0; - double std_phy_proc_tx_ifft=0; - double std_phy_proc_tx_mod=0; - double std_phy_proc_tx_enc=0; - - double std_phy_proc_rx=0; - double std_phy_proc_rx_fft=0; - double std_phy_proc_rx_demod=0; - double std_phy_proc_rx_dec=0; - effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n", @@ -2149,108 +2006,49 @@ int main(int argc, char **argv) (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + double timeBase=1/(1000*cpu_freq_GHz); if (print_perf==1) { - printf("eNB TX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_tx = sqrt((double)eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->phy_proc_tx.trials - pow((double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); - std_phy_proc_tx_ifft = sqrt((double)eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ofdm_mod_stats.trials - pow((double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_mod time :%f us (%d trials)\n",(double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,eNB->ofdm_mod_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - printf("Total PHY proc tx :%f us (%d trials)\n",(double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_tx.trials); - printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, - n_tx_dropped); - - std_phy_proc_tx_mod = sqrt((double)eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->dlsch_modulation_stats.trials - pow((double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH modulation time :%f us (%d trials)\n",(double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_modulation_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - printf("DLSCH scrambling time :%f us (%d trials)\n",(double)eNB->dlsch_scrambling_stats.diff/eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_scrambling_stats.trials); - std_phy_proc_tx_enc = sqrt((double)eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->dlsch_encoding_stats.trials - pow((double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH encoding time :%f us (%d trials)\n",(double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_modulation_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - printf("|__ DLSCH turbo encoding time :%f us (%d trials)\n", - ((double)eNB->dlsch_turbo_encoding_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_turbo_encoding_stats.diff/eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_turbo_encoding_stats.trials); - printf("|__ DLSCH rate-matching time :%f us (%d trials)\n", - ((double)eNB->dlsch_rate_matching_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_rate_matching_stats.diff/eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_rate_matching_stats.trials); - printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n", - ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); - - printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3); - printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, - rx_q1, rx_q3, n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ofdm_demod_stats.trials - pow((double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - UE->ofdm_demod_stats.trials*2/3); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - printf("|__ DLSCH rx dft :%f us (%d trials)\n", - (nsymb*UE->frame_parms.nb_antennas_rx)*(double)UE->rx_dft_stats.diff/UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,UE->rx_dft_stats.trials*2/3); - printf("|__ DLSCH channel estimation time :%f us (%d trials)\n", - (4.0)*(double)UE->dlsch_channel_estimation_stats.diff/UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_channel_estimation_stats.trials*2/3); - printf("|__ DLSCH frequency offset estimation time :%f us (%d trials)\n", - (4.0)*(double)UE->dlsch_freq_offset_estimation_stats.diff/UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_freq_offset_estimation_stats.trials*2/3); - printf("DLSCH rx pdcch :%f us (%d trials)\n",(double)UE->dlsch_rx_pdcch_stats.diff/UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_rx_pdcch_stats.trials); - std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH Channel Compensation and LLR generation time :%f us (%d trials)\n",(14-num_pdcch_symbols)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_llr_stats.trials/3); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); - printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_unscrambling_stats.trials); - std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); - printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", - eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials, - (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials, - (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", - (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); - printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, - (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); - printf(" |__ init %f us (cycles/iter %f, %d trials)\n", - (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/((double)avg_iter/iter_trials), - UE->dlsch_tc_init_stats.trials); - printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", - (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials*2, - UE->dlsch_tc_alpha_stats.trials); - printf(" |__ beta %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials*2, - UE->dlsch_tc_beta_stats.trials); - printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials*2, - UE->dlsch_tc_gamma_stats.trials); - printf(" |__ ext %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials*2, - UE->dlsch_tc_ext_stats.trials); - printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials, - UE->dlsch_tc_intl1_stats.trials); - printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials, - UE->dlsch_tc_intl2_stats.trials); + printf("\neNB TX function statistics (per 1ms subframe)\n"); + printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); + printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); + printStatIndent(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent2(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time",eNB->dlsch_rate_matching_stats.trials); + printStatIndent2(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time", eNB->dlsch_turbo_encoding_stats.trials); + printStatIndent2(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time", eNB->dlsch_interleaving_stats.trials); + printStatIndent(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + printStatIndent(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); + printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); + + printf("\nUE RX function statistics (per 1ms subframe)\n"); + printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); + printStatIndent(&ue_front_end_tot,"Front end processing"); + printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing", pdsch_procedures_tot.trials); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing", dlsch_procedures_tot.trials); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing", UE->crnti_procedures_stats.trials); + printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); + printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); + printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); + printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); + printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); + printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); + printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, + + UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, + (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, + (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), + UE->dlsch_turbo_decoding_stats.trials); + printStatIndent2(&UE->dlsch_tc_init_stats,"init", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_beta_stats,"beta", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_ext_stats,"ext", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC", UE->dlsch_tc_init_stats.trials); + } if ((transmission_mode != 3) && (transmission_mode != 4)) { @@ -2399,7 +2197,7 @@ int main(int argc, char **argv) eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials, + phy_proc_rx_tot.trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -2412,7 +2210,7 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->dlsch_modulation_stats), get_time_meas_us(&eNB->dlsch_scrambling_stats), get_time_meas_us(&eNB->dlsch_encoding_stats), - get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]), + get_time_meas_us(&phy_proc_rx_tot), nsymb*get_time_meas_us(&UE->ofdm_demod_stats), get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), @@ -2420,45 +2218,36 @@ int main(int argc, char **argv) get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]) ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); //fprintf(time_meas_fd,"IFFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->ofdm_mod_stats), + median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); //fprintf(time_meas_fd,"MOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_modulation_stats), + median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); //fprintf(time_meas_fd,"ENC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - - //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_encoding_stats), + median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); + //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min, + median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ofdm_demod_stats), + median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); //fprintf(time_meas_fd,"DEMOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->dlsch_demodulation_stats), + median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); //fprintf(time_meas_fd,"DEC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - - - /* - fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", - eNB->phy_proc_tx.trials, - eNB->ofdm_mod_stats.trials, - eNB->dlsch_modulation_stats.trials, - eNB->dlsch_scrambling_stats.trials, - eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials, - UE->ofdm_demod_stats.trials, - UE->dlsch_rx_pdcch_stats.trials, - UE->dlsch_llr_stats.trials, - UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials); - */ + fprintf(time_meas_fd,"%f;%f;%f;%f\n", + squareRoot(&UE->dlsch_decoding_stats[subframe]), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); test_passed = 1; break; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8c09da1daf9..c015063b605 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1,23 +1,23 @@ /* - Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The OpenAirInterface Software Alliance licenses this file to You under - the OAI Public License, Version 1.1 (the "License"); you may not use this file - except in compliance with the License. - You may obtain a copy of the License at - - http://www.openairinterface.org/?page_id=698 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ------------------------------------------------------------------------------- - For more information about the OpenAirInterface (OAI) Software Alliance: - contact@openairinterface.org -*/ + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file ulsim.c \brief Top-level UL simulator @@ -60,32 +60,7 @@ double cpuf; #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) //#define MCS_COUNT 23//added for PHY abstraction -static int cmpdouble(const void *p1, const void *p2) { - return *(double *)p1 > *(double *)p2; -} - -double median(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); -} - -double q1(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(input->size/4)*input->atomSize); -} - -double q3(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(3*input->size/4)*input->atomSize); -} - -void dumpVarArray(varArray_t *input) { - double *ptr=dataArray(input); - printf("dumping size=%ld\n", input->size); - - for (int i=0; i < input->size; i++) - printf("%.1f:", *ptr++); - - printf("\n"); -} - +#include <openair1/SIMULATION/LTE_PHY/common_sim.h> channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; //Added for PHY abstractionopenair1/PHY/TOOLS/lte_phy_scope.h @@ -348,48 +323,8 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB, ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; } -void printStatIndent(time_stats_t *ptr, char *txt) { - printf("|__ %-50s %.2f us (%d trials)\n", - txt, - inMicroS(ptr->diff/ptr->trials), - ptr->trials); -} - -void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { - double timeBase=1/(1000*cpu_freq_GHz); - printf(" |__ %-45s %.2f us (cycles/block %7g, %5d trials)\n", - txt, - ((double)ptr->diff)/ptr->trials*timeBase, - round(((double)ptr->diff)/turbo_iter), - ptr->trials); -} - -double squareRoot(time_stats_t *ptr) { - double timeBase=1/(1000*cpu_freq_GHz); - return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - - pow((double)ptr->diff/ptr->trials*timeBase,2)); -} - -void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { - double timeBase=1/(1000*cpu_freq_GHz); - printf("%-50s :%.2f us (%d trials)\n", - txt, - (double)ptr->diff/ptr->trials*timeBase, - ptr->trials); - printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", - squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); -} - -void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { - fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", - squareRoot(ptr), - (double)ptr->max, *(double*)dataArray(sortedList), - median(sortedList),q1(sortedList),q3(sortedList), - dropped); -} - enum eTypes { eBool, eInt, eFloat, eText }; -static int verbose,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1; +static int verbose,help,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1; int main(int argc, char **argv) { int i,j,aa,u; @@ -505,13 +440,13 @@ int main(int argc, char **argv) { //set_glog(LOG_DEBUG,LOG_MED); //hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF static paramdef_t options[] = { - { "awgn", "Additive white gaussian noise", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, { "mcs", "The MCS to use", 0, iptr:&mcs, defintval:10, TYPE_INT, 0 }, { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, { "snr", "starting snr", 0, dblptr:&snr0, defdblval:-2.9, TYPE_DOUBLE, 0 }, { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, - { "e_snr_step", "step increasint snr",0, dblptr:&input_snr_step, defdblval:0.2, TYPE_DOUBLE, 0 }, + { "e_snr_step", "step increasing snr",0, dblptr:&input_snr_step, defdblval:0.2, TYPE_DOUBLE, 0 }, { "rb_dynamic", "number of rb in dynamic allocation",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, { "first_rb", "first rb used in dynamic allocation",0, iptr:&first_rb, defintval:0, TYPE_INT, 0 }, { "osrs", "enable srs generation",PARAMFLAG_BOOL, iptr:&srs_flag, defintval:0, TYPE_INT, 0 }, @@ -538,37 +473,12 @@ int main(int argc, char **argv) { { "bundling_disable", "bundling disable",PARAMFLAG_BOOL, iptr:&disable_bundling, defintval:0, TYPE_INT, 0 }, { "Y", "n_ch_rlz",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, { "X", "abstx", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, - { "Operf", "test perf mode ?",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "Operf", "Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, }; - int l; - - for(l=0; options[l].optname[0]!=0; l++) {}; - - struct option *long_options=calloc(sizeof(struct option),l); - - for(int i=0; options[i].optname[0]!=0; i++) { - long_options[i].name=options[i].optname; - long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; - - if ( options[i].voidptr) - switch (options[i].type) { - case TYPE_INT: - *options[i].iptr=options[i].defintval; - break; - - case TYPE_DOUBLE: - *options[i].dblptr=options[i].defdblval; - break; - - default: - printf("not parsed type for default value %s\n", options[i].optname ); - exit(1); - } - - continue; - }; + struct option * long_options = parse_oai_options(options); int option_index; @@ -579,113 +489,121 @@ int main(int argc, char **argv) { if (long_options[option_index].has_arg==no_argument) *(bool *)options[option_index].iptr=1; else switch (options[option_index].type) { - case TYPE_INT: - *(int *)options[option_index].iptr=atoi(optarg); - break; - - case TYPE_DOUBLE: - *(double *)options[option_index].dblptr=atof(optarg); - break; - - default: - printf("not decoded type.\n"); - exit(1); + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; + + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); } continue; } switch (long_options[option_index].name[0]) { - case 'T': - tdd_config=atoi(optarg); - frame_type=TDD; - break; - - case 'a': - channel_model = AWGN; - chMod = 1; - break; + case 'T': + tdd_config=atoi(optarg); + frame_type=TDD; + break; - case 'g': - strncpy(channel_model_input,optarg,9); - struct tmp { - char opt; - int m; - int M; - } - tmp[]= { - {'A',SCM_A,2}, - {'B',SCM_B,3}, - {'C',SCM_C,4}, - {'D',SCM_D,5}, - {'E',EPA,6}, - {'G',ETU,8}, - {'H',Rayleigh8,9}, - {'I',Rayleigh1,10}, - {'J',Rayleigh1_corr,11}, - {'K',Rayleigh1_anticorr,12}, - {'L',Rice8,13}, - {'M',Rice1,14}, - {'N',AWGN,1}, - {0,0,0} - }; - struct tmp *ptr; - - for (ptr=tmp; ptr->opt!=0; ptr++) - if ( ptr->opt == optarg[0] ) { - channel_model=ptr->m; - chMod=ptr->M; - break; - } + case 'a': + channel_model = AWGN; + chMod = 1; + break; - AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); - break; + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + chMod=ptr->M; + break; + } + + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); + break; - case 'x': - transmission_m=atoi(optarg); - AssertFatal(transmission_m==1 || transmission_m==2, - "Unsupported transmission mode %d\n",transmission_m); - break; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); + break; - case 'r': - nb_rb = atoi(optarg); - nb_rb_set = 1; - break; + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; + break; //case 'c': // cyclic_shift = atoi(optarg); // break; - case 'i': - input_fdUL = fopen(optarg,"r"); - printf("Reading in %s (%p)\n",optarg,input_fdUL); - AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); - break; + case 'i': + input_fdUL = fopen(optarg,"r"); + printf("Reading in %s (%p)\n",optarg,input_fdUL); + AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); + break; - case 'A': - beta_ACK = atoi(optarg); - AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); - break; + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); + break; - case 'C': - beta_CQI = atoi(optarg); - AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); - break; + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); + break; - case 'R': - beta_RI = atoi(optarg); - AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); - break; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); + break; - case 'P': - dump_perf=1; - opp_enabled=1; - break; + case 'P': + dump_perf=1; + opp_enabled=1; + break; - default: - printf("Wrong option\n"); - exit(1); - break; + default: + printf("Wrong option: %s\n",long_options[option_index].name); + exit(1); + break; } } @@ -694,34 +612,12 @@ int main(int argc, char **argv) { exit(1); } - paramdef_t *ptr=options ; - - for( ptr=options; ptr->optname[0]!=0; ptr++) { - char varText[256]="need specific display"; - if (ptr->voidptr != NULL) { - if ( (ptr->paramflags & PARAMFLAG_BOOL) ) - strcpy(varText, *(bool *)ptr->iptr ? "True": "False" ); - else switch (ptr->type) { - case TYPE_INT: - sprintf(varText,"%d",*ptr->iptr); - break; - - case TYPE_DOUBLE: - sprintf(varText,"%.2f",*ptr->dblptr); - break; - - default: - printf("not decoded type\n"); - exit(1); - } - } - - printf("Option: %20s set to %s\n",ptr->optname, varText); - - if (verbose) - printf("%s\n",ptr->helpstr); - } + if (help || verbose ) + display_options_values(options, true); + if (help) + exit(0); + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_worker_conf("WORKER_ENABLE"); RC.nb_L1_inst = 1; -- GitLab