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 14230c125f26b3b08ac7d3a5e2177975fa52de0a..bae8dcfd9700074768ff0291e5175b8100ede075 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 8a66e3131fe59550fde3a414fefe1d5f40c36512..673d5a7957edfe82726c0525b6d7b479b5b22041 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 ede864b73364125b15e647292657a74c559038b4..fd9de112dcee7aeab48f31ef2c5aca282268fa63 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 589f389850cee23e06f5e7027c24d2cbdf1e3590..febd50f726a9dcfe52054f91fbfcc48c2d087528 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 e364d9acd46c912df7c13c3cb87335092ac4f92f..6023046a86f9e4c032c2721da7aa7f0d81e29a3b 100644 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -21,7 +21,7 @@ --> <testCaseList> - <TestCaseRequestedList>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</TestCaseRequestedList> + <TestCaseRequestedList>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</TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> <testCase id="010101"> @@ -42,6 +42,12 @@ <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> </testCase> + <testCase id="030106"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (TDD/Band40/20MHz/info)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> + </testCase> + <testCase id="030201"> <class>Terminate_eNB</class> <desc>Terminate eNB</desc> @@ -105,7 +111,7 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> - <testCase id="040701"> + <testCase id="040611"> <class>Iperf</class> <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc> <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> @@ -113,7 +119,7 @@ <iperf_profile>balanced</iperf_profile> </testCase> - <testCase id="040702"> + <testCase id="040612"> <class>Iperf</class> <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc> <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> @@ -121,27 +127,58 @@ <iperf_profile>single-ue</iperf_profile> </testCase> + <testCase id="040613"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> <testCase id="040641"> <class>Iperf</class> - <desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)(single-ue)</desc> - <iperf_args>-u -b 1M -t 30 -i 1 -R</iperf_args> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>single-ue</iperf_profile> + <iperf_profile>balanced</iperf_profile> </testCase> <testCase id="040642"> <class>Iperf</class> - <desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)(balanced)</desc> - <iperf_args>-u -b 1M -t 30 -i 1 -R</iperf_args> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> - <iperf_profile>balanced</iperf_profile> + <iperf_profile>single-ue</iperf_profile> </testCase> <testCase id="040643"> <class>Iperf</class> - <desc>iperf (5MHz - UL/8Mbps/UDP)(30 sec)(unbalanced)</desc> - <iperf_args>-u -b 8M -t 30 -i 1 -R</iperf_args> + <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>unbalanced</iperf_profile> + </testCase> + + <testCase id="040651"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040652"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040653"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc> + <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> <iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_profile>unbalanced</iperf_profile> </testCase> diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5bf07dae01f1a792cd3465453139495f9815578a..23d96afc545720b140473a29088dcd0c49f4834e 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 f0b3256015834e0c774a3de3353ef0c4372e6c89..e7f274c2d027846170eb26f7039157d9a00f9efa 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -990,12 +990,12 @@ <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec_args></pre_exec_args> <main_exec> $OPENAIR_DIR/targets/bin/ulsim.Rel14</main_exec> - <main_exec_args> -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 </main_exec_args> + <main_exec_args> -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 </main_exec_args> <tags>ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6</tags> <search_expr_true>"passed"</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 25898d0b8cc394f0e7cd1a5a6336ad8c2b936d4f..1bb36bd2e52f295b4f3165bb66559a1c632ad70f 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 1ceed40f8b6e901134d8c0dcaad9b335ee6a31aa..3a1364620ed6d18e3134dcb9534f32e4a26487e2 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 <math.h> +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;i<ru->nb_rx;i++) { diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 1ed9e20d602ecc39f4f573f37b83142a5fa60d2d..bcdd782073f47b16e8be9050b547065d9d3f1342 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 ded09053885c24497b5d4a22c76d94770dc53f28..30c106b16bdabfff7d1671588a94c24eb6519e38 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 50b09102d88857b2b1a2cabf439e2e81a28f2d70..e8f20c85de6a682ce3cf947ee23aa4447c0eb776 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 cb7775904099a769091795d62d23cc1b1d950b25..b37f146b0a8eb9b05f4c871f4e8562d0cc1e3afa 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 32e6883d56f5a7c2fca509b282e8205ef2a04104..eac057095a42d41ef89efc86a090715f9c09292a 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 b49613b749091bfebf633e3c9ac4f60bade49974..276006ec3be58e40a413856efc288d7d9d2f3a43 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 6272650f72b56b8af9b6cdf78af68603e85e9351..6a2fef68224b07f72edc518507858b57dbd3579a 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 89c0d09b1da0639d95390642f8285a0568486500..8c09da1daf9e3c77cb54e9535fc27f07b6f944a6 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 <string.h> @@ -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); +} -//#define MCS_COUNT 23//added for PHY abstraction +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 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 6: + 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 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; - - 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; + 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; + + 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; + } - default: - break; + 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; +} +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-50s %.2f us (%d trials)\n", + txt, + inMicroS(ptr->diff/ptr->trials), + ptr->trials); } -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 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); +} -int main(int argc, char **argv) -{ +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; - char c; +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); - - - 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; - - case 'b': - bundling_flag = 0; - break; + //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; + + for(l=0; options[l].optname[0]!=0; l++) {}; + + struct option *long_options=calloc(sizeof(struct option),l); + + for(int i=0; options[i].optname[0]!=0; i++) { + long_options[i].name=options[i].optname; + long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; + + if ( options[i].voidptr) + switch (options[i].type) { + case TYPE_INT: + *options[i].iptr=options[i].defintval; + break; - case 'd': - delay = atoi(optarg); - break; + case TYPE_DOUBLE: + *options[i].dblptr=options[i].defdblval; + break; - case 'D': - maxDoppler = atoi(optarg); - break; + default: + printf("not parsed type for default value %s\n", options[i].optname ); + exit(1); + } - case 'm': - mcs = atoi(optarg); - break; + continue; + }; - case 'n': - n_frames = atoi(optarg); - break; + int option_index; - case 'Y': - n_ch_rlz = atoi(optarg); - break; + int res; - case 'X': - abstx= atoi(optarg); - break; + 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 'g': - sprintf(channel_model_input,optarg,10); + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; - chMod = 2; - break; + default: + printf("not decoded type.\n"); + exit(1); + } - case 'B': - channel_model=SCM_B; - chMod = 3; - break; + continue; + } - case 'C': - channel_model=SCM_C; - chMod = 4; + switch (long_options[option_index].name[0]) { + case 'T': + tdd_config=atoi(optarg); + frame_type=TDD; break; - case 'D': - channel_model=SCM_D; - chMod = 5; + case 'a': + channel_model = AWGN; + chMod = 1; break; - case 'E': - channel_model=EPA; - chMod = 6; - break; + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + chMod=ptr->M; + break; + } - case 'F': - channel_model=EVA; - chMod = 7; + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - case 'G': - channel_model=ETU; - chMod = 8; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); break; - case 'H': - channel_model=Rayleigh8; - chMod = 9; + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; break; - case 'I': - channel_model=Rayleigh1; - chMod = 10; - break; + //case 'c': + // cyclic_shift = atoi(optarg); + // break; - case 'J': - channel_model=Rayleigh1_corr; - chMod = 11; + 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 'K': - channel_model=Rayleigh1_anticorr; - chMod = 12; + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); break; - case 'L': - channel_model=Rice8; - chMod = 13; + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); break; - case 'M': - channel_model=Rice1; - chMod = 14; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); break; - case 'N': - channel_model=AWGN; - chMod = 1; + case 'P': + dump_perf=1; + opp_enabled=1; break; default: - printf("Unsupported channel model!\n"); - exit(-1); + printf("Wrong option\n"); + exit(1); break; - } - - break; - - case 's': - snr0 = atof(optarg); - break; - - case 'w': - snr_int = atof(optarg); - break; - - case 'e': - input_snr_step= atof(optarg); - break; - - case 'x': - transmission_mode=atoi(optarg); - - if ((transmission_mode!=1) && - (transmission_mode!=2)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } - - break; - - case 'y': - n_rx = atoi(optarg); - 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; + if ( res != -1 ) { + printf("A wrong option has been found\n"); + exit(1); + } - case 'P': - dump_perf=1; - opp_enabled=1; - break; + paramdef_t *ptr=options ; - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; + for( ptr=options; ptr->optname[0]!=0; ptr++) { + char varText[256]="need specific display"; - case 'L': - parallel_flag=1; - break; + 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 'I': - max_turbo_iterations=atoi(optarg); - break; + case TYPE_DOUBLE: + sprintf(varText,"%.2f",*ptr->dblptr); + break; - case 'F': - xforms=1; - break; + default: + printf("not decoded type\n"); + exit(1); + } + } - case 'Z': - dump_table = 1; - break; + printf("Option: %20s set to %s\n",ptr->optname, varText); - 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; - } + 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;k<eNB->RU_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; k<eNB->RU_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;k<NUMBER_OF_UE_MAX;k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0; k<NUMBER_OF_UE_MAX; k++) eNB->ulsch[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_realization<n_ch_rlz; ch_realization++) { - /* if(abstx){ int ulchestim_f[300*12]; int ulchestim_t[2*(frame_parms->ofdm_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; trials<n_frames; trials++) { // printf("*"); // UE->frame++; // 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); - round_trials[round]++; - 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: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); - 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); - } + round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; - 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); + 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); - 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); + int modulation_type; - sched_resp.subframe=(subframe+6)%10; - sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + 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); + } - schedule_response(&sched_resp); + 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; + 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; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_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; i<eNB->frame_parms.samples_per_tti; i++) { for (aa=0; aa<eNB->frame_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; i<Kr_bytes; i++) @@ -1429,154 +1349,80 @@ int main(int argc, char **argv) } dump_ulsch(eNB,eNB->proc.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); - - /*calculate the total processing time for each packet, get the max, min, and number of packets that exceed t>3000us*/ - - 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 (xforms==1) + phy_scope_eNB(form_enb,eNB,0); - if (t_rx < t_rx_min) - t_rx_min = t_rx; + 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); - 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 9403362c4fa03fdf0e25e8a710a6fd00b70028a9..fa622ce5d7a88f24d8103bb623c44e7d4d28a7ac 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 bf4d7e7580efed434dc3df51396004231445ad7a..818df2be26d0c74c4e862ceaf660fd6be8708929 100644 --- a/openair2/UTIL/LISTS/list.h +++ b/openair2/UTIL/LISTS/list.h @@ -44,6 +44,8 @@ #include<linux/types.h> #include<stdlib.h> #include<sys/queue.h> +#include <string.h> + #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 47cd12d816d9dcd71c01e23507931d685bc8a9c7..c591cc6c0f31f2f324e2b3f09ad899313b7ab46f 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; - - //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; - - //! Sampling rate - double sample_rate; - - //! 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; + // -------------------------------- + // 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; + + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; + + //! Sampling rate + double sample_rate; + + //! 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; } 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(); - - //std::string args; - - //Set up program options - //po::options_description desc("Allowed options"); - //desc.add_options() - //("help", "help message") - //("args", po::value<std::string>(&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; - - 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<std::string> 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; - } +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<std::string>(&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; + + 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<std::string> 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)); + } + } - //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(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"); + } - 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)); - } + //Wait for GPS lock + bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool(); - //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(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; } - 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); + + 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; + 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 (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 (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; - } + + 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; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - buff_tx[i][j] = _mm256_slli_epi16(((__m256i*)buff[i])[j],4); + buff_tx[i][j] = _mm256_slli_epi16(((__m256i *)buff[i])[j],4); #else - buff_tx[i][j] = _mm_slli_epi16(((__m128i*)buff[i])[j],4); + buff_tx[i][j] = _mm_slli_epi16(((__m128i *)buff[i])[j],4); #endif #elif defined(__arm__) - buff_tx[i][j] = vshlq_n_s16(((int16x8_t*)buff[i])[j],4); + buff_tx[i][j] = vshlq_n_s16(((int16x8_t *)buff[i])[j],4); #endif + } } - } - 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<void *> buff_ptrs; - for (int i=0; i<cc; i++) - buff_ptrs.push_back(buff_tx[i]); - ret = (int)s->tx_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<void *> buff_ptrs; + + for (int i=0; i<cc; i++) + buff_ptrs.push_back(buff_tx[i]); + + ret = (int)s->tx_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<void *> buff_ptrs; - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); - samples_received = s->rx_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<void *> buff_ptrs; + + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]); + + samples_received = s->rx_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; i<cc; i++) { - for (int j=0; j<nsamps2; j++) { + + if (samples_received == nsamps) s->wait_for_first_pps=0; + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; i<cc; i++) { + for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); #else - ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); + ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); #endif #elif defined(__arm__) - ((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); + ((int16x8_t *)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4); #endif - } } + } } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); - samples_received = s->rx_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; i<cc; i++) buff_ptrs.push_back(buff[i]); + + samples_received = s->rx_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<double>::epsilon(); + return std::fabs(a-b) < std::numeric_limits<double>::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) { - - 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); +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]); + + // 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); + + // 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); + } - 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()); - - 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); + + 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; + // 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) - 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); - if (strlen(u_sf_filename) == 0) { - (void) strcpy(u_sf_filename, DEF_SF_FILE); + if (u_sf_mode == 1) { + std::cerr << "USRP device initialized in subframes record mode" << std::endl; } - 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; - - // Initialize USRP device - device->openair0_cfg = openair0_cfg; - - std::string args = "type=b200"; - - 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); - } - } + 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); - - if(device_adds.size() == 0) { - - double usrp_master_clock = 184.32e6; - std::string args = "type=x300"; - - if (addr_args) { - args += addr_args; - } + std::cerr << "Found USRP " << device_adds[0].get("type") << "\n"; + double usrp_master_clock; + + 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" ; + } + + 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); + } - // 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") == "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); + } - // 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); + s->usrp = uhd::usrp::multi_usrp::make(args); - if(device_adds.size() == 0) { - args += ",addr=192.168.30.2"; + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); - uhd::device_addrs_t device_adds = uhd::device::find(args); + 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 +#endif + LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); - 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"); + 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; - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; + 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; - // 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); + 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; - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + 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_x310" << std::endl; // Bell Labs info + 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 + } - 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; - 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; - } + 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; - } 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); + 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; - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); + 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; - // 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 + 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; - // 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; -#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 - } + 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; - 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; - } + 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; i<s->usrp->get_rx_num_channels(); i++) { - if (i<openair0_cfg[0].rx_num_channels) { - s->usrp->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()); - } + /* 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; i<s->usrp->get_rx_num_channels(); i++) { + if (i<openair0_cfg[0].rx_num_channels) { + s->usrp->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; i<s->usrp->get_tx_num_channels(); i++) { ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); + if (i<openair0_cfg[0].tx_num_channels) { s->usrp->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; i<openair0_cfg[0].rx_num_channels; i++) - stream_args_rx.channels.push_back(i); - s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++) - stream_args_tx.channels.push_back(i); - s->tx_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; i<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++) - s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - - for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) - s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - - for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { - LOG_I(PHY,"RX Channel %d\n",i); - LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->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()); - } + //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; i<openair0_cfg[0].rx_num_channels; i++) + stream_args_rx.channels.push_back(i); + + s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + + for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++) + stream_args_tx.channels.push_back(i); + + s->tx_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; i<s->usrp->get_tx_num_channels() && i<openair0_cfg[0].tx_num_channels; i++) + s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + + for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) + s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); + + for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { + LOG_I(PHY,"RX Channel %d\n",i); + LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->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; i<openair0_cfg[0].tx_num_channels; i++) { - LOG_I(PHY,"TX Channel %d\n",i); - LOG_I(PHY," Actual TX sample rate: %fMSps...\n", s->usrp->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()); - } + for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) { + LOG_I(PHY,"TX Channel %d\n",i); + LOG_I(PHY," Actual TX sample rate: %fMSps...\n", s->usrp->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); - } + 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) } + +#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); - } - } + + 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; } + +#endif + return 0; + } } /*@}*/ diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 91a3c2e479df6ba5d20c3582d10671c771f7ffc3..e2415e115683da77ccf35fbafc9783053c249490 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 9a93bc4cbc90785799792171c0c9bd12d07d70d0..006f3390d2c1754f5250d0e63051a6b41d0b7953 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; card<MAX_CARDS; card++) { - - openair0_cfg[card].mmapped_dma=mmapped_dma; - openair0_cfg[card].configFilename = NULL; - - if(frame_parms[0]->N_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 (i<openair0_cfg[card].tx_num_channels) - openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i] ; - else - openair0_cfg[card].tx_freq[i]=0.0; - - if (i<openair0_cfg[card].rx_num_channels) - openair0_cfg[card].rx_freq[i] =downlink_frequency[0][i] + uplink_frequency_offset[0][i] ; - else - openair0_cfg[card].rx_freq[i]=0.0; - - openair0_cfg[card].autocal[i] = 1; - openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_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_id<RC.nb_RU; ru_id++) { if (RC.ru[ru_id]->rfdevice.trx_end_func) { diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 2b087e5456b129f0f7468065de22b851d56fc2b8..96ab799c3d11c5e1e2c2b0ce02710b50bf453873 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 c52fe130a1ed84fe80956cd593012e64f1e93a43..69556b19f263eb445f86de64d04a26c5ad458904 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"); + } } }