diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index d4ced88c31d66b979942bffaa3838e52fc661d9a..267a370196fb56ccdd5667a1cfe88899c8599890 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -469,6 +469,11 @@ function main() {
         flash_firmware_bladerf
       fi
     fi
+    if [ "$FLEXRAN_AGENT" == "1" ] ; then
+      echo_info "installing protobuf/protobuf-c for flexran agent support"
+      install_protobuf_from_source
+      install_protobuf_c_from_source
+    fi
   fi
 
   if [ "$INSTALL_OPTIONAL" = "1" ] ; then
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 29d839b5431ee95ca7e8f50e750361423f70f6ad..631de93cfc38e472e8bee06bb0db846232dd63e8 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -202,10 +202,14 @@ install_protobuf_from_source(){
     (
     cd /tmp
     echo "Downloading protobuf"
-    rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
-    wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
-    tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner 
-    cd protobuf-2.6.1/
+    #rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
+    #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
+    #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
+    #cd protobuf-2.6.1/
+    rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
+    wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
+    tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner
+    cd protobuf-3.3.0/
     ./configure
     echo "Compiling protobuf"
     make -j`nproc`
@@ -641,8 +645,6 @@ check_install_oai_software() {
     install_asn1c_from_source
     $SUDO rm -fr /opt/ssh
     $SUDO git clone https://gist.github.com/2190472.git /opt/ssh
-    install_protobuf_from_source
-    install_protobuf_c_from_source
 }
 
 ### Remove Nettle installation which was done from sources (only done for Ubuntu Distro)
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index e2915594ab786f710a6d13849b4d8874c1a9682d..04611f7b560de9e9f8cda568b4816c9844f74b30 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -764,6 +764,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
                              struct PhysicalConfigDedicated *physicalConfigDedicated )
 {
 
+  static uint8_t first_dedicated_configuration = 0;
   PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
 
   phy_vars_ue->total_TBS[eNB_id]=0;
@@ -954,9 +955,13 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   get_cqipmiri_params(phy_vars_ue,eNB_id);
 
   // disable MIB SIB decoding once we are on connected mode
-  LOG_I(PHY,"Disabling SIB MIB decoding \n");
-  phy_vars_ue->decode_SIB = 0;
-  phy_vars_ue->decode_MIB = 0;
+  first_dedicated_configuration ++;
+  if(first_dedicated_configuration > 1)
+  {
+  	LOG_I(PHY,"Disable SIB MIB decoding \n");
+  	phy_vars_ue->decode_SIB = 0;
+  	phy_vars_ue->decode_MIB = 0;
+  }
   //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
   if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234)
       phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
@@ -1084,6 +1089,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
   LTE_UE_COMMON* const common_vars        = &ue->common_vars;
   LTE_UE_PDSCH** const pdsch_vars_SI      = ue->pdsch_vars_SI;
   LTE_UE_PDSCH** const pdsch_vars_ra      = ue->pdsch_vars_ra;
+  LTE_UE_PDSCH** const pdsch_vars_p       = ue->pdsch_vars_p;
   LTE_UE_PDSCH** const pdsch_vars_mch     = ue->pdsch_vars_MCH;
   LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars;
   LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX]   = &ue->pdcch_vars;
@@ -1179,6 +1185,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
 
     pdsch_vars_SI[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
     pdsch_vars_ra[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    pdsch_vars_p[eNB_id]   = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
     pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
     prach_vars[eNB_id]     = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH));
     pbch_vars[eNB_id]      = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH));
@@ -1242,6 +1249,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
       }
       phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
       phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
+      phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
       phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
 
       // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
@@ -1306,6 +1314,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
 
   pdsch_vars_SI[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
   pdsch_vars_ra[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
+  pdsch_vars_p[eNB_id]   = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
 
   if (abstraction_flag == 0) {
     for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index f3833b770914737e8b325a2e27bdb9e413a48e3c..dbc8718dfaf647f6c76f8779278f0ef6e3abac14 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -129,6 +129,9 @@ void lte_param_init(unsigned char N_tx_port_eNB,
 
   UE->perfect_ce = perfect_ce;
 
+  /* the UE code is multi-thread "aware", we need to setup this array */
+  for (i = 0; i < 10; i++) UE->current_thread_id[i] = i % 2;
+
   printf("Done lte_param_init\n");
 
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index 7e90116180aa97291dbf481dd4ba808c5525303e..6958666608ad72ff96c06d36476dc233c76788aa 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -40,6 +40,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
 {
 
   static int max_pos_fil = 0;
+  static int count_max_pos_ok = 0;
+  static int first_time = 1;
   int temp = 0, i, aa, max_val = 0, max_pos = 0;
   int diff;
   short Re,Im,ncoef;
@@ -58,8 +60,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
     temp = 0;
 
     for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
-      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
+      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
+      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
       temp += (Re*Re/2) + (Im*Im/2);
     }
 
@@ -78,28 +80,59 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
   // do not filter to have proactive timing adjustment
   max_pos_fil = max_pos;
 
-  diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
+  if(subframe == 6)
+  {
+      diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
+
+      if ( abs(diff) < SYNCH_HYST )
+          ue->rx_offset = 0;
+      else
+          ue->rx_offset = diff;
+
+      if(abs(diff)<5)
+          count_max_pos_ok ++;
+      else
+          count_max_pos_ok = 0;
+
+      if(count_max_pos_ok > 10 && first_time == 1)
+      {
+          first_time = 0;
+          ue->time_sync_cell = 1;
+          if (ue->mac_enabled==1) {
+              LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
+              //mac_resynch();
+              mac_xface->dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
+              ue->UE_mode[0] = PRACH;
+          }
+          else {
+              ue->UE_mode[0] = PUSCH;
+          }
+      }
 
-  if ( abs(diff) < SYNCH_HYST )
-	ue->rx_offset = 0;
-  else
-    ue->rx_offset = diff;
+      if ( ue->rx_offset < 0 )
+          ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES;
 
-  if ( ue->rx_offset < 0 )
-    ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES;
+      if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES )
+          ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES;
 
-  if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES )
-    ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES;
 
 
+      #ifdef DEBUG_PHY
+      LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
+              ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
+              subframe,
+              ue->current_thread_id[subframe],
+              diff,
+              ue->rx_offset,
+              clear,
+              max_pos,
+              max_pos_fil,
+              temp,max_val,
+              (frame_parms->nb_prefix_samples>>3));
+      #endif //DEBUG_PHY
 
-#ifdef DEBUG_PHY
-  LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (after) = %d : max_pos = %d,max_pos_fil = %d (peak %d) target_pos %d \n",
-        ue->proc.proc_rxtx[0].frame_rx,subframe,ue->rx_offset,max_pos,max_pos_fil,temp,(frame_parms->nb_prefix_samples>>3));
-#endif //DEBUG_PHY
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
-
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
+  }
 }
 
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
index 8d98511e482ee8a2bed42b849b321fcda22d0c83..7f457c436a91dc99bc4b2541512c92ef7590544c 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -51,7 +51,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   int uespec_pilot[300];
 
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
-  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[(Ns>>1)%RX_NB_TH][eNB_id];
+  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[Ns>>1]][eNB_id];
   LTE_DL_UE_HARQ_t *dlsch0_harq; 
 
   harq_pid    = dlsch_ue[0]->current_harq_pid;
@@ -63,9 +63,9 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   else
     rballoc = dlsch0_harq->rb_alloc_even;
 
-  rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF;
+  rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[Ns>>1]].rxdataF;
 
-  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[(Ns>>1)%RX_NB_TH][eNB_id]->dl_bf_ch_estimates;
+  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[Ns>>1]][eNB_id]->dl_bf_ch_estimates;
   beamforming_mode   = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
   if (phy_vars_ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
index 0ff4fde9aac89dcf5f248b606f9e524eb8206914..c737f7d635b6c0a00957a3ffd7b183825171d5cf 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -49,12 +49,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
 
   uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
 
-  uint8_t nushift,pilot1,pilot2,pilot3;
-  uint8_t previous_sfn = ((Ns>>1) - 1 )< 0 ? 9 : (Ns>>1) - 1;
-  int **dl_ch_estimates         =ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates[eNB_offset];
-  int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[(previous_sfn)%RX_NB_TH].dl_ch_estimates[eNB_offset];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF;
+  uint8_t nushift,pilot0,pilot1,pilot2,pilot3;
+  uint8_t previous_thread_id = ue->current_thread_id[Ns>>1]==0 ? (RX_NB_TH-1):(ue->current_thread_id[Ns>>1]-1);
+  int **dl_ch_estimates         =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
+  int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].dl_ch_estimates[eNB_offset];
+  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
 
+  pilot0 = 0;
   if (ue->frame_parms.Ncp == 0) {  // normal prefix
     pilot1 = 4;
     pilot2 = 7;
@@ -93,7 +94,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
   k = (nu + nushift)%6;
 
 #ifdef DEBUG_CH
-  printf("Channel Estimation : eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,l,Ns,k);
 #endif
 
@@ -797,18 +798,23 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
     break;
   }
 
-  // do ifft of channel estimate
-  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
-    for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
-      if (ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
-        idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
-             (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
-    }
-
+  if( ((Ns%2) == 0) && (l == pilot0))
+  {
+      // do ifft of channel estimate
+      for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
+          for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
+              if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
+              {
+                  //LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
+                  idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
+                          (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
+              }
+          }
+  }
 #if T_TRACER
         T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(ue->Mod_id),
-          T_INT(ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx%1024), T_INT(ue->proc.proc_rxtx[(Ns>>1)&1].subframe_rx),
-          T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates_time[eNB_offset][0][0], 512  * 4));
+          T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].frame_rx%1024), T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].subframe_rx),
+          T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][0][0], 512  * 4));
 #endif
 
   return(0);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
index f375cdec3de5132dc0c8daba636b3517a5b631c1..e1ad291eec90551270f04cfbbc648128c365a6c5 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
@@ -44,8 +44,8 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
   //  unsigned int n;
   //  int i;
 
-  int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[0];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF;
+  int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0];
+  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 
   ch_offset     = (l*(ue->frame_parms.ofdm_symbol_size));
   symbol_offset = ch_offset;//phy_vars_ue->lte_frame_parms.ofdm_symbol_size*l;
@@ -734,31 +734,31 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
 
   // do ifft of channel estimate
   for (aa=0; aa<ue->frame_parms.nb_antennas_rx*ue->frame_parms.nb_antennas_tx; aa++) {
-    if (ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa]) {
+    if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa]) {
       switch (ue->frame_parms.N_RB_DL) {
       case 6:
-	idft128((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_offset][aa],
+	idft128((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 25:
-	idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_offset][aa],
+	idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 50:
-	idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_offset][aa],
+	idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 75:
-	idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa][8],
-		 (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_offset][aa],
+	idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		 (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		 1);
 	break;
       case 100:
-	idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_offset][aa],
+	idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       default:
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index cc676ce467b217bf990c491966837e5440af0e08..49f440c8869f267efdb3f4ba3c2311b8e2fe675a 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -184,8 +184,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
   uint16_t Nid_cell = ue->frame_parms.Nid_cell;
   uint8_t eNB_offset,nu,l,nushift,k;
   uint16_t off;
+  uint8_t previous_thread_id = ue->current_thread_id[subframe]==0 ? (RX_NB_TH-1):(ue->current_thread_id[subframe]-1);
 
-  //uint8_t isPss; // indicate if this is a slot for extracting PSS
+   //uint8_t isPss; // indicate if this is a slot for extracting PSS
   //uint8_t isSss; // indicate if this is a slot for extracting SSS
   //int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS
   //int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS
@@ -210,13 +211,13 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 
           if(ue->frame_parms.frame_type == FDD)
           {
-	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
-	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
+	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
+	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
           }
           else
           {
-              rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
-              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
+              rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
+              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
           }
               //-ve spectrum from SSS
 
@@ -234,13 +235,13 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
           //          printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
               if(ue->frame_parms.frame_type == FDD)
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
               }
               else
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
               }
           //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
           //          printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
@@ -275,10 +276,10 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
           if (ue->frame_parms.Ncp==NORMAL) {
             for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
-                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(ue->current_thread_id[subframe])].rxdataF;
                 rxF_pss  = (int16_t *) &rxdataF[aarx][((pss_symb*(ue->frame_parms.ofdm_symbol_size)))];
 
-                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF;
                 rxF_sss  = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))];
 
                 //-ve spectrum from SSS
@@ -303,7 +304,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
                 ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
             //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
             //          printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
-                rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
+                rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
             //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
             //          printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
                 ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
@@ -349,7 +350,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 #endif
 
         for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
-          rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
+          rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
           off  = (ue->frame_parms.first_carrier_offset+k)<<1;
 
           if (l==(4-ue->frame_parms.Ncp)) {
@@ -515,7 +516,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
         ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] =
-          (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
+          (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
                               (N_RB_DL*12)));
         //- ue->measurements.n0_power[aarx];
 
@@ -608,8 +609,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
       // cqi/pmi information
 
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 
         for (subband=0; subband<nb_subbands; subband++) {
 
@@ -664,13 +665,13 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 #if defined(__x86_64__) || defined(__i386__)
        __m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1 /* ,mmtmpPMI2,mmtmpPMI3 */ ;
 
-        dl_ch0_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 #elif defined(__arm__)
         int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b;
 
-        dl_ch0_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 
 #endif
         for (subband=0; subband<nb_subbands; subband++) {
@@ -764,7 +765,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
     else {
       // cqi information only for mode 1
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
 
         for (subband=0; subband<7; subband++) {
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 3fd618cec8badf542569481d57206e0e0901dc45..c1264d5e77eafb963fecdbc474b3a7c04fa75932 100755
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -404,7 +404,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
             for (i=0; i<4; i++) {
               wbar[mprime] = llr[tti_offset0+i];
 #ifdef DEBUG_DCI_DECODING
-              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
 #endif
               mprime++;
               re_offset0++;
@@ -420,7 +420,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
             for (i=0; i<4; i++) {
               wbar[mprime] = llr[tti_offset+i];
 #ifdef DEBUG_DCI_DECODING
-              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
 #endif
               mprime++;
             }
@@ -653,7 +653,7 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
       //clear average level
 #if defined(__x86_64__) || defined(__i386__)
       avg128P = _mm_setzero_si128();
-      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0];
 #elif defined(__arm__)
 
 #endif
@@ -1693,55 +1693,55 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
 
   LTE_UE_COMMON *common_vars      = &ue->common_vars;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[subframe%RX_NB_TH];
+  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[ue->current_thread_id[subframe]];
 
   uint8_t log2_maxh,aatx,aarx;
 #ifdef MU_RECEIVER
   uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1
 #endif
-  int32_t avgs,s;
-  uint8_t n_pdcch_symbols = 3; //pdcch_vars[eNB_id]->num_pdcch_symbols;
+  int32_t avgs;
+  uint8_t n_pdcch_symbols;
   uint8_t mi = get_mi(frame_parms,subframe);
 
   //printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars);
-
-  for (s=0; s<n_pdcch_symbols; s++) {
+  // procress ofdm symbol 0
     if (is_secondary_ue == 1) {
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
                                pdcch_vars[eNB_id]->rxdataF_ext,
                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
 #ifdef MU_RECEIVER
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
                                pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
                                pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
 #endif //MU_RECEIVER
     } else if (frame_parms->nb_antenna_ports_eNB>1) {
-      pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                             common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+      pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                             common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                              pdcch_vars[eNB_id]->rxdataF_ext,
                              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                             s,
+                             0,
                              high_speed_flag,
                              frame_parms);
     } else {
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                pdcch_vars[eNB_id]->rxdataF_ext,
                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
     }
-  }
 
+
+  // compute channel level based on ofdm symbol 0
   pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                       frame_parms,
                       avgP,
@@ -1762,86 +1762,86 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
   T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id),  T_INT(0), T_INT(frame%1024), T_INT(subframe),
                            T_INT(avgP[0]), T_INT(avgP[1]),    T_INT(avgP[2]),             T_INT(avgP[3]));
 #endif
-  for (s=0; s<n_pdcch_symbols; s++) {
-    pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
-                               pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               pdcch_vars[eNB_id]->rxdataF_comp,
-                               (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
-                               frame_parms,
-                               s,
-                               log2_maxh); // log2_maxh+I0_shift
+
+  // compute LLRs for ofdm symbol 0 only
+  pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+          pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+          pdcch_vars[eNB_id]->rxdataF_comp,
+          (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
+                  frame_parms,
+                  0,
+                  log2_maxh); // log2_maxh+I0_shift
 
 
 #ifdef DEBUG_PHY
 
-    if (subframe==5)
+  if (subframe==5)
       write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 
 #endif
 
 #ifdef MU_RECEIVER
 
-    if (is_secondary_ue) {
+  if (is_secondary_ue) {
       //get MF output for interfering stream
       pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
-                                 pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                 pdcch_vars[eNB_id_i]->rxdataF_comp,
-                                 (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
-                                 frame_parms,
-                                 s,
-                                 log2_maxh); // log2_maxh+I0_shift
+              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id_i]->rxdataF_comp,
+              (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
+                      frame_parms,
+                      0,
+                      log2_maxh); // log2_maxh+I0_shift
 #ifdef DEBUG_PHY
       write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 #endif
       pdcch_dual_stream_correlation(frame_parms,
-                                    s,
-                                    pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                                    pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                    pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                                    log2_maxh);
-    }
+              0,
+              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id]->dl_ch_rho_ext,
+              log2_maxh);
+  }
 
 #endif //MU_RECEIVER
 
 
-    if (frame_parms->nb_antennas_rx > 1) {
+  if (frame_parms->nb_antennas_rx > 1) {
 #ifdef MU_RECEIVER
 
       if (is_secondary_ue) {
-        pdcch_detection_mrc_i(frame_parms,
-                              pdcch_vars[eNB_id]->rxdataF_comp,
-                              pdcch_vars[eNB_id_i]->rxdataF_comp,
-                              pdcch_vars[eNB_id]->rho,
-                              pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                              s);
+          pdcch_detection_mrc_i(frame_parms,
+                  pdcch_vars[eNB_id]->rxdataF_comp,
+                  pdcch_vars[eNB_id_i]->rxdataF_comp,
+                  pdcch_vars[eNB_id]->rho,
+                  pdcch_vars[eNB_id]->dl_ch_rho_ext,
+                  0);
 #ifdef DEBUG_PHY
-        write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
-        write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+          write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+          write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 #endif
       } else
 #endif //MU_RECEIVER
-        pdcch_detection_mrc(frame_parms,
-                            pdcch_vars[eNB_id]->rxdataF_comp,
-                            s);
-
-    }
+          pdcch_detection_mrc(frame_parms,
+                  pdcch_vars[eNB_id]->rxdataF_comp,
+                  0);
+  }
 
-    if (mimo_mode == SISO)
-      pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
-    else
-      pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+  if (mimo_mode == SISO)
+      pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
+  else
+      pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
 
 
 #ifdef MU_RECEIVER
 
-    if (is_secondary_ue) {
+  if (is_secondary_ue) {
       pdcch_qpsk_qpsk_llr(frame_parms,
-                          pdcch_vars[eNB_id]->rxdataF_comp,
-                          pdcch_vars[eNB_id_i]->rxdataF_comp,
-                          pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                          pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
-                          pdcch_vars[eNB_id]->llr,
-                          s);
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              pdcch_vars[eNB_id_i]->rxdataF_comp,
+              pdcch_vars[eNB_id]->dl_ch_rho_ext,
+              pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
+              pdcch_vars[eNB_id]->llr,
+              0);
       /*
       #ifdef DEBUG_PHY
       if (subframe==5) {
@@ -1849,22 +1849,21 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
       write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
       }
       #endif*/
-    } else {
+  } else {
 #endif //MU_RECEIVER
       pdcch_llr(frame_parms,
-                pdcch_vars[eNB_id]->rxdataF_comp,
-                (char *)pdcch_vars[eNB_id]->llr,
-                s);
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              (char *)pdcch_vars[eNB_id]->llr,
+              0);
       /*#ifdef DEBUG_PHY
       write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
       #endif*/
 
 #ifdef MU_RECEIVER
-    }
+  }
 
 #endif //MU_RECEIVER
 
-  }
 
 #if T_TRACER
   T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
@@ -1872,7 +1871,7 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
     T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
 #endif
 
-  // decode pcfich here
+  // decode pcfich here and find out pdcch ofdm symbol number
   n_pdcch_symbols = rx_pcfich(frame_parms,
                               subframe,
                               pdcch_vars[eNB_id],
@@ -1888,6 +1887,147 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
   printf("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
 #endif
 
+  // process pdcch ofdm symbol 1 and 2 if necessary
+  for (int s=1; s<n_pdcch_symbols; s++){
+      if (is_secondary_ue == 1) {
+          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+#ifdef MU_RECEIVER
+pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+        common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
+        pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
+        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
+        s,
+        high_speed_flag,
+        frame_parms);
+#endif //MU_RECEIVER
+      } else if (frame_parms->nb_antenna_ports_eNB>1) {
+          pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+      } else {
+          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+      }
+
+
+      pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
+                      frame_parms,
+                      s,
+                      log2_maxh); // log2_maxh+I0_shift
+
+
+#ifdef DEBUG_PHY
+
+if (subframe==5)
+    write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+
+#endif
+
+#ifdef MU_RECEIVER
+
+if (is_secondary_ue) {
+    //get MF output for interfering stream
+    pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
+            pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+            pdcch_vars[eNB_id_i]->rxdataF_comp,
+            (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
+                    frame_parms,
+                    s,
+                    log2_maxh); // log2_maxh+I0_shift
+#ifdef DEBUG_PHY
+write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+pdcch_dual_stream_correlation(frame_parms,
+        s,
+        pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+        pdcch_vars[eNB_id]->dl_ch_rho_ext,
+        log2_maxh);
+}
+
+#endif //MU_RECEIVER
+
+
+if (frame_parms->nb_antennas_rx > 1) {
+#ifdef MU_RECEIVER
+
+    if (is_secondary_ue) {
+        pdcch_detection_mrc_i(frame_parms,
+                pdcch_vars[eNB_id]->rxdataF_comp,
+                pdcch_vars[eNB_id_i]->rxdataF_comp,
+                pdcch_vars[eNB_id]->rho,
+                pdcch_vars[eNB_id]->dl_ch_rho_ext,
+                s);
+#ifdef DEBUG_PHY
+write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+    } else
+#endif //MU_RECEIVER
+        pdcch_detection_mrc(frame_parms,
+                pdcch_vars[eNB_id]->rxdataF_comp,
+                s);
+
+}
+
+if (mimo_mode == SISO)
+    pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+else
+    pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+
+
+#ifdef MU_RECEIVER
+
+if (is_secondary_ue) {
+    pdcch_qpsk_qpsk_llr(frame_parms,
+            pdcch_vars[eNB_id]->rxdataF_comp,
+            pdcch_vars[eNB_id_i]->rxdataF_comp,
+            pdcch_vars[eNB_id]->dl_ch_rho_ext,
+            pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
+            pdcch_vars[eNB_id]->llr,
+            s);
+    /*
+        #ifdef DEBUG_PHY
+        if (subframe==5) {
+        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        }
+        #endif*/
+} else {
+#endif //MU_RECEIVER
+    pdcch_llr(frame_parms,
+            pdcch_vars[eNB_id]->rxdataF_comp,
+            (char *)pdcch_vars[eNB_id]->llr,
+            s);
+    /*#ifdef DEBUG_PHY
+        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        #endif*/
+
+#ifdef MU_RECEIVER
+}
+
+#endif //MU_RECEIVER
+
+  }
+
   pdcch_demapping(pdcch_vars[eNB_id]->llr,
                   pdcch_vars[eNB_id]->wbar,
                   frame_parms,
@@ -2039,8 +2179,7 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
   return(0);
 }
 
-uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
-                         uint8_t num_common_dci,
+uint8_t generate_dci_top(int num_dci,
                          DCI_ALLOC_t *dci_alloc,
                          uint32_t n_rnti,
                          int16_t amp,
@@ -2050,7 +2189,6 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
 {
 
   uint8_t *e_ptr,num_pdcch_symbols;
-  int8_t L;
   uint32_t i, lprime;
   uint32_t gain_lin_QPSK,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset;
   int16_t re_offset;
@@ -2096,9 +2234,9 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
     break;
   }
 
-  num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
+  num_pdcch_symbols = get_num_pdcch_symbols(num_dci,dci_alloc,frame_parms,subframe);
   //  printf("subframe %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n",
-  //     subframe,num_pdcch_symbols,num_ue_spec_dci+num_common_dci);
+  //     subframe,num_pdcch_symbols,num_dci);
   generate_pcfich(num_pdcch_symbols,
                   amp,
                   frame_parms,
@@ -2117,50 +2255,22 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
 
   e_ptr = e;
 
-  // generate DCIs in order of decreasing aggregation level, then common/ue spec
-  // MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization
-  for (L=3; L>=0; L--) {
-    for (i=0; i<num_common_dci; i++) {
-
-      if (dci_alloc[i].L == (uint8_t)L) {
-
-#ifdef DEBUG_DCI_ENCODING
-        printf("Generating common DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_common_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
-              *(unsigned int*)dci_alloc[i].dci_pdu);
-        dump_dci(frame_parms,&dci_alloc[i]);
-#endif
-
-        if (dci_alloc[i].firstCCE>=0) {
-          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
-                                e+(72*dci_alloc[i].firstCCE),
-                                dci_alloc[i].dci_length,
-                                dci_alloc[i].L,
-                                dci_alloc[i].rnti);
-        }
-      }
-    }
-
-    for (; i<num_ue_spec_dci + num_common_dci; i++) {
-
-      if (dci_alloc[i].L == (uint8_t)L) {
-
+  // generate DCIs
+  for (i=0; i<num_dci; i++) {
 #ifdef DEBUG_DCI_ENCODING
-        printf(" Generating UE (rnti %x) (nCCE %d) specific DCI %d of length %d, aggregation %d, format %d (%x)\n",dci_alloc[i].rnti,dci_alloc[i].firstCCE,i,dci_alloc[i].dci_length,1<<dci_alloc[i].L,dci_alloc[i].format,
-              dci_alloc[i].dci_pdu);
-        dump_dci(frame_parms,&dci_alloc[i]);
+    printf("Generating %s DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",
+           dci_alloc[i].search_space == DCI_COMMON_SPACE ? "common" : "UE",
+           i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
+          *(unsigned int*)dci_alloc[i].dci_pdu);
+    dump_dci(frame_parms,&dci_alloc[i]);
 #endif
 
-        if (dci_alloc[i].firstCCE >= 0) {
-          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
-                                e+(72*dci_alloc[i].firstCCE),
-                                dci_alloc[i].dci_length,
-                                dci_alloc[i].L,
-                                dci_alloc[i].rnti);
-        }
-	else {
-	  
-	}
-      }
+    if (dci_alloc[i].firstCCE>=0) {
+      e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
+                            e+(72*dci_alloc[i].firstCCE),
+                            dci_alloc[i].dci_length,
+                            dci_alloc[i].L,
+                            dci_alloc[i].rnti);
     }
   }
 
@@ -2371,21 +2481,34 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
 
 #ifdef PHY_ABSTRACTION
 uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
-                              uint8_t num_ue_spec_dci,
-                              uint8_t num_common_dci,
+                              int num_dci,
                               DCI_ALLOC_t *dci_alloc,
                               uint8_t subframe)
 {
   int n_dci, n_dci_dl;
   uint8_t ue_id;
   LTE_eNB_DLSCH_t *dlsch_eNB;
-  uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,
+  int num_ue_spec_dci;
+  int num_common_dci;
+  int i;
+  uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_dci,
                               dci_alloc,
                               &phy_vars_eNB->frame_parms,
                               subframe);
   eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.cfi=num_pdcch_symbols;
 
-  memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_ue_spec_dci+num_common_dci));
+  num_ue_spec_dci = 0;
+  num_common_dci = 0;
+  for (i = 0; i < num_dci; i++) {
+    /* TODO: maybe useless test, to remove? */
+    if (!(dci_alloc[i].firstCCE>=0)) abort();
+    if (dci_alloc[i].search_space == DCI_COMMON_SPACE)
+      num_common_dci++;
+    else
+      num_ue_spec_dci++;
+  }
+
+  memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_dci));
   phy_vars_eNB->num_ue_spec_dci[subframe&1]=num_ue_spec_dci;
   phy_vars_eNB->num_common_dci[subframe&1]=num_common_dci;
   eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci = num_ue_spec_dci;
@@ -2679,6 +2802,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
 			     uint8_t subframe,
                              DCI_ALLOC_t *dci_alloc,
                              int16_t eNB_id,
+                             uint8_t current_thread_id,
                              LTE_DL_FRAME_PARMS *frame_parms,
                              uint8_t mi,
                              uint16_t si_rnti,
@@ -2810,20 +2934,20 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
         LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
                 pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
       else
-        LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
-                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
+        LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
+                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
 
 #endif
 
       dci_decoding(sizeof_bits,
                    L,
                    &pdcch_vars[eNB_id]->e_rx[CCEind*72],
-                   &dci_decoded_output[subframe%RX_NB_TH][0]);
+                   &dci_decoded_output[current_thread_id][0]);
       /*
         for (i=0;i<3+(sizeof_bits>>3);i++)
         printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
       */
-      crc = (crc16(&dci_decoded_output[subframe%RX_NB_TH][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[subframe%RX_NB_TH][0],sizeof_bits);
+      crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits);
 #ifdef DEBUG_DCI_DECODING
       printf("crc =>%x\n",crc);
 #endif
@@ -2839,29 +2963,29 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
 
         //printf("DCI FOUND !!! crc =>%x,  sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
         if (sizeof_bytes<=4) {
-          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe%RX_NB_TH][0];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe%RX_NB_TH][1];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe%RX_NB_TH][2];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe%RX_NB_TH][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
 #ifdef DEBUG_DCI_DECODING
-          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[subframe%RX_NB_TH][0],
-                  dci_decoded_output[subframe%RX_NB_TH][1],
-                  dci_decoded_output[subframe%RX_NB_TH][2],
-                  dci_decoded_output[subframe%RX_NB_TH][3]);
+          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
+                  dci_decoded_output[current_thread_id][1],
+                  dci_decoded_output[current_thread_id][2],
+                  dci_decoded_output[current_thread_id][3]);
 #endif
         } else {
-          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[subframe%RX_NB_TH][0];
-          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[subframe%RX_NB_TH][1];
-          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[subframe%RX_NB_TH][2];
-          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[subframe%RX_NB_TH][3];
-          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe%RX_NB_TH][4];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe%RX_NB_TH][5];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe%RX_NB_TH][6];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe%RX_NB_TH][7];
+          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7];
 #ifdef DEBUG_DCI_DECODING
           printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
-              dci_decoded_output[subframe%RX_NB_TH][0],dci_decoded_output[subframe%RX_NB_TH][1],dci_decoded_output[subframe%RX_NB_TH][2],dci_decoded_output[subframe%RX_NB_TH][3],
-              dci_decoded_output[subframe%RX_NB_TH][4],dci_decoded_output[subframe%RX_NB_TH][5],dci_decoded_output[subframe%RX_NB_TH][6],dci_decoded_output[subframe%RX_NB_TH][7]);
+              dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
+              dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
 #endif
         }
 
@@ -2878,7 +3002,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           *dci_cnt = *dci_cnt+1;
         } else if (crc==pdcch_vars[eNB_id]->crnti) {
 
-          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[subframe%RX_NB_TH][0]&0x80)==0)) {// check if pdu is format 0 or 1A
+          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A
             if (*format0_found == 0) {
               dci_alloc[*dci_cnt].format     = format0;
               *format0_found = 1;
@@ -2900,7 +3024,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           }
         }
 
-        LOG_D(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
+        //LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
         //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
 
 
@@ -2924,19 +3048,200 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
         }
 
 #ifdef DEBUG_DCI_DECODING
-        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x)\n",
-              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap);
+        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n",
+              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates );
         dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);
 
 #endif
-
-        //  if (crc==pdcch_vars[eNB_id]->crnti)
-        //    return;
+         return;
       } // rnti match
     }  // CCEmap_cand == 0
+/*    
+	if ( agregationLevel != 0xFF &&
+        (format_c == format0 && m==0 && si_rnti != SI_RNTI))
+    {
+      //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
+      return;
+    }
+*/
   } // candidate loop
 }
 
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                uint8_t DCIFormat,
+                                uint8_t agregationLevel,
+                                int16_t eNB_id,
+                                uint8_t subframe)
+{
+
+  uint8_t  dci_cnt=0,old_dci_cnt=0;
+  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
+  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
+  LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
+  uint8_t mi = get_mi(&ue->frame_parms,subframe);
+  uint16_t ra_rnti=99;
+  uint8_t format0_found=0,format_c_found=0;
+  uint8_t tmode = ue->transmission_mode[eNB_id];
+  uint8_t frame_type = frame_parms->frame_type;
+  uint8_t format0_size_bits=0,format0_size_bytes=0;
+  uint8_t format1_size_bits=0,format1_size_bytes=0;
+  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe);
+
+  switch (frame_parms->N_RB_DL) {
+  case 6:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 25:
+  default:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 50:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
+    }
+
+    break;
+
+  case 100:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
+    }
+
+    break;
+  }
+
+  if (ue->prach_resources[eNB_id])
+    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+
+  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          subframe,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[subframe],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+              P_RNTI,
+              agregationLevel,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  if (DCIFormat == 1)
+  {
+      if ((tmode < 3) || (tmode == 7)) {
+          //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+          // Now check UE_SPEC format 1 search spaces at aggregation 1
+
+           //printf("[DCI search] Format 1/1A aggregation 1\n");
+
+          old_dci_cnt=dci_cnt;
+          dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
+                                  dci_alloc,
+                                  eNB_id,
+                                  ue->current_thread_id[subframe],
+                                  frame_parms,
+                                  mi,
+                                  ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                                  ra_rnti,
+                                  P_RNTI,
+                                  0,
+                                  format1A,
+                                  format1A,
+                                  format1A,
+                                  format1,
+                                  format1_size_bits,
+                                  format1_size_bytes,
+                                  &dci_cnt,
+                                  &format0_found,
+                                  &format_c_found,
+                                  &CCEmap0,
+                                  &CCEmap1,
+                                  &CCEmap2);
+
+          if ((CCEmap0==0xffff) ||
+              (format_c_found==1))
+            return(dci_cnt);
+
+          if (dci_cnt>old_dci_cnt)
+            return(dci_cnt);
+
+          //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+      }
+      else
+      {
+          AssertFatal(0,"Other Transmission mode not yet coded\n");
+      }
+  }
+  else
+  {
+     AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat);
+  }
+
+  return(dci_cnt);
+
+}
+
 uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                                 DCI_ALLOC_t *dci_alloc,
                                 int do_common,
@@ -2946,7 +3251,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   uint8_t  dci_cnt=0,old_dci_cnt=0;
   uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
-  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[subframe%RX_NB_TH];
+  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
   LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
   uint8_t mi = get_mi(&ue->frame_parms,subframe);
   uint16_t ra_rnti=99;
@@ -3165,6 +3470,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0) ,
@@ -3193,6 +3499,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3225,6 +3532,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3253,6 +3561,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3287,6 +3596,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3310,12 +3620,16 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 4\n");
+  //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt);
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 4
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3339,16 +3653,18 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  if ((CCEmap0==0xffff)||
-      ((format0_found==1)&&(format_c_found==1)))
-    return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 2\n");
+  //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 2
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3372,12 +3688,17 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 4\n");
+  //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 1
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3401,9 +3722,9 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
+  //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt);
 
-
-
+  }
   // These are for CRNTI based on transmission mode
   if ((tmode < 3) || (tmode == 7)) {
     // Now check UE_SPEC format 1 search spaces at aggregation 1
@@ -3411,6 +3732,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3429,6 +3751,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff) ||
         (format_c_found==1))
@@ -3442,6 +3765,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3460,7 +3784,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
-
+    //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         (format_c_found==1))
@@ -3474,6 +3798,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3492,6 +3817,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
@@ -3506,6 +3832,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3524,6 +3851,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
@@ -3543,6 +3871,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3578,6 +3907,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3612,6 +3942,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3647,6 +3978,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3681,6 +4013,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3713,6 +4046,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3745,6 +4079,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3778,6 +4113,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3808,6 +4144,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3841,6 +4178,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3873,6 +4211,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3907,6 +4246,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index e77f66cc4599c54e7919a9e1cc29b87c0d0d4d61..a832d4bfb5fe22ee232b9a9c946ad8a9515ec88e 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -4788,11 +4788,12 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
     LOG_I(PHY,"[DCI-FORMAT-1-1A] rah        %d\n", rah);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc    %x\n", rballoc);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1       %d\n", mcs1);
-    //LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1        %d\n", rv1);
-    //LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1       %d\n", ndi1);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1        %d\n", rv1);
+    LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1       %d\n", ndi1);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC        %d\n", TPC);
 #endif
 
+
     // I- check dci content minimum coherency
     if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0)
     {
@@ -5131,10 +5132,70 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
    return(1);
 }
 
+void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
+                        LTE_UE_PDCCH *pdcch_vars,
+                        LTE_UE_PDSCH *pdsch_vars,
+                        LTE_DL_UE_HARQ_t *dlsch0_harq,
+                        uint8_t nb_rb_alloc,
+                        uint8_t subframe)
+{
+    uint32_t pbch_pss_sss_re;
+    uint32_t crs_re;
+    uint32_t granted_re;
+    uint32_t data_re;
+    uint32_t llr_offset;
+    uint8_t symbol;
+    uint8_t symbol_mod;
+
+    pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0;
+
+    //LOG_I(PHY,"compute_llr_offset:  nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm);
+
+    //dlsch0_harq->rb_alloc_even;
+    //dlsch0_harq->rb_alloc_odd;
+
+    for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++)
+    {
+        symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+        if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
+        {
+            if (frame_parms->mode1_flag==0)
+                crs_re = 4;
+            else
+                crs_re = 2;
+        }
+        else
+        {
+            crs_re = 0;
+        }
+
+        granted_re = nb_rb_alloc * (12-crs_re);
+        pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
+        pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
+        data_re = granted_re - pbch_pss_sss_re;
+        llr_offset = data_re * dlsch0_harq->Qm * 2;
+
+        pdsch_vars->llr_length[symbol]   = data_re;
+        if(symbol < (frame_parms->symbols_per_tti-1))
+          pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset;
+
+        //LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb);
+        //LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re);
+        //LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re);
+        //LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re);
+
+
+
+        //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol,
+        //      pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]);
+    }
+}
 void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                                     uint8_t N_RB_DL,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint8_t  subframe,
                                     uint16_t rnti,
 									uint16_t tc_rnti,
@@ -5156,12 +5217,27 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     uint8_t  dai       = pdci_info_extarcted->dai;
 
     uint8_t  NPRB    = 0;
+    uint8_t  nb_rb_alloc = 0;
 
     if(dci_format == format1A)
     {
         if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
         {
             NPRB = (TPC&1) + 2;
+            switch (N_RB_DL) {
+            case 6:
+                nb_rb_alloc     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+                break;
+            case 25:
+                nb_rb_alloc     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+                break;
+            case 50:
+                nb_rb_alloc     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+                break;
+            case 100:
+                nb_rb_alloc     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+                break;
+        }
         }
         else
         {
@@ -5179,11 +5255,13 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                 NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                 break;
             }
+            nb_rb_alloc = NPRB;
         }
     }
     else // format1
     {
         NPRB = conv_nprb(rah, rballoc, N_RB_DL);
+        nb_rb_alloc = NPRB;
     }
 
     pdlsch0->current_harq_pid = harq_pid;
@@ -5213,30 +5291,32 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
             pdlsch0_harq->first_tx = 0;
             pdlsch0_harq->status   = ACTIVE;
 
+        }else if (rv1  != 0 )
+            //NDI has not been toggled but rv was increased by eNB: retransmission
+        {
+            if (pdlsch0_harq->status == SCH_IDLE)
+                //packet was actually decoded in previous transmission (ACK was missed by eNB)
+                //However, the round is not a good check as it might have been decoded in a retransmission prior to this one.
+            {
+                LOG_D(PHY,"skip pdsch decoding and report ack\n");
+                // skip pdsch decoding and report ack
+                //pdlsch0_harq->status   = SCH_IDLE;
+                pdlsch0->active       = 0;
+                pdlsch0->harq_ack[subframe].ack = 1;
+                pdlsch0->harq_ack[subframe].harq_id = harq_pid;
+                pdlsch0->harq_ack[subframe].send_harq_status = 1;
+
+                //pdlsch0_harq->first_tx = 0;
+            }
+            else  //normal retransmission
+            {
+                // nothing special to do
+            }
+        }
+        else
+        {
+            pdlsch0_harq->status   = ACTIVE;
         }
-
-	else if (rv1  != 0 )
-	//NDI has not been toggled but rv was increased by eNB: retransmission
-	  {
-	    if (pdlsch0_harq->status == SCH_IDLE)
-	    //packet was actually decoded in previous transmission (ACK was missed by eNB)
-	    //However, the round is not a good check as it might have been decoded in a retransmission prior to this one.
-	      {
-		LOG_D(PHY,"skip pdsch decoding and report ack\n");
-		// skip pdsch decoding and report ack
-		//pdlsch0_harq->status   = SCH_IDLE;
-		pdlsch0->active       = 0;
-		pdlsch0->harq_ack[subframe].ack = 1;
-		pdlsch0->harq_ack[subframe].harq_id = harq_pid;
-		pdlsch0->harq_ack[subframe].send_harq_status = 1;
-
-		//pdlsch0_harq->first_tx = 0;
-	      }
-	    else  //normal retransmission
-	      {
-		// nothing special to do
-	      }
-	  }
     }
 
     pdlsch0_harq->DCINdi = ndi1;
@@ -5346,7 +5426,6 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
         pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2];
         pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3];
     }
-
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
         pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1];
@@ -5360,11 +5439,20 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
             pdlsch0_harq->Qm  = get_Qm(mcs1);
         }
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       nb_rb_alloc,
+                       subframe);
 }
 
 void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
                                   DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                   LTE_DL_FRAME_PARMS *frame_parms,
+                                  LTE_UE_PDCCH *pdcch_vars,
+                                  LTE_UE_PDSCH *pdsch_vars,
                                   uint32_t rnti,
                                   uint32_t si_rnti,
                                   uint32_t ra_rnti,
@@ -5467,6 +5555,14 @@ void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
         AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
         break;
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       pdlsch0_harq->nb_rb,
+                       subframe);
+
 }
 
 void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq)
@@ -5536,10 +5632,10 @@ switch (tpmi) {
               dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
             break;
             }
-#ifdef DEBUG_HARQ
+  #ifdef DEBUG_HARQ
               printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi);
-#endif
-}
+  #endif
+            }
 
 void compute_precoding_info_format2A(uint8_t tpmi,
                                      uint8_t nb_antenna_ports_eNB,
@@ -5640,6 +5736,8 @@ void compute_precoding_info_format2A(uint8_t tpmi,
 void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint16_t rnti,
                                     uint8_t subframe,
                                     LTE_DL_UE_HARQ_t *dlsch0_harq,
@@ -5819,7 +5917,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
       if (TB0_active) {
        // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx);
         if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))  {
-           dlsch0_harq->round = 0;
+          dlsch0_harq->round = 0;
            dlsch0_harq->status = ACTIVE;
            dlsch0_harq->DCINdi = ndi1;
 
@@ -5834,12 +5932,12 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
 	  //NDI has not been toggled but rv was increased by eNB: retransmission
 	  {
 	    if(dlsch0_harq->status == SCH_IDLE) {
-	      // skip pdsch decoding and report ack
+            // skip pdsch decoding and report ack
 	      //dlsch0_harq->status   = SCH_IDLE;
-	      pdlsch0->active       = 0;
-	      pdlsch0->harq_ack[subframe].ack = 1;
-	      pdlsch0->harq_ack[subframe].harq_id = harq_pid;
-	      pdlsch0->harq_ack[subframe].send_harq_status = 1;
+            pdlsch0->active       = 0;
+            pdlsch0->harq_ack[subframe].ack = 1;
+            pdlsch0->harq_ack[subframe].harq_id = harq_pid;
+            pdlsch0->harq_ack[subframe].send_harq_status = 1;
 	    }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
@@ -5882,13 +5980,13 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
 	//NDI has not been toggled but rv was increased by eNB: retransmission
 	  {
 	    if(dlsch1_harq->status == SCH_IDLE) {
-	      // skip pdsch decoding and report ack
+            // skip pdsch decoding and report ack
 	      //dlsch1_harq->status   = SCH_IDLE;
-	      pdlsch1->active       = 0;
-	      pdlsch1->harq_ack[subframe].ack = 1;
-	      pdlsch1->harq_ack[subframe].harq_id = harq_pid;
-	      pdlsch1->harq_ack[subframe].send_harq_status = 1;
-	    }
+            pdlsch1->active       = 0;
+            pdlsch1->harq_ack[subframe].ack = 1;
+            pdlsch1->harq_ack[subframe].harq_id = harq_pid;
+            pdlsch1->harq_ack[subframe].send_harq_status = 1;
+         }
 	  }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
@@ -5911,7 +6009,16 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
       }
 
 
+      compute_llr_offset(frame_parms,
+                         pdcch_vars,
+                         pdsch_vars,
+                         dlsch0_harq,
+                         dlsch0_harq->nb_rb,
+                         subframe);
+
+
  /* #ifdef DEBUG_HARQ
+      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
       printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active);
       if (dlsch0 != NULL && dlsch1 != NULL)
         printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status);
@@ -5927,6 +6034,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
@@ -5938,10 +6047,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
 {
 
     uint8_t harq_pid=0;
-  uint8_t frame_type=frame_parms->frame_type;
-  uint8_t tpmi=0;
-  LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
-  LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+    uint8_t frame_type=frame_parms->frame_type;
+    uint8_t tpmi=0;
+    LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+    LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
 
     DCI_INFO_EXTRACTED_t dci_info_extarcted;
     uint8_t status=0;
@@ -6006,7 +6115,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                               &dci_info_extarcted,
                                               dlsch0_harq);
       if(status == 0)
+      {
+        printf("bad DCI 1A !!! \n");
         return(-1);
+      }
 
       // dci is correct ==> update internal structure and prepare dl decoding
 #ifdef DEBUG_DCI
@@ -6016,6 +6128,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -6066,6 +6180,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
       prepare_dl_decoding_format1C(frame_parms->N_RB_DL,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    si_rnti,
                                    ra_rnti,
@@ -6107,7 +6223,11 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                               &dci_info_extarcted,
                                               dlsch0_harq);
       if(status == 0)
-        return(-1);
+      {
+          printf("bad DCI 1 !!! \n");
+          return(-1);
+      }
+
 
       // dci is correct ==> update internal structure and prepare dl decoding
 #ifdef DEBUG_DCI
@@ -6117,6 +6237,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -6130,7 +6252,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
 
     case format2:
     {
-        //extract dci infomation
+        // extract dci infomation
         //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe);
         extract_dci2_info(frame_parms->N_RB_DL,
                 frame_type,
@@ -6143,8 +6265,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch[0]->active = 1;
         dlsch[1]->active = 1;
 
-        dlsch0 = dlsch[0];
-        dlsch1 = dlsch[1];
+            dlsch0 = dlsch[0];
+            dlsch1 = dlsch[1];
 
     dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
     dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
@@ -6171,13 +6293,15 @@ int generate_ue_dlsch_params_from_dci(int frame,
         prepare_dl_decoding_format2_2A(format2,
                 &dci_info_extarcted,
                 frame_parms,
+                pdcch_vars,
+                pdsch_vars,
                 rnti,
                 subframe,
                 dlsch0_harq,
                 dlsch1_harq,
                 dlsch0,
                 dlsch1);
-}
+    }
     break;
 
     case format2A:
@@ -6224,6 +6348,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
     prepare_dl_decoding_format2_2A(format2A,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    subframe,
                                    dlsch0_harq,
@@ -6231,7 +6357,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                    dlsch0,
                                    dlsch1);
     }
-          break;
+      break;
 
     case format1E_2A_M10PRB:
       if (!dlsch[0]) return -1;
@@ -7229,7 +7355,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
   uint8_t transmission_mode = ue->transmission_mode[eNB_id];
   ANFBmode_t AckNackFBMode;
   LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
-  LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe%RX_NB_TH][0];
+  LTE_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[subframe]][0];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   //  uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];
@@ -8036,7 +8162,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
       //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
       int dl_subframe = subframe;
 
-      if (ue->dlsch[dl_subframe%RX_NB_TH][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
+      if (ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
         ulsch->harq_processes[harq_pid]->O_ACK = 1;
       } else {
         ulsch->harq_processes[harq_pid]->O_ACK = 0;
@@ -8795,7 +8921,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe)
   uint8_t transmission_mode = ue->transmission_mode[eNB_id];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   LTE_DL_FRAME_PARMS *frame_parms =  &ue->frame_parms;
-  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[subframe %RX_NB_TH].dl_ch_estimates[eNB_id];
+  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
   double *s_dB;
   s_dB = ue->sinr_CQI_dB;
   //  LTE_UE_ULSCH_t *ulsch  = ue->ulsch[eNB_id];
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index dced65fa2cbe84432a11a6bf5611ae36da28068c..4c5eb8c06ac2b7e080532147612008bdc1f34a71 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -781,6 +781,10 @@ typedef enum {
   pucch_format3    // PUCCH format3
 } PUCCH_FMT_t;
 
+typedef enum {
+  DCI_COMMON_SPACE,
+  DCI_UE_SPACE
+} dci_space_t;
 
 typedef struct {
   /// Length of DCI in bits
@@ -795,6 +799,8 @@ typedef struct {
   rnti_t rnti;
   /// Format
   DCI_format_t format;
+  /// search space
+  dci_space_t search_space;
   /// DCI pdu
   uint8_t dci_pdu[8];
 } DCI_ALLOC_t;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 6114a29bdd6c5f14dd8350d353a85709c11c3ee7..761f9f360385e3c8613904693d1b8da46426832a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -272,7 +272,7 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     return(max_turbo_iterations);
     }*/
 
-  /*harq_pid = dlsch->current_harq_pid[subframe%RX_NB_TH];
+  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
   if (harq_pid >= 8) {
     printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
     return(max_turbo_iterations);
@@ -962,9 +962,9 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   case PDSCH: // TB0
-    dlsch_ue  = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0];
+    dlsch_ue  = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0];
     harq_pid = dlsch_ue->current_harq_pid;
-    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
+    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
     DevAssert( ue_id != (uint32_t)-1 );
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0];
 
@@ -1008,9 +1008,9 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   case PDSCH1: { // TB1
-    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1];
+    dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1];
     harq_pid = dlsch_ue->current_harq_pid;
-    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
+    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
     DevAssert( UE_id != -1 );
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
     // reset HARQ
@@ -1062,7 +1062,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   default:
-    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0];
+    dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0];
     LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
     dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
     return(1+dlsch_ue->max_turbo_iterations);
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 6ec82e74510f2360c84be2a7c3444d86ab5fc309..77b72dae28aa2e5eee421491ebe8909bd0459f80 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -111,10 +111,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
   int avg_0[2];
   int avg_1[2];
 
+#if UE_TIMING_TRACE
+  uint8_t slot = 0;
+#endif
+
   unsigned char aatx,aarx;
 
   unsigned short nb_rb = 0, round;
-  int avgs, rb;
+  int avgs = 0, rb;
   LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
 
   uint8_t beamforming_mode;
@@ -143,8 +147,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
 
   case PDSCH:
-    pdsch_vars = ue->pdsch_vars[subframe%RX_NB_TH];
-    dlsch = ue->dlsch[subframe%RX_NB_TH][eNB_id];
+    pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe]];
+    dlsch = ue->dlsch[ue->current_thread_id[subframe]][eNB_id];
     //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
     LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d,  harq status %d.%d \n",
                    frame,subframe,symbol,harq_pid,
@@ -247,6 +251,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
       return(-1);
     }
   }
+
+#if UE_TIMING_TRACE
+  if(symbol > ue->frame_parms.symbols_per_tti>>1)
+  {
+      slot = 1;
+  }
+#endif
+
 #ifdef DEBUG_HARQ
   printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
 #endif
@@ -256,8 +268,11 @@ int rx_pdsch(PHY_VARS_UE *ue,
     LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]);
 #endif
 
-    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                   common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
+    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                   common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                    pdsch_vars[eNB_id]->rxdataF_ext,
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    dlsch0_harq->pmi_alloc,
@@ -277,8 +292,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
    if (rx_type >= rx_IC_single_stream) {
       if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
-      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id_i],
+      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                       common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -290,8 +305,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                        frame_parms,
                                        dlsch0_harq->mimo_mode);
       else
-        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                       common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -304,8 +319,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                        dlsch0_harq->mimo_mode);
     }
   } else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
-    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                     common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                     common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                      pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      dlsch0_harq->pmi_alloc,
@@ -318,8 +333,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
    if (rx_type==rx_IC_single_stream) {
      if (eNB_id_i<ue->n_connected_eNB)
-        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id_i],
+        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                         common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -330,8 +345,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                          ue->high_speed_flag,
                                          frame_parms);
       else
-        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                         common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -343,7 +358,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                          frame_parms);
     }
   } else if (beamforming_mode==7) { //else if beamforming_mode == 7
-    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
+    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
@@ -363,12 +378,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
     return(-1);
   }
 
-
-#ifdef DEBUG_PHY
-  LOG_D(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
-  LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,
+            symbol,ue->high_speed_flag,type,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction  %5.2f \n",frame,subframe,slot,symbol,
+            ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
 #endif
 
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   aatx = frame_parms->nb_antenna_ports_eNB;
   aarx = frame_parms->nb_antennas_rx;
 
@@ -391,6 +414,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
                         nb_rb);
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   if (first_symbol_flag==1) {
     if (beamforming_mode==0){
       if (dlsch0_harq->mimo_mode<LARGE_CDD) {
@@ -481,8 +516,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                                  avg[0],avgs);
     //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
 #endif
+
+    //wait until pdcch is decoded
+    //proc->channel_level = 1;
   }
 
+  /*
+  uint32_t wait = 0;
+  while(proc->channel_level == 0)
+  {
+      usleep(1);
+      wait++;
+  }
+  */
+
 #if T_TRACER
     if (type == PDSCH)
     {
@@ -491,6 +538,19 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
 #endif
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
 // Now channel compensation
   if (dlsch0_harq->mimo_mode<LARGE_CDD) {
     dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
@@ -685,8 +745,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                  measurements); // log2_maxh+I0_shift
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
 // MRC
-
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
 
    if (frame_parms->nb_antennas_rx > 1) {
     if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
@@ -754,31 +824,59 @@ int rx_pdsch(PHY_VARS_UE *ue,
     //i_mod should have been passed as a parameter
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
+  // compute LLRs
+  // -> // compute @pointer where llrs should filled for this ofdm-symbol
+  int8_t  *pllr_symbol_cw0;
+  int8_t  *pllr_symbol_cw1;
+  uint32_t llr_offset_symbol;
+  llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol];
+  pllr_symbol_cw0  = (int8_t*)pdsch_vars[eNB_id]->llr[0];
+  pllr_symbol_cw1  = (int8_t*)pdsch_vars[eNB_id]->llr[1];
+  pllr_symbol_cw0 += llr_offset_symbol;
+  pllr_symbol_cw1 += llr_offset_symbol;
+
+  /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
+             proc->frame_rx, proc->subframe_rx,symbol,
+             nb_rb,dlsch0_harq->Qm,
+             pdsch_vars[eNB_id]->llr_length[symbol],
+             pdsch_vars[eNB_id]->llr_offset[symbol],
+             (int16_t*)pdsch_vars[eNB_id]->llr[0],
+             pllr_symbol);*/
 
   switch (dlsch0_harq->Qm) {
   case 2 :
     if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
                        symbol,
                        first_symbol_flag,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
 
     } else if (codeword_TB0 == -1){
 
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[1],
+                       (int16_t*)pllr_symbol_cw1,
                        symbol,
                        first_symbol_flag,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128_2ndstream,
                        beamforming_mode);
     }
       else if (rx_type >= rx_IC_single_stream) {
@@ -945,22 +1043,22 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
     } else if (codeword_TB0 == -1){
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[1],
+                      (int16_t*)pllr_symbol_cw1,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128_2ndstream,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
@@ -1017,10 +1115,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               dl_ch_mag_ptr,//i
                               pdsch_vars[eNB_id]->dl_ch_rho2_ext,
-                              pdsch_vars[eNB_id]->llr[0],
+                              (int16_t*)pllr_symbol_cw0,
                               symbol,first_symbol_flag,nb_rb,
                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                              pdsch_vars[eNB_id]->llr128);
+                              pdsch_vars[eNB_id]->llr_offset[symbol]);
         if (rx_type==rx_IC_dual_stream) {
           dlsch_64qam_64qam_llr(frame_parms,
                                 rxdataF_comp_ptr,
@@ -1028,10 +1126,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                 dl_ch_mag_ptr,
                                 pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                 pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                pdsch_vars[eNB_id]->llr[1],
+                                (int16_t*)pllr_symbol_cw1,
                                 symbol,first_symbol_flag,nb_rb,
                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
-                                pdsch_vars[eNB_id]->llr128_2ndstream);
+                                pdsch_vars[eNB_id]->llr_offset[symbol]);
         }
       }
     }
@@ -1047,10 +1145,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
                        symbol,first_symbol_flag,nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
     }
     break;
@@ -1070,12 +1167,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
   }
     break;
@@ -1086,6 +1183,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
 // Please keep it: useful for debugging
 #if 0
   if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/)
@@ -1094,12 +1199,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
       if(1)
       {
 #if 1
-      write_output("rxdataF0.m"    , "rxdataF0",             &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("rxdataF1.m"    , "rxdataF1",             &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      write_output("dl_ch_estimates00.m", "dl_ch_estimates00",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates01.m", "dl_ch_estimates01",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates10.m", "dl_ch_estimates10",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates11.m", "dl_ch_estimates11",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
+      write_output("rxdataF0.m"    , "rxdataF0",             &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("rxdataF1.m"    , "rxdataF1",             &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      write_output("dl_ch_estimates00.m", "dl_ch_estimates00",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates01.m", "dl_ch_estimates01",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates10.m", "dl_ch_estimates10",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates11.m", "dl_ch_estimates11",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
 
 
       //write_output("rxdataF_ext00.m"    , "rxdataF_ext00",       &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
@@ -1132,7 +1237,6 @@ int rx_pdsch(PHY_VARS_UE *ue,
     T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0],
              2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
 #endif
-
   return(0);
 
 }
@@ -3464,11 +3568,11 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
         */
       }
 
-      avg[(aatx<<1)+aarx] =  (((int32_t*)&avg128D)[0] +
-			      ((int32_t*)&avg128D)[1] +
-			      ((int32_t*)&avg128D)[2] +
+      avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] +
+                            ((int32_t*)&avg128D)[1] +
+                            ((int32_t*)&avg128D)[2] +
 			      ((int32_t*)&avg128D)[3])/y;
-      //printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
+                //  printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
     }
 
   _mm_empty();
@@ -4644,7 +4748,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
                                       unsigned char subframe,
                                       uint32_t high_speed_flag,
                                       LTE_DL_FRAME_PARMS *frame_parms,
-                                                              MIMO_mode_t mimo_mode) {
+                                      MIMO_mode_t mimo_mode) {
 
   int prb,nb_rb=0;
   int prb_off,prb_off2;
@@ -5934,50 +6038,50 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c
 
   sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
 
   if (ue->frame_parms.nb_antennas_rx >1) {
     sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
     sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
   }
 
   sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
   sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
 
   if (ue->transmission_mode[eNB_id]==7){
     sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
     sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
     //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);
 
     sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
     sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
   }
 
   if (ue->frame_parms.nb_antennas_rx == 2) {
     sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
     sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
   }
 
   if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
     sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
     sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
 
     if (ue->frame_parms.nb_antennas_rx == 2) {
       sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
       sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
-      write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
+      write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
     }
   }
 
   sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
 
   /*
     write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
@@ -5987,31 +6091,31 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c
   sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
   sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
 
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
 
   sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
   sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
 
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
 
   sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
   if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
     sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
     sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
   }
 
   sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_llr",eNB_id,round);
-  write_output(fname,vname, ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
+  write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
   sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_mag1",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
   sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_mag2",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
 
   //  printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index 46ee54d4298bdebebbf1270ce56de9391bedc0d9..da69dc6a0519150142d91a0847fe7aa3b8eefee9 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -636,7 +636,6 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint16_t pbch_pss_sss_adjust,
-                   int16_t **llr32p,
                    uint8_t beamforming_mode)
 {
 
@@ -645,12 +644,14 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int i,len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
+  /*
   if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
   } else {
     llr32 = (uint32_t*)(*llr32p);
-  }
+  }*/
 
+  llr32 = (uint32_t*)dlsch_llr;
   if (!llr32) {
     msg("dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
     return(-1);
@@ -672,6 +673,13 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
 
   //printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             llr32);*/
+
   //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag);
   for (i=0; i<len; i++) {
     *llr32 = *rxF;
@@ -680,7 +688,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
     llr32++;
   }
 
-  *llr32p = (int16_t *)llr32;
+  //*llr32p = (int16_t *)llr32;
 
   return(0);
 }
@@ -1040,7 +1048,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
@@ -1054,11 +1063,18 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   unsigned char symbol_mod,len_mod4;
   short *llr;
   int16_t *llr2;
+  int8_t *pllr_symbol;
 
+  /*
   if (first_symbol_flag==1)
     llr = dlsch_llr;
   else
     llr = *llr_save;
+  */
+  llr = dlsch_llr;
+
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
@@ -1082,6 +1098,15 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+//  printf("dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+
+/*  LOG_I(PHY,"dlsch_64qam_llr [symb %d / FirstSym %d / Length %d]: @LLR Buff %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             pllr_symbol);*/
+
   llr2 = llr;
   llr += (len*6);
 
@@ -1176,7 +1201,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
   }
 
-  *llr_save = llr;
 #if defined(__x86_64__) || defined(__i386__)
   _mm_empty();
   _m_empty();
@@ -8789,7 +8813,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t first_symbol_flag,
                           uint16_t nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          int16_t **llr16p)
+                          //int16_t **llr16p,
+                          uint32_t llr_offset)
 {
 
   int16_t *rxF      = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
@@ -8798,16 +8823,18 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *rho      = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *llr16;
+  int8_t  *pllr_symbol; // pointer where llrs should filled for this ofdm symbol
   int len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
   //first symbol has different structure due to more pilots
-  if (first_symbol_flag == 1) {
+  /*if (first_symbol_flag == 1) {
     llr16 = (int16_t*)dlsch_llr;
   } else {
     llr16 = (int16_t*)(*llr16p);
-  }
+  }*/
 
+  llr16 = (int16_t*)dlsch_llr;
   if (!llr16) {
     msg("dlsch_64qam_64qam_llr: llr is null, symbol %d\n",symbol);
     return(-1);
@@ -8826,6 +8853,18 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
+  //printf("dlsch_64qam_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_64qam_64qam_llr [symb %d / FirstSym %d / Length %d / LLR Offset %d]: @LLR Buff %x, @LLR Buff(symb) %x, , @Compute LLR Buff(symb) %x  \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             llr_offset,
+             (int16_t*)dlsch_llr,
+             llr16,
+             pllr_symbol);*/
+
 #ifdef __AVX2__
 
   // Round length up to multiple of 16 words
@@ -8859,6 +8898,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    (int32_t *) rho_256i,
                    len);
 #endif
+  
   free16(rxF_256i, sizeof(rxF_256i));
   free16(rxF_i_256i, sizeof(rxF_i_256i));
   free16(ch_mag_256i, sizeof(ch_mag_256i));
@@ -8876,6 +8916,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
 
   llr16 += (6*len);
-  *llr16p = (short *)llr16;
+  //*llr16p = (short *)llr16;
+
   return(0);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 19b01529464e58b775fda85f8fc4bcec2f782dbb..ec7cfff7a1cd6b59f4ace20c338984c9eb4d1a77 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -233,19 +233,17 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
       break;
     }
 
-    ue->proc.proc_rxtx[0].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
-    ue->proc.proc_rxtx[0].frame_rx += frame_mod4;
-
-    ue->proc.proc_rxtx[1].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
-    ue->proc.proc_rxtx[1].frame_rx += frame_mod4;
+    for(int i=0; i<RX_NB_TH;i++)
+    {
+        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
+        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
 
 #ifndef USER_MODE
-    // one frame delay
-    ue->proc.proc_rxtx[0].frame_rx ++;
-    ue->proc.proc_rxtx[1].frame_rx ++;
+        // one frame delay
+        ue->proc.proc_rxtx[i].frame_rx ++;
 #endif
-    ue->proc.proc_rxtx[0].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
-    ue->proc.proc_rxtx[1].frame_tx = ue->proc.proc_rxtx[1].frame_rx;
+        ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
+    }
 #ifdef DEBUG_INITIAL_SYNCH
     LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully mode1_flag %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n",
           ue->Mod_id,
@@ -495,6 +493,8 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
               ue->common_vars.freq_offset );
     #endif
 
+// send sync status to higher layers later when timing offset converge to target timing
+#if OAISIM
       if (ue->mac_enabled==1) {
 	LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
 	//mac_resynch();
@@ -504,6 +504,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
       else {
 	ue->UE_mode[0] = PUSCH;
       }
+#endif
 
       generate_pcfich_reg_mapping(frame_parms);
       generate_phich_reg_mapping(frame_parms);
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index a11cf6022c8ef6f69083dd6a9f95a3140ec61108..3bbbaf6c716de38dcc2128388f29b86af40afffa 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -1078,7 +1078,7 @@ void rx_phich(PHY_VARS_UE *ue,
 
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[subframe%RX_NB_TH][eNB_id];
+  LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id];
 
   //  uint8_t HI;
   uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe);
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index 82cfe66e1c77204ddf15a139204dbd729c4933bc..29717b62337395cf75ef567a9c25e04f0638b81e 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -74,7 +74,7 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in
   write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb_pmch,1,1);
 
   write_output("mch00_ch0.m","pmch00_ch0",
-               &(ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][0][0]),
+               &(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                ue->frame_parms.ofdm_symbol_size*12,1,1);
 
   write_output("rxsig_mch.m","rxs_mch",
@@ -969,8 +969,8 @@ int rx_pmch(PHY_VARS_UE *ue,
 
   //printf("*********************mch: symbol %d\n",symbol);
 
-  mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
-                  common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
+  mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                   pdsch_vars[eNB_id]->rxdataF_ext,
                   pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                   symbol,
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 54054ed90f765dee7d478b07cad642b7b0f81984..a7dc0f518733423f0064e05e4ab9f724906709ee 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -802,7 +802,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           unsigned char first_symbol_flag,
                           unsigned short nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          short **llr16p);
+                          //short **llr16p,
+                          uint32_t llr_offset);
 
 
 /** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@@ -823,7 +824,7 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                        uint8_t first_symbol_flag,
                        uint16_t nb_rb,
                        uint16_t pbch_pss_sss_adj,
-                       int16_t **llr128p,
+                       //int16_t **llr128p,
                        uint8_t beamforming_mode);
 
 /**
@@ -909,7 +910,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 
@@ -1451,8 +1453,7 @@ void dci_encoding(uint8_t *a,
                   uint16_t rnti);
 
 /*! \brief Top-level DCI entry point. This routine codes an set of DCI PDUs and performs PDCCH modulation, interleaving and mapping.
-  \param num_ue_spec_dci  Number of UE specific DCI pdus to encode
-  \param num_common_dci Number of Common DCI pdus to encode
+  \param num_dci  Number of DCI pdus to encode
   \param dci_alloc Allocation vectors for each DCI pdu
   \param n_rnti n_RNTI (see )
   \param amp Amplitude of QPSK symbols
@@ -1461,8 +1462,7 @@ void dci_encoding(uint8_t *a,
   \param sub_frame_offset subframe offset in frame
   @returns Number of PDCCH symbols
 */
-uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
-                         uint8_t num_common_dci,
+uint8_t generate_dci_top(int num_dci,
                          DCI_ALLOC_t *dci_alloc,
                          uint32_t n_rnti,
                          int16_t amp,
@@ -1471,8 +1471,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                          uint32_t sub_frame_offset);
 
 uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
-                              uint8_t num_ue_spec_dci,
-                              uint8_t num_common_dci,
+                              int num_dci,
                               DCI_ALLOC_t *dci_alloc,
                               uint8_t subframe);
 
@@ -1521,6 +1520,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
                                 int16_t eNB_id,
                                 uint8_t subframe);
 
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                uint8_t DCIFormat,
+                                uint8_t agregationLevel,
+                                int16_t eNB_id,
+                                uint8_t subframe);
 
 uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **lte_ue_pdcch_vars,
                                      uint8_t num_ue_spec_dci,
@@ -1695,6 +1700,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       rnti_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 353e17fa0d802c4cd1e3104c0f5d3cca3c0f5670..6f6caa48e27350f23a60b4e7d09f5c131e5fbca4 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -2530,7 +2530,7 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *eNB,
   rnti = eNB->ulsch[UE_index]->rnti;
 
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
-    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe%RX_NB_TH][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti)
       break;
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c
index 21b39cc5f6cd5bfc5b8b67c9c790452882bc6976..bb12be9157126f6d8798786c0526191506d41ab1 100644
--- a/openair1/PHY/LTE_TRANSPORT/sss.c
+++ b/openair1/PHY/LTE_TRANSPORT/sss.c
@@ -160,6 +160,7 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
   int32_t *pss_rxF,*pss_rxF_ext;
   int32_t *sss_rxF,*sss_rxF_ext;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  uint8_t next_thread_id = ue->current_thread_id[subframe]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe]+1);
 
   int rx_offset = frame_parms->ofdm_symbol_size-3*12;
   uint8_t pss_symb,sss_symb;
@@ -173,7 +174,7 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
 	    pss_symb = 6-frame_parms->Ncp;
 	    sss_symb = pss_symb-1;
 
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 	    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 	    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
@@ -183,18 +184,18 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
 
 	    if(subframe==5 || subframe==0)
 	    {
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 	    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)%RX_NB_TH)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
 	    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 	    }
 	    else if(subframe==6 || subframe==1)
 	    {
-		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 		    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 
-		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
 		    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 	    }
 	    else
@@ -222,18 +223,18 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
         {
         	if(subframe==5 || subframe==0)
         	{
-    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
     	    sss_rxF  =  &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
-    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)%RX_NB_TH)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
     	    pss_rxF  =  &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))];
         	}
     	    else if(subframe==6 || subframe==1)
     	    {
-    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
     		    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 
-    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
     		    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
     	    }
     	    else
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
index 94023264203451f15644a08dd1994af7ba80dd22..5a9bacd527feb33e84d2bf2fbb54523f48131071 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
@@ -262,7 +262,7 @@ uint32_t ulsch_encoding(uint8_t *a,
   // fill CQI/PMI information
   if (ulsch->O>0) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN);
-    rnti = ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
+    rnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
     fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff);
 
     LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti);
@@ -971,7 +971,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer,
   LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   uint8_t tmode = ue->transmission_mode[eNB_id];
-  uint16_t rnti=ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
+  uint16_t rnti=ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
   LOG_D(PHY,"EMUL UE ulsch_encoding for eNB %d,mod_id %d, harq_pid %d rnti %x, ACK(%d,%d) \n",
         eNB_id,ue->Mod_id, harq_pid, rnti,ulsch->o_ACK[0],ulsch->o_ACK[1]);
 
@@ -1005,7 +1005,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer,
   //UE_transport_info_TB_index[ue->Mod_id]+=ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3;
   // navid: currently more than one eNB is not supported in the code
   UE_transport_info[ue->Mod_id][ue->CC_id].num_eNB = 1;
-  UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[subframe_rx%RX_NB_TH][0]->crnti;
+  UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][0]->crnti;
   UE_transport_info[ue->Mod_id][ue->CC_id].eNB_id[0]  = eNB_id;
   UE_transport_info[ue->Mod_id][ue->CC_id].harq_pid[0] = harq_pid;
   UE_transport_info[ue->Mod_id][ue->CC_id].tbs[0]     = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3 ;
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 9aa6d69483ea3651ad1b8f196179b890ca91b0d8..59e8b5453f0fa477d759333509ead09236f7e4cb 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -2002,7 +2002,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
 #endif
 
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
-    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe%RX_NB_TH][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti)
       break;
 
   }
diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h
index da599114a91919c05cb66631bc751c2dc1ce3ab4..d68c157445405521458b38c09b2e466cee9451a3 100644
--- a/openair1/PHY/MODULATION/defs.h
+++ b/openair1/PHY/MODULATION/defs.h
@@ -78,6 +78,17 @@ int slot_fep_ul(LTE_DL_FRAME_PARMS *frame_parms,
                 unsigned char eNb_id,
                 int no_prefix);
 
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix);
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+            int reset_freq_est);
+
 void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
 
 void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 63f1aba8da643ff6ad441dc6af58c062d8070d14..d97ffbc543e080a5d594b430ccb798c85daf25d6 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -109,7 +109,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
 
   for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+    memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
 
     rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
     // Align with 256 bit
@@ -127,14 +127,14 @@ int slot_fep(PHY_VARS_UE *ue,
                (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
         dft((int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 #if UE_TIMING_TRACE
           start_meas(&ue->rx_dft_stats);
 #endif
 
         dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
 #if UE_TIMING_TRACE
         stop_meas(&ue->rx_dft_stats);
 #endif
@@ -163,11 +163,11 @@ int slot_fep(PHY_VARS_UE *ue,
                (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
         dft((int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 
         dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 #if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
@@ -223,7 +223,7 @@ int slot_fep(PHY_VARS_UE *ue,
           start_meas(&ue->dlsch_freq_offset_estimation_stats);
 #endif
 
-        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates[0],
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0],
                             frame_parms,
                             l,
                             &common_vars->freq_offset,
@@ -242,3 +242,219 @@ int slot_fep(PHY_VARS_UE *ue,
 #endif
   return(0);
 }
+
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+  unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+  unsigned int subframe_offset;//,subframe_offset_F;
+  unsigned int slot_offset;
+  unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
+  unsigned int rx_offset;
+  uint8_t  threadId;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  void (*dft)(int16_t *,int16_t *, int);
+  int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
+
+  switch (frame_parms->ofdm_symbol_size) {
+  case 128:
+    dft = dft128;
+    break;
+
+  case 256:
+    dft = dft256;
+    break;
+
+  case 512:
+    dft = dft512;
+    break;
+
+  case 1024:
+    dft = dft1024;
+    break;
+
+  case 1536:
+    dft = dft1536;
+    break;
+
+  case 2048:
+    dft = dft2048;
+    break;
+
+  default:
+    dft = dft512;
+    break;
+  }
+
+  if (no_prefix) {
+    subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
+  } else {
+    subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
+    slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
+  }
+
+  //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+
+
+  if (l<0 || l>=7-frame_parms->Ncp) {
+    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
+    return(-1);
+  }
+
+  if (Ns<0 || Ns>=20) {
+    printf("slot_fep: Ns must be between 0 and 19\n");
+    return(-1);
+  }
+
+
+
+  threadId = ue->current_thread_id[Ns>>1];
+  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+      // change thread index
+    memset(&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+
+    rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
+    // Align with 256 bit
+    //    rx_offset = rx_offset&0xfffffff8;
+
+    if (l==0) {
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
+               (short *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+        start_meas(&ue->rx_dft_stats);
+
+        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+        stop_meas(&ue->rx_dft_stats);
+
+      }
+    } else {
+      rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
+      //                   (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
+
+#ifdef DEBUG_FEP
+      //  if (ue->frame <100)
+      LOG_I(PHY,"slot_fep: frame %d: slot %d, threadId %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n",
+              ue->proc.proc_rxtx[threadId].frame_rx,Ns, threadId,symbol,
+          nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
+#endif
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
+               (void *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      start_meas(&ue->rx_dft_stats);
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+
+        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      }
+
+      stop_meas(&ue->rx_dft_stats);
+
+
+    }
+
+    #ifdef DEBUG_FEP
+        //  if (ue->frame <100)
+        printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[threadId].frame_rx, symbol,rx_offset);
+    #endif
+  }
+  return(0);
+}
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int reset_freq_est)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  int i;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  if (ue->perfect_ce == 0) {
+    if ((l==0) || (l==(4-frame_parms->Ncp))) {
+      for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+
+#ifdef DEBUG_FEP
+        printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
+#endif
+        start_meas(&ue->dlsch_channel_estimation_stats);
+        lte_dl_channel_estimation(ue,eNB_id,0,
+                                  Ns,
+                                  aa,
+                                  l,
+                                  symbol);
+        stop_meas(&ue->dlsch_channel_estimation_stats);
+
+        for (i=0; i<ue->measurements.n_adj_cells; i++) {
+          lte_dl_channel_estimation(ue,eNB_id,i+1,
+                                    Ns,
+                                    aa,
+                                    l,
+                                    symbol);
+        }
+      }
+
+
+      // do frequency offset estimation here!
+      // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
+#ifdef DEBUG_FEP
+      printf("Frequency offset estimation\n");
+#endif
+
+      if (l==(4-frame_parms->Ncp)) {
+        start_meas(&ue->dlsch_freq_offset_estimation_stats);
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[0],
+                            frame_parms,
+                            l,
+                            &common_vars->freq_offset,
+                reset_freq_est);
+        stop_meas(&ue->dlsch_freq_offset_estimation_stats);
+
+      }
+    }
+
+  }
+  return(0);
+}
diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
index f2e459d2f250ada6902d0abe66a0b5102e605153..58e97be75691c5aaea86736071d3f8f301149bf5 100644
--- a/openair1/PHY/MODULATION/slot_fep_mbsfn.c
+++ b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
@@ -109,7 +109,7 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
 #endif
 
   for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*l],0,frame_parms->ofdm_symbol_size*sizeof(int));
+    memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],0,frame_parms->ofdm_symbol_size*sizeof(int));
     if (l==0) {
 #if UE_TIMING_TRACE
         start_meas(&ue->rx_dft_stats);
@@ -118,7 +118,7 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
           nb_prefix_samples0 +
           subframe_offset -
           SOFFSET) % frame_length_samples],
-          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
 #if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
 #endif
@@ -140,7 +140,7 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
           (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1) +
           subframe_offset-
           SOFFSET) % frame_length_samples],
-          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
 #if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
 #endif
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index cb410cac893c219d58997765c39d5bbbb8392c5c..0595c1bf04ed22d3f763b72de8a13b1161133138 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -514,32 +514,32 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
 
-  if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
-    harq_pid = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->current_harq_pid;
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+    harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
 
     if (harq_pid>=8)
       return;
 
-    mcs = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
 
     // Button 0
-    if(!phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+    if(!phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
       // we are in TM5
       fl_show_object(form->button_0);
     }
   }
 
-  if (phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]!=NULL) {
-    num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->num_pdcch_symbols;
+  if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+    num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
   }
 
   //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-  if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
     coded_bits_per_codeword = get_G(frame_parms,
-                                    phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                    phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                                     get_Qm(mcs),
-                                    phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
                                     num_pdcch_symbols,
                                     frame,
                                     subframe,
@@ -563,16 +563,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
 
   rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
-  chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_id];
-  chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id];
+  chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+  chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
   pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
   pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-  pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->llr;
-  pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp[0];
-  pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->llr[0]; // stream 0
+  pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+  pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+  pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
   //    pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
-  pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp0[0];
-  pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_mag0[0];
+  pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+  pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
 
   // Received signal in time domain of receive antenna 0
   if (rxsig_t != NULL) {
diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
index 2a7bf2c2a7c59d2a4f533ea42a7fb6a4d73ca8b9..e5d667c3c20c6528cb2126f27a49fdaac9c225b6 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -465,11 +465,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     int mcs1=0;
     unsigned char harq_pid = 0;
     int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
-    if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->current_harq_pid;
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
   if (harq_pid>=8)
     return;
-    mcs0 = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
         // Button 0
   /*
         if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
@@ -479,23 +479,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   */
     }
     fl_show_object(form->button_0);
-      if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->current_harq_pid;
+      if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
   if (harq_pid>=8)
     return;
-    mcs1 = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->mcs;
+    mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs;
     }
-    if (phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]!=NULL) {
-        num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->num_pdcch_symbols;
+    if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+        num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
     }
     //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-    if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
       mod0 = get_Qm(mcs0);
       coded_bits_per_codeword0 = get_G(frame_parms,
-              phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-              phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
               get_Qm(mcs0),
-              phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->Nl,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
               num_pdcch_symbols,
               frame,
               subframe,
@@ -504,13 +504,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
       coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
       mod0=0;
     }
-    if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]!=NULL) {
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
       mod1 = get_Qm(mcs1);
       coded_bits_per_codeword1 = get_G(frame_parms,
-               phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
-               phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
                get_Qm(mcs1),
-               phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->Nl,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
                num_pdcch_symbols,
                frame,
                subframe,
@@ -533,23 +533,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
     bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
     rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
-    chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates_time[eNB_id];
-    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id];
+    chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
     pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
     pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-    pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->llr;
-    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp[0];
-    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->llr[0]; // stream 0
-    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->llr[1]; // stream 1
-    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp0[0];
-    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[0];
-    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[1];
-    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp1[0][0])[0];
+    pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
+    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
+    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
+    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
+    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
     //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
-    pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_mag0[0];
-    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_mag1[0][0])[0];
-    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_magb0[0];
-    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_magb1[0][0])[0];
+    pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
+    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
+    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
+    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
     fl_freeze_form(form->lte_phy_scope_ue);
     // Received signal in time domain of receive antenna 0
     if (rxsig_t != NULL) {
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 49d48d676d6a1c6419821f170e9eaaa1bca0f18d..ad1d788a570d85da8afb38954ceb326fa60c54ed 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -76,6 +76,7 @@
 #define RX_NB_TH_MAX 2
 #define RX_NB_TH 2
 
+
 //#ifdef SHRLIBDEV
 //extern int rxrescale;
 //#define RX_IQRESCALELEN rxrescale
@@ -395,6 +396,32 @@ typedef struct {
   pthread_mutex_t mutex_rxtx;
   /// scheduling parameters for RXn-TXnp4 thread
   struct sched_param sched_param_rxtx;
+
+  /// internal This variable is protected by ref mutex_fep_slot1.
+  //int instance_cnt_slot0_dl_processing;
+  int instance_cnt_slot1_dl_processing;
+  /// pthread descriptor fep_slot1 thread
+  //pthread_t pthread_slot0_dl_processing;
+  pthread_t pthread_slot1_dl_processing;
+  /// pthread attributes for fep_slot1 processing thread
+ // pthread_attr_t attr_slot0_dl_processing;
+  pthread_attr_t attr_slot1_dl_processing;
+  /// condition variable for UE fep_slot1 thread;
+  //pthread_cond_t cond_slot0_dl_processing;
+  pthread_cond_t cond_slot1_dl_processing;
+  /// mutex for UE synch thread
+  //pthread_mutex_t mutex_slot0_dl_processing;
+  pthread_mutex_t mutex_slot1_dl_processing;
+  //
+  uint8_t chan_est_pilot0_slot1_available;
+  uint8_t chan_est_slot1_available;
+  uint8_t llr_slot1_available;
+  uint8_t dci_slot0_available;
+  uint8_t first_symbol_available;
+  //uint8_t channel_level;
+  /// scheduling parameters for fep_slot1 thread
+  struct sched_param sched_param_fep_slot1;
+
   int sub_frame_start;
   int sub_frame_step;
   unsigned long long gotIQs;
@@ -709,6 +736,9 @@ typedef struct {
   LTE_DL_FRAME_PARMS  frame_parms_before_ho;
   LTE_UE_COMMON    common_vars;
 
+  // point to the current rxTx thread index
+  uint8_t current_thread_id[10];
+
   LTE_UE_PDSCH     *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
   LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1];
@@ -809,6 +839,7 @@ typedef struct {
   uint8_t               decode_MIB;
   int              rx_offset; /// Timing offset
   int              rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
+  int              time_sync_cell;
   int              timing_advance; ///timing advance signalled from eNB
   int              hw_timing_advance;
   int              N_TA_offset; ///timing offset used in TDD
@@ -875,9 +906,9 @@ typedef struct {
   /// Transmission mode per eNB
   uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX];
 
-  time_stats_t phy_proc;
+  time_stats_t phy_proc[RX_NB_TH];
   time_stats_t phy_proc_tx;
-  time_stats_t phy_proc_rx[2];
+  time_stats_t phy_proc_rx[RX_NB_TH];
 
   uint32_t use_ia_receiver;
 
@@ -891,8 +922,13 @@ typedef struct {
   time_stats_t ulsch_multiplexing_stats;
 
   time_stats_t generic_stat;
-  time_stats_t pdsch_procedures_stat;
-  time_stats_t dlsch_procedures_stat;
+  time_stats_t generic_stat_bis[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t ue_front_end_stat[RX_NB_TH];
+  time_stats_t ue_front_end_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t pdcch_procedures_stat[RX_NB_TH];
+  time_stats_t pdsch_procedures_stat[RX_NB_TH];
+  time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t dlsch_procedures_stat[RX_NB_TH];
 
   time_stats_t ofdm_demod_stats;
   time_stats_t dlsch_rx_pdcch_stats;
@@ -905,6 +941,7 @@ typedef struct {
   time_stats_t dlsch_turbo_decoding_stats;
   time_stats_t dlsch_deinterleaving_stats;
   time_stats_t dlsch_llr_stats;
+  time_stats_t dlsch_llr_stats_parallelization[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
   time_stats_t dlsch_unscrambling_stats;
   time_stats_t dlsch_rate_matching_stats;
   time_stats_t dlsch_turbo_encoding_stats;
@@ -934,6 +971,14 @@ typedef struct {
 
 } PHY_VARS_UE;
 
+/* this structure is used to pass both UE phy vars and
+ * proc to the function UE_thread_rxn_txnp4
+ */
+struct rx_tx_thread_data {
+  PHY_VARS_UE    *UE;
+  UE_rxtx_proc_t *proc;
+};
+
 void exit_fun(const char* s);
 
 static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index bfcef7083486be40bab73b0822103991757ac7e8..d09fd8d9152cd4bc9cd52a96782c2d1b1093eb3f 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -40,6 +40,8 @@
 #define RX_NB_TH_MAX 2
 #define RX_NB_TH 2
 
+#define LTE_SLOTS_PER_SUBFRAME 2
+
 #define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10
 #define LTE_SLOTS_PER_FRAME  20
 #define LTE_CE_FILTER_LENGTH 5
@@ -928,6 +930,10 @@ typedef struct {
   //uint32_t *rb_alloc;
   //uint8_t Qm[2];
   //MIMO_mode_t mimo_mode;
+  // llr offset per ofdm symbol
+  uint32_t llr_offset[14];
+  // llr length per ofdm symbol
+  uint32_t llr_length[14];
 } LTE_UE_PDSCH;
 
 typedef struct {
@@ -1028,6 +1034,9 @@ typedef struct {
   uint32_t dci_missed;
   /// nCCE for PUCCH per subframe
   uint8_t nCCE[10];
+  //Check for specific DCIFormat and AgregationLevel
+  uint8_t dciFormat;
+  uint8_t agregationLevel;
 } LTE_UE_PDCCH;
 
 #define PBCH_A 24
diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h
index bb570f0ecd7b9732198915d34063d29990f34afc..17cdabc2248a8e9b90dbe9bc874aa07d8cf4c6b3 100644
--- a/openair1/PHY/vars.h
+++ b/openair1/PHY/vars.h
@@ -79,6 +79,7 @@ unsigned int ULSCH_max_consecutive_errors = 20;
 
 int number_of_cards;
 
+
 int flag_LA=0;
 int flagMag;
 //extern  channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index f00ca4a672001b3c761dbca9b8ce2d0eb86f2638..419dda4ea9378d14b3e5a51dedac758afde57a7b 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -43,6 +43,7 @@ enum THREAD_INDEX { OPENAIR_THREAD_INDEX = 0,
 
 #define OPENAIR_THREAD_STACK_SIZE     PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6
 //#define DLC_THREAD_STACK_SIZE        4096 //DLC stack size
+//#define UE_SLOT_PARALLELISATION
 
 enum openair_SCHED_STATUS {
   openair_SCHED_STOPPED=1,
@@ -139,6 +140,12 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t
   @param phy_vars_rn pointer to RN variables
 */
 int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,UE_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,PHY_VARS_RN *phy_vars_rn);
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_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,PHY_VARS_RN *phy_vars_rn);
+#ifdef UE_SLOT_PARALLELISATION
+void *UE_thread_slot1_dl_processing(void *arg);
+#endif
 
 /*! \brief Scheduling for UE TX procedures in TDD S-subframes.
   @param phy_vars_ue Pointer to UE variables on which to act
diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c
index f750253c6787a329aee900c8171778beb45c37a6..835066748dabecbc7f4b87a578ec5a2686675b6b 100644
--- a/openair1/SCHED/phy_mac_stub.c
+++ b/openair1/SCHED/phy_mac_stub.c
@@ -72,19 +72,19 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
   LOG_D(PHY,"frame %d, subframe %d, transmission_mode %d\n",proc->frame_tx,proc->subframe_tx,transmission_mode);
 
-  DCI_pdu->Num_common_dci = 0;
-  DCI_pdu->Num_ue_spec_dci=0;
+  DCI_pdu->Num_dci = 0;
 
   switch (subframe) {
   case 5:
    if ( !(proc->frame_tx&1) ) // SI message on even frame only (SFN mod 2 == 0)
    {
-	DCI_pdu->Num_common_dci = 1;
-	DCI_pdu->dci_alloc[0].L          = 2;
-	DCI_pdu->dci_alloc[0].firstCCE   = 0;
-	DCI_pdu->dci_alloc[0].rnti       = SI_RNTI;
-	DCI_pdu->dci_alloc[0].format     = format1A;
-	DCI_pdu->dci_alloc[0].ra_flag    = 0;
+	DCI_pdu->Num_dci = 1;
+	DCI_pdu->dci_alloc[0].L            = 2;
+	DCI_pdu->dci_alloc[0].firstCCE     = 0;
+	DCI_pdu->dci_alloc[0].rnti         = SI_RNTI;
+	DCI_pdu->dci_alloc[0].format       = format1A;
+	DCI_pdu->dci_alloc[0].ra_flag      = 0;
+	DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
     switch (eNB->frame_parms.N_RB_DL) {
     case 6:
@@ -206,12 +206,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
     }
     /*
   case 6:
-      DCI_pdu->Num_ue_spec_dci = 1;
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[0].format     = format2_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->Num_dci = 1;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[0].format       = format2_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1.rballoc          = 0x00ff;
       DLSCH_alloc_pdu1.TPC              = 0;
@@ -228,12 +229,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
   default:
   case 7:
-    DCI_pdu->Num_ue_spec_dci = 1;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].firstCCE   = 0;
-    DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[0].format     = format1;
-    DCI_pdu->dci_alloc[0].ra_flag    = 0;
+    DCI_pdu->Num_dci = 1;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].firstCCE     = 0;
+    DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[0].format       = format1;
+    DCI_pdu->dci_alloc[0].ra_flag      = 0;
+    DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
     if (transmission_mode<3 || transmission_mode == 7) {
       //user 1
@@ -459,10 +461,11 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
     
 
-    DCI_pdu->dci_alloc[1].L          = 2;
-    DCI_pdu->dci_alloc[1].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[1].format     = format0;
-    DCI_pdu->dci_alloc[1].ra_flag    = 0;
+    DCI_pdu->dci_alloc[1].L            = 2;
+    DCI_pdu->dci_alloc[1].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[1].format       = format0;
+    DCI_pdu->dci_alloc[1].ra_flag      = 0;
+    DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
     if (eNB->frame_parms.frame_type == FDD) {
       switch (eNB->frame_parms.N_RB_DL) {
@@ -601,13 +604,14 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       }
     }
     } else if (transmission_mode==4) {
-      DCI_pdu->Num_ue_spec_dci = 1;
+      DCI_pdu->Num_dci = 1;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_FDD_t;
-      DCI_pdu->dci_alloc[0].L          = 3;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format2;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI2_5MHz_2A_FDD_t;
+      DCI_pdu->dci_alloc[0].L            = 3;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format2;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->tpmi     = 0;
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->rv1      = 0;
@@ -623,13 +627,14 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->rah      = 0;
 
     } else if (transmission_mode==5) {
-      DCI_pdu->Num_ue_spec_dci = 2;
+      DCI_pdu->Num_dci = 2;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 3;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 3;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1E.tpmi             = 5; //5=use feedback
       DLSCH_alloc_pdu1E.rv               = 0;
@@ -648,11 +653,12 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
       //user 2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 0;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 0;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
       //DLSCH_alloc_pdu1E.mcs            = eNB->target_ue_dl_mcs;
       //DLSCH_alloc_pdu1E.mcs            = (unsigned char) (taus()%28);
       //DLSCH_alloc_pdu1E.mcs            = (unsigned char) ((eNB->frame%1024)%28);
@@ -669,12 +675,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
     /*
       case 8:
-      DCI_pdu->Num_common_dci = 1;
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0xbeef;
-      DCI_pdu->dci_alloc[0].format     = format1A;
-      DCI_pdu->dci_alloc[0].ra_flag    = 1;
+      DCI_pdu->Num_dci = 1;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1A_5MHz_TDD_1_6_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0xbeef;
+      DCI_pdu->dci_alloc[0].format       = format1A;
+      DCI_pdu->dci_alloc[0].ra_flag      = 1;
+      DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
       RA_alloc_pdu.type                = 1;
       RA_alloc_pdu.vrb_type            = 0;
@@ -721,7 +728,7 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   /*
   DCI_pdu->nCCE = 0;
 
-  for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
     DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
   }
   */
@@ -743,20 +750,20 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     rand = (rand%4)+5;
   */
 
-  DCI_pdu->Num_common_dci = 0;
-  DCI_pdu->Num_ue_spec_dci=0;
+  DCI_pdu->Num_dci = 0;
 
   switch (subframe) {
   case 5:
-    DCI_pdu->Num_ue_spec_dci = 1;
+    DCI_pdu->Num_dci = 1;
 
     if (transmission_mode<3) {
       //user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1_5MHz_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu.rballoc          = eNB->ue_dl_rb_alloc;
       DLSCH_alloc_pdu.TPC              = 0;
@@ -769,11 +776,12 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
 
       /*
       //user2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 2;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1_5MHz_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 2;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu.rballoc          = rballoc2;
       DLSCH_alloc_pdu.TPC              = 0;
@@ -785,13 +793,14 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
       memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t));
       */
     } else if (transmission_mode==5) {
-      DCI_pdu->Num_ue_spec_dci = 2;
+      DCI_pdu->Num_dci = 2;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1E.tpmi             = 5; //5=use feedback
       DLSCH_alloc_pdu1E.rv               = 0;
@@ -806,11 +815,12 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
       memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
       //user 2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 2;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 2;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
       memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
@@ -821,12 +831,13 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     break;
 
   case 7:
-    DCI_pdu->Num_common_dci = 1;
-    DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].rnti       = 0xbeef;
-    DCI_pdu->dci_alloc[0].format     = format1A;
-    DCI_pdu->dci_alloc[0].ra_flag    = 1;
+    DCI_pdu->Num_dci = 1;
+    DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1A_5MHz_TDD_1_6_t;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].rnti         = 0xbeef;
+    DCI_pdu->dci_alloc[0].format       = format1A;
+    DCI_pdu->dci_alloc[0].ra_flag      = 1;
+    DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
     RA_alloc_pdu.type                = 1;
     RA_alloc_pdu.vrb_type            = 0;
@@ -841,14 +852,15 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     break;
 
   case 9:
-    DCI_pdu->Num_ue_spec_dci = 1;
+    DCI_pdu->Num_dci = 1;
 
     //user 1
-    DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[0].format     = format0;
-    DCI_pdu->dci_alloc[0].ra_flag    = 0;
+    DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI0_5MHz_TDD_1_6_t ;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[0].format       = format0;
+    DCI_pdu->dci_alloc[0].ra_flag      = 0;
+    DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
     UL_alloc_pdu.type    = 0;
     UL_alloc_pdu.hopping = 0;
@@ -894,7 +906,7 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
   /*
   DCI_pdu->nCCE = 0;
 
-  for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
     DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
   }
   */
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 504167bb2a1679df86f03bd3bb7ee7622c0d45b3..60ca84846aed1d99130c39d9390d36455fccb630 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1319,8 +1319,8 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 
   // loop over all DCIs for this subframe to generate DLSCH allocations
-  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
-    LOG_D(PHY,"[eNB] Subframe %d: DCI %d/%d : rnti %x, CCEind %d\n",subframe,i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,DCI_pdu->dci_alloc[i].rnti,DCI_pdu->dci_alloc[i].firstCCE);
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
+    LOG_D(PHY,"[eNB] Subframe %d: DCI %d/%d : rnti %x, CCEind %d\n",subframe,i,DCI_pdu->Num_dci,DCI_pdu->dci_alloc[i].rnti,DCI_pdu->dci_alloc[i].firstCCE);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].rnti);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].format);
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->dci_alloc[i].firstCCE);
@@ -1346,7 +1346,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   phy_config_dedicated_eNB_step2(eNB);
 
   // Now loop again over the DCIs for UL configuration
-  for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) {
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
     dci_alloc = &DCI_pdu->dci_alloc[i];
 
     if (dci_alloc->format == format0) {  // this is a ULSCH allocation
@@ -1368,7 +1368,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 
   // if we have DCI to generate do it now
-  if ((DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci)>0) {
+  if (DCI_pdu->Num_dci>0) {
 
 
   } else { // for emulation!!
@@ -1379,13 +1379,12 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   if (eNB->abstraction_flag == 0) {
     if (do_pdcch_flag) {
-      if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0) {
-	LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",eNB->Mod_id,frame, subframe,
-	      DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
+      if (DCI_pdu->Num_dci > 0) {
+	LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (Num_dci=%d)\n",eNB->Mod_id,frame, subframe,
+	      DCI_pdu->Num_dci);
       }
 
-      num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
-					   DCI_pdu->Num_common_dci,
+      num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_dci,
 					   DCI_pdu->dci_alloc,
 					   0,
 					   AMP,
@@ -1395,15 +1394,15 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
     }
     else {
       num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;
-      LOG_D(PHY,"num_pdcch_symbols %"PRIu8" (dci common %"PRIu8", dci uespec %"PRIu8")\n",num_pdcch_symbols,
-	    DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
+      LOG_D(PHY,"num_pdcch_symbols %"PRIu8" (Num_dci %d)\n",num_pdcch_symbols,
+	    DCI_pdu->Num_dci);
     }
   }
 
 #ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious
   else {
     LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_to_emul\n",eNB->Mod_id,frame, subframe);
-    num_pdcch_symbols = generate_dci_top_emul(eNB,DCI_pdu->Num_ue_spec_dci,DCI_pdu->Num_common_dci,DCI_pdu->dci_alloc,subframe);
+    num_pdcch_symbols = generate_dci_top_emul(eNB,DCI_pdu->Num_dci,DCI_pdu->dci_alloc,subframe);
   }
 
 #endif
@@ -1414,10 +1413,10 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 #if defined(SMBV) 
   // Sets up PDCCH and DCI table
-  if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4) && ((DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci)>0)) {
-    LOG_D(PHY,"[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",frame,subframe,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
+  if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4) && (DCI_pdu->Num_dci>0)) {
+    LOG_D(PHY,"[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",frame,subframe,DCI_pdu->Num_dci);
     dump_dci(fp,&DCI_pdu->dci_alloc[0]);
-    smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci);
+    smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_dci);
   }
 #endif
 
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 2e00008a56055eceb54a4d0c67f92568f2d71a40..dffb7fe2bdcc157454b5e61c8937baab22258e13 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -30,12 +30,16 @@
  * \warning
  */
 
+#define _GNU_SOURCE
+
 #include "assertions.h"
 #include "defs.h"
 #include "PHY/defs.h"
 #include "PHY/extern.h"
 #include "SCHED/defs.h"
 #include "SCHED/extern.h"
+#include <sched.h>
+#include "targets/RT/USER/lte-softmodem.h"
 
 #ifdef EMOS
 #include "SCHED/phy_procedures_emos.h"
@@ -73,8 +77,6 @@ fifo_dump_emos_UE emos_dump_UE;
 
 #define NS_PER_SLOT 500000
 
-extern int oai_exit;
-
 extern double cpuf;
 
 
@@ -91,29 +93,29 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf
   uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
 
   coded_bits_per_codeword = get_G(&ue->frame_parms,
-                                  ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                  ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
-                                  ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->Qm,
-                                  ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
                                   ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
           subframe,
           ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
-  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[subframe%RX_NB_TH][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
-  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[subframe%RX_NB_TH][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
   /*
     write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
     write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
     write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
     write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
   */
-  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[subframe%RX_NB_TH][0]->rxdataF_comp0[0],300*12,1,1);
-  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[subframe%RX_NB_TH][0]->llr[0],coded_bits_per_codeword,1,0);
+  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1);
+  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0);
 
-  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[subframe%RX_NB_TH][0]->dl_ch_mag0,300*12,1,1);
-  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[subframe%RX_NB_TH][0]->dl_ch_magb0,300*12,1,1);
+  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1);
+  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1);
 }
 
 void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
@@ -142,7 +144,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
 
   write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
   /*
@@ -243,7 +245,7 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
         ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
         coded_bits_per_codeword);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
   /*
@@ -269,7 +271,7 @@ void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
 
   //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
-  for(int l=0; l<2; l++) {
+  for(int l=0; l<RX_NB_TH; l++) {
       for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
           for(j=0; j<2; j++) {
               //DL HARQ
@@ -334,6 +336,7 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
       PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
       PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
       PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
+      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
     }
   }
 
@@ -381,7 +384,7 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
   int subframe=proc->subframe_tx;
 
   LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
-        ue->Mod_id,ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti,proc->frame_tx,subframe,
+        ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,proc->frame_tx,subframe,
         ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
 
   if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
@@ -518,7 +521,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
                               CC_id,
                               frame_tx,
                               eNB_id,
-                              ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti,
+                              ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
                               subframe_tx); // subframe used for meas gap
 
                       if (SR_payload > 0)
@@ -528,7 +531,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
 
               uint8_t pucch_ack_payload[2];
               if (get_ack(&ue->frame_parms,
-                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                       subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0)
               {
                   is_sr_an_subframe = 1;
@@ -720,10 +723,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 
   if (frame_parms->frame_type == FDD ) { // FDD
     sf = (subframe<4)? subframe+6 : subframe-4;
-    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[sf]);
+    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
 
     if (SR == 0)
-      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[sf]);
+      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
     else
       return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
   } else {
@@ -786,7 +789,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           last_dl);
 
       // i=0
-      nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[last_dl];
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl];
       n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
 
       harq_ack0 = b[0];
@@ -828,18 +831,18 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
       // This is the offset for a particular subframe (2,3,4) => (0,2,4)
       last_dl = (subframe-2)<<1;
       // i=0
-      nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[5+last_dl];
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl];
       n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
       // i=1
-      nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(6+last_dl)%10];
+      nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10];
       n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
       // set ACK/NAK to values if not DTX
-      if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-        harq_ack1 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
+      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+        harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
 
-      if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-        harq_ack0 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[5+last_dl].ack;
+      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+        harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack;
 
       LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n",
                                       proc->frame_tx%1024,
@@ -914,32 +917,32 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           //last_dl = (subframe-2)<<1;
           if (subframe == 2) {
           // i=0
-          //nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[2+subframe];
-          nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(8+subframe)%10];
+          //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
           n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=1
-          nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[2+subframe];
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
           n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=2
-          nCCE2 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(8+subframe)%10];
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
 
           n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=3
-          //nCCE3 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(9+subframe)%10];
+          //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(9+subframe)%10];
           //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
           // set ACK/NAK to values if not DTX
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-            harq_ack0 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
 
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-            harq_ack1 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[2+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-            harq_ack2 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[3+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].ack;
 
-          //if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-            //harq_ack3 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
+          //if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
           //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n",
           //                      proc->frame_tx%1024,
           //                      proc->subframe_tx,
@@ -948,30 +951,30 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           }else if (subframe == 3) {
           // i=0
 
-          nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[4+subframe];
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[4+subframe];
           n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=1
-          nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[5+subframe];
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+subframe];
           n1_pucch1 = 2*get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=2
-          nCCE2 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(6+subframe)];
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+subframe)];
           n1_pucch2 = get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=3
-          nCCE3 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[(3+subframe)];
+          nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(3+subframe)];
           n1_pucch3 = 3*get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
           // set ACK/NAK to values if not DTX
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-          harq_ack0 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[4+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-          harq_ack1 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[5+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-          harq_ack2 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(6+subframe)].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack;
 
-          if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-          harq_ack3 = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[(3+subframe)].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack;
           }
 
           //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n",
@@ -1500,7 +1503,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
           eNB_id);
     }
 
-    LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
+    LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
     ue->Mod_id,frame_tx,subframe_tx,eNB_id,
     ue->prach_resources[eNB_id]->ra_PreambleIndex,
     ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id),
@@ -1647,21 +1650,21 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     }
 
     ack_status_cw0 = reset_ack(&ue->frame_parms,
-            ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
+            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
             subframe_tx,
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &Nbundled,
             0);
     ack_status_cw1 = reset_ack(&ue->frame_parms,
-            ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][1]->harq_ack,
+            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
             subframe_tx,
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &NbundledCw1,
             1);
 
-    //Nbundled = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack;
+    //Nbundled = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack;
     //ue->ulsch[eNB_id]->bundling = Nbundled;
 
     first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
@@ -1692,14 +1695,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     if(ue->ulsch[eNB_id]->o_ACK[0])
     {
     	LOG_I(PHY,"PUSCH ACK\n");
-        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid));
+        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
     }
     else
     {
     	LOG_I(PHY,"PUSCH NACK\n");
-        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid));
+        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
     }
 #endif
 #ifdef UE_DEBUG_TRACE
@@ -2039,7 +2042,7 @@ void get_pucch_param(PHY_VARS_UE    *ue,
     {
         pucch_resource[0] = get_n1_pucch(ue,
                                          proc,
-                                         ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
+                                         ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                                          eNB_id,
                                          ack_payload,
                                          SR);
@@ -2150,7 +2153,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                   CC_id,
                   frame_tx,
                   eNB_id,
-                  ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti,
+                  ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
                   subframe_tx); // subframe used for meas gap
       }
       else {
@@ -2159,14 +2162,14 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   }
 
   ack_status_cw0 = get_ack(&ue->frame_parms,
-                       ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
+                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                        subframe_tx,
                        proc->subframe_rx,
                        pucch_ack_payload,
                        0);
 
   ack_status_cw1 = get_ack(&ue->frame_parms,
-                       ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][1]->harq_ack,
+                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
                        subframe_tx,
                        proc->subframe_rx,
                        pucch_ack_payload,
@@ -2242,7 +2245,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 #if T_TRACER
       T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
-              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
 #endif
 
 #ifdef UE_DEBUG_TRACE
@@ -2250,7 +2253,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
       {
           LOG_I(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
                   Mod_id,
-                  ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+                  ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                   frame_tx%1024, subframe_tx,
                   frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                   isShortenPucch,
@@ -2262,7 +2265,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
           if (SR_payload>0) {
               LOG_I(PHY,"[UE  %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
                       Mod_id,
-                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                       frame_tx % 1024, subframe_tx,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2275,7 +2278,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
           } else {
               LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
                       Mod_id,
-                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                       frame_tx%1024, subframe_tx,ue->rx_offset_diff,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2291,13 +2294,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #if T_TRACER
       if(pucch_payload[0])
       {
-          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid));
+          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
       }
       else
       {
-          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid));
+          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
       }
 #endif
 
@@ -2350,12 +2353,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 #if T_TRACER
       T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
-              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
 #endif
 #ifdef UE_DEBUG_TRACE
-      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx,
               Po_PUCCH,
               isShortenPucch,
@@ -2372,20 +2375,20 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
               0,            // B2 not needed
               tx_amp,
               subframe_tx,
-              ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti);
+              ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti);
   }
   break;
 
   case pucch_format2a:
       LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx);
       break;
   case pucch_format2b:
       LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx);
       break;
   default:
@@ -2406,6 +2409,8 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
   unsigned int aa;
   uint8_t isSubframeSRS;
 
+  uint8_t next1_thread_id = ue->current_thread_id[proc->subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
 
@@ -2531,24 +2536,24 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
 
   // reset DL ACK/NACK status
   uint8_t N_bundled = 0;
-  if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0] != NULL)
+  if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL)
   {
     reset_ack(&ue->frame_parms,
-               ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
+               ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
                &N_bundled,
                0);
     reset_ack(&ue->frame_parms,
-               ue->dlsch[(proc->subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack,
+               ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
                &N_bundled,
                0);
     reset_ack(&ue->frame_parms,
-               ue->dlsch[(proc->subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack,
+               ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
@@ -2660,7 +2665,8 @@ void ue_measurement_procedures(
 
   }
 
-  if ((subframe_rx==0) && (slot == 0) && (l==(4-frame_parms->Ncp))) {
+  // accumulate and filter timing offset estimation every subframe (instead of every frame)
+  if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) {
 
     // AGC
 
@@ -2763,8 +2769,8 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
     emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id];
     emos_dump_UE.bitrate = ue->bitrate[eNB_id];
     emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id];
-    emos_dump_UE.pmi_saved = ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->pmi_alloc;
-    emos_dump_UE.mcs = ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->current_harq_pid]->mcs;
+    emos_dump_UE.pmi_saved = ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->pmi_alloc;
+    emos_dump_UE.mcs = ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mcs;
     emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver;
 
     bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE));
@@ -2950,16 +2956,18 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
       {
         ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
         ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
+
+        printf("[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
+ 	    ue->Mod_id,
+ 	    ue->proc.proc_rxtx[th_id].frame_rx,
+ 	    subframe_rx,
+ 	    pbch_tx_ant,
+ 	    frame_tx,
+ 	    pbch_phase,
+ 	    ue->rx_offset,
+ 	    proc->frame_rx);
       }
-       LOG_I(PHY,"[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
-	    ue->Mod_id,
-	    frame_rx,
-	    subframe_rx,
-	    pbch_tx_ant,
-	    frame_tx,
-	    pbch_phase,
-	    ue->rx_offset,
-	    proc->frame_rx);
+
 
       frame_rx = proc->frame_rx;
 
@@ -3055,6 +3063,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
   int subframe_rx = proc->subframe_rx;
   DCI_ALLOC_t dci_alloc_rx[8];
 
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
 #ifdef PHY_ABSTRACTION
   int CC_id;
@@ -3080,14 +3090,34 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
              ue->high_speed_flag,
              ue->is_secondary_ue);
 
-
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
-    dci_cnt = dci_decoding_procedure(ue,
-             dci_alloc_rx,
-             (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
-             // later when we need paging or RA during connection, update this ...
-             eNB_id,subframe_rx);
+
+
+    //printf("Decode SIB frame param agregation + DCI %d %d \n",agregationLevel,dciFormat);
+
+    //agregation level == FF means no configuration on
+    if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
+    {
+        // search all possible dcis
+        dci_cnt = dci_decoding_procedure(ue,
+                dci_alloc_rx,
+                (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
+                                                       // later when we need paging or RA during connection, update this ...
+                eNB_id,subframe_rx);
+    }
+    else
+    {
+        // search only preconfigured dcis
+        // search C RNTI dci
+        dci_cnt = dci_CRNTI_decoding_procedure(ue,
+                dci_alloc_rx,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
+                eNB_id,
+                subframe_rx);
+    }
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
     //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx);
 
@@ -3147,20 +3177,22 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
 #endif
 
-  uint8_t *nCCE_current = &ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->nCCE[subframe_rx];
-  uint8_t *nCCE_dest = &ue->pdcch_vars[(subframe_rx+1)%RX_NB_TH][eNB_id]->nCCE[subframe_rx];
-  uint8_t *nCCE_dest1 = &ue->pdcch_vars[(subframe_rx+2)%RX_NB_TH][eNB_id]->nCCE[subframe_rx];
+  uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx];
+  uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[subframe_rx];
+  uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[subframe_rx];
   memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
   memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
 
+  LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[subframe_rx], next1_thread_id, next2_thread_id);
+
   LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
        ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],
        dci_cnt,
        dci_alloc_rx[0].rnti,
-       ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+       ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
        dci_alloc_rx[0].format );
 
-  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->dci_received += dci_cnt;
+  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dci_received += dci_cnt;
 
 #ifdef EMOS
   //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
@@ -3171,15 +3203,15 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
 
     if ((ue->UE_mode[eNB_id]>PRACH) &&
-	(dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti) &&
+	(dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
 	(dci_alloc_rx[i].format != format0)) {
 
       LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
 	    ue->Mod_id,dci_alloc_rx[i].rnti,
 	    frame_rx%1024,subframe_rx,
 	    dci_alloc_rx[i].format,
-	    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
-	    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->nCCE[subframe_rx],
+	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx],
 	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
 
       //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
@@ -3188,16 +3220,18 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 	  (generate_ue_dlsch_params_from_dci(frame_rx,
 					     subframe_rx,
 					     (void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 					     dci_alloc_rx[i].format,
-					     ue->dlsch[subframe_rx%RX_NB_TH][eNB_id],
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					     ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					     ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id],
 					     &ue->frame_parms,
 					     ue->pdsch_config_dedicated,
 					     SI_RNTI,
 					     0,
 					     P_RNTI,
 					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
-					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti: 0)==0)) {
+					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) {
 
           // update TPC for PUCCH
           if((dci_alloc_rx[i].format == format1)   ||
@@ -3207,13 +3241,13 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
               (dci_alloc_rx[i].format == format2A) ||
               (dci_alloc_rx[i].format == format2B))
           {
-            //ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid]->delta_PUCCH;
-            int32_t delta_pucch = ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
             for(int th_id=0; th_id<RX_NB_TH; th_id++)
             {
                 ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
             }
-            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid,
+            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid,
                     delta_pucch,
                     ue->dlsch[0][eNB_id][0]->g_pucch,
                     ue->dlsch[1][eNB_id][0]->g_pucch
@@ -3226,13 +3260,13 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 #ifdef DEBUG_PHY_PROC
 	LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
 	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->active);
+	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active);
 #endif
 
   // we received a CRNTI, so we're in PUSCH
   if (ue->UE_mode[eNB_id] != PUSCH) {
 #ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti);
+          LOG_I(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti);
 #endif
     //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
     ue->UE_mode[eNB_id] = PUSCH;
@@ -3248,7 +3282,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
        ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
 
 #ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+      LOG_I(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
 #endif
 
 
@@ -3257,6 +3291,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
               (void *)&dci_alloc_rx[i].dci_pdu,
               SI_RNTI,
               dci_alloc_rx[i].format,
+					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					    ue->pdsch_vars_SI[eNB_id],
               &ue->dlsch_SI[eNB_id],
               &ue->frame_parms,
               ue->pdsch_config_dedicated,
@@ -3269,7 +3305,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
   ue->dlsch_SI_received[eNB_id]++;
 
 
-  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
+  LOG_I(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
   //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 
       }
@@ -3279,7 +3315,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
        ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
 
 #ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
+      LOG_I(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
 #endif
 
 
@@ -3288,6 +3324,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
               (void *)&dci_alloc_rx[i].dci_pdu,
             P_RNTI,
               dci_alloc_rx[i].format,
+					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					    ue->pdsch_vars_p[eNB_id],
               &ue->dlsch_SI[eNB_id],
               &ue->frame_parms,
               ue->pdsch_config_dedicated,
@@ -3322,6 +3360,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
               (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
               ue->prach_resources[eNB_id]->ra_RNTI,
               format1A,
+					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					    ue->pdsch_vars_ra[eNB_id],
               &ue->dlsch_ra[eNB_id],
               &ue->frame_parms,
               ue->pdsch_config_dedicated,
@@ -3338,7 +3378,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
         ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
 #endif
       }
-    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti) &&
+    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
 	       (dci_alloc_rx[i].format == format0)) {
 
 #ifdef DEBUG_PHY_PROC
@@ -3351,7 +3391,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
       if ((ue->UE_mode[eNB_id] > PRACH) &&
 	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 					     subframe_rx,
 					     format0,
 					     ue,
@@ -3420,8 +3460,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
     else {
 #ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[UE  %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti,
-	    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+      LOG_I(PHY,"[UE  %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti,
+	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 	    ue->ulsch[eNB_id]->cba_rnti[0],
 	    dci_alloc_rx[i].format);
 
@@ -3674,11 +3714,14 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
       }
 
       if ((m==s0) && (m<4))
-  first_symbol_flag = 1;
+          first_symbol_flag = 1;
       else
-	first_symbol_flag = 0;
+          first_symbol_flag = 0;
 #if UE_TIMING_TRACE
-      start_meas(&ue->dlsch_llr_stats);
+      uint8_t slot = 0;
+      if(m >= ue->frame_parms.symbols_per_tti>>1)
+        slot = 1;
+      start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
 #endif
       // process DLSCH received in first slot
       rx_pdsch(ue,
@@ -3693,8 +3736,19 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
 	       i_mod,
 	       dlsch0->current_harq_pid);
 #if UE_TIMING_TRACE
-      stop_meas(&ue->dlsch_llr_stats);
+      stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
+#endif
 #endif
+
+
+      if(first_symbol_flag)
+      {
+          proc->first_symbol_available = 1;
+      }
     } // CRNTI active
   }
 }
@@ -3707,6 +3761,8 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
   LTE_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
   int harq_pid = 0;
   uint8_t *rar;
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
   ue->Mod_id,
@@ -3727,12 +3783,12 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
 						 frame_rx,
 						 ue->prach_resources[eNB_id]->ra_RNTI,
 						 dlsch0->harq_processes[0]->b,
-						 &ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+						 &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 						 ue->prach_resources[eNB_id]->ra_PreambleIndex,
 						 dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
 
-      ue->pdcch_vars[(subframe_rx+1)%RX_NB_TH][eNB_id]->crnti = ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
-      ue->pdcch_vars[(subframe_rx+2)%RX_NB_TH][eNB_id]->crnti = ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti;
+      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
+      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
       
       if (timing_advance!=0xffff) {
 
@@ -3740,12 +3796,12 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
               ue->Mod_id,
               frame_rx,
               subframe_rx,
-              ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
+              ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
               timing_advance);
 
   // remember this c-rnti is still a tc-rnti
 
-  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti_is_temporary = 1;
+  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1;
 	      
 	//timing_advance = 0;
 	process_timing_advance_rar(ue,proc,timing_advance);
@@ -3841,7 +3897,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       pdsch_vars = ue->pdsch_vars_p[eNB_id];
       break;
     case PDSCH:
-      pdsch_vars = ue->pdsch_vars[subframe_rx%RX_NB_TH][eNB_id];
+      pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -3876,7 +3932,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 						  dlsch0->harq_processes[harq_pid]->rb_alloc_even,
 						  dlsch0->harq_processes[harq_pid]->Qm,
 						  dlsch0->harq_processes[harq_pid]->Nl,
-						  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+						  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 						  frame_rx,
 						  subframe_rx,
 						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
@@ -3902,11 +3958,11 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
       LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
       LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
-      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
-      start_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
+      start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
 #endif
       ret = dlsch_decoding(ue,
 			   pdsch_vars->llr[0],
@@ -3920,17 +3976,17 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
 
 #if UE_TIMING_TRACE
-      stop_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
+      stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
 #if DISABLE_LOG_X
       printf(" --> Unscrambling for CW0 %5.3f\n",
               (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
       printf("AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
-              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
+              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
 #else
       LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
               (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
       LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
-              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
+              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
 #endif
 
 #endif
@@ -3942,7 +3998,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
                   dlsch1->harq_processes[harq_pid]->rb_alloc_even,
                   dlsch1->harq_processes[harq_pid]->Qm,
                   dlsch1->harq_processes[harq_pid]->Nl,
-                  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+                  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
                   frame_rx,
                   subframe_rx,
                   ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
@@ -3967,11 +4023,11 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
           LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
           LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
           LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
-          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
-          start_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
+          start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
 #endif
 
           ret1 = dlsch_decoding(ue,
@@ -3986,22 +4042,22 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
                   dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
 
 #if UE_TIMING_TRACE
-          stop_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
+          stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
 #if DISABLE_LOG_X
           printf(" --> Unscrambling for CW1 %5.3f\n",
                   (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
           printf("AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
+                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
 #else
           LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
                   (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
           LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
+                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
 #endif
 
 #endif
           LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
-                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
+                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
       }
 
       LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
@@ -4171,6 +4227,825 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 
 }
 
+/*!
+ * \brief This is the UE synchronize thread.
+ * It performs band scanning and synchonization.
+ * \param arg is a pointer to a \ref PHY_VARS_UE structure.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+#ifdef UE_SLOT_PARALLELISATION
+#define FIFO_PRIORITY   40
+void *UE_thread_slot1_dl_processing(void *arg) {
+
+    static __thread int UE_dl_slot1_processing_retval;
+    struct rx_tx_thread_data *rtd = arg;
+    UE_rxtx_proc_t *proc = rtd->proc;
+    PHY_VARS_UE    *ue   = rtd->UE;
+
+    int frame_rx;
+    uint8_t subframe_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot1;
+
+    uint8_t next_subframe_rx;
+    uint8_t next_subframe_slot0;
+
+    proc->instance_cnt_slot1_dl_processing=-1;
+    proc->subframe_rx=proc->sub_frame_start;
+
+    char threadname[256];
+    sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);
+
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 )
+        CPU_SET(threads.slot1_proc_one, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
+        CPU_SET(threads.slot1_proc_two, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
+        CPU_SET(threads.slot1_proc_three, &cpuset);
+
+    init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
+                threadname);
+
+    while (!oai_exit) {
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" );
+            exit_fun("nothing to add");
+        }
+        while (proc->instance_cnt_slot1_dl_processing < 0) {
+            // most of the time, the thread is waiting here
+            pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" );
+            exit_fun("nothing to add");
+        }
+
+        /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++)
+        {
+        frame_rx    = ue->proc.proc_rxtx[0].frame_rx;
+        subframe_rx = ue->proc.proc_rxtx[0].subframe_rx;
+        printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
+        }*/
+        frame_rx    = proc->frame_rx;
+        subframe_rx = proc->subframe_rx;
+        next_subframe_rx    = (1+subframe_rx)%10;
+        next_subframe_slot0 = next_subframe_rx<<1;
+
+        slot1  = (subframe_rx<<1) + 1;
+        pilot0 = 0;
+
+        //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
+
+        if (ue->frame_parms.Ncp == 0) {  // normal prefix
+            pilot1 = 4;
+        } else { // extended prefix
+            pilot1 = 3;
+        }
+
+        /**** Slot1 FE Processing ****/
+#if UE_TIMING_TRACE
+        start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#endif
+        // I- start dl slot1 processing
+        // do first symbol of next downlink subframe for channel estimation
+        /*
+        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
+        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
+        {
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        front_end_fft(ue,
+                pilot1,
+                slot1,
+                0,
+                0);
+         */
+        // 1- perform FFT
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            //if( (l != pilot0) && (l != pilot1))
+            {
+#if UE_TIMING_TRACE
+                start_meas(&ue->ofdm_demod_stats);
+#endif
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+                //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
+                front_end_fft(ue,
+                        l,
+                        slot1,
+                        0,
+                        0);
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+                stop_meas(&ue->ofdm_demod_stats);
+#endif
+            }
+        } // for l=1..l2
+
+        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        // 2- perform Channel Estimation for slot1
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            if(l == pilot1)
+            {
+                //wait until channel estimation for pilot0/slot1 is available
+                uint32_t wait = 0;
+                while(proc->chan_est_pilot0_slot1_available == 0)
+                {
+                    usleep(1);
+                    wait++;
+                }
+                //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
+            }
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot1,
+                    0);
+            ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode);
+        }
+        //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
+        front_end_chanEst(ue,
+                pilot0,
+                next_subframe_slot0,
+                0);
+
+        if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
+        {
+            ue_pbch_procedures(0,ue,proc,0);
+        }
+
+        proc->chan_est_slot1_available = 1;
+        //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+        //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
+
+        //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
+
+
+#if UE_TIMING_TRACE
+        stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+    //wait until pdcch is decoded
+    uint32_t wait = 0;
+    while(proc->dci_slot0_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait);
+
+
+    /**** Pdsch Procedure Slot1 ****/
+    // start slot1 thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx);
+
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#endif
+    // start slave thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    uint8_t eNB_id = 0;
+    uint8_t abstraction_flag = 0;
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        //wait until first ofdm symbol is processed
+        //wait = 0;
+        //while(proc->first_symbol_available == 0)
+        //{
+        //    usleep(1);
+        //    wait++;
+        //}
+        //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait);
+
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+        LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+        LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    // do procedures for P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    proc->llr_slot1_available=1;
+    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+            exit_fun("noting to add");
+        }
+        proc->instance_cnt_slot1_dl_processing--;
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
+            exit_fun("noting to add");
+        }
+    }
+    // thread finished
+        free(arg);
+        return &UE_dl_slot1_processing_retval;
+}
+#endif
+
+#ifdef UE_SLOT_PARALLELISATION
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_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,PHY_VARS_RN *phy_vars_rn)  {
+
+    int l,l2;
+    int pmch_flag=0;
+    int frame_rx = proc->frame_rx;
+    int subframe_rx = proc->subframe_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot0;
+    uint8_t slot1;
+    uint8_t first_ofdm_sym;
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+
+#if T_TRACER
+    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
+
+    T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
+            T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
+                    ue->frame_parms.samples_per_tti * 4));
+#endif
+
+    // start timers
+#ifdef UE_DEBUG_TRACE
+    LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
+    start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+    pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
+
+    if (do_pdcch_flag) {
+        // deactivate reception until we scan pdcch
+        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
+            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
+        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
+            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
+
+        if (ue->dlsch_SI[eNB_id])
+            ue->dlsch_SI[eNB_id]->active = 0;
+        if (ue->dlsch_p[eNB_id])
+            ue->dlsch_p[eNB_id]->active = 0;
+        if (ue->dlsch_ra[eNB_id])
+            ue->dlsch_ra[eNB_id]->active = 0;
+    }
+
+#ifdef DEBUG_PHY_PROC
+    LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
+            (r_type == multicast_relay) ? "RN/UE" : "UE",
+                    ue->Mod_id,frame_rx, subframe_rx);
+#endif
+
+
+
+
+    if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
+        l2 = 5;
+    } else if (pmch_flag == 1) { // do first 2 symbols only
+        l2 = 1;
+    } else { // normal subframe, last symbol to be processed is the first of the second slot
+        l2 = (ue->frame_parms.symbols_per_tti/2)-1;
+    }
+
+    int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
+    if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=0...l2
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 0;
+    } else {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 1;
+    }
+    slot0  = (subframe_rx<<1);
+    slot1  = (subframe_rx<<1) + 1;
+    pilot0 = 0;
+    if (ue->frame_parms.Ncp == 0) {  // normal prefix
+        pilot1 = 4;
+    } else { // extended prefix
+        pilot1 = 3;
+    }
+
+    //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    proc->chan_est_pilot0_slot1_available=0;
+    proc->llr_slot1_available=0;
+    proc->dci_slot0_available=0;
+    proc->first_symbol_available=0;
+    proc->chan_est_slot1_available=0;
+    //proc->channel_level=0;
+
+    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+        LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id );
+        exit_fun("nothing to add");
+    }
+
+    proc->instance_cnt_slot1_dl_processing++;
+    if (proc->instance_cnt_slot1_dl_processing == 0)
+    {
+    LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing );
+        if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id);
+            exit_fun("nothing to add");
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id );
+            exit_fun("nothing to add");
+        }
+
+    } else
+    {
+        LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing);
+        if (proc->instance_cnt_slot1_dl_processing > 2)
+            exit_fun("instance_cnt_slot1_dl_processing > 2");
+    }
+    //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,"");
+    AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,"");
+
+
+    /**** Slot0 FE Processing ****/
+    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
+#if UE_TIMING_TRACE
+    start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#endif
+    // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
+    front_end_fft(ue,
+            pilot0,
+            slot1,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
+    front_end_fft(ue,
+            pilot1,
+            slot0,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
+    front_end_chanEst(ue,
+            pilot1,
+            slot0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
+    front_end_chanEst(ue,
+            pilot0,
+            slot1,
+            0);
+    proc->chan_est_pilot0_slot1_available = 1;
+    //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+
+    // 2- perform FFT for other ofdm symbols other than pilots
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
+#if UE_TIMING_TRACE
+            start_meas(&ue->ofdm_demod_stats);
+#endif
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+            front_end_fft(ue,
+                    l,
+                    slot0,
+                    0,
+                    0);
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->ofdm_demod_stats);
+#endif
+        }
+    } // for l=1..l2
+
+    // 3- perform Channel Estimation for slot0
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot0,
+                    0);
+        }
+        ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
+    }
+
+    if (do_pdcch_flag) {
+#if UE_TIMING_TRACE
+        start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+        if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
+            LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+            printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+            LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+            //proc->dci_slot0_available = 1;
+            return(-1);
+        }
+        //proc->dci_slot0_available=1;
+#if UE_TIMING_TRACE
+        stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    }
+
+    //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
+
+    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    //wait until slot1 FE is done
+    uint32_t wait = 0;
+    while(proc->chan_est_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+    /**** End Subframe FE Processing ****/
+
+
+#if 0
+    //Trigger LLR parallelized for Slot 1
+    proc->dci_slot0_available=1;
+    printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
+#endif
+
+    /**** Pdsch Procedure Slot0 ****/
+    // start main thread for Pdsch Procedure (slot0)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
+    //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active);
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#endif
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+    }
+
+#if 1
+    // LLR linear
+    proc->dci_slot0_available=1;
+    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+    //wait until LLR Slot1 is done
+    wait = 0;
+    while(proc->llr_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    //printf("[slot0 dl processing] AbsSubframe %d.%d Channel Decoder Start wait %d\n",frame_rx,subframe_rx,wait);
+
+
+    //=====================================================================//
+#if UE_TIMING_TRACE
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+    LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active,
+    		ue->dlsch_SI[eNB_id]->active,
+			//ue->dlsch_p[eNB_id]->active,
+			ue->dlsch_ra[eNB_id]->active);
+    // Start Turbo decoder
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
+                &ue->dlsch_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                &ue->dlsch_SI_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_SI[eNB_id]->active = 0;
+    }
+
+    // do procedures for P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                &ue->dlsch_p_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_p[eNB_id]->active = 0;
+    }
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                &ue->dlsch_ra_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_ra[eNB_id]->active = 0;
+    }
+
+#if UE_TIMING_TRACE
+        stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+        // duplicate harq structure
+        uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
+        LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+        harq_status_t    *current_harq_ack       = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
+
+        // For Debug parallelisation
+        //if (current_harq_ack->ack == 0) {
+            //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round);
+        //}
+        for(uint8_t rx_th_idx=1; rx_th_idx<RX_NB_TH; rx_th_idx++)
+        {
+            LTE_DL_UE_HARQ_t *harq_processes_dest  = ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid];
+            harq_status_t    *harq_ack_dest        = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx];
+
+            copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+            copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+        }
+    /*
+    LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+    LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+
+    harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+    harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+    harq_status_t *harq_ack_dest1    = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+
+    copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+    copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+    copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
+    copy_ack_struct(harq_ack_dest1, current_harq_ack);
+    */
+    if (subframe_rx==9) {
+        if (frame_rx % 10 == 0) {
+            if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
+                ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
+
+            ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
+            ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
+        }
+
+
+        ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
+        ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
+        LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
+                ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
+                ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
+
+#if UE_AUTOTEST_TRACE
+        if ((frame_rx % 100 == 0)) {
+            LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
+        }
+#endif
+
+    }
+
+#ifdef EMOS
+    phy_procedures_emos_UE_RX(ue,slot,eNB_id);
+#endif
+
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+    return (0);
+}
+#endif
+
+
 int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_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,PHY_VARS_RN *phy_vars_rn) {
@@ -4181,7 +5056,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
   int frame_rx = proc->frame_rx;
   int subframe_rx = proc->subframe_rx;
 
-
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
 
@@ -4199,7 +5075,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 #endif
 
 #if UE_TIMING_TRACE
-  start_meas(&ue->phy_proc_rx[subframe_rx%RX_NB_TH]);
+  start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
   start_meas(&ue->generic_stat);
 #endif
 
@@ -4207,10 +5083,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 
   if (do_pdcch_flag) {
   // deactivate reception until we scan pdcch
-  if (ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0])
-    ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->active = 0;
-  if (ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][1])
-    ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][1]->active = 0;
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
+    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
+    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
 
   if (ue->dlsch_SI[eNB_id])
     ue->dlsch_SI[eNB_id]->active = 0;
@@ -4281,11 +5157,16 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 	  ((pmch_flag==1)&(l==l2)))  {
 	LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
 
+	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
 	if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
 	  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx);
 	  return(-1);
 	}
-	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
+	//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
+    //printf("subframe %d n_pdcch_sym %d pdcch procedures  %5.3f \n",
+    //        subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+    //     (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
       }
     }
 
@@ -4322,15 +5203,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
   start_meas(&ue->generic_stat);
 #endif
   // do procedures for C-RNTI
-  if (ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->active == 1) {
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
 			NULL,
-			ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
 
@@ -4348,7 +5229,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 			SI_PDSCH,
 			ue->dlsch_SI[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
@@ -4363,7 +5244,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 			P_PDSCH,
 			ue->dlsch_p[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
@@ -4378,7 +5259,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 			RA_PDSCH,
 			ue->dlsch_ra[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
@@ -4443,16 +5324,16 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 
   // do procedures for C-RNTI
   LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
-  if (ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->active == 1) {
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
 #if UE_TIMING_TRACE
-    start_meas(&ue->pdsch_procedures_stat);
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]);
 #endif
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
 			NULL,
 			1+(ue->frame_parms.symbols_per_tti>>1),
 			ue->frame_parms.symbols_per_tti-1,
@@ -4460,26 +5341,26 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
     LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
     LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
 #if UE_TIMING_TRACE
-    stop_meas(&ue->pdsch_procedures_stat);
-    start_meas(&ue->dlsch_procedures_stat);
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
 #endif
     ue_dlsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0],
-			ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][1],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
 			&ue->dlsch_errors[eNB_id],
 			mode,
 			abstraction_flag);
 #if UE_TIMING_TRACE
-    stop_meas(&ue->dlsch_procedures_stat);
+    stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
 #if DISABLE_LOG_X
-    printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
-    printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
+    printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+    printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
 #else
-    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
-    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
+    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
 #endif
 
 #endif
@@ -4492,20 +5373,20 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 #endif
 
 #if 0
-  if(subframe_rx==5 &&  ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid]->nb_rb > 20){
+  if(subframe_rx==5 &&  ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){
        //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
        //write_output("llr.m","llr",  &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
 
-       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx%RX_NB_TH].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
-       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[(subframe_rx+1)%RX_NB_TH].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
 
-       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
 
-       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx%RX_NB_TH].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
-       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[subframe_rx%RX_NB_TH][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
-       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[subframe_rx%RX_NB_TH][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
-       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
-       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe%RX_NB_TH][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
 
        AssertFatal (0,"");
   }
@@ -4583,14 +5464,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
 
   // duplicate harq structure
 
-  uint8_t          current_harq_pid        = ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->current_harq_pid;
-  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
-  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
-  LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+  uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
+  LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
 
-  harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
-  harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
-  harq_status_t *harq_ack_dest1    = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[subframe_rx];
 
   copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
   copy_ack_struct(harq_ack_dest, current_harq_ack);
@@ -4635,11 +5516,11 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
 
 #if UE_TIMING_TRACE
-  stop_meas(&ue->phy_proc_rx[subframe_rx%RX_NB_TH]);
+  stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
 #if DISABLE_LOG_X
-  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx%RX_NB_TH].p_time/(cpuf*1000.0));
+  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
 #else
-  LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx%RX_NB_TH].p_time/(cpuf*1000.0));
+  LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
 #endif
 #endif
 
@@ -4704,7 +5585,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
 #if UE_TIMING_TRACE
-  start_meas(&ue->phy_proc);
+  start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
 #endif
 #if defined(ENABLE_ITTI)
 
@@ -4768,6 +5649,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
 
     if (ue->mac_enabled==1) {
       if (slot==0) {
+          //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx);
         ret = mac_xface->ue_scheduler(ue->Mod_id,
             frame_rx,
             subframe_rx,
@@ -4798,7 +5680,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
 #if UE_TIMING_TRACE
-    stop_meas(&ue->phy_proc);
+    stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
 #endif
   } // slot
 }
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 6b46991e879b308d31124c7bee2ac2b3d4ddb7b3..274a25fb703cea98f177f503c14ca678e2552476 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -52,7 +52,7 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
 
   Po_PUCCH = get_PL(ue->Mod_id,ue->CC_id,eNB_id)+
     ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
-    ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch;
+    ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch;
 
   switch (pucch_fmt) {
   case pucch_format1:
@@ -95,19 +95,19 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
   if (pucch_fmt!=pucch_format1) {
     LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-          ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch);
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch);
   } else {
     LOG_D(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-          ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch);
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch);
   }
 
   return(Po_PUCCH);
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 5613e0efc29ad3c4594074393f4f6b05e74d21b2..02591dcc8f3ecd608372bae441b6d598c8e6cdd9 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -390,10 +390,11 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = n_rnti+k;
-          dci_alloc[*num_dci].format     = format1;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = n_rnti+k;
+          dci_alloc[*num_dci].format       = format1;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
 	  //          printf("Generating dlsch params for user %d\n",k);
@@ -530,11 +531,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = SI_RNTI;
-          dci_alloc[*num_dci].format     = format1A;
-          dci_alloc[*num_dci].firstCCE       = 0;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = SI_RNTI;
+          dci_alloc[*num_dci].format       = format1A;
+          dci_alloc[*num_dci].firstCCE     = 0;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -699,10 +701,11 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = n_rnti+k;
-          dci_alloc[*num_dci].format     = format2A;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = n_rnti+k;
+          dci_alloc[*num_dci].format       = format2A;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           //printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
@@ -839,11 +842,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = SI_RNTI;
-          dci_alloc[*num_dci].format     = format1A;
-          dci_alloc[*num_dci].firstCCE       = 0;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = SI_RNTI;
+          dci_alloc[*num_dci].format       = format1A;
+          dci_alloc[*num_dci].firstCCE     = 0;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           //printf("Generating dlsch params for user %d\n",k);
@@ -1009,10 +1013,11 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = n_rnti+k;
-          dci_alloc[*num_dci].format     = format2;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = n_rnti+k;
+          dci_alloc[*num_dci].format       = format2;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1149,11 +1154,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[*num_dci].dci_length = dci_length;
-          dci_alloc[*num_dci].L          = 1;
-          dci_alloc[*num_dci].rnti       = SI_RNTI;
-          dci_alloc[*num_dci].format     = format1A;
-          dci_alloc[*num_dci].firstCCE       = 0;
+          dci_alloc[*num_dci].dci_length   = dci_length;
+          dci_alloc[*num_dci].L            = 1;
+          dci_alloc[*num_dci].rnti         = SI_RNTI;
+          dci_alloc[*num_dci].format       = format1A;
+          dci_alloc[*num_dci].firstCCE     = 0;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1181,11 +1187,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
       case 5:
       case 6:
         memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-        dci_alloc[*num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-        dci_alloc[*num_dci].L          = 1;
-        dci_alloc[*num_dci].rnti       = n_rnti+k;
-        dci_alloc[*num_dci].format     = format1E_2A_M10PRB;
-        dci_alloc[*num_dci].firstCCE       = 4*k;
+        dci_alloc[*num_dci].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+        dci_alloc[*num_dci].L            = 1;
+        dci_alloc[*num_dci].rnti         = n_rnti+k;
+        dci_alloc[*num_dci].format       = format1E_2A_M10PRB;
+        dci_alloc[*num_dci].firstCCE     = 4*k;
+        dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
 					   subframe,
@@ -1224,12 +1231,10 @@ int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
 DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) {
 
   if (subframeP == subframe) {
-    DCI_pdu.Num_ue_spec_dci   = num_ue_spec_dci;
-    DCI_pdu.Num_common_dci    = num_common_dci;
+    DCI_pdu.Num_dci   = num_ue_spec_dci + num_common_dci;
     DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
   } else {
-    DCI_pdu.Num_ue_spec_dci   = 0;
-    DCI_pdu.Num_common_dci    = 0;
+    DCI_pdu.Num_dci   = 0;
     DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
   }
 
@@ -1346,7 +1351,7 @@ int main(int argc, char **argv)
   // void *data;
   // int ii;
   //  int bler;
-  double blerr[4],uncoded_ber; //,avg_ber;
+  double blerr[4],uncoded_ber=0; //,avg_ber;
   short *uncoded_ber_bit=NULL;
   uint8_t N_RB_DL=25,osf=1;
   frame_t frame_type = FDD;
@@ -2017,7 +2022,7 @@ int main(int argc, char **argv)
     }
   */
 
-  UE->pdcch_vars[subframe & 0x1][0]->crnti = n_rnti;
+  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
 
   // Fill in UL_alloc
   UL_alloc_pdu.type    = 0;
@@ -2258,7 +2263,7 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
+      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
       errs[0]=0;
       errs[1]=0;
       errs[2]=0;
@@ -2291,7 +2296,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2327,7 +2332,7 @@ int main(int argc, char **argv)
       struct list time_vector_rx_dec;
       initialize(&time_vector_rx_dec);
 
-      eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[subframe&1];
+      eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[UE->current_thread_id[subframe]];
 
       for (trials = 0; trials<n_frames; trials++) {
 	//printf("Trial %d\n",trials);
@@ -2336,10 +2341,10 @@ int main(int argc, char **argv)
 
         //if (trials%100==0)
         eNB2UE[0]->first_run = 1;
-	UE->dlsch[subframe&0x1][eNB_id][0]->harq_ack[subframe].ack = 0;
-	UE->dlsch[subframe&0x1][eNB_id][1]->harq_ack[subframe].ack = 0;
+	UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0;
+	UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0;
 
-        while ((round < num_rounds) && (UE->dlsch[subframe&0x1][eNB_id][0]->harq_ack[subframe].ack == 0)) {
+        while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) {
 	  //	  printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
@@ -2512,7 +2517,7 @@ int main(int argc, char **argv)
 	  DL_channel(eNB,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd);
 
 
-	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[subframe&1];
+	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
 	  proc->subframe_rx = subframe;
 	  UE->UE_mode[0] = PUSCH;
 
@@ -2534,7 +2539,9 @@ int main(int argc, char **argv)
 						   (void *)&dci_alloc[0].dci_pdu,
 						   n_rnti,
 						   dci_alloc[0].format,
-						   UE->dlsch[proc->subframe_rx&0x1][eNB_id],
+						   UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+						   UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+                           UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
 						   &UE->frame_parms,
 						   UE->pdsch_config_dedicated,
 						   SI_RNTI,
@@ -2545,10 +2552,10 @@ int main(int argc, char **argv)
 
 		dump_dci(&UE->frame_parms, &dci_alloc[0]);
 
-		//UE->dlsch[proc->subframe_rx&0x1][eNB_id][0]->active = 1;
-		//UE->dlsch[proc->subframe_rx&0x1][eNB_id][1]->active = 1;
+		//UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1;
+		//UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1;
 
-		UE->pdcch_vars[proc->subframe_rx&0x1][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
+		UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
 
 		UE->dlsch_received[eNB_id]++;
 	    } else {
@@ -2556,11 +2563,11 @@ int main(int argc, char **argv)
 	    }
 	  }
 
-	  dci_received = UE->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->dci_received;
+	  dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
 
 	  phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx,no_relay,NULL);
 
-	  dci_received = dci_received - UE->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->dci_received;
+	  dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
 
 	  if (dci_flag && (dci_received == 0)) {
 	    //printf("DCI not received\n");
@@ -2591,35 +2598,35 @@ int main(int argc, char **argv)
 	    //common vars
 	    write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
 
-	    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
 	    if (UE->frame_parms.nb_antennas_rx>1) {
 	      write_output("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
-	      write_output("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	      write_output("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 	    }
 
 	    write_output("dlsch00_r0.m","dl00_r0",
-			 &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+			 &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
 			 UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
 	    if (UE->frame_parms.nb_antennas_rx>1)
 	      write_output("dlsch01_r0.m","dl01_r0",
-			   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
 			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
 	    if (eNB->frame_parms.nb_antennas_tx>1)
 	      write_output("dlsch10_r0.m","dl10_r0",
-			   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
 			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
 	    if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
 	      write_output("dlsch11_r0.m","dl11_r0",
-			   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
 			   UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
 
 	    //pdsch_vars
 
-	    dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+	    dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
 
 	    write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
 
@@ -2635,15 +2642,15 @@ int main(int argc, char **argv)
 
 
 
-          if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_ack[subframe].ack == 1) {
+          if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) {
 
-            avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt;
+            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
             iter_trials++;
 
             if (n_frames==1)
               printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber);
 
-            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS;
+            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
             TB0_active = 0;
 
 
@@ -2651,25 +2658,25 @@ int main(int argc, char **argv)
 	  else {
             errs[round]++;
 
-            avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt-1;
+            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
             iter_trials++;
 
             if (n_frames==1) {
               //if ((n_frames==1) || (SNR>=30)) {
               printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
 
-              for (s=0; s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) {
-                if (s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus)
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus;
+              for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
+                if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
                 else
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus;
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
 
                 Kr_bytes = Kr>>3;
 
                 printf("Decoded_output (Segment %d):\n",s);
 
                 for (i=0; i<Kr_bytes; i++)
-                  printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+                  printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
               }
 
               sprintf(fname,"rxsig0_r%d.m",round);
@@ -2678,7 +2685,7 @@ int main(int argc, char **argv)
               sprintf(fname,"rxsigF0_r%d.m",round);
               sprintf(vname,"rxs0F_r%d",round);
 
-              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"rxsig1_r%d.m",round);
@@ -2686,20 +2693,20 @@ int main(int argc, char **argv)
                 write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
                 sprintf(fname,"rxsigF1_r%d.m",round);
                 sprintf(vname,"rxs1F_r%d.m",round);
-                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
               }
 
               sprintf(fname,"dlsch00_r%d.m",round);
               sprintf(vname,"dl00_r%d",round);
               write_output(fname,vname,
-                           &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                           &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                            UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"dlsch01_r%d.m",round);
                 sprintf(vname,"dl01_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -2707,7 +2714,7 @@ int main(int argc, char **argv)
                 sprintf(fname,"dlsch10_r%d.m",round);
                 sprintf(vname,"dl10_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -2715,18 +2722,18 @@ int main(int argc, char **argv)
                 sprintf(fname,"dlsch11_r%d.m",round);
                 sprintf(vname,"dl11_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
               //pdsch_vars
-              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
 
 
               //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
               //write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
               //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
-              //write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              //write_output("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
 	      //pdcch_vars
 	      write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
 	      write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
@@ -2740,7 +2747,7 @@ int main(int argc, char **argv)
             //      printf("round %d errors %d/%d\n",round,errs[round],trials);
 
             round++;
-            //      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++;
+            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
           }
 
 	  if (xforms==1) {
@@ -2751,7 +2758,7 @@ int main(int argc, char **argv)
 			 subframe);
 	  }
 
-	  UE->proc.proc_rxtx[subframe&1].frame_rx++;
+	  UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
 	}  //round
 
         //      printf("\n");
@@ -2762,7 +2769,7 @@ int main(int argc, char **argv)
         //len = chbch_stats_read(stats_buffer,NULL,0,4096);
         //printf("%s\n\n",stats_buffer);
 
-        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
+        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
           UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
           LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
                 UE->bitrate[eNB_id]/1000);
@@ -2781,10 +2788,10 @@ int main(int argc, char **argv)
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
-        double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
 
         if (t_tx > t_tx_max)
           t_tx_max = t_tx;
@@ -2930,7 +2937,7 @@ int main(int argc, char **argv)
              //rate*effective_rate,
              100*effective_rate,
              //rate,
-             //rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+             //rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
              (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
@@ -2970,10 +2977,10 @@ int main(int argc, char **argv)
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -2997,17 +3004,17 @@ int main(int argc, char **argv)
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
         printf("DLSCH unscrambling time                             :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
                UE->dlsch_unscrambling_stats.trials);
-        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                                   2)/UE->dlsch_decoding_stats[subframe&1].trials - pow((double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000,2));
+        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
         printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
                eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials,
-               (double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&1].trials,
-               (double)UE->dlsch_decoding_stats[subframe&1].max/cpu_freq_GHz/1000.0);
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials,
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0);
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -3185,12 +3192,12 @@ int main(int argc, char **argv)
                 eNB->dlsch_modulation_stats.trials,
                 eNB->dlsch_scrambling_stats.trials,
                 eNB->dlsch_encoding_stats.trials,
-                UE->phy_proc_rx[subframe&0x1].trials,
+                UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
                 UE->ofdm_demod_stats.trials,
                 UE->dlsch_rx_pdcch_stats.trials,
                 UE->dlsch_llr_stats.trials,
                 UE->dlsch_unscrambling_stats.trials,
-                UE->dlsch_decoding_stats[subframe&1].trials
+                UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
                );
         fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
                 get_time_meas_us(&eNB->phy_proc_tx),
@@ -3198,12 +3205,12 @@ int main(int argc, char **argv)
                 get_time_meas_us(&eNB->dlsch_modulation_stats),
                 get_time_meas_us(&eNB->dlsch_scrambling_stats),
                 get_time_meas_us(&eNB->dlsch_encoding_stats),
-                get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+                get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
                 nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
                 get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
                 3*get_time_meas_us(&UE->dlsch_llr_stats),
                 get_time_meas_us(&UE->dlsch_unscrambling_stats),
-                get_time_meas_us(&UE->dlsch_decoding_stats[subframe&1])
+                get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
                );
         //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
         fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
@@ -3238,12 +3245,12 @@ int main(int argc, char **argv)
         eNB->dlsch_modulation_stats.trials,
         eNB->dlsch_scrambling_stats.trials,
         eNB->dlsch_encoding_stats.trials,
-        UE->phy_proc_rx[subframe&0x1].trials,
+        UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
         UE->ofdm_demod_stats.trials,
         UE->dlsch_rx_pdcch_stats.trials,
         UE->dlsch_llr_stats.trials,
         UE->dlsch_unscrambling_stats.trials,
-        UE->dlsch_decoding_stats[subframe&1].trials);
+        UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials);
         */
         printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
 	test_passed = 1;
@@ -3298,7 +3305,7 @@ int main(int argc, char **argv)
     printf("eNB %d\n",i);
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
   if (test_perf && !test_passed)
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index ee333ac74fecb9d2fed9a2692e0e878c31005d1d..f493336e988aa453a525609ad845d2570476c4fe 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -933,7 +933,7 @@ int main(int argc, char **argv)
     //    bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
   }
 
-  UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti;
+  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
   UE->transmission_mode[eNB_id]=transmission_mode;
   if (UE->transmission_mode[eNB_id] !=4)
       UE->measurements.rank[eNB_id]=0;
@@ -1050,15 +1050,15 @@ int main(int argc, char **argv)
   }
 
   for (i=0; i<2; i++) {
-    UE->dlsch[subframe&0x1][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
-    if (!UE->dlsch[subframe&0x1][0][i]) {
+    if (!UE->dlsch[UE->current_thread_id[subframe]][0][i]) {
 
       printf("Can't get ue dlsch structures\n");
       exit(-1);
     }
 
-    UE->dlsch[subframe&0x1][0][i]->rnti   = n_rnti;
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]->rnti   = n_rnti;
   }
 
   // structure for SIC at UE
@@ -1197,10 +1197,11 @@ int main(int argc, char **argv)
             }
           }
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format1;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format1;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
 
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
@@ -1334,11 +1335,12 @@ int main(int argc, char **argv)
             }
           }
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE   = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
           printf("Generating dlsch params for user %d\n",k);
           generate_eNB_dlsch_params_from_dci(0,
@@ -1496,10 +1498,11 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2A;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format2A;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
 
@@ -1633,11 +1636,12 @@ int main(int argc, char **argv)
             }
           }
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1827,10 +1831,11 @@ int main(int argc, char **argv)
            }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format2;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
 
@@ -1964,11 +1969,12 @@ int main(int argc, char **argv)
             }
           }
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
             printf("Generating dlsch params for user %d\n",k);
@@ -1995,11 +2001,12 @@ int main(int argc, char **argv)
       case 5:
       case 6:
         memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-        dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-        dci_alloc[num_dci].L          = 1;
-        dci_alloc[num_dci].rnti       = n_rnti+k;
-        dci_alloc[num_dci].format     = format1E_2A_M10PRB;
-        dci_alloc[num_dci].firstCCE       = 4*k;
+        dci_alloc[num_dci].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+        dci_alloc[num_dci].L            = 1;
+        dci_alloc[num_dci].rnti         = n_rnti+k;
+        dci_alloc[num_dci].format       = format1E_2A_M10PRB;
+        dci_alloc[num_dci].firstCCE     = 4*k;
+        dci_alloc[num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
                                            subframe,
@@ -2164,7 +2171,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2219,8 +2226,8 @@ int main(int argc, char **argv)
 
         eNB2UE[0]->first_run = 1;
 
-        ret[0] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
-        ret[1] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
+        ret[0] = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
+        ret[1] = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
 
         resend_cw0_cw1=1;
         resend_cw1=0;
@@ -2233,13 +2240,13 @@ int main(int argc, char **argv)
 
         while (((transmission_mode == 3 || transmission_mode == 4) &&
                ((round < num_rounds) && (((rank_indc[0] == 1) ||((rank_indc[0] == 0) && (rank_adapt==0))) &&
-                ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) ||
-               (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations))||
-                (rank_indc[0] ==0 && rank_adapt==1 && ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations )))) ||
+                ((ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) ||
+               (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations))||
+                (rank_indc[0] ==0 && rank_adapt==1 && ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations )))) ||
                ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) &&
-               (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) {
-         // printf("ret[0] =% d UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations = %d\n", ret[0], UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations);
-         // printf("ret[1] =% d UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations = %d\n", ret[1], UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations);
+               (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)))) {
+         // printf("ret[0] =% d UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations = %d\n", ret[0], UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations);
+         // printf("ret[1] =% d UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations = %d\n", ret[1], UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations);
 
 #ifdef DEBUG_HARQ
         printf("\n [DLSIM] On top round is %d\n", round);
@@ -2252,10 +2259,10 @@ int main(int argc, char **argv)
 
           //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]);
 
-        /*if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) {
+        /*if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) {
           round_trials[0][round]++;
           round_trials[1][round]++;
-        } else if ((ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations))
+        } else if ((ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations))
           round_trials[1][round]++;*/
 
 
@@ -2467,7 +2474,7 @@ int main(int argc, char **argv)
                                                          SI_RNTI,
                                                          0,
                                                          P_RNTI,
-                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                         UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                          transmission_mode>=7?transmission_mode:0
                                                          );
                     }
@@ -2629,7 +2636,7 @@ int main(int argc, char **argv)
                                                        SI_RNTI,
                                                        0,
                                                        P_RNTI,
-                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                        transmission_mode>=7?transmission_mode:0
                                                        );
                     break;
@@ -2879,7 +2886,7 @@ int main(int argc, char **argv)
                                                            SI_RNTI,
                                                            0,
                                                            P_RNTI,
-                                                           UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                            transmission_mode>=7?transmission_mode:0
                                                            );
                     } else if (rank_indc[0]==0 && rank_adapt==1) {
@@ -2929,7 +2936,7 @@ int main(int argc, char **argv)
                                                        SI_RNTI,
                                                        0,
                                                        P_RNTI,
-                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                        transmission_mode>=7?transmission_mode:0
                                                        );
                   }
@@ -3152,7 +3159,7 @@ int main(int argc, char **argv)
                                                        SI_RNTI,
                                                        0,
                                                        P_RNTI,
-                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                        transmission_mode>=7?transmission_mode:0
                                                        );
                   } else if (rank_indc[0]==0 && rank_adapt==1) {
@@ -3202,7 +3209,7 @@ int main(int argc, char **argv)
                                                        SI_RNTI,
                                                        0,
                                                        P_RNTI,
-                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
                                                        transmission_mode>=7?transmission_mode:0
                                                        );
                   }
@@ -3217,8 +3224,7 @@ int main(int argc, char **argv)
                 }
               }
             }
-            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
-                                                   num_common_dci,
+            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci + num_common_dci,
                                                    dci_alloc,
                                                    0,
                                                    AMP,
@@ -3278,7 +3284,7 @@ int main(int argc, char **argv)
               // use the PMI from previous trial
                 if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
                   eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
-                  UE->dlsch[subframe&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
                   if (n_users>1)
                     eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
                   /*
@@ -3290,7 +3296,7 @@ int main(int argc, char **argv)
           */
                 }
 #ifdef DEBUG_HARQ
-                printf("[DLSIM] UE->dlsch[subframe&0x1][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[subframe&0x1][0][TB]->pmi_alloc);
+                printf("[DLSIM] UE->dlsch[UE->current_thread_id[subframe]][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc);
 #endif
 
                 //if standard case when both TBs are active
@@ -3305,7 +3311,7 @@ int main(int argc, char **argv)
                       printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
 
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
                   }
 
                   else if (updated_csi == 0){
@@ -3318,7 +3324,7 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
-                      UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+                      UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
                     }
 
                     else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
@@ -3329,7 +3335,7 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
-                      UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+                      UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
                     }
                   } else if (updated_csi == 1){
 
@@ -3348,11 +3354,11 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I quantize from ENodeB 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
                   }
                   else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
 #ifdef DEBUG_HARQ
@@ -3368,17 +3374,17 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I quantize from ENodeB 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
                   }
 
                 }
             }
 #ifdef DEBUG_HARQ
-            printf("[DLSIM 2 ] UE->dlsch[subframe&0x1][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[subframe&0x1][0][TB]->pmi_alloc);
+            printf("[DLSIM 2 ] UE->dlsch[UE->current_thread_id[subframe]][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc);
 #endif
 
                 start_meas(&eNB->dlsch_encoding_stats);
@@ -3674,7 +3680,7 @@ int main(int argc, char **argv)
           pilot3 = 9;
         }
 
-        start_meas(&UE->phy_proc_rx[subframe&0x1]);
+        start_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
         // Inner receiver scheduling for 3 slots
           for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) {
             for (l=0;l<pilot2;l++) {
@@ -3710,9 +3716,9 @@ int main(int argc, char **argv)
                     for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
                           (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
                           (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                         }
                       }
@@ -3721,21 +3727,21 @@ int main(int argc, char **argv)
               }else {
                 if (transmission_mode==4) {
                   for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
                   }
                 } else {
                     for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
                         }
                        }
                     }
@@ -3817,7 +3823,7 @@ int main(int argc, char **argv)
 
                   stop_meas(&UE->dlsch_rx_pdcch_stats);
                   // overwrite number of pdcch symbols
-                  UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols;
+                  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols = num_pdcch_symbols;
 
                   dci_cnt = dci_decoding_procedure(UE,
                                                    dci_alloc_rx,1,
@@ -3842,10 +3848,10 @@ int main(int argc, char **argv)
                     //printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti);
 
                      if (round == 0) {
-                        UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
                       }
                       if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) {
-                        UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->first_tx=1;
                       }
 
                     if ((dci_alloc_rx[i].rnti == n_rnti) &&
@@ -3854,40 +3860,42 @@ int main(int argc, char **argv)
                                                            dci_alloc_rx[i].dci_pdu,
                                                            dci_alloc_rx[i].rnti,
                                                            dci_alloc_rx[i].format,
-                                                           UE->dlsch[subframe&0x1][0],
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0],
                                                            &UE->frame_parms,
                                                            UE->pdsch_config_dedicated,
                                                            SI_RNTI,
                                                            0,
                                                            P_RNTI,
                                                            transmission_mode<7?0:transmission_mode,
-                                                           UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0)==0)) {
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0)==0)) {
                       dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
                       coded_bits_per_codeword[0]= get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
-                                                      UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols,
                                                       0,
                                                       subframe,
                                                       transmission_mode>=7?transmission_mode:0);
                       if (transmission_mode == 3 || transmission_mode == 4) {
                         coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
-                                                      UE->pdcch_vars[subframe&0x1][1]->num_pdcch_symbols,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][1]->num_pdcch_symbols,
                                                       0,
                                                       subframe,
                                                       transmission_mode>=7?transmission_mode:0);
                       }
                       /*
-                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword);
-                      rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs);
+                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs)][UE->dlsch[UE->current_thread_id[subframe]][0][0]->nb_rb-1]/(coded_bits_per_codeword);
+                      rate*=get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs);
                       */
-                      printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS);
+                      printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->TBS);
 
                       dlsch_active = 1; // what does it indicates???
                     } else {
@@ -3908,14 +3916,14 @@ int main(int argc, char **argv)
                       }
                   }
                   } else { //dci_flag == 0
-                      UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti;
-                      UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols;
+                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
+                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols = num_pdcch_symbols;
                       if (round == 0) {
-                        UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
-                        UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->first_tx=1;
                       }
 #ifdef DEBUG_HARQ
-                   printf("[DLSIM 3 ] UE->dlsch[subframe&0x1][0][1]->pmi_alloc %d \n", UE->dlsch[subframe&0x1][0][1]->pmi_alloc);
+                   printf("[DLSIM 3 ] UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc %d \n", UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc);
 #endif
 
                    if (transmission_mode==4 && use_sic_receiver==1){
@@ -3935,33 +3943,37 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format1 : format1A,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       case 3:
 
-                        //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                        //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
 
                         generate_ue_dlsch_params_from_dci(0,
                                                           subframe,
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format2A : format1A,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
-                        //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
+                        //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                         break;
                       case 4:
                         generate_ue_dlsch_params_from_dci(0,
@@ -3969,14 +3981,16 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format2 : format1A,//format1A only for a codeblock
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       case 5:
                       case 6:
@@ -3985,14 +3999,16 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu2_1E[0],
                                                           C_RNTI,
                                                           format1E_2A_M10PRB,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       }
                       dlsch_active = 1;
@@ -4001,13 +4017,13 @@ int main(int argc, char **argv)
 
               if (dlsch_active == 1) {
                 if (TB0_active==1)
-                  cur_harq_pid =UE->dlsch[subframe&0x1][0][0]->current_harq_pid;
+                  cur_harq_pid =UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid;
                 else
-                  cur_harq_pid =UE->dlsch[subframe&0x1][0][1]->current_harq_pid;
+                  cur_harq_pid =UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid;
 
                 if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix
               /*    if (transmission_mode == 5) {
-                    if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) &&
+                    if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) &&
                         (openair_daq_vars.use_ia_receiver ==1)) {
                       rx_type = rx_IC_single_stream;
                     } else {
@@ -4018,7 +4034,7 @@ int main(int argc, char **argv)
 
                   start_meas(&UE->dlsch_llr_stats);
 
-                  for (m=UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols; m<pilot2; m++) {
+                  for (m=UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols; m<pilot2; m++) {
                     if (rx_pdsch(UE,
                                  PDSCH,
                                  eNB_id,
@@ -4026,10 +4042,10 @@ int main(int argc, char **argv)
                                  0,
                                  subframe,
                                  m,
-                                 (m==UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols)?1:0,
+                                 (m==UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols)?1:0,
                                  rx_type,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1){
                       dlsch_active = 0;
                       break;
                     }
@@ -4088,7 +4104,7 @@ int main(int argc, char **argv)
             if (trials==0 && round==0 && transmission_mode>=4){
               for (iii=0; iii<NB_RB; iii++){
                 //fprintf(csv_fd, "%d, %d", (UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
-                fprintf(csv_fd,"%x,",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]));
+                fprintf(csv_fd,"%x,",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]));
                 //printf("%x ",(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
               }
             }
@@ -4115,7 +4131,7 @@ int main(int argc, char **argv)
               break;
             }
 
-            UE->dlsch[subframe&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
             coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms,
                                             eNB->dlsch[0][TB]->harq_processes[0]->nb_rb,
                                             eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc,
@@ -4125,12 +4141,12 @@ int main(int argc, char **argv)
                                             0,subframe,
                                             transmission_mode>=7?transmission_mode:0);
 
-            UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB];
-            UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs);
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB];
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs);
 
             if (n_frames==2) {
               printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB],
-                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->TBS);
+                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->TBS);
 
               // calculate uncoded BER
               uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]);
@@ -4139,7 +4155,7 @@ int main(int argc, char **argv)
 
               sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB);
               sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB);
-              write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0);
+              write_output(fname,vname, UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0);
               sprintf(fname,"dlsch_cw%d_e.m", TB);
               sprintf(vname,"dlschcw%d_e", TB);
               write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4);
@@ -4147,7 +4163,7 @@ int main(int argc, char **argv)
               printf("trials=%d\n", trials);
 
               for (i=0;i<coded_bits_per_codeword[TB];i++)
-                if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) {
+                if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword][i]<0)) {
                   uncoded_ber_bit[i] = 1;
                   uncoded_ber++;
                 }
@@ -4169,38 +4185,38 @@ int main(int argc, char **argv)
             start_meas(&UE->dlsch_unscrambling_stats);
             dlsch_unscrambling(&UE->frame_parms,
                                0,
-                               UE->dlsch[subframe&0x1][0][TB],
+                               UE->dlsch[UE->current_thread_id[subframe]][0][TB],
                                coded_bits_per_codeword[TB],
-                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[TB],
+                               UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[TB],
                                TB,
                                subframe<<1);
             stop_meas(&UE->dlsch_unscrambling_stats);
 
-            start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+            start_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 #ifdef DEBUG_HARQ
-            //printf("non-SIC decoding TB %d LLR is %d\n", TB, UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword);
+            //printf("non-SIC decoding TB %d LLR is %d\n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword);
 #endif
             ret[TB] = dlsch_decoding(UE,
-                                     UE->pdsch_vars[subframe&0x1][eNB_id]->llr[TB],
+                                     UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[TB],
                                      &UE->frame_parms,
-                                     UE->dlsch[subframe&0x1][0][TB],
-                                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid],
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB],
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid],
                                      0,
                                      subframe,
-                                     UE->dlsch[subframe&0x1][0][TB]->current_harq_pid,
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid,
                                      1,
                                      llr8_flag);
-            stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+            stop_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 #ifdef DEBUG_HARQ
             printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]);
 #endif
 
             //printf("retr cw 0 = %d\n", ret[0]);
-            //printf("current round = %d\n", UE->dlsch[subframe&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe&0x1][0][cw_non_sic]->current_harq_pid]->round);
+            //printf("current round = %d\n", UE->dlsch[UE->current_thread_id[subframe]][0][cw_non_sic]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw_non_sic]->current_harq_pid]->round);
 
 
 
-            if (ret[TB] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1
+            if (ret[TB] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1
               decoded_tb[TB]=1;
 #ifdef DEBUG_HARQ
             printf("[DLSIM] TB%d is decoded\n", TB);
@@ -4212,33 +4228,33 @@ int main(int argc, char **argv)
               if (n_frames==1) {
                 printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                for (s=0;s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) {
-                  if (s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus)
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus;
+                for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->C;s++) {
+                  if (s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Cminus)
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kminus;
                   else
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus;
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kplus;
 
                   Kr_bytes = Kr>>3;
 
                   printf("Decoded_output (Segment %d):\n",s);
                   for (i=0;i<Kr_bytes;i++)
-                    printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i],
-                           UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+                    printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i],
+                           UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
                 }
 #endif
               }
 
-              UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][TB]->current_harq_pid]->TBS;
+              UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][TB]->current_harq_pid]->TBS;
 
               // If the  receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER
               //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained)
-              if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
+              if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
               /*
-              //for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) {
+              //for (round = 0 ; round < UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round ; round++) {
               // we assume here that the second stream has a lower MCS and is thus more likely to be decoded
               // re-encoding of second stream
-              dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+              dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
 
               dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
               dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc[0];
@@ -4252,14 +4268,14 @@ int main(int argc, char **argv)
               dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
               dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-              UE->dlsch[subframe&0x1][eNB_id]->active       = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-              UE->dlsch[subframe&0x1][eNB_id]->rnti         = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
-              UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid         = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->active       = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->rnti         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
 
-              dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b,
+              dlsch_encoding(UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->b,
                  &UE->frame_parms,
                  num_pdcch_symbols,
-                 UE->dlsch[subframe&0x1][eNB_id],
+                 UE->dlsch[UE->current_thread_id[subframe]][eNB_id],
                  0,subframe,
                  &UE->dlsch_rate_matching_stats,
                  &UE->dlsch_turbo_encoding_stats,
@@ -4267,10 +4283,10 @@ int main(int argc, char **argv)
                  );
 
               coded_bits_per_codeword = get_G(&UE->frame_parms,
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->nb_rb,
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->rb_alloc,
-                      get_Qm(UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->mcs),
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->Nl,
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->nb_rb,
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->rb_alloc,
+                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->mcs),
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->Nl,
                       num_pdcch_symbols,
                       0,subframe);
 
@@ -4278,7 +4294,7 @@ int main(int argc, char **argv)
               //scrambling
               dlsch_scrambling(&UE->frame_parms,
                    0,
-                   UE->dlsch[subframe&0x1][eNB_id],
+                   UE->dlsch[UE->current_thread_id[subframe]][eNB_id],
                    coded_bits_per_codeword,
                    0,
                    subframe<<1);
@@ -4290,7 +4306,7 @@ int main(int argc, char **argv)
                       subframe,
                       &UE->frame_parms,
                       num_pdcch_symbols,
-                      &UE->dlsch[subframe&0x1][0][0],
+                      &UE->dlsch[UE->current_thread_id[subframe]][0][0],
                       NULL);
               // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding
               // precoding is contained in effective channel estimate
@@ -4330,8 +4346,8 @@ int main(int argc, char **argv)
               }
 
 
-             if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
-                  (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) &&
+             if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+                  (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) &&
                   (rx_type==rx_SIC_dual_stream)) {
 #ifdef DEBUG_HARQ
                 printf("[DLSIM] Starting SIC procedure\n");
@@ -4348,10 +4364,10 @@ int main(int argc, char **argv)
 #endif
                 //printf("I enter round_sic loop \n");
                 //printf("round_sic= %d\n", round_sic);
-                dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-                dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+                dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+                dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
 
-                dlsch0_eNB_harq->mimo_mode    = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode;
+                dlsch0_eNB_harq->mimo_mode    = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode;
                 dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc_even[0];
                 dlsch0_eNB_harq->nb_rb        = dlsch0_ue_harq->nb_rb;
                 dlsch0_eNB_harq->mcs          = dlsch0_ue_harq->mcs;
@@ -4363,19 +4379,19 @@ int main(int argc, char **argv)
                 dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
                 dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->rvidx = round_sic;
-                UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=round_sic;
-                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round = round_sic;
-                UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->round=round_sic;
+                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->rvidx = round_sic;
+                UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->rvidx=round_sic;
+                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round = round_sic;
+                UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->round=round_sic;
 
-                UE->dlsch_eNB[eNB_id]->active                   = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-                UE->dlsch_eNB[eNB_id]->rnti                     = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
-                UE->dlsch_eNB[eNB_id]->current_harq_pid         = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+                UE->dlsch_eNB[eNB_id]->active                   = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+                UE->dlsch_eNB[eNB_id]->rnti                     = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
+                UE->dlsch_eNB[eNB_id]->current_harq_pid         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
 #ifdef DEBUG_HARQ
-                printf("UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round = %d\n", UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round);
+                printf("UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round = %d\n", UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round);
 #endif
                 dlsch_encoding_SIC(UE,
-                               input_buffer0[0], //UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,,
+                               input_buffer0[0], //UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,,
                                num_pdcch_symbols,
                                &UE->dlsch_eNB[0][0],
                                0,
@@ -4410,8 +4426,8 @@ int main(int argc, char **argv)
                                                     coded_bits_per_codeword[0]);
 
                // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1);
-               // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1);
-               // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1);
+               // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid][round],14*12*25,1,1);
+               // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid][round],14*12*25,1,1);
 
 
                 switch  (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){
@@ -4421,10 +4437,10 @@ int main(int argc, char **argv)
                   case 2:
 
                     dlsch_qpsk_llr_SIC(&UE->frame_parms,
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                        sic_buffer,
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                        num_pdcch_symbols,
                                        dlsch0_eNB_harq->nb_rb,
                                        subframe,
@@ -4435,12 +4451,12 @@ int main(int argc, char **argv)
                   case 4:
 
                     dlsch_16qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         sic_buffer,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
                                         get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
@@ -4448,13 +4464,13 @@ int main(int argc, char **argv)
                   break;
                   case 6:
                     dlsch_64qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         sic_buffer,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
                                         get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
@@ -4463,13 +4479,13 @@ int main(int argc, char **argv)
                     }
                   //}// rouns sic
 #ifdef DEBUG_HARQ
-                  printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword);
+                  printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->codeword);
 #endif
 
                     //  write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0);
 
                   // replace cw_sic with TB+1
-                  UE->dlsch[subframe&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
                   coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
                                                     eNB->dlsch[0][1]->harq_processes[0]->nb_rb,
                                                     eNB->dlsch[0][1]->harq_processes[0]->rb_alloc,
@@ -4480,26 +4496,26 @@ int main(int argc, char **argv)
                                                     subframe,
                                                     transmission_mode>=7?transmission_mode:0);
 
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1];
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1];
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
 
                   if (n_frames==1) {
                     printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1],
-                    UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->TBS);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->TBS);
 
                   // calculate uncoded BER
                     uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]);
                     AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL");
                     sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round,1);
                     sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, 1);
-                    write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[1],coded_bits_per_codeword[1],1,0);
+                    write_output(fname,vname, UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[1],coded_bits_per_codeword[1],1,0);
                     sprintf(fname,"dlsch_cw%d_e.m", 1);
                     sprintf(vname,"dlschcw%d_e", 1);
                     write_output(fname, vname,eNB->dlsch[0][1]->harq_processes[0]->e,coded_bits_per_codeword[1],1,4);
                     uncoded_ber=0;
                     printf("trials=%d\n", trials);
                     for (i=0;i<coded_bits_per_codeword[1];i++)
-                    if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword][i]<0)) {
+                    if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->codeword][i]<0)) {
                       uncoded_ber_bit[i] = 1;
                       uncoded_ber++;
                     }
@@ -4519,25 +4535,25 @@ int main(int argc, char **argv)
                 start_meas(&UE->dlsch_unscrambling_stats);
                 dlsch_unscrambling(&UE->frame_parms,
                                    0,
-                                   UE->dlsch[subframe&0x1][0][1],
+                                   UE->dlsch[UE->current_thread_id[subframe]][0][1],
                                    coded_bits_per_codeword[1],
-                                   UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
+                                   UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                    1,
                                    subframe<<1);
                 stop_meas(&UE->dlsch_unscrambling_stats);
 
-                start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+                start_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 
                 ret[1] = dlsch_decoding(UE,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         &UE->frame_parms,
-                                        UE->dlsch[subframe&0x1][0][1],
-                                        UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid],
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1],
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid],
                                         0,
                                         subframe,
-                                        UE->dlsch[subframe&0x1][0][1]->current_harq_pid,
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid,
                                         1,llr8_flag);
-                stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+                stop_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 
 #ifdef DEBUG_HARQ
                 printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d,  round sic %d\n", ret[1], round_sic);
@@ -4545,7 +4561,7 @@ int main(int argc, char **argv)
 
                 //printf("ret TB 1 = %d round %d \n", ret[1], round);
 
-                if (ret[1] <=UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) {
+                if (ret[1] <=UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ) {
                   decoded_tb[1]=1;
                   decoded_in_sic[round]++;
                   round_sic = round+1; // to exit round_sic
@@ -4560,19 +4576,19 @@ int main(int argc, char **argv)
                     printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
 
                     #ifdef PRINT_BYTES
-                    for (s=0;s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) {
-                    if (s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus)
-                      Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus;
+                    for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->C;s++) {
+                    if (s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Cminus)
+                      Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kminus;
                     else
-                      Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus;
+                      Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kplus;
 
                     Kr_bytes = Kr>>3;
 
                     printf("Decoded_output (Segment %d):\n",s);
 
                     for (i=0;i<Kr_bytes;i++)
-                      printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i],
-                      UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+                      printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i],
+                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
                     }
                     #endif
                   }
@@ -4580,7 +4596,7 @@ int main(int argc, char **argv)
               } //round_sic
 
 
-            if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){
+            if (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ){
               decoded_tb[1]=0;
               errs[1][round]++;
 #ifdef DEBUG_HARQ
@@ -4596,28 +4612,28 @@ int main(int argc, char **argv)
                     //if ((n_frames==1) || (SNR>=30)) {
                     printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                    for (s=0;s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) {
-                      if (s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus)
-                        Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus;
+                    for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->C;s++) {
+                      if (s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Cminus)
+                        Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kminus;
                       else
-                        Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus;
+                        Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kplus;
 
                       Kr_bytes = Kr>>3;
 
                       printf("Decoded_output (Segment %d):\n",s);
                       for (i=0;i<Kr_bytes;i++)
-                        printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i],
-                         UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+                        printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i],
+                         UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
                     }
 #endif
                   } //n_frames==1
                  // exit(0);
-              } //if (ret > UE->dlsch[subframe&0x1][0][1]->max_turbo_iterations )
+              } //if (ret > UE->dlsch[UE->current_thread_id[subframe]][0][1]->max_turbo_iterations )
             }//if SIC
           } else {
 
             if (TB0_active && TB1_active)
-              UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->round++;
+              UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->round++;
 
             decoded_tb[TB]=0;
             errs[TB][round]++;
@@ -4631,8 +4647,8 @@ int main(int argc, char **argv)
           iter_trials[0]++;
               }*/
 
-            if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
-              (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) &&
+            if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+              (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) &&
                 (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) {
                 errs[1][round]++;
 #ifdef DEBUG_HARQ
@@ -4651,18 +4667,18 @@ int main(int argc, char **argv)
           //if ((n_frames==1) || (SNR>=30)) {
                 printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                for (s=0;s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) {
-                  if (s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus)
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus;
+                for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->C;s++) {
+                  if (s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Cminus)
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kminus;
                   else
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus;
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kplus;
 
                   Kr_bytes = Kr>>3;
 
                   printf("Decoded_output (Segment %d):\n",s);
                   for (i=0;i<Kr_bytes;i++)
-                    printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i],
-                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+                    printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i],
+                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
                 }
 #endif
               }
@@ -4671,7 +4687,7 @@ int main(int argc, char **argv)
             TB++; // to terminate the loop over TB
           }
 
-          stop_meas(&UE->phy_proc_rx[subframe&0x1]);
+          stop_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
           if (n_frames==4) {
 
@@ -4681,14 +4697,14 @@ int main(int argc, char **argv)
             write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
             sprintf(fname,"rxsigF0_r%d.m",round);
             sprintf(vname,"rxs0F_r%d",round);
-            write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+            write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
             if (UE->frame_parms.nb_antennas_rx>1) {
               sprintf(fname,"rxsig1_r%d.m",round);
               sprintf(vname,"rxs1_r%d",round);
               write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
               sprintf(fname,"rxsig1F_r%d.m",round);
               sprintf(vname,"rxs1F_r%d",round);
-              write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
             }
 
             //channel
@@ -4710,44 +4726,44 @@ int main(int argc, char **argv)
             sprintf(fname,"dlsch00_r%d.m",round);
             sprintf(vname,"dl00_r%d",round);
             write_output(fname,vname,
-              &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+              &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
              UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             if (UE->frame_parms.nb_antennas_rx>1) {
               sprintf(fname,"dlsch01_r%d.m",round);
               sprintf(vname,"dl01_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             }
             if (eNB->frame_parms.nb_antennas_tx>1) {
               sprintf(fname,"dlsch10_r%d.m",round);
               sprintf(vname,"dl10_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             }
             if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
               sprintf(fname,"dlsch11_r%d.m",round);
               sprintf(vname,"dl11_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             }
             //pdsch_vars
-            dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+            dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
             /*
               write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
               write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
               write_output("dlsch_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
-              write_output("dlsch_UE_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              write_output("dlsch_UE_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
             */
 
             //pdcch_vars
-            write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
-            write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+            write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+            write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
 
-            write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0],4*300,1,1);
-            write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[subframe&0x1][eNB_id]->llr,2400,1,4);
+            write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0],4*300,1,1);
+            write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->llr,2400,1,4);
 
             if (round == 3) exit(-1);
           }
@@ -4763,7 +4779,7 @@ int main(int argc, char **argv)
           printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]);
 #endif
 
-          if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)){
+          if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)){
             //printf("flag 1 \n");
             round++;
           }
@@ -4828,8 +4844,8 @@ int main(int argc, char **argv)
               }
 
             if (rank_indc[0] == 1 || (rank_indc[0] == 0 && rank_adapt==0)) {
-              if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-                 ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
+              if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                 ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
                 resend_both[round]++;
                 round++;
                 resend_cw0_cw1=1;  //resend both cws
@@ -4837,8 +4853,8 @@ int main(int argc, char **argv)
                 TB0_active=1;
                 TB1_active=1;
               }
-              else if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-                       ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
+              else if (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                       ret[0] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
                 resend_one[round]++;
                 resend_cw0_cw1=0;
                 TB0_active=0;
@@ -4858,8 +4874,8 @@ int main(int argc, char **argv)
 #endif
               round++;
               }
-              else if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-                       ret[1] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
+              else if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                       ret[1] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
                 resend_one[round]++;
                 resend_cw0_cw1=0;
                 TB0_active=1;
@@ -4883,7 +4899,7 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
               printf("I am in case rank_indc[0] == 0 && rank_adapt == 1, decoded_tb[0] = %d\n", decoded_tb[0]);
 #endif
-                if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
+                if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
                   resend_one[round]++;
                   round++;
                   resend_cw0_cw1=0;  //resend both cws
@@ -4928,10 +4944,10 @@ int main(int argc, char **argv)
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
-        double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
 
 
               if (t_tx > t_tx_max)
@@ -5226,7 +5242,7 @@ int main(int argc, char **argv)
          rate[0]*effective_rate,
          100*effective_rate,
          rate[0],
-         rate[0]*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+         rate[0]*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
          (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+
           4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
          (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])
@@ -5317,10 +5333,10 @@ int main(int argc, char **argv)
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -5344,17 +5360,17 @@ int main(int argc, char **argv)
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
         printf("DLSCH unscrambling time                             :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
                UE->dlsch_unscrambling_stats.trials);
-        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                                   2)/UE->dlsch_decoding_stats[subframe&0x1].trials - pow((double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000,2));
+        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
         printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
                eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0],
-               (double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&0x1].trials,
-               (double)UE->dlsch_decoding_stats[subframe&0x1].max/cpu_freq_GHz/1000.0);
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials,
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0);
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -5755,12 +5771,12 @@ int main(int argc, char **argv)
     eNB->dlsch_modulation_stats.trials,
     eNB->dlsch_scrambling_stats.trials,
     eNB->dlsch_encoding_stats.trials,
-    UE->phy_proc_rx[subframe&0x1].trials,
+    UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
     UE->ofdm_demod_stats.trials,
     UE->dlsch_rx_pdcch_stats.trials,
     UE->dlsch_llr_stats.trials,
     UE->dlsch_unscrambling_stats.trials,
-    UE->dlsch_decoding_stats[subframe&0x1].trials
+    UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
     );
   fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
     get_time_meas_us(&eNB->phy_proc_tx),
@@ -5768,12 +5784,12 @@ int main(int argc, char **argv)
     get_time_meas_us(&eNB->dlsch_modulation_stats),
     get_time_meas_us(&eNB->dlsch_scrambling_stats),
     get_time_meas_us(&eNB->dlsch_encoding_stats),
-    get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+    get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
     nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
     get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
     3*get_time_meas_us(&UE->dlsch_llr_stats),
     get_time_meas_us(&UE->dlsch_unscrambling_stats),
-    get_time_meas_us(&UE->dlsch_decoding_stats[subframe&0x1])
+    get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
     );
   //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
   fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
@@ -5813,7 +5829,7 @@ int main(int argc, char **argv)
     UE->dlsch_rx_pdcch_stats.trials,
     UE->dlsch_llr_stats.trials,
     UE->dlsch_unscrambling_stats.trials,
-    UE->dlsch_decoding_stats[subframe&0x1].trials);
+    UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials);
     */
     printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]);
     break;
@@ -5892,7 +5908,7 @@ int main(int argc, char **argv)
 
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 3055e99b07272a4d318787f4b6830b772efd88d8..b257b1561b533b104a05fe76d704e66a46b4167c 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -953,14 +953,14 @@ int main(int argc, char **argv)
   }
 
   for (i=0; i<2; i++) {
-    UE->dlsch[subframe&0x1][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
-    if (!UE->dlsch[subframe&0x1][0][i]) {
+    if (!UE->dlsch[UE->current_thread_id[subframe]][0][i]) {
       printf("Can't get ue dlsch structures\n");
       exit(-1);
     }
 
-    UE->dlsch[subframe&0x1][0][i]->rnti   = n_rnti;
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]->rnti   = n_rnti;
   }
 
   // structure for SIC at UE
@@ -1112,10 +1112,11 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format1;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format1;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1255,11 +1256,12 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1424,10 +1426,11 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2A;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format2A;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
@@ -1564,11 +1567,12 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1734,10 +1738,11 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = n_rnti+k;
+          dci_alloc[num_dci].format       = format2;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1874,11 +1879,12 @@ int main(int argc, char **argv)
           }
 
           memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
+          dci_alloc[num_dci].dci_length   = dci_length;
+          dci_alloc[num_dci].L            = 1;
+          dci_alloc[num_dci].rnti         = SI_RNTI;
+          dci_alloc[num_dci].format       = format1A;
+          dci_alloc[num_dci].firstCCE     = 0;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1906,11 +1912,12 @@ int main(int argc, char **argv)
       case 5:
       case 6:
         memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-        dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-        dci_alloc[num_dci].L          = 1;
-        dci_alloc[num_dci].rnti       = n_rnti+k;
-        dci_alloc[num_dci].format     = format1E_2A_M10PRB;
-        dci_alloc[num_dci].firstCCE       = 4*k;
+        dci_alloc[num_dci].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+        dci_alloc[num_dci].L            = 1;
+        dci_alloc[num_dci].rnti         = n_rnti+k;
+        dci_alloc[num_dci].format       = format1E_2A_M10PRB;
+        dci_alloc[num_dci].firstCCE     = 4*k;
+        dci_alloc[num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
 					   subframe,
@@ -2039,7 +2046,7 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
+      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
       errs[0]=0;
       errs[1]=0;
       errs[2]=0;
@@ -2069,7 +2076,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2112,9 +2119,9 @@ int main(int argc, char **argv)
         //if (trials%100==0)
         eNB2UE[0]->first_run = 1;
 
-        ret = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
+        ret = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
 
-        while ((round < num_rounds) && (ret > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) {
+        while ((round < num_rounds) && (ret > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)) {
               //printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
@@ -2556,8 +2563,7 @@ PMI_FEEDBACK:
               }
             }
 	    
-            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
-                                                   num_common_dci,
+            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci + num_common_dci,
                                                    dci_alloc,
                                                    0,
                                                    AMP,
@@ -2601,7 +2607,7 @@ PMI_FEEDBACK:
                 // use the PMI from previous trial
                 if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
                   eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
-                  UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 
                   if (n_users>1)
                     eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
@@ -3059,7 +3065,7 @@ PMI_FEEDBACK:
           }
           
 
-          start_meas(&UE->phy_proc_rx[subframe&0x1]);
+          start_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
           // Inner receiver scheduling for 3 slots
         
@@ -3096,24 +3102,24 @@ PMI_FEEDBACK:
                     for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
                                 eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
                           //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
                                 eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
 
                           if (transmission_mode == 7){
 			    //this should include the BF weights! Will not work for a random channel
                             if (UE->high_speed_flag==0) {
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                               //printf("**,x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
                             } else  {
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                                 
                             }
@@ -3126,15 +3132,15 @@ PMI_FEEDBACK:
                   for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
                     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                       for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
                         if (transmission_mode == 7) {
                           if (UE->high_speed_flag==0){
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP);
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2;
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2;
                           } else {
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(short)(AMP);
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=0/2;
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=0/2;
                           }
                         }
                       }
@@ -3227,7 +3233,7 @@ PMI_FEEDBACK:
 
                   for (i=0; i<dci_cnt; i++) {
                     //        printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti);
-                    if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->first_tx=1;
+                    if (round == 0) UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->first_tx=1;
 
                     if ((dci_alloc_rx[i].rnti == n_rnti) &&
                         (generate_ue_dlsch_params_from_dci(0,
@@ -3235,7 +3241,9 @@ PMI_FEEDBACK:
                                                            dci_alloc_rx[i].dci_pdu,
                                                            dci_alloc_rx[i].rnti,
                                                            dci_alloc_rx[i].format,
-                                                           UE->dlsch[subframe&0x1][0],
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0],
                                                            &UE->frame_parms,
                                                            UE->pdsch_config_dedicated,
                                                            SI_RNTI,
@@ -3244,23 +3252,23 @@ PMI_FEEDBACK:
                                                            transmission_mode<7?0:transmission_mode))) {
                       //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
                       coded_bits_per_codeword = get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
                                                       UE->pdcch_vars[0]->num_pdcch_symbols,
                                                       0,
 						      subframe,
 						      (transmission_mode<7?0:transmission_mode));
           	    /*if (transmission_mode==7 && common_flag==0)
-       	    	      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */
+       	    	      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7; */
 
                       /*
-                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword);
-                      rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs);
+                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs)][UE->dlsch[UE->current_thread_id[subframe]][0][0]->nb_rb-1]/(coded_bits_per_codeword);
+                      rate*=get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs);
                       */
                       printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,
-                             UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS);
+                             UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->TBS);
 
                       dlsch_active = 1;
                     } else {
@@ -3288,7 +3296,7 @@ PMI_FEEDBACK:
                   UE->pdcch_vars[0]->crnti = n_rnti;
                   UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
 
-                  if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
+                  if (round == 0) UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
 
                   switch (transmission_mode) {
                   case 1:
@@ -3299,7 +3307,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format1 : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3307,24 +3317,24 @@ PMI_FEEDBACK:
                                                       P_RNTI,
                                                       transmission_mode<7?0:transmission_mode);
           	    /*if(transmission_mode==7 && common_flag==0)
-       	    	      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/
+       	    	      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7;*/
                     break;
 
                   case 3:
-                    //        printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                    //        printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                     generate_ue_dlsch_params_from_dci(0,
 						      subframe,
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format2A : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
                                                       0,
                                                       P_RNTI,
                                                       0);
-                    //        printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                    //        printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                     break;
 
                   case 4:
@@ -3333,7 +3343,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format2 : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3349,7 +3361,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu2_1E[0],
                                                       C_RNTI,
                                                       format1E_2A_M10PRB,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      ue->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      ue->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3381,7 +3395,7 @@ PMI_FEEDBACK:
                 if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix)
 
                   if ((transmission_mode == 5) &&
-                      (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->dl_power_off==0) &&
+                      (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->dl_power_off==0) &&
                       (UE->use_ia_receiver ==1)) {
                     dual_stream_UE = 1;
                   } else {
@@ -3404,7 +3418,7 @@ PMI_FEEDBACK:
                                  (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active = 0;
                       break;
                     }
@@ -3430,7 +3444,7 @@ PMI_FEEDBACK:
                                  0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active=0;
                       break;
                     }
@@ -3456,7 +3470,7 @@ PMI_FEEDBACK:
                                  0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active=0;
                       break;
                     }
@@ -3477,30 +3491,30 @@ PMI_FEEDBACK:
                     //write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
                     write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][subframe*UE->frame_parms.samples_per_tti],UE->frame_parms.samples_per_tti,1,1);
                     //write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-                    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
                     if (UE->frame_parms.nb_antennas_rx>1) {
                       write_output("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
-                      write_output("rxsigF1.m","rxsF1", UE->common_vars..common_vars_rx_data_per_thread[subframe&0x1]rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                      write_output("rxsigF1.m","rxsF1", UE->common_vars..common_vars_rx_data_per_thread[UE->current_thread_id[subframe]]rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
                     }
 
                     write_output("dlsch00_r0.m","dl00_r0",
-                                 &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                                 &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                                  UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
                     if (UE->frame_parms.nb_antennas_rx>1)
                       write_output("dlsch01_r0.m","dl01_r0",
-                                   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                                    UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
                     if (eNB->frame_parms.nb_antennas_tx>1)
                       write_output("dlsch10_r0.m","dl10_r0",
-                                   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                                    UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
                     if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
                       write_output("dlsch11_r0.m","dl11_r0",
-                                   &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                                    UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
 
                     //pdsch_vars
@@ -3527,14 +3541,14 @@ PMI_FEEDBACK:
             if (trials==0 && round==0 && transmission_mode>=5 && transmission_mode<7) {
               for (iii=0; iii<NB_RB; iii++) {
                 //fprintf(csv_fd, "%d, %d", (UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
-                fprintf(csv_fd,"%x,%x,",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
-                printf("%x ",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]));
+                fprintf(csv_fd,"%x,%x,",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
+                printf("%x ",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]));
               }
             }
           }
 
           for (int cw=Kmimo-1; cw>=0; cw--) {
-            UE->dlsch[subframe&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+            UE->dlsch[UE->current_thread_id[subframe]][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
             coded_bits_per_codeword = get_G(&eNB->frame_parms,
                                             eNB->dlsch[0][cw]->harq_processes[0]->nb_rb,
                                             eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc,
@@ -3545,14 +3559,14 @@ PMI_FEEDBACK:
 					    subframe,
 					    (transmission_mode<7?0:transmission_mode));
 
-            UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
+            UE->dlsch[UE->current_thread_id[subframe]][0][cw]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
 
 
 	                
             // calculate uncoded BLER
             uncoded_ber=0;
             for (i=0;i<coded_bits_per_codeword;i++)
-              if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[0][i]<0)) {
+              if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]<0)) {
                 uncoded_ber_bit[i] = 1;
                 uncoded_ber++;
               }
@@ -3569,26 +3583,26 @@ PMI_FEEDBACK:
             start_meas(&UE->dlsch_unscrambling_stats);
             dlsch_unscrambling(&UE->frame_parms,
                                0,
-                               UE->dlsch[subframe&0x1][0][cw],
+                               UE->dlsch[UE->current_thread_id[subframe]][0][cw],
                                coded_bits_per_codeword,
-                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw],
+                               UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[cw],
                                0,
                                subframe<<1);
             stop_meas(&UE->dlsch_unscrambling_stats);
 
             start_meas(&UE->dlsch_decoding_stats);
             ret = dlsch_decoding(UE,
-                                 UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw],
+                                 UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[cw],
                                  &UE->frame_parms,
-                                 UE->dlsch[subframe&0x1][0][cw],
-                                 UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid],
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw],
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid],
                                  subframe,
-                                 UE->dlsch[subframe&0x1][0][cw]->current_harq_pid,
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid,
                                  1,llr8_flag);
             stop_meas(&UE->dlsch_decoding_stats);
 
             if (cw==1) {
-              if (ret <= UE->dlsch[subframe&0x1][0][cw]->max_turbo_iterations) {
+              if (ret <= UE->dlsch[UE->current_thread_id[subframe]][0][cw]->max_turbo_iterations) {
               } else {
                 errs2[round]++;
               }
@@ -3596,10 +3610,10 @@ PMI_FEEDBACK:
           }
 
 
-          stop_meas(&UE->phy_proc_rx[subframe&0x1]);
+          stop_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
 
-          if (ret <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) {
+          if (ret <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) {
 
             avg_iter += ret;
             iter_trials++;
@@ -3607,15 +3621,15 @@ PMI_FEEDBACK:
             if (n_frames==1)
               printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber);
 
-            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS;
+            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
             TB0_active = 0;
 
-            if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
+            if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
               /*
-              for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) {
+              for (round = 0 ; round < UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round ; round++) {
               // re-encoding of first stream
-              dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+              dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
               dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
               dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc_even[0];
               dlsch0_eNB_harq->nb_rb        = dlsch0_ue_harq->nb_rb;
@@ -3627,13 +3641,13 @@ PMI_FEEDBACK:
               dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
               dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-              UE->dlsch[subframe&0x1][eNB_id]->active       = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-              UE->dlsch[subframe&0x1][eNB_id]->rnti         = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->active       = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->rnti         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
 
-              dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b,
+              dlsch_encoding(UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->b,
                    &UE->frame_parms,
                    num_pdcch_symbols,
-                   UE->dlsch[subframe&0x1][0],
+                   UE->dlsch[UE->current_thread_id[subframe]][0],
                    0,subframe,
                    &UE->dlsch_rate_matching_stats,
                    &UE->dlsch_turbo_encoding_stats,
@@ -3660,18 +3674,18 @@ PMI_FEEDBACK:
               //if ((n_frames==1) || (SNR>=30)) 
               printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
 
-              for (s=0; s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) {
-                if (s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus)
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus;
+              for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
+                if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
                 else
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus;
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
 
                 Kr_bytes = Kr>>3;
 
                 printf("Decoded_output (Segment %d):\n",s);
 
                 for (i=0; i<Kr_bytes; i++)
-                  printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+                  printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
               }
 
               sprintf(fname,"rxsig0_r%d.m",round);
@@ -3679,7 +3693,7 @@ PMI_FEEDBACK:
               write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
               sprintf(fname,"rxsigF0_r%d.m",round);
               sprintf(vname,"rxs0F_r%d",round);
-              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
 	     
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"rxsig1_r%d.m",round);
@@ -3687,20 +3701,20 @@ PMI_FEEDBACK:
                 write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
                 sprintf(fname,"rxsig1F_r%d.m",round);
                 sprintf(vname,"rxs1F_r%d.m",round);
-                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
               }
 
               sprintf(fname,"dlsch00_r%d.m",round);
               sprintf(vname,"dl00_r%d",round);
               write_output(fname,vname,
-                           &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                           &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                            UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"dlsch01_r%d.m",round);
                 sprintf(vname,"dl01_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3708,7 +3722,7 @@ PMI_FEEDBACK:
                 sprintf(fname,"dlsch10_r%d.m",round);
                 sprintf(vname,"dl10_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3716,7 +3730,7 @@ PMI_FEEDBACK:
                 sprintf(fname,"dlsch11_r%d.m",round);
                 sprintf(vname,"dl11_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3726,7 +3740,7 @@ PMI_FEEDBACK:
               write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
               write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
               write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
-              write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              write_output("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
               */
 
               if (round == 3) exit(-1);
@@ -3735,7 +3749,7 @@ PMI_FEEDBACK:
             //      printf("round %d errors %d/%d\n",round,errs[round],trials);
 
             round++;
-            //      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++;
+            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
           }
 
 	  if (xforms==1) {
@@ -3756,7 +3770,7 @@ PMI_FEEDBACK:
         //len = chbch_stats_read(stats_buffer,NULL,0,4096);
         //printf("%s\n\n",stats_buffer);
 
-        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
+        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
           UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
           LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
                 UE->bitrate[eNB_id]/1000);
@@ -3764,7 +3778,7 @@ PMI_FEEDBACK:
         }
 
 
-        UE->proc.proc_rxtx[subframe&1].frame_rx++;
+        UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
 
         /* calculate the total processing time for each packet,
          * get the max, min, and number of packets that exceed t>2000us
@@ -3775,7 +3789,7 @@ PMI_FEEDBACK:
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0;
@@ -3925,7 +3939,7 @@ PMI_FEEDBACK:
              rate*effective_rate,
              100*effective_rate,
              rate,
-             rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+             rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
              (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
@@ -3964,10 +3978,10 @@ PMI_FEEDBACK:
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -4001,7 +4015,7 @@ PMI_FEEDBACK:
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -4179,7 +4193,7 @@ PMI_FEEDBACK:
                 eNB->dlsch_modulation_stats.trials,
                 eNB->dlsch_scrambling_stats.trials,
                 eNB->dlsch_encoding_stats.trials,
-                UE->phy_proc_rx[subframe&0x1].trials,
+                UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
                 UE->ofdm_demod_stats.trials,
                 UE->dlsch_rx_pdcch_stats.trials,
                 UE->dlsch_llr_stats.trials,
@@ -4192,7 +4206,7 @@ PMI_FEEDBACK:
                 get_time_meas_us(&eNB->dlsch_modulation_stats),
                 get_time_meas_us(&eNB->dlsch_scrambling_stats),
                 get_time_meas_us(&eNB->dlsch_encoding_stats),
-                get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+                get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
                 nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
                 get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
                 3*get_time_meas_us(&UE->dlsch_llr_stats),
@@ -4232,7 +4246,7 @@ PMI_FEEDBACK:
         eNB->dlsch_modulation_stats.trials,
         eNB->dlsch_scrambling_stats.trials,
         eNB->dlsch_encoding_stats.trials,
-        UE->phy_proc_rx[subframe&0x1].trials,
+        UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
         UE->ofdm_demod_stats.trials,
         UE->dlsch_rx_pdcch_stats.trials,
         UE->dlsch_llr_stats.trials,
@@ -4290,7 +4304,7 @@ PMI_FEEDBACK:
     printf("eNB %d\n",i);
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c
index d056bea5d0eaad6fe28fe807658167d3ef60d748..9719aeb9e52c0be1cc4544325d5d59b81ea4984f 100644
--- a/openair1/SIMULATION/LTE_PHY/framegen.c
+++ b/openair1/SIMULATION/LTE_PHY/framegen.c
@@ -66,8 +66,7 @@ DCI_PDU *get_dci(uint8_t Mod_id, uint8_t frame, uint8_t subframe)
   int dci_length_bytes,dci_length;
   int BCCH_pdu_size_bits, BCCH_pdu_size_bytes;
 
-  DCI_pdu.Num_ue_spec_dci = 0;
-  DCI_pdu.Num_common_dci = 0;
+  DCI_pdu.Num_dci = 0;
 
   if (subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms, subframe) == SF_S) {
     return (&DCI_pdu);
@@ -281,28 +280,30 @@ DCI_PDU *get_dci(uint8_t Mod_id, uint8_t frame, uint8_t subframe)
     }
 
     // add common dci
-    DCI_pdu.dci_alloc[0].dci_length = BCCH_pdu_size_bits;
-    DCI_pdu.dci_alloc[0].L          = 2;
-    DCI_pdu.dci_alloc[0].rnti       = SI_RNTI;
-    DCI_pdu.dci_alloc[0].format     = format1A;
-    DCI_pdu.dci_alloc[0].ra_flag    = 0;
+    DCI_pdu.dci_alloc[0].dci_length   = BCCH_pdu_size_bits;
+    DCI_pdu.dci_alloc[0].L            = 2;
+    DCI_pdu.dci_alloc[0].rnti         = SI_RNTI;
+    DCI_pdu.dci_alloc[0].format       = format1A;
+    DCI_pdu.dci_alloc[0].ra_flag      = 0;
+    DCI_pdu.dci_alloc[0].search_space = DCI_COMMON_SPACE;
     memcpy((void*)&DCI_pdu.dci_alloc[0].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
-    DCI_pdu.Num_common_dci++;
+    DCI_pdu.Num_dci++;
 
     // add ue specific dci
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].dci_length = dci_length;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].L          = 0;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].rnti       = n_rnti+k;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].format     = format1;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].ra_flag    = 0;
-    memcpy((void*)&DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].dci_pdu[0], &DLSCH_alloc_pdu_1[k], dci_length_bytes);
-    DCI_pdu.Num_ue_spec_dci++;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].dci_length   = dci_length;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].L            = 0;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].rnti         = n_rnti+k;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].format       = format1;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].ra_flag      = 0;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].search_space = DCI_UE_SPACE;
+    memcpy((void*)&DCI_pdu.dci_alloc[DCI_pdu.Num_dci].dci_pdu[0], &DLSCH_alloc_pdu_1[k], dci_length_bytes);
+    DCI_pdu.Num_dci++;
 
   }
 
   DCI_pdu.nCCE = 0;
 
-  for (i=0; i<DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu.Num_dci; i++) {
     DCI_pdu.nCCE += (1<<(DCI_pdu.dci_alloc[i].L));
   }
 
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index 3b72e35d5761ecd16455be05c6390708c45841ca..687e7219e82b55cd1c01863fa69a4667ad99c924 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -570,7 +570,6 @@ int main(int argc, char **argv)
 
     /*
     num_pdcch_symbols = generate_dci_top(1,
-           0,
            dci_alloc,
            0,
            1024,
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index 2b13449c6172498a3ee2c07fd49ec41e2fb9b7e5..1102d4be3800ba2515669dfb2020aab0604741ab 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -66,8 +66,7 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2
   int UL_pdu_size_bits=0, UL_pdu_size_bytes=0;
   int mcs = 3;
 
-  DCI_pdu.Num_ue_spec_dci = 0;
-  DCI_pdu.Num_common_dci = 0;
+  DCI_pdu.Num_dci = 0;
 
   if (lte_frame_parms->frame_type == TDD) {
     switch (lte_frame_parms->N_RB_DL) {
@@ -358,35 +357,38 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2
   for (ind = 0; ind<num_dci; ind++) {
     if (format_selector[ind]==format1A) {
       // add common dci
-      DCI_pdu.dci_alloc[ind].dci_length = BCCH_pdu_size_bits;
-      DCI_pdu.dci_alloc[ind].L          = log2Lcommon;
-      DCI_pdu.dci_alloc[ind].rnti       = SI_RNTI;
-      DCI_pdu.dci_alloc[ind].format     = format1A;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
-      memcpy((void*)&DCI_pdu.dci_alloc[0].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
-      DCI_pdu.Num_common_dci++;
+      DCI_pdu.dci_alloc[ind].dci_length   = BCCH_pdu_size_bits;
+      DCI_pdu.dci_alloc[ind].L            = log2Lcommon;
+      DCI_pdu.dci_alloc[ind].rnti         = SI_RNTI;
+      DCI_pdu.dci_alloc[ind].format       = format1A;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_COMMON_SPACE;
+      memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
+      DCI_pdu.Num_dci++;
       printf("Added common dci (%d) for rnti %x\n",ind,SI_RNTI);
     }
     
 
     if (format_selector[ind]==format1) {
-      DCI_pdu.dci_alloc[ind].dci_length = dci_length;
-      DCI_pdu.dci_alloc[ind].L          = log2L;
-      DCI_pdu.dci_alloc[ind].rnti       = rnti;
-      DCI_pdu.dci_alloc[ind].format     = format1;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
+      DCI_pdu.dci_alloc[ind].dci_length   = dci_length;
+      DCI_pdu.dci_alloc[ind].L            = log2L;
+      DCI_pdu.dci_alloc[ind].rnti         = rnti;
+      DCI_pdu.dci_alloc[ind].format       = format1;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE;
       memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &DLSCH_alloc_pdu[0], dci_length_bytes);
-      DCI_pdu.Num_ue_spec_dci++;
+      DCI_pdu.Num_dci++;
     }
     
     if (format_selector[ind]==format0) {
-      DCI_pdu.dci_alloc[ind].dci_length = UL_pdu_size_bits;
-      DCI_pdu.dci_alloc[ind].L          = log2L;
-      DCI_pdu.dci_alloc[ind].rnti       = rnti;
-      DCI_pdu.dci_alloc[ind].format     = format0;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
+      DCI_pdu.dci_alloc[ind].dci_length   = UL_pdu_size_bits;
+      DCI_pdu.dci_alloc[ind].L            = log2L;
+      DCI_pdu.dci_alloc[ind].rnti         = rnti;
+      DCI_pdu.dci_alloc[ind].format       = format0;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE;
       memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &UL_alloc_pdu[0], UL_pdu_size_bytes);
-      DCI_pdu.Num_ue_spec_dci++;
+      DCI_pdu.Num_dci++;
     }
   }
   
@@ -849,20 +851,20 @@ int main(int argc, char **argv)
 	    n_trials_dl++;
 	  }
 	}
-        num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci,
+        num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu.Num_dci,
                             DCI_pdu.dci_alloc, frame_parms, subframe);
 	numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
 
         if (n_frames==1) {
           printf("num_dci %d, num_pddch_symbols %d, nCCE %d\n",
-                 DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci,
+                 DCI_pdu.Num_dci,
                  num_pdcch_symbols,numCCE);
         }
 
         // apply RNTI-based nCCE allocation
 	memset(CCE_table,0,800*sizeof(int));
 
-        for (i = 0; i < DCI_pdu.Num_common_dci + DCI_pdu.Num_ue_spec_dci; i++) {
+        for (i = 0; i < DCI_pdu.Num_dci; i++) {
           // SI RNTI
           if (DCI_pdu.dci_alloc[i].rnti == SI_RNTI) {
             DCI_pdu.dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table,
@@ -899,8 +901,7 @@ int main(int argc, char **argv)
             exit(-1);
         }
 
-        num_pdcch_symbols = generate_dci_top(DCI_pdu.Num_ue_spec_dci,
-                                             DCI_pdu.Num_common_dci,
+        num_pdcch_symbols = generate_dci_top(DCI_pdu.Num_dci,
                                              DCI_pdu.dci_alloc,
                                              0,
                                              AMP,
diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c
index 20c3f374d0b8c1ac52995b351b1cb9999f006058..ba355bbbebb113131761b93eaedb75288a811188 100644
--- a/openair1/SIMULATION/LTE_PHY/scansim.c
+++ b/openair1/SIMULATION/LTE_PHY/scansim.c
@@ -493,7 +493,6 @@ int main(int argc, char **argv)
 
 
      num_pdcch_symbols = generate_dci_top(1,
-     0,
      dci_alloc,
      0,
      1024,
diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c
index 97a94a1a4323f3bda14401c39425b1c761b6db3b..58e96a9abef054cdb198e7ec5bd8824349a0cc02 100644
--- a/openair1/SIMULATION/LTE_PHY/syncsim.c
+++ b/openair1/SIMULATION/LTE_PHY/syncsim.c
@@ -1101,11 +1101,12 @@ int main(int argc, char **argv)
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->mcs             = 0;
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->ndi             = 1;
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->rv              = 0;
-      dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t;
+      dci_alloc[0].dci_length   = sizeof_DCI1_5MHz_FDD_t;
       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_FDD_t));
-      dci_alloc[0].L          = 2;
-      dci_alloc[0].rnti       = n_rnti;
-      dci_alloc[0].format     = format1;
+      dci_alloc[0].L            = 2;
+      dci_alloc[0].rnti         = n_rnti;
+      dci_alloc[0].format       = format1;
+      dci_alloc[0].search_space = DCI_UE_SPACE;
     } else {
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rah             = 0;
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rballoc         = DLSCH_RB_ALLOC;
@@ -1117,15 +1118,15 @@ int main(int argc, char **argv)
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rv              = 0;
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->tpmi            = (transmission_mode>=5 ? 5 : 0);  // precoding
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->dl_power_off    = (transmission_mode==5 ? 0 : 1);
-      dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-      dci_alloc[0].L          = 2;
-      dci_alloc[0].rnti       = n_rnti;
-      dci_alloc[0].format     = format1E_2A_M10PRB;
+      dci_alloc[0].L            = 2;
+      dci_alloc[0].rnti         = n_rnti;
+      dci_alloc[0].format       = format1E_2A_M10PRB;
+      dci_alloc[0].search_space = DCI_UE_SPACE;
     }
 
     num_pdcch_symbols = generate_dci_top(1,
-                                         0,
                                          dci_alloc,
                                          0,
                                          AMP,
@@ -1134,7 +1135,6 @@ int main(int argc, char **argv)
                                          subframe);
     /*
     num_pdcch_symbols = generate_dci_top(1,
-           0,
            dci_alloc,
            0,
            AMP,
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index dbce85851695fb10b49f1a655221806ac2b93a02..03c736ecd3f3475bfcbd7a1c22f899701235795c 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -175,7 +175,7 @@ int main(int argc, char **argv)
 
   int aarx,aatx;
   double channelx,channely;
-  double sigma2, sigma2_dB=10,SNR,SNR2,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
+  double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
   double input_snr_step=.2,snr_int=30;
   double blerr;
 
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
index 51ae7112770a701d9212ebc2801e3fb6f8753322..7b392b6b3bbc7a89049fc5ae5708026d68064dc4 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
index 1be6f7f43a1757078da818b46810559a0c1f653c..657f362873c9aeaaeb7deaf2733b9dc35514fa30 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 import "config_common.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
index 3a5efaf7d40d427d6b1fa3185eba77f36d460ff2..0f7e34de156599a448265e2846b9b69c83aea5c6 100644
--- a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 enum flex_control_delegation_type {
diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
index 252efc6aefb3fff24e0e61389272cc3af9f5ba99..eeda90b8cbfd19fe1a427f6c4b33dff74da2c551 100644
--- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 import "mac_primitives.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
index 8ebfc7df8b55595119b0a6883ef9d40d0c92c918..d79051d201a79e647558fcb62912a35258feb035 100644
--- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";' 
+syntax = "proto2";
 package protocol;
 
 import "stats_messages.proto";
@@ -42,7 +42,7 @@ enum flexran_direction {
 }
 	
 enum flexran_err {
-        option allow_alias = true;
+        //option allow_alias = true;
 	// message errors
 	NO_ERR = 0;	
 	MSG_DEQUEUING = -1;
diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto
index 79d541200cc0ee548160ef0bdac085be991192a3..4f03e0755e2004bdfa87a37230e575ebea8e143f 100644
--- a/openair2/ENB_APP/MESSAGES/V2/header.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/header.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 message flex_header {
diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
index 01f8799a17f8ced6a8ae739e6090adbd4b3f74ef..a34e9b6eaf941d2122e1cf33dbcce3a108b716b8 100644
--- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
index cce36df00a75be5a037d7be06149ece0c31eff06..0d8a565c06446bad9b975849d7cf1b2231e760bf 100644
--- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
index 48360f6f687791965db48d3e8c22008038c45a93..1ddb19722bd68c3755143315608b21c5616636d0 100644
--- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //import "header.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/time_common.proto b/openair2/ENB_APP/MESSAGES/V2/time_common.proto
index 30a56bb776957d245e673ac44e8e2ca255408c71..8bd2497443daaed136dc55b39740c66776d95795 100644
--- a/openair2/ENB_APP/MESSAGES/V2/time_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/time_common.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 enum flex_harq_status {
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 18b8e7c38c2f12646ebc5a85c0579ac1fed89668..45a11b82954f1849224df73cf94af7a810c61575 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -257,8 +257,7 @@ typedef struct {
 
 /*!\brief  DCI PDU filled by MAC for the PHY  */
 typedef struct {
-  uint8_t Num_ue_spec_dci ;
-  uint8_t Num_common_dci  ;
+  int Num_dci;
   //  uint32_t nCCE;
   uint32_t num_pdcch_symbols;
   DCI_ALLOC_t dci_alloc[NUM_DCI_MAX] ;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 8575b0b00a324542c392c5306e1e953b9b912bd3..f46b9deb8db702e39610432cd370afe5263ec2c8 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -125,8 +125,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
 
   // clear DCI and BCCH contents before scheduling
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    DCI_pdu[CC_id]->Num_common_dci  = 0;
-    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
+    DCI_pdu[CC_id]->Num_dci  = 0;
 #if defined(Rel10) || defined(Rel14)
     eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
 #endif
@@ -172,7 +171,11 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
     else {
       // check uplink failure
       if ((UE_list->UE_sched_ctrl[i].ul_failure_timer>0)&&
-	  (UE_list->UE_sched_ctrl[i].ul_out_of_sync==0)) {
+	  (UE_list->UE_sched_ctrl[i].ul_out_of_sync==0) &&
+          /* do nothing if CCE allocation is impossible */
+          !CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,
+                                     get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
+                                     rnti)) {
 	LOG_D(MAC,"UE %d rnti %x: UL Failure timer %d \n",i,rnti,UE_list->UE_sched_ctrl[i].ul_failure_timer);
 	if (UE_list->UE_sched_ctrl[i].ra_pdcch_order_sent==0) {
 	  UE_list->UE_sched_ctrl[i].ra_pdcch_order_sent=1;
@@ -1337,17 +1340,17 @@ if (mac_agent_registered[module_idP]){
   /*
   int dummy=0;
   for (i=0;
-       i<DCI_pdu[CC_id]->Num_common_dci+DCI_pdu[CC_id]->Num_ue_spec_dci;
+       i<DCI_pdu[CC_id]->Num_dci;
        i++)
     if (DCI_pdu[CC_id]->dci_alloc[i].rnti==2)
       dummy=1;
 	
   if (dummy==1)
     for (i=0;
-	 i<DCI_pdu[CC_id]->Num_common_dci+DCI_pdu[CC_id]->Num_ue_spec_dci;
+	 i<DCI_pdu[CC_id]->Num_dci;
 	 i++)
       LOG_I(MAC,"Frame %d, subframe %d: DCI %d/%d, format %d, rnti %x, NCCE %d(num_pdcch_symb %d)\n",
-	    frameP,subframeP,i,DCI_pdu[CC_id]->Num_common_dci+DCI_pdu[CC_id]->Num_ue_spec_dci,
+	    frameP,subframeP,i,DCI_pdu[CC_id]->Num_dci,
 	    DCI_pdu[CC_id]->dci_alloc[i].format,
 	    DCI_pdu[CC_id]->dci_alloc[i].rnti,
 	    DCI_pdu[CC_id]->dci_alloc[i].firstCCE,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 68f99bf7218013ee44148f411982a6c739a57819..2c50b0b6beb95d03e726749a21f12d38df01fd3f 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -2016,7 +2016,7 @@ update_ul_dci(
   DCI0_5MHz_TDD_1_6_t *ULSCH_dci = NULL;;
 
   if (mac_xface->frame_parms->frame_type == TDD) {
-    for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
+    for (i=0; i<DCI_pdu->Num_dci; i++) {
       ULSCH_dci = (DCI0_5MHz_TDD_1_6_t *)DCI_pdu->dci_alloc[i].dci_pdu;
 
       if ((DCI_pdu->dci_alloc[i].format == format0) && (DCI_pdu->dci_alloc[i].rnti == rnti)) {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 1c1730db9c14aa0e14e4a0d99db9aefb8f738b71..610700f3e8b4b015c25244faf50dcf75d9600a78 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -655,30 +655,34 @@ void add_common_dci(DCI_PDU *DCI_pdu,
                     unsigned char dci_fmt,
                     uint8_t ra_flag)
 {
+  if (DCI_pdu->Num_dci == NUM_DCI_MAX) { printf("%s: DCI FULL, fatal!\n", __FUNCTION__); abort(); }
 
-  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_pdu[0],pdu,dci_size_bytes);
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_length = dci_size_bits;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].L          = aggregation;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].rnti       = rnti;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].format     = dci_fmt;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].ra_flag    = ra_flag;
+  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length   = dci_size_bits;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L            = aggregation;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti         = rnti;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format       = dci_fmt;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].ra_flag      = ra_flag;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = DCI_COMMON_SPACE;
 
 
-  DCI_pdu->Num_common_dci++;
+  DCI_pdu->Num_dci++;
   LOG_D(MAC,"add common dci format %d for rnti %x \n",dci_fmt,rnti);
 }
 
 void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag)
 {
+  if (DCI_pdu->Num_dci == NUM_DCI_MAX) { printf("%s: DCI FULL, fatal!\n", __FUNCTION__); abort(); }
 
-  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_pdu[0],pdu,dci_size_bytes);
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_length = dci_size_bits;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].L          = aggregation;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].rnti       = rnti;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].format     = dci_fmt;
-  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].ra_flag    = ra_flag;
+  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length   = dci_size_bits;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L            = aggregation;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti         = rnti;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format       = dci_fmt;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].ra_flag      = ra_flag;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = DCI_UE_SPACE;
 
-  DCI_pdu->Num_ue_spec_dci++;
+  DCI_pdu->Num_dci++;
 
   LOG_D(MAC,"add ue specific dci format %d for rnti %x \n",dci_fmt,rnti);
 }
@@ -1075,18 +1079,17 @@ int allocate_CCEs(int module_idP,
   DCI_ALLOC_t *dci_alloc;
   int nCCE=0;
 
-  LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (common %d,uspec %d)\n",subframeP,test_onlyP,DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
+  LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (Num_dci %d)\n",subframeP,test_onlyP,DCI_pdu->Num_dci);
   DCI_pdu->num_pdcch_symbols=1;
 
 try_again:
   init_CCE_table(module_idP,CC_idP);
   nCCE=0;
 
-  for (i=0;i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci;i++) {
+  for (i=0;i<DCI_pdu->Num_dci;i++) {
     dci_alloc = &DCI_pdu->dci_alloc[i];
-    LOG_D(MAC,"Trying to allocate DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
-          i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,
-          DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci,
+    LOG_D(MAC,"Trying to allocate DCI %d/%d : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
+          i,DCI_pdu->Num_dci,
           dci_alloc->rnti,1<<dci_alloc->L,
           nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
 
@@ -1097,7 +1100,7 @@ try_again:
     fCCE = get_nCCE_offset(CCE_table,
                            1<<(dci_alloc->L),
                            nCCE_max,
-                           (i<DCI_pdu->Num_common_dci) ? 1 : 0,
+                           dci_alloc->search_space == DCI_COMMON_SPACE ? 1 : 0,
                            dci_alloc->rnti,
                            subframeP);
     if (fCCE == -1) {
@@ -1105,11 +1108,10 @@ failed:
       if (DCI_pdu->num_pdcch_symbols == 3) {
         LOG_I(MAC,"subframe %d: Dropping Allocation for RNTI %x (DCI %d/%d)\n",
               subframeP,dci_alloc->rnti,
-              i, DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci);
+              i, DCI_pdu->Num_dci);
         for (j=0;j<=i;j++){
-          LOG_I(MAC,"DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
-                j,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,
-                DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci,
+          LOG_I(MAC,"DCI %d/%d : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
+                j,DCI_pdu->Num_dci,
                 DCI_pdu->dci_alloc[j].rnti,DCI_pdu->dci_alloc[j].format,
                 1<<DCI_pdu->dci_alloc[j].L,
                 nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
@@ -1138,37 +1140,29 @@ fatal:
 }
 
 boolean_t CCE_allocation_infeasible(int module_idP,
-				    int CC_idP,
-				    int common_flag,
-				    int subframe,
-				    int aggregation,
-				    int rnti) {
-
-
+                                    int CC_idP,
+                                    int common_flag,
+                                    int subframe,
+                                    int aggregation,
+                                    int rnti)
+{
   DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_idP].DCI_pdu;
   //DCI_ALLOC_t *dci_alloc;
   int ret;
   boolean_t res=FALSE;
 
-  if (common_flag==1) {
-    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].rnti = rnti;
-    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].L = aggregation;
-    DCI_pdu->Num_common_dci++;
-    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
-    if (ret==-1)
-      res = TRUE;
-    DCI_pdu->Num_common_dci--;
-  }
-  else {
-    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].rnti = rnti;
-    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].L = aggregation;
-    DCI_pdu->Num_ue_spec_dci++;
-    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
-    if (ret==-1)
-      res = TRUE;
-    DCI_pdu->Num_ue_spec_dci--;
-  }
-  return(res);
+  if (DCI_pdu->Num_dci == NUM_DCI_MAX) return TRUE;
+
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti = rnti;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L = aggregation;
+  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = common_flag == 1 ? DCI_COMMON_SPACE : DCI_UE_SPACE;
+  DCI_pdu->Num_dci++;
+  ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
+  if (ret==-1)
+    res = TRUE;
+  DCI_pdu->Num_dci--;
+
+  return res;
 }
 
 void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 585d9c2c1c7c7ac9443b60fb895553233d2d062d..9d0066cefd02ed8f1a53d089f62493db1c4ce1bf 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -1142,7 +1142,7 @@ abort();
 	    
 	    LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
 #ifdef DEBUG
-	    dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]);
+	    dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_dci-1]);
 #endif
 	    
           }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
index f80a46695d21baef203f4eaa59ec03b8267358ae..06ad9a3b05ace2ccbaeff4fe42a5d6a040254181 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
@@ -206,23 +206,28 @@ boolean_t rlc_am_nack_pdu (
 void rlc_am_ack_pdu (
   const protocol_ctxt_t* const  ctxt_pP,
   rlc_am_entity_t *const rlc_pP,
-  const rlc_sn_t snP)
+  const rlc_sn_t snP,
+  boolean_t free_pdu)
 {
   mem_block_t* mb_p         = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block;
   rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE];
 
   tx_data_pdu_buffer->flags.retransmit = 0;
 
-  if ((tx_data_pdu_buffer->flags.ack == 0) && (mb_p != NULL)) {
-    //if (mb_pP != NULL) {
+  if (mb_p != NULL) {
+    if (free_pdu) {
     free_mem_block(mb_p, __func__);
     tx_data_pdu_buffer->mem_block = NULL;
     LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] ACK PDU SN %05d previous retx_count %d \n",
           PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
           snP,
 		  tx_data_pdu_buffer->retx_count);
+    }
 
     if (tx_data_pdu_buffer->retx_payload_size) {
+    	AssertFatal (tx_data_pdu_buffer->flags.ack == 0,
+    			"RLC AM Rx Status Report sn=%d acked twice but is pending for Retx vtA=%d vtS=%d LcId=%d\n",
+				snP, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
       rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_buffer->retx_payload_size;
       tx_data_pdu_buffer->retx_payload_size = 0;
       tx_data_pdu_buffer->num_holes = 0;
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
index 338bc791968565aba6640d19f2e6dc181c30695c..7224d39bf96b90b11562fb4be5eb47c74daeca41 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
@@ -74,12 +74,14 @@ protected_rlc_am_retransmit(boolean_t         rlc_am_nack_pdu (
 * \param[in]  ctxtP        Running context.
 * \param[in]  rlcP         RLC AM protocol instance pointer.
 * \param[in]  snP          Sequence number of the PDU that is acknowledged.
+* \param[in]  free_pdu     Boolean indicating that the PDU can be freed because smaller than new vtA.
 * \note                    Depending on the state of the retransmission buffer, positive confirmation can be sent to higher layers about the receiving by the peer RLC AM instance of a particular SDU.
 */
 protected_rlc_am_retransmit(void         rlc_am_ack_pdu (
                               const protocol_ctxt_t* const  ctxt_pP,
                               rlc_am_entity_t *const rlcP,
-                              const rlc_sn_t snP);)
+                              const rlc_sn_t snP,
+							  boolean_t free_pdu);)
 
 /*! \fn mem_block_t* rlc_am_retransmit_get_copy (const protocol_ctxt_t* const  ctxt_pP, rlc_am_entity_t *rlcP, rlc_sn_t snP)
 * \brief      The RLC AM PDU which have the sequence number snP is marked ACKed.
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
index c07e9cd6f3fbd65f51ec07a584784bb6b799ad3d..a5c15a5262a15bcb154c9c013765ebeb8f5645db 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
@@ -318,7 +318,7 @@ rlc_am_receive_process_control_pdu(
     {
       if (rlc_pP->control_pdu_info.num_nack == 0) {
         while (sn_cursor != ack_sn) {
-          rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor);
+          rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
           sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
         }
 
@@ -330,7 +330,7 @@ rlc_am_receive_process_control_pdu(
         prev_nack_sn = 0x3FFF;
 
         while (sn_cursor != nack_sn) {
-            rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor);
+            rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
             sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
         }
 
@@ -354,7 +354,8 @@ rlc_am_receive_process_control_pdu(
           if (sn_cursor != nack_sn) {
             rlc_am_ack_pdu(ctxt_pP,
                            rlc_pP,
-                           sn_cursor);
+                           sn_cursor,
+						   FALSE);
           } else {
         	status = rlc_am_nack_pdu (ctxt_pP,
                              rlc_pP,
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
index 2dfa472523f5a536f7515ccaaa8d1fbbc218168b..3edb09d22815ca0053af0aecf9aed40f1f53e8a7 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
@@ -88,8 +88,8 @@ rlc_am_check_timer_poll_retransmit(
           /* Look for the first retransmittable PDU starting from vtS - 1 */
 		  while (sn != sn_end) {
 			tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE];
-			AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n",
-					sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+			AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d ack=%d is empty vtA=%d vtS=%d LcId=%d\n",
+					sn, tx_data_pdu_buffer_p->flags.ack,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
 		    if ((tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) {
 		    	tx_data_pdu_buffer_p->flags.retransmit = 1;
 		    	tx_data_pdu_buffer_p->retx_payload_size = tx_data_pdu_buffer_p->payload_size;
diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h
index 99e3f7367a13aea276f0927a9c90b076c957ccdb..ddc060e8c331328b9b8a3a564940df4fba896e80 100644
--- a/targets/COMMON/threads_t.h
+++ b/targets/COMMON/threads_t.h
@@ -6,6 +6,9 @@ typedef struct threads_s {
     int one;
     int two;
     int three;
+    int slot1_proc_one;
+    int slot1_proc_two;
+    int slot1_proc_three;
 } threads_t;
 
 #endif /* _THREADS_T_H_ */
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 5623231511f1609f6e459fcd8e0541c87f9b201c..a1f3bcb57b209ec28d86b097e9213e5996cd05ed 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -150,6 +150,9 @@ int chain_offset=0;
 int phy_test = 0;
 uint8_t usim_test = 0;
 
+uint8_t dci_Format = 0;
+uint8_t agregation_Level =0xFF;
+
 uint8_t nb_antenna_tx = 1;
 uint8_t nb_antenna_rx = 1;
 
@@ -222,7 +225,7 @@ double cpuf;
 char uecap_xer[1024],uecap_xer_in=0;
 
 int oaisim_flag=0;
-threads_t threads= {-1,-1,-1,-1};
+threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
 
 /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
  * this is very hackish - find a proper solution
@@ -329,6 +332,8 @@ void help (void) {
   printf("  --external-clock tells hardware to use an external clock reference\n");
   printf("  --usim-test use XOR autentication algo in case of test usim mode\n"); 
   printf("  --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); 
+  printf("  --AgregationLevel Choose the agregation level used by tghe eNB for the OAI use 1, it will save some time of processing the pdcch\n");
+  printf("  --DCIformat choose the DCI format, be careful when using this option(for the moment only valid for SISO DCI format 1)\n");
   printf("  -A Set timing_advance\n");
   printf("  -C Set the downlink frequency for all component carriers\n");
   printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
@@ -640,6 +645,11 @@ static void get_options (int argc, char **argv) {
         LONG_OPTION_THREADONESUBFRAME,
         LONG_OPTION_THREADTWOSUBFRAME,
         LONG_OPTION_THREADTHREESUBFRAME,
+        LONG_OPTION_THREADSLOT1PROCONE,
+        LONG_OPTION_THREADSLOT1PROCTWO,
+        LONG_OPTION_THREADSLOT1PROCTHREE,
+        LONG_OPTION_DCIFORMAT,
+        LONG_OPTION_AGREGATIONLEVEL,
         LONG_OPTION_DEMOD_SHIFT,
 #if T_TRACER
         LONG_OPTION_T_PORT,
@@ -677,6 +687,11 @@ static void get_options (int argc, char **argv) {
         {"threadOneSubframe",  required_argument, NULL, LONG_OPTION_THREADONESUBFRAME},
         {"threadTwoSubframe",  required_argument, NULL, LONG_OPTION_THREADTWOSUBFRAME},
         {"threadThreeSubframe",  required_argument, NULL, LONG_OPTION_THREADTHREESUBFRAME},
+        {"threadSlot1ProcOne",  required_argument, NULL, LONG_OPTION_THREADSLOT1PROCONE},
+        {"threadSlot1ProcTwo",  required_argument, NULL, LONG_OPTION_THREADSLOT1PROCTWO},
+        {"threadSlot1ProcThree",  required_argument, NULL, LONG_OPTION_THREADSLOT1PROCTHREE},
+        {"DCIformat",  required_argument, NULL, LONG_OPTION_DCIFORMAT},
+        {"AgregationLevel",  required_argument, NULL, LONG_OPTION_AGREGATIONLEVEL},
         {"dlsch-demod-shift", required_argument,  NULL, LONG_OPTION_DEMOD_SHIFT},
 #if T_TRACER
         {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
@@ -811,6 +826,21 @@ static void get_options (int argc, char **argv) {
     case LONG_OPTION_THREADTHREESUBFRAME:
        threads.three=atoi(optarg);
     break;
+    case LONG_OPTION_THREADSLOT1PROCONE:
+       threads.slot1_proc_one=atoi(optarg);
+       break;
+    case LONG_OPTION_THREADSLOT1PROCTWO:
+       threads.slot1_proc_two=atoi(optarg);
+       break;
+    case LONG_OPTION_THREADSLOT1PROCTHREE:
+       threads.slot1_proc_three=atoi(optarg);
+       break;
+    case LONG_OPTION_DCIFORMAT:
+        dci_Format = atoi(optarg);
+       break;
+    case LONG_OPTION_AGREGATIONLEVEL:
+        agregation_Level = atoi(optarg);
+        break;
     case LONG_OPTION_DEMOD_SHIFT: {
         extern int16_t dlsch_demod_shift;
         dlsch_demod_shift = atof(optarg);
@@ -1560,6 +1590,7 @@ int main( int argc, char **argv ) {
         NB_UE_INST=1;
         NB_INST=1;
 
+
         PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
         PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
 
@@ -1591,6 +1622,11 @@ int main( int argc, char **argv ) {
             UE[CC_id]->mode    = mode;
             printf("UE[%d]->mode = %d\n",CC_id,mode);
 
+            for (uint8_t i=0; i<RX_NB_TH_MAX; i++) {
+                UE[CC_id]->pdcch_vars[i][0]->agregationLevel = agregation_Level;
+                UE[CC_id]->pdcch_vars[i][0]->dciFormat     = dci_Format;
+            }
+
             compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                               UE[CC_id]->frame_parms.frame_type,
                               UE[CC_id]->X_u);
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index b438d9eee2fc04cb630e78a4d80d33b1b986669f..4d9d145c68b4edde7c56836ba7ae552c1dbbe966 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -81,6 +81,7 @@ extern void kill_eNB_proc(int inst);
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
 extern void fill_ue_band_info(void);
 extern void init_UE(int);
+extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name);
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 65d74f5ef14fc7feeb06e5077372bc12be6c85bf..3b84e8ea97987ef9266681ad2a9623d9efebf70a 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -476,15 +476,6 @@ static void *UE_thread_synch(void *arg) {
     return &UE_thread_synch_retval;
 }
 
-
-/* this structure is used to pass both UE phy vars and
- * proc to the function UE_thread_rxn_txnp4
- */
-struct rx_tx_thread_data {
-  PHY_VARS_UE    *UE;
-  UE_rxtx_proc_t *proc;
-};
-
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
  * This thread performs the phy_procedures_UE_RX() on every received slot.
@@ -507,12 +498,13 @@ static void *UE_thread_rxn_txnp4(void *arg) {
     sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
+
     if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
         CPU_SET(threads.one, &cpuset);
     if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
         CPU_SET(threads.two, &cpuset);
     if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 )
-            CPU_SET(threads.three, &cpuset);
+        CPU_SET(threads.three, &cpuset);
             //CPU_SET(threads.three, &cpuset);
     init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
                 threadname);
@@ -558,7 +550,11 @@ static void *UE_thread_rxn_txnp4(void *arg) {
                        (sf_type==SF_UL? "SF_UL" :
                         (sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
             }
+#ifdef UE_SLOT_PARALLELISATION
+            phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
+#else
             phy_procedures_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
+#endif
         }
 
 #if UE_TIMING_TRACE
@@ -649,6 +645,8 @@ void *UE_thread(void *arg) {
     char threadname[128];
     int th_id;
 
+    static uint8_t thread_idx = 0;
+
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
     if ( threads.iq != -1 )
@@ -700,6 +698,10 @@ void *UE_thread(void *arg) {
                 }
 		AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
             } else {
+#if OAISIM
+              (void)dummy_rx; /* avoid gcc warnings */
+              usleep(500);
+#else
                 // grab 10 ms of signal into dummy buffer
                 if (UE->mode != loop_through_memory) {
                     for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
@@ -712,6 +714,7 @@ void *UE_thread(void *arg) {
                                               UE->frame_parms.samples_per_tti,
                                               UE->frame_parms.nb_antennas_rx);
                 }
+#endif
             }
 
         } // UE->is_synchronized==0
@@ -729,6 +732,7 @@ void *UE_thread(void *arg) {
                                                                UE->frame_parms.nb_antennas_rx),"");
                     }
                     UE->rx_offset=0;
+                    UE->time_sync_cell=0;
                     //UE->proc.proc_rxtx[0].frame_rx++;
                     //UE->proc.proc_rxtx[1].frame_rx++;
                     for (th_id=0; th_id < RX_NB_TH; th_id++) {
@@ -750,7 +754,16 @@ void *UE_thread(void *arg) {
             } else {
                 sub_frame++;
                 sub_frame%=10;
-                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame%RX_NB_TH];
+                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
+                // update thread index for received subframe
+                UE->current_thread_id[sub_frame] = thread_idx;
+
+                LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
+
+                thread_idx++;
+                if(thread_idx>=RX_NB_TH)
+                    thread_idx = 0;
+
 
                 if (UE->mode != loop_through_memory) {
                     for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
@@ -836,6 +849,7 @@ void *UE_thread(void *arg) {
                                          UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
 
                     proc->instance_cnt_rxtx++;
+                    LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
                     if (proc->instance_cnt_rxtx == 0) {
                       if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
                         LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
@@ -871,6 +885,10 @@ void *UE_thread(void *arg) {
  * - UE_thread_rxtx0
  * - UE_thread_rxtx1
  * - UE_thread_synch
+ * - UE_thread_fep_slot0
+ * - UE_thread_fep_slot1
+ * - UE_thread_dlsch_proc_slot0
+ * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
 void init_UE_threads(PHY_VARS_UE *UE) {
@@ -896,9 +914,19 @@ void init_UE_threads(PHY_VARS_UE *UE) {
         UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
         printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
         pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
+
+#ifdef UE_SLOT_PARALLELISATION
+        //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL);
+        //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL);
+        //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd);
+
+        pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL);
+        pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL);
+        pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
+#endif
+
     }
     pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
-
 }
 
 
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index d07cd759d1c84885d0987b1bc38865bb7e46fbb3..d8f9ae2738a5cf4eb24946e8bb391e07afc2b603 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -184,7 +184,7 @@ extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
 
 double cpuf;
 #include "threads_t.h"
-threads_t threads= {-1,-1,-1};
+threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
 
 //#ifdef XFORMS
 int otg_enabled;
@@ -1405,7 +1405,8 @@ reset_opp_meas_oaisim (void)
   reset_meas (&ul_chan_stats);
 
   for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
-    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc);
+    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[0]);
+    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[1]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_tx);
@@ -1574,7 +1575,9 @@ print_opp_meas_oaisim (void)
   }
 
   for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
-    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc, "[UE][total_phy_proc]",
+    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[0], "[UE][total_phy_proc[0]]",
+                &oaisim_stats, &oaisim_stats_f);
+    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[1], "[UE][total_phy_proc[1]]",
                 &oaisim_stats, &oaisim_stats_f);
 
     print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0],
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 71304aea8ece1c2e35a4a1f9ffbb35b121e2a29c..2782620eabfbff56bca9b76cbb87ade50149b1f7 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -1431,6 +1431,11 @@ void init_openair1(void)
 	PHY_vars_UE_g[UE_id][CC_id]->mac_enabled=1;
 
       PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti = 0x1235 + UE_id;
+
+      for (uint8_t i=0; i<RX_NB_TH_MAX; i++) {
+          PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->dciFormat      = 0;
+          PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[i][0]->agregationLevel      = 0xFF;
+      }
       PHY_vars_UE_g[UE_id][CC_id]->current_dlsch_cqi[0] = 10;
 
       LOG_I(EMU, "UE %d mode is initialized to %d\n", UE_id, PHY_vars_UE_g[UE_id][CC_id]->UE_mode[0] );