diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 14230c125f..bae8dcfd97 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -209,6 +209,15 @@ RUs = ( } ); +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 8a66e3131f..673d5a7957 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -209,6 +209,15 @@ RUs = ( } ); +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index ede864b733..fd9de112dc 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -209,6 +209,15 @@ RUs = ( } ); +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 589f389850..febd50f726 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -326,26 +326,13 @@ class SSHConnection(): loopCounter = loopCounter - 1 if (loopCounter == 0): doLoop = False - # Checking if process is still alive - #self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) - #result = re.search('lte-softmodem', str(self.ssh.before)) - #if result is None: - # self.command('rsync -v enb_' + SSH.testCase_id + '.log enb_' + SSH.testCase_id + '.txt; stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --color=never -i "segmentation fault"', '\$', 5) - # result = re.search('egmentation fault', str(self.ssh.before)) - # logging.debug('\u001B[1;37;41m eNB process is already down \u001B[0m') - # if result is not None: - # logging.debug('\u001B[1;37;41m Segmentation fault \u001B[0m') - # logging.debug(str(self.ssh.before)) - # self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', 0) - # self.CreateHtmlFooter() - # self.close() - # sys.exit(1) - logging.debug('\u001B[1;30;43m eNB logging system did not show got sync! See with attach later \u001B[0m') - self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'eNB not showing got sync!', 0) - # Not getting got sync is bypassed for the moment - #sys.exit(1) + logging.error('\u001B[1;37;41m eNB logging system did not show got sync! See with attach later \u001B[0m') + self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', 0) + self.CreateHtmlFooter() + self.close() + sys.exit(1) else: - self.command('rsync -v enb_' + SSH.testCase_id + '.log enb_' + SSH.testCase_id + '.txt; stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | grep --color=never -i sync', '\$', 4) + self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | grep --color=never -i sync', '\$', 4) result = re.search('got sync', str(self.ssh.before)) if result is None: time.sleep(6) @@ -354,7 +341,6 @@ class SSHConnection(): self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', 0) logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') - self.command('rm -f enb_' + SSH.testCase_id + '.txt', '\$', 5) self.close() def InitializeUE_common(self, device_id): diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml index e364d9acd4..6023046a86 100644 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -21,7 +21,7 @@ --> - 010101 050101 060101 070101 040101 030104 040301 040501 040602 040601 040603 040401 040201 030201 030105 040301 040502 040702 040701 040401 040201 030201 050201 060201 070201 + 010101 050101 060101 070101 040101 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 030105 040301 040502 040612 040611 040613 040652 040651 040653 040401 040201 030201 050201 060201 070201 @@ -42,6 +42,12 @@ -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw + + Initialize_eNB + Initialize eNB (TDD/Band40/20MHz/info) + -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw + + Terminate_eNB Terminate eNB @@ -105,7 +111,7 @@ unbalanced - + Iperf iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) -u -b 13.5M -t 30 -i 1 @@ -113,7 +119,7 @@ balanced - + Iperf iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) -u -b 13.5M -t 30 -i 1 @@ -121,27 +127,58 @@ single-ue + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 13.5M -t 30 -i 1 + 50 + unbalanced + Iperf - iperf (5MHz - UL/1Mbps/UDP)(30 sec)(single-ue) - -u -b 1M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/1Mbps/UDP)(30 sec)(balanced) - -u -b 1M -t 30 -i 1 -R + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 -i 1 -R 50 balanced + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + Iperf - iperf (5MHz - UL/8Mbps/UDP)(30 sec)(unbalanced) - -u -b 8M -t 30 -i 1 -R + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 -i 1 -R + 50 + unbalanced + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 -i 1 -R 50 unbalanced diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5bf07dae01..23d96afc54 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2126,7 +2126,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index f0b3256015..e7f274c2d0 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -990,12 +990,12 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/ulsim.Rel14 - -B25 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B25 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 - -B50 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B50 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 - -B100 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 - -B100 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 + -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=100 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6 "passed" segmentation fault|assertion|exiting|fatal diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 25898d0b8c..1bb36bd2e5 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -76,7 +76,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { init_unscrambling_lut(); init_scrambling_lut(); //set_taus_seed(1328); - init_7_5KHz(); +// init_7_5KHz(); init_sss(); } diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index 1ceed40f8b..3a1364620e 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -31,6 +31,8 @@ #include "assertions.h" #include +void init_7_5KHz(void); + int phy_init_RU(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; @@ -65,6 +67,7 @@ int phy_init_RU(RU_t *ru) { } if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + init_7_5KHz(); LOG_I(PHY,"nb_tx %d\n",ru->nb_tx); ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); for (i=0;inb_rx;i++) { diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 1ed9e20d60..bcdd782073 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -34,6 +34,8 @@ #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_REFSIG/lte_refsig.h" +void init_7_5KHz(void); + uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10}; extern uint8_t nfapi_mode; @@ -662,6 +664,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, init_frame_parms(&ue->frame_parms,1); init_lte_top(&ue->frame_parms); + init_7_5KHz(); init_ul_hopping(&ue->frame_parms); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index ded0905388..30c106b16b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -363,7 +363,7 @@ void *te_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return(NULL); } - /*if(opp_enabled == 1 && te_wakeup_stats0->diff_now>50*3000){ + /*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){ print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr); printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); }*/ @@ -573,7 +573,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, } stop_meas(te_wait_stats); - /*if(opp_enabled == 1 && te_wait_stats->diff_now>100*3000){ + /*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){ print_meas_now(te_wait_stats,"coding_wait",stderr); printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); }*/ diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 50b09102d8..e8f20c85de 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -782,7 +782,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if DISABLE_LOG_X printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif // MRC diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index cb77759040..b37f146b0a 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -52,8 +52,8 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ if (ts->trials>0) { - //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now); - fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now); + //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->p_time/(cpu_freq_GHz*1000000.0)),subframe,ts->p_time); + fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->p_time/(cpu_freq_GHz*1000.0)),(double)ts->p_time); } } diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index 32e6883d56..eac057095a 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -40,7 +40,6 @@ typedef struct { long long in; long long diff; - long long diff_now; long long p_time; /*!< \brief absolute process duration */ long long diff_square; /*!< \brief process duration square */ long long max; @@ -50,7 +49,6 @@ typedef struct { #elif defined(__arm__) typedef struct { uint32_t in; - uint32_t diff_now; uint32_t diff; uint32_t p_time; /*!< \brief absolute process duration */ uint32_t diff_square; /*!< \brief process duration square */ @@ -116,9 +114,6 @@ static inline void stop_meas(time_stats_t *ts) if (opp_enabled) { long long out = rdtsc_oai(); - ts->diff_now = (out-ts->in); - - ts->diff_now = (out-ts->in); ts->diff += (out-ts->in); /// process duration is the difference between two clock points ts->p_time = (out-ts->in); @@ -135,7 +130,6 @@ static inline void reset_meas(time_stats_t *ts) { ts->trials=0; ts->diff=0; - ts->diff_now=0; ts->p_time=0; ts->diff_square=0; ts->max=0; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index b49613b749..276006ec3b 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -412,7 +412,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, &eNB->dlsch_turbo_encoding_wakeup_stats1, &eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_encoding_stats); - if(eNB->dlsch_encoding_stats.diff_now>500*3000 && opp_enabled == 1) + if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) { print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); } @@ -1337,7 +1337,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) ret, ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK, - eNB->ulsch_decoding_stats.diff_now, eNB->ulsch_decoding_stats.max); + eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered @@ -2084,7 +2084,4 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); - - stop_meas(&eNB->phy_proc_rx); - } diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index 6272650f72..6a2fef6822 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -50,10 +50,6 @@ #include "targets/RT/USER/rt_wrapper.h" -// RU OFDM Modulator, used in IF4p5 RRU, RCC/RAU with IF5, eNodeB - -extern openair0_config_t openair0_cfg[MAX_CARDS]; - extern int oai_exit; @@ -160,7 +156,7 @@ static void *feptx_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } - /*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.diff_now>30*3000){ + /*if(opp_enabled == 1 && ru->ofdm_mod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_mod_wakeup_stats,"fep wakeup",stderr); printf("delay in fep wakeup in frame_tx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); }*/ @@ -220,7 +216,7 @@ void feptx_ofdm_2thread(RU_t *ru) { start_meas(&ru->ofdm_mod_wait_stats); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); stop_meas(&ru->ofdm_mod_wait_stats); - /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.diff_now>30*3000){ + /*if(opp_enabled == 1 && ru->ofdm_mod_wait_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_mod_wait_stats,"fep wakeup",stderr); printf("delay in feptx wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_tx,proc->subframe_tx); }*/ @@ -467,7 +463,7 @@ static void *fep_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return NULL; } - /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + /*if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); printf("delay in fep wakeup in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); }*/ @@ -582,7 +578,7 @@ void ru_fep_full_2thread(RU_t *ru) { start_meas(&ru->ofdm_demod_wait_stats); wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); stop_meas(&ru->ofdm_demod_wait_stats); - if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.diff_now>30*3000){ + if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 89c0d09b1d..8c09da1daf 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1,33 +1,33 @@ /* - * 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 - \author R. Knopp - \date 2011 - 2014 - \version 0.1 - \company Eurecom - \email: knopp@eurecom.fr - \note - \warning + \brief Top-level UL simulator + \author R. Knopp + \date 2011 - 2014 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr + \note + \warning */ #include @@ -58,21 +58,43 @@ #include "common/config/config_load_configmodule.h" 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"); +} 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 abstraction +//Added for PHY abstractionopenair1/PHY/TOOLS/lte_phy_scope.h node_desc_t *enb_data[NUMBER_OF_eNB_MAX]; node_desc_t *ue_data[NUMBER_OF_UE_MAX]; //double sinr_bler_map[MCS_COUNT][2][16]; extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16]; //extern char* namepointer_chMag ; - int xforms=0; FD_lte_phy_scope_enb *form_enb; char title[255]; @@ -88,6 +110,8 @@ int nfapi_mode = 0; extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; @@ -124,32 +148,29 @@ WORKER_CONF_t get_thread_worker_conf(void) void fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint8_t cqi_req, - uint8_t p_eNB, - uint8_t cqi_ReportModeAperiodic, - uint8_t betaOffset_CQI_Index, - uint8_t betaOffset_RI_Index, - uint8_t dl_cqi_pmi_size, - uint8_t tmode, - uint32_t handle, - uint16_t rnti, - uint8_t resource_block_start, - uint8_t number_of_resource_blocks, - uint8_t modulation_type, - uint8_t cyclic_shift_2_for_drms, - uint8_t frequency_hopping_enabled_flag, - uint8_t frequency_hopping_bits, - uint8_t new_data_indication, - uint8_t redundancy_version, - uint8_t harq_process_number, - uint8_t ul_tx_mode, - uint8_t current_tx_nb, - uint8_t n_srs, - uint16_t size) -{ + uint8_t cqi_req, + uint8_t p_eNB, + uint8_t cqi_ReportModeAperiodic, + uint8_t betaOffset_CQI_Index, + uint8_t betaOffset_RI_Index, + uint8_t dl_cqi_pmi_size, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t modulation_type, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) { memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; @@ -181,15 +202,15 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); if (p_eNB <= 2 - && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; for (int ri = 0; - ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); - ri++) - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; @@ -197,587 +218,538 @@ fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, } void fill_ulsch_dci(PHY_VARS_eNB *eNB, - int frame, - int subframe, - Sched_Rsp_t *sched_resp, - uint16_t rnti, - void *UL_dci, - int first_rb, - int nb_rb, - int mcs, - int modulation_type, - int ndi, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint16_t rnti, + void *UL_dci, + int first_rb, + int nb_rb, + int mcs, + int modulation_type, + int ndi, int TBS, - int cqi_flag, - uint8_t beta_CQI, - uint8_t beta_RI, - uint8_t cqi_size) { - + int cqi_flag, + uint8_t beta_CQI, + uint8_t beta_RI, + uint8_t cqi_size) { nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; int harq_pid = ((frame*10)+subframe)&7; //printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi); switch (eNB->frame_parms.N_RB_UL) { - case 6: - break; + case 6: + break; - case 25: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_5MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_5MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci); - ((DCI0_5MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_5MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_5MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_5MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_5MHz_FDD_t*)UL_dci)->cshift = 0; - } + case 25: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_5MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_5MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci); + ((DCI0_5MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_5MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_5MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_5MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_5MHz_FDD_t *)UL_dci)->cshift = 0; + } - break; + break; - case 50: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_10MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_10MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_10MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_10MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_10MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_10MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_10MHz_FDD_t*)UL_dci)->cshift = 0; - } + case 50: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_10MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_10MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_10MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_10MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_10MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_10MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_10MHz_FDD_t *)UL_dci)->cshift = 0; + } - break; + break; - case 100: - if (eNB->frame_parms.frame_type == TDD) { - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->type = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->TPC = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cshift = 0; - ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->dai = 1; - } else { - ((DCI0_20MHz_FDD_t*)UL_dci)->type = 0; - ((DCI0_20MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 - // printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci); - ((DCI0_20MHz_FDD_t*)UL_dci)->mcs = mcs; - ((DCI0_20MHz_FDD_t*)UL_dci)->ndi = ndi; - ((DCI0_20MHz_FDD_t*)UL_dci)->TPC = 0; - ((DCI0_20MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; - ((DCI0_20MHz_FDD_t*)UL_dci)->cshift = 0; - } + case 100: + if (eNB->frame_parms.frame_type == TDD) { + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->type = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci); + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->ndi = ndi; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->TPC = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cshift = 0; + ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->dai = 1; + } else { + ((DCI0_20MHz_FDD_t *)UL_dci)->type = 0; + ((DCI0_20MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8 + // printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci); + ((DCI0_20MHz_FDD_t *)UL_dci)->mcs = mcs; + ((DCI0_20MHz_FDD_t *)UL_dci)->ndi = ndi; + ((DCI0_20MHz_FDD_t *)UL_dci)->TPC = 0; + ((DCI0_20MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1; + ((DCI0_20MHz_FDD_t *)UL_dci)->cshift = 0; + } - break; + break; - default: - break; + default: + break; } fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], - cqi_flag&1, - 1, // p_eNB - 0, // reportmode Aperiodic - beta_CQI, - beta_RI, - cqi_size, - //cc, - //UE_template->physicalConfigDedicated, - 1, - 0, - 14, // rnti - first_rb, // resource_block_start - nb_rb, // number_of_resource_blocks - modulation_type, - 0, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - mcs>28?(mcs-28):0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - TBS); - + cqi_flag&1, + 1, // p_eNB + 0, // reportmode Aperiodic + beta_CQI, + beta_RI, + cqi_size, + //cc, + //UE_template->physicalConfigDedicated, + 1, + 0, + 14, // rnti + first_rb, // resource_block_start + nb_rb, // number_of_resource_blocks + modulation_type, + 0, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + mcs>28?(mcs-28):0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + TBS); sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req->number_of_pdus=1; ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } -extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-50s %.2f us (%d trials)\n", + txt, + inMicroS(ptr->diff/ptr->trials), + ptr->trials); +} -int main(int argc, char **argv) -{ +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); +} - char c; +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; + +int main(int argc, char **argv) { int i,j,aa,u; PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; RU_t *ru; int aarx,aatx; double channelx,channely; - double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; - double input_snr_step=.2,snr_int=30; + static double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; + static double input_snr_step=.2,snr_int=30; double blerr; - int rvidx[8]={0,2,3,1,0,2,3,1}; + int rvidx[8]= {0,2,3,1,0,2,3,1}; int **txdata; - LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720]; double r_re2[30720],r_im2[30720]; double r_re3[30720],r_im3[30720]; - double *s_re[2]={s_re0,s_re1}; - double *s_im[2]={s_im0,s_im1}; - double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; - double *r_im[4]={r_im0,r_im1,r_im2,r_im3}; + double *s_re[2]= {s_re0,s_re1}; + double *s_im[2]= {s_im0,s_im1}; + double *r_re[4]= {r_re0,r_re1,r_re2,r_re3}; + double *r_im[4]= {r_im0,r_im1,r_im2,r_im3}; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; - uint8_t extended_prefix_flag=0; - int cqi_flag=0,cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives; + int cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives; int ch_realization; int eNB_id = 0; int chMod = 0 ; int UE_id = 0; - unsigned char nb_rb=25,first_rb=0,mcs=0,round=0,bundling_flag=1; + static int nb_rb=25,first_rb=0,mcs=0,round=0; //unsigned char l; - - unsigned char awgn_flag = 0 ; + static int awgn_flag = 0 ; SCM_t channel_model=Rice1; - - - unsigned char *input_buffer,harq_pid; + unsigned char *input_buffer=0,harq_pid; unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - int subframe=3; unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0}; - uint8_t transmission_mode=1,n_rx=1; - FILE *bler_fd=NULL; char bler_fname[512]; - FILE *time_meas_fd=NULL; char time_meas_fname[256]; - FILE *input_fdUL=NULL,*trch_out_fdUL=NULL; // unsigned char input_file=0; char input_val_str[50],input_val_str2[50]; - // FILE *rx_frame_file; FILE *csv_fdUL=NULL; - /* - FILE *fperen=NULL; - char fperen_name[512]; + FILE *fperen=NULL; + char fperen_name[512]; - FILE *fmageren=NULL; - char fmageren_name[512]; + FILE *fmageren=NULL; + char fmageren_name[512]; - FILE *flogeren=NULL; - char flogeren_name[512]; + FILE *flogeren=NULL; + char flogeren_name[512]; */ - /* FILE *ftxlev; char ftxlev_name[512]; */ - char csv_fname[512]; - int n_frames=5000; - int n_ch_rlz = 1; - int abstx = 0; + static int n_frames=5000; + static int n_ch_rlz = 1; + static int abstx = 0; int hold_channel=0; channel_desc_t *UE2eNB; - //uint8_t control_only_flag = 0; - int delay = 0; - double maxDoppler = 0.0; - uint8_t srs_flag = 0; - - uint8_t N_RB_DL=25,osf=1; - + static int delay = 0; + static double maxDoppler = 0.0; + static int srs_flag = 0; + static int N_RB_DL=25,osf=1; //uint8_t cyclic_shift = 0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; - uint8_t tdd_config=3,frame_type=FDD; - - uint8_t N0=30; - double tx_gain=1.0; + static uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; + static uint8_t tdd_config=3,frame_type=FDD; + static int N0=30; + static double tx_gain=1.0; double cpu_freq_GHz; - int avg_iter,iter_trials; - + int iter_trials; uint32_t UL_alloc_pdu; int s,Kr,Kr_bytes; int dump_perf=0; - int test_perf=0; - int dump_table =0; - + static int dump_table =0; double effective_rate=0.0; - char channel_model_input[10]; - - uint8_t max_turbo_iterations=4; - uint8_t parallel_flag=0; + char channel_model_input[10]= {0}; + static int max_turbo_iterations=4; + static int parallel_flag=0; int nb_rb_set = 0; int sf; - - int threequarter_fs=0; + static int threequarter_fs=0; int ndi; - opp_enabled=1; // to enable the time meas - sched_resp.DL_req = &DL_req; sched_resp.UL_req = &UL_req; sched_resp.HI_DCI0_req = &HI_DCI0_req; sched_resp.TX_req = &TX_req; - memset((void*)&DL_req,0,sizeof(DL_req)); - memset((void*)&UL_req,0,sizeof(UL_req)); - memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); - memset((void*)&TX_req,0,sizeof(TX_req)); - + memset((void *)&DL_req,0,sizeof(DL_req)); + memset((void *)&UL_req,0,sizeof(UL_req)); + memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void *)&TX_req,0,sizeof(TX_req)); UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; - cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; - printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); AssertFatal(load_configmodule(argc,argv) != NULL, - "cannot load configuration module, exiting\n"); - + "cannot load configuration module, exiting\n"); logInit(); - // enable these lines if you need debug info // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); //set_comp_log(PHY,LOG_DEBUG,LOG_MED,1); //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 }, + { "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 }, + { "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 }, + { "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 }, + { "delay_chan", "Channel delay",0, iptr:&delay, defintval:0, TYPE_INT, 0 }, + { "Doppler", "Maximum doppler shift",0, dblptr:&maxDoppler, defdblval:0.0, TYPE_DOUBLE, 0 }, + { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, + { "Forms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, + { "Lparallel", "Enable parallel execution", PARAMFLAG_BOOL, iptr:¶llel_flag, defintval:0, TYPE_INT, 0 }, + { "Iterations", "Number of iterations of turbo decoder", 0, iptr:&max_turbo_iterations, defintval:4, TYPE_INT, 0 }, + { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Q_cqi", "Enable CQI", PARAMFLAG_BOOL, iptr:&cqi_flag, defintval:0, TYPE_INT, 0 }, + { "prefix_extended","Extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 }, + { "RI_beta", "TBD", 0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "CQI_beta", "TBD",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "ACK_beta", "TBD",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "N0", "N0",0, iptr:&N0, defintval:30, TYPE_INT, 0 }, + { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 }, + { "TDD", "Enable TDD and set the tdd configuration mode",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "Subframe", "subframe to use",0, iptr:&subframe, defintval:3, TYPE_INT, 0 }, + { "xTransmission","transmission mode (1 or 2 are supported)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "yN_rx", "TBD: n_rx",0, iptr:&n_rx, defintval:1, TYPE_INT, 0 }, + { "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 }, + { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + }; + int l; - while ((c = getopt (argc, argv, "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")) != -1) { - switch (c) { - case 'a': - channel_model = AWGN; - chMod = 1; - break; + for(l=0; options[l].optname[0]!=0; l++) {}; - case 'b': - bundling_flag = 0; - break; + struct option *long_options=calloc(sizeof(struct option),l); - case 'd': - delay = atoi(optarg); - break; + 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; - case 'D': - maxDoppler = atoi(optarg); - break; + if ( options[i].voidptr) + switch (options[i].type) { + case TYPE_INT: + *options[i].iptr=options[i].defintval; + break; - case 'm': - mcs = atoi(optarg); - break; + case TYPE_DOUBLE: + *options[i].dblptr=options[i].defdblval; + break; - case 'n': - n_frames = atoi(optarg); - break; + default: + printf("not parsed type for default value %s\n", options[i].optname ); + exit(1); + } - case 'Y': - n_ch_rlz = atoi(optarg); - break; + continue; + }; - case 'X': - abstx= atoi(optarg); - break; + int option_index; - case 'g': - sprintf(channel_model_input,optarg,10); + int res; - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; - chMod = 2; + 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; + + 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 'B': - channel_model=SCM_B; - chMod = 3; - break; - - case 'C': - channel_model=SCM_C; - chMod = 4; - break; - - case 'D': - channel_model=SCM_D; - chMod = 5; - break; - - case 'E': - channel_model=EPA; - chMod = 6; - break; - - case 'F': - channel_model=EVA; - chMod = 7; - break; - - case 'G': - channel_model=ETU; - chMod = 8; - break; - - case 'H': - channel_model=Rayleigh8; - chMod = 9; - break; - - case 'I': - channel_model=Rayleigh1; - chMod = 10; - break; - - case 'J': - channel_model=Rayleigh1_corr; - chMod = 11; - break; - - case 'K': - channel_model=Rayleigh1_anticorr; - chMod = 12; - break; - - case 'L': - channel_model=Rice8; - chMod = 13; - break; - - case 'M': - channel_model=Rice1; - chMod = 14; - break; - - case 'N': - channel_model=AWGN; + case 'a': + channel_model = AWGN; chMod = 1; break; - default: - printf("Unsupported channel model!\n"); - exit(-1); + 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; - } - break; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); + break; - case 's': - snr0 = atof(optarg); - break; + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; + break; - case 'w': - snr_int = atof(optarg); - break; + //case 'c': + // cyclic_shift = atoi(optarg); + // break; - case 'e': - input_snr_step= atof(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 'x': - transmission_mode=atoi(optarg); + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); + break; - if ((transmission_mode!=1) && - (transmission_mode!=2)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); + break; - break; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); + break; - case 'y': - n_rx = atoi(optarg); - break; + case 'P': + dump_perf=1; + opp_enabled=1; + break; - case 'S': - subframe = atoi(optarg); - break; - - case 'T': - tdd_config=atoi(optarg); - frame_type=TDD; - break; - - case 'p': - extended_prefix_flag=1; - break; - - case 'r': - nb_rb = atoi(optarg); - nb_rb_set = 1; - break; - - case 'f': - first_rb = atoi(optarg); - break; - - //case 'c': - // cyclic_shift = atoi(optarg); - // break; - - case 'E': - threequarter_fs=1; - break; - - case 'N': - N0 = atoi(optarg); - break; - - case 'o': - srs_flag = 1; - break; - - case 'i': - input_fdUL = fopen(optarg,"r"); - printf("Reading in %s (%p)\n",optarg,input_fdUL); - - if (input_fdUL == (FILE*)NULL) { - printf("Unknown file %s\n",optarg); - exit(-1); - } - - // input_file=1; - break; - - case 'A': - beta_ACK = atoi(optarg); - - if (beta_ACK>15) { - printf("beta_ack must be in (0..15)\n"); - exit(-1); - } - - break; - - case 'C': - beta_CQI = atoi(optarg); - - if ((beta_CQI>15)||(beta_CQI<2)) { - printf("beta_cqi must be in (2..15)\n"); - exit(-1); - } - - break; - - case 'R': - beta_RI = atoi(optarg); - - if ((beta_RI>15)||(beta_RI<2)) { - printf("beta_ri must be in (0..13)\n"); - exit(-1); - } - - break; - - case 'Q': - cqi_flag=1; - break; - - case 'B': - N_RB_DL=atoi(optarg); - break; - - case 'P': - dump_perf=1; - opp_enabled=1; - break; - - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; - - case 'L': - parallel_flag=1; - break; - - case 'I': - max_turbo_iterations=atoi(optarg); - break; - - case 'F': - xforms=1; - break; - - case 'Z': - dump_table = 1; - break; - - case 'h': - default: - /* option "-c cyclic_shift" is not used, let's remove from documentation */ - //printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -c cyclic_shift -o (srs on) -g channel_model [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'), -d Channel delay, -D maximum Doppler shift \n", - printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -o (srs on) -g channel_model [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'), -d Channel delay, -D maximum Doppler shift \n", - argv[0]); - exit(1); - break; + default: + printf("Wrong option\n"); + exit(1); + break; } } + + if ( res != -1 ) { + printf("A wrong option has been found\n"); + 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); + } set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_worker_conf("WORKER_ENABLE"); RC.nb_L1_inst = 1; RC.nb_RU = 1; - lte_param_init(&eNB,&UE,&ru, - 1, - 1, - n_rx, 1, - 1, - extended_prefix_flag, - frame_type, - 0, - tdd_config, - N_RB_DL, - 4, - threequarter_fs, - osf, - 0); - + 1, + n_rx, + 1, + 1, + extended_prefix_flag, + frame_type, + 0, + tdd_config, + N_RB_DL, + 4, + threequarter_fs, + osf, + 0); RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); RC.ru = (RU_t **)malloc(sizeof(RC.ru)); RC.eNB[0][0] = eNB; RC.ru[0] = ru; - for (int k=0;kRU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; - memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + for (int k=0; kRU_list[0]->nb_rx; k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; + memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); printf("Setting indication lists\n"); eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; @@ -785,12 +757,10 @@ int main(int argc, char **argv) eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; - printf("lte_param_init done\n"); - // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE - PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); - PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); + PHY_vars_UE_g = (PHY_VARS_UE ***)malloc(sizeof(PHY_VARS_UE **)); + PHY_vars_UE_g[0] = (PHY_VARS_UE **) malloc(sizeof(PHY_VARS_UE *)); PHY_vars_UE_g[0][0] = UE; if (nb_rb_set == 0) @@ -799,19 +769,14 @@ int main(int argc, char **argv) printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]); printf("Setting mcs = %d\n",mcs); printf("n_frames = %d\n", n_frames); - snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; - txdata = UE->common_vars.txdata; - nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12; - - sprintf(bler_fname,"ULbler_mcs%d_nrb%d_ChannelModel%d_nsim%d.csv",mcs,nb_rb,chMod,n_frames); bler_fd = fopen(bler_fname,"w"); + if (bler_fd==NULL) { fprintf(stderr,"Problem creating file %s\n",bler_fname); exit(-1); @@ -828,8 +793,9 @@ int main(int argc, char **argv) //sprintf(dirname, "%s//SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname); //mkdir(dirname, 0777); sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_antrx%d_channel%s_tx%d.csv", - N_RB_DL,mcs,n_rx,channel_model_input,transmission_mode); + N_RB_DL,mcs,n_rx,channel_model_input,transmission_m); time_meas_fd = fopen(time_meas_fname,"w"); + if (time_meas_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); exit(-1); @@ -838,16 +804,17 @@ int main(int argc, char **argv) if(abstx) { // CSV file - sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_mode,mcs,nb_rb,chMod,n_frames); + sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_m,mcs,nb_rb,chMod,n_frames); csv_fdUL = fopen(csv_fname,"w"); + if (csv_fdUL == NULL) { fprintf(stderr,"Problem opening file %s\n",csv_fname); exit(-1); } + fprintf(csv_fdUL,"data_all%d=[",mcs); } - if (xforms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_enb = create_lte_phy_scope_enb(); @@ -856,7 +823,6 @@ int main(int argc, char **argv) } UE->pdcch_vars[0][0]->crnti = 14; - UE->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; @@ -867,7 +833,6 @@ int main(int argc, char **argv) UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0; UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0; UE->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = 0; - eNB->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; @@ -878,29 +843,22 @@ int main(int argc, char **argv) eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0; eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; - - eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI; UE->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK; UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = beta_RI; UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI; - UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1; - // disable periodic cqi/ri reporting UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - - printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); - UE2eNB = new_channel_desc_scm(1, n_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), forgetting_factor, delay, 0); @@ -908,7 +866,8 @@ int main(int argc, char **argv) UE2eNB->max_Doppler = maxDoppler; // NN: N_RB_UL has to be defined in ulsim - for (int k=0;kulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0; kulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); printf("ULSCH %p\n",UE->ulsch[0]); @@ -918,70 +877,66 @@ int main(int argc, char **argv) init_fep_thread(eNB,NULL); init_td_thread(eNB); } + // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); + if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } + eNB->dlsch[0][i]->rnti = 14; } + /* allocate memory for both subframes (only one is really used - * but there is now "copy_harq_proc_struct" which needs both - * to be valid) - * TODO: refine this somehow (necessary?) - */ + but there is now "copy_harq_proc_struct" which needs both + to be valid) + TODO: refine this somehow (necessary?) + */ for (sf = 0; sf < 2; sf++) { for (i=0; i<2; i++) { UE->dlsch[sf][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + if (!UE->dlsch[sf][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } + UE->dlsch[sf][0][i]->rnti = 14; } } UE->dlsch_SI[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->dlsch_ra[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); - UE->measurements.rank[0] = 0; UE->transmission_mode[0] = 2; - UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing; + UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing; eNB->transmission_mode[0] = 2; - eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing; + eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - UE->mac_enabled=0; - eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; - proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; - printf("Init UL hopping UE\n"); init_ul_hopping(&UE->frame_parms); printf("Init UL hopping eNB\n"); init_ul_hopping(&eNB->frame_parms); - - UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; - UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb; @@ -989,26 +944,20 @@ int main(int argc, char **argv) if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O; rate = (double)dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1]/(coded_bits_per_codeword); - printf("Rate = %f (mod %d), coded bits %d\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword); - - for (ch_realization=0; ch_realizationofdm_symbol_size)]; } */ - if(abstx) { printf("**********************Channel Realization Index = %d **************************\n", ch_realization); saving_bler=1; } - // if ((subframe>5) || (subframe < 4)) // UE->frame++; @@ -1026,17 +975,17 @@ int main(int argc, char **argv) cqi_crc_falsepositives=0; cqi_crc_falsenegatives=0; round=0; - //randominit(0); - - harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe); input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8; + + if ( input_buffer != NULL ) + free(input_buffer); + input_buffer = (unsigned char *)memalign(32,input_buffer_length+64); + // printf("UL frame %d/subframe %d, harq_pid %d\n",UE->frame,subframe,harq_pid); if (input_fdUL == NULL) { - - if (n_frames == 1) { trch_out_fdUL= fopen("ulsch_trchUL.txt","w"); @@ -1058,14 +1007,15 @@ int main(int argc, char **argv) while (!feof(input_fdUL)) { ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + if (ret != 2) printf("ERROR: error reading file\n"); if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + ((short *)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short *)txdata[0])[i/4],((short *)txdata[0])[(i/4)+1]); //1,input_val2,); } i++; @@ -1080,10 +1030,8 @@ int main(int argc, char **argv) tx_lev = signal_energy(&txdata[0][0], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - avg_iter = 0; iter_trials=0; reset_meas(&UE->phy_proc_tx); reset_meas(&UE->ofdm_mod_stats); @@ -1094,7 +1042,6 @@ int main(int argc, char **argv) reset_meas(&UE->ulsch_turbo_encoding_stats); reset_meas(&UE->ulsch_segmentation_stats); reset_meas(&UE->ulsch_multiplexing_stats); - reset_meas(&eNB->phy_proc_rx); reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats); @@ -1104,6 +1051,7 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_deinterleaving_stats); reset_meas(&eNB->ulsch_demultiplexing_stats); reset_meas(&eNB->ulsch_rate_unmatching_stats); + reset_meas(&eNB->ulsch_demodulation_stats); reset_meas(&eNB->ulsch_tc_init_stats); reset_meas(&eNB->ulsch_tc_alpha_stats); reset_meas(&eNB->ulsch_tc_beta_stats); @@ -1111,91 +1059,82 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_tc_ext_stats); reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_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); - + 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)); + 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)); ndi=0; - phy_reset_ue(0,0,0); UE->UE_mode[eNB_id]=PUSCH; + SET_LOG_DEBUG(UE_TIMING); for (trials = 0; trialsframe++; // eNB->frame++; - ndi = (1-ndi); + ndi = (1-ndi); fflush(stdout); round=0; while (round < 4) { - proc_rxtx->frame_rx=1; - proc_rxtx->subframe_rx=subframe; - - proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); - proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); - - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); - proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; - + proc_rxtx->frame_rx=1; + proc_rxtx->subframe_rx=subframe; + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); + proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); + + if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); + round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; - UL_req.sfn_sf = (1<<4)+subframe; - if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); + if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); - int modulation_type; - if (mcs < 11) modulation_type = 2; - else if (mcs < 21) modulation_type = 4; - else if (mcs < 29) modulation_type = 6; + int modulation_type; + + if (mcs < 11) modulation_type = 2; + else if (mcs < 21) modulation_type = 4; + else if (mcs < 29) modulation_type = 6; else { - LOG_E(SIM,"mcs %i is not valid\n",mcs); - exit(-1); + LOG_E(SIM,"mcs %i is not valid\n",mcs); + exit(-1); } - fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,get_TBS_UL(mcs,nb_rb),cqi_flag,beta_CQI,beta_RI,cqi_size); + fill_ulsch_dci(eNB, proc_rxtx->frame_rx, subframe, &sched_resp, 14, + (void *)&UL_alloc_pdu, first_rb,nb_rb, (round==0)?mcs:(28+rvidx[round]), + modulation_type, ndi, get_TBS_UL(mcs,nb_rb), cqi_flag, beta_CQI, + beta_RI, cqi_size); + UE->ulsch_Msg3_active[eNB_id] = 0; + UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; - UE->ulsch_Msg3_active[eNB_id] = 0; - UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; - if (n_frames==1) printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); - generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, - 14, - (subframe+6)%10, - format0, - UE, - proc_rxtx_ue, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - 0, - srs_flag); - - sched_resp.subframe=(subframe+6)%10; - sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; - - schedule_response(&sched_resp); + if (n_frames==1) + printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); + generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, + 14, + (subframe+6)%10, + format0, + UE, + proc_rxtx_ue, + SI_RNTI, + 0, + P_RNTI, + CBA_RNTI, + 0, + srs_flag); + sched_resp.subframe=(subframe+6)%10; + sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + schedule_response(&sched_resp); ///////////////////// if (abstx) { @@ -1214,31 +1153,24 @@ int main(int argc, char **argv) /////////////////////////////////////// if (input_fdUL == NULL) { - - eNB->proc.frame_rx = 1; - eNB->proc.subframe_rx = subframe; - ru->proc.frame_rx = 1; - ru->proc.subframe_rx = subframe; - - proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; - proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; - - phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx); - - - tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], - eNB->frame_parms.samples_per_tti); - + eNB->proc.frame_rx = 1; + eNB->proc.subframe_rx = subframe; + ru->proc.frame_rx = 1; + ru->proc.subframe_rx = subframe; + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; + phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx); + tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], + eNB->frame_parms.samples_per_tti); if (n_frames==1) { LOG_M("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1, - 1); + 1); //LOG_M("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); } - - } // input_fd == NULL + } // input_fd == NULL tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev); @@ -1251,21 +1183,17 @@ int main(int argc, char **argv) //Set target wideband RX noise level to N0 sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); - // compute tx_gain to achieve target SNR (per resource element!) tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); - - if (n_frames==1) + if (n_frames==1) printf("tx_lev = %d (%d.%d dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain)); - // fill measurement symbol (19) with noise for (i=0; iframe_parms.nb_antennas_rx; aa++) { - - ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -1293,7 +1221,6 @@ int main(int argc, char **argv) if (trials==0 && round==0) { // calculate freq domain representation to compute SINR freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1); - // snr=pow(10.0,.1*SNR); fprintf(csv_fdUL,"%f,%d,%d,%f,%f,%f,",SNR,tx_lev,tx_lev_dB,sigma2_dB,tx_gain,SNR2); @@ -1304,7 +1231,7 @@ int main(int argc, char **argv) // abs_channel = (eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x + eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y); channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].x; channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].y; - // if(transmission_mode==5){ + // if(transmission_m==5){ fprintf(csv_fdUL,"%e+i*(%e),",channelx,channely); // } // else{ @@ -1322,39 +1249,42 @@ int main(int argc, char **argv) for (i=0; iframe_parms.samples_per_tti; i++) { for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { - ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( - sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = + (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = + (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } } if (n_frames<=10) { - printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) - &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int *) + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) - + eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level data symbol %f\n", + 10*log10(signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); } - SNRmeas = 10*log10(((double)signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int*) + SNRmeas = 10*log10(((double)signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int *) &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb); if (n_frames<=10) { printf("SNRmeas %f\n",SNRmeas); + LOG_M("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - LOG_M("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - - ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; - eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - - - ru->feprx(ru); - phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); - + start_meas(&eNB->phy_proc_rx); + ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; + eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + ru->feprx(ru); + phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); + stop_meas(&eNB->phy_proc_rx); + if (cqi_flag > 0) { cqi_error = 0; @@ -1365,7 +1295,6 @@ int main(int argc, char **argv) cqi_error = 1; } } else { - } if (cqi_error == 1) { @@ -1383,15 +1312,10 @@ int main(int argc, char **argv) ack_errors++; // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); + // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { + iter_trials++; - - // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - - if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { - - // avg_iter += ret; - iter_trials++; - + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { if (n_frames==1) { printf("No ULSCH errors found, o_ACK[0]= %d, cqi_crc_status=%d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0],eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status); @@ -1405,9 +1329,6 @@ int main(int argc, char **argv) round=5; } else { - // avg_iter += ret-1; - iter_trials++; - errs[round]++; if (n_frames==1) { @@ -1420,7 +1341,6 @@ int main(int argc, char **argv) Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - printf("Decoded_output (Segment %d):\n",s); for (i=0; iproc.frame_rx,subframe,0,round); + if (round == 4) exit(-1); } - if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); + round++; if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } } // ulsch error - } // round // printf("\n"); if ((errs[0]>=100) && (trials>(n_frames/2))) break; - if (xforms==1) - phy_scope_eNB(form_enb,eNB,0); + if (xforms==1) + phy_scope_eNB(form_enb,eNB,0); - /*calculate the total processing time for each packet, get the max, min, and number of packets that exceed t>3000us*/ + double t_tx = inMicroS(UE->phy_proc_tx.p_time); + double t_tx_ifft = inMicroS(UE->ofdm_mod_stats.p_time); + double t_tx_mod = inMicroS(UE->ulsch_modulation_stats.p_time); + double t_tx_enc = inMicroS(UE->ulsch_encoding_stats.p_time); + double t_rx = inMicroS(eNB->phy_proc_rx.p_time); + double t_rx_fft = inMicroS(ru->ofdm_demod_stats.p_time); + double t_rx_demod = inMicroS(eNB->ulsch_demodulation_stats.p_time); + double t_rx_dec = inMicroS(eNB->ulsch_decoding_stats.p_time); - double t_tx = (double)UE->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)UE->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)UE->ulsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)UE->ulsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)eNB->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)ru->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)eNB->ulsch_demodulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)eNB->ulsch_decoding_stats.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) + 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_tx_mod, &t_tx_mod ); + appendVarArray(table_tx_enc, &t_tx_enc ); + 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 - 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,"The receiver raw data: \n"); + LOG_UDUMPMSG(SIM,dataArray(table_tx),table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver 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; - printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %d dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n", nb_rb,mcs,SNR,SNR2, tx_lev_dB, 20*log10(tx_gain), (double)N0, eNB->measurements.n0_power_tot_dB, - get_hundred_times_delta_IF(UE,eNB_id,harq_pid) , + get_hundred_times_delta_IF(UE,eNB_id,harq_pid), dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), eNB->measurements.n0_power_dB[0], eNB->measurements.n0_power_dB[1]); - effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); - printf("Errors (%d/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e) => effective rate %f (%3.1f%%,%f,%f), normalized delay %f (%f)\n", errs[0], round_trials[0], @@ -1608,7 +1454,6 @@ int main(int argc, char **argv) if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] > 0) printf("ACK/NAK errors %d/%d\n",ack_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]); - fprintf(bler_fd,"%f;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, mcs, @@ -1623,112 +1468,53 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3]); - + double timeBase=1/(1000*cpu_freq_GHz); if (dump_perf==1) { printf("UE TX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_tx = sqrt((double)UE->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_tx.trials - pow((double)UE->phy_proc_tx.diff/UE->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc tx :%f us (%d trials)\n",(double)UE->phy_proc_tx.diff/UE->phy_proc_tx.trials/cpu_freq_GHz/1000.0,UE->phy_proc_tx.trials); - printf("|__ Statistics std: %f us 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_ifft = sqrt((double)UE->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ofdm_mod_stats.trials - pow((double)UE->ofdm_mod_stats.diff/UE->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_mod time :%f us (%d trials)\n",(double)UE->ofdm_mod_stats.diff/UE->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,UE->ofdm_mod_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - std_phy_proc_tx_mod = sqrt((double)UE->ulsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ulsch_modulation_stats.trials - pow((double)UE->ulsch_modulation_stats.diff/UE->ulsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH modulation time :%f us (%d trials)\n",(double)UE->ulsch_modulation_stats.diff/UE->ulsch_modulation_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_modulation_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - std_phy_proc_tx_enc = sqrt((double)UE->ulsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ulsch_encoding_stats.trials - pow((double)UE->ulsch_encoding_stats.diff/UE->ulsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH encoding time :%f us (%d trials)\n",(double)UE->ulsch_encoding_stats.diff/UE->ulsch_encoding_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_encoding_stats.trials); - printf("|__ Statistics std: %f us median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - printf("|__ ULSCH segmentation time :%f us (%d trials)\n",(double)UE->ulsch_segmentation_stats.diff/UE->ulsch_segmentation_stats.trials/cpu_freq_GHz/1000.0, - UE->ulsch_segmentation_stats.trials); - printf("|__ ULSCH turbo encoding time :%f us (%d trials)\n", - ((double)UE->ulsch_turbo_encoding_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_turbo_encoding_stats.diff/UE->ulsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_turbo_encoding_stats.trials); - printf("|__ ULSCH rate-matching time :%f us (%d trials)\n", - ((double)UE->ulsch_rate_matching_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_rate_matching_stats.diff/UE->ulsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_rate_matching_stats.trials); - printf("|__ ULSCH sub-block interleaving time :%f us (%d trials)\n", - ((double)UE->ulsch_interleaving_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_interleaving_stats.diff/UE->ulsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_interleaving_stats.trials); - printf("|__ ULSCH multiplexing time :%f us (%d trials)\n", - ((double)UE->ulsch_multiplexing_stats.trials/UE->ulsch_encoding_stats.trials)*(double) - UE->ulsch_multiplexing_stats.diff/UE->ulsch_multiplexing_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_multiplexing_stats.trials); - - printf("\n\neNB RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)eNB->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->phy_proc_rx.trials - pow((double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_rx.trials); - 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)ru->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/ru->ofdm_demod_stats.trials - pow((double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_demod time :%f us (%d trials)\n",(double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - ru->ofdm_demod_stats.trials); - 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); - std_phy_proc_rx_demod = sqrt((double)eNB->ulsch_demodulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ulsch_demodulation_stats.trials - pow((double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH demodulation time :%f us (%d trials)\n",(double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000.0, - eNB->ulsch_demodulation_stats.trials); - 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); - std_phy_proc_rx_dec = sqrt((double)eNB->ulsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ulsch_decoding_stats.trials - pow((double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %f) :%f us (%d trials, max %f)\n", - UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)avg_iter/iter_trials, - (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_decoding_stats.trials, - (double)eNB->ulsch_decoding_stats.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("|__ sub-block interleaving %f us (%d trials)\n", - (double)eNB->ulsch_deinterleaving_stats.diff/eNB->ulsch_deinterleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_deinterleaving_stats.trials); - printf("|__ demultiplexing %f us (%d trials)\n", - (double)eNB->ulsch_demultiplexing_stats.diff/eNB->ulsch_demultiplexing_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_demultiplexing_stats.trials); - printf("|__ rate-matching %f us (%d trials)\n", - (double)eNB->ulsch_rate_unmatching_stats.diff/eNB->ulsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,eNB->ulsch_rate_unmatching_stats.trials); - printf("|__ turbo_decoder(%d bits) %f us (%d cycles, %d trials)\n", - eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : eNB->ulsch[0]->harq_processes[harq_pid]->Kplus, - (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0, - (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials),eNB->ulsch_turbo_decoding_stats.trials); - printf(" |__ init %f us (cycles/iter %f, %d trials)\n", - (double)eNB->ulsch_tc_init_stats.diff/eNB->ulsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_init_stats.diff/eNB->ulsch_tc_init_stats.trials/((double)avg_iter/iter_trials), - eNB->ulsch_tc_init_stats.trials); - printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", - (double)eNB->ulsch_tc_alpha_stats.diff/eNB->ulsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_alpha_stats.diff/eNB->ulsch_tc_alpha_stats.trials*2, - eNB->ulsch_tc_alpha_stats.trials); - printf(" |__ beta %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_beta_stats.diff/eNB->ulsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_beta_stats.diff/eNB->ulsch_tc_beta_stats.trials*2, - eNB->ulsch_tc_beta_stats.trials); - printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_gamma_stats.diff/eNB->ulsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_gamma_stats.diff/eNB->ulsch_tc_gamma_stats.trials*2, - eNB->ulsch_tc_gamma_stats.trials); - printf(" |__ ext %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_ext_stats.diff/eNB->ulsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_ext_stats.diff/eNB->ulsch_tc_ext_stats.trials*2, - eNB->ulsch_tc_ext_stats.trials); - printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_intl1_stats.diff/eNB->ulsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_intl1_stats.diff/eNB->ulsch_tc_intl1_stats.trials, - eNB->ulsch_tc_intl1_stats.trials); - printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n", - (double)eNB->ulsch_tc_intl2_stats.diff/eNB->ulsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0, - (double)eNB->ulsch_tc_intl2_stats.diff/eNB->ulsch_tc_intl2_stats.trials, - eNB->ulsch_tc_intl2_stats.trials); + printDistribution(&UE->phy_proc_tx,table_tx,"Total PHY proc tx"); + printDistribution(&UE->ofdm_mod_stats, table_tx_ifft, "OFDM_mod time"); + printDistribution(&UE->ulsch_modulation_stats,table_tx_mod, "ULSCH modulation time"); + printDistribution(&UE->ulsch_encoding_stats,table_tx_enc, "ULSCH encoding time"); + printStatIndent(&UE->ulsch_segmentation_stats,"ULSCH segmentation time"); + printStatIndent(&UE->ulsch_turbo_encoding_stats,"ULSCH turbo encoding time"); + printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time"); + printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving"); + printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time"); + printDistribution(&eNB->phy_proc_rx,table_rx,"\nTotal PHY proc rx subframe"); + printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"OFDM_demod time"); + printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"ULSCH demodulation time"); + printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %.2f) :%.2f us (%d trials, max %.2f)\n", + UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)iter_trials, + (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials*timeBase, + eNB->ulsch_decoding_stats.trials, + (double)eNB->ulsch_decoding_stats.max*timeBase); + printf("|__ Statistics std: %.2fus median %.2fus q1 %.2fus q3 %.2fus \n", + squareRoot(&eNB->ulsch_decoding_stats), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); + printStatIndent(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); + printStatIndent(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); + printStatIndent(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); + printf("|__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? + eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : + eNB->ulsch[0]->harq_processes[harq_pid]->Kplus, + eNB->ulsch_tc_intl1_stats.trials/(double)eNB->ulsch_tc_init_stats.trials, + (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials*timeBase, + (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials), + eNB->ulsch_turbo_decoding_stats.trials); + printStatIndent2(&eNB->ulsch_tc_init_stats,"init", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_alpha_stats,"alpha", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_beta_stats,"beta", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_gamma_stats,"gamma", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_ext_stats,"ext", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver", eNB->ulsch_tc_init_stats.trials); + printStatIndent2(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC", eNB->ulsch_tc_init_stats.trials); } if(abstx) { //ABSTRACTION blerr= (double)errs[1]/(round_trials[1]); //printf("hata yok XX,"); - - blerr = (double)errs[0]/(round_trials[0]); if(saving_bler==0) @@ -1736,12 +1522,9 @@ int main(int argc, char **argv) // printf("hata yok XX,"); - if(blerr<1) saving_bler = 0; else saving_bler =1; - - } //ABStraction if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { @@ -1759,7 +1542,6 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3]); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%f;%2.1f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%f;%f;", SNR, @@ -1783,7 +1565,6 @@ int main(int argc, char **argv) (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)eNB->ulsch[0]->harq_processes[harq_pid]->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])); - //fprintf(time_meas_fd,"UE_PROC_TX(%d); OFDM_MOD(%d); UL_MOD(%d); UL_ENC(%d); eNB_PROC_RX(%d); OFDM_DEMOD(%d); UL_DEMOD(%d); UL_DECOD(%d);\n", fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d;", UE->phy_proc_tx.trials, @@ -1805,52 +1586,52 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_decoding_stats) ); - //fprintf(time_meas_fd,"UE_PROC_TX_STD;UE_PROC_TX_MAX;UE_PROC_TX_MIN;UE_PROC_TX_MED;UE_PROC_TX_Q1;UE_PROC_TX_Q3;UE_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(&UE->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(&UE->ulsch_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,"%f;%f;%f;%f;", + squareRoot(&UE->ulsch_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;", 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;%f;%f;%d;", + squareRoot(&eNB->phy_proc_rx), 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(&ru->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(&eNB->ulsch_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(&eNB->ulsch_decoding_stats), + 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 ); break; } else if (test_perf !=0 ) { printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - if (((double)errs[0]/(round_trials[0]))<1e-2) break; - } // SNR + } // SNR // - - //LOG_M("chestim_f.m","chestf",eNB->pusch_vars[0]->drs_ch_estimates[0][0],300*12,2,1); // LOG_M("chestim_t.m","chestt",eNB->pusch_vars[0]->drs_ch_estimates_time[0][0], (frame_parms->ofdm_symbol_size)*2,2,1); - }//ch realization - oai_exit=1; pthread_cond_signal(&ru->proc.cond_fep); @@ -1865,7 +1646,6 @@ int main(int argc, char **argv) fclose (time_meas_fd); return(0); - } diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 9403362c4f..fa622ce5d7 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -146,7 +146,7 @@ typedef enum { {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ -{CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"0.0.0.0", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ } diff --git a/openair2/UTIL/LISTS/list.h b/openair2/UTIL/LISTS/list.h index bf4d7e7580..818df2be26 100644 --- a/openair2/UTIL/LISTS/list.h +++ b/openair2/UTIL/LISTS/list.h @@ -44,6 +44,8 @@ #include #include #include +#include + #include "UTIL/MEM/mem_block.h" @@ -103,4 +105,37 @@ void totable (double*, struct list*); int compare (const void * a, const void * b); int32_t calculate_median(struct list *loc_list); + +typedef struct { + size_t size; + size_t mallocedSize; + size_t atomSize; + size_t increment; +} varArray_t; + +static inline varArray_t * initVarArray(size_t increment, size_t atomSize) { + varArray_t * tmp=malloc(sizeof(varArray_t)+increment*atomSize); + tmp->size=0; + tmp->atomSize=atomSize; + tmp->mallocedSize=increment; + tmp->increment=increment; + return(tmp); +} + +static inline void * dataArray(varArray_t * input) { + return input+1; +} + +static inline void appendVarArray(varArray_t * input, void* data) { + if (input->size>=input->mallocedSize) { + input->mallocedSize+=input->increment; + input=realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize); + } + memcpy((uint8_t*)(input+1)+input->atomSize*input->size++, data, input->atomSize); +} + +static inline void freeVarArray(varArray_t * input) { + free(input); +} + #endif diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 47cd12d816..c591cc6c0f 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -65,211 +65,191 @@ /*! \brief USRP Configuration */ typedef struct { - // -------------------------------- - // variables for USRP configuration - // -------------------------------- - //! USRP device pointer - uhd::usrp::multi_usrp::sptr usrp; + // -------------------------------- + // variables for USRP configuration + // -------------------------------- + //! USRP device pointer + uhd::usrp::multi_usrp::sptr usrp; - //create a send streamer and a receive streamer - //! USRP TX Stream - uhd::tx_streamer::sptr tx_stream; - //! USRP RX Stream - uhd::rx_streamer::sptr rx_stream; + //create a send streamer and a receive streamer + //! USRP TX Stream + uhd::tx_streamer::sptr tx_stream; + //! USRP RX Stream + uhd::rx_streamer::sptr rx_stream; - //! USRP TX Metadata - uhd::tx_metadata_t tx_md; - //! USRP RX Metadata - uhd::rx_metadata_t rx_md; + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; - //! Sampling rate - double sample_rate; + //! Sampling rate + double sample_rate; - //! TX forward samples. We use usrp_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz + //! TX forward samples. We use usrp_time_offset to get this value + int tx_forward_nsamps; //166 for 20Mhz - // -------------------------------- - // Debug and output control - // -------------------------------- - int num_underflows; - int num_overflows; - int num_seq_errors; - int64_t tx_count; - int64_t rx_count; - int wait_for_first_pps; - int use_gps; - //! timestamp of RX packet - openair0_timestamp rx_timestamp; + // -------------------------------- + // Debug and output control + // -------------------------------- + int num_underflows; + int num_overflows; + int num_seq_errors; + int64_t tx_count; + int64_t rx_count; + int wait_for_first_pps; + int use_gps; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; } usrp_state_t; //void print_notes(void) //{ - // Helpful notes - // std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); - // std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n"); - // std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n"); - // std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); - // std::cout << boost::format("****************************************************************************************************************\n"); +// Helpful notes +// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); +// std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n"); +// std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n"); +// std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n"); +// std::cout << boost::format("****************************************************************************************************************\n"); //} -static int sync_to_gps(openair0_device *device) -{ - uhd::set_thread_priority_safe(); +static int sync_to_gps(openair0_device *device) { + uhd::set_thread_priority_safe(); + //std::string args; + //Set up program options + //po::options_description desc("Allowed options"); + //desc.add_options() + //("help", "help message") + //("args", po::value(&args)->default_value(""), "USRP device arguments") + //; + //po::variables_map vm; + //po::store(po::parse_command_line(argc, argv, desc), vm); + //po::notify(vm); + //Print the help message + //if (vm.count("help")) + //{ + // std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl; + // return EXIT_FAILURE; + //} + //Create a USRP device + //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; + //uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); + //std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); + usrp_state_t *s = (usrp_state_t *)device->priv; - //std::string args; + try { + size_t num_mboards = s->usrp->get_num_mboards(); + size_t num_gps_locked = 0; - //Set up program options - //po::options_description desc("Allowed options"); - //desc.add_options() - //("help", "help message") - //("args", po::value(&args)->default_value(""), "USRP device arguments") - //; - //po::variables_map vm; - //po::store(po::parse_command_line(argc, argv, desc), vm); - //po::notify(vm); + for (size_t mboard = 0; mboard < num_mboards; mboard++) { + std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; + //Set references to GPSDO + s->usrp->set_clock_source("gpsdo", mboard); + s->usrp->set_time_source("gpsdo", mboard); + //std::cout << std::endl; + //print_notes(); + //std::cout << std::endl; + //Check for 10 MHz lock + std::vector sensor_names = s->usrp->get_mboard_sensor_names(mboard); - //Print the help message - //if (vm.count("help")) - //{ - // std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl; - // return EXIT_FAILURE; - //} + if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) { + std::cout << "Waiting for reference lock..." << std::flush; + bool ref_locked = false; - //Create a USRP device - //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; - //uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); - //std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); - - usrp_state_t *s = (usrp_state_t*)device->priv; + for (int i = 0; i < 30 and not ref_locked; i++) { + ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - try - { - size_t num_mboards = s->usrp->get_num_mboards(); - size_t num_gps_locked = 0; - for (size_t mboard = 0; mboard < num_mboards; mboard++) - { - std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; - - //Set references to GPSDO - s->usrp->set_clock_source("gpsdo", mboard); - s->usrp->set_time_source("gpsdo", mboard); - - //std::cout << std::endl; - //print_notes(); - //std::cout << std::endl; - - //Check for 10 MHz lock - std::vector sensor_names = s->usrp->get_mboard_sensor_names(mboard); - if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) - { - std::cout << "Waiting for reference lock..." << std::flush; - bool ref_locked = false; - for (int i = 0; i < 30 and not ref_locked; i++) - { - ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool(); - if (not ref_locked) - { - std::cout << "." << std::flush; - boost::this_thread::sleep(boost::posix_time::seconds(1)); - } - } - if(ref_locked) - { - std::cout << "LOCKED" << std::endl; - } else { - std::cout << "FAILED" << std::endl; - std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; - exit(EXIT_FAILURE); - } - } - else - { - std::cout << boost::format("ref_locked sensor not present on this board.\n"); - } - - //Wait for GPS lock - bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); - if(gps_locked) - { - num_gps_locked++; - std::cout << boost::format("GPS Locked\n"); - } - else - { - std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; - } - - //Set to GPS time - uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); - //s->usrp->set_time_next_pps(gps_time+1.0, mboard); - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); - - //Wait for it to apply - //The wait is 2 seconds because N-Series has a known issue where - //the time at the last PPS does not properly update at the PPS edge - //when the time is actually set. - boost::this_thread::sleep(boost::posix_time::seconds(2)); - - //Check times - gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); - uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard); - std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; - std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; - //if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) - // std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; - //else - // std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; + if (not ref_locked) { + std::cout << "." << std::flush; + boost::this_thread::sleep(boost::posix_time::seconds(1)); + } } - if (num_gps_locked == num_mboards and num_mboards > 1) - { - //Check to see if all USRP times are aligned - //First, wait for PPS. - uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); - while (time_last_pps == s->usrp->get_time_last_pps()) - { - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); - } - - //Sleep a little to make sure all devices have seen a PPS edge - boost::this_thread::sleep(boost::posix_time::milliseconds(200)); - - //Compare times across all mboards - bool all_matched = true; - uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0); - for (size_t mboard = 1; mboard < num_mboards; mboard++) - { - uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard); - if (mboard_time != mboard0_time) - { - all_matched = false; - std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") - % mboard0_time.get_real_secs() - % mboard - % mboard_time.get_real_secs()) << std::endl; - } - } - if (all_matched) - { - std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl; - } else { - std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; - } + if(ref_locked) { + std::cout << "LOCKED" << std::endl; + } else { + std::cout << "FAILED" << std::endl; + std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl; + exit(EXIT_FAILURE); } - } - catch (std::exception& e) - { - std::cout << boost::format("\nError: %s") % e.what(); - std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); - std::cout << boost::format("Visit one of these pages if the problem persists:\n"); - std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"); - std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); - std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); - exit(EXIT_FAILURE); + } else { + std::cout << boost::format("ref_locked sensor not present on this board.\n"); + } + + //Wait for GPS lock + bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); + + if(gps_locked) { + num_gps_locked++; + std::cout << boost::format("GPS Locked\n"); + } else { + std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; + } + + //Set to GPS time + uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); + //s->usrp->set_time_next_pps(gps_time+1.0, mboard); + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + //Wait for it to apply + //The wait is 2 seconds because N-Series has a known issue where + //the time at the last PPS does not properly update at the PPS edge + //when the time is actually set. + boost::this_thread::sleep(boost::posix_time::seconds(2)); + //Check times + gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard); + std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; + std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; + //if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) + // std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; + //else + // std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; } - return EXIT_SUCCESS; + if (num_gps_locked == num_mboards and num_mboards > 1) { + //Check to see if all USRP times are aligned + //First, wait for PPS. + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); + + while (time_last_pps == s->usrp->get_time_last_pps()) { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + //Sleep a little to make sure all devices have seen a PPS edge + boost::this_thread::sleep(boost::posix_time::milliseconds(200)); + //Compare times across all mboards + bool all_matched = true; + uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0); + + for (size_t mboard = 1; mboard < num_mboards; mboard++) { + uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard); + + if (mboard_time != mboard0_time) { + all_matched = false; + std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") + % mboard0_time.get_real_secs() + % mboard + % mboard_time.get_real_secs()) << std::endl; + } + } + + if (all_matched) { + std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl; + } else { + std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; + } + } + } catch (std::exception &e) { + std::cout << boost::format("\nError: %s") % e.what(); + std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); + std::cout << boost::format("Visit one of these pages if the problem persists:\n"); + std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html"); + std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n"); + std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); + exit(EXIT_FAILURE); + } + + return EXIT_SUCCESS; } #if defined(USRP_REC_PLAY) @@ -315,24 +295,18 @@ char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; @param device pointer to the device structure specific to the RF hardware target */ static int trx_usrp_start(openair0_device *device) { - #if defined(USRP_REC_PLAY) - if (u_sf_mode != 2) { // not replay mode -#endif - usrp_state_t *s = (usrp_state_t*)device->priv; - - - // setup GPIO for TDD, GPIO(4) = ATR_RX - //set data direction register (DDR) to output + if (u_sf_mode != 2) { // not replay mode +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; + // setup GPIO for TDD, GPIO(4) = ATR_RX + //set data direction register (DDR) to output s->usrp->set_gpio_attr("FP0", "DDR", 0x1f, 0x1f); - - //set control register to ATR + //set control register to ATR s->usrp->set_gpio_attr("FP0", "CTRL", 0x1f,0x1f); - - //set ATR register + //set ATR register s->usrp->set_gpio_attr("FP0", "ATR_RX", 1<<4, 0x1f); - // init recv and send streaming uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); LOG_I(PHY,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); @@ -340,28 +314,26 @@ static int trx_usrp_start(openair0_device *device) { if (s->use_gps == 1) { s->wait_for_first_pps = 1; - cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); - } - else { - s->wait_for_first_pps = 0; + cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); + } else { + s->wait_for_first_pps = 0; cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); } cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); s->tx_md.has_time_spec = true; s->tx_md.start_of_burst = true; s->tx_md.end_of_burst = false; - s->rx_count = 0; s->tx_count = 0; s->rx_timestamp = 0; #if defined(USRP_REC_PLAY) - } -#endif - return 0; + } + +#endif + return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use @@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) { static void trx_usrp_end(openair0_device *device) { #if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times... static int done = 0; - if (done == 1) return; - done = 1; - if (u_sf_mode != 2) { // not subframes replay -#endif - usrp_state_t *s = (usrp_state_t*)device->priv; + if (done == 1) return; + + done = 1; + + if (u_sf_mode != 2) { // not subframes replay +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); //send a mini EOB packet s->tx_md.end_of_burst = true; @@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) { s->tx_md.end_of_burst = false; sleep(1); #if defined(USRP_REC_PLAY) - } + } + #endif #if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { // subframes store - pFile = fopen (u_sf_filename,"wb+"); - if (pFile == NULL) { - std::cerr << "Cannot open " << u_sf_filename << std::endl; - } else { - unsigned int i = 0; - unsigned int modu = 0; - if ((modu = nb_samples % 10) != 0) { - nb_samples -= modu; // store entire number of frames - } - std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; - for (i = 0; i < nb_samples; i++) { - fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); - } - fclose (pFile); - std::cerr << "File " << u_sf_filename << " closed." << std::endl; + + if (u_sf_mode == 1) { // subframes store + pFile = fopen (u_sf_filename,"wb+"); + + if (pFile == NULL) { + std::cerr << "Cannot open " << u_sf_filename << std::endl; + } else { + unsigned int i = 0; + unsigned int modu = 0; + + if ((modu = nb_samples % 10) != 0) { + nb_samples -= modu; // store entire number of frames } + + std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; + + for (i = 0; i < nb_samples; i++) { + fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); + } + + fclose (pFile); + std::cerr << "File " << u_sf_filename << " closed." << std::endl; } - if (u_sf_mode == 1) { // record + } + + if (u_sf_mode == 1) { // record + if (ms_sample != NULL) { + free((void *)ms_sample); + ms_sample = NULL; + } + } + + if (u_sf_mode == 2) { // replay + if (use_mmap) { + if (ms_sample != MAP_FAILED) { + munmap(ms_sample, sb.st_size); + ms_sample = NULL; + } + + if (mmapfd != 0) { + close(mmapfd); + mmapfd = 0; + } + } else { if (ms_sample != NULL) { - free((void*)ms_sample); - ms_sample = NULL; + free(ms_sample); + ms_sample = NULL; + } + + if (iqfd != 0) { + close(iqfd); + iqfd = 0; } } - if (u_sf_mode == 2) { // replay - if (use_mmap) { - if (ms_sample != MAP_FAILED) { - munmap(ms_sample, sb.st_size); - ms_sample = NULL; - } - if (mmapfd != 0) { - close(mmapfd); - mmapfd = 0; - } - } else { - if (ms_sample != NULL) { - free(ms_sample); - ms_sample = NULL; - } - if (iqfd != 0) { - close(iqfd); - iqfd = 0; - } - } - } -#endif + } + +#endif } /*! \brief Called to send samples to the USRP RF target @@ -444,78 +430,80 @@ static void trx_usrp_end(openair0_device *device) { static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; #if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode -#endif - usrp_state_t *s = (usrp_state_t*)device->priv; - - int nsamps2; // aligned to upper 32 or 16 byte boundary +#endif + usrp_state_t *s = (usrp_state_t *)device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[2][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tx[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tx[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tx[2][nsamps2]; #endif - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; itx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_md.has_time_spec = flags; - - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - - if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; - } else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; - } else if (flags == 4) { // start and end - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = true; - } else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; - } - if(flags==10){ // fail safe mode - s->tx_md.has_time_spec = false; - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; - } - if (cc>1) { - std::vector buff_ptrs; - for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } else - ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3); - - - - if (ret != nsamps) - LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_md.has_time_spec = flags; + + if(flags>0) + s->tx_md.has_time_spec = true; + else + s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } else if (flags == 4) { // start and end + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = true; + } else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } + + if(flags==10) { // fail safe mode + s->tx_md.has_time_spec = false; + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } + + if (cc>1) { + std::vector buff_ptrs; + + for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + } else + ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3); + + if (ret != nsamps) + LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); + #if defined(USRP_REC_PLAY) } else { struct timespec req; @@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, nanosleep(&req, NULL); ret = nsamps; } -#endif +#endif return ret; } @@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \returns the number of sample read */ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t *)device->priv; int samples_received=0,i,j; int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode -#endif +#endif #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp #endif if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received=0; - while (samples_received != nsamps) { - samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, - nsamps-samples_received, s->rx_md); - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { printf("sleep...\n");} //usleep(100); - } - if (samples_received == nsamps) s->wait_for_first_pps=0; + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; + + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; + + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); + + if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) + break; + + if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { + printf("sleep...\n"); //usleep(100); + } } - // bring RX data into 12 LSBs for softmodem RX - for (int i=0; iwait_for_first_pps=0; + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; itype == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; - for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); - } + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); + } } + if (samples_received < nsamps) - LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); + LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - LOG_E(PHY, "%s\n", s->rx_md.to_pp_string(true).c_str()); + LOG_E(PHY, "%s\n", s->rx_md.to_pp_string(true).c_str()); s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; #if defined (USRP_REC_PLAY) } -#endif + +#endif #if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { // record mode // Copy subframes to memory (later dump on a file) if (nb_samples < u_sf_max) { - (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; + (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; (ms_sample+nb_samples)->ts = *ptimestamp; memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); nb_samples++; @@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp if (cur_samples == nb_samples) { cur_samples = 0; wrap_count++; + if (wrap_count == u_sf_loops) { - std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; - return 0; // should make calling process exit + std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; + return 0; // should make calling process exit } + wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + if (!use_mmap) { - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Seeking at the beginning of IQ file" << std::endl; - } else { - std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; - } + if (lseek(iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Seeking at the beginning of IQ file" << std::endl; + } else { + std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; + } } } + if (use_mmap) { if (cur_samples < nb_samples) { - *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); - cur_samples++; + *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; } } else { // read sample from file if (read(iqfd, ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; - close(iqfd); - free(ms_sample); - ms_sample = NULL; - iqfd = 0; - exit(-1); + std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl; + close(iqfd); + free(ms_sample); + ms_sample = NULL; + iqfd = 0; + exit(-1); } if (cur_samples < nb_samples) { - static int64_t ts0 = 0; - if ((cur_samples == 0) && (wrap_count == 0)) { - ts0 = ms_sample->ts; - } - *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; - if (cur_samples == 0) { - std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts - << " ts=" << *ptimestamp << std::endl; - } - memcpy(buff[0], &ms_sample->samples[0], nsamps*4); - cur_samples++; - // Prepare for next read - off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); + static int64_t ts0 = 0; + + if ((cur_samples == 0) && (wrap_count == 0)) { + ts0 = ms_sample->ts; + } + + *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts; + + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + + memcpy(buff[0], &ms_sample->samples[0], nsamps*4); + cur_samples++; + // Prepare for next read + off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET); } } + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = u_sf_read_delay * 1000; + nanosleep(&req, NULL); + return nsamps; } + #endif return samples_received; } @@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp * \param b second variable */ static bool is_equal(double a, double b) { - return std::fabs(a-b) < std::numeric_limits::epsilon(); + return std::fabs(a-b) < std::numeric_limits::epsilon(); } void *freq_thread(void *arg) { - - openair0_device *device=(openair0_device *)arg; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t *)device->priv; + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use @@ -711,23 +727,20 @@ void *freq_thread(void *arg) { * \param dummy dummy variable not used * \returns 0 in success */ -int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { +int trx_usrp_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) { + usrp_state_t *s = (usrp_state_t *)device->priv; + pthread_t f_thread; + printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - usrp_state_t *s = (usrp_state_t*)device->priv; - pthread_t f_thread; - - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - - // spawn a thread to handle the frequency change to not block the calling thread - if (dont_block == 1) - pthread_create(&f_thread,NULL,freq_thread,(void*)device); - else { - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); - } - - return(0); + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void *)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } + return(0); } /*! \brief Set RX frequencies @@ -735,21 +748,16 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, * \param openair0_cfg RF frontend parameters set by application * \returns 0 in success */ -int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { - - usrp_state_t *s = (usrp_state_t*)device->priv; - static int first_call=1; - static double rf_freq,diff; - - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); - - rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; - rf_freq=openair0_cfg[0].rx_freq[0]; - s->usrp->set_rx_freq(rx_tune_req); - - return(0); - +int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg) { + usrp_state_t *s = (usrp_state_t *)device->priv; + static int first_call=1; + static double rf_freq,diff; + uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); + rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; + rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; + rf_freq=openair0_cfg[0].rx_freq[0]; + s->usrp->set_rx_freq(rx_tune_req); + return(0); } /*! \brief Set Gains (TX/RX) @@ -757,62 +765,62 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open * \param openair0_cfg RF frontend parameters set by application * \returns 0 in success */ -int trx_usrp_set_gains(openair0_device* device, +int trx_usrp_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + usrp_state_t *s = (usrp_state_t *)device->priv; + ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); + s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - usrp_state_t *s = (usrp_state_t*)device->priv; - ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); - s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { - LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); - LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], - openair0_cfg[0].rx_gain[0],gain_range.stop()); + // limit to maximum gain + if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { + LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); + exit(-1); + } - return(0); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], + openair0_cfg[0].rx_gain[0],gain_range.stop()); + return(0); } /*! \brief Stop USRP * \param card refers to the hardware index to use */ -int trx_usrp_stop(openair0_device* device) { - return(0); +int trx_usrp_stop(openair0_device *device) { + return(0); } /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210[] = { - {3500000000.0,44.0}, - {2660000000.0,49.0}, - {2300000000.0,50.0}, - {1880000000.0,53.0}, - {816000000.0,58.0}, - {-1,0} + {3500000000.0,44.0}, + {2660000000.0,49.0}, + {2300000000.0,50.0}, + {1880000000.0,53.0}, + {816000000.0,58.0}, + {-1,0} }; /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210_38[] = { - {3500000000.0,44.0}, - {2660000000.0,49.8}, - {2300000000.0,51.0}, - {1880000000.0,53.0}, - {816000000.0,57.0}, - {-1,0} + {3500000000.0,44.0}, + {2660000000.0,49.8}, + {2300000000.0,51.0}, + {1880000000.0,53.0}, + {816000000.0,57.0}, + {-1,0} }; /*! \brief USRPx310 RX calibration table */ rx_gain_calib_table_t calib_table_x310[] = { - {3500000000.0,77.0}, - {2660000000.0,81.0}, - {2300000000.0,81.0}, - {1880000000.0,82.0}, - {816000000.0,85.0}, - {-1,0} + {3500000000.0,77.0}, + {2660000000.0,81.0}, + {2300000000.0,81.0}, + {1880000000.0,82.0}, + {816000000.0,85.0}, + {-1,0} }; /*! \brief Set RX gain offset @@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = { * \returns 0 in success */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff,gain_adj=0.0; - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff,gain_adj=0.0; - if (bw_gain_adjust==1) { - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - break; - case 23040000: - gain_adj=1.25; - break; - case 15360000: - gain_adj=3.0; - break; - case 7680000: - gain_adj=6.0; - break; - case 3840000: - gain_adj=9.0; - break; - case 1920000: - gain_adj=12.0; - break; - default: - LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); - break; - } + if (bw_gain_adjust==1) { + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + break; + + case 23040000: + gain_adj=1.25; + break; + + case 15360000: + gain_adj=3.0; + break; + + case 7680000: + gain_adj=6.0; + break; + + case 3840000: + gain_adj=9.0; + break; + + case 1920000: + gain_adj=12.0; + break; + + default: + LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); + exit(-1); + break; } - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; - } - i++; + } + + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset,diff); + + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; } + + i++; + } } /*! \brief print the USRP statistics * \param device the hardware to use * \returns 0 on success */ -int trx_usrp_get_stats(openair0_device* device) { - return(0); +int trx_usrp_get_stats(openair0_device *device) { + return(0); } /*! \brief Reset the USRP statistics * \param device the hardware to use * \returns 0 on success */ -int trx_usrp_reset_stats(openair0_device* device) { - return(0); +int trx_usrp_reset_stats(openair0_device *device) { + return(0); } #if defined(USRP_REC_PLAY) extern "C" { -/*! \brief Initializer for USRP record/playback config - * \param parameter array description - * \returns 0 on success - */ -int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { + /*! \brief Initializer for USRP record/playback config + * \param parameter array description + * \returns 0 on success + */ + int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { // --subframes-file memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); usrp_recplay_params[0].helpstr = config_hlp_sf_file; @@ -943,9 +960,8 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE; usrp_recplay_params[6].type=TYPE_UINT; usrp_recplay_params[6].numelt=0; - return 0; // always ok -} + } } #endif @@ -954,478 +970,473 @@ extern "C" { * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application */ - int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - + int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { LOG_D(PHY, "openair0_cfg[0].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs); LOG_D(PHY, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source); - #if defined(USRP_REC_PLAY) - paramdef_t usrp_recplay_params[7]; - struct sysinfo systeminfo; - // to check - static int done = 0; - if (done == 1) { - return 0; - } // prevent from multiple init - done = 1; - // end to check - // Use mmap for IQ files for systems with less than 6GB total RAM - sysinfo(&systeminfo); - if (systeminfo.totalram < 6144000000) { - use_mmap = 0; - } - memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); - memset(&u_sf_filename[0], 0, 1024); - if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { - std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; - return -1; - } - config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); + paramdef_t usrp_recplay_params[7]; + struct sysinfo systeminfo; + // to check + static int done = 0; - if (strlen(u_sf_filename) == 0) { - (void) strcpy(u_sf_filename, DEF_SF_FILE); - } + if (done == 1) { + return 0; + } // prevent from multiple init - if (u_sf_replay == 1) u_sf_mode = 2; - if (u_sf_record == 1) u_sf_mode = 1; - - if (u_sf_mode == 2) { - // Replay subframes from from file - int bw_gain_adjust=0; - device->openair0_cfg = openair0_cfg; - device->type = USRP_B200_DEV; - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); - device->priv = NULL; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" - << use_mmap << std::endl; - } else { + done = 1; + // end to check + // Use mmap for IQ files for systems with less than 6GB total RAM + sysinfo(&systeminfo); + + if (systeminfo.totalram < 6144000000) { + use_mmap = 0; + } + + memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); + memset(&u_sf_filename[0], 0, 1024); + + if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { + std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; + return -1; + } + + config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); + + if (strlen(u_sf_filename) == 0) { + (void) strcpy(u_sf_filename, DEF_SF_FILE); + } + + if (u_sf_replay == 1) u_sf_mode = 2; + + if (u_sf_record == 1) u_sf_mode = 1; + + if (u_sf_mode == 2) { + // Replay subframes from from file + int bw_gain_adjust=0; + device->openair0_cfg = openair0_cfg; + device->type = USRP_B200_DEV; + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); + device->priv = NULL; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" + << use_mmap << std::endl; + } else { #endif - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); - - if (openair0_cfg[0].clock_source==gpsdo) - s->use_gps =1; + uhd::set_thread_priority_safe(1.0); + usrp_state_t *s = (usrp_state_t *)calloc(sizeof(usrp_state_t),1); - // Initialize USRP device - device->openair0_cfg = openair0_cfg; + if (openair0_cfg[0].clock_source==gpsdo) + s->use_gps =1; - std::string args = "type=b200"; + // Initialize USRP device + device->openair0_cfg = openair0_cfg; + int vers=0,subvers=0,subsubvers=0; + int bw_gain_adjust=0; +#if defined(USRP_REC_PLAY) - char *addr_args = NULL; - // Check whether sdr_addrs is set in the config or not - if (openair0_cfg[0].sdr_addrs != NULL) { - if (strcmp(openair0_cfg[0].sdr_addrs, "0.0.0.0") != 0) { - // Check whether sdr_addrs contains multiple IP addresses - // and split and add them to addr_args - if (strstr(openair0_cfg[0].sdr_addrs, ",") != NULL) { - char *addr0 = openair0_cfg[0].sdr_addrs; - // Replace , with \0 - strsep(&openair0_cfg[0].sdr_addrs, ","); - char *addr1 = openair0_cfg[0].sdr_addrs; - // Allocate memory for ",addr0=,addr1=\0" and the addresses - size_t addr_args_len = sizeof(char)*(15 + strlen(addr0) + strlen(addr1)); - addr_args = (char *)malloc(addr_args_len); - snprintf(addr_args, addr_args_len, ",addr0=%s,addr1=%s", addr0, addr1); - args += addr_args; - LOG_D(PHY, "addr_args == '%s'\n", addr_args); - } - } + if (u_sf_mode == 1) { + std::cerr << "USRP device initialized in subframes record mode" << std::endl; + } + +#endif + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); + LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", + uhd::get_version_string().c_str(),vers,subvers,subsubvers); + + std::string args; + if (openair0_cfg[0].sdr_addrs == NULL) { + args = "type=b200"; + } else { + args = openair0_cfg[0].sdr_addrs; } uhd::device_addrs_t device_adds = uhd::device::find(args); - int vers=0,subvers=0,subsubvers=0; - int bw_gain_adjust=0; + if (device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } else if (device_adds.size() > 1) { + std::cerr<<"More than one USRP Device Found. Please specify device more precisely in config file." << std::endl; + free(s); + return -1; + } -#if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { - std::cerr << "USRP device initialized in subframes record mode" << std::endl; - } -#endif - sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); - LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", - uhd::get_version_string().c_str(),vers,subvers,subsubvers); + std::cerr << "Found USRP " << device_adds[0].get("type") << "\n"; + double usrp_master_clock; - if(device_adds.size() == 0) { - - double usrp_master_clock = 184.32e6; - std::string args = "type=x300"; - - if (addr_args) { - args += addr_args; - } - - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate + if (device_adds[0].get("type") == "b200") { + printf("Found USRP b200\n"); + device->type = USRP_B200_DEV; + usrp_master_clock = 30.72e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + } - // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); + if (device_adds[0].get("type") == "n3xx") { + printf("Found USRP n300\n"); + device->type=USRP_X300_DEV; //treat it as X300 for now + usrp_master_clock = 122.88e6; + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + } - if(device_adds.size() == 0) { - args += ",addr=192.168.30.2"; + if (device_adds[0].get("type") == "x300") { + printf("Found USRP x300\n"); + device->type=USRP_X300_DEV; + usrp_master_clock = 184.32e6; + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + } - uhd::device_addrs_t device_adds = uhd::device::find(args); + s->usrp = uhd::usrp::multi_usrp::make(args); - if(device_adds.size() == 0) { - - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - } - } - LOG_I(PHY,"Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); - - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); + if (device->type==USRP_X300_DEV) { + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; #if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info #endif + LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); - LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); + switch ((int)openair0_cfg[0].sample_rate) { + case 122880000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; //to be checked + openair0_cfg[0].tx_bw = 80e6; + openair0_cfg[0].rx_bw = 80e6; + break; - switch ((int)openair0_cfg[0].sample_rate) { - case 122880000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; //to be checked - openair0_cfg[0].tx_bw = 80e6; - openair0_cfg[0].rx_bw = 80e6; - break; - case 61440000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 40e6; - openair0_cfg[0].rx_bw = 40e6; - break; - case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + case 61440000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + case 30720000: + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 15360000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + + case 7680000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + + case 1920000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; + break; + + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + + if (device->type == USRP_B200_DEV) { + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; +#if defined(USRP_REC_PLAY) + std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info +#endif } else { - LOG_I(PHY,"Found USRP B200\n"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); - - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming - - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal){ - s->usrp->set_clock_source("internal"); - } - else{ - s->usrp->set_clock_source("external"); - s->usrp->set_time_source("external"); - } - - device->type = USRP_B200_DEV; - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; #if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info -#endif - } else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; -#if defined(USRP_REC_PLAY) - std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info -#endif - } - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: - LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info +#endif } - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; - for(int i=0; iusrp->get_rx_num_channels(); i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), - "RX Gain too high, lower by %f dB\n", - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - LOG_I(PHY,"RX Gain %d %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; } + } + + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + + for(int i=0; iusrp->get_rx_num_channels(); i++) { + if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); + set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); + // limit to maximum gain + AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), + "RX Gain too high, lower by %f dB\n", + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); + LOG_I(PHY,"RX Gain %d %f (%f) => %f (max %f)\n",i, + openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + } + } LOG_D(PHY, "usrp->get_tx_num_channels() == %zd\n", s->usrp->get_tx_num_channels()); LOG_D(PHY, "openair0_cfg[0].tx_num_channels == %d\n", openair0_cfg[0].tx_num_channels); + for(int i=0; iusrp->get_tx_num_channels(); i++) { ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); + if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i); - - LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); - } + LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]); } - - //s->usrp->set_clock_source("external"); - //s->usrp->set_time_source("external"); - - // display USRP settings - LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); - sleep(1); - - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - int samples=openair0_cfg[0].sample_rate; - int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); - samples/=10000; - LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); - if ( samples < max ) - stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); - LOG_I(PHY,"rx_max_num_samps %zu\n", - s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); - - for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(int i=0; iusrp->get_tx_num_channels() && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - - for(int i=0; iusrp->get_rx_num_channels() && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - - for (int i=0; iusrp->get_rx_rate(i)/1e6); - LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); - LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); - LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); - LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); - } - - for (int i=0; iusrp->get_tx_rate(i)/1e6); - LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); - LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); - LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); - LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); - } - - LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - - device->priv = s; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; - - s->sample_rate = openair0_cfg[0].sample_rate; - // TODO: - // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) - s->tx_forward_nsamps = 176; - if(is_equal(s->sample_rate, (double)15.36e6)) - s->tx_forward_nsamps = 90; - if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; - - if (s->use_gps == 1) { - if (sync_to_gps(device)) { - LOG_I(PHY,"USRP fails to sync with GPS...\n"); - exit(0); - } - } - -#if defined(USRP_REC_PLAY) } + + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); + // display USRP settings + LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); + sleep(1); + // create tx & rx streamer + uhd::stream_args_t stream_args_rx("sc16", "sc16"); + int samples=openair0_cfg[0].sample_rate; + int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + samples/=10000; + LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); + + if ( samples < max ) + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + + LOG_I(PHY,"rx_max_num_samps %zu\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + + for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); + + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ + for(int i=0; iusrp->get_tx_num_channels() && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + + for(int i=0; iusrp->get_rx_num_channels() && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); + + for (int i=0; iusrp->get_rx_rate(i)/1e6); + LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } + + for (int i=0; iusrp->get_tx_rate(i)/1e6); + LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); + LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); + LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + } + + LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); + device->priv = s; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + s->sample_rate = openair0_cfg[0].sample_rate; + + // TODO: + // init tx_forward_nsamps based usrp_time_offset ex + if(is_equal(s->sample_rate, (double)30.72e6)) + s->tx_forward_nsamps = 176; + + if(is_equal(s->sample_rate, (double)15.36e6)) + s->tx_forward_nsamps = 90; + + if(is_equal(s->sample_rate, (double)7.68e6)) + s->tx_forward_nsamps = 50; + + if (s->use_gps == 1) { + if (sync_to_gps(device)) { + LOG_I(PHY,"USRP fails to sync with GPS...\n"); + exit(0); + } + } + +#if defined(USRP_REC_PLAY) + } + #endif #if defined(USRP_REC_PLAY) - if (u_sf_mode == 1) { // record mode - ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t)); - if (ms_sample == NULL) { - std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; - exit(-1); - } - memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + + if (u_sf_mode == 1) { // record mode + ms_sample = (iqrec_t *) malloc(u_sf_max * sizeof(iqrec_t)); + + if (ms_sample == NULL) { + std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; + exit(-1); } - if (u_sf_mode == 2) { - if (use_mmap) { - // use mmap - mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); - if (mmapfd != 0) { - fstat(mmapfd, &sb); - std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); - if (ms_sample != MAP_FAILED) { - nb_samples = (sb.st_size / sizeof(iqrec_t)); - int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; - std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; - if (aligned == 0) { - std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; - close(mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot mmap file, exiting." << std::endl; - close(mmapfd); - exit(-1); - } - } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } else { - iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); - if (iqfd != 0) { - fstat(iqfd, &sb); - nb_samples = (sb.st_size / sizeof(iqrec_t)); - std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename - << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; - // allocate buffer for 1 sample at a time - ms_sample = (iqrec_t*) malloc(sizeof(iqrec_t)); - if (ms_sample == NULL) { - std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; - close(iqfd); - exit(-1); - } - memset(ms_sample, 0, sizeof(iqrec_t)); - // point at beginning of file - if (lseek(iqfd, 0, SEEK_SET) == 0) { - std::cerr << "Initial seek at beginning of the file" << std::endl; - } else { - std::cerr << "Problem initial seek at beginning of the file" << std::endl; - } - } else { - std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; - exit(-1); - } - } - } -#endif - return 0; + + memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); } + + if (u_sf_mode == 2) { + if (use_mmap) { + // use mmap + mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + + if (mmapfd != 0) { + fstat(mmapfd, &sb); + std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); + + if (ms_sample != MAP_FAILED) { + nb_samples = (sb.st_size / sizeof(iqrec_t)); + int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; + std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; + + if (aligned == 0) { + std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot mmap file, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + exit(-1); + } + } else { + iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + + if (iqfd != 0) { + fstat(iqfd, &sb); + nb_samples = (sb.st_size / sizeof(iqrec_t)); + std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename + << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + // allocate buffer for 1 sample at a time + ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)); + + if (ms_sample == NULL) { + std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; + close(iqfd); + exit(-1); + } + + memset(ms_sample, 0, sizeof(iqrec_t)); + + // point at beginning of file + if (lseek(iqfd, 0, SEEK_SET) == 0) { + std::cerr << "Initial seek at beginning of the file" << std::endl; + } else { + std::cerr << "Problem initial seek at beginning of the file" << std::endl; + } + } else { + std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + exit(-1); + } + } + } + +#endif + return 0; + } } /*@}*/ diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 91a3c2e479..e2415e1156 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -111,8 +111,6 @@ extern volatile int start_UE; #endif extern volatile int oai_exit; -extern openair0_config_t openair0_cfg[MAX_CARDS]; - extern int transmission_mode; extern int oaisim_flag; @@ -260,7 +258,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx); LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", - softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now, + softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time, TICK_TO_US(eNB->phy_proc), TICK_TO_US(eNB->phy_proc_tx), TICK_TO_US(eNB->phy_proc_rx), diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 9a93bc4cbc..006f3390d2 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -171,8 +171,6 @@ double rx_gain_off = 0.0; double sample_rate=30.72e6; double bw = 10.0e6; -static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; - char rf_config_file[1024]; int chain_offset=0; @@ -199,7 +197,6 @@ int otg_enabled; //int number_of_cards = 1; -static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; uint32_t target_dl_mcs = 28; //maximum allowed mcs uint32_t target_ul_mcs = 20; uint32_t timing_advance = 0; @@ -250,8 +247,6 @@ WORKER_CONF_t get_thread_worker_conf(void) /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; -openair0_config_t openair0_cfg[MAX_CARDS]; - double cpuf; extern char uecap_xer[1024]; @@ -632,112 +627,6 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { } - -void init_openair0(void) { - - int card; - int i; - - - for (card=0; cardN_RB_DL == 100) { - if(numerology == 0) - { - if (frame_parms[0]->threequarter_fs) { - openair0_cfg[card].sample_rate=23.04e6; - openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } else { - openair0_cfg[card].sample_rate=30.72e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; - } - }else if(numerology == 1) - { - openair0_cfg[card].sample_rate=61.44e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; - }else if(numerology == 2) - { - openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; - }else - { - printf("Un supported numerology\n"); - } - } else if(frame_parms[0]->N_RB_DL == 50) { - openair0_cfg[card].sample_rate=15.36e6; - openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; - } else if (frame_parms[0]->N_RB_DL == 25) { - openair0_cfg[card].sample_rate=7.68e6; - openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; - } else if (frame_parms[0]->N_RB_DL == 6) { - openair0_cfg[card].sample_rate=1.92e6; - openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; - } - - - if (frame_parms[0]->frame_type==TDD) - openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD - openair0_cfg[card].duplex_mode = duplex_mode_FDD; - - printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - RC.eNB[0][0]->frame_parms.nb_antennas_tx , - RC.eNB[0][0]->frame_parms.nb_antennas_rx ); - openair0_cfg[card].Mod_id = 0; - - openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; - - openair0_cfg[card].clock_source = clock_source; - - - openair0_cfg[card].tx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_tx ); - openair0_cfg[card].rx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_rx ); - - for (i=0; i<4; i++) { - - if (irx_total_gain_dB; - - - openair0_cfg[card].configFilename = rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } - } /* for loop on cards */ -} - - void wait_RUs(void) { LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); @@ -922,9 +811,6 @@ int main( int argc, char **argv ) mode = normal_txrx; - memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); - - memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); set_latency_target(); @@ -1283,8 +1169,6 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&ue_pf_po_mutex); - // *** Handle per CC_id openair0 - for(ru_id=0; ru_idrfdevice.trx_end_func) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 2b087e5456..96ab799c3d 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -98,6 +98,9 @@ #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" +#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" +#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n" + /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ @@ -147,7 +150,9 @@ {"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ {"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -} +{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ +{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \ + } #define DEFAULT_DLF 2680000000 diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index c52fe130a1..69556b19f2 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -223,6 +223,9 @@ int numerology = 0; char *parallel_config = NULL; char *worker_config = NULL; +char* usrp_args=NULL; +char* usrp_clksrc=NULL; + static THREAD_STRUCT thread_struct; void set_parallel_conf(char *parallel_conf) { @@ -739,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { openair0_cfg[card].tx_freq[i], openair0_cfg[card].rx_freq[i]); } + + if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; + if (usrp_clksrc) { + if (strcmp(usrp_clksrc, "internal") == 0) { + openair0_cfg[card].clock_source = internal; + LOG_D(PHY, "USRP clock source set as internal\n"); + } else if (strcmp(usrp_clksrc, "external") == 0) { + openair0_cfg[card].clock_source = external; + LOG_D(PHY, "USRP clock source set as external\n"); + } else if (strcmp(usrp_clksrc, "gpsdo") == 0) { + openair0_cfg[card].clock_source = gpsdo; + LOG_D(PHY, "USRP clock source set as gpsdo\n"); + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source unknown ('%s'). defaulting to internal\n", usrp_clksrc); + } + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source not specified. defaulting to internal\n"); + } } }