diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index d5e595aaf025c12c6d0bd9829bee364ddfab9a49..97f94ea9c86b7d6005eeb3b928c344656070de17 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -264,6 +264,8 @@ typedef struct {
   pthread_mutex_t mutex_rxtx;
   /// scheduling parameters for RXn-TXnp4 thread
   struct sched_param sched_param_rxtx;
+  /// pipeline ready state
+  int pipe_ready;
 } eNB_rxtx_proc_t;
 
 typedef struct {
@@ -452,6 +454,8 @@ typedef struct RU_proc_t_s {
   int                  num_slaves;
   /// array of pointers to slaves
   struct RU_proc_t_s           **slave_proc;
+  /// pipeline ready state
+  int ru_rx_ready;
 } RU_proc_t;
 
 /// Context data structure for eNB subframe processing
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index 6cd02db114a230e46f041d9375f4f5046560d1c8..b2abcf8cb2eb3e53bf28ccd39fd662ac54c1b9ef 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -196,7 +196,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
   int               UE_id = 0;
   uint8_t           aggregation    = 2;
   rnti_t            rnti           = 0x1235;
-  uint8_t           mcs            = 20;
+  uint8_t           mcs            = 0;
   uint8_t           harq_pid       = 0;
   uint32_t          cqi_req = 0,cshift,ndi,tpc = 1;
   int32_t           normalized_rx_power;
diff --git a/targets/RT/USER/eNB_usrp.gtkw b/targets/RT/USER/eNB_usrp.gtkw
index 2209e35851a4d346c66fe671d7633ad01c2cf506..e50c1831b69ba1e7e49ab33f79f0df523cb15ec0 100644
--- a/targets/RT/USER/eNB_usrp.gtkw
+++ b/targets/RT/USER/eNB_usrp.gtkw
@@ -1,17 +1,17 @@
 [*]
 [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
-[*] Fri Nov  3 16:03:52 2017
+[*] Thu Feb 22 14:46:40 2018
 [*]
 [dumpfile] "/tmp/openair_dump_eNB.vcd"
-[dumpfile_mtime] "Fri Nov  3 16:00:30 2017"
-[dumpfile_size] 56765827
+[dumpfile_mtime] "Thu Feb 22 14:44:26 2018"
+[dumpfile_size] 3482761
 [savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/eNB_usrp.gtkw"
-[timestart] 15220241000
+[timestart] 4525000000
 [size] 1920 1018
 [pos] 0 22
-*-19.666586 15221741584 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+*-21.506693 4530514310 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 [sst_width] 386
-[signals_width] 302
+[signals_width] 344
 [sst_expanded] 1
 [sst_vpaned_height] 303
 @28
@@ -34,11 +34,15 @@ functions.macxface_ue_scheduler
 functions.phy_eNB_ofdm_mod_l
 @24
 variables.frame_number_RX0_eNB[63:0]
-variables.frame_number_TX0_eNB[63:0]
 @25
-variables.frame_number_RX1_eNB[63:0]
+variables.subframe_number_RX0_eNB[63:0]
 @24
+variables.frame_number_TX0_eNB[63:0]
+variables.subframe_number_TX0_eNB[63:0]
+variables.frame_number_RX1_eNB[63:0]
+variables.subframe_number_RX1_eNB[63:0]
 variables.frame_number_TX1_eNB[63:0]
+variables.subframe_number_TX1_eNB[63:0]
 @28
 functions.phy_eNB_dlsch_modulation
 functions.phy_eNB_dlsch_encoding
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 0a1a7487feb5db8975eb4799f0a9629456c87796..beb715119fba5565abde49509e16f6a5ee16859b 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -146,7 +146,7 @@ void init_eNB(int,int);
 void stop_eNB(int nb_inst);
 
 int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc);
-int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc);
+int wakeup_txfh(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc);
 void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #ifdef Rel14
 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
@@ -183,7 +183,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
-  
+  proc->pipe_ready = 1;
   if(get_nprocs() >= 8)
   {
     wakeup_tx(eNB,eNB->proc.ru_proc);
@@ -193,13 +193,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
     if(oai_exit) return(-1);
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
     
-    wakeup_txfh(proc,eNB->proc.ru_proc);
+    wakeup_txfh(eNB,eNB->proc.ru_proc);
   }
   else
   {
     if(oai_exit) return(-1);
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
   }
+  proc->pipe_ready = 0;
 
   stop_meas( &softmodem_stats_rxtx_sf );
   
@@ -236,7 +237,9 @@ static void* tx_thread(void* param) {
     phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
 	if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
 	
-    wakeup_txfh(proc,eNB_proc->ru_proc);
+    proc->pipe_ready = 1;
+    wakeup_txfh(eNB,eNB_proc->ru_proc);
+    proc->pipe_ready = 0;
   }
 
   return 0;
@@ -358,15 +361,24 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t
   }
 }
 
-int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) {
+int wakeup_txfh(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
   
   struct timespec wait;
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
+  eNB_proc_t *proc=&eNB->proc;
+  eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
+  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
   
+  int ru_rx_ready = ru_proc->ru_rx_ready;
+  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
+  int pipe_ready_tx  = proc_rxtx1->pipe_ready;
   
+  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
+    usleep(10);
+  }
   if (ru_proc->instance_cnt_eNBs == 0) {
-    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping\n",proc->frame_rx,proc->subframe_rx);
+    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
     return(-1);
   }
   if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
@@ -376,9 +388,9 @@ int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) {
   }
 
     ++ru_proc->instance_cnt_eNBs;
-    ru_proc->timestamp_tx = proc->timestamp_tx;
-    ru_proc->subframe_tx  = proc->subframe_tx;
-    ru_proc->frame_tx     = proc->frame_tx;
+    ru_proc->timestamp_tx = proc_rxtx1->timestamp_tx;
+    ru_proc->subframe_tx  = proc_rxtx1->subframe_tx;
+    ru_proc->frame_tx     = proc_rxtx1->frame_tx;
   
   // the thread can now be woken up
   if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
@@ -405,6 +417,13 @@ int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
   
+  int ru_rx_ready = ru_proc->ru_rx_ready;
+  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
+  int pipe_ready_tx  = proc_rxtx1->pipe_ready;
+  
+  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
+    usleep(10);
+  }
   if (proc_rxtx1->instance_cnt_rxtx == 0) {
     LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx);
     return(-1);
@@ -442,8 +461,8 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   eNB_proc_t *proc=&eNB->proc;
   RU_proc_t *ru_proc=&ru->proc;
 
-  eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[0];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
-  //proc->ru_proc = &ru->proc;
+  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
+  eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
   
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
@@ -474,26 +493,32 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
 
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
-
-  /* accept some delay in processing - up to 50us */
-  if (proc_rxtx->instance_cnt_rxtx == 0) {
-    usleep(50);
+  int ru_rx_ready = ru_proc->ru_rx_ready;
+  int pipe_ready_rx  = proc_rxtx0->pipe_ready;
+  int pipe_ready_tx  = proc_rxtx1->pipe_ready;
+  
+  while(!ru_rx_ready && !pipe_ready_rx && !pipe_ready_tx){
+    usleep(10);
   }
-  if (proc_rxtx->instance_cnt_rxtx == 0) {
-    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx->frame_rx,proc_rxtx->subframe_rx);
+  /* accept some delay in processing - up to 50us */
+  //if (proc_rxtx0->instance_cnt_rxtx == 0) {
+  //  usleep(50);
+  //}
+  if (proc_rxtx0->instance_cnt_rxtx == 0) {
+    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
     return(-1);
   }
 
   // wake up TX for subframe n+4
   // lock the TX mutex and make sure the thread is ready
-  if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
-    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
+  if (pthread_mutex_timedlock(&proc_rxtx0->mutex_rxtx,&wait) != 0) {
+    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx0->subframe_rx&1,proc_rxtx0->instance_cnt_rxtx );
     exit_fun( "error locking mutex_rxtx" );
     return(-1);
   }
   
 
-  ++proc_rxtx->instance_cnt_rxtx;
+  ++proc_rxtx0->instance_cnt_rxtx;
   
   // We have just received and processed the common part of a subframe, say n. 
   // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
@@ -508,22 +533,22 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + 4)%10;
   */
   
-  proc_rxtx->subframe_rx = ru_proc->subframe_rx;
-  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_rx+(4*fp->samples_per_tti);
+  proc_rxtx0->subframe_rx = ru_proc->subframe_rx;
+  proc_rxtx0->frame_rx    = ru_proc->frame_rx;
+  proc_rxtx0->subframe_tx = (ru_proc->subframe_rx+4)%10;
+  proc_rxtx0->frame_tx    = (ru_proc->subframe_rx>5) ? (1+ru_proc->frame_rx)&1023 : ru_proc->frame_rx;
+  proc->frame_tx         = proc_rxtx0->frame_tx;
+  proc->frame_rx         = proc_rxtx0->frame_rx;
+  proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx+(4*fp->samples_per_tti);
   
   // the thread can now be woken up
-  if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
+  if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) {
     LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
     exit_fun( "ERROR pthread_cond_signal" );
     return(-1);
   }
   
-  pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
+  pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx );
 
   return(0);
 }
@@ -785,6 +810,8 @@ void init_eNB_proc(int inst) {
     proc_rxtx                      = proc->proc_rxtx;
     proc_rxtx[0].instance_cnt_rxtx = -1;
     proc_rxtx[1].instance_cnt_rxtx = -1;
+    proc_rxtx[0].pipe_ready        = 1;
+    proc_rxtx[1].pipe_ready        = 1;
     proc->instance_cnt_prach       = -1;
     proc->instance_cnt_asynch_rxtx = -1;
     proc->instance_cnt_synch       = -1;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 6b3fa67b13084ed3dd705850aeb6c854dd7712b8..640f15ef7f1ba5a34db1f3bfc1d3465331dbca86 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1596,7 +1596,9 @@ static void* ru_thread( void* param ) {
 
     LOG_D(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx);
     // wakeup all eNB processes waiting for this RU
+    proc->ru_rx_ready = 1;
     if (ru->num_eNB>0) wakeup_eNBs(ru);
+    proc->ru_rx_ready = 0;
 
     
 	if(get_nprocs() <=4)
@@ -1752,6 +1754,7 @@ void init_RU_proc(RU_t *ru) {
   proc->frame_offset             = 0;
   proc->num_slaves               = 0;
   proc->frame_tx_unwrap          = 0;
+  proc->ru_rx_ready              = 1;
 
   for (i=0;i<10;i++) proc->symbol_mask[i]=0;