diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
index 37656de75527716462e60a62de7cf0cf32c2cbaa..3d79fd09863ece7498e6233d960515f96dd484c8 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf
@@ -228,6 +228,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 NETWORK_CONTROLLER :
 {
     FLEXRAN_ENABLED        = "no";
diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
index 01c1ca1428c5025cb37221914f84079403dfcc06..b4c20ba644513bfca3387ce63f2efc4cae237226 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf
@@ -228,6 +228,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 NETWORK_CONTROLLER :
 {
     FLEXRAN_ENABLED        = "no";
diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
index eb5822cb22fcb6f98a48cd3a1fbf406869e1be80..a6ac1f8c140cfcad9883d7190715aa915ec651df 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
@@ -228,6 +228,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 NETWORK_CONTROLLER :
 {
     FLEXRAN_ENABLED        = "no";
diff --git a/ci-scripts/conf_files/lte-basic-sim.conf b/ci-scripts/conf_files/lte-basic-sim.conf
index f0fab0bdcba24e59c043441a1b321c13825db24f..0b02e8f871738ae1c45cde192c1c82b20b5cf17e 100644
--- a/ci-scripts/conf_files/lte-basic-sim.conf
+++ b/ci-scripts/conf_files/lte-basic-sim.conf
@@ -229,6 +229,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_SINGLE_THREAD";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 NETWORK_CONTROLLER :
 {
     FLEXRAN_ENABLED        = "no";
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index a766bb82023df5caddfea8982a68a5812c8cca20..ded09053885c24497b5d4a22c76d94770dc53f28 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -57,8 +57,8 @@
 		     uint64_t runtime,
 		     uint64_t deadline,
 		     uint64_t period);*/
+extern WORKER_CONF_t get_thread_worker_conf(void);
 
-extern int codingw;
 
 void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
 {
@@ -615,8 +615,10 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
 		}
 	}
 
-    if(C >= 8 && get_nprocs()>=16 && codingw)//one main three worker
+    if(get_thread_worker_conf() == WORKER_ENABLE)
     {
+      if(C >= 8)//one main three worker
+      {
         encoding_return =
 		dlsch_encoding_2threads(eNB,
 				   a,
@@ -632,9 +634,9 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    te_wakeup_stats1,
                    i_stats,
                    3);
-    }
-    else if(C >= 6 && get_nprocs()>=8 && codingw)//one main two worker
-    {
+      }
+      else if(C >= 6)//one main two worker
+      {
         encoding_return =
 		dlsch_encoding_2threads(eNB,
 				   a,
@@ -650,9 +652,9 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    te_wakeup_stats1,
                    i_stats,
                    2);
-    }
-    else if(C >= 4 && get_nprocs()>=4 && codingw)//one main one worker
-    {
+      }
+      else if(C >= 4)//one main one worker
+      {
         encoding_return =
 		dlsch_encoding_2threads(eNB,
 				   a,
@@ -668,9 +670,23 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    te_wakeup_stats1,
                    i_stats,
                    1);
+      }
+      else
+      {
+		encoding_return =
+		dlsch_encoding(eNB,
+				   a,
+                   num_pdcch_symbols,
+                   dlsch,
+                   frame,
+                   subframe,
+                   rm_stats,
+                   te_stats,
+                   i_stats);
+      }
     }
-	else
-	{
+    else
+    {
 		encoding_return =
 		dlsch_encoding(eNB,
 				   a,
@@ -681,7 +697,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
                    rm_stats,
                    te_stats,
                    i_stats);
-	}
+    }
 	return encoding_return;
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 851bcfff5a88582da16401f394b45c106529b45c..046e456916a104bf5afc892142a9317807ac4e80 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -45,7 +45,7 @@
 #include "targets/RT/USER/rt_wrapper.h"
 #include "transport_proto.h"
 
-extern int codingw;
+extern WORKER_CONF_t get_thread_worker_conf(void);
 
 void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch)
 {
@@ -723,7 +723,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
 int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) 
 {
   int ret = 0;
-  /*if(codingw)
+  /*if(get_thread_worker_conf() == WORKER_ENABLE)
   {
     ret = ulsch_decoding_data_2thread(eNB,UE_id,harq_pid,llr8_flag);
   }
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index 03d83472f8b8c81a46ada530cf664c6e701a7990..9a735b038fedd588a06afe665824d02f68d47da0 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -862,7 +862,22 @@ typedef enum {
   RESYNCH=4
 } UE_MODE_t;
 
+/// Threading Parameter
+typedef enum {
+  PARALLEL_SINGLE_THREAD    =0,
+  PARALLEL_RU_L1_SPLIT      =1,
+  PARALLEL_RU_L1_TRX_SPLIT  =2
+}PARALLEL_CONF_t;
 
+typedef enum {
+  WORKER_DISABLE            =0,
+  WORKER_ENABLE             =1
+}WORKER_CONF_t;
+
+typedef struct THREAD_STRUCT_s {
+  PARALLEL_CONF_t  parallel_conf;
+  WORKER_CONF_t    worker_conf;
+} THREAD_STRUCT;
 
 typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t;
 
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index c58fffe0ef2ebe8fa890dbac762dcd4e9bb2a56f..f23485cad84e732ec2459da1ec7c005052b6b74e 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -270,7 +270,6 @@ typedef enum {
   REMOTE_IF4p5    =3,
   REMOTE_IF1pp    =4,
   MAX_RU_IF_TYPES =5
-  //EMULATE_RF      =6
 } RU_if_south_t;
 
 typedef struct RU_t_s{
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index a03ce34bcae135d452b54c53a7e5dbb79bf39049..3583c0f25eae1246f0f86760b79734700313067b 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -82,7 +82,30 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */
 int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
 int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
 
-int codingw = 0;
+char *parallel_config = NULL;
+char *worker_config = NULL;
+static THREAD_STRUCT thread_struct;
+void set_parallel_conf(char *parallel_conf)
+{
+  if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0)           thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0)        thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0)    thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
+  printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
+} 
+void set_worker_conf(char *worker_conf)
+{
+  if(strcmp(worker_conf,"WORKER_DISABLE")==0)                     thread_struct.worker_conf = WORKER_DISABLE;
+  else if(strcmp(worker_conf,"WORKER_ENABLE")==0)                 thread_struct.worker_conf = WORKER_ENABLE;
+  printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
+} 
+PARALLEL_CONF_t get_thread_parallel_conf(void)
+{
+  return thread_struct.parallel_conf;
+} 
+WORKER_CONF_t get_thread_worker_conf(void)
+{
+  return thread_struct.worker_conf;
+} 
 
 int emulate_rf = 0;
 
@@ -1041,6 +1064,8 @@ int main(int argc, char **argv)
       break;
     }
   }
+  set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT");
+  set_worker_conf("WORKER_ENABLE");
 
   if (transmission_mode>1) pa=dBm3;
   printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa);
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 3fcb01068548a1c2fab305b50385174ada689737..89c0d09b1da0639d95390642f8285a0568486500 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -97,7 +97,30 @@ nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU];
 nfapi_tx_request_t TX_req;
 Sched_Rsp_t sched_resp;
 
-int codingw = 0;
+char *parallel_config = NULL;
+char *worker_config = NULL;
+static THREAD_STRUCT thread_struct;
+void set_parallel_conf(char *parallel_conf)
+{
+  if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0)           thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0)        thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0)    thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
+  printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
+} 
+void set_worker_conf(char *worker_conf)
+{
+  if(strcmp(worker_conf,"WORKER_DISABLE")==0)                     thread_struct.worker_conf = WORKER_DISABLE;
+  else if(strcmp(worker_conf,"WORKER_ENABLE")==0)                 thread_struct.worker_conf = WORKER_ENABLE;
+  printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
+} 
+PARALLEL_CONF_t get_thread_parallel_conf(void)
+{
+  return thread_struct.parallel_conf;
+} 
+WORKER_CONF_t get_thread_worker_conf(void)
+{
+  return thread_struct.worker_conf;
+} 
 
 void
 fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu,
@@ -725,6 +748,8 @@ int main(int argc, char **argv)
       break;
     }
   }
+  set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT");
+  set_worker_conf("WORKER_ENABLE");
   RC.nb_L1_inst = 1;
   RC.nb_RU = 1;
 
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 1edc1886601e2d9e46f8581212710ae03c93615d..dd995a53a043c2fb4afda8844a84e12054cd5961 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -61,6 +61,10 @@
 #include "enb_paramdef.h"
 
 extern uint16_t sf_ahead;
+extern void set_parallel_conf(char* parallel_conf);
+extern void set_worker_conf(char* worker_conf);
+extern PARALLEL_CONF_t get_thread_parallel_conf(void);
+extern WORKER_CONF_t   get_thread_worker_conf(void);
 
 void RCconfig_flexran() {
   uint16_t i;
@@ -2303,6 +2307,44 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
   return 0;
 }
 
+int RCconfig_parallel(void)
+{
+  char *parallel_conf = NULL;
+  char *worker_conf   = NULL;
+  extern char *parallel_config;
+  extern char *worker_config;
+
+  paramdef_t ThreadParams[]  = THREAD_CONF_DESC;
+  paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0};
+  
+  config_getlist( &THREADParamList,NULL,0,NULL);
+
+  if(THREADParamList.numelt>0)
+  {
+    config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
+    parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr));
+  }
+  else
+  {
+    parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT");
+  }
+  if(THREADParamList.numelt>0)
+  {
+    config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL);
+    worker_conf   = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr));
+  }
+  else
+  {
+    worker_conf   = strdup("WORKER_ENABLE");
+  }
+
+
+  if(parallel_config == NULL) set_parallel_conf(parallel_conf);
+  if(worker_config == NULL)   set_worker_conf(worker_conf);
+
+  return 0;
+}
+
 void RCConfig(void) {
   paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
   paramlist_def_t L1ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
@@ -2337,4 +2379,5 @@ void RCConfig(void) {
   // Get num RU instances
   config_getlist( &RUParamList,NULL,0, NULL);
   RC.nb_RU     = RUParamList.numelt;
+  RCconfig_parallel();
 }
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 04edea1493b955f5840e7da84ead7099168bfc2b..9403362c4fa03fdf0e25e8a710a6fd00b70028a9 100755
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -879,3 +879,28 @@ typedef enum {
 #define MACRLC_SCHED_MODE_IDX                                  17
 #define MACRLC_PHY_TEST_IDX                                    18
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+/* thread configuration parameters section name */
+#define THREAD_CONFIG_STRING_THREAD_STRUCT                "THREAD_STRUCT"
+
+/* thread configuration parameters names   */
+#define THREAD_CONFIG_STRING_PARALLEL              "parallel_config"
+#define THREAD_CONFIG_STRING_WORKER                "worker_config"
+
+
+#define THREAD_PARALLEL_IDX          0
+#define THREAD_WORKER_IDX            1
+
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                                             thread configuration parameters                                                                 */
+/*   optname                                          helpstr   paramflags    XXXptr       defXXXval                                 type           numelt     */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define THREAD_CONF_DESC {  \
+{THREAD_CONFIG_STRING_PARALLEL,          CONFIG_HLP_PARALLEL,      0,       strptr:NULL,   defstrval:"PARALLEL_RU_L1_TRX_SPLIT",   TYPE_STRING,   0},          \
+{THREAD_CONFIG_STRING_WORKER,            CONFIG_HLP_WORKER,        0,       strptr:NULL,   defstrval:"WORKER_ENABLE",              TYPE_STRING,   0}           \
+}
+
+
+#define CONFIG_HLP_WORKER                          "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
+#define CONFIG_HLP_PARALLEL                        "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index 03def311723c157b227742d2e5f4e74b0cadf66d..81c418c12352ea83d87cbe1aedbf0941df37641b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -71,7 +71,7 @@ schedule_ue_spec_phy_test(
   uint16_t                       rnti      = 0x1235;
   uint32_t                       rb_alloc  = 0x1FFFFF;
   int32_t                        tpc       = 1;
-  int32_t                        mcs       = 10;
+  int32_t                        mcs       = 28;
   int32_t                        cqi       = 15;
   int32_t                        ndi       = (frameP*10+subframeP)/8;
   int32_t                        dai       = 0;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
index bec9c2c6ddc9c573a4a9a329d6f7a69c0a523588..2761fe5fdbed1ff753c32dfa5402b40325860c57 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
@@ -156,6 +156,15 @@ eNBs =
         ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
     log_config :
     {
       global_log_level                      ="debug";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
index 834b6cf044177eb27d4569c12b96ada46e68aa0c..56b3c37c0a62eee61c575d941556b232f30403b1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
@@ -156,6 +156,15 @@ eNBs =
         ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
     };
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
     log_config :
     {
       global_log_level                      ="debug";
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 6b3614f490bb35c4317c9a7d07c82fd3d965f429..f088eda84f39a093ce6640f363d0be013f709243 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
@@ -193,6 +193,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
      log_config :
      {
        global_log_level                      ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
index fb184549c54eb67ce7e63ca62a85c9cc09778b5c..3bd4b1275adcd38c2f7870e6475ce81a7790741b 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
@@ -235,6 +235,15 @@ NETWORK_CONTROLLER :
     FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
     FLEXRAN_AWAIT_RECONF   = "no";
 };
+
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
 /*
      log_config :
      {
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
index c6ace3b68fa396c9b87c5a357c0b250d20e108c7..a41912284663542ad4735b072a47ee70c3efd7ed 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
@@ -225,6 +225,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
      log_config :
      {
        global_log_level                      ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
index c2f10e20aebd768bfdb47271763d0c4f226ae8ba..e08b83d58a87d920e44639e2f4c2db6012be2e85 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
@@ -238,6 +238,15 @@ NETWORK_CONTROLLER :
     FLEXRAN_AWAIT_RECONF   = "no";
 };
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
      log_config :
      {
        global_log_level                      ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
index e46467598ee5f1a207562226e81864271fab827f..f0a3cb524a1f094aba901fa51d6d78679e60f5a1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
@@ -192,6 +192,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
      log_config :
      {
        global_log_level                      ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
index a6efe742834a27904e4b39d4a998b96b6a0209cb..039f0c39c1839aa35397ba9f233a1bce53ae99d7 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf
@@ -199,6 +199,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config = { 
       global_log_level                      ="info";
       global_log_verbosity                  ="medium";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
index fefb4b11def94013d1efc34ba79c617f0e03aead..8f6aac632b4b5b17f049dbfee8d61e8ef77dfcc3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
@@ -182,6 +182,15 @@ MACRLCs = (
         }  
 );
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
      log_config :
      {
        global_log_level                      ="debug";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
index cd21fb935e44f8529457a66448dcac1159976c44..f4ac5a9aa3b13ef63f846da88c01e6d624a522d1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
@@ -210,6 +210,15 @@ MACRLCs = (
         }  
 );
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config =
     {
       global_log_level                      ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
index 581012d7d315f1f8ba9c3e02b2edaa75006e7bc5..ea205e44d178d594670cd812c120108b1a145671 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
@@ -198,6 +198,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config = { 
       global_log_level                      ="info";
       global_log_verbosity                  ="medium";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
index 5f9f8c4d7b6a1321ef12112f59c76612f26230a5..a2e97648c9ec532b9a23d24acd856270dd3e50e7 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
@@ -197,6 +197,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config = { 
       global_log_level                      ="info";
       global_log_verbosity                  ="medium";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
index 41b322fb55865e6a519f31ecfc587a50c9acaf9a..ba2e7f1ada542e7df2d29af491890c7b30cf6e4c 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf
@@ -17,6 +17,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config = { 
       global_log_level                      ="info";
       global_log_verbosity                  ="medium";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf
index da1481ac7bc24260490a177884d91108bb5451c1..494086defdc827df902b90f7b5446bd38753f451 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.tdd.conf
@@ -18,6 +18,15 @@ RUs = (
     }
 );  
 
+THREAD_STRUCT = (
+  {
+    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
+    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+    worker_config      = "WORKER_ENABLE";
+  }
+);
+
 log_config = { 
       global_log_level                      ="info";
       global_log_verbosity                  ="medium";
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 8c6f6dd766881ef32dc8cd3a7b635dd67a293d28..91a3c2e479df6ba5d20c3582d10671c771f7ffc3 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -151,7 +151,8 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #endif
-extern int codingw;
+extern PARALLEL_CONF_t get_thread_parallel_conf(void);
+extern WORKER_CONF_t   get_thread_worker_conf(void);
 
 extern uint8_t nfapi_mode;
 extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
@@ -223,7 +224,7 @@ 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(!eNB->single_thread_flag && get_nprocs() >= 8){
+  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);
@@ -245,7 +246,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
   /* CONFLICT RESOLUTION: BEGIN */
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
   if(oai_exit) return(-1);
-  if(eNB->single_thread_flag || get_nprocs() <= 4){
+  if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){
 #ifndef PHY_TX_THREAD
     phy_procedures_eNB_TX(eNB, proc, 1);
 #endif
@@ -421,8 +422,8 @@ static void* eNB_thread_rxtx( void* param ) {
     }
     pthread_mutex_unlock( &proc->mutex_rxtx );
     if (nfapi_mode!=2){
-    	if(get_nprocs() >= 8)      wakeup_tx(eNB,eNB->proc.ru_proc);
-    	else
+    	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);
@@ -881,7 +882,7 @@ static void* process_stats_thread(void* param) {
 
 void init_eNB_proc(int inst) {
   
-  int i=0;
+  /*int i=0;*/
   int CC_id;
   PHY_VARS_eNB *eNB;
   eNB_proc_t *proc;
@@ -953,7 +954,7 @@ void init_eNB_proc(int inst) {
     //    attr_te     = &proc->attr_te; 
 #endif
 
-    if(get_nprocs() > 2 && codingw)
+    if(get_thread_worker_conf() == WORKER_ENABLE)
     {
       init_te_thread(eNB);
       init_td_thread(eNB);
@@ -962,7 +963,7 @@ void init_eNB_proc(int inst) {
 
     LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
 
-    if (eNB->single_thread_flag==0 && nfapi_mode!=2) {
+    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);
     }
@@ -970,13 +971,13 @@ void init_eNB_proc(int inst) {
 #if (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];
+    /*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);
 	
@@ -1029,7 +1030,7 @@ void kill_eNB_proc(int inst) {
     proc = &eNB->proc;
     proc_rxtx = &proc->proc_rxtx[0];
 
-    if(get_nprocs() > 2 && codingw) {
+    if(get_thread_worker_conf() == WORKER_ENABLE) {
       kill_td_thread(eNB);
       kill_te_thread(eNB);
     }
@@ -1323,8 +1324,8 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
 #endif
 
 
-      eNB->td                   = ulsch_decoding_data_all;//(get_nprocs()<=4) ? ulsch_decoding_data : ulsch_decoding_data_2thread;
-      eNB->te                   = dlsch_encoding_all;//(get_nprocs()<=4) ? dlsch_encoding : dlsch_encoding_2threads;
+      eNB->td                   = ulsch_decoding_data_all;
+      eNB->te                   = dlsch_encoding_all;
 
       
       LOG_I(PHY,"Registering with MAC interface module\n");
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index d20b614ad79d4332bc10915d270106bc67c3340b..8ee2cb04f609e50c859778d5b6663c0b9623e9c5 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -119,10 +119,10 @@ static int DEFENBS[] = {0};
 extern volatile int                    oai_exit;
 extern int emulate_rf;
 extern int numerology;
-extern int fepw;
-extern int single_thread_flag;
 extern clock_source_t clock_source;
 
+extern PARALLEL_CONF_t get_thread_parallel_conf(void);
+extern WORKER_CONF_t   get_thread_worker_conf(void);
 extern void  phy_init_RU(RU_t*);
 extern void  phy_free_RU(RU_t*);
 
@@ -1257,7 +1257,7 @@ void wakeup_eNBs(RU_t *ru) {
   LOG_D(PHY,"wakeup_eNBs (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_nprocs() <= 4 || single_thread_flag)) {
+  if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
     // call eNB function directly
   
     char string[20];
@@ -1782,7 +1782,7 @@ static void* ru_thread( void* param ) {
     if (ru->num_eNB>0) wakeup_eNBs(ru);
     
 #ifndef PHY_TX_THREAD
-    if(get_nprocs() <= 4 || ru->num_eNB==0 || single_thread_flag){
+    if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){
       // do TX front-end processing if needed (precoding and/or IDFTs)
       if (ru->feptx_prec) ru->feptx_prec(ru);
       
@@ -2195,7 +2195,7 @@ void init_RU_proc(RU_t *ru) {
   if(emulate_rf)
     pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
 
-  if (!single_thread_flag && get_nprocs() > 4)
+  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
     pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru );
 
   if (ru->function == NGFI_RRU_IF4p5) {
@@ -2222,7 +2222,7 @@ void init_RU_proc(RU_t *ru) {
     pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
   }
 
-  if (get_nprocs()> 2 && fepw) { 
+  if (get_thread_worker_conf() == WORKER_ENABLE) { 
     init_fep_thread(ru,NULL); 
     init_feptx_thread(ru,NULL);
   } 
@@ -2260,7 +2260,7 @@ void kill_RU_proc(RU_t *ru)
   pthread_cond_destroy( &proc->cond_rf_tx);
 #endif
 
-  if (get_nprocs() > 2 && fepw) {
+  if (get_thread_worker_conf() == WORKER_ENABLE) {
       LOG_D(PHY, "killing FEP thread\n"); 
       kill_fep_thread(ru);
       LOG_D(PHY, "killing FEP TX thread\n"); 
@@ -2309,7 +2309,7 @@ void kill_RU_proc(RU_t *ru)
 
   LOG_D(PHY, "Joining pthread_FH\n");
   pthread_join(proc->pthread_FH, NULL);
-  if (!single_thread_flag && get_nprocs() > 4) {
+  if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
     LOG_D(PHY, "Joining pthread_FHTX\n");
     pthread_join(proc->pthread_FH1, NULL);
   }
@@ -2583,8 +2583,8 @@ void set_function_spec_param(RU_t *ru)
       ru->fh_north_out          = fh_if4p5_north_out;       // send_IF4p5 on reception
       ru->fh_south_out          = tx_rf;                    // send output to RF
       ru->fh_north_asynch_in    = fh_if4p5_north_asynch_in; // TX packets come asynchronously
-      ru->feprx                 = (get_nprocs()<=2 || !fepw) ? fep_full :ru_fep_full_2thread;                 // RX DFTs
-      ru->feptx_ofdm            = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread;               // this is fep with idft only (no precoding in RRU)
+      ru->feprx                 = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread;                 // RX DFTs
+      ru->feptx_ofdm            = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread;               // this is fep with idft only (no precoding in RRU)
       ru->feptx_prec            = NULL;
       ru->start_if              = start_if;                 // need to start the if interface for if4p5
       ru->ifdevice.host_type    = RRU_HOST;
@@ -2605,8 +2605,8 @@ void set_function_spec_param(RU_t *ru)
     }
     else if (ru->function == eNodeB_3GPP) {
       ru->do_prach             = 0;                       // no prach processing in RU
-      ru->feprx                = (get_nprocs()<=2 || !fepw) ? fep_full : ru_fep_full_2thread;                // RX DFTs
-      ru->feptx_ofdm           = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread;              // this is fep with idft and precoding
+      ru->feprx                = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread;                // RX DFTs
+      ru->feptx_ofdm           = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread;              // this is fep with idft and precoding
       ru->feptx_prec           = feptx_prec;              // this is fep with idft and precoding
       ru->fh_north_in          = NULL;                    // no incoming fronthaul from north
       ru->fh_north_out         = NULL;                    // no outgoing fronthaul to north
@@ -2634,9 +2634,9 @@ void set_function_spec_param(RU_t *ru)
 
   case REMOTE_IF5: // the remote unit is IF5 RRU
     ru->do_prach               = 0;
-    ru->feprx                  = (get_nprocs()<=2 || !fepw) ? fep_full : fep_full;                   // this is frequency-shift + DFTs
+    ru->feprx                  = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full;                   // this is frequency-shift + DFTs
     ru->feptx_prec             = feptx_prec;                 // need to do transmit Precoding + IDFTs
-    ru->feptx_ofdm             = (get_nprocs()<=2 || !fepw) ? feptx_ofdm : feptx_ofdm_2thread;                 // need to do transmit Precoding + IDFTs
+    ru->feptx_ofdm             = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread;                 // need to do transmit Precoding + IDFTs
     if (ru->if_timing == synch_to_other) {
       ru->fh_south_in          = fh_slave_south_in;                  // synchronize to master
       ru->fh_south_out         = fh_if5_mobipass_south_out;          // use send_IF5 for mobipass
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 6c20e3bf0eabfec55659c9cb7736002df2add8e7..9a93bc4cbc90785799792171c0c9bd12d07d70d0 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -219,8 +219,31 @@ extern void init_eNB_afterRU(void);
 int transmission_mode=1;
 int emulate_rf = 0;
 int numerology = 0;
-int codingw = 0;
-int fepw = 0;
+char *parallel_config = NULL;
+char *worker_config = NULL;
+
+static THREAD_STRUCT thread_struct;
+void set_parallel_conf(char *parallel_conf)
+{
+  if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0)           thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0)        thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0)    thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
+  printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
+} 
+void set_worker_conf(char *worker_conf)
+{
+  if(strcmp(worker_conf,"WORKER_DISABLE")==0)                     thread_struct.worker_conf = WORKER_DISABLE;
+  else if(strcmp(worker_conf,"WORKER_ENABLE")==0)                 thread_struct.worker_conf = WORKER_ENABLE;
+  printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
+} 
+PARALLEL_CONF_t get_thread_parallel_conf(void)
+{
+  return thread_struct.parallel_conf;
+} 
+WORKER_CONF_t get_thread_worker_conf(void)
+{
+  return thread_struct.worker_conf;
+} 
 
 
 
@@ -554,6 +577,8 @@ static void get_options(unsigned int *start_msc) {
          RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0;
       }
    }
+  if(parallel_config != NULL) set_parallel_conf(parallel_config);
+  if(worker_config != NULL)   set_worker_conf(worker_config);
 }
 
 
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index b421181f37ab1ebfb9efaf06c07af0d4aa5ff79c..2b087e5456b129f0f7468065de22b851d56fc2b8 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -92,9 +92,9 @@
 #define CONFIG_HLP_TNOFORK       "to ease debugging with gdb\n"
 
 #define CONFIG_HLP_NUMEROLOGY    "adding numerology for 5G\n"
-#define CONFIG_HLP_CODINGW       "coding worker thread enable(disable by defult)\n"
-#define CONFIG_HLP_FEPW          "FEP worker thread enabled(disable by defult)\n"
 #define CONFIG_HLP_EMULATE_RF    "Emulated RF enabled(disable by defult)\n"
+#define CONFIG_HLP_PARALLEL_CMD  "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
+#define CONFIG_HLP_WORKER_CMD    "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
 
 #define CONFIG_HLP_DISABLNBIOT   "disable nb-iot, even if defined in config\n"
 
@@ -186,9 +186,9 @@
 {"s" ,                      CONFIG_HLP_SNR,         0,                      iptr:&snr_dB,                       defintval:25,                   TYPE_INT,       0},                     \
 {"numerology" ,             CONFIG_HLP_NUMEROLOGY,  PARAMFLAG_BOOL,         iptr:&numerology,                   defintval:0,                    TYPE_INT,       0},                     \
 {"emulate-rf" ,             CONFIG_HLP_EMULATE_RF,  PARAMFLAG_BOOL,         iptr:&emulate_rf,                   defintval:0,                    TYPE_INT,       0},                     \
-{"codingw" ,                CONFIG_HLP_CODINGW,     PARAMFLAG_BOOL,         iptr:&codingw,                      defintval:0,                    TYPE_INT,       0},                     \
-{"fepw" ,                   CONFIG_HLP_FEPW,        PARAMFLAG_BOOL,         iptr:&fepw,                         defintval:0,                    TYPE_INT,       0},                     \
-{"nbiot-disable",           CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL,         iptr:&nonbiotflag,			defintval:0,			TYPE_INT,	0} \
+{"parallel-config",         CONFIG_HLP_PARALLEL_CMD,0,                      strptr:(char **)&parallel_config,   defstrval:NULL,                 TYPE_STRING,    0},                     \
+{"worker-config",           CONFIG_HLP_WORKER_CMD,  0,                      strptr:(char **)&worker_config,     defstrval:NULL,                 TYPE_STRING,    0},                     \
+{"nbiot-disable",           CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL,         iptr:&nonbiotflag,			defintval:0,                    TYPE_INT,       0}                      \
 }
 
 #define CONFIG_HLP_FLOG          "Enable online log \n"
@@ -279,6 +279,10 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t UE_id,
                           uint8_t abstraction_flag);
 void init_eNB_afterRU(void);
+PARALLEL_CONF_t get_thread_parallel_conf(void);
+WORKER_CONF_t   get_thread_worker_conf(void);
+void set_parallel_conf(char *parallel_conf);
+void set_worker_conf(char *worker_conf);
 
 extern int stop_L1L2(module_id_t enb_id);
 extern int restart_L1L2(module_id_t enb_id);
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 2efcb496ac1ba8d399971bea9ff8486715885284..c52fe130a1ed84fe80956cd593012e64f1e93a43 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -220,8 +220,31 @@ int transmission_mode=1;
 
 int emulate_rf = 0;
 int numerology = 0;
-int codingw = 0;
-int fepw = 0;
+char *parallel_config = NULL;
+char *worker_config = NULL;
+
+static THREAD_STRUCT thread_struct;
+void set_parallel_conf(char *parallel_conf)
+{
+  if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0)           thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0)        thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
+  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0)    thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
+  printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
+} 
+void set_worker_conf(char *worker_conf)
+{
+  if(strcmp(worker_conf,"WORKER_DISABLE")==0)                     thread_struct.worker_conf = WORKER_DISABLE;
+  else if(strcmp(worker_conf,"WORKER_ENABLE")==0)                 thread_struct.worker_conf = WORKER_ENABLE;
+  printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
+} 
+PARALLEL_CONF_t get_thread_parallel_conf(void)
+{
+  return thread_struct.parallel_conf;
+} 
+WORKER_CONF_t get_thread_worker_conf(void)
+{
+  return thread_struct.worker_conf;
+}  
 
 /* struct for ethernet specific parameters given in eNB conf file */
 eth_params_t *eth_params;
@@ -583,6 +606,8 @@ static void get_options(unsigned int *start_msc) {
     if(nfapi_mode!=3)
     	uecap_xer_in=1;
 	} *//* UE with config file  */
+  if(parallel_config != NULL) set_parallel_conf(parallel_config);
+  if(worker_config != NULL)   set_worker_conf(worker_config);
 }
 
 
@@ -800,6 +825,8 @@ int main( int argc, char **argv )
   for (int i=0;i<MAX_NUM_CCs;i++) tx_max_power[i]=23; 
   get_options (&start_msc);
 
+printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker config [%d] \n", get_thread_parallel_conf(), get_thread_worker_conf());
+
 
   printf("Running with %d UE instances\n",NB_UE_INST);
   if (NB_UE_INST > 1 && simL1flag != 1) {