From 69e90fa6cbb2bbc31ac10a375bd016f2b57d0734 Mon Sep 17 00:00:00 2001
From: Wang Tsu-Han <wangts@eurecom.fr>
Date: Fri, 17 Nov 2017 11:11:24 +0100
Subject: [PATCH] Creating Emulated FH

---
 openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 19 ++++++++++--
 openair1/PHY/LTE_TRANSPORT/proto.h        |  2 ++
 openair1/PHY/TOOLS/time_meas.c            |  2 +-
 openair1/PHY/defs.h                       |  6 ++--
 openair1/SCHED/phy_procedures_lte_eNb.c   |  4 ++-
 targets/RT/USER/lte-enb.c                 |  2 --
 targets/RT/USER/lte-ru.c                  | 36 +++++++++++++++++++----
 7 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index bf0675c7f3..d7e106c2f4 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -52,7 +52,11 @@
   ((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
 */
 #define is_not_pilot(pilots,first_pilot,re) (1)
-
+/*extern void thread_top_init(char *thread_name,
+		     int affinity,
+		     uint64_t runtime,
+		     uint64_t deadline,
+		     uint64_t period);*/
 
 void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
 {
@@ -452,6 +456,7 @@ void *te_thread(void *param) {
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   
+  //thread_top_init("te_thread",1,870000,1000000,1000000);
   pthread_setname_np( pthread_self(),"te processing");
   LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid));
   
@@ -482,6 +487,7 @@ void *te_thread1(void *param) {
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   
+  //thread_top_init("te_thread1",1,870000,1000000,1000000);
   pthread_setname_np( pthread_self(),"te processing 1");
   LOG_I(PHY,"thread te 1 created id=%ld\n", syscall(__NR_gettid));
   
@@ -517,6 +523,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
 			    uint8_t subframe,
 			    time_stats_t *rm_stats,
 			    time_stats_t *te_stats,
+				time_stats_t *te_wait_stats,
 			    time_stats_t *i_stats)
 {
 
@@ -714,9 +721,14 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
   }
 
   // wait for worker to finish
-
+  start_meas(te_wait_stats);
   wait_on_busy_condition(&proc->mutex_te[0],&proc->cond_te[0],&proc->instance_cnt_te[0],"te thread");
   wait_on_busy_condition(&proc->mutex_te[1],&proc->cond_te[1],&proc->instance_cnt_te[1],"te thread1");
+  stop_meas(te_wait_stats);
+  if(opp_enabled == 1 && te_wait_stats->diff_now>50*3000){
+    print_meas_now(te_wait_stats,"coding_wait",stderr);
+	printf("frame_rx: %d  subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx);
+  }
 
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
@@ -731,6 +743,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    uint8_t subframe,
                    time_stats_t *rm_stats,
                    time_stats_t *te_stats,
+				   time_stats_t *te_wait_stats,
                    time_stats_t *i_stats)
 {
 	int encoding_return = 0;
@@ -763,8 +776,8 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    subframe,
                    rm_stats,
                    te_stats,
+				   te_wait_stats,
                    i_stats);
-		//printf("having more then 5 segmentation\n");///////////*******
 		}
 	else
 		{
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 169490d03d..6da6653492 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -130,6 +130,7 @@ int32_t dlsch_encoding_all(PHY_VARS_eNB *eNB,
                        uint8_t subframe,
                        time_stats_t *rm_stats,
                        time_stats_t *te_stats,
+					   time_stats_t *te_wait_stats,
                        time_stats_t *i_stats);
 
 int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue,
@@ -175,6 +176,7 @@ int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
                                 uint8_t subframe,
                                 time_stats_t *rm_stats,
                                 time_stats_t *te_stats,
+								time_stats_t *te_wait_stats,
                                 time_stats_t *i_stats);
 
 void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c
index 31a613d032..857696a48f 100644
--- a/openair1/PHY/TOOLS/time_meas.c
+++ b/openair1/PHY/TOOLS/time_meas.c
@@ -53,7 +53,7 @@ void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){
     if (ts->trials>0) {
 
       //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->diff_now/(cpu_freq_GHz*1000000.0)),subframe,ts->diff_now);
-      fprintf(file_name,"%15.3f ms, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000000.0)),(double)ts->diff_now);
+      fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->diff_now/(cpu_freq_GHz*1000.0)),(double)ts->diff_now);
       
     }
   }
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index aa714c88cb..81a4953b15 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -666,7 +666,8 @@ typedef enum {
   REMOTE_MBP_IF5  =2,
   REMOTE_IF4p5    =3,
   REMOTE_IF1pp    =4,
-  MAX_RU_IF_TYPES =5
+  MAX_RU_IF_TYPES =5,
+  EMULATE_RF      =6
 } RU_if_south_t;
 
 typedef struct RU_t_s{
@@ -946,7 +947,7 @@ typedef struct PHY_VARS_eNB_s {
   eth_params_t         eth_params;
   int                  rx_total_gain_dB;
   int                  (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag);
-  int                  (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *);
+  int                  (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *);
   int                  (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
   uint8_t              local_flag;
   LTE_DL_FRAME_PARMS   frame_parms;
@@ -1125,6 +1126,7 @@ typedef struct PHY_VARS_eNB_s {
   time_stats_t dlsch_scrambling_stats;
   time_stats_t dlsch_rate_matching_stats;
   time_stats_t dlsch_turbo_encoding_stats;
+  time_stats_t dlsch_turbo_encoding_waiting_stats;
   time_stats_t dlsch_interleaving_stats;
 
   time_stats_t rx_dft_stats;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 63bf430d7c..c3268cdccd 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -341,9 +341,11 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
 	  dlsch_harq->pdu,
 	  dlsch_harq->pdsch_start,
 	  dlsch,
-	  frame,subframe,
+	  frame,
+	  subframe,
 	  &eNB->dlsch_rate_matching_stats,
 	  &eNB->dlsch_turbo_encoding_stats,
+	  &eNB->dlsch_turbo_encoding_waiting_stats,
 	  &eNB->dlsch_interleaving_stats);
   stop_meas(&eNB->dlsch_encoding_stats);
   // 36-211
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 6b91157e9c..ff489dbd8b 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -381,8 +381,6 @@ int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
   proc_rxtx->frame_rx    = ru_proc->frame_rx;
   proc_rxtx->subframe_tx = (ru_proc->subframe_rx+4)%10;
   proc_rxtx->frame_tx    = (ru_proc->subframe_rx>5) ? (1+ru_proc->frame_rx)&1023 : ru_proc->frame_rx;
-  proc->frame_tx         = proc_rxtx->frame_tx;
-  proc->frame_rx         = proc_rxtx->frame_rx;
   proc_rxtx->timestamp_tx = ru_proc->timestamp_tx;
   
   // the thread can now be woken up
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index a106012815..8c139ae22f 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -110,6 +110,10 @@ unsigned short config_frames[4] = {2,9,11,13};
 
 #include "T.h"
 
+#ifndef EMULATE_RF
+#define EMULATE_RF
+#endif
+
 extern volatile int                    oai_exit;
 extern int numerology;
 extern int fh_two_thread;
@@ -694,12 +698,20 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
 
   old_ts = proc->timestamp_rx;
-
+  #ifdef EMULATE_RF
+  int microsec = 450; // length of time to sleep, in miliseconds
+  struct timespec req = {0};
+  req.tv_sec = 0;
+  req.tv_nsec = microsec * 1000L;
+  nanosleep(&req, (struct timespec *)NULL);
+  rxs = fp->samples_per_tti;
+  #else
   rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
 				   &ts,
 				   rxp,
 				   fp->samples_per_tti,
 				   ru->nb_rx);
+  #endif
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
  
@@ -714,7 +726,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   }
   else {
     if (proc->timestamp_rx - old_ts != fp->samples_per_tti) {
-      LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
+      //LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset);
       ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti);
       proc->timestamp_rx = ts-ru->ts_offset;
     }
@@ -1396,7 +1408,8 @@ static void* ru_thread_tx( void* param ) {
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
 	//printf("//////////////////instance_cnt_eNBs = %d\n",proc->instance_cnt_eNBs);//////////////////*********
   	    
-  	    
+  	#ifdef EMULATE_RF
+    #else    
     // do TX front-end processing if needed (precoding and/or IDFTs)
     if (ru->feptx_prec) ru->feptx_prec(ru);
   	    
@@ -1406,6 +1419,7 @@ static void* ru_thread_tx( void* param ) {
     if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
   	    
     if (ru->fh_north_out) ru->fh_north_out(ru);
+	#endif
 
     release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
   }
@@ -1439,7 +1453,15 @@ static void* ru_thread( void* param ) {
 
   LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]);
 
-
+  #ifdef EMULATE_RF
+  fill_rf_config(ru,ru->rf_config_file);
+  init_frame_parms(&ru->frame_parms,1);
+  phy_init_RU(ru);
+  if (setup_RU_buffers(ru)!=0) {
+        printf("Exiting, cannot initialize RU Buffers\n");
+        exit(-1);
+  }
+  #else
   // Start IF device if any
   if (ru->start_if) {
     LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
@@ -1460,6 +1482,7 @@ static void* ru_thread( void* param ) {
         printf("Exiting, cannot initialize RU Buffers\n");
         exit(-1);
   }
+  #endif
 
   LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
   pthread_mutex_lock(&RC.ru_mutex);
@@ -1471,7 +1494,8 @@ static void* ru_thread( void* param ) {
   
 
 
-
+  #ifdef EMULATE_RF
+  #else
   // Start RF device if any
   if (ru->start_rf) {
     if (ru->start_rf(ru) != 0)
@@ -1480,7 +1504,6 @@ static void* ru_thread( void* param ) {
   }
   else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
 
-
   // if an asnych_rxtx thread exists
   // wakeup the thread because the devices are ready at this point
  
@@ -1499,6 +1522,7 @@ static void* ru_thread( void* param ) {
   proc->instance_cnt_FH1=0;
   pthread_mutex_unlock(&proc->mutex_FH1);
   pthread_cond_signal(&proc->cond_FH1);
+  #endif
 
 
   // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
-- 
GitLab