Commit b4c987a6 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'develop_integration_2018_w40' into 'develop'

Develop integration 2018 w40

See merge request oai/openairinterface5g!407
parents 4cbd9817 7260c9a9
...@@ -209,6 +209,15 @@ RUs = ( ...@@ -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 : NETWORK_CONTROLLER :
{ {
FLEXRAN_ENABLED = "no"; FLEXRAN_ENABLED = "no";
......
...@@ -209,6 +209,15 @@ RUs = ( ...@@ -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 : NETWORK_CONTROLLER :
{ {
FLEXRAN_ENABLED = "no"; FLEXRAN_ENABLED = "no";
......
...@@ -209,6 +209,15 @@ RUs = ( ...@@ -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 : NETWORK_CONTROLLER :
{ {
FLEXRAN_ENABLED = "no"; FLEXRAN_ENABLED = "no";
......
...@@ -326,26 +326,13 @@ class SSHConnection(): ...@@ -326,26 +326,13 @@ class SSHConnection():
loopCounter = loopCounter - 1 loopCounter = loopCounter - 1
if (loopCounter == 0): if (loopCounter == 0):
doLoop = False doLoop = False
# Checking if process is still alive logging.error('\u001B[1;37;41m eNB logging system did not show got sync! See with attach later \u001B[0m')
#self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', 0)
#result = re.search('lte-softmodem', str(self.ssh.before)) self.CreateHtmlFooter()
#if result is None: self.close()
# 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) sys.exit(1)
# 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)
else: 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)) result = re.search('got sync', str(self.ssh.before))
if result is None: if result is None:
time.sleep(6) time.sleep(6)
...@@ -354,7 +341,6 @@ class SSHConnection(): ...@@ -354,7 +341,6 @@ class SSHConnection():
self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', 0) self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', 0)
logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
self.command('rm -f enb_' + SSH.testCase_id + '.txt', '\$', 5)
self.close() self.close()
def InitializeUE_common(self, device_id): def InitializeUE_common(self, device_id):
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
--> -->
<testCaseList> <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> <TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101"> <testCase id="010101">
...@@ -42,6 +42,12 @@ ...@@ -42,6 +42,12 @@
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args> <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw</Initialize_eNB_args>
</testCase> </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"> <testCase id="030201">
<class>Terminate_eNB</class> <class>Terminate_eNB</class>
<desc>Terminate eNB</desc> <desc>Terminate eNB</desc>
...@@ -105,7 +111,7 @@ ...@@ -105,7 +111,7 @@
<iperf_profile>unbalanced</iperf_profile> <iperf_profile>unbalanced</iperf_profile>
</testCase> </testCase>
<testCase id="040701"> <testCase id="040611">
<class>Iperf</class> <class>Iperf</class>
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc> <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
...@@ -113,7 +119,7 @@ ...@@ -113,7 +119,7 @@
<iperf_profile>balanced</iperf_profile> <iperf_profile>balanced</iperf_profile>
</testCase> </testCase>
<testCase id="040702"> <testCase id="040612">
<class>Iperf</class> <class>Iperf</class>
<desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc> <desc>iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args> <iperf_args>-u -b 13.5M -t 30 -i 1</iperf_args>
...@@ -121,27 +127,58 @@ ...@@ -121,27 +127,58 @@
<iperf_profile>single-ue</iperf_profile> <iperf_profile>single-ue</iperf_profile>
</testCase> </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"> <testCase id="040641">
<class>Iperf</class> <class>Iperf</class>
<desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)(single-ue)</desc> <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc>
<iperf_args>-u -b 1M -t 30 -i 1 -R</iperf_args> <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile> <iperf_profile>balanced</iperf_profile>
</testCase> </testCase>
<testCase id="040642"> <testCase id="040642">
<class>Iperf</class> <class>Iperf</class>
<desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)(balanced)</desc> <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc>
<iperf_args>-u -b 1M -t 30 -i 1 -R</iperf_args> <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold> <iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>balanced</iperf_profile> <iperf_profile>single-ue</iperf_profile>
</testCase> </testCase>
<testCase id="040643"> <testCase id="040643">
<class>Iperf</class> <class>Iperf</class>
<desc>iperf (5MHz - UL/8Mbps/UDP)(30 sec)(unbalanced)</desc> <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)</desc>
<iperf_args>-u -b 8M -t 30 -i 1 -R</iperf_args> <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_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_profile>unbalanced</iperf_profile> <iperf_profile>unbalanced</iperf_profile>
</testCase> </testCase>
......
...@@ -2126,7 +2126,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ...@@ -2126,7 +2126,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
target_link_libraries (${myExe} 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 -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) endforeach(myExe)
......
...@@ -990,12 +990,12 @@ ...@@ -990,12 +990,12 @@
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args> <pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/ulsim.Rel14</main_exec> <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 <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
-B25 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 -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
-B50 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 -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
-B50 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 -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
-B100 -m5 -y1 -gN -x1 -s6 -w1.0 -e.1 -P -n500 -O70 -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
-B100 -m16 -y1 -gN -x1 -s12 -w1.0 -e.1 -P -n500 -O70 </main_exec_args> -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> <tags>ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6</tags>
<search_expr_true>"passed"</search_expr_true> <search_expr_true>"passed"</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
......
...@@ -76,7 +76,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { ...@@ -76,7 +76,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) {
init_unscrambling_lut(); init_unscrambling_lut();
init_scrambling_lut(); init_scrambling_lut();
//set_taus_seed(1328); //set_taus_seed(1328);
init_7_5KHz(); // init_7_5KHz();
init_sss(); init_sss();
} }
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "assertions.h" #include "assertions.h"
#include <math.h> #include <math.h>
void init_7_5KHz(void);
int phy_init_RU(RU_t *ru) { int phy_init_RU(RU_t *ru) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
...@@ -65,6 +67,7 @@ int phy_init_RU(RU_t *ru) { ...@@ -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 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); LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
for (i=0;i<ru->nb_rx;i++) { for (i=0;i<ru->nb_rx;i++) {
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "PHY/LTE_REFSIG/lte_refsig.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}; uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
...@@ -662,6 +664,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, ...@@ -662,6 +664,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
init_frame_parms(&ue->frame_parms,1); init_frame_parms(&ue->frame_parms,1);
init_lte_top(&ue->frame_parms); init_lte_top(&ue->frame_parms);
init_7_5KHz();
init_ul_hopping(&ue->frame_parms); init_ul_hopping(&ue->frame_parms);
......
...@@ -363,7 +363,7 @@ void *te_thread(void *param) { ...@@ -363,7 +363,7 @@ void *te_thread(void *param) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return(NULL); 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); 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); 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, ...@@ -573,7 +573,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
} }
stop_meas(te_wait_stats); 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); print_meas_now(te_wait_stats,"coding_wait",stderr);
printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx);
}*/ }*/
......
...@@ -782,7 +782,7 @@ int rx_pdsch(PHY_VARS_UE *ue, ...@@ -782,7 +782,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
#if DISABLE_LOG_X #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)); 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 #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
#endif #endif
// MRC // MRC
......
...@@ -52,8 +52,8 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ ...@@ -52,8 +52,8 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){
if (ts->trials>0) { 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,"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->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now); fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->p_time/(cpu_freq_GHz*1000.0)),(double)ts->p_time);
} }
} }
......
...@@ -40,7 +40,6 @@ typedef struct { ...@@ -40,7 +40,6 @@ typedef struct {
long long in; long long in;
long long diff; long long diff;
long long diff_now;
long long p_time; /*!< \brief absolute process duration */ long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */ long long diff_square; /*!< \brief process duration square */
long long max; long long max;
...@@ -50,7 +49,6 @@ typedef struct { ...@@ -50,7 +49,6 @@ typedef struct {
#elif defined(__arm__) #elif defined(__arm__)
typedef struct { typedef struct {
uint32_t in; uint32_t in;
uint32_t diff_now;
uint32_t diff; uint32_t diff;
uint32_t p_time; /*!< \brief absolute process duration */ uint32_t p_time; /*!< \brief absolute process duration */
uint32_t diff_square; /*!< \brief process duration square */ uint32_t diff_square; /*!< \brief process duration square */
...@@ -116,9 +114,6 @@ static inline void stop_meas(time_stats_t *ts) ...@@ -116,9 +114,6 @@ static inline void stop_meas(time_stats_t *ts)
if (opp_enabled) { if (opp_enabled) {
long long out = rdtsc_oai(); long long out = rdtsc_oai();
ts->diff_now = (out-ts->in);
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in); ts->diff += (out-ts->in);
/// process duration is the difference between two clock points /// process duration is the difference between two clock points
ts->p_time = (out-ts->in); ts->p_time = (out-ts->in);
...@@ -135,7 +130,6 @@ static inline void reset_meas(time_stats_t *ts) { ...@@ -135,7 +130,6 @@ static inline void reset_meas(time_stats_t *ts) {
ts->trials=0; ts->trials=0;
ts->diff=0; ts->diff=0;
ts->diff_now=0;
ts->p_time=0; ts->p_time=0;
ts->diff_square=0; ts->diff_square=0;
ts->max=0; ts->max=0;
......
...@@ -412,7 +412,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, ...@@ -412,7 +412,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
&eNB->dlsch_turbo_encoding_wakeup_stats1, &eNB->dlsch_turbo_encoding_wakeup_stats1,
&eNB->dlsch_interleaving_stats); &eNB->dlsch_interleaving_stats);
stop_meas(&eNB->dlsch_encoding_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); 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) ...@@ -1337,7 +1337,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
ret, ret,
ulsch_harq->cqi_crc_status, ulsch_harq->cqi_crc_status,
ulsch_harq->O_ACK, 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) //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 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) ...@@ -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 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
stop_meas(&eNB->phy_proc_rx);
} }
...@@ -50,10 +50,6 @@ ...@@ -50,10 +50,6 @@
#include "targets/RT/USER/rt_wrapper.h" #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; extern int oai_exit;
...@@ -160,7 +156,7 @@ static void *feptx_thread(void *param) { ...@@ -160,7 +156,7 @@ static void *feptx_thread(void *param) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return NULL; 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); 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); 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) { ...@@ -220,7 +216,7 @@ void feptx_ofdm_2thread(RU_t *ru) {
start_meas(&ru->ofdm_mod_wait_stats); start_meas(&ru->ofdm_mod_wait_stats);
wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread"); wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"feptx thread");
stop_meas(&ru->ofdm_mod_wait_stats); 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); 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); 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) { ...@@ -467,7 +463,7 @@ static void *fep_thread(void *param) {
exit_fun( "ERROR pthread_cond_signal" ); exit_fun( "ERROR pthread_cond_signal" );
return NULL; 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); 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); 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) { ...@@ -582,7 +578,7 @@ void ru_fep_full_2thread(RU_t *ru) {
start_meas(&ru->ofdm_demod_wait_stats); start_meas(&ru->ofdm_demod_wait_stats);
wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread"); wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"fep thread");
stop_meas(&ru->ofdm_demod_wait_stats); 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); 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); printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
} }
......
/* /*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under 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 the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. except in compliance with the License.
* You may obtain a copy of the License at You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698 http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and See the License for the specific language governing permissions and
* limitations under the License. limitations under the License.
*------------------------------------------------------------------------------- -------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance: For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org contact@openairinterface.org
*/ */
/*! \file ulsim.c /*! \file ulsim.c
\brief Top-level UL simulator \brief Top-level UL simulator
\author R. Knopp \author R. Knopp
\date 2011 - 2014 \date 2011 - 2014
\version 0.1 \version 0.1
\company Eurecom \company Eurecom
\email: knopp@eurecom.fr \email: knopp@eurecom.fr
\note \note
\warning \warning
*/ */
#include <string.h> #include <string.h>
...@@ -58,21 +58,43 @@ ...@@ -58,21 +58,43 @@
#include "common/config/config_load_configmodule.h" #include "common/config/config_load_configmodule.h"
double cpuf; 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 *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_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 *enb_data[NUMBER_OF_eNB_MAX];
node_desc_t *ue_data[NUMBER_OF_UE_MAX]; node_desc_t *ue_data[NUMBER_OF_UE_MAX];
//double sinr_bler_map[MCS_COUNT][2][16]; //double sinr_bler_map[MCS_COUNT][2][16];
extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16]; extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16];
//extern char* namepointer_chMag ; //extern char* namepointer_chMag ;
int xforms=0; int xforms=0;
FD_lte_phy_scope_enb *form_enb; FD_lte_phy_scope_enb *form_enb;
char title[255]; char title[255];
...@@ -88,6 +110,8 @@ int nfapi_mode = 0; ...@@ -88,6 +110,8 @@ int nfapi_mode = 0;
extern void fep_full(RU_t *ru); extern void fep_full(RU_t *ru);
extern void ru_fep_full_2thread(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_dl_config_request_t DL_req;
nfapi_ul_config_request_t UL_req; nfapi_ul_config_request_t UL_req;
...@@ -124,32 +148,29 @@ WORKER_CONF_t get_thread_worker_conf(void) ...@@ -124,32 +148,29 @@ WORKER_CONF_t get_thread_worker_conf(void)
void void
fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint8_t cqi_req, uint8_t cqi_req,
uint8_t p_eNB, uint8_t p_eNB,
uint8_t cqi_ReportModeAperiodic, uint8_t cqi_ReportModeAperiodic,
uint8_t betaOffset_CQI_Index, uint8_t betaOffset_CQI_Index,
uint8_t betaOffset_RI_Index, uint8_t betaOffset_RI_Index,
uint8_t dl_cqi_pmi_size, uint8_t dl_cqi_pmi_size,
uint8_t tmode, uint8_t tmode,
uint32_t handle, uint32_t handle,
uint16_t rnti, uint16_t rnti,
uint8_t resource_block_start, uint8_t resource_block_start,
uint8_t number_of_resource_blocks, uint8_t number_of_resource_blocks,
uint8_t modulation_type, uint8_t modulation_type,
uint8_t cyclic_shift_2_for_drms, uint8_t cyclic_shift_2_for_drms,
uint8_t frequency_hopping_enabled_flag, uint8_t frequency_hopping_enabled_flag,
uint8_t frequency_hopping_bits, uint8_t frequency_hopping_bits,
uint8_t new_data_indication, uint8_t new_data_indication,
uint8_t redundancy_version, uint8_t redundancy_version,
uint8_t harq_process_number, uint8_t harq_process_number,
uint8_t ul_tx_mode, uint8_t ul_tx_mode,
uint8_t current_tx_nb, uint8_t current_tx_nb,
uint8_t n_srs, uint8_t n_srs,
uint16_t size) uint16_t size) {
{
memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); 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_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); 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; 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, ...@@ -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); 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 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; 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 <= 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; 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; 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 < (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++) 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.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_cqi = betaOffset_CQI_Index;
ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_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, ...@@ -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, void fill_ulsch_dci(PHY_VARS_eNB *eNB,
int frame, int frame,
int subframe, int subframe,
Sched_Rsp_t *sched_resp, Sched_Rsp_t *sched_resp,
uint16_t rnti, uint16_t rnti,
void *UL_dci, void *UL_dci,
int first_rb, int first_rb,
int nb_rb, int nb_rb,
int mcs, int mcs,
int modulation_type, int modulation_type,
int ndi, int ndi,
int TBS, int TBS,
int cqi_flag, int cqi_flag,
uint8_t beta_CQI, uint8_t beta_CQI,
uint8_t beta_RI, uint8_t beta_RI,
uint8_t cqi_size) { uint8_t cqi_size) {
nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body;
int harq_pid = ((frame*10)+subframe)&7; 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); //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) { switch (eNB->frame_parms.N_RB_UL) {
case 6: case 6:
break; 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;
}
break; case 25:
if (eNB->frame_parms.frame_type == TDD) {
case 50: ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->type = 0;
if (eNB->frame_parms.frame_type == TDD) { ((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
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->type = 0; //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_10MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->mcs = mcs;
// 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_5MHz_TDD_1_6_t *)UL_dci)->ndi = ndi;
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->mcs = mcs; ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->TPC = 0;
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->ndi = ndi; ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1;
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->TPC = 0; ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cshift = 0;
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1; ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->dai = 1;
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cshift = 0; } else {
((DCI0_10MHz_TDD_1_6_t*)UL_dci)->dai = 1; ((DCI0_5MHz_FDD_t *)UL_dci)->type = 0;
} else { ((DCI0_5MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
((DCI0_10MHz_FDD_t*)UL_dci)->type = 0; // 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_10MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8 ((DCI0_5MHz_FDD_t *)UL_dci)->mcs = mcs;
//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_5MHz_FDD_t *)UL_dci)->ndi = ndi;
((DCI0_10MHz_FDD_t*)UL_dci)->mcs = mcs; ((DCI0_5MHz_FDD_t *)UL_dci)->TPC = 0;
((DCI0_10MHz_FDD_t*)UL_dci)->ndi = ndi; ((DCI0_5MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1;
((DCI0_10MHz_FDD_t*)UL_dci)->TPC = 0; ((DCI0_5MHz_FDD_t *)UL_dci)->cshift = 0;
((DCI0_10MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1; }
((DCI0_10MHz_FDD_t*)UL_dci)->cshift = 0;
}
break; break;
case 100:
if (eNB->frame_parms.frame_type == TDD) {
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->type = 0;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
// printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->mcs = mcs;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->ndi = ndi;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->TPC = 0;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cshift = 0;
((DCI0_20MHz_TDD_1_6_t*)UL_dci)->dai = 1;
} else {
((DCI0_20MHz_FDD_t*)UL_dci)->type = 0;
((DCI0_20MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
// printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci);
((DCI0_20MHz_FDD_t*)UL_dci)->mcs = mcs;
((DCI0_20MHz_FDD_t*)UL_dci)->ndi = ndi;
((DCI0_20MHz_FDD_t*)UL_dci)->TPC = 0;
((DCI0_20MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1;
((DCI0_20MHz_FDD_t*)UL_dci)->cshift = 0;
}
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], fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0],
cqi_flag&1, cqi_flag&1,
1, // p_eNB 1, // p_eNB
0, // reportmode Aperiodic 0, // reportmode Aperiodic
beta_CQI, beta_CQI,
beta_RI, beta_RI,
cqi_size, cqi_size,
//cc, //cc,
//UE_template->physicalConfigDedicated, //UE_template->physicalConfigDedicated,
1, 1,
0, 0,
14, // rnti 14, // rnti
first_rb, // resource_block_start first_rb, // resource_block_start
nb_rb, // number_of_resource_blocks nb_rb, // number_of_resource_blocks
modulation_type, modulation_type,
0, // cyclic_shift_2_for_drms 0, // cyclic_shift_2_for_drms
0, // frequency_hopping_enabled_flag 0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits 0, // frequency_hopping_bits
ndi, // new_data_indication ndi, // new_data_indication
mcs>28?(mcs-28):0, // redundancy_version mcs>28?(mcs-28):0, // redundancy_version
harq_pid, // harq_process_number harq_pid, // harq_process_number
0, // ul_tx_mode 0, // ul_tx_mode
0, // current_tx_nb 0, // current_tx_nb
0, // n_srs 0, // n_srs
TBS); TBS);
sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
ul_req->number_of_pdus=1; ul_req->number_of_pdus=1;
ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; 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); void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) {
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); 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; int i,j,aa,u;
PHY_VARS_eNB *eNB; PHY_VARS_eNB *eNB;
PHY_VARS_UE *UE; PHY_VARS_UE *UE;
RU_t *ru; RU_t *ru;
int aarx,aatx; int aarx,aatx;
double channelx,channely; double channelx,channely;
double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; static 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 input_snr_step=.2,snr_int=30;
double blerr; 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; int **txdata;
LTE_DL_FRAME_PARMS *frame_parms; LTE_DL_FRAME_PARMS *frame_parms;
double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; 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 s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720];
double r_re2[30720],r_im2[30720]; double r_re2[30720],r_im2[30720];
double r_re3[30720],r_im3[30720]; double r_re3[30720],r_im3[30720];
double *s_re[2]={s_re0,s_re1}; double *s_re[2]= {s_re0,s_re1};
double *s_im[2]={s_im0,s_im1}; double *s_im[2]= {s_im0,s_im1};
double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; 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 *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 forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
double iqim=0.0; double iqim=0.0;
uint8_t extended_prefix_flag=0; int cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives;
int cqi_flag=0,cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives;
int ch_realization; int ch_realization;
int eNB_id = 0; int eNB_id = 0;
int chMod = 0 ; int chMod = 0 ;
int UE_id = 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 l;
static int awgn_flag = 0 ;
unsigned char awgn_flag = 0 ;
SCM_t channel_model=Rice1; SCM_t channel_model=Rice1;
unsigned char *input_buffer=0,harq_pid;
unsigned char *input_buffer,harq_pid;
unsigned short input_buffer_length; unsigned short input_buffer_length;
unsigned int ret; unsigned int ret;
unsigned int coded_bits_per_codeword,nsymb; 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}; 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; FILE *bler_fd=NULL;
char bler_fname[512]; char bler_fname[512];
FILE *time_meas_fd=NULL; FILE *time_meas_fd=NULL;
char time_meas_fname[256]; char time_meas_fname[256];
FILE *input_fdUL=NULL,*trch_out_fdUL=NULL; FILE *input_fdUL=NULL,*trch_out_fdUL=NULL;
// unsigned char input_file=0; // unsigned char input_file=0;
char input_val_str[50],input_val_str2[50]; char input_val_str[50],input_val_str2[50];
// FILE *rx_frame_file; // FILE *rx_frame_file;
FILE *csv_fdUL=NULL; FILE *csv_fdUL=NULL;
/* /*
FILE *fperen=NULL; FILE *fperen=NULL;
char fperen_name[512]; char fperen_name[512];
FILE *fmageren=NULL; FILE *fmageren=NULL;
char fmageren_name[512]; char fmageren_name[512];
FILE *flogeren=NULL; FILE *flogeren=NULL;
char flogeren_name[512]; char flogeren_name[512];
*/ */
/* FILE *ftxlev; /* FILE *ftxlev;
char ftxlev_name[512]; char ftxlev_name[512];
*/ */
char csv_fname[512]; char csv_fname[512];
int n_frames=5000; static int n_frames=5000;
int n_ch_rlz = 1; static int n_ch_rlz = 1;
int abstx = 0; static int abstx = 0;
int hold_channel=0; int hold_channel=0;
channel_desc_t *UE2eNB; channel_desc_t *UE2eNB;
//uint8_t control_only_flag = 0; //uint8_t control_only_flag = 0;
int delay = 0; static int delay = 0;
double maxDoppler = 0.0; static double maxDoppler = 0.0;
uint8_t srs_flag = 0; static int srs_flag = 0;
static int N_RB_DL=25,osf=1;
uint8_t N_RB_DL=25,osf=1;
//uint8_t cyclic_shift = 0; //uint8_t cyclic_shift = 0;
uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; static uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11;
uint8_t tdd_config=3,frame_type=FDD; static uint8_t tdd_config=3,frame_type=FDD;
static int N0=30;
uint8_t N0=30; static double tx_gain=1.0;
double tx_gain=1.0;
double cpu_freq_GHz; double cpu_freq_GHz;
int avg_iter,iter_trials; int iter_trials;
uint32_t UL_alloc_pdu; uint32_t UL_alloc_pdu;
int s,Kr,Kr_bytes; int s,Kr,Kr_bytes;
int dump_perf=0; int dump_perf=0;
int test_perf=0; static int dump_table =0;
int dump_table =0;
double effective_rate=0.0; double effective_rate=0.0;
char channel_model_input[10]; char channel_model_input[10]= {0};
static int max_turbo_iterations=4;
uint8_t max_turbo_iterations=4; static int parallel_flag=0;
uint8_t parallel_flag=0;
int nb_rb_set = 0; int nb_rb_set = 0;
int sf; int sf;
static int threequarter_fs=0;
int threequarter_fs=0;
int ndi; int ndi;
opp_enabled=1; // to enable the time meas opp_enabled=1; // to enable the time meas
sched_resp.DL_req = &DL_req; sched_resp.DL_req = &DL_req;
sched_resp.UL_req = &UL_req; sched_resp.UL_req = &UL_req;
sched_resp.HI_DCI0_req = &HI_DCI0_req; sched_resp.HI_DCI0_req = &HI_DCI0_req;
sched_resp.TX_req = &TX_req; sched_resp.TX_req = &TX_req;
memset((void*)&DL_req,0,sizeof(DL_req)); memset((void *)&DL_req,0,sizeof(DL_req));
memset((void*)&UL_req,0,sizeof(UL_req)); memset((void *)&UL_req,0,sizeof(UL_req));
memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req));
memset((void*)&TX_req,0,sizeof(TX_req)); memset((void *)&TX_req,0,sizeof(TX_req));
UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; 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; TX_req.tx_request_body.tx_pdu_list = tx_pdu_list;
cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpu_freq_GHz = (double)get_cpu_freq_GHz();
cpuf = cpu_freq_GHz; cpuf = cpu_freq_GHz;
printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
AssertFatal(load_configmodule(argc,argv) != NULL, AssertFatal(load_configmodule(argc,argv) != NULL,
"cannot load configuration module, exiting\n"); "cannot load configuration module, exiting\n");
logInit(); logInit();
// enable these lines if you need debug info // enable these lines if you need debug info
// however itti will catch all signals, so ctrl-c won't work anymore // however itti will catch all signals, so ctrl-c won't work anymore
// alternatively you can disable ITTI completely in CMakeLists.txt // 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); //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_comp_log(PHY,LOG_DEBUG,LOG_MED,1);
//set_glog(LOG_DEBUG,LOG_MED); //set_glog(LOG_DEBUG,LOG_MED);
//hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF
static paramdef_t options[] = {
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) { { "awgn", "Additive white gaussian noise", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
switch (c) { { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 },
case 'a': { "mcs", "The MCS to use", 0, iptr:&mcs, defintval:10, TYPE_INT, 0 },
channel_model = AWGN; { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 },
chMod = 1; { "snr", "starting snr", 0, dblptr:&snr0, defdblval:-2.9, TYPE_DOUBLE, 0 },
break; { "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 },
case 'b': { "rb_dynamic", "number of rb in dynamic allocation",0, iptr:NULL, defintval:0, TYPE_INT, 0 },
bundling_flag = 0; { "first_rb", "first rb used in dynamic allocation",0, iptr:&first_rb, defintval:0, TYPE_INT, 0 },
break; { "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:&parallel_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': case TYPE_DOUBLE:
delay = atoi(optarg); *options[i].dblptr=options[i].defdblval;
break; break;
case 'D': default:
maxDoppler = atoi(optarg); printf("not parsed type for default value %s\n", options[i].optname );
break; exit(1);
}
case 'm': continue;
mcs = atoi(optarg); };
break;
case 'n': int option_index;
n_frames = atoi(optarg);
break;
case 'Y': int res;
n_ch_rlz = atoi(optarg);
break;
case 'X': while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) {
abstx= atoi(optarg); if (options[option_index].voidptr != NULL ) {
break; 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': case TYPE_DOUBLE:
sprintf(channel_model_input,optarg,10); *(double *)options[option_index].dblptr=atof(optarg);
break;
switch((char)*optarg) { default:
case 'A': printf("not decoded type.\n");
channel_model=SCM_A; exit(1);
chMod = 2; }
break;
case 'B': continue;
channel_model=SCM_B; }
chMod = 3;
break;
case 'C': switch (long_options[option_index].name[0]) {
channel_model=SCM_C; case 'T':
chMod = 4; tdd_config=atoi(optarg);
frame_type=TDD;
break; break;
case 'D': case 'a':
channel_model=SCM_D; channel_model = AWGN;
chMod = 5; chMod = 1;
break; break;
case 'E': case 'g':
channel_model=EPA; strncpy(channel_model_input,optarg,9);
chMod = 6; struct tmp {
break; 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': AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg );
channel_model=EVA;
chMod = 7;
break; break;
case 'G': case 'x':
channel_model=ETU; transmission_m=atoi(optarg);
chMod = 8; AssertFatal(transmission_m==1 || transmission_m==2,
"Unsupported transmission mode %d\n",transmission_m);
break; break;
case 'H': case 'r':
channel_model=Rayleigh8; nb_rb = atoi(optarg);
chMod = 9; nb_rb_set = 1;
break; break;
case 'I': //case 'c':
channel_model=Rayleigh1; // cyclic_shift = atoi(optarg);
chMod = 10; // break;
break;
case 'J': case 'i':
channel_model=Rayleigh1_corr; input_fdUL = fopen(optarg,"r");
chMod = 11; printf("Reading in %s (%p)\n",optarg,input_fdUL);
AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg);
break; break;
case 'K': case 'A':
channel_model=Rayleigh1_anticorr; beta_ACK = atoi(optarg);
chMod = 12; AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n");
break; break;
case 'L': case 'C':
channel_model=Rice8; beta_CQI = atoi(optarg);
chMod = 13; AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n");
break; break;
case 'M': case 'R':
channel_model=Rice1; beta_RI = atoi(optarg);
chMod = 14; AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n");
break; break;
case 'N': case 'P':
channel_model=AWGN; dump_perf=1;
chMod = 1; opp_enabled=1;
break; break;
default: default:
printf("Unsupported channel model!\n"); printf("Wrong option\n");
exit(-1); exit(1);
break; 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': if ( res != -1 ) {
N_RB_DL=atoi(optarg); printf("A wrong option has been found\n");
break; exit(1);
}
case 'P': paramdef_t *ptr=options ;
dump_perf=1;
opp_enabled=1;
break;
case 'O': for( ptr=options; ptr->optname[0]!=0; ptr++) {
test_perf=atoi(optarg); char varText[256]="need specific display";
//print_perf =1;
break;
case 'L': if (ptr->voidptr != NULL) {
parallel_flag=1; if ( (ptr->paramflags & PARAMFLAG_BOOL) )
break; strcpy(varText, *(bool *)ptr->iptr ? "True": "False" );
else switch (ptr->type) {
case TYPE_INT:
sprintf(varText,"%d",*ptr->iptr);
break;
case 'I': case TYPE_DOUBLE:
max_turbo_iterations=atoi(optarg); sprintf(varText,"%.2f",*ptr->dblptr);
break; break;
case 'F': default:
xforms=1; printf("not decoded type\n");
break; exit(1);
}
}
case 'Z': printf("Option: %20s set to %s\n",ptr->optname, varText);
dump_table = 1;
break;
case 'h': if (verbose)
default: printf("%s\n",ptr->helpstr);
/* 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;
}
} }
set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT");
set_worker_conf("WORKER_ENABLE"); set_worker_conf("WORKER_ENABLE");
RC.nb_L1_inst = 1; RC.nb_L1_inst = 1;
RC.nb_RU = 1; RC.nb_RU = 1;
lte_param_init(&eNB,&UE,&ru, lte_param_init(&eNB,&UE,&ru,
1,
1,
n_rx,
1, 1,
1, 1,
extended_prefix_flag, n_rx,
frame_type, 1,
0, 1,
tdd_config, extended_prefix_flag,
N_RB_DL, frame_type,
4, 0,
threequarter_fs, tdd_config,
osf, N_RB_DL,
0); 4,
threequarter_fs,
osf,
0);
RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **));
RC.eNB[0] = (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.ru = (RU_t **)malloc(sizeof(RC.ru));
RC.eNB[0][0] = eNB; RC.eNB[0][0] = eNB;
RC.ru[0] = ru; 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"); printf("Setting indication lists\n");
eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; 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; 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) ...@@ -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.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_pdu_list = eNB->cqi_pdu_list;
eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
printf("lte_param_init done\n"); 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 // 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 = (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] = (PHY_VARS_UE **) malloc(sizeof(PHY_VARS_UE *));
PHY_vars_UE_g[0][0] = UE; PHY_vars_UE_g[0][0] = UE;
if (nb_rb_set == 0) if (nb_rb_set == 0)
...@@ -799,19 +769,14 @@ int main(int argc, char **argv) ...@@ -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("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]);
printf("Setting mcs = %d\n",mcs); printf("Setting mcs = %d\n",mcs);
printf("n_frames = %d\n", n_frames); printf("n_frames = %d\n", n_frames);
snr1 = snr0+snr_int; snr1 = snr0+snr_int;
printf("SNR0 %f, SNR1 %f\n",snr0,snr1); printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
frame_parms = &eNB->frame_parms; frame_parms = &eNB->frame_parms;
txdata = UE->common_vars.txdata; txdata = UE->common_vars.txdata;
nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12; 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); 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"); bler_fd = fopen(bler_fname,"w");
if (bler_fd==NULL) { if (bler_fd==NULL) {
fprintf(stderr,"Problem creating file %s\n",bler_fname); fprintf(stderr,"Problem creating file %s\n",bler_fname);
exit(-1); exit(-1);
...@@ -828,8 +793,9 @@ int main(int argc, char **argv) ...@@ -828,8 +793,9 @@ int main(int argc, char **argv)
//sprintf(dirname, "%s//SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname); //sprintf(dirname, "%s//SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname);
//mkdir(dirname, 0777); //mkdir(dirname, 0777);
sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_antrx%d_channel%s_tx%d.csv", 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"); time_meas_fd = fopen(time_meas_fname,"w");
if (time_meas_fd==NULL) { if (time_meas_fd==NULL) {
fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
exit(-1); exit(-1);
...@@ -838,16 +804,17 @@ int main(int argc, char **argv) ...@@ -838,16 +804,17 @@ int main(int argc, char **argv)
if(abstx) { if(abstx) {
// CSV file // 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"); csv_fdUL = fopen(csv_fname,"w");
if (csv_fdUL == NULL) { if (csv_fdUL == NULL) {
fprintf(stderr,"Problem opening file %s\n",csv_fname); fprintf(stderr,"Problem opening file %s\n",csv_fname);
exit(-1); exit(-1);
} }
fprintf(csv_fdUL,"data_all%d=[",mcs); fprintf(csv_fdUL,"data_all%d=[",mcs);
} }
if (xforms==1) { if (xforms==1) {
fl_initialize (&argc, argv, NULL, 0, 0); fl_initialize (&argc, argv, NULL, 0, 0);
form_enb = create_lte_phy_scope_enb(); form_enb = create_lte_phy_scope_enb();
...@@ -856,7 +823,6 @@ int main(int argc, char **argv) ...@@ -856,7 +823,6 @@ int main(int argc, char **argv)
} }
UE->pdcch_vars[0][0]->crnti = 14; 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.enabled_flag = srs_flag;
UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3;
...@@ -867,7 +833,6 @@ int main(int argc, char **argv) ...@@ -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].transmissionComb = 0;
UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0; UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0;
UE->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = 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.enabled_flag = srs_flag;
eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3;
...@@ -878,29 +843,22 @@ int main(int argc, char **argv) ...@@ -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].transmissionComb = 0;
eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0;
eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 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_ACK_Index = beta_ACK;
eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI;
eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI; 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_ACK_Index = beta_ACK;
UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = beta_RI; UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = beta_RI;
UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI; UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1; UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1;
// disable periodic cqi/ri reporting // disable periodic cqi/ri reporting
UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_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); 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, UE2eNB = new_channel_desc_scm(1,
n_rx, n_rx,
channel_model, channel_model,
N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
forgetting_factor, forgetting_factor,
delay, delay,
0); 0);
...@@ -908,7 +866,8 @@ int main(int argc, char **argv) ...@@ -908,7 +866,8 @@ int main(int argc, char **argv)
UE2eNB->max_Doppler = maxDoppler; UE2eNB->max_Doppler = maxDoppler;
// NN: N_RB_UL has to be defined in ulsim // 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); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
printf("ULSCH %p\n",UE->ulsch[0]); printf("ULSCH %p\n",UE->ulsch[0]);
...@@ -918,70 +877,66 @@ int main(int argc, char **argv) ...@@ -918,70 +877,66 @@ int main(int argc, char **argv)
init_fep_thread(eNB,NULL); init_fep_thread(eNB,NULL);
init_td_thread(eNB); init_td_thread(eNB);
} }
// Create transport channel structures for 2 transport blocks (MIMO) // Create transport channel structures for 2 transport blocks (MIMO)
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms);
if (!eNB->dlsch[0][i]) { if (!eNB->dlsch[0][i]) {
printf("Can't get eNB dlsch structures\n"); printf("Can't get eNB dlsch structures\n");
exit(-1); exit(-1);
} }
eNB->dlsch[0][i]->rnti = 14; eNB->dlsch[0][i]->rnti = 14;
} }
/* allocate memory for both subframes (only one is really used /* allocate memory for both subframes (only one is really used
* but there is now "copy_harq_proc_struct" which needs both but there is now "copy_harq_proc_struct" which needs both
* to be valid) to be valid)
* TODO: refine this somehow (necessary?) TODO: refine this somehow (necessary?)
*/ */
for (sf = 0; sf < 2; sf++) { for (sf = 0; sf < 2; sf++) {
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
UE->dlsch[sf][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->dlsch[sf][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
if (!UE->dlsch[sf][0][i]) { if (!UE->dlsch[sf][0][i]) {
printf("Can't get ue dlsch structures\n"); printf("Can't get ue dlsch structures\n");
exit(-1); exit(-1);
} }
UE->dlsch[sf][0][i]->rnti = 14; 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_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->dlsch_ra[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
UE->measurements.rank[0] = 0; UE->measurements.rank[0] = 0;
UE->transmission_mode[0] = 2; 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->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; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
eNB->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; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
eNB->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; UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
UE->mac_enabled=0; UE->mac_enabled=0;
eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; 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]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1];
proc_rxtx->frame_rx=1; proc_rxtx->frame_rx=1;
proc_rxtx->subframe_rx=subframe; proc_rxtx->subframe_rx=subframe;
proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,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->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe);
proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; 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->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_tx = proc_rxtx->subframe_rx;
proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
printf("Init UL hopping UE\n"); printf("Init UL hopping UE\n");
init_ul_hopping(&UE->frame_parms); init_ul_hopping(&UE->frame_parms);
printf("Init UL hopping eNB\n"); printf("Init UL hopping eNB\n");
init_ul_hopping(&eNB->frame_parms); 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->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->ulsch_Msg3_active[eNB_id] = 0;
UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1;
coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb; coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb;
...@@ -989,26 +944,20 @@ int main(int argc, char **argv) ...@@ -989,26 +944,20 @@ int main(int argc, char **argv)
if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O; 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); 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); 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++) { for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
/* /*
if(abstx){ if(abstx){
int ulchestim_f[300*12]; int ulchestim_f[300*12];
int ulchestim_t[2*(frame_parms->ofdm_symbol_size)]; int ulchestim_t[2*(frame_parms->ofdm_symbol_size)];
} }
*/ */
if(abstx) { if(abstx) {
printf("**********************Channel Realization Index = %d **************************\n", ch_realization); printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
saving_bler=1; saving_bler=1;
} }
// if ((subframe>5) || (subframe < 4)) // if ((subframe>5) || (subframe < 4))
// UE->frame++; // UE->frame++;
...@@ -1026,17 +975,17 @@ int main(int argc, char **argv) ...@@ -1026,17 +975,17 @@ int main(int argc, char **argv)
cqi_crc_falsepositives=0; cqi_crc_falsepositives=0;
cqi_crc_falsenegatives=0; cqi_crc_falsenegatives=0;
round=0; round=0;
//randominit(0); //randominit(0);
harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe); 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; 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); 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); // printf("UL frame %d/subframe %d, harq_pid %d\n",UE->frame,subframe,harq_pid);
if (input_fdUL == NULL) { if (input_fdUL == NULL) {
if (n_frames == 1) { if (n_frames == 1) {
trch_out_fdUL= fopen("ulsch_trchUL.txt","w"); trch_out_fdUL= fopen("ulsch_trchUL.txt","w");
...@@ -1058,14 +1007,15 @@ int main(int argc, char **argv) ...@@ -1058,14 +1007,15 @@ int main(int argc, char **argv)
while (!feof(input_fdUL)) { while (!feof(input_fdUL)) {
ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); 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 (ret != 2) printf("ERROR: error reading file\n");
if ((i%4)==0) { if ((i%4)==0) {
((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,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)); ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL));
if ((i/4)<100) 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++; i++;
...@@ -1080,10 +1030,8 @@ int main(int argc, char **argv) ...@@ -1080,10 +1030,8 @@ int main(int argc, char **argv)
tx_lev = signal_energy(&txdata[0][0], tx_lev = signal_energy(&txdata[0][0],
OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
tx_lev_dB = (unsigned int) dB_fixed(tx_lev); tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
} }
avg_iter = 0;
iter_trials=0; iter_trials=0;
reset_meas(&UE->phy_proc_tx); reset_meas(&UE->phy_proc_tx);
reset_meas(&UE->ofdm_mod_stats); reset_meas(&UE->ofdm_mod_stats);
...@@ -1094,7 +1042,6 @@ int main(int argc, char **argv) ...@@ -1094,7 +1042,6 @@ int main(int argc, char **argv)
reset_meas(&UE->ulsch_turbo_encoding_stats); reset_meas(&UE->ulsch_turbo_encoding_stats);
reset_meas(&UE->ulsch_segmentation_stats); reset_meas(&UE->ulsch_segmentation_stats);
reset_meas(&UE->ulsch_multiplexing_stats); reset_meas(&UE->ulsch_multiplexing_stats);
reset_meas(&eNB->phy_proc_rx); reset_meas(&eNB->phy_proc_rx);
reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_channel_estimation_stats);
reset_meas(&eNB->ulsch_freq_offset_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats);
...@@ -1104,6 +1051,7 @@ int main(int argc, char **argv) ...@@ -1104,6 +1051,7 @@ int main(int argc, char **argv)
reset_meas(&eNB->ulsch_deinterleaving_stats); reset_meas(&eNB->ulsch_deinterleaving_stats);
reset_meas(&eNB->ulsch_demultiplexing_stats); reset_meas(&eNB->ulsch_demultiplexing_stats);
reset_meas(&eNB->ulsch_rate_unmatching_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_init_stats);
reset_meas(&eNB->ulsch_tc_alpha_stats); reset_meas(&eNB->ulsch_tc_alpha_stats);
reset_meas(&eNB->ulsch_tc_beta_stats); reset_meas(&eNB->ulsch_tc_beta_stats);
...@@ -1111,91 +1059,82 @@ int main(int argc, char **argv) ...@@ -1111,91 +1059,82 @@ int main(int argc, char **argv)
reset_meas(&eNB->ulsch_tc_ext_stats); reset_meas(&eNB->ulsch_tc_ext_stats);
reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_tc_intl1_stats);
reset_meas(&eNB->ulsch_tc_intl2_stats); reset_meas(&eNB->ulsch_tc_intl2_stats);
// initialization // initialization
struct list time_vector_tx; varArray_t *table_tx=initVarArray(1000,sizeof(double));
initialize(&time_vector_tx); varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double));
struct list time_vector_tx_ifft; varArray_t *table_tx_mod=initVarArray(1000,sizeof(double));
initialize(&time_vector_tx_ifft); varArray_t *table_tx_enc=initVarArray(1000,sizeof(double));
struct list time_vector_tx_mod; varArray_t *table_rx=initVarArray(1000,sizeof(double));
initialize(&time_vector_tx_mod); varArray_t *table_rx_fft=initVarArray(1000,sizeof(double));
struct list time_vector_tx_enc; varArray_t *table_rx_demod=initVarArray(1000,sizeof(double));
initialize(&time_vector_tx_enc); varArray_t *table_rx_dec=initVarArray(1000,sizeof(double));
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);
ndi=0; ndi=0;
phy_reset_ue(0,0,0); phy_reset_ue(0,0,0);
UE->UE_mode[eNB_id]=PUSCH; UE->UE_mode[eNB_id]=PUSCH;
SET_LOG_DEBUG(UE_TIMING);
for (trials = 0; trials<n_frames; trials++) { for (trials = 0; trials<n_frames; trials++) {
// printf("*"); // printf("*");
// UE->frame++; // UE->frame++;
// eNB->frame++; // eNB->frame++;
ndi = (1-ndi); ndi = (1-ndi);
fflush(stdout); fflush(stdout);
round=0; round=0;
while (round < 4) { while (round < 4) {
proc_rxtx->frame_rx=1; proc_rxtx->frame_rx=1;
proc_rxtx->subframe_rx=subframe; proc_rxtx->subframe_rx=subframe;
proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,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->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->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
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; eNB->ulsch[0]->harq_processes[harq_pid]->round=round;
UE->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: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx);
if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe);
int modulation_type; round_trials[round]++;
if (mcs < 11) modulation_type = 2; UL_req.sfn_sf = (1<<4)+subframe;
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);
}
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; int modulation_type;
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; if (mcs < 11) modulation_type = 2;
sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; 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) { if (abstx) {
...@@ -1214,31 +1153,24 @@ int main(int argc, char **argv) ...@@ -1214,31 +1153,24 @@ int main(int argc, char **argv)
/////////////////////////////////////// ///////////////////////////////////////
if (input_fdUL == NULL) { if (input_fdUL == NULL) {
eNB->proc.frame_rx = 1;
eNB->proc.frame_rx = 1; eNB->proc.subframe_rx = subframe;
eNB->proc.subframe_rx = subframe; ru->proc.frame_rx = 1;
ru->proc.frame_rx = 1; ru->proc.subframe_rx = subframe;
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->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx;
proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx);
proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe],
eNB->frame_parms.samples_per_tti);
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) { 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, 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); //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); tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev);
...@@ -1251,21 +1183,17 @@ int main(int argc, char **argv) ...@@ -1251,21 +1183,17 @@ int main(int argc, char **argv)
//Set target wideband RX noise level to N0 //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_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); sigma2 = pow(10,sigma2_dB/10);
// compute tx_gain to achieve target SNR (per resource element!) // 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); 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)); 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 // fill measurement symbol (19) with noise
for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) {
for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { 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] = (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+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
} }
} }
...@@ -1293,7 +1221,6 @@ int main(int argc, char **argv) ...@@ -1293,7 +1221,6 @@ int main(int argc, char **argv)
if (trials==0 && round==0) { if (trials==0 && round==0) {
// calculate freq domain representation to compute SINR // calculate freq domain representation to compute SINR
freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1); freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1);
// snr=pow(10.0,.1*SNR); // 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); 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) ...@@ -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); // 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; channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].x;
channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].y; 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); fprintf(csv_fdUL,"%e+i*(%e),",channelx,channely);
// } // }
// else{ // else{
...@@ -1322,39 +1249,42 @@ int main(int argc, char **argv) ...@@ -1322,39 +1249,42 @@ int main(int argc, char **argv)
for (i=0; i<eNB->frame_parms.samples_per_tti; i++) { for (i=0; i<eNB->frame_parms.samples_per_tti; i++) {
for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { 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] =
((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( (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
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) { if (n_frames<=10) {
printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) 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))); &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -
printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
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)], 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*) 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], &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); OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb);
if (n_frames<=10) { if (n_frames<=10) {
printf("SNRmeas %f\n",SNRmeas); 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);
} }
start_meas(&eNB->phy_proc_rx);
ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full;
eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
ru->feprx(ru);
phy_procedures_eNB_uespec_RX(eNB,proc_rxtx);
ru->feprx(ru); stop_meas(&eNB->phy_proc_rx);
phy_procedures_eNB_uespec_RX(eNB,proc_rxtx);
if (cqi_flag > 0) { if (cqi_flag > 0) {
cqi_error = 0; cqi_error = 0;
...@@ -1365,7 +1295,6 @@ int main(int argc, char **argv) ...@@ -1365,7 +1295,6 @@ int main(int argc, char **argv)
cqi_error = 1; cqi_error = 1;
} }
} else { } else {
} }
if (cqi_error == 1) { if (cqi_error == 1) {
...@@ -1383,15 +1312,10 @@ int main(int argc, char **argv) ...@@ -1383,15 +1312,10 @@ int main(int argc, char **argv)
ack_errors++; ack_errors++;
// printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]);
// if (ret <= eNB->ulsch[0]->max_turbo_iterations) {
iter_trials++;
if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) {
// 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 (n_frames==1) { 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); 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) ...@@ -1405,9 +1329,6 @@ int main(int argc, char **argv)
round=5; round=5;
} else { } else {
// avg_iter += ret-1;
iter_trials++;
errs[round]++; errs[round]++;
if (n_frames==1) { if (n_frames==1) {
...@@ -1420,7 +1341,6 @@ int main(int argc, char **argv) ...@@ -1420,7 +1341,6 @@ int main(int argc, char **argv)
Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus;
Kr_bytes = Kr>>3; Kr_bytes = Kr>>3;
printf("Decoded_output (Segment %d):\n",s); printf("Decoded_output (Segment %d):\n",s);
for (i=0; i<Kr_bytes; i++) for (i=0; i<Kr_bytes; i++)
...@@ -1429,154 +1349,80 @@ int main(int argc, char **argv) ...@@ -1429,154 +1349,80 @@ int main(int argc, char **argv)
} }
dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
if (round == 4) exit(-1); 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++; round++;
if (n_frames==1) { if (n_frames==1) {
printf("ULSCH in error in round %d\n",round); printf("ULSCH in error in round %d\n",round);
} }
} // ulsch error } // ulsch error
} // round } // round
// printf("\n"); // printf("\n");
if ((errs[0]>=100) && (trials>(n_frames/2))) if ((errs[0]>=100) && (trials>(n_frames/2)))
break; break;
if (xforms==1) if (xforms==1)
phy_scope_eNB(form_enb,eNB,0); 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 (t_rx < t_rx_min) double t_tx = inMicroS(UE->phy_proc_tx.p_time);
t_rx_min = t_rx; 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++; n_tx_dropped++;
if (t_rx > 2000) if (t_rx > 2000 )
n_rx_dropped++; n_rx_dropped++;
push_front(&time_vector_tx, t_tx); appendVarArray(table_tx, &t_tx);
push_front(&time_vector_tx_ifft, t_tx_ifft); appendVarArray(table_tx_ifft, &t_tx_ifft);
push_front(&time_vector_tx_mod, t_tx_mod); appendVarArray(table_tx_mod, &t_tx_mod );
push_front(&time_vector_tx_enc, t_tx_enc); appendVarArray(table_tx_enc, &t_tx_enc );
appendVarArray(table_rx, &t_rx );
push_front(&time_vector_rx, t_rx); appendVarArray(table_rx_fft, &t_rx_fft );
push_front(&time_vector_rx_fft, t_rx_fft); appendVarArray(table_rx_demod, &t_rx_demod );
push_front(&time_vector_rx_demod, t_rx_demod); appendVarArray(table_rx_dec, &t_rx_dec );
push_front(&time_vector_rx_dec, t_rx_dec);
} //trials } //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 // sort table
qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble);
qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); 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 ) { if (dump_table == 1 ) {
set_component_filelog(SIM); // file located in /tmp/usim.txt 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,dataArray(table_tx),table_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_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", 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, nb_rb,mcs,SNR,SNR2,
tx_lev_dB, tx_lev_dB,
20*log10(tx_gain), 20*log10(tx_gain),
(double)N0, (double)N0,
eNB->measurements.n0_power_tot_dB, 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[0]),
dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]),
eNB->measurements.n0_power_dB[0], eNB->measurements.n0_power_dB[0],
eNB->measurements.n0_power_dB[1]); 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])); 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", 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], errs[0],
round_trials[0], round_trials[0],
...@@ -1608,7 +1454,6 @@ int main(int argc, char **argv) ...@@ -1608,7 +1454,6 @@ int main(int argc, char **argv)
if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] > 0) 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]); 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", fprintf(bler_fd,"%f;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n",
SNR, SNR,
mcs, mcs,
...@@ -1623,112 +1468,53 @@ int main(int argc, char **argv) ...@@ -1623,112 +1468,53 @@ int main(int argc, char **argv)
round_trials[2], round_trials[2],
errs[3], errs[3],
round_trials[3]); round_trials[3]);
double timeBase=1/(1000*cpu_freq_GHz);
if (dump_perf==1) { if (dump_perf==1) {
printf("UE TX function statistics (per 1ms subframe)\n\n"); 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, printDistribution(&UE->phy_proc_tx,table_tx,"Total PHY proc tx");
2)/UE->phy_proc_tx.trials - pow((double)UE->phy_proc_tx.diff/UE->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); printDistribution(&UE->ofdm_mod_stats, table_tx_ifft, "OFDM_mod time");
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); printDistribution(&UE->ulsch_modulation_stats,table_tx_mod, "ULSCH modulation time");
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, printDistribution(&UE->ulsch_encoding_stats,table_tx_enc, "ULSCH encoding time");
n_tx_dropped); printStatIndent(&UE->ulsch_segmentation_stats,"ULSCH segmentation time");
std_phy_proc_tx_ifft = sqrt((double)UE->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, printStatIndent(&UE->ulsch_turbo_encoding_stats,"ULSCH turbo encoding time");
2)/UE->ofdm_mod_stats.trials - pow((double)UE->ofdm_mod_stats.diff/UE->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time");
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); printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving");
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); printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time");
std_phy_proc_tx_mod = sqrt((double)UE->ulsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, printDistribution(&eNB->phy_proc_rx,table_rx,"\nTotal PHY proc rx subframe");
2)/UE->ulsch_modulation_stats.trials - pow((double)UE->ulsch_modulation_stats.diff/UE->ulsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"OFDM_demod time");
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, printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"ULSCH demodulation time");
UE->ulsch_modulation_stats.trials); printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %.2f) :%.2f us (%d trials, max %.2f)\n",
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); UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)iter_trials,
std_phy_proc_tx_enc = sqrt((double)UE->ulsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials*timeBase,
2)/UE->ulsch_encoding_stats.trials - pow((double)UE->ulsch_encoding_stats.diff/UE->ulsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); eNB->ulsch_decoding_stats.trials,
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, (double)eNB->ulsch_decoding_stats.max*timeBase);
UE->ulsch_encoding_stats.trials); printf("|__ Statistics std: %.2fus median %.2fus q1 %.2fus q3 %.2fus \n",
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); squareRoot(&eNB->ulsch_decoding_stats),
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, median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));
UE->ulsch_segmentation_stats.trials); printStatIndent(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" );
printf("|__ ULSCH turbo encoding time :%f us (%d trials)\n", printStatIndent(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" );
((double)UE->ulsch_turbo_encoding_stats.trials/UE->ulsch_encoding_stats.trials)*(double) printStatIndent(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" );
UE->ulsch_turbo_encoding_stats.diff/UE->ulsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_turbo_encoding_stats.trials); printf("|__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n",
printf("|__ ULSCH rate-matching time :%f us (%d trials)\n", eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ?
((double)UE->ulsch_rate_matching_stats.trials/UE->ulsch_encoding_stats.trials)*(double) eNB->ulsch[0]->harq_processes[harq_pid]->Kminus :
UE->ulsch_rate_matching_stats.diff/UE->ulsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_rate_matching_stats.trials); eNB->ulsch[0]->harq_processes[harq_pid]->Kplus,
printf("|__ ULSCH sub-block interleaving time :%f us (%d trials)\n", eNB->ulsch_tc_intl1_stats.trials/(double)eNB->ulsch_tc_init_stats.trials,
((double)UE->ulsch_interleaving_stats.trials/UE->ulsch_encoding_stats.trials)*(double) (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials*timeBase,
UE->ulsch_interleaving_stats.diff/UE->ulsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_interleaving_stats.trials); (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials),
printf("|__ ULSCH multiplexing time :%f us (%d trials)\n", eNB->ulsch_turbo_decoding_stats.trials);
((double)UE->ulsch_multiplexing_stats.trials/UE->ulsch_encoding_stats.trials)*(double) printStatIndent2(&eNB->ulsch_tc_init_stats,"init", eNB->ulsch_tc_init_stats.trials);
UE->ulsch_multiplexing_stats.diff/UE->ulsch_multiplexing_stats.trials/cpu_freq_GHz/1000.0,UE->ulsch_multiplexing_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);
printf("\n\neNB RX function statistics (per 1ms subframe)\n\n"); printStatIndent2(&eNB->ulsch_tc_gamma_stats,"gamma", eNB->ulsch_tc_init_stats.trials);
std_phy_proc_rx = sqrt((double)eNB->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, printStatIndent2(&eNB->ulsch_tc_ext_stats,"ext", eNB->ulsch_tc_init_stats.trials);
2)/eNB->phy_proc_rx.trials - pow((double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); printStatIndent2(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver", eNB->ulsch_tc_init_stats.trials);
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); printStatIndent2(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC", eNB->ulsch_tc_init_stats.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);
} }
if(abstx) { //ABSTRACTION if(abstx) { //ABSTRACTION
blerr= (double)errs[1]/(round_trials[1]); blerr= (double)errs[1]/(round_trials[1]);
//printf("hata yok XX,"); //printf("hata yok XX,");
blerr = (double)errs[0]/(round_trials[0]); blerr = (double)errs[0]/(round_trials[0]);
if(saving_bler==0) if(saving_bler==0)
...@@ -1736,12 +1522,9 @@ int main(int argc, char **argv) ...@@ -1736,12 +1522,9 @@ int main(int argc, char **argv)
// printf("hata yok XX,"); // printf("hata yok XX,");
if(blerr<1) if(blerr<1)
saving_bler = 0; saving_bler = 0;
else saving_bler =1; else saving_bler =1;
} //ABStraction } //ABStraction
if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
...@@ -1759,7 +1542,6 @@ int main(int argc, char **argv) ...@@ -1759,7 +1542,6 @@ int main(int argc, char **argv)
round_trials[2], round_trials[2],
errs[3], errs[3],
round_trials[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,"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;", 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, SNR,
...@@ -1783,7 +1565,6 @@ int main(int argc, char **argv) ...@@ -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])/ (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, (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])); (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,"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;", fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d;",
UE->phy_proc_tx.trials, UE->phy_proc_tx.trials,
...@@ -1805,52 +1586,52 @@ int main(int argc, char **argv) ...@@ -1805,52 +1586,52 @@ int main(int argc, char **argv)
get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_demodulation_stats),
get_time_meas_us(&eNB->ulsch_decoding_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,"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,"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,"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,"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,"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,"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,"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,"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 ); printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
break; break;
} else if (test_perf !=0 ) { } else if (test_perf !=0 ) {
printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); 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) if (((double)errs[0]/(round_trials[0]))<1e-2)
break; 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_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); // 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 }//ch realization
oai_exit=1; oai_exit=1;
pthread_cond_signal(&ru->proc.cond_fep); pthread_cond_signal(&ru->proc.cond_fep);
...@@ -1865,7 +1646,6 @@ int main(int argc, char **argv) ...@@ -1865,7 +1646,6 @@ int main(int argc, char **argv)
fclose (time_meas_fd); fclose (time_meas_fd);
return(0); return(0);
} }
......
...@@ -146,7 +146,7 @@ typedef enum { ...@@ -146,7 +146,7 @@ typedef enum {
{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {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_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_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}, \ {CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \
} }
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include<linux/types.h> #include<linux/types.h>
#include<stdlib.h> #include<stdlib.h>
#include<sys/queue.h> #include<sys/queue.h>
#include <string.h>
#include "UTIL/MEM/mem_block.h" #include "UTIL/MEM/mem_block.h"
...@@ -103,4 +105,37 @@ void totable (double*, struct list*); ...@@ -103,4 +105,37 @@ void totable (double*, struct list*);
int compare (const void * a, const void * b); int compare (const void * a, const void * b);
int32_t calculate_median(struct list *loc_list); 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 #endif
...@@ -65,211 +65,191 @@ ...@@ -65,211 +65,191 @@
/*! \brief USRP Configuration */ /*! \brief USRP Configuration */
typedef struct { typedef struct {
// -------------------------------- // --------------------------------
// variables for USRP configuration // variables for USRP configuration
// -------------------------------- // --------------------------------
//! USRP device pointer //! USRP device pointer
uhd::usrp::multi_usrp::sptr usrp; uhd::usrp::multi_usrp::sptr usrp;
//create a send streamer and a receive streamer //create a send streamer and a receive streamer
//! USRP TX Stream //! USRP TX Stream
uhd::tx_streamer::sptr tx_stream; uhd::tx_streamer::sptr tx_stream;
//! USRP RX Stream //! USRP RX Stream
uhd::rx_streamer::sptr rx_stream; uhd::rx_streamer::sptr rx_stream;
//! USRP TX Metadata //! USRP TX Metadata
uhd::tx_metadata_t tx_md; uhd::tx_metadata_t tx_md;
//! USRP RX Metadata //! USRP RX Metadata
uhd::rx_metadata_t rx_md; uhd::rx_metadata_t rx_md;
//! Sampling rate //! Sampling rate
double sample_rate; double sample_rate;
//! TX forward samples. We use usrp_time_offset to get this value //! TX forward samples. We use usrp_time_offset to get this value
int tx_forward_nsamps; //166 for 20Mhz int tx_forward_nsamps; //166 for 20Mhz
// -------------------------------- // --------------------------------
// Debug and output control // Debug and output control
// -------------------------------- // --------------------------------
int num_underflows; int num_underflows;
int num_overflows; int num_overflows;
int num_seq_errors; int num_seq_errors;
int64_t tx_count; int64_t tx_count;
int64_t rx_count; int64_t rx_count;
int wait_for_first_pps; int wait_for_first_pps;
int use_gps; int use_gps;
//! timestamp of RX packet //! timestamp of RX packet
openair0_timestamp rx_timestamp; openair0_timestamp rx_timestamp;
} usrp_state_t; } usrp_state_t;
//void print_notes(void) //void print_notes(void)
//{ //{
// Helpful notes // Helpful notes
// std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n"); // 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("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("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("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
// std::cout << boost::format("****************************************************************************************************************\n"); // std::cout << boost::format("****************************************************************************************************************\n");
//} //}
static int sync_to_gps(openair0_device *device) static int sync_to_gps(openair0_device *device) {
{ uhd::set_thread_priority_safe();
uhd::set_thread_priority_safe(); //std::string args;
//Set up program options
//std::string args; //po::options_description desc("Allowed options");
//desc.add_options()
//Set up program options //("help", "help message")
//po::options_description desc("Allowed options"); //("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments")
//desc.add_options() //;
//("help", "help message") //po::variables_map vm;
//("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments") //po::store(po::parse_command_line(argc, argv, desc), vm);
//; //po::notify(vm);
//po::variables_map vm; //Print the help message
//po::store(po::parse_command_line(argc, argv, desc), vm); //if (vm.count("help"))
//po::notify(vm); //{
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
//Print the help message // return EXIT_FAILURE;
//if (vm.count("help")) //}
//{ //Create a USRP device
// std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl; //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
// return EXIT_FAILURE; //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;
//Create a USRP device
//std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args; try {
//uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); size_t num_mboards = s->usrp->get_num_mboards();
//std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string(); size_t num_gps_locked = 0;
usrp_state_t *s = (usrp_state_t*)device->priv; for (size_t mboard = 0; mboard < num_mboards; mboard++) {
std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl;
try //Set references to GPSDO
{ s->usrp->set_clock_source("gpsdo", mboard);
size_t num_mboards = s->usrp->get_num_mboards(); s->usrp->set_time_source("gpsdo", mboard);
size_t num_gps_locked = 0; //std::cout << std::endl;
for (size_t mboard = 0; mboard < num_mboards; mboard++) //print_notes();
{ //std::cout << std::endl;
std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl; //Check for 10 MHz lock
std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard);
//Set references to GPSDO
s->usrp->set_clock_source("gpsdo", mboard); if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) {
s->usrp->set_time_source("gpsdo", mboard); std::cout << "Waiting for reference lock..." << std::flush;
bool ref_locked = false;
//std::cout << std::endl;
//print_notes(); for (int i = 0; i < 30 and not ref_locked; i++) {
//std::cout << std::endl; ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool();
//Check for 10 MHz lock if (not ref_locked) {
std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard); std::cout << "." << std::flush;
if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) boost::this_thread::sleep(boost::posix_time::seconds(1));
{ }
std::cout << "Waiting for reference lock..." << std::flush; }
bool ref_locked = false;
for (int i = 0; i < 30 and not ref_locked; i++)
{
ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool();
if (not ref_locked)
{
std::cout << "." << std::flush;
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}
if(ref_locked)
{
std::cout << "LOCKED" << std::endl;
} else {
std::cout << "FAILED" << std::endl;
std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl;
exit(EXIT_FAILURE);
}
}
else
{
std::cout << boost::format("ref_locked sensor not present on this board.\n");
}
//Wait for GPS lock
bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool();
if(gps_locked)
{
num_gps_locked++;
std::cout << boost::format("GPS Locked\n");
}
else
{
std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl;
}
//Set to GPS time if(ref_locked) {
uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); std::cout << "LOCKED" << std::endl;
//s->usrp->set_time_next_pps(gps_time+1.0, mboard); } else {
s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); std::cout << "FAILED" << std::endl;
std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl;
//Wait for it to apply exit(EXIT_FAILURE);
//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;
} }
} else {
std::cout << boost::format("ref_locked sensor not present on this board.\n");
}
if (num_gps_locked == num_mboards and num_mboards > 1) //Wait for GPS lock
{ bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool();
//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 if(gps_locked) {
boost::this_thread::sleep(boost::posix_time::milliseconds(200)); num_gps_locked++;
std::cout << boost::format("GPS Locked\n");
//Compare times across all mboards } else {
bool all_matched = true; std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl;
uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0); }
for (size_t mboard = 1; mboard < num_mboards; mboard++)
{ //Set to GPS time
uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard); uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int()));
if (mboard_time != mboard0_time) //s->usrp->set_time_next_pps(gps_time+1.0, mboard);
{ s->usrp->set_time_next_pps(uhd::time_spec_t(0.0));
all_matched = false; //Wait for it to apply
std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f") //The wait is 2 seconds because N-Series has a known issue where
% mboard0_time.get_real_secs() //the time at the last PPS does not properly update at the PPS edge
% mboard //when the time is actually set.
% mboard_time.get_real_secs()) << std::endl; 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()));
if (all_matched) 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 << "SUCCESS: USRP times aligned" << std::endl << std::endl; std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl;
} else { //if (gps_time.get_real_secs() == time_last_pps.get_real_secs())
std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl; // 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)
{ if (num_gps_locked == num_mboards and num_mboards > 1) {
std::cout << boost::format("\nError: %s") % e.what(); //Check to see if all USRP times are aligned
std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n"); //First, wait for PPS.
std::cout << boost::format("Visit one of these pages if the problem persists:\n"); uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps();
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"); while (time_last_pps == s->usrp->get_time_last_pps()) {
std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n"); boost::this_thread::sleep(boost::posix_time::milliseconds(1));
exit(EXIT_FAILURE); }
//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) #if defined(USRP_REC_PLAY)
...@@ -315,24 +295,18 @@ char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; ...@@ -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 @param device pointer to the device structure specific to the RF hardware target
*/ */
static int trx_usrp_start(openair0_device *device) { static int trx_usrp_start(openair0_device *device) {
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode != 2) { // not replay mode
#endif
usrp_state_t *s = (usrp_state_t*)device->priv;
if (u_sf_mode != 2) { // not replay mode
// setup GPIO for TDD, GPIO(4) = ATR_RX #endif
//set data direction register (DDR) to output 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); 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); 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); s->usrp->set_gpio_attr("FP0", "ATR_RX", 1<<4, 0x1f);
// init recv and send streaming // init recv and send streaming
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); 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)); 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) { ...@@ -340,28 +314,26 @@ static int trx_usrp_start(openair0_device *device) {
if (s->use_gps == 1) { if (s->use_gps == 1) {
s->wait_for_first_pps = 1; s->wait_for_first_pps = 1;
cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0);
} } else {
else { s->wait_for_first_pps = 0;
s->wait_for_first_pps = 0;
cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05);
} }
cmd.stream_now = false; // start at constant delay cmd.stream_now = false; // start at constant delay
s->rx_stream->issue_stream_cmd(cmd); 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.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.has_time_spec = true;
s->tx_md.start_of_burst = true; s->tx_md.start_of_burst = true;
s->tx_md.end_of_burst = false; s->tx_md.end_of_burst = false;
s->rx_count = 0; s->rx_count = 0;
s->tx_count = 0; s->tx_count = 0;
s->rx_timestamp = 0; s->rx_timestamp = 0;
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
} }
#endif
return 0; #endif
return 0;
} }
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources /*! \brief Terminate operation of the USRP transceiver -- free all associated resources
* \param device the hardware to use * \param device the hardware to use
...@@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) { ...@@ -369,12 +341,14 @@ static int trx_usrp_start(openair0_device *device) {
static void trx_usrp_end(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... #if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
static int done = 0; static int done = 0;
if (done == 1) return; if (done == 1) return;
done = 1; 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); s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
//send a mini EOB packet //send a mini EOB packet
s->tx_md.end_of_burst = true; s->tx_md.end_of_burst = true;
...@@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) { ...@@ -382,55 +356,67 @@ static void trx_usrp_end(openair0_device *device) {
s->tx_md.end_of_burst = false; s->tx_md.end_of_burst = false;
sleep(1); sleep(1);
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
} }
#endif #endif
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode == 1) { // subframes store
pFile = fopen (u_sf_filename,"wb+"); if (u_sf_mode == 1) { // subframes store
if (pFile == NULL) { pFile = fopen (u_sf_filename,"wb+");
std::cerr << "Cannot open " << u_sf_filename << std::endl;
} else { if (pFile == NULL) {
unsigned int i = 0; std::cerr << "Cannot open " << u_sf_filename << std::endl;
unsigned int modu = 0; } else {
if ((modu = nb_samples % 10) != 0) { unsigned int i = 0;
nb_samples -= modu; // store entire number of frames unsigned int modu = 0;
}
std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; if ((modu = nb_samples % 10) != 0) {
for (i = 0; i < nb_samples; i++) { nb_samples -= modu; // store entire number of frames
fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile);
}
fclose (pFile);
std::cerr << "File " << u_sf_filename << " closed." << std::endl;
} }
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) { if (ms_sample != NULL) {
free((void*)ms_sample); free(ms_sample);
ms_sample = NULL; ms_sample = NULL;
} }
}
if (u_sf_mode == 2) { // replay if (iqfd != 0) {
if (use_mmap) { close(iqfd);
if (ms_sample != MAP_FAILED) { iqfd = 0;
munmap(ms_sample, sb.st_size);
ms_sample = NULL;
}
if (mmapfd != 0) {
close(mmapfd);
mmapfd = 0;
}
} else {
if (ms_sample != NULL) {
free(ms_sample);
ms_sample = NULL;
}
if (iqfd != 0) {
close(iqfd);
iqfd = 0;
}
} }
} }
#endif }
#endif
} }
/*! \brief Called to send samples to the USRP RF target /*! \brief Called to send samples to the USRP RF target
...@@ -444,78 +430,80 @@ static void trx_usrp_end(openair0_device *device) { ...@@ -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) { static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
int ret=0; int ret=0;
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode != 2) { // not replay mode if (u_sf_mode != 2) { // not replay mode
#endif #endif
usrp_state_t *s = (usrp_state_t*)device->priv; usrp_state_t *s = (usrp_state_t *)device->priv;
int nsamps2; // aligned to upper 32 or 16 byte boundary
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__) #if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__ #ifdef __AVX2__
nsamps2 = (nsamps+7)>>3; nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[2][nsamps2]; __m256i buff_tx[2][nsamps2];
#else #else
nsamps2 = (nsamps+3)>>2; nsamps2 = (nsamps+3)>>2;
__m128i buff_tx[2][nsamps2]; __m128i buff_tx[2][nsamps2];
#endif #endif
#elif defined(__arm__) #elif defined(__arm__)
nsamps2 = (nsamps+3)>>2; nsamps2 = (nsamps+3)>>2;
int16x8_t buff_tx[2][nsamps2]; int16x8_t buff_tx[2][nsamps2];
#endif #endif
// bring RX data into 12 LSBs for softmodem RX // bring RX data into 12 LSBs for softmodem RX
for (int i=0; i<cc; i++) { for (int i=0; i<cc; i++) {
for (int j=0; j<nsamps2; j++) { for (int j=0; j<nsamps2; j++) {
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__ #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 #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 #endif
#elif defined(__arm__) #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 #endif
}
} }
}
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
s->tx_md.has_time_spec = flags; s->tx_md.has_time_spec = flags;
if(flags>0)
if(flags>0) s->tx_md.has_time_spec = true;
s->tx_md.has_time_spec = true; else
else s->tx_md.has_time_spec = false;
s->tx_md.has_time_spec = false;
if (flags == 2) { // start of burst
if (flags == 2) { // start of burst s->tx_md.start_of_burst = true;
s->tx_md.start_of_burst = true; s->tx_md.end_of_burst = false;
s->tx_md.end_of_burst = false; } else if (flags == 3) { // end of burst
} else if (flags == 3) { // end of burst s->tx_md.start_of_burst = false;
s->tx_md.start_of_burst = false; s->tx_md.end_of_burst = true;
s->tx_md.end_of_burst = true; } else if (flags == 4) { // start and end
} else if (flags == 4) { // start and end s->tx_md.start_of_burst = true;
s->tx_md.start_of_burst = true; s->tx_md.end_of_burst = true;
s->tx_md.end_of_burst = true; } else if (flags==1) { // middle of burst
} else if (flags==1) { // middle of burst s->tx_md.start_of_burst = false;
s->tx_md.start_of_burst = false; s->tx_md.end_of_burst = false;
s->tx_md.end_of_burst = false; }
}
if(flags==10){ // fail safe mode if(flags==10) { // fail safe mode
s->tx_md.has_time_spec = false; s->tx_md.has_time_spec = false;
s->tx_md.start_of_burst = false; s->tx_md.start_of_burst = false;
s->tx_md.end_of_burst = true; s->tx_md.end_of_burst = true;
} }
if (cc>1) {
std::vector<void *> buff_ptrs; if (cc>1) {
for (int i=0; i<cc; i++) std::vector<void *> buff_ptrs;
buff_ptrs.push_back(buff_tx[i]);
ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); for (int i=0; i<cc; i++)
} else buff_ptrs.push_back(buff_tx[i]);
ret = (int)s->tx_stream->send(buff_tx[0], nsamps, s->tx_md,1e-3);
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 (ret != nsamps)
LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps);
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
} else { } else {
struct timespec req; struct timespec req;
...@@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, ...@@ -524,8 +512,8 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
nanosleep(&req, NULL); nanosleep(&req, NULL);
ret = nsamps; ret = nsamps;
} }
#endif
#endif
return ret; return ret;
} }
...@@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, ...@@ -541,12 +529,13 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
* \returns the number of sample read * \returns the number of sample read
*/ */
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { 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 samples_received=0,i,j;
int nsamps2; // aligned to upper 32 or 16 byte boundary int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode != 2) { // not replay mode if (u_sf_mode != 2) { // not replay mode
#endif #endif
#if defined(__x86_64) || defined(__i386__) #if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__ #ifdef __AVX2__
nsamps2 = (nsamps+7)>>3; nsamps2 = (nsamps+7)>>3;
...@@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -561,66 +550,79 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
#endif #endif
if (device->type == USRP_B200_DEV) { if (device->type == USRP_B200_DEV) {
if (cc>1) { if (cc>1) {
// receive multiple channels (e.g. RF A and RF B) // receive multiple channels (e.g. RF A and RF B)
std::vector<void *> buff_ptrs; 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); for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]);
} else {
// receive a single channel (e.g. from connector RF A) samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md);
samples_received=0; } else {
while (samples_received != nsamps) { // receive a single channel (e.g. from connector RF A)
samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, samples_received=0;
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)) while (samples_received != nsamps) {
break; samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received,
if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { printf("sleep...\n");} //usleep(100); nsamps-samples_received, s->rx_md);
}
if (samples_received == nsamps) s->wait_for_first_pps=0; 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++) { if (samples_received == nsamps) s->wait_for_first_pps=0;
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__) #if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__ #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 #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 #endif
#elif defined(__arm__) #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 #endif
}
} }
}
} else if (device->type == USRP_X300_DEV) { } else if (device->type == USRP_X300_DEV) {
if (cc>1) { if (cc>1) {
// receive multiple channels (e.g. RF A and RF B) // receive multiple channels (e.g. RF A and RF B)
std::vector<void *> buff_ptrs; std::vector<void *> buff_ptrs;
for (int i=0; i<cc; i++) buff_ptrs.push_back(buff[i]); 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 { samples_received = s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md);
// receive a single channel (e.g. from connector RF A) } else {
samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); // 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) 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) 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_count += nsamps;
s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
*ptimestamp = s->rx_timestamp; *ptimestamp = s->rx_timestamp;
#if defined (USRP_REC_PLAY) #if defined (USRP_REC_PLAY)
} }
#endif
#endif
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode == 1) { // record mode if (u_sf_mode == 1) { // record mode
// Copy subframes to memory (later dump on a file) // Copy subframes to memory (later dump on a file)
if (nb_samples < u_sf_max) { 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; (ms_sample+nb_samples)->ts = *ptimestamp;
memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4);
nb_samples++; nb_samples++;
...@@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -629,62 +631,78 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
if (cur_samples == nb_samples) { if (cur_samples == nb_samples) {
cur_samples = 0; cur_samples = 0;
wrap_count++; wrap_count++;
if (wrap_count == u_sf_loops) { if (wrap_count == u_sf_loops) {
std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl;
return 0; // should make calling process exit return 0; // should make calling process exit
} }
wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000));
if (!use_mmap) { if (!use_mmap) {
if (lseek(iqfd, 0, SEEK_SET) == 0) { if (lseek(iqfd, 0, SEEK_SET) == 0) {
std::cerr << "Seeking at the beginning of IQ file" << std::endl; std::cerr << "Seeking at the beginning of IQ file" << std::endl;
} else { } else {
std::cerr << "Problem seeking at the beginning of IQ file" << std::endl; std::cerr << "Problem seeking at the beginning of IQ file" << std::endl;
} }
} }
} }
if (use_mmap) { if (use_mmap) {
if (cur_samples < nb_samples) { if (cur_samples < nb_samples) {
*ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; *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 if (cur_samples == 0) {
<< " ts=" << *ptimestamp << std::endl; 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++;
memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4);
cur_samples++;
} }
} else { } else {
// read sample from file // read sample from file
if (read(iqfd, ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { 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; std::cerr << "pb reading iqfile at index " << sizeof(iqrec_t)*cur_samples << std::endl;
close(iqfd); close(iqfd);
free(ms_sample); free(ms_sample);
ms_sample = NULL; ms_sample = NULL;
iqfd = 0; iqfd = 0;
exit(-1); exit(-1);
} }
if (cur_samples < nb_samples) { if (cur_samples < nb_samples) {
static int64_t ts0 = 0; static int64_t ts0 = 0;
if ((cur_samples == 0) && (wrap_count == 0)) {
ts0 = ms_sample->ts; 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 *ptimestamp = ts0 + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)) + wrap_ts;
<< " ts=" << *ptimestamp << std::endl;
} if (cur_samples == 0) {
memcpy(buff[0], &ms_sample->samples[0], nsamps*4); std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts
cur_samples++; << " ts=" << *ptimestamp << std::endl;
// Prepare for next read }
off_t where = lseek(iqfd, cur_samples * sizeof(iqrec_t), SEEK_SET);
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; struct timespec req;
req.tv_sec = 0; req.tv_sec = 0;
req.tv_nsec = u_sf_read_delay * 1000; req.tv_nsec = u_sf_read_delay * 1000;
nanosleep(&req, NULL); nanosleep(&req, NULL);
return nsamps; return nsamps;
} }
#endif #endif
return samples_received; return samples_received;
} }
...@@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -694,16 +712,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
* \param b second variable * \param b second variable
*/ */
static bool is_equal(double a, double b) { 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) { void *freq_thread(void *arg) {
openair0_device *device=(openair0_device *)arg;
openair0_device *device=(openair0_device *)arg; usrp_state_t *s = (usrp_state_t *)device->priv;
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]);
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 /*! \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 * \param device the hardware to use
...@@ -711,23 +727,20 @@ void *freq_thread(void *arg) { ...@@ -711,23 +727,20 @@ void *freq_thread(void *arg) {
* \param dummy dummy variable not used * \param dummy dummy variable not used
* \returns 0 in success * \returns 0 in success
*/ */
int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { int trx_usrp_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) {
usrp_state_t *s = (usrp_state_t *)device->priv;
usrp_state_t *s = (usrp_state_t*)device->priv; pthread_t f_thread;
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]);
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)
// spawn a thread to handle the frequency change to not block the calling thread pthread_create(&f_thread,NULL,freq_thread,(void *)device);
if (dont_block == 1) else {
pthread_create(&f_thread,NULL,freq_thread,(void*)device); s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]);
else { s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]);
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);
return(0);
} }
/*! \brief Set RX frequencies /*! \brief Set RX frequencies
...@@ -735,21 +748,16 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, ...@@ -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 * \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success * \returns 0 in success
*/ */
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg) {
usrp_state_t *s = (usrp_state_t *)device->priv;
usrp_state_t *s = (usrp_state_t*)device->priv; static int first_call=1;
static int first_call=1; static double rf_freq,diff;
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;
uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0];
rf_freq=openair0_cfg[0].rx_freq[0];
rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; s->usrp->set_rx_freq(rx_tune_req);
rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; return(0);
rf_freq=openair0_cfg[0].rx_freq[0];
s->usrp->set_rx_freq(rx_tune_req);
return(0);
} }
/*! \brief Set Gains (TX/RX) /*! \brief Set Gains (TX/RX)
...@@ -757,62 +765,62 @@ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *open ...@@ -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 * \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success * \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) { 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; s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]);
::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n",
s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0],
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); openair0_cfg[0].rx_gain[0],gain_range.stop());
// limit to maximum gain return(0);
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);
} }
/*! \brief Stop USRP /*! \brief Stop USRP
* \param card refers to the hardware index to use * \param card refers to the hardware index to use
*/ */
int trx_usrp_stop(openair0_device* device) { int trx_usrp_stop(openair0_device *device) {
return(0); return(0);
} }
/*! \brief USRPB210 RX calibration table */ /*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t calib_table_b210[] = { rx_gain_calib_table_t calib_table_b210[] = {
{3500000000.0,44.0}, {3500000000.0,44.0},
{2660000000.0,49.0}, {2660000000.0,49.0},
{2300000000.0,50.0}, {2300000000.0,50.0},
{1880000000.0,53.0}, {1880000000.0,53.0},
{816000000.0,58.0}, {816000000.0,58.0},
{-1,0} {-1,0}
}; };
/*! \brief USRPB210 RX calibration table */ /*! \brief USRPB210 RX calibration table */
rx_gain_calib_table_t calib_table_b210_38[] = { rx_gain_calib_table_t calib_table_b210_38[] = {
{3500000000.0,44.0}, {3500000000.0,44.0},
{2660000000.0,49.8}, {2660000000.0,49.8},
{2300000000.0,51.0}, {2300000000.0,51.0},
{1880000000.0,53.0}, {1880000000.0,53.0},
{816000000.0,57.0}, {816000000.0,57.0},
{-1,0} {-1,0}
}; };
/*! \brief USRPx310 RX calibration table */ /*! \brief USRPx310 RX calibration table */
rx_gain_calib_table_t calib_table_x310[] = { rx_gain_calib_table_t calib_table_x310[] = {
{3500000000.0,77.0}, {3500000000.0,77.0},
{2660000000.0,81.0}, {2660000000.0,81.0},
{2300000000.0,81.0}, {2300000000.0,81.0},
{1880000000.0,82.0}, {1880000000.0,82.0},
{816000000.0,85.0}, {816000000.0,85.0},
{-1,0} {-1,0}
}; };
/*! \brief Set RX gain offset /*! \brief Set RX gain offset
...@@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = { ...@@ -821,72 +829,81 @@ rx_gain_calib_table_t calib_table_x310[] = {
* \returns 0 in success * \returns 0 in success
*/ */
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { 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; if (bw_gain_adjust==1) {
// loop through calibration table to find best adjustment factor for RX frequency switch ((int)openair0_cfg[0].sample_rate) {
double min_diff = 6e9,diff,gain_adj=0.0; case 30720000:
if (bw_gain_adjust==1) { break;
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000: case 23040000:
break; gain_adj=1.25;
case 23040000: break;
gain_adj=1.25;
break; case 15360000:
case 15360000: gain_adj=3.0;
gain_adj=3.0; break;
break;
case 7680000: case 7680000:
gain_adj=6.0; gain_adj=6.0;
break; break;
case 3840000:
gain_adj=9.0; case 3840000:
break; gain_adj=9.0;
case 1920000: break;
gain_adj=12.0;
break; case 1920000:
default: gain_adj=12.0;
LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); break;
exit(-1);
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", while (openair0_cfg->rx_gain_calib_table[i].freq>0) {
i, diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq);
openair0_cfg->rx_gain_calib_table[i].freq, LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n",
openair0_cfg->rx_gain_calib_table[i].offset,diff); i,
if (min_diff > diff) { openair0_cfg->rx_gain_calib_table[i].freq,
min_diff = diff; openair0_cfg->rx_gain_calib_table[i].offset,diff);
openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj;
} if (min_diff > diff) {
i++; 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 /*! \brief print the USRP statistics
* \param device the hardware to use * \param device the hardware to use
* \returns 0 on success * \returns 0 on success
*/ */
int trx_usrp_get_stats(openair0_device* device) { int trx_usrp_get_stats(openair0_device *device) {
return(0); return(0);
} }
/*! \brief Reset the USRP statistics /*! \brief Reset the USRP statistics
* \param device the hardware to use * \param device the hardware to use
* \returns 0 on success * \returns 0 on success
*/ */
int trx_usrp_reset_stats(openair0_device* device) { int trx_usrp_reset_stats(openair0_device *device) {
return(0); return(0);
} }
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
extern "C" { extern "C" {
/*! \brief Initializer for USRP record/playback config /*! \brief Initializer for USRP record/playback config
* \param parameter array description * \param parameter array description
* \returns 0 on success * \returns 0 on success
*/ */
int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
// --subframes-file // --subframes-file
memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_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; usrp_recplay_params[0].helpstr = config_hlp_sf_file;
...@@ -943,9 +960,8 @@ int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { ...@@ -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].defuintval=DEF_SF_DELAY_WRITE;
usrp_recplay_params[6].type=TYPE_UINT; usrp_recplay_params[6].type=TYPE_UINT;
usrp_recplay_params[6].numelt=0; usrp_recplay_params[6].numelt=0;
return 0; // always ok return 0; // always ok
} }
} }
#endif #endif
...@@ -954,478 +970,473 @@ extern "C" { ...@@ -954,478 +970,473 @@ extern "C" {
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application * \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].sdr_addrs == '%s'\n", openair0_cfg[0].sdr_addrs);
LOG_D(PHY, "openair0_cfg[0].clock_source == '%d'\n", openair0_cfg[0].clock_source); 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) #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) { if (u_sf_mode == 1) {
(void) strcpy(u_sf_filename, DEF_SF_FILE); 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 #endif
uhd::set_thread_priority_safe(1.0); sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers);
usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n",
uhd::get_version_string().c_str(),vers,subvers,subsubvers);
if (openair0_cfg[0].clock_source==gpsdo)
s->use_gps =1; std::string args;
if (openair0_cfg[0].sdr_addrs == NULL) {
// Initialize USRP device args = "type=b200";
device->openair0_cfg = openair0_cfg; } else {
args = openair0_cfg[0].sdr_addrs;
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);
}
}
} }
uhd::device_addrs_t device_adds = uhd::device::find(args); uhd::device_addrs_t device_adds = uhd::device::find(args);
int vers=0,subvers=0,subsubvers=0; if (device_adds.size() == 0) {
int bw_gain_adjust=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) std::cerr << "Found USRP " << device_adds[0].get("type") << "\n";
if (u_sf_mode == 1) { double usrp_master_clock;
std::cerr << "USRP device initialized in subframes record mode" << std::endl;
} if (device_adds[0].get("type") == "b200") {
#endif printf("Found USRP b200\n");
sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); device->type = USRP_B200_DEV;
LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", usrp_master_clock = 30.72e6;
uhd::get_version_string().c_str(),vers,subvers,subsubvers); 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.size() == 0) { }
double usrp_master_clock = 184.32e6; if (device_adds[0].get("type") == "n3xx") {
std::string args = "type=x300"; printf("Found USRP n300\n");
device->type=USRP_X300_DEV; //treat it as X300 for now
if (addr_args) { usrp_master_clock = 122.88e6;
args += addr_args; 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 += 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"; s->usrp = uhd::usrp::multi_usrp::make(args);
uhd::device_addrs_t device_adds = uhd::device::find(args);
if(device_adds.size() == 0) { // lock mboard clocks
args += ",addr=192.168.30.2"; 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) { switch ((int)openair0_cfg[0].sample_rate) {
case 122880000:
std::cerr<<"No USRP Device Found. " << std::endl; // from usrp_time_offset
free(s); //openair0_cfg[0].samples_per_packet = 2048;
return -1; openair0_cfg[0].tx_sample_advance = 15; //to be checked
} openair0_cfg[0].tx_bw = 80e6;
} openair0_cfg[0].rx_bw = 80e6;
LOG_I(PHY,"Found USRP X300\n"); break;
s->usrp = uhd::usrp::multi_usrp::make(args);
// lock mboard clocks case 61440000:
if (openair0_cfg[0].clock_source == internal) // from usrp_time_offset
s->usrp->set_clock_source("internal"); //openair0_cfg[0].samples_per_packet = 2048;
else openair0_cfg[0].tx_sample_advance = 15;
s->usrp->set_clock_source("external"); 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 case 15360000:
device->type=USRP_X300_DEV; //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 case 7680000:
// set master clock rate and sample rate for tx & rx for streaming //openair0_cfg[0].samples_per_packet = 2048;
//s->usrp->set_master_clock_rate(usrp_master_clock); 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) #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 #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 30720000:
switch ((int)openair0_cfg[0].sample_rate) { s->usrp->set_master_clock_rate(30.72e6);
case 122880000: //openair0_cfg[0].samples_per_packet = 1024;
// from usrp_time_offset openair0_cfg[0].tx_sample_advance = 115;
//openair0_cfg[0].samples_per_packet = 2048; openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].tx_sample_advance = 15; //to be checked openair0_cfg[0].rx_bw = 20e6;
openair0_cfg[0].tx_bw = 80e6; break;
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;
}
} else { case 23040000:
LOG_I(PHY,"Found USRP B200\n"); s->usrp->set_master_clock_rate(23.04e6); //to be checked
args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; //openair0_cfg[0].samples_per_packet = 1024;
s->usrp = uhd::usrp::multi_usrp::make(args); 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); case 15360000:
// s->usrp->set_tx_subdev_spec(tx_subdev); 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 case 7680000:
// // lock mboard clocks s->usrp->set_master_clock_rate(30.72e6);
// s->usrp->set_clock_source("internal"); //openair0_cfg[0].samples_per_packet = 1024;
// set master clock rate and sample rate for tx & rx for streaming openair0_cfg[0].tx_sample_advance = 80;
openair0_cfg[0].tx_bw = 20e6;
openair0_cfg[0].rx_bw = 20e6;
break;
// lock mboard clocks case 1920000:
if (openair0_cfg[0].clock_source == internal){ s->usrp->set_master_clock_rate(30.72e6);
s->usrp->set_clock_source("internal"); //openair0_cfg[0].samples_per_packet = 1024;
} openair0_cfg[0].tx_sample_advance = 40;
else{ openair0_cfg[0].tx_bw = 20e6;
s->usrp->set_clock_source("external"); openair0_cfg[0].rx_bw = 20e6;
s->usrp->set_time_source("external"); break;
}
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
}
switch ((int)openair0_cfg[0].sample_rate) { default:
case 30720000: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
s->usrp->set_master_clock_rate(30.72e6); exit(-1);
//openair0_cfg[0].samples_per_packet = 1024; break;
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;
}
} }
}
/* device specific */ /* device specific */
//openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered //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].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_txshift = 4;//shift
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
for(int i=0; i<s->usrp->get_rx_num_channels(); i++) { for(int i=0; i<s->usrp->get_rx_num_channels(); i++) {
if (i<openair0_cfg[0].rx_num_channels) { if (i<openair0_cfg[0].rx_num_channels) {
s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i); s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i);
s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i);
set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust);
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i);
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); // limit to maximum gain
// limit to maximum gain AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(),
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",
"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());
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);
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,
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], openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop());
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, "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); 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++) { 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); ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i);
if (i<openair0_cfg[0].tx_num_channels) { if (i<openair0_cfg[0].tx_num_channels) {
s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i); 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_freq(openair0_cfg[0].tx_freq[i],i);
s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[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_clock_source("external");
//s->usrp->set_time_source("external"); //s->usrp->set_time_source("external");
// display USRP settings
// display USRP settings LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6);
LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); sleep(1);
sleep(1); // create tx & rx streamer
uhd::stream_args_t stream_args_rx("sc16", "sc16");
// create tx & rx streamer int samples=openair0_cfg[0].sample_rate;
uhd::stream_args_t stream_args_rx("sc16", "sc16"); int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps();
int samples=openair0_cfg[0].sample_rate; samples/=10000;
int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples);
samples/=10000;
LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); if ( samples < max )
if ( samples < max ) stream_args_rx.args["spp"] = str(boost::format("%d") % samples );
stream_args_rx.args["spp"] = str(boost::format("%d") % samples );
LOG_I(PHY,"rx_max_num_samps %zu\n", LOG_I(PHY,"rx_max_num_samps %zu\n",
s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps());
for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++)
stream_args_rx.channels.push_back(i); stream_args_rx.channels.push_back(i);
s->rx_stream = s->usrp->get_rx_stream(stream_args_rx);
s->rx_stream = s->usrp->get_rx_stream(stream_args_rx);
uhd::stream_args_t stream_args_tx("sc16", "sc16"); 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); for (int i = 0; i<openair0_cfg[0].tx_num_channels; i++)
s->tx_stream = s->usrp->get_tx_stream(stream_args_tx); stream_args_tx.channels.push_back(i);
/* Setting TX/RX BW after streamers are created due to USRP calibration issue */ s->tx_stream = s->usrp->get_tx_stream(stream_args_tx);
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); /* 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++)
for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++) s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i);
s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++)
for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) { s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,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); for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) {
LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); LOG_I(PHY,"RX Channel %d\n",i);
LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); LOG_I(PHY," Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6);
LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9);
LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); 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++) { for (int i=0; i<openair0_cfg[0].tx_num_channels; i++) {
LOG_I(PHY,"TX Channel %d\n",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 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 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 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 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," 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()); LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs());
device->priv = s;
device->priv = s; device->trx_start_func = trx_usrp_start;
device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write;
device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read;
device->trx_read_func = trx_usrp_read; device->trx_get_stats_func = trx_usrp_get_stats;
device->trx_get_stats_func = trx_usrp_get_stats; device->trx_reset_stats_func = trx_usrp_reset_stats;
device->trx_reset_stats_func = trx_usrp_reset_stats; device->trx_end_func = trx_usrp_end;
device->trx_end_func = trx_usrp_end; device->trx_stop_func = trx_usrp_stop;
device->trx_stop_func = trx_usrp_stop; device->trx_set_freq_func = trx_usrp_set_freq;
device->trx_set_freq_func = trx_usrp_set_freq; device->trx_set_gains_func = trx_usrp_set_gains;
device->trx_set_gains_func = trx_usrp_set_gains; device->openair0_cfg = openair0_cfg;
device->openair0_cfg = openair0_cfg; s->sample_rate = openair0_cfg[0].sample_rate;
s->sample_rate = openair0_cfg[0].sample_rate; // TODO:
// TODO: // init tx_forward_nsamps based usrp_time_offset ex
// init tx_forward_nsamps based usrp_time_offset ex if(is_equal(s->sample_rate, (double)30.72e6))
if(is_equal(s->sample_rate, (double)30.72e6)) s->tx_forward_nsamps = 176;
s->tx_forward_nsamps = 176;
if(is_equal(s->sample_rate, (double)15.36e6)) if(is_equal(s->sample_rate, (double)15.36e6))
s->tx_forward_nsamps = 90; s->tx_forward_nsamps = 90;
if(is_equal(s->sample_rate, (double)7.68e6))
s->tx_forward_nsamps = 50; if(is_equal(s->sample_rate, (double)7.68e6))
s->tx_forward_nsamps = 50;
if (s->use_gps == 1) {
if (sync_to_gps(device)) { if (s->use_gps == 1) {
LOG_I(PHY,"USRP fails to sync with GPS...\n"); if (sync_to_gps(device)) {
exit(0); LOG_I(PHY,"USRP fails to sync with GPS...\n");
} exit(0);
} }
#if defined(USRP_REC_PLAY)
} }
#if defined(USRP_REC_PLAY)
}
#endif #endif
#if defined(USRP_REC_PLAY) #if defined(USRP_REC_PLAY)
if (u_sf_mode == 1) { // record mode
ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t)); if (u_sf_mode == 1) { // record mode
if (ms_sample == NULL) { ms_sample = (iqrec_t *) malloc(u_sf_max * sizeof(iqrec_t));
std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
exit(-1); if (ms_sample == NULL) {
} std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); exit(-1);
} }
if (u_sf_mode == 2) {
if (use_mmap) { memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF);
// use mmap }
mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE);
if (mmapfd != 0) { if (u_sf_mode == 2) {
fstat(mmapfd, &sb); if (use_mmap) {
std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; // use mmap
ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE);
if (ms_sample != MAP_FAILED) {
nb_samples = (sb.st_size / sizeof(iqrec_t)); if (mmapfd != 0) {
int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; fstat(mmapfd, &sb);
std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl;
if (aligned == 0) { ms_sample = (iqrec_t *) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0);
std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl;
close(mmapfd); if (ms_sample != MAP_FAILED) {
exit(-1); nb_samples = (sb.st_size / sizeof(iqrec_t));
} int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0;
} else { std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl;
std::cerr << "Cannot mmap file, exiting." << std::endl;
close(mmapfd); if (aligned == 0) {
exit(-1); std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl;
} close(mmapfd);
} else { exit(-1);
std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; }
exit(-1); } else {
} std::cerr << "Cannot mmap file, exiting." << std::endl;
} else { close(mmapfd);
iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); exit(-1);
if (iqfd != 0) { }
fstat(iqfd, &sb); } else {
nb_samples = (sb.st_size / sizeof(iqrec_t)); std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl;
std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename exit(-1);
<< " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; }
// allocate buffer for 1 sample at a time } else {
ms_sample = (iqrec_t*) malloc(sizeof(iqrec_t)); iqfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE);
if (ms_sample == NULL) {
std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl; if (iqfd != 0) {
close(iqfd); fstat(iqfd, &sb);
exit(-1); nb_samples = (sb.st_size / sizeof(iqrec_t));
} std::cerr << "Loading " << nb_samples << " subframes from " << u_sf_filename
memset(ms_sample, 0, sizeof(iqrec_t)); << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl;
// point at beginning of file // allocate buffer for 1 sample at a time
if (lseek(iqfd, 0, SEEK_SET) == 0) { ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t));
std::cerr << "Initial seek at beginning of the file" << std::endl;
} else { if (ms_sample == NULL) {
std::cerr << "Problem initial seek at beginning of the file" << std::endl; std::cerr<< "Memory allocation failed for individual subframe replay mode." << std::endl;
} close(iqfd);
} else { exit(-1);
std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; }
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;
}
} }
/*@}*/ /*@}*/
...@@ -111,8 +111,6 @@ extern volatile int start_UE; ...@@ -111,8 +111,6 @@ extern volatile int start_UE;
#endif #endif
extern volatile int oai_exit; extern volatile int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern int transmission_mode; extern int transmission_mode;
extern int oaisim_flag; extern int oaisim_flag;
...@@ -260,7 +258,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam ...@@ -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,"%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 ", 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),
TICK_TO_US(eNB->phy_proc_tx), TICK_TO_US(eNB->phy_proc_tx),
TICK_TO_US(eNB->phy_proc_rx), TICK_TO_US(eNB->phy_proc_rx),
......
...@@ -171,8 +171,6 @@ double rx_gain_off = 0.0; ...@@ -171,8 +171,6 @@ double rx_gain_off = 0.0;
double sample_rate=30.72e6; double sample_rate=30.72e6;
double bw = 10.0e6; double bw = 10.0e6;
static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/;
char rf_config_file[1024]; char rf_config_file[1024];
int chain_offset=0; int chain_offset=0;
...@@ -199,7 +197,6 @@ int otg_enabled; ...@@ -199,7 +197,6 @@ int otg_enabled;
//int number_of_cards = 1; //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_dl_mcs = 28; //maximum allowed mcs
uint32_t target_ul_mcs = 20; uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0; uint32_t timing_advance = 0;
...@@ -250,8 +247,6 @@ WORKER_CONF_t get_thread_worker_conf(void) ...@@ -250,8 +247,6 @@ WORKER_CONF_t get_thread_worker_conf(void)
/* struct for ethernet specific parameters given in eNB conf file */ /* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params; eth_params_t *eth_params;
openair0_config_t openair0_cfg[MAX_CARDS];
double cpuf; double cpuf;
extern char uecap_xer[1024]; extern char uecap_xer[1024];
...@@ -632,112 +627,6 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { ...@@ -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) { void wait_RUs(void) {
LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); 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 ) ...@@ -922,9 +811,6 @@ int main( int argc, char **argv )
mode = normal_txrx; 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(); set_latency_target();
...@@ -1283,8 +1169,6 @@ int main( int argc, char **argv ) ...@@ -1283,8 +1169,6 @@ int main( int argc, char **argv )
pthread_mutex_destroy(&ue_pf_po_mutex); pthread_mutex_destroy(&ue_pf_po_mutex);
// *** Handle per CC_id openair0
for(ru_id=0; ru_id<RC.nb_RU; ru_id++) { for(ru_id=0; ru_id<RC.nb_RU; ru_id++) {
if (RC.ru[ru_id]->rfdevice.trx_end_func) { if (RC.ru[ru_id]->rfdevice.trx_end_func) {
......
...@@ -98,6 +98,9 @@ ...@@ -98,6 +98,9 @@
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #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 /* 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 */ when calling config_get or config_getlist functions */
...@@ -147,7 +150,9 @@ ...@@ -147,7 +150,9 @@
{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ {"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}, \ {"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}, \ {"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 #define DEFAULT_DLF 2680000000
......
...@@ -223,6 +223,9 @@ int numerology = 0; ...@@ -223,6 +223,9 @@ int numerology = 0;
char *parallel_config = NULL; char *parallel_config = NULL;
char *worker_config = NULL; char *worker_config = NULL;
char* usrp_args=NULL;
char* usrp_clksrc=NULL;
static THREAD_STRUCT thread_struct; static THREAD_STRUCT thread_struct;
void set_parallel_conf(char *parallel_conf) void set_parallel_conf(char *parallel_conf)
{ {
...@@ -739,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { ...@@ -739,6 +742,26 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) {
openair0_cfg[card].tx_freq[i], openair0_cfg[card].tx_freq[i],
openair0_cfg[card].rx_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");
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment