diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index e7416922146235fc93ff273077b65dec8e673df6..78c058ad007229b775a8558b3eb22c7f4ef00432 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -69,12 +69,12 @@ char uecap_xer_in;
 
 extern void init_eNB_afterRU(void);
 extern void init_UE_stub(int nb_inst,int,int);
-extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu);
-extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present);
-extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc,  nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu);
-extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu);
+extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu);
+extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present);
+extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc,  nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu);
+extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
+extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
+extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu);
 
 extern uint8_t  nfapi_mode;
 
@@ -741,7 +741,7 @@ int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t*
   //phy_info* phy = (phy_info*)(pnf_p7->user_data);
 
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
+  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
 
   for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) {
 
@@ -798,7 +798,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
   int sf = NFAPI_SFNSF2SF(req->sfn_sf);
 
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
+  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
   nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
   LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1];
 
@@ -869,7 +869,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
 
         //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
 
-        handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.proc_rxtx[0], &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
+        handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.L1_proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu);
 
       } else {
 
@@ -945,7 +945,7 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request
   uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf);
 
   struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];
+  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;
   nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list;
 
   for (int i=0;i<req->ul_config_request_body.number_of_pdus;i++) {
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index bd9ce8dc1c1abc3b875f43fd264f6bd48d42f8fc..a8e5d665f6640f4daa03c2224b5b4cc121f3e000 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -341,9 +341,9 @@ int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_
 
 int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
 
-  eNB_proc_t *proc=&eNB->proc;
+  L1_proc_t *proc=&eNB->proc;
 
-  eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[sf&1];
+  L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx;
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
 
@@ -357,8 +357,8 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
 
   // wake up TX for subframe n+sf_ahead
   // 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(&L1_proc->mutex,&wait) != 0) {
+    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
     exit_fun( "error locking mutex_rxtx" );
     return(-1);
   }
@@ -377,9 +377,9 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
     if (old_sf == 0 && old_sfn % 100==0) LOG_W( PHY,"[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx);
   }
 
-  ++proc_rxtx->instance_cnt_rxtx;
+  ++L1_proc->instance_cnt;
 
-  //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] proc_rxtx->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx);
+  //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->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
@@ -387,23 +387,23 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) {
   // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
   // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
   // and proc->subframe_tx = proc->subframe_rx+sf_ahead
-  proc_rxtx->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
-  proc_rxtx->frame_rx     = proc->frame_rx;
-  proc_rxtx->subframe_rx  = proc->subframe_rx;
-  proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
-  proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + sf_ahead)%10;
+  L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
+  L1_proc->frame_rx     = proc->frame_rx;
+  L1_proc->subframe_rx  = proc->subframe_rx;
+  L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+  L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
 
-  //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] proc_rxtx[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx, proc_rxtx->frame_rx, proc_rxtx->subframe_rx);
+  //LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] L1_proc[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx, L1_proc->frame_rx, L1_proc->subframe_rx);
 
   // the thread can now be woken up
-  if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
+  if (pthread_cond_signal(&L1_proc->cond) != 0) {
     LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
     exit_fun( "ERROR pthread_cond_signal" );
     return(-1);
   }
 
   //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
-  pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
+  pthread_mutex_unlock( &L1_proc->mutex );
   //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
 
   return(0);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
index 4512fc0d9be15bf9d52efaf1f68248725fc0d8ba..9cdc2f4bf7bbc49b219972ec8e58a4c0100f918f 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
+++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h
@@ -203,7 +203,7 @@ void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue,
                       unsigned char eNB_id);
 
 int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
-			      eNB_rxtx_proc_t *proc,
+			      L1_rxtx_proc_t *proc,
                               module_id_t UE_id,
                               uint8_t l,
                               uint8_t Ns);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index a8d73cfdea4efd724d8c54a0e0923380e8a16379..206ba8b15f93626d9d3624d401efed8247a38180 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -35,7 +35,7 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32
 #define SCALE 0x3FFF
 
 int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
-				  eNB_rxtx_proc_t *proc,
+				  L1_rxtx_proc_t *proc,
                                   module_id_t UE_id,
                                   unsigned char l,
                                   unsigned char Ns) {
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index c33d9efe63b35dba960f5c9412fac2e607bd2d4e..f003b7f36a416ac4d50ba12b85437971c6959e13 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -90,7 +90,7 @@ int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
 
 
 
-void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu)
+void fill_pdcch_order(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu)
 {
   LTE_DL_FRAME_PARMS                *fp      = &eNB->frame_parms;
   uint8_t                           *dci_pdu = &dci_alloc->dci_pdu[0];
@@ -224,7 +224,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a
         proc->frame_tx, proc->subframe_tx, rel8->rnti);
 }
 
-void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu)
+void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu)
 {
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
@@ -1497,7 +1497,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
 
 }
 
-void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) {
+void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) {
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
 
@@ -1770,7 +1770,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
 
 }
 
-void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
     DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu)
 {
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 30c106b16bdabfff7d1671588a94c24eb6519e38..6ca2fdc42973b3c21c6aa45a34b1df026cd4972d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -393,7 +393,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
   //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats);
 
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
   unsigned int G;
   unsigned int crc=1;
 
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index cc466ce3e2a026632963cfb07bf9704a35dd2db6..dd82699fe9018df7645b73bd0305bf779d097046 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -705,7 +705,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
 
 
 void generate_phich_top(PHY_VARS_eNB *eNB,
-                        eNB_rxtx_proc_t *proc,
+                        L1_rxtx_proc_t *proc,
 			int16_t amp)
 {
 
diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
index fddc29b5242f4d005851fedf1b95b6d639619d24..475102b57c908cb66ee401139fe29e04998683c3 100644
--- a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
+++ b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c
@@ -34,7 +34,7 @@
 #include "PHY/LTE_REFSIG/lte_refsig.h"
 
 int generate_mbsfn_pilot(PHY_VARS_eNB *eNB,
-			 eNB_rxtx_proc_t *proc,
+			 L1_rxtx_proc_t *proc,
                          int32_t **txdataF,
                          int16_t amp)
 
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index 23bc07f17448806c4c2a8563f47bf86f647fc024..6fab3dc59bd8e229708d7fe9dd3e32c3f249a6c5 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -83,7 +83,7 @@ void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx)
 }
 
 
-void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a)
+void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
 {
 
   int G;
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
index f3c55b85e6447ea6708a4d6b3ee3970fb25c9ad3..4b475478b6a67e3d6c114e2c58c44102be9f281e 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
@@ -273,7 +273,7 @@ int mch_modulation(int32_t **txdataF,
     @param abstraction_flag
 
 */
-void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a);
+void generate_mch(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t *a);
 
 /** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals)
     @param phy_vars_eNB Pointer to eNB variables
@@ -317,7 +317,7 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB,
                              int first_pilot_only);
 
 int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
-                             eNB_rxtx_proc_t *proc,
+                             L1_rxtx_proc_t *proc,
                              int32_t **txdataF,
                              int16_t amp);
 
@@ -410,13 +410,13 @@ void ulsch_extract_rbs_single(int32_t **rxdataF,
 void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
                         int frame,
                         int subframe,
-			eNB_rxtx_proc_t *proc,
+			L1_rxtx_proc_t *proc,
 			DCI_ALLOC_t *dci_alloc,
 			nfapi_dl_config_dci_dl_pdu *pdu);
 
-void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu);
+void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu);
 
-void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
+void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
 	      nfapi_hi_dci0_dci_pdu *pdu);
 
 void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe);
@@ -427,7 +427,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB,
                                        unsigned char subframe);
 
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
-                                       eNB_rxtx_proc_t *proc,
+                                       L1_rxtx_proc_t *proc,
                                        void *dci_pdu,
                                        rnti_t rnti,
                                        DCI_format_t dci_format,
@@ -466,7 +466,7 @@ void init_transport_channels(uint8_t);
 
 
 void rx_ulsch(PHY_VARS_eNB *eNB,
-              eNB_rxtx_proc_t *proc,
+              L1_rxtx_proc_t *proc,
               uint8_t UE_id);
 
 
@@ -487,7 +487,7 @@ int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,
   @returns 0 on success
 */
 unsigned int  ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
-                             eNB_rxtx_proc_t *proc,
+                             L1_rxtx_proc_t *proc,
                              uint8_t UE_id,
                              uint8_t control_only_flag,
                              uint8_t Nbundled,
@@ -520,7 +520,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,
                         int llr8_flag);
 
 void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
-			eNB_rxtx_proc_t *proc,
+			L1_rxtx_proc_t *proc,
                         int16_t amp);
 
 
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 50b9ef17acb6a0b2b8e06c0fe1cdf4a120f3a1cc..7c6fc9bdcf60d3bfd9997e0d485366c5a4b1161a 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -382,7 +382,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
 extern int oai_exit;
 void *td_thread(void *param) {
   PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
-  eNB_proc_t *proc  = &eNB->proc;
+  L1_proc_t *proc  = &eNB->proc;
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   
@@ -412,7 +412,7 @@ void *td_thread(void *param) {
 
 int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
   unsigned int r,r_offset=0,Kr,Kr_bytes;
   uint8_t crc_type;
   int offset = 0;
@@ -762,7 +762,7 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2,
 
 }
   
-unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
                              uint8_t UE_id,
                              uint8_t control_only_flag,
                              uint8_t Nbundled,
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index 61076f2aae48fdfd6af03fafcda9d5c9b0bfdb06..f4137697cf621c664fe720fcb6db0bfd74493d33 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -1104,7 +1104,7 @@ void init_ulsch_power_LUT(void) {
 }
 
 void rx_ulsch(PHY_VARS_eNB *eNB,
-	      eNB_rxtx_proc_t *proc,
+	      L1_rxtx_proc_t *proc,
               uint8_t UE_id) {
 
 
@@ -1305,7 +1305,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
 }
 
 void rx_ulsch_emul(PHY_VARS_eNB *eNB,
-		   eNB_rxtx_proc_t *proc,
+		   L1_rxtx_proc_t *proc,
                    uint8_t UE_index)
 {
   LOG_I(PHY,"[PHY] EMUL eNB %d rx_ulsch_emul : subframe %d, UE_index %d\n",eNB->Mod_id,proc->subframe_rx,UE_index);
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
index 76176d346e8773cf105f05c00198e6bd4af4093c..c31bc587a7b73a4fcc4d617101d9b2a14929073c 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c
@@ -4222,7 +4222,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
 /*
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
-                                       eNB_rxtx_proc_t *proc,
+                                       L1_rxtx_proc_t *proc,
                                        void *dci_pdu,
                                        uint16_t rnti,
                                        DCI_format_t dci_format,
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index 9f2ec54744941e783e0cb27cabeb19b93c95e4d5..000eb4861585adf34756dbbec7c8b32fc60e668c 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -178,7 +178,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
   float time[FRAME_LENGTH_COMPLEX_SAMPLES];
   float time2[2048];
   float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
-  int frame = phy_vars_enb->proc.proc_rxtx[0].frame_tx;
+  int frame = phy_vars_enb->proc.L1_proc.frame_tx;
   uint32_t total_dlsch_bitrate = phy_vars_enb->total_dlsch_bitrate;
   int coded_bits_per_codeword = 0;
   uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index bb147a3963375266c1a04832d0cd014bf8625fd0..4de830507504591dcf11cdad49d1ffde86272286 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -257,9 +257,6 @@ typedef struct RU_proc_t_s {
   pthread_mutex_t mutex_pre_scd;
   int instance_pre_scd;
 #endif
-  /// pipeline ready state
-  int ru_rx_ready;
-  int ru_tx_ready;
   int emulate_rf_busy;
 } RU_proc_t;
 
@@ -648,20 +645,25 @@ typedef struct {
   int frame_rx;
   /// \brief Instance count for RXn-TXnp4 processing thread.
   /// \internal This variable is protected by \ref mutex_rxtx.
-  int instance_cnt_rxtx;
+  int instance_cnt;
   /// pthread structure for RXn-TXnp4 processing thread
-  pthread_t pthread_rxtx;
+  pthread_t pthread;
   /// pthread attributes for RXn-TXnp4 processing thread
-  pthread_attr_t attr_rxtx;
+  pthread_attr_t attr;
   /// condition variable for tx processing thread
-  pthread_cond_t cond_rxtx;
+  pthread_cond_t cond;
   /// mutex for RXn-TXnp4 processing thread
-  pthread_mutex_t mutex_rxtx;
+  pthread_mutex_t mutex;
   /// scheduling parameters for RXn-TXnp4 thread
   struct sched_param sched_param_rxtx;
-  /// pipeline ready state
-  int pipe_ready;
-} eNB_rxtx_proc_t;
+
+  /// \internal This variable is protected by \ref mutex_RUs.
+  int instance_cnt_RUs;
+  /// condition variable for tx processing thread
+  pthread_cond_t cond_RUs;
+  /// mutex for RXn-TXnp4 processing thread
+  pthread_mutex_t mutex_RUs;
+} L1_rxtx_proc_t;
 
 typedef struct {
   struct PHY_VARS_eNB_s *eNB;
@@ -693,7 +695,7 @@ typedef struct {
 } te_params;
 
 /// Context data structure for eNB subframe processing
-typedef struct eNB_proc_t_s {
+typedef struct L1_proc_t_s {
   /// Component Carrier index
   uint8_t              CC_id;
   /// thread index
@@ -804,12 +806,16 @@ typedef struct eNB_proc_t_s {
   pthread_mutex_t mutex_asynch_rxtx;
   /// mutex for RU access to eNB processing (PDSCH/PUSCH)
   pthread_mutex_t mutex_RU;
+  /// mutex for eNB processing to access RU TX (PDSCH/PUSCH)
+  pthread_mutex_t mutex_RU_tx;
   /// mutex for RU access to eNB processing (PRACH)
   pthread_mutex_t mutex_RU_PRACH;
   /// mutex for RU access to eNB processing (PRACH BR)
   pthread_mutex_t mutex_RU_PRACH_br;
   /// mask for RUs serving eNB (PDSCH/PUSCH)
   int RU_mask;
+  /// mask for RUs serving eNB (PDSCH/PUSCH)
+  int RU_mask_tx;
   /// mask for RUs serving eNB (PRACH)
   int RU_mask_prach;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
@@ -821,12 +827,10 @@ typedef struct eNB_proc_t_s {
   /// parameters for turbo-encoding worker thread
   te_params tep[3];
   /// set of scheduling variables RXn-TXnp4 threads
-  eNB_rxtx_proc_t proc_rxtx[2];
+  L1_rxtx_proc_t L1_proc,L1_proc_tx;
   /// stats thread pthread descriptor
   pthread_t process_stats_thread;
-  /// for waking up tx procedure
-  RU_proc_t *ru_proc;
-} eNB_proc_t;
+} L1_proc_t;
 
 
 
@@ -894,7 +898,7 @@ typedef struct PHY_VARS_eNB_s {
   module_id_t          Mod_id;
   uint8_t              CC_id;
   uint8_t              configured;
-  eNB_proc_t           proc;
+  L1_proc_t            proc;
   int                  single_thread_flag;
   int                  abstraction_flag;
   int                  num_RU;
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index ec14b32ac26f6214bf8b89f58cd8c24e1db55fb9..26160696284a3b8b5bccb34cb6a9aa98ce09f468 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -48,7 +48,7 @@ extern uint8_t nfapi_mode;
 
 void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
                              int frame, int subframe,
-                             eNB_rxtx_proc_t *proc,
+                             L1_rxtx_proc_t *proc,
                              nfapi_dl_config_request_pdu_t *dl_config_pdu)
 {
   int idx                         = subframe&1;
@@ -66,7 +66,7 @@ void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
 void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,
-                             eNB_rxtx_proc_t *proc,
+                             L1_rxtx_proc_t *proc,
                              nfapi_dl_config_request_pdu_t *dl_config_pdu)
 {
   int idx                         = proc->subframe_tx&1;
@@ -81,7 +81,7 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,
 
 #endif
 
-void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                                   nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
 {
   int idx                         = subframe&1;
@@ -93,7 +93,7 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_r
   fill_dci0(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu);
 }
 
-void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                                  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
 {
   LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1];
@@ -112,7 +112,7 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rx
   AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n");
 }
 
-void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
                           nfapi_dl_config_request_pdu_t *dl_config_pdu,
                           uint8_t *sdu)
 {
@@ -139,7 +139,7 @@ extern uint32_t localRIV2alloc_LUT100_2[6000];
 extern uint32_t localRIV2alloc_LUT100_3[6000];
 #endif
 
-void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                             nfapi_dl_config_request_pdu_t *dl_config_pdu,
                             uint8_t codeword_index,
                             uint8_t *sdu)
@@ -569,7 +569,7 @@ void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_p
   AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n");
 }
 
-void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
                          nfapi_ul_config_request_pdu_t *ul_config_pdu,
                          uint16_t frame,uint8_t subframe,uint8_t srs_present)
 {
@@ -647,7 +647,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 void schedule_response(Sched_Rsp_t *Sched_INFO)
 {
   PHY_VARS_eNB *eNB;
-  eNB_rxtx_proc_t *proc;
+  L1_rxtx_proc_t *proc;
   // copy data from L2 interface into L1 structures
   module_id_t               Mod_id       = Sched_INFO->module_id;
   uint8_t                   CC_id        = Sched_INFO->CC_id;
@@ -670,7 +670,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
 
   eNB         = RC.eNB[Mod_id][CC_id];
   fp          = &eNB->frame_parms;
-  proc        = &eNB->proc.proc_rxtx[0];
+  proc        = &eNB->proc.L1_proc;
 
   /* TODO: check that following line is correct - in the meantime it is disabled */
   //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return;
diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h
index efb028f46444b73cbed6df710faf6db75bcc4080..3bd469b685f6ea3fc04d973f9fc6463d4533a545 100644
--- a/openair1/SCHED/fapi_l1.h
+++ b/openair1/SCHED/fapi_l1.h
@@ -43,17 +43,17 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe
 void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
 void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
 void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
-void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
-void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
-void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
+void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
+void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
 				  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
 				 nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu);
-void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
 			    nfapi_dl_config_request_pdu_t *dl_config_pdu,
 			    uint8_t codeword_index,
 			    uint8_t *sdu);
-void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
 			 nfapi_ul_config_request_pdu_t *ul_config_pdu,
 			 uint16_t frame,uint8_t subframe,uint8_t srs_present);
 
diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c
index 664791f7c459632d51541e413ef844384e6c8ab1..55149f8d2ea075623bb4788ec600f30c0a9a44bc 100644
--- a/openair1/SCHED/phy_mac_stub.c
+++ b/openair1/SCHED/phy_mac_stub.c
@@ -40,7 +40,7 @@
 uint8_t dci_ndi_toggle_even[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 uint8_t dci_ndi_toggle_odd[8]  = {0, 0, 0, 0, 0, 0, 0, 0};
 
-void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
+void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc)
 {
 /* SYRTEM */
   uint8_t *dci_ndi_toggle_tmp = NULL;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 141f6e43ffbedb3190da404a341b1094b0b28ded..0997f9c552e5a93199cae2da298d46505b19c7db 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -133,7 +133,7 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr
 
 }
 
-void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
+void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
 
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0))
@@ -314,7 +314,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
 
 
 void pdsch_procedures(PHY_VARS_eNB *eNB,
-		      eNB_rxtx_proc_t *proc,
+		      L1_rxtx_proc_t *proc,
 		      int harq_pid,
 		      LTE_eNB_DLSCH_t *dlsch, 
 		      LTE_eNB_DLSCH_t *dlsch1,
@@ -465,7 +465,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
 
 
 void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
-			   eNB_rxtx_proc_t *proc,
+			   L1_rxtx_proc_t *proc,
 			   int do_meas)
 {
   int frame=proc->frame_tx;
@@ -656,7 +656,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 }
 
 
-void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
+void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   const int subframe = proc->subframe_rx;
@@ -719,7 +719,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
+void uci_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc)
 {
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0};
@@ -1253,7 +1253,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   }
 }
 
-void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
+void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc)
 {
   uint32_t ret=0,i;
   uint32_t harq_pid;
@@ -1474,7 +1474,7 @@ extern void *td_thread(void*);
 
 void init_td_thread(PHY_VARS_eNB *eNB) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
 
   proc->tdp.eNB = eNB;
   proc->instance_cnt_td         = -1;
@@ -1488,7 +1488,7 @@ void init_td_thread(PHY_VARS_eNB *eNB) {
 }
 void kill_td_thread(PHY_VARS_eNB *eNB) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
   proc->instance_cnt_td         = 0;
   pthread_cond_signal(&proc->cond_td);
   
@@ -1501,7 +1501,7 @@ extern void *te_thread(void*);
 
 void init_te_thread(PHY_VARS_eNB *eNB) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
 
   for(int i=0; i<3 ;i++){
     proc->tep[i].eNB = eNB;
@@ -1517,7 +1517,7 @@ void init_te_thread(PHY_VARS_eNB *eNB) {
 }
 void kill_te_thread(PHY_VARS_eNB *eNB) {
 
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
 
   for(int i=0; i<3 ;i++){
     proc->tep[i].instance_cnt_te         = 0;
@@ -2033,7 +2033,7 @@ void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
 
-void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
+void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc)
 {
   //RX processing for ue-specific resources (i
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h
index 3e1455e67ca3efd0d121f96c107265b28e53a74f..e9af869b05518d68b71d05f4efef29ec90a9adeb 100644
--- a/openair1/SCHED/sched_common.h
+++ b/openair1/SCHED/sched_common.h
@@ -180,7 +180,7 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
   @param UE_id ID of UE which may be issuing the SR
   @returns 1 if TXOp is active.
 */
-uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id);
+uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t UE_id);
 
 /*! \brief Gives the UL subframe corresponding to a PDDCH order in subframe n
   @param frame_parms Pointer to DL frame parameters
@@ -247,7 +247,7 @@ TDD, this routine computes the procedure described in Section 10.1 of 36.213 (th
 @param n1_pucch3 Pointer to n1_pucch3
 */
 void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB,
-		      eNB_rxtx_proc_t *proc,
+		      L1_rxtx_proc_t *proc,
                       uint8_t UE_id,
                       int16_t *n1_pucch0,
                       int16_t *n1_pucch1,
@@ -266,7 +266,7 @@ void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB,
 */
 void process_HARQ_feedback(uint8_t UE_id,
                            PHY_VARS_eNB *phy_vars_eNB,
-			   eNB_rxtx_proc_t *proc,
+			   L1_rxtx_proc_t *proc,
                            uint8_t pusch_flag,
                            uint8_t *pucch_payload,
                            uint8_t pucch_sel,
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index 9815f25574beb8f15751a7a5c37d20fcb43cd60d..dccfbf7c388ac204771e391eaa1044cffea9e4cd 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -92,13 +92,13 @@ enum openair_HARQ_TYPE {
   @param abstraction_flag Indicator of PHY abstraction
   @param do_meas Do inline timing measurement
 */
-void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,int do_meas);
+void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,int do_meas);
 
 /*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes.
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param proc Pointer to RXn-TXnp4 proc information
 */
-void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc);
+void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc);
 
 /*! \brief Scheduling for eNB TX procedures in TDD S-subframes.
   @param phy_vars_eNB Pointer to eNB variables on which to act
@@ -110,7 +110,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *pr
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
 */
-void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc);
+void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc);
 
 /*! \brief Scheduling for eNB TX procedures in TDD S-subframes.
   @param phy_vars_eNB Pointer to eNB variables on which to act
@@ -121,7 +121,7 @@ void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB);
 /*! \brief Scheduling for eNB RX procedures in TDD S-subframes.
   @param phy_vars_eNB Pointer to eNB variables on which to act
 */
-void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc);
+void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc);
 
 /*! \brief Scheduling for eNB PRACH RX procedures
   @param phy_vars_eNB Pointer to eNB variables on which to act
@@ -186,7 +186,7 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
   @param UE_id ID of UE which may be issuing the SR
   @returns 1 if TXOp is active.
 */
-uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id);
+uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t UE_id);
 
 int8_t find_ue_dlsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index faf1b5b87a583ae9bb126343a0f888edcf9a5d0b..f7a8f794c578018d2a412c6bf5207ae401320595 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -1341,7 +1341,7 @@ int main(int argc, char **argv)
       eNB->UE_stats[1].DL_pmi_single = 0;
   }
 
-  eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]];
+  L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
 
   if (input_fd==NULL) {
 
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index ac442ae5e97f6c21a56308ca37a0a0e4503cb03e..569d2226deb1e7953da67a8d39c7c9690e1bb39e 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -750,7 +750,7 @@ int main(int argc, char **argv)
                                 0,
                                 0);
 
-  eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1];
+  L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx;
 
   eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0);
   UE->ulsch[0]   = new_ue_ulsch(N_RB_DL,0);
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 75b3486f240f1200376eb2df81054b5e5a06440c..24338e1370335b5ac6b51b0b4db3c7efdf3cf174 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -85,8 +85,8 @@ int nfapi_mode = 0;
 
 extern void fep_full(RU_t *ru);
 extern void ru_fep_full_2thread(RU_t *ru);
-extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc);
-extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc);
+extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
+extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
 
 nfapi_dl_config_request_t DL_req;
 nfapi_ul_config_request_t UL_req;
@@ -800,7 +800,7 @@ int main(int argc, char **argv) {
   UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
   eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
   UE->mac_enabled=0;
-  eNB_rxtx_proc_t *proc_rxtx   = &eNB->proc.proc_rxtx[subframe&1];
+  L1_rxtx_proc_t *proc_rxtx         = &eNB->proc.L1_proc;
   UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1];
   proc_rxtx->frame_rx=1;
   proc_rxtx->subframe_rx=subframe;
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 166616c368069279247ab3dcb18ddebf0e49692f..18e2fa4cb742a03820ba376fc0cd78894ce149f0 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -590,7 +590,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //,
   //Mod_id = 0; // Currently static (only for one UE) but this should change.
 
   /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
-  eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];*/
+  L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;*/
   nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list;
   nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp;
 
@@ -941,14 +941,14 @@ void UE_config_stub_pnf(void) {
 
 /* Dummy functions*/
 
-void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                                   nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
 {
 
 }
 
 
-void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                                  nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu)
 {
 
@@ -957,14 +957,14 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rx
 
 void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
                              int frame, int subframe,
-                             eNB_rxtx_proc_t *proc,
+                             L1_rxtx_proc_t *proc,
                              nfapi_dl_config_request_pdu_t *dl_config_pdu)
 {
 
 }
 
 
-void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
                           nfapi_dl_config_request_pdu_t *dl_config_pdu,
                           uint8_t *sdu)
 {
@@ -972,7 +972,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 }
 
 
-void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
+void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
                             nfapi_dl_config_request_pdu_t *dl_config_pdu,
                             uint8_t codeword_index,
                             uint8_t *sdu)
@@ -981,7 +981,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
 }
 
 
-void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
+void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
                          nfapi_ul_config_request_pdu_t *ul_config_pdu,
                          uint16_t frame,uint8_t subframe,uint8_t srs_present)
 {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
index 60b47c5c493e62a245dbbcb8d50a5267a21b9ed8..728492ee835aaf2607ea6aefd09eb5a7be2cc880 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
@@ -15,7 +15,7 @@ eNBs =
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code = 1;
 
-    plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
+    plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
 
     tr_s_preference     = "local_mac"
 
@@ -138,7 +138,7 @@ eNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.26";
+    mme_ip_address      = ( { ipv4       = "192.168.12.148";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -187,7 +187,7 @@ RUs = (
          max_pdschReferenceSignalPower = -27;
          max_rxgain                    = 116;
          eNB_instances  = [0];
-
+       sdr_addrs      = "type=x300";
     }
 );  
 
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index aad542b3d260f9d6b7e4c5ea4056926f879127b3..cc25ca088535774423a57d2f57bbe069f52bf740 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -143,8 +143,8 @@ extern double cpuf;
 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_tx(PHY_VARS_eNB *eNB);
+int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB);
 void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
@@ -158,8 +158,9 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
 #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
 
 
-static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
+static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) {
   start_meas(&softmodem_stats_rxtx_sf);
+  //L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx;
 
   // *******************************************************************
 
@@ -217,14 +218,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 );
 
-  if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
-    if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) {
-      LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx);
-      return(-1);
-    }
-
-    if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0)  return(-1);
-  }
 
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   eNB->UL_INFO.frame     = proc->frame_rx;
@@ -290,20 +283,20 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
 }
 
 
-static void *tx_thread(void *param) {
-  eNB_proc_t *eNB_proc  = (eNB_proc_t *)param;
-  eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1];
+static void* L1_thread_tx(void* param) {
+
+  L1_proc_t *eNB_proc  = (L1_proc_t*)param;
+  L1_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx;
   PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
   char thread_name[100];
-  sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
+  sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
   thread_top_init(thread_name,1,470000,500000,500000);
 
   //wait_sync("tx_thread");
 
   while (!oai_exit) {
-    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
-
-    if (oai_exit) break;
+    if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
+    if (oai_exit) break;  
 
     // *****************************************
     // TX processing for subframe n+4
@@ -316,19 +309,17 @@ static void *tx_thread(void *param) {
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx);
     phy_procedures_eNB_TX(eNB, proc, 1);
 
-    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
 
-    pthread_mutex_lock( &proc->mutex_rxtx );
-    proc->pipe_ready++;
+    pthread_mutex_lock( &proc->mutex );
+    proc->instance_cnt = -1;
 
     // the thread can now be woken up
-    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
+    if (pthread_cond_signal(&proc->cond) != 0) {
       LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
       exit_fun( "ERROR pthread_cond_signal" );
     }
-
-    pthread_mutex_unlock( &proc->mutex_rxtx );
-    wakeup_txfh(proc,eNB_proc->ru_proc);
+    pthread_mutex_unlock( &proc->mutex );
+    wakeup_txfh(proc,eNB);
   }
 
   return 0;
@@ -336,31 +327,34 @@ static void *tx_thread(void *param) {
 
 /*!
  * \brief The RX UE-specific and TX thread of eNB.
- * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \param param is a \ref L1_proc_t structure which contains the info what to process.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 
-static void *eNB_thread_rxtx( void *param ) {
+static void* L1_thread( void* param ) {
+
   static int eNB_thread_rxtx_status;
-  //eNB_proc_t *eNB_proc  = (eNB_proc_t*)param;
-  eNB_rxtx_proc_t *proc;
+  //L1_proc_t *eNB_proc  = (L1_proc_t*)param;
+  L1_rxtx_proc_t *proc;
 
   // Working
-  if(nfapi_mode ==2) {
-    proc = (eNB_rxtx_proc_t *)param;
-  } else {
-    eNB_proc_t *eNB_proc  = (eNB_proc_t *)param;
-    proc = &eNB_proc->proc_rxtx[0];
+  if(nfapi_mode ==2){
+    proc = (L1_rxtx_proc_t*)param;
+  }
+  else{
+    L1_proc_t *eNB_proc  = (L1_proc_t*)param;
+    proc = &eNB_proc->L1_proc;
   }
 
   PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id];
-  //RU_proc_t *ru_proc = NULL;
+
   char thread_name[100];
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   // set default return value
   eNB_thread_rxtx_status = 0;
-  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
+
+  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1);
   thread_top_init(thread_name,1,470000,500000,500000);
   pthread_setname_np( pthread_self(),"rxtx processing");
   LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid));
@@ -369,7 +363,7 @@ static void *eNB_thread_rxtx( void *param ) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
     T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
 
-    if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
+    if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break;
 
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu());
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
@@ -384,25 +378,11 @@ static void *eNB_thread_rxtx( void *param ) {
       if (rxtx(eNB,proc,thread_name) < 0) break;
     }
 
-    if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
-
-    pthread_mutex_lock( &proc->mutex_rxtx );
-    proc->pipe_ready++;
-
-    // the thread can now be woken up
-    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
-      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
-      exit_fun( "ERROR pthread_cond_signal" );
-    }
-
-    pthread_mutex_unlock( &proc->mutex_rxtx );
-
-    if (nfapi_mode!=2) {
-      if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)      wakeup_tx(eNB,eNB->proc.ru_proc);
-      else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
-        phy_procedures_eNB_TX(eNB, proc, 1);
-        wakeup_txfh(proc,eNB->proc.ru_proc);
-      }
+    if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)              phy_procedures_eNB_TX(eNB, proc, 1);
+    if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
+    if (nfapi_mode!=2){
+    	if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)      wakeup_tx(eNB);
+    	else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT)     wakeup_txfh(proc,eNB);
     }
   } // while !oai_exit
 
@@ -412,9 +392,10 @@ static void *eNB_thread_rxtx( void *param ) {
   return &eNB_thread_rxtx_status;
 }
 
-void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) {
-  eNB_proc_t *proc           = &eNB->proc;
-  eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
+void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru)
+{
+  L1_proc_t *proc           = &eNB->proc;
+  L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
   LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
   RU_proc_t *ru_proc=&ru->proc;
   proc->frame_rx    = frame_rx;
@@ -422,104 +403,121 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t
 
   if (!oai_exit) {
     T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
-    proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
-    proc_rxtx->frame_rx     = ru_proc->frame_rx;
-    proc_rxtx->subframe_rx  = ru_proc->subframe_rx;
-    proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > (9-sf_ahead)) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
-    proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + sf_ahead)%10;
 
-    if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
+    L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
+    L1_proc->frame_rx     = ru_proc->frame_rx;
+    L1_proc->subframe_rx  = ru_proc->subframe_rx;
+    L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+    L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
 
-    ru_proc->timestamp_tx = proc_rxtx->timestamp_tx;
-    ru_proc->subframe_tx  = proc_rxtx->subframe_tx;
-    ru_proc->frame_tx     = proc_rxtx->frame_tx;
+    if (rxtx(eNB,L1_proc,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
+    ru_proc->timestamp_tx = L1_proc->timestamp_tx;
+    ru_proc->subframe_tx  = L1_proc->subframe_tx;
+    ru_proc->frame_tx     = L1_proc->frame_tx;
   }
 }
 
-int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) {
-  if(ru_proc == NULL)
-    return(0);
+int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) {
+
+  RU_t *ru;
+  RU_proc_t *ru_proc;
+
 
   struct timespec wait;
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
 
-  if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) {
-    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx);
+  if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) {
+    LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx);
     return(-1);
   }
+  pthread_mutex_lock(&eNB->proc.mutex_RU_tx);
+  eNB->proc.RU_mask_tx = 0;
+  pthread_mutex_unlock(&eNB->proc.mutex_RU_tx);
+  if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1);
+
+  for(int i=0; i<eNB->num_RU; i++)
+  {
+    ru      = eNB->RU_list[i];
+    ru_proc = &ru->proc;
+    if (ru_proc->instance_cnt_eNBs == 0) {
+      LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx);
+      return(-1);
+    }
+    if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
+      LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
+      exit_fun( "error locking mutex_eNB" );
+      return(-1);
+    }
 
-  if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1);
+    ru_proc->instance_cnt_eNBs = 0;
+    ru_proc->timestamp_tx = proc->timestamp_tx;
+    ru_proc->subframe_tx  = proc->subframe_tx;
+    ru_proc->frame_tx     = proc->frame_tx;
 
-  if (ru_proc->instance_cnt_eNBs == 0) {
-    LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx);
-    return(-1);
+  
+    // the thread can now be woken up
+    if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
+      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
+      exit_fun( "ERROR pthread_cond_signal" );
+      return(-1);
+    }
+  
+    pthread_mutex_unlock( &ru_proc->mutex_eNBs );
   }
 
-  if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) {
-    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs );
-    exit_fun( "error locking mutex_eNB" );
-    return(-1);
-  }
+  return(0);
+}
 
-  ++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;
+int wakeup_tx(PHY_VARS_eNB *eNB) {
 
-  // the thread can now be woken up
-  if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) {
-    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
-    exit_fun( "ERROR pthread_cond_signal" );
-    return(-1);
-  }
+  L1_proc_t *proc=&eNB->proc;
 
-  pthread_mutex_unlock( &ru_proc->mutex_eNBs );
-  return(0);
-}
+  L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx;
+  L1_rxtx_proc_t *L1_proc    = &proc->L1_proc;
 
-int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) {
-  eNB_proc_t *proc=&eNB->proc;
-  eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1];
-  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
+  
   struct timespec wait;
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
-
-  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);
+  
+  
+  if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) {
+    LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n");
+    exit_fun("ERROR pthread_lock");
     return(-1);
   }
-
-  if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) {
-    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx );
-    exit_fun( "error locking mutex_tx" );
-    return(-1);
+  while(L1_proc_tx->instance_cnt == 0){
+    pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
   }
 
-  ++proc_rxtx1->instance_cnt_rxtx;
-  proc_rxtx1->subframe_rx   = proc_rxtx0->subframe_rx;
-  proc_rxtx1->frame_rx      = proc_rxtx0->frame_rx;
-  proc_rxtx1->subframe_tx   = proc_rxtx0->subframe_tx;
-  proc_rxtx1->frame_tx      = proc_rxtx0->frame_tx;
-  proc_rxtx1->timestamp_tx  = proc_rxtx0->timestamp_tx;
+  L1_proc_tx->instance_cnt = 0;
+
+  
+  L1_proc_tx->subframe_rx   = L1_proc->subframe_rx;
+  L1_proc_tx->frame_rx      = L1_proc->frame_rx;
+  L1_proc_tx->subframe_tx   = L1_proc->subframe_tx;
+  L1_proc_tx->frame_tx      = L1_proc->frame_tx;
+  L1_proc_tx->timestamp_tx  = L1_proc->timestamp_tx;
 
   // the thread can now be woken up
-  if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 0) {
+  if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
     LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
     exit_fun( "ERROR pthread_cond_signal" );
     return(-1);
   }
-
-  pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx );
+  
+  pthread_mutex_unlock( &L1_proc_tx->mutex);
   return(0);
 }
 
 int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
-  eNB_proc_t *proc=&eNB->proc;
+
+  L1_proc_t *proc=&eNB->proc;
   RU_proc_t *ru_proc=&ru->proc;
-  eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0];
-  //eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];
+
+  L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
+  
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   int i;
   struct timespec wait;
@@ -547,52 +545,48 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
 
-  if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) {
-    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx);
-    return(-1);
-  }
-
-  if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1);
-
-  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);
+    
+  if (L1_proc->instance_cnt == 0) {
+    LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",L1_proc->frame_rx,L1_proc->subframe_rx);
     return(-1);
   }
 
   // wake up TX for subframe n+sf_ahead
   // lock the TX mutex and make sure the thread is ready
-  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 );
+  if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
+    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
     exit_fun( "error locking mutex_rxtx" );
     return(-1);
   }
 
-  ++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
+  ++L1_proc->instance_cnt;
+  
+  // 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 
   // transmitted timestamp of the next TX slot (first).
   // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
   // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
   // and proc->subframe_tx = proc->subframe_rx+sf_ahead
-  proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
-  proc_rxtx0->frame_rx     = ru_proc->frame_rx;
-  proc_rxtx0->subframe_rx  = ru_proc->subframe_rx;
-  proc_rxtx0->frame_tx     = (proc_rxtx0->subframe_rx > (9-sf_ahead)) ? (proc_rxtx0->frame_rx+1)&1023 : proc_rxtx0->frame_rx;
-  proc_rxtx0->subframe_tx  = (proc_rxtx0->subframe_rx + sf_ahead)%10;
+  L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti);
+  L1_proc->frame_rx     = ru_proc->frame_rx;
+  L1_proc->subframe_rx  = ru_proc->subframe_rx;
+  L1_proc->frame_tx     = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+  L1_proc->subframe_tx  = (L1_proc->subframe_rx + sf_ahead)%10;
 
   // the thread can now be woken up
-  if (pthread_cond_signal(&proc_rxtx0->cond_rxtx) != 0) {
+  if (pthread_cond_signal(&L1_proc->cond) != 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_rxtx0->mutex_rxtx );
+  pthread_mutex_unlock( &L1_proc->mutex);
   return(0);
 }
 
 void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
-  eNB_proc_t *proc = &eNB->proc;
+
+  L1_proc_t *proc = &eNB->proc;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   int i;
 
@@ -654,7 +648,8 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
 
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
-  eNB_proc_t *proc = &eNB->proc;
+
+  L1_proc_t *proc = &eNB->proc;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   int i;
 
@@ -718,13 +713,14 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
 
 /*!
  * \brief The prach receive thread of eNB.
- * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \param param is a \ref L1_proc_t structure which contains the info what to process.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 static void *eNB_thread_prach( void *param ) {
   static int eNB_thread_prach_status;
   PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
+
   // set default return value
   eNB_thread_prach_status = 0;
   thread_top_init("eNB_thread_prach",1,500000,1000000,20000000);
@@ -754,13 +750,14 @@ static void *eNB_thread_prach( void *param ) {
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 /*!
  * \brief The prach receive thread of eNB for BL/CE UEs.
- * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \param param is a \ref L1_proc_t structure which contains the info what to process.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 static void *eNB_thread_prach_br( void *param ) {
   static int eNB_thread_prach_status;
   PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
-  eNB_proc_t *proc = &eNB->proc;
+  L1_proc_t *proc = &eNB->proc;
+
   // set default return value
   eNB_thread_prach_status = 0;
   thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000);
@@ -827,8 +824,8 @@ void init_eNB_proc(int inst) {
   /*int i=0;*/
   int CC_id;
   PHY_VARS_eNB *eNB;
-  eNB_proc_t *proc;
-  eNB_rxtx_proc_t *proc_rxtx;
+  L1_proc_t *proc;
+  L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
   pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   pthread_attr_t *attr_prach_br=NULL;
@@ -841,34 +838,45 @@ void init_eNB_proc(int inst) {
     LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
 #endif
     proc = &eNB->proc;
-    proc_rxtx                      = proc->proc_rxtx;
-    proc_rxtx[0].instance_cnt_rxtx = -1;
-    proc_rxtx[1].instance_cnt_rxtx = -1;
-    proc_rxtx[0].pipe_ready        = 0;
-    proc_rxtx[1].pipe_ready        = 0;
+
+    L1_proc                        = &proc->L1_proc;
+    L1_proc_tx                     = &proc->L1_proc_tx;
+    L1_proc->instance_cnt          = -1;
+    L1_proc_tx->instance_cnt       = -1;
+    L1_proc->instance_cnt_RUs      = 0;
+    L1_proc_tx->instance_cnt_RUs   = 0;
     proc->instance_cnt_prach       = -1;
     proc->instance_cnt_asynch_rxtx = -1;
     proc->instance_cnt_synch       = -1;
-    proc->CC_id                    = CC_id;
-    proc->first_rx=1;
-    proc->first_tx=1;
-    proc->RU_mask=0;
-    proc->RU_mask_prach=0;
+    proc->CC_id                    = CC_id;    
+
+    proc->first_rx                 =1;
+    proc->first_tx                 =1;
+    proc->RU_mask_tx               = (1<<eNB->num_RU)-1;
+    proc->RU_mask                  =0;
+    proc->RU_mask_prach            =0;
+
     pthread_mutex_init( &eNB->UL_INFO_mutex, NULL);
-    pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
-    pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
-    pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
-    pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
+    pthread_mutex_init( &L1_proc->mutex, NULL);
+    pthread_mutex_init( &L1_proc_tx->mutex, NULL);
+    pthread_cond_init( &L1_proc->cond, NULL);
+    pthread_cond_init( &L1_proc_tx->cond, NULL);
+    pthread_mutex_init( &L1_proc->mutex_RUs, NULL);
+    pthread_mutex_init( &L1_proc_tx->mutex_RUs, NULL);
+    pthread_cond_init( &L1_proc->cond_RUs, NULL);
+    pthread_cond_init( &L1_proc_tx->cond_RUs, NULL);
+
     pthread_mutex_init( &proc->mutex_prach, NULL);
     pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
     pthread_mutex_init( &proc->mutex_RU,NULL);
+    pthread_mutex_init( &proc->mutex_RU_tx,NULL);
     pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
     pthread_cond_init( &proc->cond_prach, NULL);
     pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
     pthread_attr_init( &proc->attr_prach);
     pthread_attr_init( &proc->attr_asynch_rxtx);
-    pthread_attr_init( &proc_rxtx[0].attr_rxtx);
-    pthread_attr_init( &proc_rxtx[1].attr_rxtx);
+    pthread_attr_init( &L1_proc->attr);
+    pthread_attr_init( &L1_proc_tx->attr);
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     proc->instance_cnt_prach_br    = -1;
     proc->RU_mask_prach_br=0;
@@ -878,8 +886,8 @@ void init_eNB_proc(int inst) {
     pthread_attr_init( &proc->attr_prach_br);
 #endif
 #ifndef DEADLINE_SCHEDULER
-    attr0       = &proc_rxtx[0].attr_rxtx;
-    attr1       = &proc_rxtx[1].attr_rxtx;
+    attr0       = &L1_proc->attr;
+    attr1       = &L1_proc_tx->attr;
     attr_prach  = &proc->attr_prach;
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     attr_prach_br  = &proc->attr_prach_br;
@@ -896,21 +904,15 @@ void init_eNB_proc(int inst) {
     LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
 
     if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
-      pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc );
-      pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc);
+      pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
+      pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc);
     }
 
     pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
 #endif
-    /*char name[16];
-    if (eNB->single_thread_flag==0) {
-      snprintf( name, sizeof(name), "RXTX0 %d", i );
-      pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
-      snprintf( name, sizeof(name), "RXTX1 %d", i );
-      pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
-    }*/
+
     AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
 
     if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB);
@@ -923,7 +925,7 @@ void init_eNB_proc(int inst) {
 
      if (eNB->node_timing == synch_to_ext_device) { //master
      eNB->proc.num_slaves = MAX_NUM_CCs-1;
-     eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*));
+     eNB->proc.slave_proc = (L1_proc_t**)malloc(eNB->proc.num_slaves*sizeof(L1_proc_t*));
 
      for (i=0; i< eNB->proc.num_slaves; i++) {
      if (i < CC_id)  eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc);
@@ -946,14 +948,15 @@ void init_eNB_proc(int inst) {
 void kill_eNB_proc(int inst) {
   int *status;
   PHY_VARS_eNB *eNB;
-  eNB_proc_t *proc;
-  eNB_rxtx_proc_t *proc_rxtx;
-  int i;
+  L1_proc_t *proc;
+  L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
 
   for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB=RC.eNB[inst][CC_id];
-    proc = &eNB->proc;
-    proc_rxtx = &proc->proc_rxtx[0];
+    
+    proc        = &eNB->proc;
+    L1_proc     = &proc->L1_proc;
+    L1_proc_tx  = &proc->L1_proc_tx;
 
     if(get_thread_worker_conf() == WORKER_ENABLE) {
       kill_td_thread(eNB);
@@ -962,12 +965,16 @@ void kill_eNB_proc(int inst) {
 
     LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst );
 
-    for (i=0; i<2; i++) {
-      pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx);
-      proc_rxtx[i].instance_cnt_rxtx = 0;
-      proc_rxtx[i].pipe_ready = 0;
-      pthread_cond_signal(&proc_rxtx[i].cond_rxtx);
-      pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx);
+    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
+      pthread_mutex_lock(&L1_proc->mutex);
+      L1_proc->instance_cnt = 0;
+      pthread_cond_signal(&L1_proc->cond);
+      pthread_mutex_unlock(&L1_proc->mutex);
+
+      pthread_mutex_lock(&L1_proc_tx->mutex);
+      L1_proc_tx->instance_cnt = 0;
+      pthread_cond_signal(&L1_proc_tx->cond);
+      pthread_mutex_unlock(&L1_proc_tx->mutex);
     }
 
     pthread_mutex_lock(&proc->mutex_prach);
@@ -991,18 +998,27 @@ void kill_eNB_proc(int inst) {
     LOG_I(PHY, "Destroying UL_INFO mutex\n");
     pthread_mutex_destroy(&eNB->UL_INFO_mutex);
 
-    for (i=0; i<2; i++) {
-      LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i);
-      pthread_join( proc_rxtx[i].pthread_rxtx, (void **)&status );
-      LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i);
-      pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
-      pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
+    if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) {
+      LOG_I(PHY, "Joining L1_proc mutex/cond\n");
+      pthread_join( L1_proc->pthread, (void**)&status );
+      LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
+      pthread_join( L1_proc_tx->pthread, (void**)&status );
     }
+    LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
+    pthread_mutex_destroy( &L1_proc->mutex );
+    pthread_cond_destroy( &L1_proc->cond );
+    pthread_mutex_destroy( &L1_proc->mutex_RUs );
+    pthread_cond_destroy( &L1_proc->cond_RUs );
+    LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
+    pthread_mutex_destroy( &L1_proc_tx->mutex );
+    pthread_cond_destroy( &L1_proc_tx->cond );
+    pthread_mutex_destroy( &L1_proc_tx->mutex_RUs );
+    pthread_cond_destroy( &L1_proc_tx->cond_RUs );
 
     pthread_attr_destroy(&proc->attr_prach);
     pthread_attr_destroy(&proc->attr_asynch_rxtx);
-    pthread_attr_destroy(&proc_rxtx[0].attr_rxtx);
-    pthread_attr_destroy(&proc_rxtx[1].attr_rxtx);
+    pthread_attr_destroy(&L1_proc->attr);
+    pthread_attr_destroy(&L1_proc_tx->attr);
 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     pthread_mutex_destroy(&proc->mutex_RU_PRACH_br);
     pthread_attr_destroy(&proc->attr_prach_br);
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 3f0fe776472f571880dbb70f1be52ff2264f007a..10b47b2459813f74be7d04712347907c4759b689 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -956,7 +956,7 @@ void tx_rf(RU_t *ru) {
 /*!
  * \brief The Asynchronous RX/TX FH thread of RAU/RCC/eNB/RRU.
  * This handles the RX FH for an asynchronous RRU/UE
- * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \param param is a \ref L1_proc_t structure which contains the info what to process.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 static void* ru_thread_asynch_rxtx( void* param ) {
@@ -1249,12 +1249,12 @@ void do_ru_synch(RU_t *ru) {
 
 
 
-void wakeup_eNBs(RU_t *ru) {
+void wakeup_L1s(RU_t *ru) {
 
   int i;
   PHY_VARS_eNB **eNB_list = ru->eNB_list;
 
-  LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
+  LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top);
 
 
   if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
@@ -1273,7 +1273,6 @@ void wakeup_eNBs(RU_t *ru) {
     for (i=0;i<ru->num_eNB;i++)
     {
       LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx);
-      eNB_list[i]->proc.ru_proc = &ru->proc;
       if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0)
       {
         LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
@@ -1529,8 +1528,12 @@ volatile int16_t phy_tx_end;
 #endif
 
 static void* ru_thread_tx( void* param ) {
-  RU_t *ru         = (RU_t*)param;
-  RU_proc_t *proc  = &ru->proc;
+  RU_t *ru              = (RU_t*)param;
+  RU_proc_t *proc       = &ru->proc;
+  PHY_VARS_eNB *eNB;
+  L1_proc_t *eNB_proc;
+  L1_rxtx_proc_t *L1_proc;
+
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
 
@@ -1551,7 +1554,7 @@ static void* ru_thread_tx( void* param ) {
     if (oai_exit) break;   
 
 
-	LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
+	LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n");
 	// wait until eNBs are finished subframe RX n and TX n+4
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
     if (oai_exit) break;
@@ -1568,15 +1571,37 @@ static void* ru_thread_tx( void* param ) {
       if (ru->fh_north_out) ru->fh_north_out(ru);
 	}
     release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx");
-    
-    pthread_mutex_lock( &proc->mutex_eNBs );
-    proc->ru_tx_ready++;
-    // the thread can now be woken up
-    if (pthread_cond_signal(&proc->cond_eNBs) != 0) {
-      LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
-      exit_fun( "ERROR pthread_cond_signal" );
+    for(int i = 0; i<ru->num_eNB; i++)
+    {
+      eNB       = ru->eNB_list[i];
+      eNB_proc  = &eNB->proc;
+      L1_proc   = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc;
+      pthread_mutex_lock(&eNB_proc->mutex_RU_tx);
+      for (int j=0;j<eNB->num_RU;j++) {
+        if (ru == eNB->RU_list[j]) {
+          if ((eNB_proc->RU_mask_tx&(1<<j)) > 0)
+            LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
+	      eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx);
+          eNB_proc->RU_mask_tx |= (1<<j);
+        }
+      }
+      if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
+        pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
+      }
+      else { // all RUs TX are finished so send the ready signal to eNB processing
+        eNB_proc->RU_mask_tx = 0;
+        pthread_mutex_unlock(&eNB_proc->mutex_RU_tx);
+
+        pthread_mutex_lock( &L1_proc->mutex_RUs);
+        L1_proc->instance_cnt_RUs = 0;
+        // the thread can now be woken up
+        if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) {
+          LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n");
+          exit_fun( "ERROR pthread_cond_signal" );
+        }
+        pthread_mutex_unlock( &L1_proc->mutex_RUs );
+      }
     }
-    pthread_mutex_unlock( &proc->mutex_eNBs );
   }
   release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
   return 0;
@@ -1785,7 +1810,7 @@ static void* ru_thread( void* param ) {
 #endif
 
     // wakeup all eNB processes waiting for this RU
-    if (ru->num_eNB>0) wakeup_eNBs(ru);
+    if (ru->num_eNB>0) wakeup_L1s(ru);
     
 #ifndef PHY_TX_THREAD
     if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){
@@ -1963,7 +1988,7 @@ void* pre_scd_thread( void* param ){
 #ifdef PHY_TX_THREAD
 /*!
  * \brief The phy tx thread of eNB.
- * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \param param is a \ref L1_proc_t structure which contains the info what to process.
  * \returns a pointer to an int. The storage is not on the heap and must not be freed.
  */
 static void* eNB_thread_phy_tx( void* param ) {
@@ -1974,7 +1999,7 @@ static void* eNB_thread_phy_tx( void* param ) {
   RU_proc_t *proc = &ru->proc;
   PHY_VARS_eNB **eNB_list = ru->eNB_list;
 
-  eNB_rxtx_proc_t proc_rxtx;
+  L1_rxtx_proc_t L1_proc;
 
   // set default return value
   eNB_thread_phy_tx_status = 0;
@@ -1991,9 +2016,9 @@ static void* eNB_thread_phy_tx( void* param ) {
 
     LOG_D(PHY,"Running eNB phy tx procedures\n");
     if(ru->num_eNB == 1){
-       proc_rxtx.subframe_tx = proc->subframe_phy_tx;
-       proc_rxtx.frame_tx = proc->frame_phy_tx;
-       phy_procedures_eNB_TX(eNB_list[0], &proc_rxtx, 1);
+       L1_proc.subframe_tx = proc->subframe_phy_tx;
+       L1_proc.frame_tx = proc->frame_phy_tx;
+       phy_procedures_eNB_TX(eNB_list[0], &L1_proc, 1);
        phy_tx_txdataF_end = 1;
        if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0){
           LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx);
@@ -2125,8 +2150,6 @@ void init_RU_proc(RU_t *ru) {
   proc->frame_offset             = 0;
   proc->num_slaves               = 0;
   proc->frame_tx_unwrap          = 0;
-  proc->ru_rx_ready              = 0;
-  proc->ru_tx_ready              = 0;
 
   for (i=0;i<10;i++) proc->symbol_mask[i]=0;
   
@@ -2301,7 +2324,6 @@ void kill_RU_proc(RU_t *ru)
   pthread_mutex_unlock(&proc->mutex_synch);
 
   pthread_mutex_lock(&proc->mutex_eNBs);
-  proc->ru_tx_ready = 0;
   proc->instance_cnt_eNBs = 1;
   // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send
   // a broadcast to wake up both threads
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 99a402d441cef381b50bb154c58bc327ace22cd8..5dde1034a48343eb9da7eeaa1ea57df717d5510f 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -189,6 +189,8 @@ extern void print_opp_meas(void);
 extern void init_eNB_afterRU(void);
 
 int transmission_mode=1;
+int emulate_rf = 0;
+int numerology = 0;
 
 THREAD_STRUCT thread_struct;
 /* struct for ethernet specific parameters given in eNB conf file */