diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index a344cb6a7f8ac30f8210104a5025b4a4d0348eeb..b15b5bfcbce60ee193a752a3aba071f79a43e4ba 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
         <testCase id="090102">
                 <class>Initialize_OAI_UE</class>
                 <desc>Initialize NR UE USRP</desc>
-		<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .</Initialize_OAI_UE_args>
+		<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75  --rrc_config_path .</Initialize_OAI_UE_args>
 		<air_interface>NR</air_interface>
         </testCase>
 
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
index 9e5e0a2bac25951101b2d58dcb8462e1475e787c..54b957473dcb04272b0c0937f411810e68d2802b 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml
@@ -52,7 +52,7 @@
         <testCase id="090104">
                 <class>Initialize_OAI_UE</class>
                 <desc>Initialize NR UE USRP</desc>
-		<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .</Initialize_OAI_UE_args>
+		<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75  --rrc_config_path .</Initialize_OAI_UE_args>
 		<air_interface>NR</air_interface>
         </testCase>
 
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 0b9d9250171303ff90e010b54bcdd66f6873dfd4..39d1c312739e05dee01ddcd2a82bb9864627223a 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -3232,6 +3232,7 @@ add_executable(nr_dlschsim
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/utils.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
@@ -3246,6 +3247,7 @@ add_executable(nr_pbchsim
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/utils.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
@@ -3262,6 +3264,7 @@ add_executable(nr_pucchsim
   ${OPENAIR_DIR}/common/utils/nr/nr_common.c
   ${OPENAIR_DIR}/common/utils/system.c
   ${OPENAIR_DIR}/common/utils/utils.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
@@ -3280,6 +3283,7 @@ add_executable(nr_dlsim
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${NFAPI_USER_DIR}/nfapi.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES}
@@ -3299,6 +3303,7 @@ add_executable(nr_prachsim
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${NFAPI_USER_DIR}/nfapi.c
+  ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
   ${UTIL_SRC}
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES})
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 55dea68896260a5fb351390683479ea2bcf21018..d893708a8b5327d6af0fdd72852c6d374eb832d4 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -148,6 +148,7 @@ extern "C" {
 #define DEBUG_SECURITY     (1<<11)
 #define DEBUG_NAS          (1<<12)
 #define DEBUG_RLC          (1<<13)
+#define DEBUG_DLSCH_DECOD  (1<<14)
 #define UE_TIMING          (1<<20)
 
 
@@ -166,6 +167,7 @@ extern "C" {
     {"SECURITY",    DEBUG_SECURITY},\
     {"NAS",         DEBUG_NAS},\
     {"RLC",         DEBUG_RLC},\
+    {"DLSCH_DECOD", DEBUG_DLSCH_DECOD},\
     {"UE_TIMING",   UE_TIMING},\
     {NULL,-1}\
   }
diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c
index e1446f15d71a70d374851ba9cfa5f4707590c58b..77729ae7a7ae187feee5223d5bd3bc6a50657212 100644
--- a/common/utils/threadPool/thread-pool.c
+++ b/common/utils/threadPool/thread-pool.c
@@ -92,7 +92,7 @@ void *one_thread(void *arg) {
   } while (true);
 }
 
-void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
+void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name) {
   memset(pool,0,sizeof(*pool));
   char *measr=getenv("threadPoolMeasurements");
   pool->measurePerf=performanceMeas;
@@ -116,6 +116,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
   pool->restrictRNTI=false;
   curptr=strtok_r(parms_cpy,",",&saveptr);
   struct one_thread * ptr;
+  char *tname = (name == NULL ? "Tpool" : name);
   while ( curptr!=NULL ) {
     int c=toupper(curptr[0]);
 
@@ -129,7 +130,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
         break;
 
       default:
-	ptr=pool->allthreads;
+        ptr=pool->allthreads;
         pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
         pool->allthreads->next=ptr;
         printf("create a thread for core %d\n", atoi(curptr));
@@ -138,7 +139,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
         pool->allthreads->pool=pool;
         //Configure the thread scheduler policy for Linux
         // set the thread name for debugging
-        sprintf(pool->allthreads->name,"Tpool_%d",pool->allthreads->coreID);
+        sprintf(pool->allthreads->name,"%s%d_%d",tname,pool->nbThreads,pool->allthreads->coreID);
         threadCreate(&pool->allthreads->threadID, one_thread, (void *)pool->allthreads,
                      pool->allthreads->name, pool->allthreads->coreID, OAI_PRIORITY_RT);
         pool->nbThreads++;
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index 0ed8715811e1e7345d0600e7b332a176ff20a9d5..5db1a5e34e6ca58a1b439977b26c9d1267ec867c 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -45,7 +45,7 @@
 #define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
 #define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
 #define condsignal(signal)    AssertFatal(pthread_cond_broadcast(&signal)==0,"");
-
+#define tpool_nbthreads(tpool)   (tpool.nbThreads)
 typedef struct notifiedFIFO_elt_s {
   struct notifiedFIFO_elt_s *next;
   uint64_t key; //To filter out elements
@@ -294,6 +294,6 @@ static inline int abortTpool(tpool_t *t, uint64_t key) {
   mutexunlock(nf->lockF);
   return nbRemoved;
 }
-void initTpool(char *params,tpool_t *pool, bool performanceMeas);
-
+void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name);
+#define  initTpool(PARAMPTR,TPOOLPTR, MEASURFLAG) initNamedTpool(PARAMPTR,TPOOLPTR, MEASURFLAG, NULL)
 #endif
diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md
index 4db3cd6ad17ed93bb9df8d9201b58c10dc46a399..a087b989faddba2b8374721ea34d609d589444a7 100644
--- a/common/utils/threadPool/thread-pool.md
+++ b/common/utils/threadPool/thread-pool.md
@@ -112,13 +112,13 @@ No delete() call, same principle as not thread safe queues
 # Thread pools
 
 ## initialization
-The clients can create one or more thread pools with init_tpool()
+The clients can create one or more thread pools with `initTpool(char *params,tpool_t *pool, bool performanceMeas  )` or `initNamedTpool(char *params,tpool_t *pool, bool performanceMeas , char *name)`
 
 the params string structure: describes a list of cores, separated by "," that run a worker thread
 
 If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
 
-The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
+The threads are all Linux real time scheduler, their name is set automatically to `Tpool<thread index>_<core id>` if initTpool is used or to `<name><thread index>_<core id>` when initNamedTpool is used.
 
 ## adding jobs
 The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
@@ -132,11 +132,13 @@ A abort service abortTpool() allows to abort all jobs that match a key (see jobs
 Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
 
 ## API details
-Each thread pool (there can be several in the same process) should be initialized
+Each thread pool (there can be several in the same process) should be initialized once using one of the two API's:
 
-### initTpool(char *params,tpool_t *pool, bool performanceMeas) is to be called oncepool
+### initNamedTpool(char *params,tpool_t *pool, bool performanceMeas,char *name)
 
-the configuration parameter is a string, elements separated by ",":
+### initTpool(char *params,tpool_t *pool, bool performanceMeas)
+
+`params`: the configuration parameter is a string, elements separator is a comma ",". An element can be:
 
 * N: if a N is in the parameter list, no threads are created
     The purpose is to keep the same API in any case
@@ -151,9 +153,11 @@ example: "-1,-1,-1"
 as there is no core number -1, the thread pool is made of 3 floating threads
 be careful with fix allocation: it is hard to be more clever than Linux kernel
 
-pool is the memory you allocated before to store the thread pool internal state (same concept as above queues)
+`pool` is the memory you allocated before to store the thread pool internal state (same concept as above queues)
+
+`performanceMeas` is a flag to enable measurements (well described in documentation)
 
-performanceMeas is a flag to enable measurements (well described in documentation)
+`name` is used to build the thread names. 
 
 ### pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg)
 
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index fb757a9f47cab8e3ff6965276a1392e0ee0124b3..fe1fc64207a71522871ab4812a27956f65300dc4 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -300,87 +300,11 @@ void exit_function(const char *file, const char *function, const int line, const
 }
 
 
-void *l2l1_task(void *arg) {
-  MessageDef *message_p = NULL;
-  int         result;
-  itti_set_task_real_time(TASK_L2L1);
-  itti_mark_task_ready(TASK_L2L1);
-  /* Wait for the initialize message */
-  printf("Wait for the ITTI initialize message\n");
-
-  do {
-    if (message_p != NULL) {
-      result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
-      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-    }
-
-    itti_receive_msg (TASK_L2L1, &message_p);
-
-    switch (ITTI_MSG_ID(message_p)) {
-      case INITIALIZE_MESSAGE:
-        /* Start gNB thread */
-        LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
-        start_gNB = 1;
-        break;
-
-      case TERMINATE_MESSAGE:
-        printf("received terminate message\n");
-        oai_exit=1;
-        start_gNB = 0;
-        itti_exit_task ();
-        break;
-
-      default:
-        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
-        break;
-    }
-  } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
-
-  result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
-  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-  /* ???? no else but seems to be UE only ???
-    do {
-      // Wait for a message
-      itti_receive_msg (TASK_L2L1, &message_p);
-
-      switch (ITTI_MSG_ID(message_p)) {
-      case TERMINATE_MESSAGE:
-        oai_exit=1;
-        itti_exit_task ();
-        break;
-
-      case ACTIVATE_MESSAGE:
-        start_UE = 1;
-        break;
-
-      case DEACTIVATE_MESSAGE:
-        start_UE = 0;
-        break;
-
-      case MESSAGE_TEST:
-        LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
-        break;
-
-      default:
-        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
-        break;
-      }
-
-      result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
-      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-    } while(!oai_exit);
-  */
-  return NULL;
-}
 
 int create_gNB_tasks(uint32_t gnb_nb) {
   LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
   itti_wait_ready(1);
 
-  if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
-    LOG_E(PDCP, "Create task for L2L1 failed\n");
-    return -1;
-  }
 
   if (gnb_nb > 0) {
     /* Last task to create, others task must be ready before its start */
@@ -717,7 +641,6 @@ int stop_L1L2(module_id_t gnb_id) {
 
   /* these tasks need to pick up new configuration */
   terminate_task(TASK_RRC_ENB, gnb_id);
-  terminate_task(TASK_L2L1, gnb_id);
   LOG_I(GNB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id);
   kill_gNB_proc(gnb_id);
   LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id);
@@ -753,13 +676,6 @@ int restart_L1L2(module_id_t gnb_id) {
   rrc_enb_init();
   itti_mark_task_ready(TASK_RRC_ENB);
 
-  if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
-    LOG_E(PDCP, "Create task for L2L1 failed\n");
-    return -1;
-  } else {
-    LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
-  }
-
   /* pass a reconfiguration request which will configure everything down to
    * RC.eNB[i][j]->frame_parms, too */
   msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 8192546eb7cfc63e83ae744d3cc8b8e3c1a2630b..a4f7e7ab157596f73c67622ea2f3db93570d7a91 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -411,7 +411,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
 #else
     uint64_t a=rdtsc();
-    phy_procedures_nrUE_RX( UE, proc, 0, UE->mode);
+    phy_procedures_nrUE_RX( UE, proc, 0, UE->mode,get_nrUE_params()->nr_dlsch_parallel);
     LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_slot_rx, (rdtsc()-a)/3500);
     //printf(">>> nr_ue_pdcch_procedures ended\n");
 #endif
@@ -603,7 +603,7 @@ void *UE_thread(void *arg) {
 
   while (!oai_exit) {
     if (syncRunning) {
-      notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool);
+      notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
 
       if (res) {
         syncRunning=false;
@@ -629,7 +629,7 @@ void *UE_thread(void *arg) {
       syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
       syncMsg->UE=UE;
       memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
-      pushTpool(Tpool, Msg);
+      pushTpool(&(get_nrUE_params()->Tpool), Msg);
       trashed_frames=0;
       syncRunning=true;
       continue;
@@ -739,7 +739,7 @@ void *UE_thread(void *arg) {
     notifiedFIFO_elt_t *res;
 
     while (nbSlotProcessing >= RX_NB_TH) {
-      res=pullTpool(&nf, Tpool);
+      res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
       nbSlotProcessing--;
       processingData_t *tmp=(processingData_t *)res->msgData;
 
@@ -779,13 +779,13 @@ void *UE_thread(void *arg) {
 
     nbSlotProcessing++;
     msgToPush->key=slot_nr;
-    pushTpool(Tpool, msgToPush);
+    pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
 
     if (IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) {  //getenv("RFSIMULATOR")
       // FixMe: Wait previous thread is done, because race conditions seems too bad
       // in case of actual RF board, the overlap between threads mitigate the issue
       // We must receive one message, that proves the slot processing is done
-      res=pullTpool(&nf, Tpool);
+      res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
       nbSlotProcessing--;
       processingData_t *tmp=(processingData_t *)res->msgData;
 
@@ -841,11 +841,11 @@ void init_NR_UE_threads(int nb_inst) {
     LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
     threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
 
-#ifdef UE_DLSCH_PARALLELISATION
-    pthread_t dlsch0_threads;
-    threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
-#endif
-
+     if(get_nrUE_params()->nr_dlsch_parallel)
+     {
+       pthread_t dlsch0_threads;
+       threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
+     }
   }
 }
 
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 1d3288862dde71422c638a83624058b16f0cd50a..36bca40b1a77b8d01a70e4176bde35e309055233 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -43,6 +43,7 @@
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "SCHED/sched_common_vars.h"
 #include "PHY/MODULATION/modulation_vars.h"
+#include "PHY/NR_TRANSPORT/nr_dlsch.h"
 //#include "../../SIMU/USER/init_lte.h"
 
 #include "LAYER2/MAC/mac_vars.h"
@@ -81,6 +82,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
 #include "PHY/TOOLS/phy_scope_interface.h"
 #include "PHY/TOOLS/nr_phy_scope.h"
+#define NRUE_MAIN
 #include <executables/nr-uesoftmodem.h>
 #include "executables/softmodem-common.h"
 #include "executables/thread-common.h"
@@ -96,33 +98,23 @@ pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
 int config_sync_var=-1;
-tpool_t *Tpool;
-#ifdef UE_DLSCH_PARALLELISATION
-  tpool_t *Tpool_dl;
-#endif
+
+
 
 RAN_CONTEXT_t RC;
 volatile int             start_eNB = 0;
 volatile int             start_UE = 0;
 volatile int             oai_exit = 0;
 
-// Command line options
 
 extern int16_t  nr_dlsch_demod_shift;
 static int      tx_max_power[MAX_NUM_CCs] = {0};
 
 int      single_thread_flag = 1;
-int         threequarter_fs = 0;
-int         UE_scan_carrier = 0;
-int      UE_fo_compensation = 0;
-int UE_no_timing_correction = 0;
-int                 N_RB_DL = 0;
 int                 tddflag = 0;
 int                 vcdflag = 0;
-uint8_t       nb_antenna_tx = 1;
-uint8_t       nb_antenna_rx = 1;
+
 double          rx_gain_off = 0.0;
-uint32_t     timing_advance = 0;
 char             *usrp_args = NULL;
 char       *rrc_config_path = NULL;
 int               dumpframe = 0;
@@ -148,8 +140,7 @@ int16_t           node_synch_ref[MAX_NUM_CCs];
 int               otg_enabled;
 double            cpuf;
 
-runmode_t            mode = normal_txrx;
-int               UE_scan = 0;
+
 int          chain_offset = 0;
 int           card_offset = 0;
 uint64_t num_missed_slots = 0; // counter for the number of missed slots
@@ -209,74 +200,35 @@ void exit_function(const char *file, const char *function, const int line, const
   exit(1);
 }
 
-void *l2l1_task(void *arg) {
-  MessageDef *message_p = NULL;
-  int         result;
-  itti_set_task_real_time(TASK_L2L1);
-  itti_mark_task_ready(TASK_L2L1);
-
-  do {
-    // Wait for a message
-    itti_receive_msg (TASK_L2L1, &message_p);
-
-    switch (ITTI_MSG_ID(message_p)) {
-      case TERMINATE_MESSAGE:
-        oai_exit=1;
-        itti_exit_task ();
-        break;
-
-      case ACTIVATE_MESSAGE:
-        start_UE = 1;
-        break;
-
-      case DEACTIVATE_MESSAGE:
-        start_UE = 0;
-        break;
-
-      case MESSAGE_TEST:
-        LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
-        break;
-
-      default:
-        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
-        break;
-    }
-
-    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
-    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-  } while(!oai_exit);
+uint64_t get_nrUE_optmask(void) {
+  return nrUE_params.optmask;
+}
 
-  return NULL;
+uint64_t set_nrUE_optmask(uint64_t bitmask) {
+  nrUE_params.optmask = nrUE_params.optmask | bitmask;
+  return nrUE_params.optmask;
 }
 
+nrUE_params_t *get_nrUE_params(void) {
+  return &nrUE_params;
+}
+/* initialie thread pools used for NRUE processing paralleliation */ 
+void init_tpools(uint8_t nun_dlsch_threads) {
+  char *params=calloc(1,(RX_NB_TH*3)+1);
+  for (int i=0; i<RX_NB_TH; i++) {
+    memcpy(params+(i*3),"-1,",3);
+  }
+  initTpool(params, &(nrUE_params.Tpool), false);
+  free(params);
+  init_dlsch_tpool( nun_dlsch_threads);
+}
 static void get_options(void) {
 
-  char *loopfile=NULL;
-
-  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
-  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
-  paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC;
-  paramdef_t cmdline_ueparams[] = CMDLINE_NRUEPARAMS_DESC;
-  config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
-  config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
-
-  if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
-
-  if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
+  paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
+  int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
+  config_process_cmdline( cmdline_params,numparams,NULL);
 
-  if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
 
-  if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr)
-    if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
-
-  if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr)
-    if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0)  mode = no_L2_connect;
-
-  if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
-    if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
-
-  if ((cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0)
-    mode = rx_dump_frame;
 
   if (vcdflag > 0)
     ouput_vcd = 1;
@@ -288,10 +240,43 @@ static void get_options(void) {
     printf("%s\n",uecap_xer);
     uecap_xer_in=1;
   } /* UE with config file  */
+    init_tpools(nrUE_params.nr_dlsch_parallel);
 }
 
 // set PHY vars from command line
 void set_options(int CC_id, PHY_VARS_NR_UE *UE){
+  NR_DL_FRAME_PARMS *fp       = &UE->frame_parms;
+  paramdef_t cmdline_params[] = CMDLINE_NRUE_PHYPARAMS_DESC ;
+  int numparams               = sizeof(cmdline_params)/sizeof(paramdef_t);
+
+  UE->mode = normal_txrx;
+
+  config_process_cmdline( cmdline_params,numparams,NULL);
+
+  int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT);
+  if ( (cmdline_params[pindex].paramflags &  PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue;
+  
+  pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXMED_OPT);
+  if ( (cmdline_params[pindex].paramflags &  PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_med;
+
+  pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXBYP_OPT);              
+  if ( (cmdline_params[pindex].paramflags &  PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_byp;
+
+  pindex = config_paramidx_fromname(cmdline_params,numparams, DBGPRACH_OPT); 
+  if (cmdline_params[pindex].uptr)
+    if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = debug_prach;
+
+  pindex = config_paramidx_fromname(cmdline_params,numparams,NOL2CONNECT_OPT ); 
+  if (cmdline_params[pindex].uptr)
+    if ( *(cmdline_params[pindex].uptr) > 0)  UE->mode = no_L2_connect;
+
+  pindex = config_paramidx_fromname(cmdline_params,numparams,CALIBPRACH_OPT );
+  if (cmdline_params[pindex].uptr)
+    if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = calib_prach_tx;
+
+  pindex = config_paramidx_fromname(cmdline_params,numparams,DUMPFRAME_OPT );
+  if ((cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0)
+    UE->mode = rx_dump_frame;
 
   // Init power variables
   tx_max_power[CC_id] = tx_max_power[0];
@@ -299,35 +284,29 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
   tx_gain[0][CC_id]   = tx_gain[0][0];
 
   // Set UE variables
-  UE->UE_scan              = UE_scan;
-  UE->UE_scan_carrier      = UE_scan_carrier;
-  UE->UE_fo_compensation   = UE_fo_compensation;
-  UE->no_timing_correction = UE_no_timing_correction;
-  UE->mode                 = mode;
+
   UE->rx_total_gain_dB     = (int)rx_gain[CC_id][0] + rx_gain_off;
   UE->tx_total_gain_dB     = (int)tx_gain[CC_id][0];
   UE->tx_power_max_dBm     = tx_max_power[CC_id];
   UE->rf_map.card          = card_offset;
   UE->rf_map.chain         = CC_id + chain_offset;
-  UE->timing_advance       = timing_advance;
 
-  LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", mode, UE_fo_compensation, UE_scan, UE_scan_carrier, UE_no_timing_correction);
+
+  LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", 
+  	   UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction);
 
   // Set FP variables
-  NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
-  fp->nb_antennas_tx    = nb_antenna_tx;
-  fp->nb_antennas_rx    = nb_antenna_rx;
-  fp->threequarter_fs   = threequarter_fs;
+
+
+  
   if (tddflag){
     fp->frame_type = TDD;
     LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
   }
-  if (N_RB_DL){
-    fp->N_RB_DL = N_RB_DL;
-    LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL);
-  }
 
-  LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", nb_antenna_rx, nb_antenna_tx, threequarter_fs);
+  LOG_I(PHY, "Set UE N_RB_DL %d\n", fp->N_RB_DL);
+
+  LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
 
 }
 
@@ -496,23 +475,17 @@ int main( int argc, char **argv ) {
   // initialize logging
   logInit();
   // get options and fill parameters from configuration file
-  get_options(); //Command-line options
+
+  get_options (); //Command-line options specific for NRUE
+
   get_common_options(SOFTMODEM_5GUE_BIT );
+  CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
 #if T_TRACER
   T_Config_Init();
 #endif
   //randominit (0);
   set_taus_seed (0);
-  tpool_t pool;
-  Tpool = &pool;
-  char params[]="-1,-1";
-  initTpool(params, Tpool, false);
-#ifdef UE_DLSCH_PARALLELISATION
-  tpool_t pool_dl;
-  Tpool_dl = &pool_dl;
-  char params_dl[]="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
-  initTpool(params_dl, Tpool_dl, false);
-#endif
+
   cpuf=get_cpu_freq_GHz();
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
 
@@ -542,6 +515,7 @@ int main( int argc, char **argv ) {
 
   for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
+
     PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
     UE[CC_id] = PHY_vars_UE_g[0][CC_id];
     memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
@@ -579,7 +553,9 @@ int main( int argc, char **argv ) {
     load_softscope("nr",PHY_vars_UE_g[0][0]);
   }     
 
+  
   init_NR_UE_threads(1);
+  config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
   printf("UE threads created by %ld\n", gettid());
   
   // wait for end of program
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index b2d321ae293bb368558f4bdabbc411c54f1cd546..de5aa377fc6ef9ea0318ebd57a8355ca33c676d7 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -5,71 +5,76 @@
 #include "PHY/defs_nr_UE.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
 
+
+
+
+#define  CONFIG_HLP_DLSCH_PARA             "number of threads for dlsch processing 0 for no parallelization"
 /***************************************************************************************************************************************/
 /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
    when calling config_get or config_getlist functions                                                                                 */
 
+#define CALIBRX_OPT       "calib-ue-rx"
+#define CALIBRXMED_OPT    "calib-ue-rx-med"
+#define CALIBRXBYP_OPT    "calib-ue-rx-byp"
+#define DBGPRACH_OPT      "debug-ue-prach"
+#define NOL2CONNECT_OPT   "no-L2-connect"
+#define CALIBPRACH_OPT    "calib-prach-tx"
+#define DUMPFRAME_OPT     "ue-dump-frame"
 
 /*------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            command line parameters defining UE running mode                                              */
 /*   optname                     helpstr                paramflags                      XXXptr        defXXXval         type       numelt   */
 /*------------------------------------------------------------------------------------------------------------------------------------------*/
-#define CMDLINE_UEMODEPARAMS_DESC {  \
-    {"calib-ue-rx",              CONFIG_HLP_CALUER,     0,                iptr:&rx_input_level_dBm,   defintval:0,        TYPE_INT,   0},    \
-    {"calib-ue-rx-med",          CONFIG_HLP_CALUERM,    0,                iptr:&rx_input_level_dBm,   defintval:0,        TYPE_INT,   0},    \
-    {"calib-ue-rx-byp",          CONFIG_HLP_CALUERB,    0,                iptr:&rx_input_level_dBm,   defintval:0,        TYPE_INT,   0},    \
-    {"debug-ue-prach",           CONFIG_HLP_DBGUEPR,    PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
-    {"no-L2-connect",            CONFIG_HLP_NOL2CN,     PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
-    {"calib-prach-tx",           CONFIG_HLP_CALPRACH,   PARAMFLAG_BOOL,   uptr:NULL,                  defuintval:1,       TYPE_INT,   0},    \
-    {"loop-memory",              CONFIG_HLP_UELOOP,     0,                strptr:&loopfile,           defstrval:"iqs.in", TYPE_STRING,0},    \
-    {"ue-dump-frame",            CONFIG_HLP_DUMPFRAME,  PARAMFLAG_BOOL,   iptr:&dumpframe,            defintval:0,        TYPE_INT,   0},    \
-  }
-#define CMDLINE_CALIBUERX_IDX                   0
-#define CMDLINE_CALIBUERXMED_IDX                1
-#define CMDLINE_CALIBUERXBYP_IDX                2
-#define CMDLINE_DEBUGUEPRACH_IDX                3
-#define CMDLINE_NOL2CONNECT_IDX                 4
-#define CMDLINE_CALIBPRACHTX_IDX                5
-#define CMDLINE_MEMLOOP_IDX                     6
-#define CMDLINE_DUMPMEMORY_IDX                  7
-/*------------------------------------------------------------------------------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
-/*                                            command line parameters specific to UE                                                                       */
-/*   optname                     helpstr             paramflags                  XXXptr                      defXXXval              type          numelt   */
-/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define CMDLINE_NRUEPARAMS_DESC {  \
-    {"ue-rxgain",                CONFIG_HLP_UERXG,       0,              dblptr:&(rx_gain[0][0]),            defdblval:0,           TYPE_DOUBLE,   0},     \
-    {"ue-rxgain-off",            CONFIG_HLP_UERXGOFF,    0,              dblptr:&rx_gain_off,                defdblval:0,           TYPE_DOUBLE,   0},     \
-    {"ue-txgain",                CONFIG_HLP_UETXG,       0,              dblptr:&(tx_gain[0][0]),            defdblval:0,           TYPE_DOUBLE,   0},     \
-    {"ue-nb-ant-rx",             CONFIG_HLP_UENANTR,     0,              u8ptr:&nb_antenna_rx,               defuintval:1,          TYPE_UINT8,    0},     \
-    {"ue-nb-ant-tx",             CONFIG_HLP_UENANTT,     0,              u8ptr:&nb_antenna_tx,               defuintval:1,          TYPE_UINT8,    0},     \
-    {"ue-scan-carrier",          CONFIG_HLP_UESCAN,      PARAMFLAG_BOOL, iptr:&UE_scan_carrier,              defintval:0,           TYPE_INT,      0},     \
-    {"ue-fo-compensation",       CONFIG_HLP_UEFO,        PARAMFLAG_BOOL, iptr:&UE_fo_compensation,           defintval:0,           TYPE_INT,      0},     \
-    {"ue-max-power",             NULL,                   0,              iptr:&(tx_max_power[0]),            defintval:90,          TYPE_INT,      0},     \
-    {"r"  ,                      CONFIG_HLP_PRB,         0,              iptr:&(N_RB_DL),                    defintval:25,          TYPE_UINT,     0},     \
-    {"usrp-args",                CONFIG_HLP_USRP_ARGS,   0,              strptr:(char **)&usrp_args,         defstrval:"type=b200", TYPE_STRING,   0}      \
-  }
+    {"usrp-args",                CONFIG_HLP_USRP_ARGS,   0,               strptr:(char **)&usrp_args,         defstrval:"type=b200", TYPE_STRING,   0},    \
+    {"single-thread-disable",    CONFIG_HLP_NOSNGLT,     PARAMFLAG_BOOL,  iptr:&single_thread_flag,           defintval:1,           TYPE_INT,    0}, \
+    {"dlsch-parallel",           CONFIG_HLP_DLSCH_PARA,  0,               iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel,       defintval:0,           TYPE_UINT8,  0}, \
+    {"nr-dlsch-demod-shift",     CONFIG_HLP_DLSHIFT,     0,               iptr:(int32_t *)&nr_dlsch_demod_shift,    defintval:0,     TYPE_INT,    0}, \
+    {"V" ,                       CONFIG_HLP_VCD,         PARAMFLAG_BOOL,  iptr:&vcdflag,                            defintval:0,     TYPE_INT,    0}, \
+    {"rrc_config_path",          CONFIG_HLP_RRC_CFG_PATH,0,               strptr:(char **)&rrc_config_path,         defstrval:"./",  TYPE_STRING, 0} \
+}
+
 
-/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
-/*                                            command line parameters common to gNB and UE                                                            */
-/*   optname                helpstr                 paramflags      XXXptr                                 defXXXval              type         numelt */
-/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
-#define CMDLINE_PARAMS_DESC_UE {  \
-  {"single-thread-disable", CONFIG_HLP_NOSNGLT,     PARAMFLAG_BOOL, iptr:&single_thread_flag,              defintval:1,           TYPE_INT,    0}, \
-  {"nr-dlsch-demod-shift",  CONFIG_HLP_DLSHIFT,     0,              iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0,           TYPE_INT,    0}, \
-  {"A" ,                    CONFIG_HLP_TADV,        0,              uptr:&timing_advance,                  defintval:0,           TYPE_UINT,   0}, \
-  {"E" ,                    CONFIG_HLP_TQFS,        PARAMFLAG_BOOL, iptr:&threequarter_fs,                 defintval:0,           TYPE_INT,    0}, \
-  {"T" ,                    CONFIG_HLP_TDD,         PARAMFLAG_BOOL, iptr:&tddflag,                         defintval:0,           TYPE_INT,    0}, \
-  {"V" ,                    CONFIG_HLP_VCD,         PARAMFLAG_BOOL, iptr:&vcdflag,                         defintval:0,           TYPE_INT,    0}, \
-  {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0,        TYPE_INT,    0}, \
-  {"rrc_config_path",       CONFIG_HLP_RRC_CFG_PATH,0,              strptr:(char **)&rrc_config_path,      defstrval:"./",        TYPE_STRING, 0} \
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters defining UE running mode                                              */
+/*   optname                     helpstr                paramflags                      XXXptr        defXXXval         type       numelt   */
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_NRUE_PHYPARAMS_DESC {  \
+    { CALIBRX_OPT,               CONFIG_HLP_CALUER,     0,                iptr:&rx_input_level_dBm,           defintval:0,           TYPE_INT,   0},    \
+    { CALIBRXMED_OPT,            CONFIG_HLP_CALUERM,    0,                iptr:&rx_input_level_dBm,           defintval:0,           TYPE_INT,   0},    \
+    { CALIBRXBYP_OPT,            CONFIG_HLP_CALUERB,    0,                iptr:&rx_input_level_dBm,           defintval:0,           TYPE_INT,   0},    \
+    { DBGPRACH_OPT,              CONFIG_HLP_DBGUEPR,    PARAMFLAG_BOOL,   uptr:NULL,                          defuintval:1,          TYPE_INT,   0},    \
+    { NOL2CONNECT_OPT,           CONFIG_HLP_NOL2CN,     PARAMFLAG_BOOL,   uptr:NULL,                          defuintval:1,          TYPE_INT,   0},    \
+    {CALIBPRACH_OPT,             CONFIG_HLP_CALPRACH,   PARAMFLAG_BOOL,   uptr:NULL,                          defuintval:1,          TYPE_INT,   0},    \
+    { DUMPFRAME_OPT,             CONFIG_HLP_DUMPFRAME,  PARAMFLAG_BOOL,   iptr:&dumpframe,                    defintval:0,           TYPE_INT,   0},    \
+    {"ue-rxgain",                CONFIG_HLP_UERXG,       0,               dblptr:&(rx_gain[0][0]),            defdblval:0,           TYPE_DOUBLE,   0},     \
+    {"ue-rxgain-off",            CONFIG_HLP_UERXGOFF,    0,               dblptr:&rx_gain_off,                defdblval:0,           TYPE_DOUBLE,   0},     \
+    {"ue-txgain",                CONFIG_HLP_UETXG,       0,               dblptr:&(tx_gain[0][0]),            defdblval:0,           TYPE_DOUBLE,   0},     \
+    {"ue-nb-ant-rx",             CONFIG_HLP_UENANTR,     0,               u8ptr:&(fp->nb_antennas_rx),         defuintval:1,          TYPE_UINT8,    0},     \
+    {"ue-nb-ant-tx",             CONFIG_HLP_UENANTT,     0,               u8ptr:&(fp->nb_antennas_tx),         defuintval:1,          TYPE_UINT8,    0},     \
+    {"ue-scan-carrier",          CONFIG_HLP_UESCAN,      PARAMFLAG_BOOL,  iptr:&(UE->UE_scan_carrier),        defintval:0,           TYPE_INT,      0},     \
+    {"ue-fo-compensation",       CONFIG_HLP_UEFO,        PARAMFLAG_BOOL,  iptr:&(UE->UE_fo_compensation),     defintval:0,           TYPE_INT,      0},     \
+    {"ue-max-power",             NULL,                   0,               iptr:&(tx_max_power[0]),            defintval:90,          TYPE_INT,      0},     \
+    {"r"  ,                      CONFIG_HLP_PRB,         0,               iptr:&(fp->N_RB_DL),                defintval:25,          TYPE_UINT,     0},     \
+    {"A" ,                       CONFIG_HLP_TADV,        0,               iptr:&(UE->timing_advance),         defintval:0,           TYPE_INT,   0}, \
+    {"E" ,                       CONFIG_HLP_TQFS,        PARAMFLAG_BOOL,  u8ptr:&(fp->threequarter_fs),       defintval:0,           TYPE_UINT8,    0}, \
+    {"T" ,                       CONFIG_HLP_TDD,         PARAMFLAG_BOOL,  iptr:&tddflag,                            defintval:0,     TYPE_INT,    0}, \
+    {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0,         TYPE_INT,    0}, \
 }
 
-extern int T_port;
-extern int T_nowait;
-extern int T_dont_fork;
+
+typedef struct {
+  uint64_t       optmask;   //mask to store boolean config options
+  uint8_t        nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
+  tpool_t        Tpool;             // thread pool 
+} nrUE_params_t;
+extern uint64_t get_nrUE_optmask(void);
+extern uint64_t set_nrUE_optmask(uint64_t bitmask);
+extern nrUE_params_t *get_nrUE_params(void);
+
+#ifdef NRUE_MAIN
+nrUE_params_t nrUE_params;
+#endif
 
 // In nr-ue.c
 extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
@@ -80,6 +85,5 @@ extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 void *UE_thread(void *arg);
 void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag);
-extern tpool_t *Tpool;
-extern tpool_t *Tpool_dl;
+
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index 23ec75653186f82bdeed21d8804a3a6887749ea6..6af8f28eac15faab7a9b6c89f7273764100d5ed3 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -95,7 +95,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
 		      time_stats_t *dlsch_interleaving_stats,
 		      time_stats_t *dlsch_segmentation_stats);
 
-
+void init_dlsch_tpool(uint8_t nun_dlsch_threads);
 void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
 
 void dump_pdsch_stats(PHY_VARS_gNB *gNB);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 808b21b40a5a9c4b85a64faee3b58f59af714cce..1a5675ffd9dce8ad3058f294abe9751c35488dc2 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -44,7 +44,7 @@
 #include "executables/nr-uesoftmodem.h"
 #include "PHY/CODING/nrLDPC_extern.h"
 #include "LAYER2/NR_MAC_gNB/mac_proto.h"
-//#define DEBUG_DLSCH_DECODING
+
 //#define ENABLE_PHY_PAYLOAD_DEBUG 1
 
 //#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
@@ -56,7 +56,23 @@ notifiedFIFO_t freeBlocks_dl;
 notifiedFIFO_elt_t *msgToPush_dl;
 int nbDlProcessing =0;
 
+
+static  tpool_t pool_dl;
+
 //extern double cpuf;
+void init_dlsch_tpool(uint8_t num_dlsch_threads)
+{
+    if( num_dlsch_threads==0)
+    	return;
+
+  char *params=calloc(1,(num_dlsch_threads*3)+1);
+  for (int i=0; i<num_dlsch_threads; i++) {
+    memcpy(params+(i*3),"-1,",3);
+  }
+  initNamedTpool(params, &pool_dl, false,"dlsch");
+  free(params);
+}
+
 
 void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
 {
@@ -140,7 +156,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
     dlsch->max_ldpc_iterations = max_ldpc_iterations;
  
     for (i=0; i<Mdlharq; i++) {
-      //      printf("new_ue_dlsch: Harq process %d\n",i);
       dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
 
       if (dlsch->harq_processes[i]) {
@@ -188,7 +203,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
       return(dlsch);
   }
 
-  printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
+  LOG_I(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
   free_nr_ue_dlsch(&dlsch,N_RB_DL);
 
   return(NULL);
@@ -250,7 +265,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   t_nrLDPC_time_stats* p_procTime =&procTime ;
   
   if (!harq_process) {
-    printf("dlsch_decoding.c: NULL harq_process pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
     return(dlsch->max_ldpc_iterations + 1);
   }
   t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
@@ -290,12 +305,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];
 
   if (!dlsch_llr) {
-    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
     return(dlsch->max_ldpc_iterations + 1);
   }
 
   if (!frame_parms) {
-    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
     return(dlsch->max_ldpc_iterations + 1);
   }
 
@@ -391,12 +406,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                     &harq_process->F,
                     p_decParams->BG);
 
-#ifdef DEBUG_DLSCH_DECODING
-    if (!frame%100)
-      printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
-#endif
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
+       LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
   }
-
+  
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
 
   p_decParams->Z = harq_process->Z;
@@ -422,9 +435,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     return((1+dlsch->max_ldpc_iterations));
   }
 
-#ifdef DEBUG_DLSCH_DECODING
-  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
-#endif
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
+
 
   opp_enabled=1;
 
@@ -451,8 +464,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
 
-    //for (int i =0; i<16; i++)
-    //          printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
 
 #if UE_TIMING_TRACE
     stop_meas(dlsch_deinterleaving_stats);
@@ -506,29 +517,19 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 #endif
     }
 
-
-    //for (int i =0; i<16; i++)
-    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
-
     r_offset += E;
 
-#ifdef DEBUG_DLSCH_DECODING
-    if (r==0) {
-      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
-      write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
-    }
-
-    printf("decoder input(segment %u) :",r);
-    int i;
-    for (i=0;i<E;i++)
-      printf("%d : %d\n",i,harq_process->d[r][i]);
-    printf("\n");
-#endif
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+  {
+    LOG_I(PHY,"decoder input(segment %u) :",r);
+    for (int i=0;i<E;i++)
+     LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
+    LOG_D(PHY,"\n");
+  }
 
-    //    printf("Clearing c, %p\n",harq_process->c[r]);
     memset(harq_process->c[r],0,Kr_bytes);
 
-    //    printf("done\n");
+
     if (harq_process->C == 1){
     	if (A > 3824) 
     		crc_type = CRC24_A;
@@ -549,9 +550,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
       start_meas(dlsch_turbo_decoding_stats);
 #endif
 
-      //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_slot_rx,r,harq_process->C-1, A);
-
-      //printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
 
       //set first 2*Z_c bits to zeros
       memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
@@ -588,7 +586,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
         ret = no_iteration_ldpc;
       }
       else {
-        LOG_D(PHY,"CRC NOK\n\033[0m");
+        LOG_I(PHY,"CRC NOK\n\033[0m");
         ret = 1 + dlsch->max_ldpc_iterations;
       }
 
@@ -598,24 +596,17 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
         nb_error_decod++;
       }
 
-      //if (!nb_total_decod%10000){
-      //printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
-      //}
-      //else
-      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
-
       for (int m=0; m < Kr>>3; m ++)
       {
         harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
       }
 
-#ifdef DEBUG_DLSCH_DECODING
-      //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
-      for (int k=0;k<A>>3;k++)
-        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
-      printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
-      //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
-#endif
+      if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      	{
+        for (int k=0;k<A>>3;k++)
+          LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
+        LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
+        }
 
 
 #if UE_TIMING_TRACE
@@ -623,33 +614,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 #endif
     }
     
-    
-
-    /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
-                  harq_process->C,
-                  r,
-                  dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
-                  dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
-                  dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
-
 
     if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
-      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
+      LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
       err_flag = 1;
     }
   }
 
   if (err_flag == 1) {
-//#if UE_DEBUG_TRACE
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
+    LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
         phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-//#endif
+
     harq_process->harq_ack.ack = 0;
     harq_process->harq_ack.harq_id = harq_pid;
     harq_process->harq_ack.send_harq_status = 1;
     harq_process->errors[harq_process->round]++;
 
-    //    printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round);
     if (harq_process->round >= dlsch->Mlimit) {
       harq_process->status = SCH_IDLE;
       harq_process->round  = 0;
@@ -658,16 +638,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 
     if(is_crnti)
     {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+    LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
                phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
     }
 
     return((1 + dlsch->max_ldpc_iterations));
   } else {
-//#if UE_DEBUG_TRACE
+
     LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
 	  phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
-//#endif
 
     harq_process->status = SCH_IDLE;
     harq_process->round  = 0;
@@ -691,11 +670,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   Kr = harq_process->K;
   Kr_bytes = Kr>>3;
 
-  /*
-  printf("harq_pid %d\n",harq_pid);
-  printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
-  printf("C %d\n",harq_process->C);
-  */
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
 
@@ -706,30 +680,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
 	   Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
     offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
 
-#ifdef DEBUG_DLSCH_DECODING
-    printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
-    printf("copied %d bytes to b sequence (harq_pid %d)\n",
-              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
-              printf("b[0] = %x,c[%d] = %x\n",
-              harq_process->b[offset],
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      {
+      LOG_D(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
+      LOG_D(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
+             (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
+      LOG_D(PHY,"b[0] = %p,c[%d] = %p\n",
+              (void *)(uint64_t)(harq_process->b[offset]),
               harq_process->F>>3,
-              harq_process->c[r]);
-
-              /*printf ("Printing payload bytes:");
-                for (int i = 0; i < Kr_bytes; i++){
-                printf("%d : %d \n", i, harq_process->b[i]);
-                }*/
-#endif
-
-#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
-           if (frame%100 == 0){
-              LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
-              for (int i = 0; i <10 ; i++){ //Kr_bytes
-            	  LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
-              }
+              (void *)(uint64_t)(harq_process->c[r]) );
+      if (frame%100 == 0){
+          LOG_D (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
+          for (int i = 0; i <10 ; i++){ //Kr_bytes
+            LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]);
           }
-#endif
-
+        }
+      }
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
@@ -739,7 +705,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
   return(ret);
 }
 
-#ifdef UE_DLSCH_PARALLELISATION
+
 uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                                     UE_nr_rxtx_proc_t *proc,
                                     int eNB_id,
@@ -777,35 +743,29 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   t_nrLDPC_time_stats* p_procTime =&procTime ;
   int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
     if (!harq_process) {
-    printf("dlsch_decoding.c: NULL harq_process pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
     return(dlsch->max_ldpc_iterations);
   }
   t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
   uint8_t Nl=4;
   int16_t z [68*384];
   int8_t l [68*384];
-  //__m128i l;
-  //int16_t inv_d [68*384];
-  //int16_t *p_invd =&inv_d;
-  uint8_t kb, kc;
+  uint8_t kc;
   uint8_t Ilbrm = 1;
   uint32_t Tbslbrm = 950984;
   uint16_t nb_rb = 30;
   double Coderate = 0.0;
   uint8_t dmrs_type = harq_process->dmrsConfigType;
-  //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
-  //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
 
   uint8_t nb_re_dmrs;
-  if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
+  if (dmrs_type == NFAPI_NR_DMRS_TYPE1)
     nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
   else
     nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
 
-  uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); 
-
+  uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); 
+  
   uint32_t i,j;
-//  int nbDlProcessing =0;
 
   __m128i *pv = (__m128i*)&z;
   __m128i *pl = (__m128i*)&l;
@@ -815,14 +775,14 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
 
   if (!dlsch_llr) {
-    printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
     return(dlsch->max_ldpc_iterations);
   }
 
 
 
   if (!frame_parms) {
-    printf("dlsch_decoding.c: NULL frame_parms pointer\n");
+    LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
     return(dlsch->max_ldpc_iterations);
   }
 
@@ -865,14 +825,12 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 
   G = harq_process->G;
 
-  LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
+  LOG_I(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d  mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
 
   proc->decoder_main_available = 1;
   proc->decoder_thread_available = 0;
   proc->decoder_thread_available1 = 0;
-  //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);
 
-  //  printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
 
   if ((harq_process->R)<1024)
     Coderate = (float) (harq_process->R) /(float) 1024;
@@ -928,7 +886,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     
     p_decParams->Z = harq_process->Z;
 
-  //printf("coderate %f kc %d \n", Coderate, kc);
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
 
@@ -946,15 +903,15 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
     return((1+dlsch->max_ldpc_iterations));
   }
-#ifdef DEBUG_DLSCH_DECODING
-  printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
-#endif
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
+
 
   notifiedFIFO_elt_t *res_dl;
   opp_enabled=1;
   if (harq_process->C>1) {
 	for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
-	  if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
+	  if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
 	          pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
 	        }
 
@@ -976,7 +933,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 	  curMsg->proc.llr8_flag = llr8_flag;
 
 	  msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
-	  pushTpool(Tpool_dl, msgToPush_dl);
+	  pushTpool(&pool_dl, msgToPush_dl);
 
   /*Qm= harq_process->Qm;
     Nl=harq_process->Nl;
@@ -1020,10 +977,9 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                            harq_process->w[r],
                            dlsch_llr+r_offset);
 
-#ifdef DEBUG_DLSCH_DECODING
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
         for (int i =0; i<16; i++)
-              printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
-#endif
+              LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
 
 #if UE_TIMING_TRACE
     stop_meas(dlsch_deinterleaving_stats);
@@ -1033,8 +989,8 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     start_meas(dlsch_rate_unmatching_stats);
 #endif
 
-#ifdef DEBUG_DLSCH_DECODING
-    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
           harq_pid,r, G,
           Kr*3,
           harq_process->TBS,
@@ -1043,7 +999,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
           harq_process->Nl,
           harq_process->rvidx,
           harq_process->round);
-#endif
+ 
 
     // for tbslbrm calculation according to 5.4.2.1 of 38.212
     if (harq_process->Nl < Nl)
@@ -1075,35 +1031,28 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 #endif
     }
 
-    //for (int i =0; i<16; i++)
-    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
-
-    //r_offset += E;
-    //printf("main thread r_offset %d\n",r_offset);
  
-#ifdef DEBUG_DLSCH_DECODING   
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))   
     for (int i =0; i<16; i++)
-      printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
-#endif
+      LOG_I(PHY,"rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
+
 
-#ifdef DEBUG_DLSCH_DECODING
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) 
+    {
 
     if (r==0) {
-      write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
-      write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
+      LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0);
+      LOG_M("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
     }
 
-    printf("decoder input(segment %u) :",r);
+    LOG_D(PHY,"decoder input(segment %u) :",r);
     for (int i=0;i<(3*8*Kr_bytes);i++)
-      printf("%d : %d\n",i,harq_process->d[r][i]);
-    printf("\n");
-#endif
+      LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
+    LOG_D(PHY,"\n");
+   }
 
-
-    //    printf("Clearing c, %p\n",harq_process->c[r]);
     memset(harq_process->c[r],0,Kr_bytes);
 
-    //    printf("done\n");
     if (harq_process->C == 1){
       if (A > 3824)
     	crc_type = CRC24_A;
@@ -1129,7 +1078,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 #if UE_TIMING_TRACE
       start_meas(dlsch_turbo_decoding_stats);
 #endif
-      LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
+      LOG_I(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
 
       /*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
         inv_d[cnt] = (1)*harq_process->d[r][cnt];
@@ -1165,11 +1114,11 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
       }
 
       if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
-        printf("Segment %u CRC OK\n",r);
+        LOG_D(PHY,"Segment %u CRC OK\n",r);
         ret = 2;
       }
       else {
-        printf("CRC NOK\n");
+        LOG_I(PHY,"CRC NOK\n");
         ret = 1+dlsch->max_ldpc_iterations;
       }
 
@@ -1177,9 +1126,6 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
         printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
     }
 
-    //else
-      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
-
       for (int m=0; m < Kr>>3; m ++)
       {
         harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
@@ -1201,10 +1147,10 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     //printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
 
     //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
-#ifdef DEBUG_DLSCH_DECODING
-      for (int k=0;k<32;k++)
-        printf("output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
-#endif
+     if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+       for (int k=0;k<32;k++)
+         LOG_D(PHY,"output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
+
 
 #if UE_TIMING_TRACE
       stop_meas(dlsch_turbo_decoding_stats);
@@ -1213,40 +1159,36 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 
 
     if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
-      LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
+      LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
       err_flag = 1;
     }
   //} //loop r
 
   if (err_flag == 1) {
-#if UE_DEBUG_TRACE
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
         phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-#endif
     harq_process->harq_ack.ack = 0;
     harq_process->harq_ack.harq_id = harq_pid;
     harq_process->harq_ack.send_harq_status = 1;
     harq_process->errors[harq_process->round]++;
     harq_process->round++;
 
-
-    //    printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
     if (harq_process->round >= dlsch->Mlimit) {
       harq_process->status = SCH_IDLE;
       harq_process->round  = 0;
     }
     if(is_crnti)
     {
-    LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+    LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
                phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
     }
 
     return((1+dlsch->max_ldpc_iterations));
   } else {
-#if UE_DEBUG_TRACE
-      LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
+   if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+      LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
            phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
-#endif
 
     harq_process->status = SCH_IDLE;
     harq_process->round  = 0;
@@ -1300,15 +1242,16 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
       offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
 
-#ifdef DEBUG_DLSCH_DECODING
-      printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
-      printf("copied %d bytes to b sequence (harq_pid %d)\n",
-                (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
-                printf("b[0] = %x,c[%d] = %x\n",
-                harq_process->b[offset],
-                harq_process->F>>3,
-                harq_process->c[r]);
-#endif
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    {
+    LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
+    LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
+              (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
+     LOG_I(PHY,"b[0] = %p,c[%d] = %p\n",
+              (void *)(uint64_t)(harq_process->b[offset]),
+              harq_process->F>>3,
+               (void *)(uint64_t)(harq_process->c[r]));
+    }
   }
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
@@ -1319,15 +1262,14 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
 
   return(ret);
 }
-#endif
 
-#ifdef UE_DLSCH_PARALLELISATION
+
+
 void nr_dlsch_decoding_process(void *arg)
 {
 	nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
     UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
     PHY_VARS_NR_UE    *phy_vars_ue   = rxtxD->UE;
-    NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
     int llr8_flag1;
     int32_t no_iteration_ldpc,length_dec;
     t_nrLDPC_dec_params decParams;
@@ -1341,7 +1283,7 @@ void nr_dlsch_decoding_process(void *arg)
     //__m128i l;
     //int16_t inv_d [68*384];
     //int16_t *p_invd =&inv_d;
-    uint8_t kb, kc;
+    uint8_t  kc;
     uint8_t Ilbrm = 1;
     uint32_t Tbslbrm = 950984;
     uint16_t nb_rb = 30; //to update
@@ -1351,8 +1293,6 @@ void nr_dlsch_decoding_process(void *arg)
     uint16_t length_dmrs = 1;
 
     uint32_t i,j;
-    uint32_t k;
-
     __m128i *pv = (__m128i*)&z;
     __m128i *pl = (__m128i*)&l;
 
@@ -1369,8 +1309,10 @@ void nr_dlsch_decoding_process(void *arg)
 #endif
   uint32_t A,E;
   uint32_t G;
-  uint32_t ret,offset;
+
+  uint32_t ret;
   uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bits_F;
+
   uint8_t crc_type;
   uint8_t C,Cprime;
   uint8_t Qm;
@@ -1381,31 +1323,17 @@ void nr_dlsch_decoding_process(void *arg)
   int harq_pid              = proc->harq_pid;
   llr8_flag1                = proc->llr8_flag;
   int frame                 = proc->frame_rx;
-  int slot                  = proc->nr_slot_rx;
   r               	    = proc->num_seg;
 
   NR_UE_DLSCH_t *dlsch      = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0];
   NR_DL_UE_HARQ_t *harq_process  = dlsch->harq_processes[harq_pid];
   short *dlsch_llr        = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0];
-  //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag);
+
   p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
   nb_symb_sch = harq_process->nb_symbols;
-  printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
+  LOG_I(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
 
 
-  /*
-  if (nb_rb > frame_parms->N_RB_DL) {
-    printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
-    return(max_ldpc_iterations);
-    }*/
-
-  /*harq_pid = dlsch->current_harq_pid[proc->thread_id];
-  if (harq_pid >= 8) {
-    printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
-    return(max_ldpc_iterations);
-  }
-  */
-
   nb_rb = harq_process->nb_rb;
 
   harq_process->trials[harq_process->round]++;
@@ -1422,7 +1350,7 @@ void nr_dlsch_decoding_process(void *arg)
   harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
   G = harq_process->G;
 
-  LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
+  LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
 
   if ((harq_process->R)<1024)
     Coderate = (float) (harq_process->R) /(float) 1024;
@@ -1478,36 +1406,13 @@ void nr_dlsch_decoding_process(void *arg)
 
    // }
     
-    //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
+    LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
 
 
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
 
-  /*
-  else {
-    printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
-    return(max_ldpc_iterations);
-  }
-  */
   err_flag = 0;
-  //r_offset = 0;
-
-  /*
-  uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS;  //number of segments to be allocated
-
-  if (nb_rb != 273) {
-    a_segments = a_segments*nb_rb;
-    a_segments = a_segments/273 +1;
-  }  
-
-  if (harq_process->C > a_segments) {
-    LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
-    return((1+dlsch->max_ldpc_iterations));
-  }*/
-#ifdef DEBUG_DLSCH_DECODING
-  printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
-#endif
 
   opp_enabled=1;
   
@@ -1522,9 +1427,7 @@ void nr_dlsch_decoding_process(void *arg)
     r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
   else
     r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
-
-    //  printf("thread0 r_offset %d\n",r_offset);
-           
+          
   //for (r=(harq_process->C/2); r<harq_process->C; r++) {
      //    r=1; //(harq_process->C/2);
 
@@ -1544,10 +1447,10 @@ void nr_dlsch_decoding_process(void *arg)
                            harq_process->w[r],
                            dlsch_llr+r_offset);
 
-#ifdef DEBUG_DLSCH_DECODING
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
     for (int i =0; i<16; i++)
-              printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
-#endif
+              LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
+
 
 #if UE_TIMING_TRACE
     stop_meas(dlsch_deinterleaving_stats);
@@ -1557,8 +1460,8 @@ void nr_dlsch_decoding_process(void *arg)
     start_meas(dlsch_rate_unmatching_stats);
 #endif
 
-#ifdef DEBUG_DLSCH_DECODING
-    LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
+  if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
+    LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
           harq_pid,r, G,
           Kr*3,
           harq_process->TBS,
@@ -1567,7 +1470,7 @@ void nr_dlsch_decoding_process(void *arg)
           harq_process->Nl,
           harq_process->rvidx,
           harq_process->round);
-#endif
+
 
     if (Nl<4)
       Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
@@ -1598,25 +1501,14 @@ void nr_dlsch_decoding_process(void *arg)
 #endif
     }
 
-    //for (int i =0; i<16; i++)
-    //      printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
-
-    //r_offset += E;
-
-#ifdef DEBUG_DLSCH_DECODING
-    if (r==0) {
-              write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
-              write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
+    if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
+      LOG_D(PHY,"decoder input(segment %u) :",r);
+      for (int i=0;i<(3*8*Kr_bytes)+12;i++)
+        LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
+      LOG_D(PHY,"\n");
     }
 
-    printf("decoder input(segment %u) :",r);
-    int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
-      printf("%d : %d\n",i,harq_process->d[r][i]);
-      printf("\n");
-#endif
-
 
-    //    printf("Clearing c, %p\n",harq_process->c[r]);
     memset(harq_process->c[r],0,Kr_bytes);
 
     if (harq_process->C == 1){
@@ -1634,18 +1526,18 @@ void nr_dlsch_decoding_process(void *arg)
 
     if (err_flag == 0) {
 /*
-        LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
+        LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
                             Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
                             harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
 */
       if (llr8_flag1) {
-        AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
+        AssertFatal (Kr >= 256, "LDPC algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
             Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
       }
 #if UE_TIMING_TRACE
         start_meas(dlsch_turbo_decoding_stats);
 #endif
-//      LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
+//      LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
 /*
         for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
               inv_d[cnt] = (1)*harq_process->d[r][cnt];
@@ -1678,39 +1570,23 @@ void nr_dlsch_decoding_process(void *arg)
           ret = 2;
         }
         else {
-          LOG_D(PHY,"Segment %u CRC NOK\n",r);
+          LOG_I(PHY,"Segment %u CRC NOK\n",r);
           ret = 1+dlsch->max_ldpc_iterations;
         }
 
     if (no_iteration_ldpc > 10)
-      LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
-    //else
-      //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
+      LOG_I(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
+
 
     for (int m=0; m < Kr>>3; m ++)
                     {
                   harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
                     }
 
-            /*for (int u=0; u < Kr>>3; u ++)
-                            {
-                      ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
-                            }
-
-
-            printf("output unsigned ullrProcBuf \n");
+    if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))       
+      for (int k=0;k<2;k++)
+        LOG_D(PHY,"segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
 
-            for (int j=0; j < Kr>>3; j ++)
-                                    {
-
-                              printf(" %d \n", ullrProcBuf[j]);
-
-                                    }
-          printf(" \n");*/
-#ifdef DEBUG_DLSCH_DECODING       
-  for (int k=0;k<2;k++)
-      printf("segment 1 output decoder [%d] =  0x%02x \n", k, harq_process->c[r][k]);
-#endif 
     
 #if UE_TIMING_TRACE
       stop_meas(dlsch_turbo_decoding_stats);
@@ -1729,13 +1605,12 @@ void nr_dlsch_decoding_process(void *arg)
 
 void *dlsch_thread(void *arg) {
   //this thread should be over the processing thread to keep in real time
-  PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
   notifiedFIFO_t nf;
   initNotifiedFIFO(&nf);
   notifiedFIFO_elt_t *res_dl;
   initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
 
-  for (int i=0; i<RX_NB_TH_DL+1; i++){
+  for (int i=0; i<tpool_nbthreads(pool_dl)+1; i++){
     pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
                                   newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
 
@@ -1743,9 +1618,8 @@ void *dlsch_thread(void *arg) {
 
     notifiedFIFO_elt_t *res;
 
-    while (nbDlProcessing >= RX_NB_TH_DL) {
-      if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
-        nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
+    while (nbDlProcessing >= tpool_nbthreads(pool_dl)) {
+      if ( (res=tryPullTpool(&nf, &pool_dl)) != NULL ) {
         //nbDlProcessing--;
         pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
       }
@@ -1753,7 +1627,7 @@ void *dlsch_thread(void *arg) {
       usleep(200);
     }
     
-    res_dl=pullTpool(&nf, Tpool_dl);
+    res_dl=pullTpool(&nf, &pool_dl);
     nbDlProcessing--;
 	pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
     
@@ -1766,4 +1640,4 @@ void *dlsch_thread(void *arg) {
   return NULL;
 }
 
-#endif
+
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 78e34036a32c9dcda8aedfb8beac4096d58bbfa9..b11c163ae84cd4e12fce6586c3c6ec448dcb8d6c 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -25,8 +25,8 @@
 
 #include <stdlib.h>
 #include "nr_phy_scope.h"
-#include "executables/nr-softmodem-common.h"
 #include "executables/softmodem-common.h"
+#include "executables/nr-softmodem-common.h"
 #include <forms.h>
 
 #define TPUT_WINDOW_LENGTH 100
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index 6a3d2c02b3fb6b1be4666f4a975c2c517150126e..4888e887976fa19120ece007e2821dcde794f5a7 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -110,15 +110,17 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
 
 /*! \brief Scheduling for UE RX procedures in normal subframes.
-  @param ue       Pointer to UE variables on which to act
-  @param proc     Pointer to proc information
-  @param gNB_id   Local id of eNB on which to act
-  @param mode     calibration/debug mode
+  @param ue             Pointer to UE variables on which to act
+  @param proc           Pointer to proc information
+  @param gNB_id         Local id of eNB on which to act
+  @param mode           calibration/debug mode
+  @param dlsch_parallel use multithreaded dlsch processing
 */
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           runmode_t mode);
+                           runmode_t mode,
+                           uint8_t dlsch_parallel);
 
 int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
 
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 1e588b11039a17049b4ebd2652ef851b6f8d42f4..c0dbcc9c990245d1db7da3bf93942aa5361244be 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -50,6 +50,7 @@
 #include "SCHED/phy_procedures_emos.h"
 #endif
 #include "executables/softmodem-common.h"
+#include "executables/nr-uesoftmodem.h"
 #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
 
 //#define DEBUG_PHY_PROC
@@ -921,7 +922,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
        NR_UE_DLSCH_t *dlsch0,
        NR_UE_DLSCH_t *dlsch1,
        int *dlsch_errors,
-       runmode_t mode) {
+       runmode_t mode,
+       uint8_t dlsch_parallel) {
 
   if (dlsch0==NULL)
     AssertFatal(0,"dlsch0 should be defined at this level \n");
@@ -1052,8 +1054,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #endif
 
-#ifdef UE_DLSCH_PARALLELISATION
-		 ret = nr_dlsch_decoding_mthread(ue,
+  if( dlsch_parallel)
+    {
+    ret = nr_dlsch_decoding_mthread(ue,
 			   proc,
 			   eNB_id,
 			   pdsch_vars->llr[0],
@@ -1066,9 +1069,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 			   harq_pid,
 			   pdsch==PDSCH?1:0,
 			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
-		 LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret = %d\n", ret);
-#else
-      ret = nr_dlsch_decoding(ue,
+    LOG_T(PHY,"dlsch decoding is parallelized, ret = %d\n", ret);
+    }
+  else
+    {
+    ret = nr_dlsch_decoding(ue,
 			   proc,
 			   eNB_id,
 			   pdsch_vars->llr[0],
@@ -1081,9 +1086,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 			   harq_pid,
 			   pdsch==PDSCH?1:0,
 			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
-      LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d\n", ret);
-      //printf("start cW0 dlsch decoding\n");
-#endif
+      LOG_T(PHY,"Sequential dlsch decoding , ret = %d\n", ret);
+     }
+
 
 #if UE_TIMING_TRACE
       stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
@@ -1135,38 +1140,40 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
           start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
 #endif
 
-#ifdef UE_DLSCH_PARALLELISATION
-          ret1 = nr_dlsch_decoding_mthread(ue,
-                                           proc,
-                                           eNB_id,
-                                           pdsch_vars->llr[1],
-                                           &ue->frame_parms,
-                                           dlsch1,
-                                           dlsch1->harq_processes[harq_pid],
-                                           frame_rx,
-                                           nb_symb_sch,
-                                           nr_slot_rx,
-                                           harq_pid,
-                                           pdsch==PDSCH?1:0,
-                                           dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-          LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1);
-#else
-          ret1 = nr_dlsch_decoding(ue,
-                                   proc,
-                                   eNB_id,
-                                   pdsch_vars->llr[1],
-                                   &ue->frame_parms,
-                                   dlsch1,
-                                   dlsch1->harq_processes[harq_pid],
-                                   frame_rx,
-                                   nb_symb_sch,
-                                   nr_slot_rx,
-                                   harq_pid,
-                                   pdsch==PDSCH?1:0,//proc->decoder_switch,
-                                   dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-          LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1);
-          printf("start cw1 dlsch decoding\n");
-#endif
+  if(dlsch_parallel)
+    {
+    ret1 = nr_dlsch_decoding_mthread(ue,
+                                     proc,
+                                     eNB_id,
+                                     pdsch_vars->llr[1],
+                                     &ue->frame_parms,
+                                     dlsch1,
+                                     dlsch1->harq_processes[harq_pid],
+                                     frame_rx,
+                                     nb_symb_sch,
+				     nr_slot_rx,
+                                     harq_pid,
+                                     pdsch==PDSCH?1:0,
+                                     dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+          LOG_T(PHY,"CW dlsch decoding is parallelized, ret1 = %d\n", ret1);
+    }
+    else
+    {
+    ret1 = nr_dlsch_decoding(ue,
+			     proc,
+			     eNB_id,
+                             pdsch_vars->llr[1],
+                             &ue->frame_parms,
+                             dlsch1,
+                             dlsch1->harq_processes[harq_pid],
+                             frame_rx,
+                             nb_symb_sch,
+                             nr_slot_rx,
+                             harq_pid,
+                             pdsch==PDSCH?1:0,//proc->decoder_switch,
+                             dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+    LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1);
+    }
 
 #if UE_TIMING_TRACE
           stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
@@ -1700,8 +1707,10 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
-                           runmode_t mode)
-{
+                           runmode_t mode,
+                           uint8_t dlsch_parallel
+                           )
+{                                         
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int slot_pbch;
@@ -1899,7 +1908,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            ue->dlsch_SI[gNB_id],
                            NULL,
                            &ue->dlsch_SI_errors[gNB_id],
-                           mode);
+                           mode,
+                           dlsch_parallel);
 
     // deactivate dlsch once dlsch proc is done
     ue->dlsch_SI[gNB_id]->active = 0;
@@ -1924,7 +1934,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            ue->dlsch_p[gNB_id],
                            NULL,
                            &ue->dlsch_p_errors[gNB_id],
-                           mode);
+                           mode,
+                           dlsch_parallel);
 
     // deactivate dlsch once dlsch proc is done
     ue->dlsch_p[gNB_id]->active = 0;
@@ -1949,7 +1960,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            ue->dlsch_ra[gNB_id],
                            NULL,
                            &ue->dlsch_ra_errors[gNB_id],
-                           mode);
+                           mode,
+                           dlsch_parallel);
 
     // deactivate dlsch once dlsch proc is done
     ue->dlsch_ra[gNB_id]->active = 0;
@@ -1975,7 +1987,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 			   ue->dlsch[proc->thread_id][gNB_id][0],
 			   ue->dlsch[proc->thread_id][gNB_id][1],
 			   &ue->dlsch_errors[gNB_id],
-			   mode);
+			   mode,
+			   dlsch_parallel);
 
 
 #if UE_TIMING_TRACE
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 57923895d3470d855261b8b70eaca5e161266332..ffb6368b4bc3f892b034b92e1351a70ce37ce8de 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -270,7 +270,7 @@ int main(int argc, char **argv)
   uint16_t ptrsSymbPerSlot = 0;
   uint16_t rbSize = 106;
   uint8_t  mcsIndex = 9;
-
+  uint8_t  dlsch_threads = 0;
   if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
     exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
   }
@@ -281,7 +281,7 @@ int main(int argc, char **argv)
 
   FILE *scg_fd=NULL;
   
-  while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w:T:U:q")) != -1) {
+  while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) {
     switch (c) {
     case 'f':
       scg_fd = fopen(optarg,"r");
@@ -448,7 +448,9 @@ int main(int argc, char **argv)
     case 'b':
       g_rbSize = atoi(optarg);
       break;
-
+    case 'd':
+      dlsch_threads = atoi(optarg);
+      break;    
     case 'e':
       g_mcsIndex = atoi(optarg);
       break;
@@ -519,6 +521,7 @@ int main(int argc, char **argv)
       printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
       printf("-P Print DLSCH performances\n");
       printf("-w Write txdata to binary file (one frame)\n");
+      printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
       exit (-1);
       break;
     }
@@ -534,6 +537,7 @@ int main(int argc, char **argv)
   
   if (snr1set==0)
     snr1 = snr0+10;
+  init_dlsch_tpool(dlsch_threads);
 
 
   RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
@@ -987,7 +991,8 @@ int main(int argc, char **argv)
         phy_procedures_nrUE_RX(UE,
                                &UE_proc,
                                0,
-                               normal_txrx);
+                               normal_txrx,
+                               dlsch_threads);
         
         //printf("dlsim round %d ends\n",round);
         round++;
diff --git a/targets/COMMON/create_nr_tasks.h b/targets/COMMON/create_nr_tasks.h
index ca259a2b34a6cce96639ffa1ef2762511d73c3eb..23dd23e7db1ddab36c4bdeef5b459ca2dd46683a 100644
--- a/targets/COMMON/create_nr_tasks.h
+++ b/targets/COMMON/create_nr_tasks.h
@@ -22,8 +22,6 @@
 #ifndef CREATE_NR_TASKS_H_
 #define CREATE_NR_TASKS_H_
 
-/* External declaration of L2L1 task that depend on the target */
-extern void *l2l1_task(void *arg);
 
 int create_gNB_tasks(uint32_t gnb_nb);
 
diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h
index 843897cefb4a73b0f52fc74e7b2fc80ddeb0790d..e3f871964a3f6ae735698e876979d30ecd7d0933 100644
--- a/targets/COMMON/create_tasks.h
+++ b/targets/COMMON/create_tasks.h
@@ -22,9 +22,6 @@
 #ifndef CREATE_TASKS_H_
 #define CREATE_TASKS_H_
 
-/* External declaration of L2L1 task that depend on the target */
-extern void *l2l1_task(void *arg);
-
 int create_tasks(uint32_t enb_nb);
 int create_tasks_ue(uint32_t ue_nb);
 int create_tasks_mbms(uint32_t enb_nb);