issue 359 dlsim CPU measurements
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
+284
-495
@@ -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,38 +726,97 @@ 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) {
|
||||
|
||||
struct option * long_options = parse_oai_options(options);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (long_options[option_index].name[0]) {
|
||||
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;
|
||||
|
||||
case 'c':
|
||||
num_pdcch_symbols=atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
Nid_cell = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
dci_flag = 1;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
frame_type=TDD;
|
||||
break;
|
||||
@@ -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,139 +838,51 @@ 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);
|
||||
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;
|
||||
|
||||
switch((char)*optarg) {
|
||||
case 'A':
|
||||
channel_model=SCM_A;
|
||||
for (ptr=tmp; ptr->opt!=0; ptr++)
|
||||
if ( ptr->opt == optarg[0] ) {
|
||||
channel_model=ptr->m;
|
||||
break;
|
||||
}
|
||||
|
||||
AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg );
|
||||
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;
|
||||
|
||||
case 'N':
|
||||
channel_model=AWGN;
|
||||
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;
|
||||
UE->use_ia_receiver = 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_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 = (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;
|
||||
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 > 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)
|
||||
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);
|
||||
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");
|
||||
|
||||
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("\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,
|
||||
|
||||
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);
|
||||
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,"%f;%f;%f;%f\n",
|
||||
squareRoot(&UE->dlsch_decoding_stats[subframe]),
|
||||
median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));
|
||||
|
||||
|
||||
/*
|
||||
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);
|
||||
*/
|
||||
printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
|
||||
test_passed = 1;
|
||||
break;
|
||||
|
||||
+122
-226
@@ -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_INT:
|
||||
*(int *)options[option_index].iptr=atoi(optarg);
|
||||
break;
|
||||
|
||||
case TYPE_DOUBLE:
|
||||
*(double *)options[option_index].dblptr=atof(optarg);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
*(double *)options[option_index].dblptr=atof(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("not decoded type.\n");
|
||||
exit(1);
|
||||
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 'T':
|
||||
tdd_config=atoi(optarg);
|
||||
frame_type=TDD;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
channel_model = AWGN;
|
||||
chMod = 1;
|
||||
break;
|
||||
case 'a':
|
||||
channel_model = AWGN;
|
||||
chMod = 1;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user