diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 0c80e960a45286fe34d3387d3c0783267cb63dc7..d9ed38a4ec84faa06c69e610a37f07e039efbb1a 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -941,9 +941,14 @@
       (Test 7b, 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)),
       (Test 10, 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)),
       (Test 10b, 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)),
-      (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
+      (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)),
+      (Test 11b, 10 MHz, R7-1.FDD (MCS 25), EVA5, 16.7dB (70%)),
+      (Test 15, 20 MHz, R.9 FDD	(MCS 26), EVA5, 17.6dB (70%)),
+      (Test 15b, 20 MHz, R.9-2 FDD (MCS 26, 17PRB), EVA5, 17.3dB (70%)),
+      (Test 15c, 20 MHz, R.9-1 FDD (MCS 26, 83 PRB), EVA5, 16.6dB (70%)),
+
       (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
-      (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+      (TM2 Test 1b 5 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
        </desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
@@ -960,6 +965,9 @@
                        -m25 -gF -s17.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70
                        -m25 -gF -s17.5 -w1.0 -f.2 -n500 -B25 -c3 -z2 -r1022 -O70
                        -m26 -gF -s17.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70
+                       -m26 -gF -s17.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -O70
+                       -m26 -gF -s17.3 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1600 -O70
+                       -m26 -gF -s16.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1899 -O70
 		       -m14 -gF -s6.8  -w1.0 -f.2 -n500 -B50 -c2 -x2 -y2 -z2 -O70
                        -m13 -gF -s5.9  -w1.0 -f.2 -n500 -B25 -c3 -x2 -y2 -z2 -O70</main_exec_args>
       <tags>dlsim.test1 dlsim.test5 dlsim.test6 dlsim.test6b dlsim.test7 dlsim.test7b dlsim.test10 dlsim.test10b dlsim.test11 dlsim.TM2_test1 dlsim.TM2_test1b</tags>
diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt
index 5ed4d93d800250f7ed1eae511e6615782e5cd46e..ab718a8503d3a1339d0ba3996eae2e082458319d 100644
--- a/cmake_targets/lte-simulators/CMakeLists.txt
+++ b/cmake_targets/lte-simulators/CMakeLists.txt
@@ -3,7 +3,7 @@ set(PACKAGE_NAME "unitary_tests_simulators")
 set(PHYSIM True)
 set(RF_BOARD None)
 set(XFORMS True)
-
+set(ENABLE_ITTI False)
 set(DEBUG_PHY False)
 set(MU_RECIEVER False)
 set(RANDOM_BF False)
diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile
index f6c65f64000e6da238d14d843d1fe36e8325eda2..fd58005fff6bf3fb890f4ee9ac2a0809388b26cd 100644
--- a/common/utils/T/tracer/Makefile
+++ b/common/utils/T/tracer/Makefile
@@ -58,7 +58,7 @@ filter/filter.a:
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 clean:
-	rm -f *.o core tracer_remote textlog enb vcd record replay
+	rm -f *.o core tracer_remote textlog enb ue vcd record replay
 	rm -f extract_config macpdu2wireshark
 	cd gui && make clean
 	cd view && make clean
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 53c12d04cf7ab6f71826bba3fecec49446609aee..e2915594ab786f710a6d13849b4d8874c1a9682d 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -1082,18 +1082,19 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
   // create shortcuts
   LTE_DL_FRAME_PARMS* const fp            = &ue->frame_parms;
   LTE_UE_COMMON* const common_vars        = &ue->common_vars;
-  LTE_UE_PDSCH** const pdsch_vars_th0     = ue->pdsch_vars[0];
-  LTE_UE_PDSCH** const pdsch_vars_th1     = ue->pdsch_vars[1];
   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_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;
   LTE_UE_PBCH** const pbch_vars           = ue->pbch_vars;
-  LTE_UE_PDCCH** const pdcch_vars_th0     = ue->pdcch_vars[0];
-  LTE_UE_PDCCH** const pdcch_vars_th1     = ue->pdcch_vars[1];
   LTE_UE_PRACH** const prach_vars         = ue->prach_vars;
 
+
+
   int i,j,k,l;
   int eNB_id;
+  int th_id;
 
   printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
@@ -1137,109 +1138,105 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
     // init RX buffers
 
     common_vars->rxdata   = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-    common_vars->common_vars_rx_data_per_thread[0].rxdataF  = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-    common_vars->common_vars_rx_data_per_thread[1].rxdataF  = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        common_vars->common_vars_rx_data_per_thread[th_id].rxdataF  = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+    }
 
     for (i=0; i<fp->nb_antennas_rx; i++) {
       common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) );
-      common_vars->common_vars_rx_data_per_thread[0].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
-      common_vars->common_vars_rx_data_per_thread[1].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+          common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
+      }
     }
   }
 
   // Channel estimates
   for (eNB_id=0; eNB_id<7; eNB_id++) {
-    common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+        common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+    }
 
     for (i=0; i<fp->nb_antennas_rx; i++)
       for (j=0; j<4; j++) {
         int idx = (j<<1) + i;
-        common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-        common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-        common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
-        common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
+        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+            common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
+            common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
+        }
       }
   }
 
   // DLSCH
   for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
-    pdsch_vars_th0[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
-    pdsch_vars_th1[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        (*pdsch_vars_th)[th_id][eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    }
+
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
+    }
+
     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_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
-    pdcch_vars_th0[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
-    pdcch_vars_th1[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
     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));
 
     if (abstraction_flag == 0) {
-      phy_init_lte_ue__PDSCH( pdsch_vars_th0[eNB_id], fp );
-      phy_init_lte_ue__PDSCH( pdsch_vars_th1[eNB_id], fp );
-
-      // thread 0
-      pdsch_vars_th0[eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
-      pdsch_vars_th0[eNB_id]->llr_shifts_p        = pdsch_vars_th0[eNB_id]->llr_shifts;
-      pdsch_vars_th0[eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-      pdsch_vars_th0[eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
-      pdsch_vars_th0[eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-
-       // thread 0
-      pdsch_vars_th1[eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
-      pdsch_vars_th1[eNB_id]->llr_shifts_p        = pdsch_vars_th0[eNB_id]->llr_shifts;
-      pdsch_vars_th1[eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-      pdsch_vars_th1[eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
-      pdsch_vars_th1[eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-
-
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+         phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
+      }
 
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
+        (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p        = (*pdsch_vars_th)[0][eNB_id]->llr_shifts;
+        (*pdsch_vars_th)[th_id][eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+        (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
+        (*pdsch_vars_th)[th_id][eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
+      }
 
       for (int i=0; i<fp->nb_antennas_rx; i++){
-        pdsch_vars_th0[eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-        pdsch_vars_th1[eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+            (*pdsch_vars_th)[th_id][eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
         }
 
-      pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdsch_vars_th1[eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+        }
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+          (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      }
 
       for (i=0; i<fp->nb_antennas_rx; i++)
         for (j=0; j<4; j++) {
           const int idx = (j<<1)+i;
           const size_t num = 7*2*fp->N_RB_DL*12+4;
-          pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdsch_vars_th1[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-        }
+          for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+              (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+          }
 
+        }
 
       //const size_t num = 7*2*fp->N_RB_DL*12+4;
       for (k=0;k<8;k++) { //harq_pid
         for (l=0;l<8;l++) { //round
-          pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th0[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-
-          pdsch_vars_th1[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th1[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-          pdsch_vars_th1[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+          for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+              (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+              (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+              (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+              (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+          }
 
 
           for (int i=0; i<fp->nb_antennas_rx; i++)
             for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
               const int idx = (j<<1)+i;
-              pdsch_vars_th0[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-
-              pdsch_vars_th1[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th1[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-              pdsch_vars_th1[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+              for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+                  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+                  (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+                  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+                  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+              }
+
                 }
         }
       }
@@ -1248,46 +1245,35 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
       phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
 
       // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
-      pdcch_vars_th0[eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th0[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th0[eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th0[eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
-
-      pdcch_vars_th0[eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th0[eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th0[eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-      pdcch_vars_th0[eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-
-      pdcch_vars_th1[eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th1[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th1[eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-      pdcch_vars_th1[eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
-
-      pdcch_vars_th1[eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th1[eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th1[eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-      pdcch_vars_th1[eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-      pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+          (*pdcch_vars_th)[th_id][eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+          (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+          (*pdcch_vars_th)[th_id][eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+          (*pdcch_vars_th)[th_id][eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
+
+          (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+          (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+          (*pdcch_vars_th)[th_id][eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+          (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+          (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      }
+      
       for (i=0; i<fp->nb_antennas_rx; i++) {
         //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
-        pdcch_vars_th0[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
-        pdcch_vars_th1[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
-
+        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+            (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
+        }
+        
         for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
           int idx = (j<<1)+i;
           //  size_t num = 7*2*fp->N_RB_DL*12;
           size_t num = 4*100*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
-          pdcch_vars_th0[eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th0[eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th0[eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-
-          pdcch_vars_th1[eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th1[eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th1[eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-          pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+          for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+              (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+              (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+              (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+              (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+          }
         }
       }
 
@@ -1314,18 +1300,19 @@ int phy_init_lte_ue(PHY_VARS_UE *ue,
   }
 
   // initialization for the last instance of pdsch_vars (used for MU-MIMO)
+  for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdsch_vars_th)[th_id][eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
+  }
 
-  pdsch_vars_th0[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
-  pdsch_vars_th1[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
   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) );
 
   if (abstraction_flag == 0) {
-    phy_init_lte_ue__PDSCH( pdsch_vars_th0[eNB_id], fp );
-    pdsch_vars_th0[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
+        (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+    }
 
-    phy_init_lte_ue__PDSCH( pdsch_vars_th1[eNB_id], fp );
-    pdsch_vars_th1[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
   } else { //abstraction == 1
     ue->sinr_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
   }
diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h
index 08615119ef613667c78ac6b63aafc3355d79aeef..f2cbf97f9d52d8883bbc13430e27d144bb3f0e30 100644
--- a/openair1/PHY/LTE_ESTIMATION/defs.h
+++ b/openair1/PHY/LTE_ESTIMATION/defs.h
@@ -161,7 +161,7 @@ int lte_est_freq_offset(int **dl_ch_estimates,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         int l,
                         int* freq_offset,
-			int reset);
+            int reset);
 
 int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
                               LTE_DL_FRAME_PARMS *frame_parms,
@@ -180,7 +180,7 @@ This function computes the time domain channel response, finds the peak and adju
 void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
                       PHY_VARS_UE *phy_vars_ue,
                       module_id_t eNb_id,
-					  uint8_t subframe,
+                      uint8_t subframe,
                       unsigned char clear,
                       short coef);
 
@@ -189,7 +189,8 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
                          unsigned int subframe_offset,
                          unsigned char N0_symbol,
                          unsigned char abstraction_flag,
-						 uint8_t subframe);
+                         unsigned char rank_adaptation,
+                         uint8_t subframe);
 
 //! \brief This function performance RSRP/RSCP measurements
 void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
@@ -214,11 +215,11 @@ int8_t set_RSRQ_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,floa
 
 //! Automatic gain control
 void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue,
-		      uint32_t rx_power_fil_dB,
+              uint32_t rx_power_fil_dB,
                       unsigned char eNB_id);
 
 int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
-			      eNB_rxtx_proc_t *proc,
+                  eNB_rxtx_proc_t *proc,
                               module_id_t eNB_id,
                               module_id_t UE_id,
                               uint8_t l,
@@ -246,7 +247,7 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
 int lte_est_timing_advance_pusch(PHY_VARS_eNB* phy_vars_eNB,module_id_t UE_id);
 
 void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB,
-			     int subframe,
+                 int subframe,
                              module_id_t eNB_id,
                              unsigned char clear);
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index cefa6fd99f91d083914a111642649ab270800680..7e90116180aa97291dbf481dd4ba808c5525303e 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -58,8 +58,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&0x1].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
-      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
+      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)];
       temp += (Re*Re/2) + (Im*Im/2);
     }
 
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 7e112342ce15980c0e199cc930c6428ea8347db7..8d98511e482ee8a2bed42b849b321fcda22d0c83 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)&0x1][eNB_id];
+  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[(Ns>>1)%RX_NB_TH][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)&0x1].rxdataF;
+  rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF;
 
-  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[(Ns>>1)&0x1][eNB_id]->dl_bf_ch_estimates;
+  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[(Ns>>1)%RX_NB_TH][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 9743c68a22a2071e84fef4ed29c36293c8441429..0ff4fde9aac89dcf5f248b606f9e524eb8206914 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -50,9 +50,10 @@ 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;
-  int **dl_ch_estimates         =ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[eNB_offset];
-  int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[((Ns>>1)+1)&0x1].dl_ch_estimates[eNB_offset];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF;
+  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;
 
   if (ue->frame_parms.Ncp == 0) {  // normal prefix
     pilot1 = 4;
@@ -799,15 +800,15 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
   // 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)&0x1].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
-        idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
-             (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
+      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 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)&0x1].dl_ch_estimates_time[eNB_offset][0][0], 512  * 4));
+          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));
 #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 2ce0e45b14988c390b70a36f0dc5821f0da5047f..f375cdec3de5132dc0c8daba636b3517a5b631c1 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&0x1].dl_ch_estimates[0];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF;
+  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;
 
   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&0x1].dl_ch_estimates[eNB_offset][aa]) {
+    if (ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].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&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	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],
 		1);
 	break;
       case 25:
-	idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	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],
 		1);
 	break;
       case 50:
-	idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	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],
 		1);
 	break;
       case 75:
-	idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		 (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	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],
 		 1);
 	break;
       case 100:
-	idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	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],
 		1);
 	break;
       default:
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index 4033e4c37835351927db640fe5f11cc1ea0b0a01..cc676ce467b217bf990c491966837e5440af0e08 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -34,6 +34,9 @@
 
 //#define DEBUG_MEAS_RRC
 //#define DEBUG_MEAS_UE
+//#define DEBUG_RANK_EST
+
+int16_t cond_num_threshold = 0;
 
 #ifdef USER_MODE
 void print_shorts(char *s,short *x)
@@ -207,61 +210,61 @@ 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&0x1].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
-	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
+	      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)];
           }
           else
           {
-              rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
-              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
+              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)];
           }
               //-ve spectrum from SSS
 
               //+ve spectrum from SSS
-	          ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
+              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
-	      //	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
-	      //	      printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
+              //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
+              //              printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
               //+ve spectrum from PSS
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
               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
+          //              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
               if(ue->frame_parms.frame_type == FDD)
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
+                  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)];
               }
               else
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
+                  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)];
               }
-	      //              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[-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]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
-              
+
               ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[-70]*rxF_sss[-70])+((int32_t)rxF_sss[-69]*rxF_sss[-69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-68]*rxF_sss[-68])+((int32_t)rxF_sss[-67]*rxF_sss[-67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-66]*rxF_sss[-66])+((int32_t)rxF_sss[-65]*rxF_sss[-65]));
 
-	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
-	      //	      printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
+          //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
+          //          printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
               ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
               ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
-            }
+        }
 
             //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
 
-	    ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
-	    ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
-          } else {
+        ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
+        ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
+        } else {
             LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n");
-          }
+        }
         }
         else if ((ue->frame_parms.frame_type == TDD) &&
                  ((subframe == 1) || (subframe == 6))) {  // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation
@@ -272,10 +275,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&0x1)].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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)&0x1].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF;
                 rxF_sss  = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))];
 
                 //-ve spectrum from SSS
@@ -300,7 +303,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&0x1].rxdataF[aarx][(7*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)];
             //              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]));
@@ -310,12 +313,11 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
             //          printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
                 ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
                 ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
-	    }
+        }
 
         ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
         ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
 
-
         //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
 
           }
@@ -347,7 +349,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&0x1].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
+          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)];
           off  = (ue->frame_parms.first_carrier_offset+k)<<1;
 
           if (l==(4-ue->frame_parms.Ncp)) {
@@ -357,8 +359,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 
               ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
               //        printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
-	      //	      if ((ue->frame_rx&0x3ff) == 0)
-	      //                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
+              //              if ((ue->frame_rx&0x3ff) == 0)
+              //                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
 
 
               off+=12;
@@ -424,7 +426,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
     //    if (slot == 0) {
 
       if (eNB_offset == 0)
-        LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
+       LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
               ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
               10*log10(ue->measurements.rssi),
               ue->rx_total_gain_dB,
@@ -454,7 +456,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
                          unsigned int subframe_offset,
                          unsigned char N0_symbol,
                          unsigned char abstraction_flag,
-						 uint8_t subframe)
+                         unsigned char rank_adaptation,
+                         uint8_t subframe)
 {
 
 
@@ -468,17 +471,17 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
   int16x8_t *dl_ch0_128, *dl_ch1_128;
 #endif
   int *dl_ch0,*dl_ch1;
+
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int nb_subbands,subband_size,last_subband_size;
   int N_RB_DL = frame_parms->N_RB_DL;
+
+
+  int rank_tm3_tm4;
+
+
   ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
 
-    if (ue->transmission_mode[eNB_id]!=4)
-     ue->measurements.rank[eNB_id] = 0;
-    else
-    ue->measurements.rank[eNB_id] = 1;
-  //  printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
-  //  printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
 
   switch (N_RB_DL) {
   case 6:
@@ -512,7 +515,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&0x1].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
+          (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],
                               (N_RB_DL*12)));
         //- ue->measurements.n0_power[aarx];
 
@@ -539,6 +542,28 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 
   } //eNB_id
 
+  eNB_id=0;
+  if (ue->transmission_mode[0]==4 || ue->transmission_mode[0]==3){
+    if (rank_adaptation == 1)
+      rank_tm3_tm4 = rank_estimation_tm3_tm4(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][4],
+                                             N_RB_DL);
+    else
+      rank_tm3_tm4=1;
+#ifdef DEBUG_RANK_EST
+  printf("rank tm3 or tm4 %d\n", rank_tm3_tm4);
+#endif
+  }
+
+  if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3)
+    ue->measurements.rank[eNB_id] = 0;
+  else
+    ue->measurements.rank[eNB_id] = rank_tm3_tm4;
+  //  printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
+  //  printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
+
   // filter to remove jitter
   if (ue->init_averaging == 0) {
     for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++)
@@ -547,7 +572,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
             (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10);
 
     //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg,
-  	//	  ue->measurements.n0_power_tot);
+    //    ue->measurements.n0_power_tot);
     ue->measurements.n0_power_avg = (int)
         (((k1*((long long int) (ue->measurements.n0_power_avg))) +
           (k2*((long long int) (ue->measurements.n0_power_tot))))>>10);
@@ -567,12 +592,12 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 #ifdef DEBUG_MEAS_UE
       LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
             eNB_id,
-			subframe,
+            subframe,
             ue->measurements.rx_rssi_dBm[eNB_id],
             ue->measurements.rx_power_avg_dB[eNB_id],
             ue->measurements.wideband_cqi_avg[eNB_id],
             ue->measurements.rx_power_avg[eNB_id],
-            ue->measurements.n0_power_avg);
+            ue->measurements.n0_power_tot);
 #endif
   }
 
@@ -583,8 +608,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&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        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];
 
         for (subband=0; subband<nb_subbands; subband++) {
 
@@ -633,19 +658,19 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
       }
 
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-	//printf("aarx=%d", aarx);
+        //printf("aarx=%d", aarx);
         // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit)
 
 #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&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        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];
 #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&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        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];
 
 #endif
         for (subband=0; subband<nb_subbands; subband++) {
@@ -654,12 +679,12 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
           // pmi
 #if defined(__x86_64__) || defined(__i386__)
 
-	  pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re);
+          pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re);
           pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im);
 #elif defined(__arm__)
 
           pmi128_re = vdupq_n_s32(0);
-	  pmi128_im = vdupq_n_s32(0);
+          pmi128_im = vdupq_n_s32(0);
 #endif
           // limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB)
           // for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB
@@ -671,48 +696,48 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
           for (i=0; i<limit; i++) {
 
 #if defined(__x86_64__) || defined(__i386__)
-	      mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
+              mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
               mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
 
             // For each RE in subband perform ch0 * conj(ch1)
             // multiply by conjugated channel
-		//  print_ints("ch0",&dl_ch0_128[0]);
-		//  print_ints("ch1",&dl_ch1_128[0]);
+                //  print_ints("ch0",&dl_ch0_128[0]);
+                //  print_ints("ch1",&dl_ch1_128[0]);
 
-	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
-	         //  print_ints("re",&mmtmpPMI0);
+            mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
+                 //  print_ints("re",&mmtmpPMI0);
             mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));
               //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
-	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
+                //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]);
-	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
+               //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]);
-	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
+               //   print_ints("mm_madd_epi16",&mmtmpPMI1);
             // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
             pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
-	     //   print_ints(" pmi128_re 0",&pmi128_re);
+             //   print_ints(" pmi128_re 0",&pmi128_re);
             pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
-	       //   print_ints(" pmi128_im 0 ",&pmi128_im);
+               //   print_ints(" pmi128_im 0 ",&pmi128_im);
 
-	  /*  mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
+          /*  mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
             mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
 
-	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]);
-	         //  print_ints("re",&mmtmpPMI0);
+            mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]);
+                 //  print_ints("re",&mmtmpPMI0);
             mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1));
               //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
-	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
+                //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate);
-	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
+               //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]);
-	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
+               //   print_ints("mm_madd_epi16",&mmtmpPMI1);
             // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
             pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
-	        //  print_ints(" pmi128_re 1",&pmi128_re);
+                //  print_ints(" pmi128_re 1",&pmi128_re);
             pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
-	    //print_ints(" pmi128_im 1 ",&pmi128_im);*/
+            //print_ints(" pmi128_im 1 ",&pmi128_im);*/
 
 #elif defined(__arm__)
 
@@ -739,7 +764,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&0x1].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][aarx][4];
 
         for (subband=0; subband<7; subband++) {
 
@@ -806,3 +831,553 @@ void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id)
   msg("[PHY] EMUL UE lte_ue_measurements_emul subframe %d, eNB_id %d\n",subframe,eNB_id);
 }
 
+
+uint8_t rank_estimation_tm3_tm4 (int *dl_ch_estimates_00, // please respect the order of channel estimates
+                                 int *dl_ch_estimates_01,
+                                 int *dl_ch_estimates_10,
+                                 int *dl_ch_estimates_11,
+                                 unsigned short nb_rb)
+{
+
+  int i=0;
+  int rank=0;
+  int N_RB=nb_rb;
+  int *ch00_rank, *ch01_rank, *ch10_rank, *ch11_rank;
+
+  int32_t shift;
+  int avg_0[2];
+  int avg_1[2];
+
+  int count=0;
+
+  /* we need at least alignment to 16 bytes, let's put 32 to be sure
+   * (maybe not necessary but doesn't hurt)
+   */
+  int32_t conjch00_ch01[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch01_ch00[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch10_ch11[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch11_ch10[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch00_ch00[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch01_ch01[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch10_ch10[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch11_ch11[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_00[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_00_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_01_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_10_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_11_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_01[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_10[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_11[12*N_RB] __attribute__((aligned(32)));
+  int32_t determ_fin[12*N_RB] __attribute__((aligned(32)));
+  int32_t denum_db[12*N_RB] __attribute__((aligned(32)));
+  int32_t numer_fin[12*N_RB] __attribute__((aligned(32)));
+  int32_t numer_db[12*N_RB] __attribute__((aligned(32)));
+  int32_t cond_db[12*N_RB] __attribute__((aligned(32)));
+
+  ch00_rank = dl_ch_estimates_00;
+  ch01_rank = dl_ch_estimates_01;
+  ch10_rank = dl_ch_estimates_10;
+  ch11_rank = dl_ch_estimates_11;
+
+  dlsch_channel_level_TM34_meas(ch00_rank,
+                                ch01_rank,
+                                ch10_rank,
+                                ch11_rank,
+                                avg_0,
+                                avg_1,
+                                N_RB);
+
+  avg_0[0] = (log2_approx(avg_0[0])/2);
+  shift = cmax(avg_0[0],0);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n shift %d \n" , shift);
+  printf("\n conj(ch00)ch01 \n");
+#endif
+
+  conjch0_mult_ch1(ch00_rank,
+                   ch01_rank,
+                   conjch00_ch01,
+                   N_RB,
+                   shift); // this is an arbitrary shift to avoid overflow. can be changed.
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch01)ch00 \n");
+#endif
+
+  conjch0_mult_ch1(ch01_rank,
+                   ch00_rank,
+                   conjch01_ch00,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch10)ch11 \n");
+#endif
+
+
+  conjch0_mult_ch1(ch10_rank,
+                   ch11_rank,
+                   conjch10_ch11,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch11)ch10 \n");
+#endif
+
+  conjch0_mult_ch1(ch11_rank,
+                   ch10_rank,
+                   conjch11_ch10,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch00)ch00 \n");
+#endif
+
+  conjch0_mult_ch1(ch00_rank,
+                   ch00_rank,
+                   conjch00_ch00,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch01)ch01 \n");
+#endif
+
+  conjch0_mult_ch1(ch01_rank,
+                   ch01_rank,
+                   conjch01_ch01,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch10)ch10 \n");
+#endif
+
+  conjch0_mult_ch1(ch10_rank,
+                   ch10_rank,
+                   conjch10_ch10,
+                   N_RB,
+                   shift);
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch11)ch11 \n");
+#endif
+
+  conjch0_mult_ch1(ch11_rank,
+                   ch11_rank,
+                   conjch11_ch11,
+                   N_RB,
+                   shift);
+
+  construct_HhH_elements(conjch00_ch00,
+                         conjch01_ch01,
+                         conjch11_ch11,
+                         conjch10_ch10,
+                         conjch00_ch01,
+                         conjch01_ch00,
+                         conjch10_ch11,
+                         conjch11_ch10,
+                         af_mf_00,
+                         af_mf_01,
+                         af_mf_10,
+                         af_mf_11,
+                         N_RB);
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH00|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_00,
+                         af_mf_00_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH01|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_01,
+                         af_mf_01_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH10|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_10,
+                         af_mf_10_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH11|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_11,
+                         af_mf_11_sq,
+                         N_RB);
+
+  det_HhH(af_mf_00,
+          af_mf_01,
+          af_mf_10,
+          af_mf_11,
+          determ_fin,
+          N_RB);
+
+  numer(af_mf_00_sq,
+        af_mf_01_sq,
+        af_mf_10_sq,
+        af_mf_11_sq,
+        numer_fin,
+        N_RB);
+
+  for (i=1; i<12*N_RB; i++)
+  {
+    denum_db[i]=dB_fixed(determ_fin[i]);
+    numer_db[i]=dB_fixed(numer_fin[i]);
+    cond_db[i]=(numer_db[i]-denum_db[i]);
+    if (cond_db[i] < cond_num_threshold)
+      count++;
+#ifdef DEBUG_RANK_EST
+    printf("cond_num_threshold =%d \n", cond_num_threshold);
+    printf("i %d  numer_db[i] = %d \n", i, numer_db[i]);
+    printf("i %d  denum_db[i] = %d \n", i, denum_db[i]);
+    printf("i %d  cond_db[i] =  %d \n", i, cond_db[i]);
+    printf("i %d counter = %d \n", i, count);
+#endif
+  }
+
+  if (count >= 6*N_RB) // conditional number is lower 10dB in half on more Res Blocks
+    rank=1;
+
+#ifdef DEBUG_RANK_EST
+    printf(" rank = %d \n", rank);
+#endif
+   return(rank);
+}
+
+void conjch0_mult_ch1(int *ch0,
+                      int *ch1,
+                      int32_t *ch0conj_ch1,
+                      unsigned short nb_rb,
+                      unsigned char output_shift0)
+{
+  //This function is used to compute multiplications in Hhermitian * H matrix
+  unsigned short rb;
+  __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
+
+  dl_ch0_128 = (__m128i *)ch0;
+  dl_ch1_128 = (__m128i *)ch1;
+
+  ch0conj_ch1_128 = (__m128i *)ch0conj_ch1;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
+    mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
+    mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]);
+    mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+    mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+    mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+    mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+    ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing conjugates \n");
+    print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]);
+    print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]);
+    print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]);
+#endif
+
+    dl_ch0_128+=1;
+    dl_ch1_128+=1;
+    ch0conj_ch1_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+void construct_HhH_elements(int *ch0conj_ch0, //00_00
+                            int *ch1conj_ch1,//01_01
+                            int *ch2conj_ch2,//11_11
+                            int *ch3conj_ch3,//10_10
+                            int *ch0conj_ch1,//00_01
+                            int *ch1conj_ch0,//01_00
+                            int *ch2conj_ch3,//10_11
+                            int *ch3conj_ch2,//11_10
+                            int32_t *after_mf_00,
+                            int32_t *after_mf_01,
+                            int32_t *after_mf_10,
+                            int32_t *after_mf_11,
+                            unsigned short nb_rb)
+{
+  unsigned short rb;
+  __m128i *ch0conj_ch0_128, *ch1conj_ch1_128, *ch2conj_ch2_128, *ch3conj_ch3_128;
+  __m128i *ch0conj_ch1_128, *ch1conj_ch0_128, *ch2conj_ch3_128, *ch3conj_ch2_128;
+  __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
+
+  ch0conj_ch0_128 = (__m128i *)ch0conj_ch0;
+  ch1conj_ch1_128 = (__m128i *)ch1conj_ch1;
+  ch2conj_ch2_128 = (__m128i *)ch2conj_ch2;
+  ch3conj_ch3_128 = (__m128i *)ch3conj_ch3;
+  ch0conj_ch1_128 = (__m128i *)ch0conj_ch1;
+  ch1conj_ch0_128 = (__m128i *)ch1conj_ch0;
+  ch2conj_ch3_128 = (__m128i *)ch2conj_ch3;
+  ch3conj_ch2_128 = (__m128i *)ch3conj_ch2;
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    after_mf_00_128[0] =_mm_adds_epi16(ch0conj_ch0_128[0],ch3conj_ch3_128[0]);// _mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10
+    after_mf_11_128[0] =_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11
+    after_mf_01_128[0] =_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]);//00_01 + 10_11
+    after_mf_10_128[0] =_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]);//01_00 + 11_10
+
+#ifdef DEBUG_RANK_EST
+    printf(" \n construct_HhH_elements \n");
+    print_shorts("ch0conj_ch0_128:",(int16_t*)&ch0conj_ch0_128[0]);
+    print_shorts("ch1conj_ch1_128:",(int16_t*)&ch1conj_ch1_128[0]);
+    print_shorts("ch2conj_ch2_128:",(int16_t*)&ch2conj_ch2_128[0]);
+    print_shorts("ch3conj_ch3_128:",(int16_t*)&ch3conj_ch3_128[0]);
+    print_shorts("ch0conj_ch1_128:",(int16_t*)&ch0conj_ch1_128[0]);
+    print_shorts("ch1conj_ch0_128:",(int16_t*)&ch1conj_ch0_128[0]);
+    print_shorts("ch2conj_ch3_128:",(int16_t*)&ch2conj_ch3_128[0]);
+    print_shorts("ch3conj_ch2_128:",(int16_t*)&ch3conj_ch2_128[0]);
+    print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
+    print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
+    print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
+    print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+#endif
+
+    ch0conj_ch0_128+=1;
+    ch1conj_ch1_128+=1;
+    ch2conj_ch2_128+=1;
+    ch3conj_ch3_128+=1;
+    ch0conj_ch1_128+=1;
+    ch1conj_ch0_128+=1;
+    ch2conj_ch3_128+=1;
+    ch3conj_ch2_128+=1;
+
+    after_mf_00_128+=1;
+    after_mf_01_128+=1;
+    after_mf_10_128+=1;
+    after_mf_11_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+void squared_matrix_element(int32_t *Hh_h_00,
+                            int32_t *Hh_h_00_sq,
+                            unsigned short nb_rb)
+{
+   unsigned short rb;
+  __m128i *Hh_h_00_128,*Hh_h_00_sq_128;
+
+  Hh_h_00_128 = (__m128i *)Hh_h_00;
+  Hh_h_00_sq_128 = (__m128i *)Hh_h_00_sq;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    Hh_h_00_sq_128[0] = _mm_madd_epi16(Hh_h_00_128[0],Hh_h_00_128[0]);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing squared_matrix_element \n");
+    print_shorts("Hh_h_00_128:",(int16_t*)&Hh_h_00_128[0]);
+    print_ints("Hh_h_00_sq_128:",(int32_t*)&Hh_h_00_sq_128[0]);
+#endif
+
+    Hh_h_00_sq_128+=1;
+    Hh_h_00_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+
+void det_HhH(int32_t *after_mf_00,
+             int32_t *after_mf_01,
+             int32_t *after_mf_10,
+             int32_t *after_mf_11,
+             int32_t *det_fin,
+             unsigned short nb_rb)
+
+{
+  unsigned short rb;
+  __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128;
+  __m128i *det_fin_128, det_128;
+
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  det_fin_128 = (__m128i *)det_fin;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    ad_re_128 = _mm_madd_epi16(after_mf_00_128[0],after_mf_11_128[0]);
+    bc_re_128 = _mm_madd_epi16(after_mf_01_128[0],after_mf_01_128[0]);
+    det_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
+    det_fin_128[0] = _mm_abs_epi32(det_128);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing denominator \n");
+    print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
+    print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
+    print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
+    print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+    print_ints("ad_re_128:",(int32_t*)&ad_re_128);
+    print_ints("bc_re_128:",(int32_t*)&bc_re_128);
+    print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+#endif
+
+    det_fin_128+=1;
+    after_mf_00_128+=1;
+    after_mf_01_128+=1;
+    after_mf_10_128+=1;
+    after_mf_11_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+void numer(int32_t *Hh_h_00_sq,
+           int32_t *Hh_h_01_sq,
+           int32_t *Hh_h_10_sq,
+           int32_t *Hh_h_11_sq,
+           int32_t *num_fin,
+           unsigned short nb_rb)
+
+{
+  unsigned short rb;
+  __m128i *h_h_00_sq_128, *h_h_01_sq_128, *h_h_10_sq_128, *h_h_11_sq_128;
+  __m128i *num_fin_128, sq_a_plus_sq_d_128, sq_b_plus_sq_c_128;
+
+  h_h_00_sq_128 = (__m128i *)Hh_h_00_sq;
+  h_h_01_sq_128 = (__m128i *)Hh_h_01_sq;
+  h_h_10_sq_128 = (__m128i *)Hh_h_10_sq;
+  h_h_11_sq_128 = (__m128i *)Hh_h_11_sq;
+
+  num_fin_128 = (__m128i *)num_fin;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    sq_a_plus_sq_d_128 = _mm_add_epi32(h_h_00_sq_128[0],h_h_11_sq_128[0]);
+    sq_b_plus_sq_c_128 = _mm_add_epi32(h_h_01_sq_128[0],h_h_10_sq_128[0]);
+    num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing numerator \n");
+    print_ints("h_h_00_sq_128:",(int32_t*)&h_h_00_sq_128[0]);
+    print_ints("h_h_01_sq_128:",(int32_t*)&h_h_01_sq_128[0]);
+    print_ints("h_h_10_sq_128:",(int32_t*)&h_h_10_sq_128[0]);
+    print_ints("h_h_11_sq_128:",(int32_t*)&h_h_11_sq_128[0]);
+    print_shorts("sq_a_plus_sq_d_128:",(int16_t*)&sq_a_plus_sq_d_128);
+    print_shorts("sq_b_plus_sq_c_128:",(int16_t*)&sq_b_plus_sq_c_128);
+    print_shorts("num_fin_128:",(int16_t*)&num_fin_128[0]);
+#endif
+
+    num_fin_128+=1;
+    h_h_00_sq_128+=1;
+    h_h_01_sq_128+=1;
+    h_h_10_sq_128+=1;
+    h_h_11_sq_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+
+
+
+void dlsch_channel_level_TM34_meas(int *ch00,
+                                   int *ch01,
+                                   int *ch10,
+                                   int *ch11,
+                                   int *avg_0,
+                                   int *avg_1,
+                                   unsigned short nb_rb)
+{
+
+#if defined(__x86_64__)||defined(__i386__)
+
+  short rb;
+  unsigned char nre=12;
+  __m128i *ch00_128, *ch01_128, *ch10_128, *ch11_128;
+  __m128i avg_0_row0_128D, avg_1_row0_128D, avg_0_row1_128D, avg_1_row1_128D;
+  __m128i ch00_128_tmp, ch01_128_tmp, ch10_128_tmp, ch11_128_tmp;
+
+  avg_0[0] = 0;
+  avg_0[1] = 0;
+  avg_1[0] = 0;
+  avg_1[1] = 0;
+
+  ch00_128 = (__m128i *)ch00;
+  ch01_128 = (__m128i *)ch01;
+  ch10_128 = (__m128i *)ch10;
+  ch11_128 = (__m128i *)ch11;
+
+  avg_0_row0_128D = _mm_setzero_si128();
+  avg_1_row0_128D = _mm_setzero_si128();
+  avg_0_row1_128D = _mm_setzero_si128();
+  avg_1_row1_128D = _mm_setzero_si128();
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+    ch00_128_tmp = _mm_load_si128(&ch00_128[0]);
+    ch01_128_tmp = _mm_load_si128(&ch01_128[0]);
+    ch10_128_tmp = _mm_load_si128(&ch10_128[0]);
+    ch11_128_tmp = _mm_load_si128(&ch11_128[0]);
+
+    avg_0_row0_128D = _mm_add_epi32(avg_0_row0_128D,_mm_madd_epi16(ch00_128_tmp,ch00_128_tmp));
+    avg_1_row0_128D = _mm_add_epi32(avg_1_row0_128D,_mm_madd_epi16(ch01_128_tmp,ch01_128_tmp));
+    avg_0_row1_128D = _mm_add_epi32(avg_0_row1_128D,_mm_madd_epi16(ch10_128_tmp,ch10_128_tmp));
+    avg_1_row1_128D = _mm_add_epi32(avg_1_row1_128D,_mm_madd_epi16(ch11_128_tmp,ch11_128_tmp));
+
+    ch00_128+=1;
+    ch01_128+=1;
+    ch10_128+=1;
+    ch11_128+=1;
+  }
+
+  avg_0[0] = (((int*)&avg_0_row0_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[3])/(nb_rb*nre);
+
+  avg_1[0] = (((int*)&avg_1_row0_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[3])/(nb_rb*nre);
+
+  avg_0[1] = (((int*)&avg_0_row1_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[3])/(nb_rb*nre);
+
+  avg_1[1] = (((int*)&avg_1_row1_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[3])/(nb_rb*nre);
+
+  avg_0[0] = avg_0[0] + avg_0[1];
+  avg_1[0] = avg_1[0] + avg_1[1];
+  avg_0[0] = min (avg_0[0], avg_1[0]);
+  avg_1[0] = avg_0[0];
+
+  _mm_empty();
+  _m_empty();
+
+#elif defined(__arm__)
+
+#endif
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 41180b6e61c4c5ec88b404e98438575e4f3a4f31..3fd618cec8badf542569481d57206e0e0901dc45 100755
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -1693,7 +1693,7 @@ 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 & 0x1];
+  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[subframe%RX_NB_TH];
 
   uint8_t log2_maxh,aatx,aarx;
 #ifdef MU_RECEIVER
@@ -1707,16 +1707,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
 
   for (s=0; s<n_pdcch_symbols; s++) {
     if (is_secondary_ue == 1) {
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].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[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_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[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].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[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_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,
@@ -1724,16 +1724,16 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
                                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&0x1].rxdataF,
-                             common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+      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_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[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+      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_vars[eNB_id]->rxdataF_ext,
                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                                s,
@@ -2031,7 +2031,7 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
   }
 
 
-  LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
+  LOG_D(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
   //for (i=0;i<num_dci;i++) {
   //  printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
   //}
@@ -2514,7 +2514,7 @@ void dci_decoding(uint8_t DCI_LENGTH,
 }
 
 
-static uint8_t dci_decoded_output[2][(MAX_DCI_SIZE_BITS+64)/8];
+static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
 
 uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
 {
@@ -2818,12 +2818,12 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
       dci_decoding(sizeof_bits,
                    L,
                    &pdcch_vars[eNB_id]->e_rx[CCEind*72],
-                   &dci_decoded_output[subframe&0x1][0]);
+                   &dci_decoded_output[subframe%RX_NB_TH][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&0x1][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[subframe&0x1][0],sizeof_bits);
+      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);
 #ifdef DEBUG_DCI_DECODING
       printf("crc =>%x\n",crc);
 #endif
@@ -2839,29 +2839,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&0x1][0];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][1];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][2];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][3];
+          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];
 #ifdef DEBUG_DCI_DECODING
-          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[subframe&0x1][0],
-                  dci_decoded_output[subframe&0x1][1],
-                  dci_decoded_output[subframe&0x1][2],
-                  dci_decoded_output[subframe&0x1][3]);
+          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]);
 #endif
         } else {
-          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[subframe&0x1][0];
-          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[subframe&0x1][1];
-          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[subframe&0x1][2];
-          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[subframe&0x1][3];
-          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe&0x1][4];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][5];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][6];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][7];
+          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];
 #ifdef DEBUG_DCI_DECODING
           printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
-              dci_decoded_output[subframe&0x1][0],dci_decoded_output[subframe&0x1][1],dci_decoded_output[subframe&0x1][2],dci_decoded_output[subframe&0x1][3],
-              dci_decoded_output[subframe&0x1][4],dci_decoded_output[subframe&0x1][5],dci_decoded_output[subframe&0x1][6],dci_decoded_output[subframe&0x1][7]);
+              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]);
 #endif
         }
 
@@ -2878,7 +2878,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&0x1][0]&0x80)==0)) {// check if pdu is format 0 or 1A
+          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 (*format0_found == 0) {
               dci_alloc[*dci_cnt].format     = format0;
               *format0_found = 1;
@@ -2946,7 +2946,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 & 0x1];
+  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[subframe%RX_NB_TH];
   LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
   uint8_t mi = get_mi(&ue->frame_parms,subframe);
   uint16_t ra_rnti=99;
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index d61dca4648b893608bfedfc5e1dd4107b1a7cdbe..c39518690dcd52057d8ac27596242475e27c616d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -1270,7 +1270,6 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     if (dlsch0_harq->round == 0) {
       dlsch0_harq->status = ACTIVE;
-      //            printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
       // MCS and TBS don't change across HARQ rounds
       dlsch0_harq->mcs         = mcs;
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
@@ -1494,7 +1493,6 @@ int generate_eNB_dlsch_params_from_dci(int frame,
       break;
     }
 
-
     if (harq_pid>=8) {
       LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
       return(-1);
@@ -1513,7 +1511,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
       TB1_active=0;
     }
 #ifdef DEBUG_HARQ
-    printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
+    printf(" eNOdeB RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
 #endif
     if (TB0_active && TB1_active && tbswap==0) {
       dlsch0=dlsch[0];
@@ -1578,6 +1576,8 @@ int generate_eNB_dlsch_params_from_dci(int frame,
       printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
 #endif
     }
+  // printf("[eNB] dlsch0_harq->round = %d, dlsch1_harq->round = %d \n", dlsch0_harq->round, dlsch1_harq->round);
+
 
     if (dlsch0 != NULL){
       dlsch0->subframe_tx[subframe] = 1;
@@ -1721,6 +1721,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
             dlsch1_harq->pmi_alloc   = DL_pmi_single;
             break;
           }
+         // printf ("[eNB] dlsch1_harq->pmi_alloc %d\n", dlsch1_harq->pmi_alloc);
         }
 
     } else if (frame_parms->nb_antenna_ports_eNB == 4) {
@@ -1738,6 +1739,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
     if (dlsch1 != NULL)
       dlsch1->rnti = rnti;
 
+
     break;
 
   case format2A:
@@ -2829,8 +2831,6 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
 int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
 {
-
-
   switch (dci->format) {
 
   case format0:   // This is an UL SCH allocation so nothing here, inform MAC
@@ -4773,25 +4773,27 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
     uint8_t  mcs1      = pdci_info_extarcted->mcs1;
     uint8_t  TPC       = pdci_info_extarcted->TPC;
     uint8_t  rah       = pdci_info_extarcted->rah;
-//#ifdef DEBUG_DCI
+#ifdef DEBUG_DCI
     uint8_t  rv1       = pdci_info_extarcted->rv1;
     uint8_t  ndi1      = pdci_info_extarcted->ndi1;
-//#endif
+#endif
 
     uint8_t  NPRB    = 0;
     long long int RIV_max = 0;
 
-//#ifdef DEBUG_DCI
+
     LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti       %x\n",  rnti);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid   %d\n", harq_pid);
     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);
+#ifdef DEBUG_DCI
     LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1        %d\n", rv1);
     LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1       %d\n", ndi1);
+#endif
     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)
@@ -4933,7 +4935,7 @@ int check_dci_format1c_coherency(uint8_t N_RB_DL,
 
     // I- check dci content minimum coherency
 
-    if((rnti!=si_rnti) || (rnti!=p_rnti) || (rnti!=ra_rnti))
+    if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti))
       return(0);
 
     switch (N_RB_DL) {
@@ -5045,22 +5047,15 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
 
     }
 
-    /*
-    if((pdlsch0_harq->round > 0) && (mcs1 != pdlsch0_harq->mcs))
-    {
-      // DCI false detection
-      return(0);
-    }*/
 
-
-    if((pdlsch0_harq->round == 0) && (rv1 > 0))
+    if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
     {
       // DCI false detection
         LOG_I(PHY,"bad rv1\n");
       return(0);
     }
 
-    if((pdlsch1_harq->round == 0) && (rv2 > 0))
+    if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
     {
       // DCI false detection
         LOG_I(PHY,"bad rv2\n");
@@ -5243,7 +5238,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
             case 100:
                 nb_rb_alloc     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                 break;
-            }
+        }
         }
         else
         {
@@ -5279,7 +5274,6 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
         pdlsch0_harq->round    = 0;
-        pdlsch0_harq->first_tx = 1;
         pdlsch0_harq->status   = ACTIVE;
     }
     else //CRNTI
@@ -5291,27 +5285,36 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
 				 rnti,harq_pid,pdlsch0_harq->DCINdi);
     	}
 
-        // DCI has been toggled or this is the first transmission
-        if (ndi1!=pdlsch0_harq->DCINdi)
+        // NDI has been toggled or this is the first transmission
+        if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1))
         {
             pdlsch0_harq->round    = 0;
-            pdlsch0_harq->first_tx = 1;
+            pdlsch0_harq->first_tx = 0;
             pdlsch0_harq->status   = ACTIVE;
+
         }
 
-        if( ((ndi1 == pdlsch0_harq->DCINdi) && (pdlsch0_harq->round == 0)) ||
-            ((rv1  != 0) && (pdlsch0_harq->round == 0))
-          )
+	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_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;
+		//pdlsch0_harq->first_tx = 0;
+	      }
+	    else  //normal retransmission
+	      {
+		// nothing special to do
+	      }
         }
     }
 
@@ -5587,6 +5590,9 @@ switch (tpmi) {
                 dlsch1_harq->pmi_alloc   = pmi_alloc;
                 dlsch0_harq->pmi_alloc   = pmi_alloc^0x1555;
             }
+#ifdef DEBUG_HARQ
+              printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc);
+  #endif
           break;
           default:
           break;
@@ -5618,20 +5624,17 @@ switch (tpmi) {
             break;
             case 5:
               dlsch_harq->mimo_mode   = PUSCH_PRECODING0;
-              dlsch_harq->pmi_alloc   = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
-  #ifdef DEBUG_HARQ
-              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
-  #endif
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
             break;
             case 6:
               dlsch_harq->mimo_mode   = PUSCH_PRECODING1;
-              dlsch_harq->pmi_alloc   = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+            break;
+            }
   #ifdef DEBUG_HARQ
-              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
+              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi);
   #endif
-            break;
             }
-}
 
 void compute_precoding_info_format2A(uint8_t tpmi,
                                      uint8_t nb_antenna_ports_eNB,
@@ -5755,15 +5758,12 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
     uint8_t  ndi1     = pdci_info_extarcted->ndi1;
     uint8_t  ndi2     = pdci_info_extarcted->ndi2;
 
-    uint8_t TB0_active = 0;
-    uint8_t TB1_active = 0;
+    uint8_t TB0_active = 1;
+    uint8_t TB1_active = 1;
 
+   // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc);
 
 
-      // check if either TB is disabled (see 36-213 V8.6 p. 26)
-      TB0_active = 1;
-      TB1_active = 1;
-
       if ((rv1 == 1) && (mcs1 == 0)) {
         TB0_active=0;
       }
@@ -5810,6 +5810,16 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
         dlsch1_harq->codeword = 0;
       }
 
+
+      if (!TB0_active && TB1_active){
+        dlsch1_harq->codeword = 0;
+      }
+
+      if (TB0_active && !TB1_active){
+        dlsch0_harq->codeword = 0;
+      }
+
+
       if (TB0_active==0) {
         dlsch0_harq->status = SCH_IDLE;
         pdlsch0->active     = 0;
@@ -5823,9 +5833,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
         pdlsch1->active     = 0;
       }
 
-//#ifdef DEBUG_HARQ
+#ifdef DEBUG_HARQ
       printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-//#endif
+#endif
 
       // compute resource allocation
       if (TB0_active == 1){
@@ -5880,10 +5890,13 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
       {
       if ((TB0_active) && (TB1_active)){  //two CW active
         compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq);
+
+   //   printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
       } else if ((TB0_active) && (!TB1_active))  { // only CW 0 active
         compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq);
       } else {
-        compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch1_harq);
+        compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq);
+       // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi);
       }
       //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
       if ((frame_parms->mode1_flag == 1) && (TB0_active))
@@ -5898,11 +5911,14 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                       dlsch0_harq,
                                       dlsch1_harq);
       }
-
+  //    printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
       // reset round + compute Qm
       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->status = ACTIVE;
+           dlsch0_harq->DCINdi = ndi1;
 
           //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n",
           //           subframe,harq_pid,dlsch0_harq->round);
@@ -5910,18 +5926,18 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
             dlsch0_harq->first_tx = 0;
           }
-        }else{
-         if(dlsch0_harq->round == 0) {
-#if 0
+        }
+	/*else if (rv1  != 0 )
+	  //NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch0_harq->status == SCH_IDLE) {
             // skip pdsch decoding and report ack
-            dlsch0_harq->status   = SCH_IDLE;
+	      //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;
-#endif
-         }
-        }
+	    }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
         // PDCCH for the same trasport block using Imcs in [0 .. 28]
@@ -5944,27 +5960,33 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             dlsch0_harq->Qm = (mcs1-28)<<1;
       }
 
+   //   printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+
       if (TB1_active) {
+       // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx);
         if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
           dlsch1_harq->round = 0;
+          dlsch1_harq->status = ACTIVE;
+          dlsch1_harq->DCINdi = ndi2;
           //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n",
           //           subframe,harq_pid,dlsch0_harq->round);
           if (dlsch1_harq->first_tx==1) {
             LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
             dlsch1_harq->first_tx = 0;
           }
-        }else{
-#if 0
-         if(dlsch1_harq->round == 0) {
+        }
+	/*else if (rv1  != 0 )
+	//NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch1_harq->status == SCH_IDLE) {
             // skip pdsch decoding and report ack
-            dlsch1_harq->status   = SCH_IDLE;
+	      //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;
          }
-#endif
-        }
+	  }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
         // PDCCH for the same trasport block using Imcs in [0 .. 28]
@@ -5992,18 +6014,18 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                          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);
-#endif
 
-  #ifdef DEBUG_HARQ
+
+ /* #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);
       else if (dlsch0 == NULL && dlsch1 != NULL)
         printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status);
       else if (dlsch0 != NULL && dlsch1 == NULL)
         printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status);
-  #endif
+  #endif*/
 }
 
 int generate_ue_dlsch_params_from_dci(int frame,
@@ -6023,12 +6045,12 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       uint16_t tc_rnti)
 {
 
-
     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;
+
     DCI_INFO_EXTRACTED_t dci_info_extarcted;
     uint8_t status=0;
 
@@ -6230,20 +6252,19 @@ int generate_ue_dlsch_params_from_dci(int frame,
                 dci_pdu,
                 &dci_info_extarcted);
 
+
         // check dci content
-        dlsch[0]->active = 0;
-        dlsch[1]->active = 0;
+        dlsch[0]->active = 1;
+        dlsch[1]->active = 1;
 
-        if (dci_info_extarcted.tb_swap == 0) {
             dlsch0 = dlsch[0];
             dlsch1 = dlsch[1];
-        } else {
-            dlsch0 = dlsch[1];
-            dlsch1 = dlsch[0];
-        }
 
-        dlsch0_harq = dlsch0->harq_processes[harq_pid];
-        dlsch1_harq = dlsch1->harq_processes[harq_pid];
+    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
+   // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc);
+   // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc);
+   // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc);
 
         //LOG_I(PHY,"[DCI-format2] check dci content \n");
         status = check_dci_format2_2a_coherency(format2,
@@ -6258,6 +6279,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
         if(status == 0)
             return(-1);
 
+
         // dci is correct ==> update internal structure and prepare dl decoding
         //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n");
         prepare_dl_decoding_format2_2A(format2,
@@ -6271,7 +6293,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
                 dlsch1_harq,
                 dlsch0,
                 dlsch1);
-
     }
     break;
 
@@ -6458,11 +6479,15 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0_harq->mimo_mode   = SISO;
 
 
-      if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) {
+      if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) ||
+	(dlsch0_harq->first_tx==1)) {
 
         dlsch0_harq->round = 0;
+	dlsch0_harq->first_tx = 0;
         dlsch0_harq->status = ACTIVE;
-      } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process,
+      }
+      /*
+	else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process,
         // this happens if either another harq process in the same
         // is NAK or an ACK was not received
 
@@ -6472,6 +6497,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0->active = 0;
         return(0);
       }
+      */
 
       dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
       dlsch0_harq->mcs    = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
@@ -6499,16 +6525,15 @@ int generate_ue_dlsch_params_from_dci(int frame,
       break;
     }
 
-
 #ifdef UE_DEBUG_TRACE
 
     if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
         LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
-        LOG_D(PHY,"PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
+        LOG_I(PHY,"PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
         LOG_D(PHY,"PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
         LOG_D(PHY,"PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
-        LOG_D(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",harq_pid);
-        LOG_D(PHY,"PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
+        LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid);
+        LOG_I(PHY,"PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
         LOG_D(PHY,"PDSCH dlsch0 UE: round    %d\n",dlsch0_harq->round);
         LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
         LOG_D(PHY,"PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
@@ -7322,7 +7347,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&0x1][0];
+  LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe%RX_NB_TH][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];
@@ -8129,7 +8154,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&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
+      if (ue->dlsch[dl_subframe%RX_NB_TH][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;
@@ -8888,7 +8913,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 &0x1].dl_ch_estimates[eNB_id];
+  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[subframe %RX_NB_TH].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/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 90f8242cc87c9af6a507b0b0850114c125189a3e..7d4bfc05930d520b793a115a88beccaf8d7d9a75 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -598,7 +598,9 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-
+#ifdef DEBUG_DLSCH_CODING
+  printf("encoding thinks this is a new packet \n");
+#endif
     /*
     int i;
     printf("dlsch (tx): \n");
@@ -705,6 +707,9 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
 #endif
 
     start_meas(rm_stats);
+#ifdef DEBUG_DLSCH_CODING
+  printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                         G,  //G
                                         dlsch->harq_processes[harq_pid]->w[r],
@@ -775,7 +780,9 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-
+#ifdef DEBUG_DLSCH_CODING
+  printf("SIC encoding thinks this is a new packet \n");
+#endif
     /*
     int i;
     printf("dlsch (tx): \n");
@@ -882,6 +889,9 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
 #endif
 
     start_meas(rm_stats);
+#ifdef DEBUG_DLSCH_CODING
+    printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                         G,  //G
                                         dlsch->harq_processes[harq_pid]->w[r],
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 87d5d481627e1fb903825da13dd5be5d8b291978..6114a29bdd6c5f14dd8350d353a85709c11c3ee7 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&0x1];
+  /*harq_pid = dlsch->current_harq_pid[subframe%RX_NB_TH];
   if (harq_pid >= 8) {
     printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
     return(max_turbo_iterations);
@@ -393,7 +393,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
           harq_process->round);
 #endif
 
-//printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#ifdef DEBUG_DLSCH_DECODING
+    printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
                                    G,
                                    harq_process->w[r],
@@ -960,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&0x1][eNB_id][0];
+    dlsch_ue  = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0];
     harq_pid = dlsch_ue->current_harq_pid;
-    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe & 0x1][(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[subframe%RX_NB_TH][(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];
 
@@ -1006,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&0x1][eNB_id][1];
+    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1];
     harq_pid = dlsch_ue->current_harq_pid;
-    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe & 0x1][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] );
+    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] );
     DevAssert( UE_id != -1 );
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1];
     // reset HARQ
@@ -1060,7 +1062,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   default:
-    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
+    dlsch_ue = phy_vars_ue->dlsch[subframe%RX_NB_TH][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 f2a743898431f2ccdc397e20ad1d35e6914bbf25..ffc8d0405e1fdd0118004111e58b2f1f9410bfe0 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -48,6 +48,7 @@
  * default value: 0
  */
 int16_t dlsch_demod_shift = 0;
+int16_t interf_unaw_shift = 13;
 
 //#define DEBUG_HARQ
 
@@ -61,9 +62,6 @@ int16_t dlsch_demod_shift = 0;
 
 // [MCS][i_mod (0,1,2) = (2,4,6)]
 unsigned char offset_mumimo_llr_drange_fix=0;
-uint8_t interf_unaw_shift0=0;
-uint8_t interf_unaw_shift1=0;
-uint8_t interf_unaw_shift=0;
 //inferference-free case
 unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
                                              1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
@@ -146,8 +144,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
 
   case PDSCH:
-    pdsch_vars = ue->pdsch_vars[subframe&0x1];
-    dlsch = ue->dlsch[subframe&0x1][eNB_id];
+    pdsch_vars = ue->pdsch_vars[subframe%RX_NB_TH];
+    dlsch = ue->dlsch[subframe%RX_NB_TH][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,
                    dlsch[0]->harq_processes[harq_pid]->status,
@@ -159,6 +158,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
       dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
       dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming both TBs are active\n");
+#endif
     }
      else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
               (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
@@ -166,6 +168,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
       dlsch1_harq = NULL;
       codeword_TB1 = -1;
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming only TB0 is active\n");
+#endif
     }
      else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
               (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
@@ -173,6 +178,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       dlsch0_harq  = dlsch[1]->harq_processes[harq_pid];
       dlsch1_harq  = NULL;
       codeword_TB0 = -1;
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword);
+#endif
     }
     else {
       LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe);
@@ -193,6 +201,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
   DevAssert(dlsch0_harq);
   round = dlsch0_harq->round;
+  //printf("round = %d\n", round);
 
   if (eNB_id > 2) {
     LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
@@ -232,7 +241,6 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 
 
-
   if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING)))  {
     DevAssert(dlsch1_harq);
     if (eNB_id!=eNB_id_i) {
@@ -240,14 +248,17 @@ int rx_pdsch(PHY_VARS_UE *ue,
       return(-1);
     }
   }
+#ifdef DEBUG_HARQ
+  printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
+#endif
 
   if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
 #ifdef DEBUG_DLSCH_MOD
     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&0x1].rxdataF,
-                                   common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+    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],
                                    pdsch_vars[eNB_id]->rxdataF_ext,
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    dlsch0_harq->pmi_alloc,
@@ -267,8 +278,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&0x1].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
+      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],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -280,8 +291,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&0x1].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+        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],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -294,8 +305,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&0x1].rxdataF,
-                                     common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+    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],
                                      pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      dlsch0_harq->pmi_alloc,
@@ -308,8 +319,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&0x1].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
+        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],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -320,8 +331,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&0x1].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+        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],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -333,7 +344,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&0x1].rxdataF,
+    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
@@ -409,23 +420,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                  nb_rb,
                                  dlsch0_harq->mimo_mode);
 
-      LOG_D(PHY,"Channel Level TM34  avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, interf_unaw_shift %d \n", avg_0[0],
-              avg_1[0], rx_type, rx_standard, interf_unaw_shift);
+      LOG_D(PHY,"Channel Level TM34  avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0],
+              avg_1[0], rx_type, rx_standard, dlsch_demod_shift);
         if (rx_type>rx_standard) {
           avg_0[0] = (log2_approx(avg_0[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
           avg_1[0] = (log2_approx(avg_1[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
           pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
           pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
-          //printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
-          //printf("TM4 I-A log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
+         // printf("dlsch_demod_shift  %d\n", dlsch_demod_shift);
          }
           else {
           avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift;
           avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift;
           pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
           pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
-          //printf("TM4 I-UA log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
-          //printf("TM4 I-UA log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
         }
       }
       else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
@@ -769,7 +777,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
   switch (dlsch0_harq->Qm) {
   case 2 :
-    if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
+    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
                        (int16_t*)pllr_symbol_cw0,
@@ -778,6 +786,17 @@ int rx_pdsch(PHY_VARS_UE *ue,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
                        beamforming_mode);
+
+    } else if (codeword_TB0 == -1){
+
+        dlsch_qpsk_llr(frame_parms,
+                       pdsch_vars[eNB_id]->rxdataF_comp0,
+                       (int16_t*)pllr_symbol_cw1,
+                       symbol,
+                       first_symbol_flag,
+                       nb_rb,
+                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+                       beamforming_mode);
     }
       else if (rx_type >= rx_IC_single_stream) {
         if (dlsch1_harq->Qm == 2) {
@@ -847,7 +866,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
       }
     break;
   case 4 :
-    if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
+    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
       dlsch_16qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       pdsch_vars[eNB_id]->llr[0],
@@ -856,6 +875,15 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
                       pdsch_vars[eNB_id]->llr128,
                       beamforming_mode);
+    } else if (codeword_TB0 == -1){
+      dlsch_16qam_llr(frame_parms,
+                      pdsch_vars[eNB_id]->rxdataF_comp0,
+                      pdsch_vars[eNB_id]->llr[1],
+                      pdsch_vars[eNB_id]->dl_ch_mag0,
+                      symbol,first_symbol_flag,nb_rb,
+                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+                      pdsch_vars[eNB_id]->llr128_2ndstream,
+                      beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
       if (dlsch1_harq->Qm == 2) {
@@ -931,9 +959,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
     break;
   case 6 :
-    //printf("LLR rx_type %d cw0 %d cw1 %d symbol %d first symbol %d nb_rb %d rballoceven %d sfn %d beamforming_mode %d\n",
-    //        rx_type,codeword_TB0,codeword_TB1,symbol,first_symbol_flag,nb_rb,dlsch0_harq->rb_alloc_even,subframe,beamforming_mode);
-    if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1))  {
+    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       (int16_t*)pllr_symbol_cw0,
@@ -943,6 +969,16 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
                       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,
+                      (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]->llr_offset[symbol],
+                      beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
       if (dlsch1_harq->Qm == 2) {
@@ -1074,12 +1110,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&0x1].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&0x1].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&0x1].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&0x1].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&0x1].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&0x1].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[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("rxdataF_ext00.m"    , "rxdataF_ext00",       &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
@@ -3397,7 +3433,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
 
   short rb;
   unsigned char aatx,aarx,nre=12,symbol_mod;
-  __m128i *dl_ch128, avg128D, coeff128;
+  __m128i *dl_ch128, avg128D;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
@@ -3408,11 +3444,10 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
   else
     nre=12;
 
-  double one_over_nb_re = 0.0;
-  one_over_nb_re = 1/((double)(nb_rb*nre));
-  int16_t one_over_nb_re_q1_15 = (int16_t)(one_over_nb_re * (double)(1<<15) );
-  coeff128 = _mm_set_epi16(one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,
-                            one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15);
+  //nb_rb*nre = y * 2^x
+  int16_t x = factor2(nb_rb*nre);
+  int16_t y = (nb_rb*nre)>>x;
+  //printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x);
 
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -3425,14 +3460,18 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
       for (rb=0;rb<nb_rb;rb++) {
         //      printf("rb %d : ",rb);
         //      print_shorts("ch",&dl_ch128[0]);
-        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
-        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
+	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
+	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
+
+        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
+        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
 
         if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
           dl_ch128+=2;
         }
         else {
-          avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15)));
+	  avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
+          //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15)));
           dl_ch128+=3;
         }
         /*
@@ -3447,7 +3486,7 @@ 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] +
-                            ((int32_t*)&avg128D)[3]);
+			      ((int32_t*)&avg128D)[3])/y;
                 //  printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
     }
 
@@ -5914,50 +5953,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&0x1][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][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&0x1][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][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&0x1][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+  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);
 
   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&0x1][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
+    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,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&0x1][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+    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);
   }
 
   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&0x1][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
+    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);
   }
 
   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&0x1][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+    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);
 
     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&0x1][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
+      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);
     }
   }
 
   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&0x1][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
+  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("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
@@ -5967,31 +6006,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&0x1][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+  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);
 
   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&0x1][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
+  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);
 
   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&0x1][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][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&0x1][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+    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);
   }
 
   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&0x1][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
+  write_output(fname,vname, ue->pdsch_vars[subframe%RX_NB_TH][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&0x1][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][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&0x1][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][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 9e102a1c65f4f45ec152650c6118bb1ba79479c2..da69dc6a0519150142d91a0847fe7aa3b8eefee9 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -701,9 +701,8 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                            uint8_t num_pdcch_symbols,
                            uint16_t nb_rb,
                            uint8_t subframe,
-                           uint32_t rb_alloc,
                            uint16_t mod_order_0,
-                           LTE_UE_DLSCH_t *dlsch0)
+                           uint32_t rb_alloc)
 {
 
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
@@ -734,7 +733,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
       amp_tmp=0x1fff;//1.5*dlsch0->sqrt_rho_a; already taken into account
 
     if (mod_order_0==6)
-      amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation to avoid overflow
+      amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation
 
 
     pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol);
@@ -941,10 +940,8 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
                           int32_t **dl_ch_mag,
                           uint16_t nb_rb,
                           uint8_t subframe,
-                          uint32_t rb_alloc,
                           uint16_t mod_order_0,
-                          LTE_UE_DLSCH_t *dlsch0
-                          )
+                          uint32_t rb_alloc)
 {
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
   int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
@@ -1221,10 +1218,8 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t **dl_ch_magb,
                          uint16_t nb_rb,
                          uint8_t subframe,
-                         uint32_t rb_alloc,
                          uint16_t mod_order_0,
-                         LTE_UE_DLSCH_t *dlsch0
-                         )
+                         uint32_t rb_alloc)
 {
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
   int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
diff --git a/openair1/PHY/LTE_TRANSPORT/extern.h b/openair1/PHY/LTE_TRANSPORT/extern.h
index 88c034e9db0efbb5b442d734e4f6023f52431ed0..af4dc20df611b1bff4d66b9e575ccb70411c6f93 100644
--- a/openair1/PHY/LTE_TRANSPORT/extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/extern.h
@@ -23,6 +23,8 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110],TBStable1C[32];
 extern unsigned short lte_cqi_eff1024[16];
 extern char lte_cqi_snr_dB[15];
 extern short conjugate[8],conjugate2[8];
+extern short minus_one[8];
+extern short minus_one[8];
 extern short *ul_ref_sigs[30][2][33];
 extern short *ul_ref_sigs_rx[30][2][33];
 extern unsigned short dftsizes[33];
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 7e5bf272dc1288964687574ce911b1bbc27afe26..19b01529464e58b775fda85f8fc4bcec2f782dbb 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -43,13 +43,13 @@ extern openair0_config_t openair0_cfg[];
 
 //#define DEBUG_INITIAL_SYNCH
 
-int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) 
+int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 {
 
   uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   char phich_resource[6];
-  
+
 #ifdef DEBUG_INITIAL_SYNCH
   LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
         ue->rx_offset);
@@ -63,7 +63,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 	     ue->rx_offset,
 	     0,
 	     1);
-  }  
+  }
   for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
 
     slot_fep(ue,
@@ -72,7 +72,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 	     ue->rx_offset,
 	     0,
 	     1);
-  }  
+  }
   slot_fep(ue,
 	   0,
 	   2,
@@ -83,9 +83,11 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
   lte_ue_measurements(ue,
 		      ue->rx_offset,
 		      0,
-		      0,0);
-  
-  
+                      0,
+		      0,
+                      0);
+
+
   if (ue->frame_parms.frame_type == TDD) {
     ue_rrc_measurements(ue,
 			2,
@@ -541,8 +543,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 	  ue->measurements.n0_power_tot_dBm,
 	  10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
 	  (10*log10(ue->measurements.rsrq[0])));
-    
-    
+
     LOG_I(PHY, "[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
 	  ue->Mod_id,
 	  ue->proc.proc_rxtx[0].frame_rx,
@@ -599,7 +600,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
       rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
 				frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
-    
+
     /*
     // do a measurement on the full frame
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
@@ -608,7 +609,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     */
 
     // we might add a low-pass filter here later
-    ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx; 
+    ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx;
 
     ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
 
@@ -617,7 +618,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 #endif
 
 #ifndef OAI_USRP
-#ifndef OAI_BLADERF 
+#ifndef OAI_BLADERF
 #ifndef OAI_LMSSDR
   phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0);
 #endif
@@ -628,7 +629,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
   else {
 
 #ifndef OAI_USRP
-#ifndef OAI_BLADERF 
+#ifndef OAI_BLADERF
 #ifndef OAI_LMSSDR
   phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0);
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index ab245f2f7ae5f73e855fd541071c659091056c9f..a11cf6022c8ef6f69083dd6a9f95a3140ec61108 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 & 0x1][eNB_id];
+  LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[subframe%RX_NB_TH][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 3bd327588316856414ef781e1bf5fc9ff5b48767..82cfe66e1c77204ddf15a139204dbd729c4933bc 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&0x1].dl_ch_estimates[eNB_id][0][0]),
+               &(ue->common_vars.common_vars_rx_data_per_thread[subframe%RX_NB_TH].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&0x1].rxdataF,
-                  common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+  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],
                   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 c4df9f79bebdc39672f01fa4f3c682fd8930029f..1af7415cbc6d7ab0f0f911f62ecacbd4bc5bdbe3 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -112,7 +112,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
     @returns status
 */
 int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
-		       uint8_t *a,
+                       uint8_t *a,
                        uint8_t num_pdcch_symbols,
                        LTE_eNB_DLSCH_t *dlsch,
                        int frame,
@@ -157,14 +157,14 @@ int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue,
     @returns status
 */
 int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
-				uint8_t *a,
-				uint8_t num_pdcch_symbols,
-				LTE_eNB_DLSCH_t *dlsch,
-				int frame,
-				uint8_t subframe,
-				time_stats_t *rm_stats,
-				time_stats_t *te_stats,
-				time_stats_t *i_stats);
+                                uint8_t *a,
+                                uint8_t num_pdcch_symbols,
+                                LTE_eNB_DLSCH_t *dlsch,
+                                int frame,
+                                uint8_t subframe,
+                                time_stats_t *rm_stats,
+                                time_stats_t *te_stats,
+                                time_stats_t *i_stats);
 
 void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
                          uint8_t *DLSCH_pdu,
@@ -263,11 +263,11 @@ int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
                            uint8_t skip_half,
-			   uint8_t lprime,
-			   uint8_t mprime,
-			   uint8_t Ns,
-			   int *P1_SHIFT,
-			   int *P2_SHIFT);
+                           uint8_t lprime,
+                           uint8_t mprime,
+                           uint8_t Ns,
+                           int *P1_SHIFT,
+                           int *P2_SHIFT);
 
 
 /** \fn int32_t dlsch_modulation(int32_t **txdataF,
@@ -387,7 +387,7 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB,
 
 int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
                              eNB_rxtx_proc_t *proc,
-			     int32_t **txdataF,
+                             int32_t **txdataF,
                              int16_t amp);
 
 void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
@@ -395,7 +395,7 @@ void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
                              int32_t **txdataF,
                              int16_t amp,
                              uint16_t Ntti,
-		             uint8_t beamforming_mode);
+                             uint8_t beamforming_mode);
 
 int32_t generate_pss(int32_t **txdataF,
                      int16_t amp,
@@ -842,16 +842,15 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 */
 
 int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
-                       int **rxdataF_comp,
-                                   int32_t **sic_buffer,
-                                   int **rho_i,
-                       short *dlsch_llr,
-                                   uint8_t num_pdcch_symbols,
-                       uint16_t nb_rb,
-                       uint8_t subframe,
-                                   uint32_t rb_alloc,
-                       uint16_t mod_order_0,
-                                   LTE_UE_DLSCH_t *dlsch0);
+                           int **rxdataF_comp,
+                           int32_t **sic_buffer,
+                           int **rho_i,
+                           short *dlsch_llr,
+                           uint8_t num_pdcch_symbols,
+                           uint16_t nb_rb,
+                           uint8_t subframe,
+                           uint16_t mod_order_0,
+                           uint32_t rb_alloc);
 
 void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      int32_t **rxdataF_comp,
@@ -878,30 +877,28 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 */
 void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
                           int32_t **rxdataF_comp,
-                                            int32_t **sic_buffer,  //Q15
-                                      int32_t **rho_i,
-                                            int16_t *dlsch_llr,
-                                            uint8_t num_pdcch_symbols,
-                                            int32_t **dl_ch_mag,
-                                            uint16_t nb_rb,
-                                            uint8_t subframe,
-                                            uint32_t rb_alloc,
+                          int32_t **sic_buffer,  //Q15
+                          int32_t **rho_i,
+                          int16_t *dlsch_llr,
+                          uint8_t num_pdcch_symbols,
+                          int32_t **dl_ch_mag,
+                          uint16_t nb_rb,
+                          uint8_t subframe,
                           uint16_t mod_order_0,
-                                            LTE_UE_DLSCH_t *dlsch0);
+                          uint32_t rb_alloc);
 
 void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t **rxdataF_comp,
-                                           int32_t **sic_buffer,  //Q15
-                                     int32_t **rho_i,
-                                           int16_t *dlsch_llr,
-                                           uint8_t num_pdcch_symbols,
-                                           int32_t **dl_ch_mag,
-                                           int32_t **dl_ch_magb,
-                                           uint16_t nb_rb,
-                                           uint8_t subframe,
-                                           uint32_t rb_alloc,
+                         int32_t **sic_buffer,  //Q15
+                         int32_t **rho_i,
+                         int16_t *dlsch_llr,
+                         uint8_t num_pdcch_symbols,
+                         int32_t **dl_ch_mag,
+                         int32_t **dl_ch_magb,
+                         uint16_t nb_rb,
+                         uint8_t subframe,
                          uint16_t mod_order_0,
-                                           LTE_UE_DLSCH_t *dlsch0);
+                         uint32_t rb_alloc);
 
 
 void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
@@ -1172,6 +1169,58 @@ void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
                                    int **dl_ch_rho_ext,
                                    unsigned char output_shift0,
                                    unsigned char output_shift1);
+//This function is used to compute multiplications in Hhermitian * H matrix
+void conjch0_mult_ch1(int *ch0,
+                      int *ch1,
+                      int32_t *ch0conj_ch1,
+                      unsigned short nb_rb,
+                      unsigned char output_shift0);
+
+void construct_HhH_elements(int *ch0conj_ch0,
+                         int *ch1conj_ch1,
+                         int *ch2conj_ch2,
+                         int *ch3conj_ch3,
+                         int *ch0conj_ch1,
+                         int *ch1conj_ch0,
+                         int *ch2conj_ch3,
+                         int *ch3conj_ch2,
+                         int32_t *after_mf_00,
+                         int32_t *after_mf_01,
+                         int32_t *after_mf_10,
+                         int32_t *after_mf_11,
+                         unsigned short nb_rb);
+
+void squared_matrix_element(int32_t *Hh_h_00,
+                            int32_t *Hh_h_00_sq,
+                            unsigned short nb_rb);
+
+void dlsch_channel_level_TM34_meas(int *ch00,
+                                   int *ch01,
+                                   int *ch10,
+                                   int *ch11,
+                                   int *avg_0,
+                                   int *avg_1,
+                                   unsigned short nb_rb);
+
+void det_HhH(int32_t *after_mf_00,
+             int32_t *after_mf_01,
+             int32_t *after_mf_10,
+             int32_t *after_mf_11,
+             int32_t *det_fin_128,
+             unsigned short nb_rb);
+
+void numer(int32_t *Hh_h_00_sq,
+           int32_t *Hh_h_01_sq,
+           int32_t *Hh_h_10_sq,
+           int32_t *Hh_h_11_sq,
+           int32_t *num_fin,
+           unsigned short nb_rb);
+
+uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
+                                int *dl_ch_estimates_01,
+                                int *dl_ch_estimates_10,
+                                int *dl_ch_estimates_11,
+                                unsigned short nb_rb);
 
 void dlsch_channel_compensation_TM56(int **rxdataF_ext,
                                      int **dl_ch_estimates_ext,
@@ -1328,7 +1377,7 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
 int pss_sss_extract(PHY_VARS_UE *phy_vars_ue,
                     int32_t pss_ext[4][72],
                     int32_t sss_ext[4][72],
-					uint8_t subframe);
+                                        uint8_t subframe);
 
 /*! \brief Extract only PSS resource elements
   @param phy_vars_ue Pointer to UE variables
@@ -1601,7 +1650,7 @@ int32_t generate_srs_tx(PHY_VARS_UE *phy_vars_ue,
 */
 
 int32_t generate_drs_pusch(PHY_VARS_UE *phy_vars_ue,
-			   UE_rxtx_proc_t *proc,
+                           UE_rxtx_proc_t *proc,
                            uint8_t eNB_id,
                            int16_t amp,
                            uint32_t subframe,
@@ -1686,7 +1735,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       DCI_format_t dci_format,
                                       PHY_VARS_UE *phy_vars_ue,
                                       UE_rxtx_proc_t *proc,
-				      uint16_t si_rnti,
+                                      uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
                                       uint16_t cba_rnti,
@@ -1694,21 +1743,21 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       uint8_t use_srs);
 
 int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_UE *phy_vars_ue,
-					  UE_rxtx_proc_t *proc,
-					  uint8_t eNB_id);
+                                          UE_rxtx_proc_t *proc,
+                                          uint8_t eNB_id);
 double sinr_eff_cqi_calc(PHY_VARS_UE *phy_vars_ue,
                          uint8_t eNB_id,
-						 uint8_t subframe);
+                                                 uint8_t subframe);
 
 uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
 
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
-				       eNB_rxtx_proc_t *proc,
-				       void *dci_pdu,
+                                       eNB_rxtx_proc_t *proc,
+                                       void *dci_pdu,
                                        rnti_t rnti,
-				       DCI_format_t dci_format,
+                                       DCI_format_t dci_format,
                                        uint8_t UE_id,
-				       uint16_t si_rnti,
+                                       uint16_t si_rnti,
                                        uint16_t ra_rnti,
                                        uint16_t p_rnti,
                                        uint16_t cba_rnti,
@@ -1764,13 +1813,13 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode);
 
 void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB,
               eNB_rxtx_proc_t *proc,
-	      uint8_t eNB_id,  // this is the effective sector id
+              uint8_t eNB_id,  // this is the effective sector id
               uint8_t UE_id,
               LTE_eNB_ULSCH_t **ulsch,
               uint8_t cooperation_flag);
 
 void rx_ulsch_emul(PHY_VARS_eNB *phy_vars_eNB,
-		   eNB_rxtx_proc_t *proc,
+                   eNB_rxtx_proc_t *proc,
                    uint8_t sect_id,
                    uint8_t UE_index);
 
@@ -1820,7 +1869,7 @@ int32_t ulsch_encoding_emul(uint8_t *ulsch_buffer,
   @returns 0 on success
 */
 unsigned int  ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
-			     eNB_rxtx_proc_t *proc,
+                             eNB_rxtx_proc_t *proc,
                              uint8_t UE_id,
                              uint8_t control_only_flag,
                              uint8_t Nbundled,
@@ -1835,9 +1884,9 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
   @returns 0 on success
 */
 int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
-				int UE_id,
-				int harq_pid,
-				int llr8_flag);
+                                int UE_id,
+                                int harq_pid,
+                                int llr8_flag);
 
 /*!
   \brief Decoding of ULSCH data component from 36-212. This one is single thread.
@@ -1848,17 +1897,17 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
   @returns 0 on success
 */
 int ulsch_decoding_data(PHY_VARS_eNB *eNB,
-			int UE_id,
-			int harq_pid,
-			int llr8_flag);
+                        int UE_id,
+                        int harq_pid,
+                        int llr8_flag);
 
 uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB,
                              eNB_rxtx_proc_t *proc,
-			     uint8_t UE_index,
+                             uint8_t UE_index,
                              uint16_t *crnti);
 
 void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
-			eNB_rxtx_proc_t *proc,
+                        eNB_rxtx_proc_t *proc,
                         int16_t amp,
                         uint8_t sect_id);
 
@@ -1870,7 +1919,7 @@ void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
 */
 
 void rx_phich(PHY_VARS_UE *phy_vars_ue,
-	      UE_rxtx_proc_t *proc,
+              UE_rxtx_proc_t *proc,
               uint8_t subframe,
               uint8_t eNB_id);
 
@@ -1982,28 +2031,28 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
 void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
 
 void generate_pucch1x(int32_t **txdataF,
-		      LTE_DL_FRAME_PARMS *frame_parms,
-		      uint8_t ncs_cell[20][7],
-		      PUCCH_FMT_t fmt,
-		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-		      uint16_t n1_pucch,
-		      uint8_t shortened_format,
-		      uint8_t *payload,
-		      int16_t amp,
-		      uint8_t subframe);
+                      LTE_DL_FRAME_PARMS *frame_parms,
+                      uint8_t ncs_cell[20][7],
+                      PUCCH_FMT_t fmt,
+                      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+                      uint16_t n1_pucch,
+                      uint8_t shortened_format,
+                      uint8_t *payload,
+                      int16_t amp,
+                      uint8_t subframe);
 
 void generate_pucch2x(int32_t **txdataF,
-		      LTE_DL_FRAME_PARMS *fp,
-		      uint8_t ncs_cell[20][7],
-		      PUCCH_FMT_t fmt,
-		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-		      uint16_t n2_pucch,
-		      uint8_t *payload,
-		      int A,
-		      int B2,
-		      int16_t amp,
-		      uint8_t subframe,
-		      uint16_t rnti);
+                      LTE_DL_FRAME_PARMS *fp,
+                      uint8_t ncs_cell[20][7],
+                      PUCCH_FMT_t fmt,
+                      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+                      uint16_t n2_pucch,
+                      uint8_t *payload,
+                      int A,
+                      int B2,
+                      int16_t amp,
+                      uint8_t subframe,
+                      uint16_t rnti);
 
 void generate_pucch3x(int32_t **txdataF,
                     LTE_DL_FRAME_PARMS *frame_parms,
@@ -2018,7 +2067,7 @@ void generate_pucch3x(int32_t **txdataF,
                     uint16_t rnti);
 
 void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue,
-			 UE_rxtx_proc_t *proc,
+                         UE_rxtx_proc_t *proc,
                          PUCCH_FMT_t format,
                          uint8_t ncs1,
                          uint8_t *pucch_ack_payload,
@@ -2038,11 +2087,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
                   uint8_t pucch1_thres);
 
 int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB,
-		      eNB_rxtx_proc_t *proc,
-		      uint8_t UE_index,
-		      PUCCH_FMT_t fmt,
-		      uint8_t n1_pucch_sel,
-		      uint8_t *payload);
+                      eNB_rxtx_proc_t *proc,
+                      uint8_t UE_index,
+                      PUCCH_FMT_t fmt,
+                      uint8_t n1_pucch_sel,
+                      uint8_t *payload);
 
 
 /*!
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 8adc693b31c7d668785ea011da34c21ed581ad5b..353e17fa0d802c4cd1e3104c0f5d3cca3c0f5670 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 & 0x1][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe%RX_NB_TH][0]->crnti)
       break;
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c
index 5eada8bc9c3eef2af838b2ae7901644d0a806d29..21b39cc5f6cd5bfc5b8b67c9c790452882bc6976 100644
--- a/openair1/PHY/LTE_TRANSPORT/sss.c
+++ b/openair1/PHY/LTE_TRANSPORT/sss.c
@@ -173,7 +173,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&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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 +183,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&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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)&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)%RX_NB_TH)].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&0x1)].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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)&0x1].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].rxdataF;
 		    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 	    }
 	    else
@@ -222,18 +222,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&0x1)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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)&0x1)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)%RX_NB_TH)].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&0x1)].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe%RX_NB_TH)].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)&0x1].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)%RX_NB_TH].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 9ae1dc6603e985dbb5e9480301ac1557ad3be61d..94023264203451f15644a08dd1994af7ba80dd22 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 & 0x1][eNB_id]->crnti;
+    rnti = ue->pdcch_vars[subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->crnti;
+  uint16_t rnti=ue->pdcch_vars[subframe_rx%RX_NB_TH][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 & 0x1][0]->crnti;
+  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].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 51a9d1e9469d8862088c2d17fb9fe32640d2e8a1..9aa6d69483ea3651ad1b8f196179b890ca91b0d8 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 & 0x1][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe%RX_NB_TH][0]->crnti)
       break;
 
   }
diff --git a/openair1/PHY/LTE_TRANSPORT/vars.h b/openair1/PHY/LTE_TRANSPORT/vars.h
index ba589398786fb528a7745dff4a399df127083d3a..4845ab6925aef5ca9de38339e4a4e7f263d1adeb 100644
--- a/openair1/PHY/LTE_TRANSPORT/vars.h
+++ b/openair1/PHY/LTE_TRANSPORT/vars.h
@@ -59,8 +59,8 @@ char lte_cqi_snr_dB[15] = { -2,
 
 unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1,1,1,0,0,0};
 
-short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ;
-short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 int qam64_table[8],qam16_table[4];
 
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 6a9bbb354a746fcf291bbcd45e50d3da1371d8cb..4d1955494388d1dbc24efb9774fec12b50bdd530 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)&0x1].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[(Ns>>1)%RX_NB_TH].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)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].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)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].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)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].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)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
 #if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
@@ -218,10 +218,12 @@ int slot_fep(PHY_VARS_UE *ue,
 #endif
 
       if (l==(4-frame_parms->Ncp)) {
+
 #if UE_TIMING_TRACE
           start_meas(&ue->dlsch_freq_offset_estimation_stats);
 #endif
-        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[0],
+
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)%RX_NB_TH].dl_ch_estimates[0],
                             frame_parms,
                             l,
                             &common_vars->freq_offset,
diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
index e20a984bd17b0708f3fe8873c52682fbcc050ee5..f2e459d2f250ada6902d0abe66a0b5102e605153 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&0x1].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[subframe%RX_NB_TH].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&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].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&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].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/defs.h b/openair1/PHY/TOOLS/defs.h
index 542b8edba5820b37c9e4d343fef07dfc6715414a..a90a8b718cfc36ec6ccbd3927eae8f70ae3abfea 100644
--- a/openair1/PHY/TOOLS/defs.h
+++ b/openair1/PHY/TOOLS/defs.h
@@ -338,6 +338,9 @@ uint8_t log2_approx64(unsigned long long int x);
 int16_t invSqrt(int16_t x);
 uint32_t angle(struct complex16 perrror);
 
+/// computes the number of factors 2 in x
+unsigned char factor2(unsigned int x);
+
 /*!\fn int32_t phy_phase_compensation_top (uint32_t pilot_type, uint32_t initial_pilot,
         uint32_t last_pilot, int32_t ignore_prefix);
 Compensate the phase rotation of the RF. WARNING: This function is currently unused. It has not been tested!
diff --git a/openair1/PHY/TOOLS/log2_approx.c b/openair1/PHY/TOOLS/log2_approx.c
index 0317a97d2f5d6fa1b3dd068dc97aee9d42612f0d..bd4d5d04ab87fec8fad51b0026163fa1a3bce3c2 100644
--- a/openair1/PHY/TOOLS/log2_approx.c
+++ b/openair1/PHY/TOOLS/log2_approx.c
@@ -37,6 +37,26 @@ unsigned char log2_approx(unsigned int x)
   return(l2);
 }
 
+unsigned char factor2(unsigned int x)
+{
+
+  int i;
+  unsigned char l2;
+
+  l2=0;
+
+  for (i=0; i<31; i++)
+    if ((x&(1<<i)) != 0)
+      break;
+
+  l2 = i;
+
+  //printf("factor2(%d) = %d\n",x,l2);
+  return(l2);
+}
+
+
+
 unsigned char log2_approx64(unsigned long long int x)
 {
 
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index cea702ef7804d69da774a5eca5e9027df3a05b8f..cb410cac893c219d58997765c39d5bbbb8392c5c 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&0x1][eNB_id][0]!=NULL) {
-    harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+  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 (harq_pid>=8)
       return;
 
-    mcs = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->mcs;
 
     // Button 0
-    if(!phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+    if(!phy_vars_ue->dlsch[subframe%RX_NB_TH][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&0x1][eNB_id]!=NULL) {
-    num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols;
+  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;
   }
 
   //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-  if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
+  if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
     coded_bits_per_codeword = get_G(frame_parms,
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                    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,
                                     get_Qm(mcs),
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                    phy_vars_ue->dlsch[subframe%RX_NB_TH][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&0x1].dl_ch_estimates_time[eNB_id];
-  chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id];
+  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];
   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&0x1][eNB_id]->llr;
-  pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0];
-  pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 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_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&0x1][eNB_id]->rxdataF_comp0[0];
-  pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[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];
 
   // 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 92a0d9f218e2ebedc09ecbdcf4eecccfa55ad022..2a7bf2c2a7c59d2a4f533ea42a7fb6a4d73ca8b9 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -24,6 +24,7 @@
 #include "lte_phy_scope.h"
 #define TPUT_WINDOW_LENGTH 100
 int otg_enabled;
+int use_sic_receiver=0;
 FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
 float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
 float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -54,6 +55,21 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
     fl_set_object_color(button, FL_RED, FL_RED);
   }
 }
+
+static void sic_receiver_on_off( FL_OBJECT *button, long arg)
+{
+
+  if (fl_get_button(button)) {
+    fl_set_object_label(button, "SIC Receiver ON");
+    use_sic_receiver = 1;
+    fl_set_object_color(button, FL_GREEN, FL_GREEN);
+  } else {
+    fl_set_object_label(button, "SIC Receiver OFF");
+    use_sic_receiver = 0;
+    fl_set_object_color(button, FL_RED, FL_RED);
+  }
+}
+
 FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
 {
   FL_OBJECT *obj;
@@ -398,16 +414,17 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
     fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
     fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
     fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
+    */
     // Generic UE Button
     fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
     fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
-    //openair_daq_vars.use_ia_receiver = 0;
+    //use_sic_receiver = 0;
     fl_set_button(fdui->button_0,0);
-    fl_set_object_label(fdui->button_0, "IA Receiver OFF");
+    fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
     fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
-    fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
+    fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
     fl_hide_object(fdui->button_0);
-    */
+
     fl_end_form( );
     fdui->lte_phy_scope_ue->fdui = fdui;
     return fdui;
@@ -448,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&0x1][eNB_id][0]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+    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 (harq_pid>=8)
     return;
-    mcs0 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs0 = phy_vars_ue->dlsch[subframe%RX_NB_TH][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) {
@@ -461,23 +478,24 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
         }
   */
     }
-       if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid;
+    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 (harq_pid>=8)
     return;
-    mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs;
+    mcs1 = phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->mcs;
     }
-    if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) {
-        num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols;
+    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;
     }
     //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-    if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
+    if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]!=NULL) {
       mod0 = get_Qm(mcs0);
       coded_bits_per_codeword0 = get_G(frame_parms,
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+              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,
               get_Qm(mcs0),
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
+              phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][0]->harq_processes[harq_pid]->Nl,
               num_pdcch_symbols,
               frame,
               subframe,
@@ -486,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&0x1][eNB_id][1]!=NULL) {
+    if (phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]!=NULL) {
       mod1 = get_Qm(mcs1);
       coded_bits_per_codeword1 = get_G(frame_parms,
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+               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,
                get_Qm(mcs1),
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl,
+               phy_vars_ue->dlsch[subframe%RX_NB_TH][eNB_id][1]->harq_processes[harq_pid]->Nl,
                num_pdcch_symbols,
                frame,
                subframe,
@@ -515,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&0x1].dl_ch_estimates_time[eNB_id];
-    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id];
+    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];
     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&0x1][eNB_id]->llr;
-    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0];
-    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0
-    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[1]; // stream 1
-    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0];
-    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0];
-    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[1];
-    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0])[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];
     //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&0x1][eNB_id]->dl_ch_mag0[0];
-    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[0][0])[0];
-    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb0[0];
-    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[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];
     fl_freeze_form(form->lte_phy_scope_ue);
     // Received signal in time domain of receive antenna 0
     if (rxsig_t != NULL) {
@@ -797,4 +815,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     for (arx=0;arx<nb_antennas_rx;arx++) {
         free(chest_t_abs[arx]);
     }
+
+    //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
+    /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
+      for (int i = 0; i<8; ++i)
+        for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
+          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
+
+      for (int m=0; m<coded_bits_per_codeword1; ++m)
+          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
+      }*/
   }
+
+
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 55a14923d3ddb9730a5b52f76dfd01d76b07e07b..df5fd25c231098f6be1cfccd4b22c6d51ac2b4ed 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -73,6 +73,9 @@
 #define openair_free(y,x) free((y))
 #define PAGE_SIZE 4096
 
+#define RX_NB_TH_MAX 2
+#define RX_NB_TH 2
+
 //#ifdef SHRLIBDEV
 //extern int rxrescale;
 //#define RX_IQRESCALELEN rxrescale
@@ -442,7 +445,7 @@ typedef struct {
   /// mutex for UE synch thread
   pthread_mutex_t mutex_synch;
   /// set of scheduling variables RXn-TXnp4 threads
-  UE_rxtx_proc_t proc_rxtx[2];
+  UE_rxtx_proc_t proc_rxtx[RX_NB_TH];
 } UE_proc_t;
 
 /// Top-level PHY Data Structure for eNB
@@ -725,16 +728,16 @@ typedef struct {
   LTE_DL_FRAME_PARMS  frame_parms_before_ho;
   LTE_UE_COMMON    common_vars;
 
-  LTE_UE_PDSCH     *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
+  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];
   LTE_UE_PDSCH     *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_PBCH      *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
-  LTE_UE_PDCCH     *pdcch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX];
+  LTE_UE_PDCCH     *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_PRACH     *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
-  LTE_UE_DLSCH_t   *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
+  LTE_UE_DLSCH_t   *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
   LTE_UE_ULSCH_t   *ulsch[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_DLSCH_t   *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_DLSCH_t   *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX];
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index f40e8ae3e4a6c4e2febb35297e0f212431aaadc1..b3e908916333291c9a1cfac532f8cb52dbfdd809 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -37,6 +37,9 @@
 #include "types.h"
 //#include "defs.h"
 
+#define RX_NB_TH_MAX 2
+#define RX_NB_TH 2
+
 #define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10
 #define LTE_SLOTS_PER_FRAME  20
 #define LTE_CE_FILTER_LENGTH 5
@@ -822,7 +825,7 @@ typedef struct {
   /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[
   int32_t **rxdata;
 
-  LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2];
+  LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX];
 
   /// holds output of the sync correlator
   int32_t *sync_corr;
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 73883ebc5e1d235285cf53a377ec120c45c74455..3bcdb1d4228c6ad21074ba1216eff289da7e1536 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -103,7 +103,7 @@ void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t
   @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
   @param *phy_vars_rn pointer to RN variables
 */
-void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+void phy_procedures_UE_lte(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);
 
 #if defined(Rel10) || defined(Rel14)
 /*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs.
@@ -139,7 +139,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t
   @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
   @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,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+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);
 
 #ifdef UE_SLOT_PARALLELISATION
 void *UE_thread_fep_slot1(void *arg);
@@ -168,7 +168,7 @@ void phy_procedures_UE_S_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abst
   @param phy_vars_rn pointer to the RN variables
   @param do_meas Do inline timing measurement
 */
-void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn,int do_meas);
+void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn,int do_meas, int do_pdcch_flag);
 
 /*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes.
   @param phy_vars_eNB Pointer to eNB variables on which to act
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index f8b9a9ae5965be7f4fd4fee20623e0a168ac7e4b..504167bb2a1679df86f03bd3bb7ee7622c0d45b3 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1147,7 +1147,8 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 			   eNB_rxtx_proc_t *proc,
                            relaying_type_t r_type,
 			   PHY_VARS_RN *rn,
-			   int do_meas)
+			   int do_meas,
+			   int do_pdcch_flag)
 {
   UNUSED(rn);
   int frame=proc->frame_tx;
@@ -1317,21 +1318,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   }
 
 
-  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);
-
-#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);
-    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);
-  }
-#endif
-
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->num_pdcch_symbols);
-
   // 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);
@@ -1390,23 +1376,28 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
     eNB->num_common_dci[(subframe)&1]=0;
   }
 
+
   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_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);
+      num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
+					   DCI_pdu->Num_common_dci,
+					   DCI_pdu->dci_alloc,
+					   0,
+					   AMP,
+					   fp,
+					   eNB->common_vars.txdataF[0],
+					   subframe);
+    }
+    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);
     }
-
-
-    num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
-                                         DCI_pdu->Num_common_dci,
-                                         DCI_pdu->dci_alloc,
-                                         0,
-                                         AMP,
-                                         fp,
-                                         eNB->common_vars.txdataF[0],
-                                         subframe);
-
   }
 
 #ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious
@@ -1417,8 +1408,19 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 #endif
 
+  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,DCI_pdu->num_pdcch_symbols);
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
 
+#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);
+    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);
+  }
+#endif
+
   // Check for SI activity
 
   if ((eNB->dlsch_SI) && (eNB->dlsch_SI->active == 1)) {
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index e998dd1754ee641eac4f8181d4f92c18853001e1..71f244a04f0cefcf5d802734f271ced690c895f3 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -73,7 +73,6 @@ fifo_dump_emos_UE emos_dump_UE;
 
 #define NS_PER_SLOT 500000
 
-
 extern int oai_exit;
 
 extern double cpuf;
@@ -92,29 +91,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&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  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->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]);
+          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&0x1].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
-  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[subframe&0x1][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&0x1][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
+  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("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&0x1][0]->rxdataF_comp0[0],300*12,1,1);
-  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[subframe&0x1][0]->llr[0],coded_bits_per_codeword,1,0);
+  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_mag1.m","dlschmag1",ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0,300*12,1,1);
-  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0,300*12,1,1);
+  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);
 }
 
 void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
@@ -127,23 +126,23 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
                                   2,
                                   1,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
-				  subframe,
-				  0);
+          subframe,
+          0);
   LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
-	ue->frame_parms.ofdm_symbol_size,
-	nsymb,
+  ue->frame_parms.ofdm_symbol_size,
+  nsymb,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
-        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
         coded_bits_per_codeword);
 
   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&0x1].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[subframe%RX_NB_TH].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);
   /*
@@ -232,19 +231,19 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
                                   2,
                                   1,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
-				  subframe,
-				  0);
+          subframe,
+          0);
   LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
-        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+        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&0x1].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[subframe%RX_NB_TH].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);
   /*
@@ -382,7 +381,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 & 0x1][eNB_id]->crnti,proc->frame_tx,subframe,
+        ue->Mod_id,ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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
@@ -465,9 +464,9 @@ void compute_cqi_ri_resources(PHY_VARS_UE *ue,
     }
 }
 
-void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) 
+void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS)
 {
-  
+
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int frame_tx    = proc->frame_tx;
   int subframe_tx = proc->subframe_tx;
@@ -481,7 +480,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
   pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
   pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS;
 
-  if (isSubframeSRS) {  
+  if (isSubframeSRS) {
     LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
       if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
       {
@@ -519,7 +518,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 & 0x1][eNB_id]->crnti,
+                              ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti,
                               subframe_tx); // subframe used for meas gap
 
                       if (SR_payload > 0)
@@ -529,7 +528,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&0x1][eNB_id][0]->harq_ack,
+                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
                       subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0)
               {
                   is_sr_an_subframe = 1;
@@ -588,19 +587,19 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
       cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
     }
     else if (cqi_PMI_ConfigIndex > 317) {
-      
+
       if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
-	cqirep->Npd = 32;
+  cqirep->Npd = 32;
       cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
       }
       else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
-	cqirep->Npd = 64;
-	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
+  cqirep->Npd = 64;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
       }
       else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
-	cqirep->Npd = 128;
-	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
-      }  
+  cqirep->Npd = 128;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
+      }
     }
   }
   else { // TDD
@@ -664,7 +663,7 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
           } else if (frame_type == TDD) {
               return pucch_format1b;
           } else {
-	      AssertFatal(1==0,"Unknown frame_type");
+              AssertFatal(1==0,"Unknown frame_type");
           }*/
       }
   }
@@ -698,7 +697,7 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
   return pucch_format1a;
 }
 uint16_t get_n1_pucch(PHY_VARS_UE *ue,
-		      UE_rxtx_proc_t *proc,
+          UE_rxtx_proc_t *proc,
                       harq_status_t *harq_ack,
                       uint8_t eNB_id,
                       uint8_t *b,
@@ -721,10 +720,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&0x1][eNB_id]->nCCE[sf]);
+    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]);
 
     if (SR == 0)
-      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[sf]);
+      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->nCCE[sf]);
     else
       return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
   } else {
@@ -787,7 +786,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           last_dl);
 
       // i=0
-      nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[last_dl];
+      nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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];
@@ -829,18 +828,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 & 0x1][eNB_id]->nCCE[5+last_dl];
+      nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[(6+last_dl)%10];
+      nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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&0x1][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&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
+      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[proc->subframe_rx&0x1][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&0x1][eNB_id][0]->harq_ack[5+last_dl].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;
 
       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,
@@ -915,30 +914,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 & 0x1][eNB_id]->nCCE[(8+subframe)%10];
+          //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];
           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 & 0x1][eNB_id]->nCCE[3+subframe];
+          nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[(2+subframe)%10];
+          nCCE2 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[(9+subframe)%10];
+          //nCCE3 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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&0x1][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&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
+          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[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-            harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].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[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(2+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-            harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(2+subframe)%10].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[proc->subframe_rx&0x1][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&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].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;
           //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,
@@ -947,30 +948,30 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           }else if (subframe == 3) {
           // i=0
 
-          nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[4+subframe];
+          nCCE0 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[5+subframe];
+          nCCE1 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[(6+subframe)];
+          nCCE2 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->nCCE[(3+subframe)];
+          nCCE3 = ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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&0x1][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&0x1][eNB_id][0]->harq_ack[4+subframe].ack;
+          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[proc->subframe_rx&0x1][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&0x1][eNB_id][0]->harq_ack[5+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[proc->subframe_rx&0x1][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&0x1][eNB_id][0]->harq_ack[(6+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[proc->subframe_rx&0x1][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&0x1][eNB_id][0]->harq_ack[(3+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;
           }
 
           //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",
@@ -1022,7 +1023,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
               return(n1_pucch_inter);
 
             } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
-                
+
              if (subframe == 3) {
                  LOG_I(PHY, "sbuframe=%d \n",subframe);
               if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
@@ -1251,7 +1252,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
   start_meas(&ue->ofdm_mod_stats);
 #endif
   nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
-  
+
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
   ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
          ue->hw_timing_advance-
@@ -1278,14 +1279,14 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
       for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
 
           if (overflow > 0)
-		 {
-			 memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
-			 memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
-		 }
-		 else
-		 {
-			 memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
-		 }
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
+       memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
+     }
+     else
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
+     }
       }
 /*#else
       overflow = ulsch_start - 9*frame_parms->samples_per_tti;
@@ -1307,37 +1308,37 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
 
   if ((frame_tx%100) == 0)
     LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
-	  ue->Mod_id,frame_tx,subframe_tx,
-	  ulsch_start,
-	  ue->rx_offset,
-	  ue->hw_timing_advance,
-	  ue->timing_advance,
-	  ue->N_TA_offset);
-  
-  
+    ue->Mod_id,frame_tx,subframe_tx,
+    ulsch_start,
+    ue->rx_offset,
+    ue->hw_timing_advance,
+    ue->timing_advance,
+    ue->N_TA_offset);
+
+
   for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
     if (frame_parms->Ncp == 1)
       PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-		   dummy_tx_buffer,
+       dummy_tx_buffer,
 #else
-		   &ue->common_vars.txdata[aa][ulsch_start],
+       &ue->common_vars.txdata[aa][ulsch_start],
 #endif
-		   frame_parms->ofdm_symbol_size,
-		   nsymb,
-		   frame_parms->nb_prefix_samples,
-		   CYCLIC_PREFIX);
+       frame_parms->ofdm_symbol_size,
+       nsymb,
+       frame_parms->nb_prefix_samples,
+       CYCLIC_PREFIX);
     else
       normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-			dummy_tx_buffer,
+      dummy_tx_buffer,
 #else
-			&ue->common_vars.txdata[aa][ulsch_start],
+      &ue->common_vars.txdata[aa][ulsch_start],
 #endif
-			nsymb,
-			&ue->frame_parms);
-    
-    
+      nsymb,
+      &ue->frame_parms);
+
+
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
     apply_7_5_kHz(ue,dummy_tx_buffer,0);
     apply_7_5_kHz(ue,dummy_tx_buffer,1);
@@ -1345,17 +1346,17 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
     apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
     apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
 #endif
-    
-    
+
+
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
     overflow = ulsch_start - 9*frame_parms->samples_per_tti;
-    
-    
+
+
     for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) {
       ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
       ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
     }
-    
+
     for (k=0; k<overflow; k++,l++) {
       ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
       ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
@@ -1364,11 +1365,11 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
     // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
     for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
       if (k<0)
-	ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+  ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
       else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
-	ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+  ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
       else
-	ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
+  ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
     }
 #endif
 #endif
@@ -1381,12 +1382,13 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
       write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
     }
     */
-    
+
   } //nb_antennas_tx
-  
+
 #if UE_TIMING_TRACE
       stop_meas(&ue->ofdm_mod_stats);
 #endif
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
 
 }
@@ -1413,17 +1415,17 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
       LOG_D(PHY,"Getting PRACH resources\n");
       ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,
-							   ue->CC_id,
-							   frame_tx,
-							   eNB_id,
-							   subframe_tx);
+                 ue->CC_id,
+                 frame_tx,
+                 eNB_id,
+                 subframe_tx);
       LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
       LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
     }
   }
-  
+
   if (ue->prach_resources[eNB_id]!=NULL) {
-    
+
     ue->generate_prach=1;
     ue->prach_cnt=0;
 #ifdef SMBV
@@ -1432,65 +1434,65 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #ifdef OAI_EMU
     ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
 #endif
-    
+
     if (abstraction_flag == 0) {
 
       LOG_I(PHY,"mode %d\n",mode);
-      
+
       if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
-	ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
+  ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
       }
       else {
-	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
-	ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
+  ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
+  ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
       }
-      
+
       LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
-	    ue->Mod_id,
-	    frame_tx,
-	    subframe_tx,
-	    ue->prach_resources[eNB_id]->ra_PreambleIndex,
-		get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-		ue->tx_power_dBm[subframe_tx],
-	    ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
-	    ue->prach_resources[eNB_id]->ra_TDD_map_index,
-	    ue->prach_resources[eNB_id]->ra_RNTI);
+      ue->Mod_id,
+      frame_tx,
+      subframe_tx,
+      ue->prach_resources[eNB_id]->ra_PreambleIndex,
+    get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+    ue->tx_power_dBm[subframe_tx],
+      ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+      ue->prach_resources[eNB_id]->ra_TDD_map_index,
+      ue->prach_resources[eNB_id]->ra_RNTI);
 
       ue->tx_total_RE[subframe_tx] = 96;
-      
+
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
       ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
-					       ue->tx_power_max_dBm,
-					       ue->frame_parms.N_RB_UL,
-					       6);
+                 ue->tx_power_max_dBm,
+                 ue->frame_parms.N_RB_UL,
+                 6);
 #else
       ue->prach_vars[eNB_id]->amp = AMP;
 #endif
       if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
-	LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",
-	      ue->Mod_id,
-	      proc->frame_rx,
-	      proc->subframe_tx,
-	      ue->tx_power_dBm[subframe_tx],
-	      ue->prach_vars[eNB_id]->amp);
-      
-      
+  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",
+        ue->Mod_id,
+        proc->frame_rx,
+        proc->subframe_tx,
+        ue->tx_power_dBm[subframe_tx],
+        ue->prach_vars[eNB_id]->amp);
+
+
       //      start_meas(&ue->tx_prach);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
       prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
       //      stop_meas(&ue->tx_prach);
       LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
-	    ue->Mod_id,
-	    get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-	    ue->tx_power_dBm[subframe_tx],
-	    dB_fixed(prach_power),
-	    ue->prach_vars[eNB_id]->amp);
+      ue->Mod_id,
+      get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+      ue->tx_power_dBm[subframe_tx],
+      dB_fixed(prach_power),
+      ue->prach_vars[eNB_id]->amp);
     } else {
       UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
       UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
     }
-    
+
     if (ue->mac_enabled==1){
       mac_xface->Msg1_transmitted(ue->Mod_id,
           ue->CC_id,
@@ -1499,23 +1501,23 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     }
 
     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",
-	  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),
-	  get_PL(ue->Mod_id,ue->CC_id,eNB_id));
-    
-  }	  
-  
+    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),
+    get_PL(ue->Mod_id,ue->CC_id,eNB_id));
+
+  }
+
 
   // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
   if (mode == calib_prach_tx)
     ue->prach_resources[eNB_id]=NULL;
-  
+
   LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",
-	ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
-  
+  ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
+
   ue->prach_cnt++;
-  
+
   if (ue->prach_cnt==3)
     ue->generate_prach=0;
 
@@ -1547,31 +1549,31 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 
   // get harq_pid from subframe relationship
   harq_pid = subframe2harq_pid(&ue->frame_parms,
-			       frame_tx,
-			       subframe_tx);
-  
-  
+             frame_tx,
+             subframe_tx);
+
+
   if (ue->mac_enabled == 1) {
     if ((ue->ulsch_Msg3_active[eNB_id] == 1) &&
-	(ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
-	(ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
-      
+  (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
+  (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
+
       ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
-      
+
       if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
-	generate_ue_ulsch_params_from_rar(ue,
-					  proc,
-					  eNB_id);
-      
+  generate_ue_ulsch_params_from_rar(ue,
+            proc,
+            eNB_id);
+
       ue->ulsch[eNB_id]->power_offset = 14;
       LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n",
-	    Mod_id,
-	    frame_tx,
-	    subframe_tx,
-	    harq_pid);
+      Mod_id,
+      frame_tx,
+      subframe_tx,
+      harq_pid);
       Msg3_flag = 1;
     } else {
-      
+
       if (harq_pid==255) {
 	LOG_E(PHY,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
 	      Mod_id,frame_tx, subframe_tx);
@@ -1582,11 +1584,11 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 #endif
 	return;
       }
-      
+
       Msg3_flag=0;
     }
   }
-  
+
   if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
 
     uint8_t isBad = 0;
@@ -1631,9 +1633,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     }
   }
   if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
-    
+
     ue->generate_ul_signal[eNB_id] = 1;
-    
+
     // deactivate service request
     // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
     LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit);
@@ -1643,40 +1645,39 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
     }
-    
+
     ack_status_cw0 = reset_ack(&ue->frame_parms,
-            ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+            ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][1]->harq_ack,
+            ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][1]->harq_ack,
             subframe_tx,
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &NbundledCw1,
             1);
 
-    //Nbundled = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack;
+    //Nbundled = ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack;
     //ue->ulsch[eNB_id]->bundling = Nbundled;
 
     first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
     nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
-    
-    
+
+
     // check Periodic CQI/RI reporting
     cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
         (is_cqi_TXOp(ue,proc,eNB_id)==1));
 
     ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
              (is_ri_TXOp(ue,proc,eNB_id)==1));
-    
+
     // compute CQI/RI resources
     compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status);
 
-
     if (ack_status_cw0 > 0) {
 
       // check if we received a PDSCH at subframe_tx - 4
@@ -1691,14 +1692,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&0x1][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx&0x1][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[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));
     }
     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&0x1][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx&0x1][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[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));
     }
 #endif
 #ifdef UE_DEBUG_TRACE
@@ -1715,30 +1716,30 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
         LOG_I(PHY,
               "[UE  %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, "
               "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n",
-	  Mod_id,harq_pid,frame_tx%1024,subframe_tx,
-	  first_rb,nb_rb,
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
-	  (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
-	   ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
-	   ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12,
-	  ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
-	  ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1],
-	  ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
-	  ack_status_cw0,
-	  ack_status_cw1,
-	  ue->ulsch[eNB_id]->bundling, Nbundled,
-	  cqi_status,
-	  ri_status);
-#endif
-    
-    
-    
-    
-    
+          Mod_id,harq_pid,frame_tx%1024,subframe_tx,
+          first_rb,nb_rb,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
+          (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
+           ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
+           ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12,
+          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
+          ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1],
+          ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+          ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK,
+          ack_status_cw0,
+          ack_status_cw1,
+          ue->ulsch[eNB_id]->bundling, Nbundled,
+          cqi_status,
+          ri_status);
+#endif
+
+
+
+
+
     if (Msg3_flag == 1) {
       LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
 	    subframe_tx,
@@ -1758,7 +1759,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 #if UE_TIMING_TRACE
       start_meas(&ue->ulsch_encoding_stats);
 #endif
-      
+
       if (abstraction_flag==0) {
 	if (ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
 			   ue,
@@ -1776,67 +1777,67 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 	  return;
 	}
       }
-      
+
 #ifdef PHY_ABSTRACTION
       else {
-	ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,proc->subframe_rx,harq_pid,0);
+        ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,proc->subframe_rx,harq_pid,0);
       }
-      
+
 #endif
-      
+
 #if UE_TIMING_TRACE
       stop_meas(&ue->ulsch_encoding_stats);
 #endif
       if (ue->mac_enabled == 1) {
-	// signal MAC that Msg3 was sent
-	mac_xface->Msg3_transmitted(Mod_id,
-				    CC_id,
-				    frame_tx,
-				    eNB_id);
+  // signal MAC that Msg3 was sent
+  mac_xface->Msg3_transmitted(Mod_id,
+            CC_id,
+            frame_tx,
+            eNB_id);
       }
     } // Msg3_flag==1
     else {
       input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
-      
+
       if (ue->mac_enabled==1) {
-	//  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
-	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
-	  //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
-	  access_mode=SCHEDULED_ACCESS;
-	  mac_xface->ue_get_sdu(Mod_id,
-				CC_id,
-				frame_tx,
-				subframe_tx,
-				eNB_id,
-				ulsch_input_buffer,
-				input_buffer_length,
-				&access_mode);
-	}
-	
+  //  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
+    //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
+    access_mode=SCHEDULED_ACCESS;
+    mac_xface->ue_get_sdu(Mod_id,
+        CC_id,
+        frame_tx,
+        subframe_tx,
+        eNB_id,
+        ulsch_input_buffer,
+        input_buffer_length,
+        &access_mode);
+  }
+
 #ifdef DEBUG_PHY_PROC
 #ifdef DEBUG_ULSCH
-	LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
-	
-	for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
-	  LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
-	
-	LOG_T(PHY,"\n");
+  LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
+
+  for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
+    LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
+
+  LOG_T(PHY,"\n");
 #endif
 #endif
       }
       else {
-	unsigned int taus(void);
-	
-	for (i=0; i<input_buffer_length; i++)
-	  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
-	
+  unsigned int taus(void);
+
+  for (i=0; i<input_buffer_length; i++)
+    ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
+
       }
-      
+
 #if UE_TIMING_TRACE
       start_meas(&ue->ulsch_encoding_stats);
 #endif
       if (abstraction_flag==0) {
-	
+
 	if (ulsch_encoding(ulsch_input_buffer,
 			   ue,
 			   harq_pid,
@@ -1852,33 +1853,33 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 	  return;
 	}
       }
-      
+
 #ifdef PHY_ABSTRACTION
       else {
-	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
+        ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
       }
-      
+
 #endif
 #if UE_TIMING_TRACE
       stop_meas(&ue->ulsch_encoding_stats);
 #endif
     }
-    
+
     if (abstraction_flag == 0) {
       if (ue->mac_enabled==1) {
-	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
-	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
+  pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
+  ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
       }
       else {
-	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
+  ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
       }
       ue->tx_total_RE[subframe_tx] = nb_rb*12;
-      
+
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
       tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
-			  ue->tx_power_max_dBm,
-			  ue->frame_parms.N_RB_UL,
-			  nb_rb);
+        ue->tx_power_max_dBm,
+        ue->frame_parms.N_RB_UL,
+        nb_rb);
 #else
       tx_amp = AMP;
 #endif
@@ -1886,19 +1887,21 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
       T(T_UE_PHY_PUSCH_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->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb));
 #endif
+
 #ifdef UE_DEBUG_TRACE
       LOG_I(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
 	    Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
 #endif
 #if UE_TIMING_TRACE
+
       start_meas(&ue->ulsch_modulation_stats);
 #endif
       ulsch_modulation(ue->common_vars.txdataF,
-		       tx_amp,
-		       frame_tx,
-		       subframe_tx,
-		       &ue->frame_parms,
-		       ue->ulsch[eNB_id]);
+           tx_amp,
+           frame_tx,
+           subframe_tx,
+           &ue->frame_parms,
+           ue->ulsch[eNB_id]);
       for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
 	generate_drs_pusch(ue,
 			   proc,
@@ -1912,7 +1915,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
       stop_meas(&ue->ulsch_modulation_stats);
 #endif
     }
-    
+
     if (abstraction_flag==1) {
       // clear SR
       ue->sr[subframe_tx]=0;
@@ -1972,11 +1975,11 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8
 
     uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
     uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1));
-    generate_srs(&ue->frame_parms, 
-		 &ue->soundingrs_ul_config_dedicated[eNB_id], 
-		 &ue->common_vars.txdataF[eNB_id][symbol_offset], 
-		 tx_amp, 
-		 subframe_tx);
+    generate_srs(&ue->frame_parms,
+     &ue->soundingrs_ul_config_dedicated[eNB_id],
+     &ue->common_vars.txdataF[eNB_id][symbol_offset],
+     tx_amp,
+     subframe_tx);
   }
 }
 
@@ -1985,16 +1988,16 @@ int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) {
   if ((ue->transmission_mode[eNB_id]<4)||
       (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback
     // 4-bit CQI message
-	  /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
-			  ue->measurements.wideband_cqi_avg[eNB_id],
-			  sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
-			            ue->transmission_mode[eNB_id]));*/
+          /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
+                          ue->measurements.wideband_cqi_avg[eNB_id],
+                          sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
+                                    ue->transmission_mode[eNB_id]));*/
     *len=4;
     return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
-		    ue->transmission_mode[eNB_id]));
+        ue->transmission_mode[eNB_id]));
   }
   else { // Mode 1-1 feedback, later
-	  //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
+          //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
     *len=0;
     // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)
 
@@ -2036,7 +2039,7 @@ void get_pucch_param(PHY_VARS_UE    *ue,
     {
         pucch_resource[0] = get_n1_pucch(ue,
                                          proc,
-                                         ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+                                         ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack,
                                          eNB_id,
                                          ack_payload,
                                          SR);
@@ -2098,7 +2101,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   uint8_t ri_status=0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
-  
+
   SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
 
   // 36.213 8.2
@@ -2121,7 +2124,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
 
   bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
-  
+
   if ((frame_parms->frame_type==FDD) ||
       (bundling_flag==bundling)    ||
       ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) {
@@ -2131,7 +2134,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     format = pucch_format1b;
     LOG_D(PHY,"[UE] PUCCH 1b\n");
   }
-  
+
   // Part - I
   // Collect feedback that should be transmitted at this subframe
   // - SR
@@ -2147,7 +2150,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 & 0x1][eNB_id]->crnti,
+                  ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][eNB_id]->crnti,
                   subframe_tx); // subframe used for meas gap
       }
       else {
@@ -2156,14 +2159,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&0x1][eNB_id][0]->harq_ack,
+                       ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][1]->harq_ack,
+                       ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][1]->harq_ack,
                        subframe_tx,
                        proc->subframe_rx,
                        pucch_ack_payload,
@@ -2207,9 +2210,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                   (uint8_t *)&pucch_payload,
                   &len);
 
-  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
-          frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
 
+  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
+	frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
 
   // Part - IV
   // Generate PUCCH signal
@@ -2239,7 +2242,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&0x1][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[proc->subframe_rx%RX_NB_TH][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
 #endif
 
 #ifdef UE_DEBUG_TRACE
@@ -2247,7 +2250,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&0x1][eNB_id][0]->rnti,
+                  ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
                   frame_tx%1024, subframe_tx,
                   frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                   isShortenPucch,
@@ -2259,7 +2262,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&0x1][eNB_id][0]->rnti,
+                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
                       frame_tx % 1024, subframe_tx,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2272,7 +2275,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&0x1][eNB_id][0]->rnti,
+                      ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
                       frame_tx%1024, subframe_tx,ue->rx_offset_diff,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2288,13 +2291,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&0x1][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx&0x1][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[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));
       }
       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&0x1][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx&0x1][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[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));
       }
 #endif
 
@@ -2347,12 +2350,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&0x1][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[proc->subframe_rx%RX_NB_TH][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",
               Mod_id,
-              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+              ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx,
               Po_PUCCH,
               isShortenPucch,
@@ -2369,20 +2372,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 & 0x1][eNB_id]->crnti);
+              ue->pdcch_vars[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->rnti,
+              ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->rnti,
+              ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx);
       break;
   default:
@@ -2394,7 +2397,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 }
 
 void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) {
-  
+
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   //int32_t ulsch_start=0;
@@ -2403,8 +2406,10 @@ 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;
 
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
 
+  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
 #if T_TRACER
   T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
 #endif
@@ -2419,15 +2424,15 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
 #endif
 
   ue->tx_power_dBm[subframe_tx]=-127;
-      
+
   if (abstraction_flag==0) {
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
       memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
-	     0,
-	     frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
+       0,
+       frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
     }
   }
-      
+
   if (ue->UE_mode[eNB_id] != PRACH) {
     // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding
     isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx);
@@ -2437,17 +2442,17 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
     ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
 
   }
-  	  
+
   if (ue->UE_mode[eNB_id] == PUSCH) {
       // check if we need to use PUCCH 1a/1b
       ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
       // check if we need to use SRS
       ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
   } // UE_mode==PUSCH
-	
-  	
+
+
 #ifdef CBA
-	
+
   if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
       (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
     ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
@@ -2457,62 +2462,62 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
     //cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
     input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
     access_mode=CBA_ACCESS;
-	  
+
     LOG_D(PHY,"[UE %d] Frame %d, subframe %d: CBA num dci %d\n",
-	  Mod_id,frame_tx,subframe_tx,
-	  ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]);
-	  
+    Mod_id,frame_tx,subframe_tx,
+    ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]);
+
     mac_xface->ue_get_sdu(Mod_id,
-			  CC_id,
-			  frame_tx,
-			  subframe_tx,
-			  eNB_id,
-			  ulsch_input_buffer,
-			  input_buffer_length,
-			  &access_mode);
-	  
+        CC_id,
+        frame_tx,
+        subframe_tx,
+        eNB_id,
+        ulsch_input_buffer,
+        input_buffer_length,
+        &access_mode);
+
     ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]=0;
-	  
+
     if (access_mode > UNKNOWN_ACCESS) {
-	    
+
       if (abstraction_flag==0) {
-	if (ulsch_encoding(ulsch_input_buffer,
-			   ue,
-			   harq_pid,
-			   eNB_id,
-			   proc->subframe_rx,
-			   ue->transmission_mode[eNB_id],0,
-			   0)!=0) {  //  Nbundled, to be updated!!!!
-	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
-	  return;
-	}
+        if (ulsch_encoding(ulsch_input_buffer,
+                           ue,
+                           harq_pid,
+                           eNB_id,
+                           proc->subframe_rx,
+                           ue->transmission_mode[eNB_id],0,
+                           0)!=0) {  //  Nbundled, to be updated!!!!
+          LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+          return;
+        }
       }
-	    
+
 #ifdef PHY_ABSTRACTION
       else {
-	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
+        ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0);
       }
-	    
+
 #endif
     } else {
       ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
       //reset_cba_uci(ue->ulsch[eNB_id]->o);
       LOG_N(PHY,"[UE %d] Frame %d, subframe %d: CBA transmission cancelled or postponed\n",
-	    Mod_id, frame_tx,subframe_tx);
+      Mod_id, frame_tx,subframe_tx);
     }
   }
-	
+
 #endif // end CBA
 
-  	
+
   if (abstraction_flag == 0) {
     ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
   } // mode != PRACH
-    
-      
-  if ((ue->UE_mode[eNB_id] == PRACH) && 
+
+
+  if ((ue->UE_mode[eNB_id] == PRACH) &&
       (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
-	
+
     // check if we have PRACH opportunity
 
     if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
@@ -2523,20 +2528,27 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
   else {
     ue->generate_prach=0;
   }
-    
+
   // reset DL ACK/NACK status
   uint8_t N_bundled = 0;
-  if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL)
+  if (ue->dlsch[proc->subframe_rx%RX_NB_TH][eNB_id][0] != NULL)
   {
     reset_ack(&ue->frame_parms,
-               ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+               ue->dlsch[proc->subframe_rx%RX_NB_TH][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)&0x1][eNB_id][0]->harq_ack,
+               ue->dlsch[(proc->subframe_rx+1)%RX_NB_TH][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,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
@@ -2553,7 +2565,9 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
              &N_bundled,
              0);
 
-      
+
+  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
 #if UE_TIMING_TRACE
   stop_meas(&ue->phy_proc_tx);
@@ -2564,21 +2578,21 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_f
 {
   int aa;//i,aa;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  
+
   if (abstraction_flag==0) {
-    
+
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
 #if defined(EXMIMO) //this is the EXPRESS MIMO case
       int i;
       // set the whole tx buffer to RX
       for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
-	ue->common_vars.txdata[aa][i] = 0x00010001;
-      
+  ue->common_vars.txdata[aa][i] = 0x00010001;
+
 #else //this is the normal case
       memset(&ue->common_vars.txdata[aa][0],0,
-	     (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
+       (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
 #endif //else EXMIMO
-      
+
     }
   }
 }
@@ -2586,12 +2600,12 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_f
 void ue_measurement_procedures(
     uint16_t l,    // symbol index of each slot [0..6]
     PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,
-    uint16_t slot, // slot index of each radio frame [0..19]    
+    uint16_t slot, // slot index of each radio frame [0..19]
     uint8_t abstraction_flag,runmode_t mode)
 {
+
   //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp);
 
-  
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
 
   int subframe_rx = proc->subframe_rx;
@@ -2604,14 +2618,17 @@ void ue_measurement_procedures(
       LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
 
       lte_ue_measurements(ue,
-			  (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
-			  (subframe_rx == 1) ? 1 : 0,
-			  0,subframe_rx);
+        (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
+        (subframe_rx == 1) ? 1 : 0,
+        0,
+        0,
+        subframe_rx);
     } else {
       lte_ue_measurements(ue,
-			  0,
-			  0,
-			  1,
+        0,
+        0,
+        1,
+        0,
       subframe_rx);
     }
 #if T_TRACER
@@ -2628,14 +2645,14 @@ void ue_measurement_procedures(
   }
 
   if (l==(6-ue->frame_parms.Ncp)) {
-	
+
     // make sure we have signal from PSS/SSS for N0 measurement
-	 // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
+         // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
     ue_rrc_measurements(ue,
-			slot,
-			abstraction_flag);
+      slot,
+      abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
 
     if (abstraction_flag==1)
@@ -2660,16 +2677,16 @@ void ue_measurement_procedures(
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
 
     eNB_id = 0;
-    
+
     if (abstraction_flag == 0) {
       if (ue->no_timing_correction==0)
-	lte_adjust_synch(&ue->frame_parms,
-			 ue,
-			 eNB_id,
-			 subframe_rx,
-			 0,
-			 16384);
-    }      
+  lte_adjust_synch(&ue->frame_parms,
+       ue,
+       eNB_id,
+       subframe_rx,
+       0,
+       16384);
+    }
 
   }
 
@@ -2701,14 +2718,14 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
   if ((last_slot==10) || (last_slot==11)) {
     for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
       for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
-	// first OFDM symbol with pilots
-	memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
-	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
-	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
-	// second OFDM symbol with pilots
-	memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
-	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
-	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
+  // first OFDM symbol with pilots
+  memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
+         &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
+         ue->frame_parms.ofdm_symbol_size*sizeof(int));
+  // second OFDM symbol with pilots
+  memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
+         &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
+         ue->frame_parms.ofdm_symbol_size*sizeof(int));
       }
   }
 
@@ -2746,8 +2763,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&0x1][eNB_id][0]->pmi_alloc;
-    emos_dump_UE.mcs = ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mcs;
+    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.use_ia_receiver = openair_daq_vars.use_ia_receiver;
 
     bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE));
@@ -2756,7 +2773,7 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
       LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
     } else {
       if (proc->frame_rx%100==0) {
-	LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot, bytes);
+  LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot, bytes);
       }
     }
   }
@@ -2857,12 +2874,12 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
     //LOG_I(PHY,"[UE  %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
     if (abstraction_flag == 0) {
       pbch_tx_ant = rx_pbch(&ue->common_vars,
-			    ue->pbch_vars[eNB_id],
-			    &ue->frame_parms,
-			    eNB_id,
-			    ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
-			    ue->high_speed_flag,
-			    pbch_phase);
+          ue->pbch_vars[eNB_id],
+          &ue->frame_parms,
+          eNB_id,
+          ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
+          ue->high_speed_flag,
+          pbch_phase);
 
 
 
@@ -2871,8 +2888,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 #ifdef PHY_ABSTRACTION
     else {
       pbch_tx_ant = rx_pbch_emul(ue,
-				 eNB_id,
-				 pbch_phase);
+         eNB_id,
+         pbch_phase);
     }
 
 #endif
@@ -2916,9 +2933,9 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
     if (ue->mac_enabled==1) {
       mac_xface->dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id,
-				     ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0);
+             ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0);
     }
-    
+
 #ifdef EMOS
     //emos_dump_UE.frame_tx = frame_tx;
     //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
@@ -2929,9 +2946,12 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
       proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
       proc->frame_tx = proc->frame_rx;
-      ue->proc.proc_rxtx[1].frame_rx = proc->frame_rx;
-      ue->proc.proc_rxtx[1].frame_tx = proc->frame_tx;
-      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",
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
+      }
+       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,
@@ -2940,44 +2960,49 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 	    pbch_phase,
 	    ue->rx_offset,
 	    proc->frame_rx);
+
       frame_rx = proc->frame_rx;
-      
+
     } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
       //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
       LOG_D(PHY,"[UE %d] frame %d, subframe %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%%1024=%d, phase %d).\n",
-	    ue->Mod_id,
-	    proc->frame_rx,
-	    subframe_rx,
-	    pbch_tx_ant,
-	    frame_tx,
-	    frame_rx & 0x03FF,
-	    pbch_phase);
+      ue->Mod_id,
+      proc->frame_rx,
+      subframe_rx,
+      pbch_tx_ant,
+      frame_tx,
+      frame_rx & 0x03FF,
+      pbch_phase);
 
       proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
-      ue->proc.proc_rxtx[1].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
       proc->frame_tx = proc->frame_rx;
-      ue->proc.proc_rxtx[1].frame_tx = proc->frame_rx;
       frame_rx = proc->frame_rx;
+      
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx;
+      }
 
     }
 
 #ifdef DEBUG_PHY_PROC
     LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): mode1_flag %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
-	  ue->Mod_id,
-	  frame_rx,
-	  subframe_rx,
-	  ue->frame_parms.mode1_flag,
-	  pbch_tx_ant,
-	  frame_tx,
-	  ue->frame_parms.N_RB_DL,
-	  ue->frame_parms.phich_config_common.phich_duration,
-	  ue->frame_parms.phich_config_common.phich_resource);
-#endif
-
-  } else { 
+    ue->Mod_id,
+    frame_rx,
+    subframe_rx,
+    ue->frame_parms.mode1_flag,
+    pbch_tx_ant,
+    frame_tx,
+    ue->frame_parms.N_RB_DL,
+    ue->frame_parms.phich_config_common.phich_duration,
+    ue->frame_parms.phich_config_common.phich_resource);
+#endif
+
+  } else {
     /*
     LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
-	  ue->Mod_id,frame_rx, subframe_rx);
+    ue->Mod_id,frame_rx, subframe_rx);
 
     LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);
 
@@ -3001,8 +3026,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
     }
     else{
       if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
-	LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
-	mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
+  LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
+  mac_xface->macphy_exit("More that 100 consecutive PBCH errors!");
       }
     }
   }
@@ -3014,9 +3039,9 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
 #ifdef DEBUG_PHY_PROC
   LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
-	ue->Mod_id,frame_rx, subframe_rx,
-	ue->pbch_vars[eNB_id]->pdu_errors,
-	ue->pbch_vars[eNB_id]->pdu_errors_conseq);
+  ue->Mod_id,frame_rx, subframe_rx,
+  ue->pbch_vars[eNB_id]->pdu_errors,
+  ue->pbch_vars[eNB_id]->pdu_errors_conseq);
 #endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
 }
@@ -3048,28 +3073,28 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
     rx_pdcch(ue,
-	     proc->frame_rx,
-	     subframe_rx,
-	     eNB_id,
-	     (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
-	     ue->high_speed_flag,
-	     ue->is_secondary_ue);
+             proc->frame_rx,
+             subframe_rx,
+             eNB_id,
+             (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+             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);
+             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);
     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);
 
     if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
       rx_phich(ue,proc,
-	       subframe_rx,eNB_id);
+         subframe_rx,eNB_id);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
     }
   }
@@ -3078,11 +3103,11 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
   else {
     for (i=0; i<NB_eNB_INST; i++) {
       for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
-	if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
-	  break;
+  if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
+    break;
 
       if (CC_id < MAX_NUM_CCs)
-	break;
+  break;
     }
 
     if (i==NB_eNB_INST) {
@@ -3094,46 +3119,48 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
     LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
     dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars[subframe_rx&1],
-					  PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1],
-					  PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1],
-					  PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1],
-					  dci_alloc_rx,
-					  eNB_id);
+                                          PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1],
+                                          PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1],
+                                          PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1],
+                                          dci_alloc_rx,
+                                          eNB_id);
     //    printf("DCI: dci_cnt %d\n",dci_cnt);
     UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
 
     if (UE_id>=0) {
       //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
       if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
-	harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,subframe_rx);
+  harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,subframe_rx);
 
-	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
-	  // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
-	  ue->ulsch_Msg3_active[eNB_id] = 0;
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
-	  LOG_D(PHY,"Msg3 inactive\n");
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
+    // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
+    ue->ulsch_Msg3_active[eNB_id] = 0;
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+    LOG_D(PHY,"Msg3 inactive\n");
 
-	} // harq_pid is ACTIVE
+  } // harq_pid is ACTIVE
       } // This is a PHICH subframe
     } // UE_id exists
   }
 
 #endif
 
-  uint8_t *nCCE_current = &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->nCCE[subframe_rx];
-  uint8_t *nCCE_dest = &ue->pdcch_vars[(subframe_rx+1) & 0x1][eNB_id]->nCCE[subframe_rx];
+  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];
   memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
+  memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
 
   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 & 0x1][eNB_id]->crnti,
+       ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
        dci_alloc_rx[0].format );
 
-  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->dci_received += dci_cnt;
+  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->dci_received += dci_cnt;
 
 #ifdef EMOS
   //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
@@ -3144,39 +3171,35 @@ 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 & 0x1][eNB_id]->crnti) &&
+	(dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx%RX_NB_TH][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 & 0x1][eNB_id]->num_pdcch_symbols,
-	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->nCCE[subframe_rx],
+	    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],
 	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
 
-
-
-
-      
       //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
       if ((ue->UE_mode[eNB_id] > PRACH) &&
 	  (generate_ue_dlsch_params_from_dci(frame_rx,
 					     subframe_rx,
 					     (void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+					     ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
 					     dci_alloc_rx[i].format,
-					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
-					     ue->pdsch_vars[subframe_rx & 0x1][eNB_id],
-					     ue->dlsch[subframe_rx&0x1][eNB_id],
+					     ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id],
+					     ue->pdsch_vars[subframe_rx%RX_NB_TH][eNB_id],
+					     ue->dlsch[subframe_rx%RX_NB_TH][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&0x1][eNB_id]->crnti_is_temporary? ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti: 0)==0)) {
+					     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)) {
 
           // update TPC for PUCCH
           if((dci_alloc_rx[i].format == format1)   ||
@@ -3186,34 +3209,45 @@ 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&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            //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;
+            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,
+                    delta_pucch,
+                    ue->dlsch[0][eNB_id][0]->g_pucch,
+                    ue->dlsch[1][eNB_id][0]->g_pucch
+                    //ue->dlsch[2][eNB_id][0]->g_pucch
+                    );
           }
 
-	ue->dlsch_received[eNB_id]++;
-	
+  ue->dlsch_received[eNB_id]++;
+
 #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&0x1][eNB_id][0]->active);
+	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);
 #endif
-	
-	// we received a CRNTI, so we're in PUSCH
-	if (ue->UE_mode[eNB_id] != PUSCH) {
+
+  // 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_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);
 #endif
-	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-	  ue->UE_mode[eNB_id] = PUSCH;
-	  //mac_xface->macphy_exit("Connected. Exiting\n");
-	}
+    //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+    ue->UE_mode[eNB_id] = PUSCH;
+    //mac_xface->macphy_exit("Connected. Exiting\n");
+  }
       } else {
-	LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
-	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+  LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
+  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       }
     }
 
     else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
-	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+       ((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);
@@ -3221,32 +3255,32 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
-					    subframe_rx,
-					    (void *)&dci_alloc_rx[i].dci_pdu,
-					    SI_RNTI,
-					    dci_alloc_rx[i].format,
-					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+              subframe_rx,
+              (void *)&dci_alloc_rx[i].dci_pdu,
+              SI_RNTI,
+              dci_alloc_rx[i].format,
+					    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id],
 					    ue->pdsch_vars_SI[eNB_id],
-					    &ue->dlsch_SI[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->dlsch_SI[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],
               0)==0) {
 
-	ue->dlsch_SI_received[eNB_id]++;
- 
+  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");
-	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+
+  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");
+  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 
       }
     }
 
     else if ((dci_alloc_rx[i].rnti == P_RNTI) &&
-	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+       ((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);
@@ -3254,33 +3288,31 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
-					    subframe_rx,
-					    (void *)&dci_alloc_rx[i].dci_pdu,
-						P_RNTI,
-					    dci_alloc_rx[i].format,
-					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+              subframe_rx,
+              (void *)&dci_alloc_rx[i].dci_pdu,
+            P_RNTI,
+              dci_alloc_rx[i].format,
+					    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id],
 					    ue->pdsch_vars_p[eNB_id],
-					    &ue->dlsch_SI[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->dlsch_SI[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],
                                             0)==0) {
 
-	ue->dlsch_p_received[eNB_id]++;
- 
-
-	LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH P_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]);
+  ue->dlsch_p_received[eNB_id]++;
+  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH P_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]);
 
       }
     }
 
     else if ((ue->prach_resources[eNB_id]) &&
-	     (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
-	     (dci_alloc_rx[i].format == format1A)) {
+       (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
+       (dci_alloc_rx[i].format == format1A)) {
 
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i);
@@ -3292,33 +3324,34 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
-					    subframe_rx,
-					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
-					    ue->prach_resources[eNB_id]->ra_RNTI,
-					    format1A,
-					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+              subframe_rx,
+              (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
+              ue->prach_resources[eNB_id]->ra_RNTI,
+              format1A,
+					    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id],
 					    ue->pdsch_vars_ra[eNB_id],
-					    &ue->dlsch_ra[eNB_id],
-					    &ue->frame_parms,
-					    ue->pdsch_config_dedicated,
-					    SI_RNTI,
-					    ue->prach_resources[eNB_id]->ra_RNTI,
-					    P_RNTI,
-					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+              &ue->dlsch_ra[eNB_id],
+              &ue->frame_parms,
+              ue->pdsch_config_dedicated,
+              SI_RNTI,
+              ue->prach_resources[eNB_id]->ra_RNTI,
+              P_RNTI,
+              ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                             0)==0) {
 
-	ue->dlsch_ra_received[eNB_id]++;
+  ue->dlsch_ra_received[eNB_id]++;
 
 #ifdef DEBUG_PHY_PROC
-	LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
-	      ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
+  LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
+        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 & 0x1][eNB_id]->crnti) &&
+    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti) &&
 	       (dci_alloc_rx[i].format == format0)) {
+
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
-	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
+      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
 #endif
 
       ue->ulsch_no_allocation_counter[eNB_id] = 0;
@@ -3326,7 +3359,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 & 0x1][eNB_id]->crnti,
+					     ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
 					     subframe_rx,
 					     format0,
 					     ue,
@@ -3337,7 +3370,6 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					     CBA_RNTI,
 					     eNB_id,
 					     0)==0)) {
-
 #if T_TRACER
     LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
     uint8_t harq_pid = subframe2harq_pid(frame_parms,
@@ -3353,20 +3385,20 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
       T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
 #endif
 #ifdef DEBUG_PHY_PROC
-	LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
+  LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
 #endif
 
       }
     } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
-	       (dci_alloc_rx[i].format == format0)) {
+         (dci_alloc_rx[i].format == format0)) {
       // UE could belong to more than one CBA group
       // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
-	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
+      ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
       /*
-	if (((frame_rx%100) == 0) || (frame_rx < 20))
-	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+  if (((frame_rx%100) == 0) || (frame_rx < 20))
+  dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       */
 #endif
 
@@ -3374,32 +3406,33 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
       //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
 
       if ((ue->UE_mode[eNB_id] > PRACH) &&
-	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->ulsch[eNB_id]->cba_rnti[0],
-					     subframe_rx,
-					     format0,
-					     ue,
-					     proc,
-					     SI_RNTI,
-					     0,
-					     P_RNTI,
-					     CBA_RNTI,
-					     eNB_id,
-					     0)==0)) {
+    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+               ue->ulsch[eNB_id]->cba_rnti[0],
+               subframe_rx,
+               format0,
+               ue,
+               proc,
+               SI_RNTI,
+               0,
+               P_RNTI,
+               CBA_RNTI,
+               eNB_id,
+               0)==0)) {
 
 #ifdef DEBUG_PHY_PROC
-	LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
+  LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
 #endif
-	ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
+  ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
       }
     }
 
     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 & 0x1][eNB_id]->crnti,
+	    ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
 	    ue->ulsch[eNB_id]->cba_rnti[0],
 	    dci_alloc_rx[i].format);
+
       //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 #endif
     }
@@ -3428,129 +3461,129 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 
   if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
     LOG_D(PHY,"ue calling pmch subframe ..\n ");
-    
+
     LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
-	  ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
+    ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
 #if defined(Rel10) || defined(Rel14)
     pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id,
-				       CC_id,
-				       frame_rx,
-				       subframe_rx,
-				       eNB_id,
-				       &sync_area,
-				       &mcch_active);
-    
+               CC_id,
+               frame_rx,
+               subframe_rx,
+               eNB_id,
+               &sync_area,
+               &mcch_active);
+
 #else
     pmch_mcs=-1;
 #endif
-    
+
     if (pmch_mcs>=0) {
       LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs);
       fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
-      
+
       if (abstraction_flag == 0 ) {
-	for (l=2; l<12; l++) {
-	  
-	  slot_fep_mbsfn(ue,
-			 l,
-			 subframe_rx,
-			 0,0);//ue->rx_offset,0);
-	}
+  for (l=2; l<12; l++) {
 
-	for (l=2; l<12; l++) {
-	  rx_pmch(ue,
-		  0,
-		  subframe_rx,
-		  l);
-	}
+    slot_fep_mbsfn(ue,
+       l,
+       subframe_rx,
+       0,0);//ue->rx_offset,0);
+  }
+
+  for (l=2; l<12; l++) {
+    rx_pmch(ue,
+      0,
+      subframe_rx,
+      l);
+  }
 
 
-	ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
-						       ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
-						       ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
-						       ue->dlsch_MCH[0]->harq_processes[0]->Qm,
-						       1,
-						       2,
-						       frame_rx,
-						       subframe_rx,
-						       0);
-	
-	dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
-			   ue->dlsch_MCH[0]->harq_processes[0]->G,
-			   ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
-	
-	ret = dlsch_decoding(ue,
-			     ue->pdsch_vars_MCH[0]->llr[0],
-			     &ue->frame_parms,
-			     ue->dlsch_MCH[0],
-			     ue->dlsch_MCH[0]->harq_processes[0],
-			     frame_rx,
-			     subframe_rx,
-			     0,
-			     0,1);
+  ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
+                   ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
+                   ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
+                   ue->dlsch_MCH[0]->harq_processes[0]->Qm,
+                   1,
+                   2,
+                   frame_rx,
+                   subframe_rx,
+                   0);
+
+  dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
+         ue->dlsch_MCH[0]->harq_processes[0]->G,
+         ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
+
+  ret = dlsch_decoding(ue,
+           ue->pdsch_vars_MCH[0]->llr[0],
+           &ue->frame_parms,
+           ue->dlsch_MCH[0],
+           ue->dlsch_MCH[0]->harq_processes[0],
+           frame_rx,
+           subframe_rx,
+           0,
+           0,1);
       } else { // abstraction
 #ifdef PHY_ABSTRACTION
-	ret = dlsch_decoding_emul(ue,
-				  subframe_rx,
-				  5, // PMCH
-				  eNB_id);
+  ret = dlsch_decoding_emul(ue,
+          subframe_rx,
+          5, // PMCH
+          eNB_id);
 #endif
       }
-      
+
       if (mcch_active == 1)
-	ue->dlsch_mcch_trials[sync_area][0]++;
+  ue->dlsch_mcch_trials[sync_area][0]++;
       else
-	ue->dlsch_mtch_trials[sync_area][0]++;
-      
+  ue->dlsch_mtch_trials[sync_area][0]++;
+
       if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
-	if (mcch_active == 1)
-	  ue->dlsch_mcch_errors[sync_area][0]++;
-	else
-	  ue->dlsch_mtch_errors[sync_area][0]++;
-	
-	LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
-	      ue->Mod_id,
+  if (mcch_active == 1)
+    ue->dlsch_mcch_errors[sync_area][0]++;
+  else
+    ue->dlsch_mtch_errors[sync_area][0]++;
+
+  LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
+        ue->Mod_id,
               frame_rx,subframe_rx,
-	      ue->dlsch_mcch_errors[sync_area][0],
-	      ue->dlsch_mtch_errors[sync_area][0],
-	      ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
-	      ue->dlsch_MCH[0]->max_turbo_iterations,
-	      ue->dlsch_MCH[0]->harq_processes[0]->G);
-	dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
+        ue->dlsch_mcch_errors[sync_area][0],
+        ue->dlsch_mtch_errors[sync_area][0],
+        ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+        ue->dlsch_MCH[0]->max_turbo_iterations,
+        ue->dlsch_MCH[0]->harq_processes[0]->G);
+  dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
 #ifdef DEBUG_DLSCH
-	
-	for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
-	  LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
-	}
-	
-	LOG_T(PHY,"\n");
+
+  for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
+    LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
+  }
+
+  LOG_T(PHY,"\n");
 #endif
-	
-	if (subframe_rx==9)
-	  mac_xface->macphy_exit("Why are we exiting here?");
+
+  if (subframe_rx==9)
+    mac_xface->macphy_exit("Why are we exiting here?");
       } else { // decoding successful
 #if defined(Rel10) || defined(Rel14)
-	
-	if (mcch_active == 1) {
-	  mac_xface->ue_send_mch_sdu(ue->Mod_id,
-				     CC_id,
-				     frame_rx,
-				     ue->dlsch_MCH[0]->harq_processes[0]->b,
-				     ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
-				     eNB_id,// not relevant in eMBMS context
-				     sync_area);
-	  ue->dlsch_mcch_received[sync_area][0]++;
-	  
-	  
-	  if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
-	    ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
-	  } else {
-	    ue->dlsch_mch_received[0]+=1;
-	    ue->dlsch_mch_received_sf[subframe_rx][0]=1;
-	  }
-	  
-	  
-	}
+
+  if (mcch_active == 1) {
+    mac_xface->ue_send_mch_sdu(ue->Mod_id,
+             CC_id,
+             frame_rx,
+             ue->dlsch_MCH[0]->harq_processes[0]->b,
+             ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+             eNB_id,// not relevant in eMBMS context
+             sync_area);
+    ue->dlsch_mcch_received[sync_area][0]++;
+
+
+    if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
+      ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
+    } else {
+      ue->dlsch_mch_received[0]+=1;
+      ue->dlsch_mch_received_sf[subframe_rx][0]=1;
+    }
+
+
+  }
 #endif // Rel10 || Rel14
       } // decoding sucessful
     } // pmch_mcs>=0
@@ -3615,14 +3648,15 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
     if (dlsch0 && (!dlsch1))  {
       harq_pid = dlsch0->current_harq_pid;
       LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m);
-	    
-      if ((pdsch==PDSCH) && 
-	  (ue->transmission_mode[eNB_id] == 5) &&
-	  (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
-	  (ue->use_ia_receiver ==1)) {
-	dual_stream_UE = 1;
-	eNB_id_i = ue->n_connected_eNB;
-	i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
+
+      if ((pdsch==PDSCH) &&
+          (ue->transmission_mode[eNB_id] == 5) &&
+          (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
+          (ue->use_ia_receiver ==1)) {
+        dual_stream_UE = 1;
+        eNB_id_i = ue->n_connected_eNB;
+        i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
+
       }
       else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3))
       {
@@ -3631,9 +3665,9 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
           i_mod          = 0;
       }
       else {
-	dual_stream_UE = 0;
-	eNB_id_i = eNB_id+1;
-	i_mod = 0;
+        dual_stream_UE = 0;
+        eNB_id_i = eNB_id+1;
+        i_mod = 0;
       }
 
       //TM7 UE specific channel estimation here!!!
@@ -3646,9 +3680,9 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
           LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
         }
       }
-     
+
       if ((m==s0) && (m<4))
-	first_symbol_flag = 1;
+  first_symbol_flag = 1;
       else
 	first_symbol_flag = 0;
 #if UE_TIMING_TRACE
@@ -3672,7 +3706,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
 #endif
     } // CRNTI active
   }
-} 
+}
 
 void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
 
@@ -3684,14 +3718,14 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
   uint8_t *rar;
 
   LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
-	ue->Mod_id,
-	frame_rx,
-	subframe_rx, ue->UE_mode[eNB_id]);
-  
-	
+  ue->Mod_id,
+  frame_rx,
+  subframe_rx, ue->UE_mode[eNB_id]);
+
+
   if (ue->mac_enabled == 1) {
-    if ((ue->UE_mode[eNB_id] != PUSCH) && 
-	(ue->prach_resources[eNB_id]->Msg3!=NULL)) {
+    if ((ue->UE_mode[eNB_id] != PUSCH) &&
+  (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
       LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n",
 	    ue->Mod_id,frame_rx,
 	    subframe_rx,
@@ -3702,24 +3736,25 @@ 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 & 0x1][eNB_id]->crnti,
+						 &ue->pdcch_vars[subframe_rx%RX_NB_TH][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) & 0x1][eNB_id]->crnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti;
+      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;
       
-	    
       if (timing_advance!=0xffff) {
-	      
-	      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
+
+              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
               ue->Mod_id,
               frame_rx,
               subframe_rx,
-              ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+              ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti,
               timing_advance);
-	      
+
   // remember this c-rnti is still a tc-rnti
-  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti_is_temporary = 1;
+
+  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->crnti_is_temporary = 1;
 	      
 	//timing_advance = 0;
 	process_timing_advance_rar(ue,proc,timing_advance);
@@ -3749,9 +3784,9 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
 	  ue->ulsch_no_allocation_counter[eNB_id] = 0;
 	}
       } else { // PRACH preamble doesn't match RAR
-	LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
-	      ue->Mod_id,
-	      ue->prach_resources[eNB_id]->ra_PreambleIndex);
+  LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
+        ue->Mod_id,
+        ue->prach_resources[eNB_id]->ra_PreambleIndex);
       }
     } // mode != PUSCH
   }
@@ -3760,18 +3795,18 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
     timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
     process_timing_advance_rar(ue,proc,timing_advance);
   }
-  
+
 }
 
-void ue_dlsch_procedures(PHY_VARS_UE *ue, 
-			 UE_rxtx_proc_t *proc, 
-			 int eNB_id,
-			 PDSCH_t pdsch, 
-			 LTE_UE_DLSCH_t *dlsch0, 
-			 LTE_UE_DLSCH_t *dlsch1, 
-			 int *dlsch_errors, 
-			 runmode_t mode, 
-			 int abstraction_flag) {
+void ue_dlsch_procedures(PHY_VARS_UE *ue,
+       UE_rxtx_proc_t *proc,
+       int eNB_id,
+       PDSCH_t pdsch,
+       LTE_UE_DLSCH_t *dlsch0,
+       LTE_UE_DLSCH_t *dlsch1,
+       int *dlsch_errors,
+       runmode_t mode,
+       int abstraction_flag) {
 
   int harq_pid;
   int frame_rx = proc->frame_rx;
@@ -3815,7 +3850,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&0x1][eNB_id];
+      pdsch_vars = ue->pdsch_vars[subframe_rx%RX_NB_TH][eNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -3829,17 +3864,16 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       break;
 
     }
-
     if (frame_rx < *dlsch_errors)
       *dlsch_errors=0;
 
     if (pdsch==RA_PDSCH) {
       if (ue->prach_resources[eNB_id]!=NULL)
-	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+  dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
       else {
-	LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
-	mac_xface->macphy_exit("prach_resources is NULL");
-	return;
+  LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
+  mac_xface->macphy_exit("prach_resources is NULL");
+  return;
       }
     }
 
@@ -3851,7 +3885,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 & 0x1][eNB_id]->num_pdcch_symbols,
+						  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
 						  frame_rx,
 						  subframe_rx,
 						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
@@ -3877,12 +3911,12 @@ 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 & 0x1][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[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
 #endif
+
 #if UE_TIMING_TRACE
-      start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
+      start_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
 #endif
-
       ret = dlsch_decoding(ue,
 			   pdsch_vars->llr[0],
 			   &ue->frame_parms,
@@ -3893,23 +3927,22 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 			   harq_pid,
 			   pdsch==PDSCH?1:0,
 			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
-#if UE_TIMING_TRACE
-      stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
 
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
 #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&0x1].p_time)/(cpuf*1000.0));
+              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].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&0x1].p_time)/(cpuf*1000.0));
+              frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].p_time)/(cpuf*1000.0));
 #endif
 
 #endif
-
       if(is_cw1_active)
       {
           // start turbo decode for CW 1
@@ -3918,7 +3951,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 & 0x1][eNB_id]->num_pdcch_symbols,
+                  ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                   frame_rx,
                   subframe_rx,
                   ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
@@ -3943,12 +3976,13 @@ 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 & 0x1][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[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
 #endif
 
 #if UE_TIMING_TRACE
-          start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
+          start_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
 #endif
+
           ret1 = dlsch_decoding(ue,
                   pdsch_vars->llr[1],
                   &ue->frame_parms,
@@ -3959,123 +3993,123 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
                   harq_pid,
                   pdsch==PDSCH?1:0,
                   dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-#if UE_TIMING_TRACE
-
-          stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
 
+#if UE_TIMING_TRACE
+          stop_meas(&ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH]);
 #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&0x1].p_time)/(cpuf*1000.0));
+                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].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&0x1].p_time)/(cpuf*1000.0));
+                  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx%RX_NB_TH].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));
       }
 
       LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
     }
-	
+
     else {
       LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
 #ifdef PHY_ABSTRACTION
       ret = dlsch_decoding_emul(ue,
-				subframe_rx,
-				pdsch,
-				eNB_id);
+        subframe_rx,
+        pdsch,
+        eNB_id);
 #endif
     }
-	
+
     // Check CRC for CW 0
     if (ret == (1+dlsch0->max_turbo_iterations)) {
       *dlsch_errors=*dlsch_errors+1;
-      
+
       if(dlsch0->rnti != 0xffff)
       {
       LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
-	    ue->Mod_id,dlsch0->rnti,
-	    harq_pid,frame_rx,subframe_rx,
-	    dlsch0->harq_processes[harq_pid]->rvidx,
-        dlsch0->harq_processes[harq_pid]->round,
-	    dlsch0->harq_processes[harq_pid]->mcs,
-	    dlsch0->harq_processes[harq_pid]->TBS);
+            ue->Mod_id,dlsch0->rnti,
+            harq_pid,frame_rx,subframe_rx,
+            dlsch0->harq_processes[harq_pid]->rvidx,
+            dlsch0->harq_processes[harq_pid]->round,
+            dlsch0->harq_processes[harq_pid]->mcs,
+            dlsch0->harq_processes[harq_pid]->TBS);
       }
-      
+
 
     } else {
         if(dlsch0->rnti != 0xffff)
         {
       LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
-	    ue->Mod_id,dlsch0->rnti,
-	    harq_pid,frame_rx,subframe_rx,
-	    dlsch0->harq_processes[harq_pid]->rvidx,
-        dlsch0->harq_processes[harq_pid]->round,
-	    dlsch0->harq_processes[harq_pid]->mcs,
-	    dlsch0->harq_processes[harq_pid]->TBS);
+            ue->Mod_id,dlsch0->rnti,
+            harq_pid,frame_rx,subframe_rx,
+            dlsch0->harq_processes[harq_pid]->rvidx,
+            dlsch0->harq_processes[harq_pid]->round,
+            dlsch0->harq_processes[harq_pid]->mcs,
+            dlsch0->harq_processes[harq_pid]->TBS);
         }
 
 #ifdef DEBUG_DLSCH
       int j;
       LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
-      
+
       for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
-	LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
-      
+  LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
+
       LOG_T(PHY,"\n");
 #endif
 
-      
+
       if (ue->mac_enabled == 1) {
-	switch (pdsch) {
-	case PDSCH:
-	  mac_xface->ue_send_sdu(ue->Mod_id,
-				 CC_id,
-				 frame_rx,
+  switch (pdsch) {
+  case PDSCH:
+    mac_xface->ue_send_sdu(ue->Mod_id,
+         CC_id,
+         frame_rx,
          subframe_rx,
-				 dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
-				 dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
-				 eNB_id);
-	  break;
-	case SI_PDSCH:
-	  mac_xface->ue_decode_si(ue->Mod_id,
-				  CC_id,
-				  frame_rx,
-				  eNB_id,
-				  ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
-				  ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
-	  break;
-	case P_PDSCH:
-	  mac_xface->ue_decode_p(ue->Mod_id,
-				 CC_id,
-				 frame_rx,
-				 eNB_id,
-				 ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
-				 ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
-	  break;
-	case RA_PDSCH:
-	  process_rar(ue,proc,eNB_id,mode,abstraction_flag);
-	  break;
-	case PDSCH1:
-	  LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
-	  AssertFatal(1==0,"exiting");
-	  break;
-	case PMCH:
-	  LOG_E(PHY,"Shouldn't have PMCH here\n");
-	  AssertFatal(1==0,"exiting");
-	  break;
-	}
+         dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
+         dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
+         eNB_id);
+    break;
+  case SI_PDSCH:
+    mac_xface->ue_decode_si(ue->Mod_id,
+          CC_id,
+          frame_rx,
+          eNB_id,
+          ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
+          ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
+    break;
+  case P_PDSCH:
+    mac_xface->ue_decode_p(ue->Mod_id,
+         CC_id,
+         frame_rx,
+         eNB_id,
+         ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
+         ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
+    break;
+  case RA_PDSCH:
+    process_rar(ue,proc,eNB_id,mode,abstraction_flag);
+    break;
+  case PDSCH1:
+    LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
+    AssertFatal(1==0,"exiting");
+    break;
+  case PMCH:
+    LOG_E(PHY,"Shouldn't have PMCH here\n");
+    AssertFatal(1==0,"exiting");
+    break;
+  }
       }
       ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] +
-	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+  dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
       ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
-	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+  dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
     }
-  
     // Check CRC for CW 1
     if(is_cw1_active)
     {
@@ -4119,27 +4153,26 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
             }
         }
     }
-  
-      
+
 #ifdef DEBUG_PHY_PROC
     LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
-	  ue->Mod_id,
-	  dlsch0->rnti,harq_pid,
-	  frame_rx,subframe_rx,ret,
-	  dlsch0->harq_processes[harq_pid]->mcs,
-	  dlsch0->harq_processes[harq_pid]->rvidx,
-	  dlsch0->harq_processes[harq_pid]->TBS);
-    
+    ue->Mod_id,
+    dlsch0->rnti,harq_pid,
+    frame_rx,subframe_rx,ret,
+    dlsch0->harq_processes[harq_pid]->mcs,
+    dlsch0->harq_processes[harq_pid]->rvidx,
+    dlsch0->harq_processes[harq_pid]->TBS);
+
     if (frame_rx%100==0) {
       LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
-	    ue->Mod_id,dlsch0->rnti,
-	    frame_rx,subframe_rx,
-	    ue->dlsch_errors[eNB_id],
-	    ue->dlsch_received[eNB_id],
-	    ue->dlsch_fer[eNB_id],
-	    ue->measurements.wideband_cqi_tot[eNB_id]);
+      ue->Mod_id,dlsch0->rnti,
+      frame_rx,subframe_rx,
+      ue->dlsch_errors[eNB_id],
+      ue->dlsch_received[eNB_id],
+      ue->dlsch_fer[eNB_id],
+      ue->measurements.wideband_cqi_tot[eNB_id]);
     }
-    
+
 #endif
 
   }
@@ -4147,6 +4180,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 
 }
 
+//Merge 2017.w25
 #ifdef UE_SLOT_PARALLELISATION
 /*!
  * \brief This is the UE synchronize thread.
@@ -4157,289 +4191,14 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 #define FIFO_PRIORITY   40
 void *UE_thread_fep_slot1(void *arg) {
 
-    static __thread int UE_thread_rxtx_retval;
-    struct rx_tx_thread_data *rtd = arg;
-    UE_rxtx_proc_t *proc = rtd->proc;
-    PHY_VARS_UE    *ue   = rtd->UE;
-
-    char threadname[256];
-    proc->subframe_rx=proc->sub_frame_start;
-    sprintf(threadname,"UE_SLOT1_PROC_%d", proc->sub_frame_start);
-    cpu_set_t cpuset;
-    CPU_ZERO(&cpuset);
-    if ( (proc->sub_frame_start+1)%2 == 0 )
-        CPU_SET(0, &cpuset);
-    if ( (proc->sub_frame_start+1)%2 == 1 )
-        CPU_SET(4, &cpuset);
-    init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
-                threadname);
-
-
-    uint8_t l;
-    uint8_t compute_llrs_slot1;
-
-#ifdef UE_SLOT_PARALLELISATION
-    proc->instance_cnt_fep_slot1=-1;
-#endif
-
-    while (!oai_exit) {
-        if (pthread_mutex_lock(&proc->mutex_fep_slot1) != 0) {
-            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE FEP Slo1\n" );
-            exit_fun("nothing to add");
-        }
-#ifdef UE_SLOT_PARALLELISATION
-        while (proc->instance_cnt_fep_slot1 < 0) {
-            // most of the time, the thread is waiting here
-            pthread_cond_wait( &proc->cond_fep_slot1, &proc->mutex_fep_slot1 );
-        }
-        if (pthread_mutex_unlock(&proc->mutex_fep_slot1) != 0) {
-            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
-            exit_fun("nothing to add");
-        }
-
-        // Start Thread Processing
-        LOG_I(PHY," [Th-Slave] ==> execute fep slot1 thread for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
-#endif
-
-#if 1
-        int frame_rx    = proc->frame_rx;
-        int subframe_rx = proc->subframe_rx;
-        uint8_t pilot0;
-        uint8_t pilot1;
-        uint8_t slot1;
-
-        slot1  = (subframe_rx<<1) + 1;
-        pilot0 = 0;
-        if (ue->frame_parms.Ncp == 0) {  // normal prefix
-          pilot1 = 4;
-        } else { // extended prefix
-          pilot1 = 3;
-        }
-
-<<<<<<< Updated upstream
-#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_D(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[subframe_rx&0x1]);
-  start_meas(&ue->generic_stat);
-#endif
-=======
-        // do first symbol of next downlink subframe for channel estimation
-        int next_subframe_rx = (1+subframe_rx)%10;
-        uint8_t next_subframe_slot0 = next_subframe_rx<<1;
-        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
-        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
-        {
-            //LOG_I(PHY,"[Th-Slave] FFT symbol %d slot %d \n", pilot0, next_subframe_slot0);
-            front_end_fft(ue,
-                    pilot0,
-                    next_subframe_slot0,
-                    0,
-                    0);
-        }
-        //LOG_I(PHY,"[Th-Slave]FFT symbol %d slot %d \n",pilot1,slot1);
-        front_end_fft(ue,
-                pilot1,
-                slot1,
-                0,
-                0);
-        // 2- perform FFT for other ofdm symbols other than pilots
-        for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
-        {
-            if( (l != pilot0) && (l != pilot1))
-            {
-                //LOG_I(PHY,"[Th-Slave]FFT symbol %d slot %d\n",l,slot1);
-                start_meas(&ue->ofdm_demod_stats);
-                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
-                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);
-                stop_meas(&ue->ofdm_demod_stats);
-            }
-        } // for l=1..l2
-
-        // 3- perform Channel Estimation for slot1
-        for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
-        {
-            uint32_t wait=0;
-            if(l==pilot1)
-            {
-                LOG_I(PHY,"[Th-Slave] ==> wait pilot0 slot1 channel estimation is ready \n");
-                while(proc->chan_est_pilot0_slot1_available==0)
-                {
-                    //wait until channel estimation for pilot0/slot1 is available
-                    usleep(1);
-                    wait++;
-                }
-            }
-            front_end_chanEst(ue,
-                    l,
-                    slot1,
-                    0);
-
-            //LOG_I(PHY,"[Th-Slave]ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
-            ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode);
-        }
-        //LOG_I(PHY,"[Th-Slave]ChanEst symbol %d slot %d\n",0,next_subframe_slot0);
-        front_end_chanEst(ue,
-                0,
-                next_subframe_slot0,
-                0);
-
-        if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
-        {
-            ue_pbch_procedures(0,ue,proc,0);
-        }
-#endif
-        LOG_I(PHY," [Th-Slave] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
-
-        LOG_I(PHY," [Th-Slave] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
-
-#if 1
-     // wait until dci info are available
-     uint32_t wait=0;
-     while(proc->dci_slot0_available==0) // (proc->dci_slot0_available==0)
-     {
-        //wait until channel estimation for pilot0/slot1 is available
-        usleep(1);
-        wait++;
-     }
-     // check if a dl grant was received on a DCI
-     compute_llrs_slot1 = 0;
-     if(ue->dlsch[subframe_rx&0x1][0][0]->active ||
-        ((ue->dlsch_SI[0]) && (ue->dlsch_SI[0]->active == 1)) ||
-        ((ue->dlsch_p[0]) && (ue->dlsch_p[0]->active == 1)) ||
-        ((ue->dlsch_ra[0]) && (ue->dlsch_ra[0]->active == 1))
-        )
-     {
-       compute_llrs_slot1 = 1;
-     }
-     else
-     {
-       proc->llr_slot1_available = 1;
-     }
-     LOG_I(PHY,"[Th-Slave] compute llrs slot-1 %d AbsSubframe %d.%d \n",compute_llrs_slot1,frame_rx%1024,subframe_rx);
-
-     if(compute_llrs_slot1)
-     {
-         // wait until computation of first ofdm symbol is done
-         uint32_t wait=0;
-         while(proc->first_symbol_available==0)
-         {
-             //wait until channel estimation for pilot0/slot1 is available
-             usleep(1);
-             wait++;
-         }
-
-         // start slave thread for Pdsch Procedure (slot1)
-         // do procedures for C-RNTI
-         //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure (slot1) wait %d \n",frame_rx%1024,subframe_rx,wait);
-         //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[subframe_rx&0x1][0][0]->active);
-         if (ue->dlsch[subframe_rx&0x1][0][0]->active == 1) {
-             //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure PDSCH \n",frame_rx%1024,subframe_rx);
-             VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-             start_meas(&ue->pdsch_procedures_stat);
-             ue_pdsch_procedures(ue,
-                     proc,
-                     0,
-                     PDSCH,
-                     ue->dlsch[subframe_rx&0x1][0][0],
-                     NULL,
-                     1+(ue->frame_parms.symbols_per_tti>>1),
-                     ue->frame_parms.symbols_per_tti-1,
-                     0);
-             stop_meas(&ue->pdsch_procedures_stat);
-         }
-
-         // do procedures for SI-RNTI
-         if ((ue->dlsch_SI[0]) && (ue->dlsch_SI[0]->active == 1)) {
-             //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure SI-PDSCH \n",frame_rx%1024,subframe_rx);
-             ue_pdsch_procedures(ue,
-                     proc,
-                     0,
-                     SI_PDSCH,
-                     ue->dlsch_SI[0],
-                     NULL,
-                     1+(ue->frame_parms.symbols_per_tti>>1),
-                     ue->frame_parms.symbols_per_tti-1,
-                     0);
-         }
-
-         // do procedures for P-RNTI
-         if ((ue->dlsch_p[0]) && (ue->dlsch_p[0]->active == 1)) {
-             //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure P-PDSCH \n",frame_rx%1024,subframe_rx);
-             ue_pdsch_procedures(ue,
-                     proc,
-                     0,
-                     P_PDSCH,
-                     ue->dlsch_p[0],
-                     NULL,
-                     1+(ue->frame_parms.symbols_per_tti>>1),
-                     ue->frame_parms.symbols_per_tti-1,
-                     0);
-         }
-         // do procedures for RA-RNTI
-         if ((ue->dlsch_ra[0]) && (ue->dlsch_ra[0]->active == 1)) {
-             //LOG_I(PHY,"[Th-Slave] AbsSubframe %d.%d Pdsch Procedure RA-PDSCH \n",frame_rx%1024,subframe_rx);
-             ue_pdsch_procedures(ue,
-                     proc,
-                     0,
-                     RA_PDSCH,
-                     ue->dlsch_ra[0],
-                     NULL,
-                     1+(ue->frame_parms.symbols_per_tti>>1),
-                     ue->frame_parms.symbols_per_tti-1,
-                     0);
-         }
-
-         //LOG_I(PHY,"Set available llrs slot1 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
-         proc->llr_slot1_available = 1;
-     }
-#endif
-
-     LOG_I(PHY," [Th-Slave] ==> End slot1 Thread for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
-
-        // End Thread Processing
->>>>>>> Stashed changes
-
-        if (pthread_mutex_lock(&proc->mutex_fep_slot1) != 0) {
-            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
-            exit_fun("noting to add");
-        }
-        proc->instance_cnt_fep_slot1--;
-        if (pthread_mutex_unlock(&proc->mutex_fep_slot1) != 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_thread_rxtx_retval;
-
-
 }
 #endif
 
-int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
+#if 1
+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) {
 
-
     int l,l2;
     int pmch_flag=0;
     int frame_rx = proc->frame_rx;
@@ -4452,63 +4211,77 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
 
-  #if T_TRACER
+#if T_TRACER
     T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
-  #endif
-
 
     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));
+            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);
-    start_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->phy_proc_rx[subframe_rx%RX_NB_TH]);
     start_meas(&ue->generic_stat);
+#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[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_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
 
-    // deactivate reception until we scan pdcch
-    if (ue->dlsch[subframe_rx&0x1][eNB_id][0])
-      ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0;
-    if (ue->dlsch[subframe_rx&0x1][eNB_id][1])
-      ue->dlsch[subframe_rx&0x1][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;
 
-  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;
-  }
-    
+
+    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;
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // 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;
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // 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;
+        pilot1 = 4;
     } else { // extended prefix
-      pilot1 = 3;
+        pilot1 = 3;
     }
 
     //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
@@ -4525,14 +4298,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     proc->instance_cnt_fep_slot1++;
     if (proc->instance_cnt_fep_slot1 == 0) {
         LOG_I(PHY,"unblock fep slot1 thread blocked on cond_fep_slot1 : instance_cnt_fep_slot1 %d \n", proc->instance_cnt_fep_slot1 );
-      if (pthread_cond_signal(&proc->cond_fep_slot1) != 0) {
-        LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE FEP slot1 thread\n", ue->Mod_id);
-        exit_fun("nothing to add");
-      }
+        if (pthread_cond_signal(&proc->cond_fep_slot1) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE FEP slot1 thread\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_fep_slot1);
-      if (proc->instance_cnt_fep_slot1 > 2)
-        exit_fun("instance_cnt_fep_slot1 > 2");
+        LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_fep_slot1);
+        if (proc->instance_cnt_fep_slot1 > 2)
+            exit_fun("instance_cnt_fep_slot1 > 2");
     }
     AssertFatal(pthread_cond_signal(&proc->cond_fep_slot1) ==0 ,"");
     AssertFatal(pthread_mutex_unlock(&proc->mutex_fep_slot1) ==0,"");
@@ -4540,39 +4313,39 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
     /**** FFT Slot0 + Slot1 ****/
     // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
-
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat);
+#endif
     // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
-    LOG_I(PHY,"FFT symbol %d slot %d \n",pilot0,slot1);
     front_end_fft(ue,
             pilot0,
             slot1,
             0,
             0);
-    LOG_I(PHY,"FFT symbol %d slot %d \n",pilot1,slot0);
     front_end_fft(ue,
             pilot1,
             slot0,
             0,
             0);
-    LOG_I(PHY,"ChanEst symbol %d slot %d\n",pilot1,slot0);
     front_end_chanEst(ue,
             pilot1,
             slot0,
             0);
-    LOG_I(PHY,"ChanEst symbol %d slot %d\n",pilot0,slot1);
     front_end_chanEst(ue,
             pilot0,
             slot1,
             0);
     proc->chan_est_pilot0_slot1_available = 1;
-    LOG_I(PHY,"Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    //LOG_I(PHY,"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))
         {
-            LOG_I(PHY,"FFT symbol %d slot %d \n", l, slot0);
+#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,
@@ -4580,7 +4353,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                     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
 
@@ -4589,33 +4364,48 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     {
         if( (l != pilot0) && (l != pilot1))
         {
-        LOG_I(PHY,"ChanEst symbol %d slot %d\n",l,slot0);
-        front_end_chanEst(ue,
-                l,
-                slot0,
-                0);
+            front_end_chanEst(ue,
+                    l,
+                    slot0,
+                    0);
         }
         ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
     }
 
-    // PDCCH decoding
-    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);
+    if (do_pdcch_flag) {
+        LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
+
+        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_I(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
-    LOG_I(PHY,"Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
+    //LOG_I(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols);
+    //LOG_I(PHY,"Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
     proc->dci_slot0_available=1;
 
+    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+#endif
+
 
     // If this is PMCH, call procedures and return
     if (pmch_flag == 1) {
-      ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
-      return 0;
+        ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
+        return 0;
     }
 
 #if 1
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat);
+#endif
     // II- start slave thread for FFT/ChanEst
     // do first symbol of next downlink subframe for channel estimation
     int next_subframe_rx = (1+subframe_rx)%10;
@@ -4623,7 +4413,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
     if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
     {
-        LOG_I(PHY,"FFT symbol %d slot %d \n", pilot0, next_subframe_slot0);
         front_end_fft(ue,
                 pilot0,
                 next_subframe_slot0,
@@ -4631,7 +4420,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                 0);
     }
 
-    LOG_I(PHY,"FFT symbol %d slot %d \n",pilot1,slot1);
     front_end_fft(ue,
             pilot1,
             slot1,
@@ -4643,8 +4431,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     {
         if( (l != pilot0) && (l != pilot1))
         {
-            LOG_I(PHY,"FFT symbol %d slot %d\n",l,slot1);
+#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,
@@ -4652,7 +4441,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                     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
 
@@ -4665,17 +4456,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
             uint32_t wait = 0;
             while(proc->chan_est_pilot0_slot1_available == 0)
             {
-              wait++;
+                wait++;
             }
         }
-        LOG_I(PHY,"ChanEst symbol %d slot %d\n",l,slot1);
         front_end_chanEst(ue,
                 l,
                 slot1,
                 0);
         ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
     }
-    LOG_I(PHY,"ChanEst symbol %d slot %d\n",0,next_subframe_slot0);
     front_end_chanEst(ue,
             pilot0,
             next_subframe_slot0,
@@ -4683,12 +4472,19 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
     if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
     {
-      ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
+        ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
     }
-#endif
 
+#if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat);
-    //printf("------Front-End PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+#endif
+
+#endif
     /**** End Subframe FFT-ChannelEst ****/
 
 
@@ -4696,137 +4492,183 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     // start main thread for Pdsch Procedure (slot0)
     // do procedures for C-RNTI
     //LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
-    //LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[subframe_rx&0x1][0][0]->active);
+    //LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[subframe_rx%RX_NB_TH][0][0]->active);
 
+#if UE_TIMING_TRACE
     start_meas(&ue->generic_stat);
-    if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-        LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure PDSCH \n",frame_rx%1024,subframe_rx);
-      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&0x1][eNB_id][0],
-              NULL,
-              ue->pdcch_vars[subframe_rx & 0x1][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, VCD_FUNCTION_OUT);
+#endif
+    if (ue->dlsch[subframe_rx%RX_NB_TH][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],
+                NULL,
+                ue->pdcch_vars[subframe_rx%RX_NB_TH][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, VCD_FUNCTION_OUT);
     }
-    
+
     // do procedures for SI-RNTI
     if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
-        LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure SI-PDSCH \n",frame_rx%1024,subframe_rx);
-      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[subframe_rx & 0x1][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);
+        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[subframe_rx%RX_NB_TH][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);
     }
-    
+
     // do procedures for SI-RNTI
     if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
-        LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure P-PDSCH \n",frame_rx%1024,subframe_rx);
-      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[subframe_rx & 0x1][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);
+        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[subframe_rx%RX_NB_TH][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);
     }
 
     // do procedures for RA-RNTI
     if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
-        LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure RA-PDSCH \n",frame_rx%1024,subframe_rx);
-      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[subframe_rx & 0x1][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);
+        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[subframe_rx%RX_NB_TH][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);
     }
 
+#if UE_TIMING_TRACE
     stop_meas(&ue->generic_stat);
-    //printf("------LLR-Slot0  [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot0: LLR Computation %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot0: LLR Computation %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+#endif
 
 #if 1
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat);
+#endif
     // start slave thread for Pdsch Procedure (slot1)
     // do procedures for C-RNTI
-
-    if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-      start_meas(&ue->pdsch_procedures_stat);
-      ue_pdsch_procedures(ue,
-              proc,
-              eNB_id,
-              PDSCH,
-              ue->dlsch[subframe_rx&0x1][eNB_id][0],
-              NULL,
-              1+(ue->frame_parms.symbols_per_tti>>1),
-              ue->frame_parms.symbols_per_tti-1,
-              abstraction_flag);
-      stop_meas(&ue->pdsch_procedures_stat);
+    if (ue->dlsch[subframe_rx%RX_NB_TH][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);
+#endif
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0],
+                NULL,
+                1+(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);
+#if UE_TIMING_TRACE
+        stop_meas(&ue->pdsch_procedures_stat);
+#endif
     }
 
     // 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,
-              1+(ue->frame_parms.symbols_per_tti>>1),
-              ue->frame_parms.symbols_per_tti-1,
-              abstraction_flag);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                1+(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,
-              1+(ue->frame_parms.symbols_per_tti>>1),
-              ue->frame_parms.symbols_per_tti-1,
-              abstraction_flag);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                1+(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,
-              1+(ue->frame_parms.symbols_per_tti>>1),
-              ue->frame_parms.symbols_per_tti-1,
-              abstraction_flag);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                1+(ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
     }
     proc->llr_slot1_available=1;
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot1: LLR Computation %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot1: LLR Computation %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 #endif
 
-    start_meas(&ue->generic_stat);
-    // wait until llr on slot1 are available
-    uint32_t wait=0;
+#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){
+        //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_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("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);
+
+        AssertFatal (0,"");
+    }
+#endif
+
+    //=====================================================================//
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat);
+#endif
+    // wait until llr on slot1 are available
+    uint32_t wait=0;
     while(proc->llr_slot1_available==0)
     {
         //wait until channel estimation for pilot0/slot1 is available
@@ -4838,640 +4680,659 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
     LOG_I(PHY,"==> Start Turbo Decoder wait %d\n", wait);
     // Start Turbo decoder
-    if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-       start_meas(&ue->dlsch_procedures_stat);
-       ue_dlsch_procedures(ue,
-               proc,
-               eNB_id,
-               PDSCH,
-               ue->dlsch[subframe_rx&0x1][eNB_id][0],
-               ue->dlsch[subframe_rx&0x1][eNB_id][1],
-               &ue->dlsch_errors[eNB_id],
-               mode,
-               abstraction_flag);
-       stop_meas(&ue->dlsch_procedures_stat);
-       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
-     }
+    if (ue->dlsch[subframe_rx%RX_NB_TH][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->dlsch_procedures_stat);
+#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_errors[eNB_id],
+                mode,
+                abstraction_flag);
+#if UE_TIMING_TRACE
+        stop_meas(&ue->dlsch_procedures_stat);
+#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));
+#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));
+#endif
 
-     // 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;
-     }
+#endif
 
-     // 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;
-     }
-     //printf("------ Turbo Decoding [SFN %d]: %5.2f ------\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
 
-    /**** End Pdsch processing for this subframe ****/
+    // 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->generic_stat);
+#if DISABLE_LOG_X
+    printf("[SFN %d] Channel Decoder: %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Channel Decoder: %5.2f %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+#endif
+    // 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];
+
+    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]);
+        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->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);
+        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
+#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
 
     }
 
-    //printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat);
+    printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 
-  #ifdef EMOS
+#ifdef EMOS
     phy_procedures_emos_UE_RX(ue,slot,eNB_id);
-  #endif
+#endif
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
-    stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
 
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
 
-    //printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0));
-    LOG_I(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc_rx[subframe_rx%RX_NB_TH]);
+#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));
+#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));
+#endif
+#endif
 
+    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
     return (0);
-  }
+}
+#else
 
+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) {
 
+  int l,l2;
+  int pilot1;
+  int pmch_flag=0;
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
 
-static int phy_procedures_UE_RX_new(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_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);
+  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_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[subframe_rx%RX_NB_TH]);
+  start_meas(&ue->generic_stat);
+#endif
 
-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));
+  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[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_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;
+  }
 
-// start timers
-LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
-start_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
-start_meas(&ue->generic_stat);
+#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
 
-pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
+  if (ue->frame_parms.Ncp == 0) {  // normal prefix
+    pilot1 = 4;
+  } else { // extended prefix
+    pilot1 = 3;
+  }
 
 
-// deactivate reception until we scan pdcch
-if (ue->dlsch[subframe_rx&0x1][eNB_id][0])
-  ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0;
-if (ue->dlsch[subframe_rx&0x1][eNB_id][1])
-  ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0;
+  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;
+  }
 
-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;
+  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
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    l=0;
+  } else {
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+    l=1;
+  }
 
-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;
-}
+  LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+  for (; l<=l2; l++) {
+    if (abstraction_flag == 0) {
+#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);
+      slot_fep(ue,
+         l,
+         (subframe_rx<<1),
+         0,
+         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
+    }
 
-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;
-}
+    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
 
-//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;
+    if (do_pdcch_flag) {
+      if ((l==pilot1) ||
+	  ((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);
 
-#ifdef UE_SLOT_PARALLELISATION
-//LOG_I(PHY,"fep slot1 thread : instance_cnt %d \n",
-//          proc->instance_cnt_fep_slot1);
-proc->instance_cnt_fep_slot1++;
-if (proc->instance_cnt_fep_slot1 == 0) {
-    LOG_I(PHY,"unblock fep slot1 thread blocked on cond_fep_slot1 : instance_cnt_fep_slot1 %d \n", proc->instance_cnt_fep_slot1 );
-  if (pthread_cond_signal(&proc->cond_fep_slot1) != 0) {
-    LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE FEP slot1 thread\n", ue->Mod_id);
-    exit_fun("nothing to add");
+	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);
+      }
+    }
+
+  } // for l=1..l2
+  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
+
+  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+    // If this is PMCH, call procedures and return
+  if (pmch_flag == 1) {
+    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
+    return 0;
   }
-} else {
-  LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_fep_slot1);
-  if (proc->instance_cnt_fep_slot1 > 2)
-    exit_fun("instance_cnt_fep_slot1 > 2");
-}
-AssertFatal(pthread_cond_signal(&proc->cond_fep_slot1) ==0 ,"");
-AssertFatal(pthread_mutex_unlock(&proc->mutex_fep_slot1) ==0,"");
+
+  slot_fep(ue,
+     0,
+     1+(subframe_rx<<1),
+     0,
+     0,
+     0);
+
+  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
 #endif
 
-/**** FFT Slot0 + Slot1 ****/
-// I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
+#endif
 
-// 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
-LOG_I(PHY,"FFT symbol %d slot %d \n",pilot0,slot1);
-front_end_fft(ue,
-        pilot0,
-        slot1,
-        0,
-        0);
-LOG_I(PHY,"FFT symbol %d slot %d \n",pilot1,slot0);
-front_end_fft(ue,
-        pilot1,
-        slot0,
-        0,
-        0);
-LOG_I(PHY,"ChanEst symbol %d slot %d\n",pilot1,slot0);
-front_end_chanEst(ue,
-        pilot1,
-        slot0,
-        0);
-LOG_I(PHY,"ChanEst symbol %d slot %d\n",pilot0,slot1);
-front_end_chanEst(ue,
-        pilot0,
-        slot1,
-        0);
-proc->chan_est_pilot0_slot1_available = 1;
-LOG_I(PHY,"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))
-    {
-        LOG_I(PHY,"FFT symbol %d slot %d \n", l, slot0);
-        start_meas(&ue->ofdm_demod_stats);
-        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);
-        stop_meas(&ue->ofdm_demod_stats);
-    }
-} // for l=1..l2
+  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+#if UE_TIMING_TRACE
+  start_meas(&ue->generic_stat);
+#endif
+  // do procedures for C-RNTI
+  if (ue->dlsch[subframe_rx%RX_NB_TH][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],
+			NULL,
+			ue->pdcch_vars[subframe_rx%RX_NB_TH][eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
 
-// 3- perform Channel Estimation for slot0
-for (l=first_ofdm_sym; l<=l2; l++)
-{
-    if( (l != pilot0) && (l != pilot1))
-    {
-    LOG_I(PHY,"ChanEst symbol %d slot %d\n",l,slot0);
-    front_end_chanEst(ue,
-            l,
-            slot0,
-            0);
-    }
-    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
-}
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+  }
 
-// PDCCH decoding
-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," ------ end PDSCH ChannelComp/LLR slot 0: 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)) {
+    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[subframe_rx%RX_NB_TH][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);
+  }
 
-LOG_I(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
-LOG_I(PHY,"Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
-proc->dci_slot0_available=1;
+  // 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[subframe_rx%RX_NB_TH][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);
+  }
 
+  // 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[subframe_rx%RX_NB_TH][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);
+  }
 
-// If this is PMCH, call procedures and return
-if (pmch_flag == 1) {
-  ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
-  return 0;
-}
+  LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+  LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
 
-#if 1
-// II- start slave thread for FFT/ChanEst
-// do first symbol of next downlink subframe for channel estimation
-int next_subframe_rx = (1+subframe_rx)%10;
-uint8_t next_subframe_slot0 = next_subframe_rx<<1;
-// 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
-if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
-{
-    LOG_I(PHY,"FFT symbol %d slot %d \n", pilot0, next_subframe_slot0);
-    front_end_fft(ue,
-            pilot0,
-            next_subframe_slot0,
-            0,
-            0);
-}
+  if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) {  // do front-end processing for second slot, and first symbol of next subframe
+    for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) {
+      if (abstraction_flag == 0) {
+#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);
+	slot_fep(ue,
+		 l,
+		 1+(subframe_rx<<1),
+		 0,
+		 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
+      }
 
-LOG_I(PHY,"FFT symbol %d slot %d \n",pilot1,slot1);
-front_end_fft(ue,
-        pilot1,
-        slot1,
-        0,
-        0);
+      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
 
-// 2- perform FFT for other ofdm symbols other than pilots
-for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
-{
-    if( (l != pilot0) && (l != pilot1))
-    {
-        LOG_I(PHY,"FFT symbol %d slot %d\n",l,slot1);
-        start_meas(&ue->ofdm_demod_stats);
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
-        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);
-        stop_meas(&ue->ofdm_demod_stats);
-    }
-} // for l=1..l2
+    } // for l=1..l2
 
-// 3- perform Channel Estimation for slot1
-for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
-{
-    if(l == pilot0)
+    // do first symbol of next downlink subframe for channel estimation
+    int next_subframe_rx = (1+subframe_rx)%10;
+    if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
     {
-        //wait until channel estimation for pilot0/slot1 is available
-        uint32_t wait = 0;
-        while(proc->chan_est_pilot0_slot1_available == 0)
-        {
-          wait++;
-        }
+      slot_fep(ue,
+         0,
+         (next_subframe_rx<<1),
+         0,
+         0,
+         0);
     }
-    LOG_I(PHY,"ChanEst symbol %d slot %d\n",l,slot1);
-    front_end_chanEst(ue,
-            l,
-            slot1,
-            0);
-    ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
-}
-LOG_I(PHY,"ChanEst symbol %d slot %d\n",0,next_subframe_slot0);
-front_end_chanEst(ue,
-        pilot0,
-        next_subframe_slot0,
-        0);
+  } // not an S-subframe
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 
-if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
-{
-  ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
-}
 #endif
 
-stop_meas(&ue->generic_stat);
-//printf("------Front-End PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
-/**** End Subframe FFT-ChannelEst ****/
+  LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
 
+  if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
+  {
+    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
+  }
 
-/**** Pdsch Procedure Slot0 + Slot1 ****/
-// start main thread for Pdsch Procedure (slot0)
-// do procedures for C-RNTI
-//LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
-//LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[subframe_rx&0x1][0][0]->active);
 
-start_meas(&ue->generic_stat);
-if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-    LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure PDSCH \n",frame_rx%1024,subframe_rx);
-  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&0x1][eNB_id][0],
-          NULL,
-          ue->pdcch_vars[subframe_rx & 0x1][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, VCD_FUNCTION_OUT);
-}
 
-// do procedures for SI-RNTI
-if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
-    LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure SI-PDSCH \n",frame_rx%1024,subframe_rx);
-  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[subframe_rx & 0x1][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);
-}
+  // 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) {
+    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);
+#endif
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0],
+			NULL,
+			1+(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);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat);
+    start_meas(&ue->dlsch_procedures_stat);
+#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_errors[eNB_id],
+			mode,
+			abstraction_flag);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->dlsch_procedures_stat);
+#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));
+#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));
+#endif
 
-// do procedures for SI-RNTI
-if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
-    LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure P-PDSCH \n",frame_rx%1024,subframe_rx);
-  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[subframe_rx & 0x1][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);
-}
+#endif
 
-// do procedures for RA-RNTI
-if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
-    LOG_I(PHY,"AbsSubframe %d.%d Pdsch Procedure RA-PDSCH \n",frame_rx%1024,subframe_rx);
-  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[subframe_rx & 0x1][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);
-}
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
 
-stop_meas(&ue->generic_stat);
-//printf("------LLR-Slot0  [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+  }
+#if UE_TIMING_TRACE
+  start_meas(&ue->generic_stat);
+#endif
 
-#if 1
-// start slave thread for Pdsch Procedure (slot1)
-// do procedures for C-RNTI
-
-if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-  start_meas(&ue->pdsch_procedures_stat);
-  ue_pdsch_procedures(ue,
-          proc,
-          eNB_id,
-          PDSCH,
-          ue->dlsch[subframe_rx&0x1][eNB_id][0],
-          NULL,
-          1+(ue->frame_parms.symbols_per_tti>>1),
-          ue->frame_parms.symbols_per_tti-1,
-          abstraction_flag);
-  stop_meas(&ue->pdsch_procedures_stat);
-}
+#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){
+       //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);
 
-// 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,
-          1+(ue->frame_parms.symbols_per_tti>>1),
-          ue->frame_parms.symbols_per_tti-1,
-          abstraction_flag);
-}
+       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);
 
-// 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,
-          1+(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,
-          1+(ue->frame_parms.symbols_per_tti>>1),
-          ue->frame_parms.symbols_per_tti-1,
-          abstraction_flag);
-}
-proc->llr_slot1_available=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("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);
+
+       AssertFatal (0,"");
+  }
 #endif
 
-start_meas(&ue->generic_stat);
-// wait until llr on slot1 are available
-uint32_t wait=0;
-while(proc->llr_slot1_available==0)
-{
-    //wait until channel estimation for pilot0/slot1 is available
-    usleep(1);
-    wait++;
-}
-stop_meas(&ue->generic_stat);
-//printf("------ Waiting for LLR-Slot1  [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
-
-LOG_I(PHY,"==> Start Turbo Decoder wait %d\n", wait);
-// Start Turbo decoder
-if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
-   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-   start_meas(&ue->dlsch_procedures_stat);
-   ue_dlsch_procedures(ue,
-           proc,
-           eNB_id,
-           PDSCH,
-           ue->dlsch[subframe_rx&0x1][eNB_id][0],
-           ue->dlsch[subframe_rx&0x1][eNB_id][1],
-           &ue->dlsch_errors[eNB_id],
-           mode,
-           abstraction_flag);
-   stop_meas(&ue->dlsch_procedures_stat);
-   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;
- }
- //printf("------ Turbo Decoding [SFN %d]: %5.2f ------\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
-
-/**** End Pdsch processing for this subframe ****/
-
-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]);
+  // 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,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+
+    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;
+  }
 
-    ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
-    ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
+  // 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,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+
+    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_pdsch_procedures(ue,
+      proc,
+      eNB_id,
+      RA_PDSCH,
+      ue->dlsch_ra[eNB_id],
+      NULL,
+      1+(ue->frame_parms.symbols_per_tti>>1),
+      ue->frame_parms.symbols_per_tti-1,
+      abstraction_flag);
+    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;
   }
 
+  // duplicate harq structure
 
-  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",
+  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];
+
+  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
+  #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
 
-}
+  }
 
-//printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#if UE_TIMING_TRACE
+  stop_meas(&ue->generic_stat);
+  printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 
 #ifdef EMOS
-phy_procedures_emos_UE_RX(ue,slot,eNB_id);
+  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);
-stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
 
-//printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0));
-LOG_I(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+#if UE_TIMING_TRACE
+  stop_meas(&ue->phy_proc_rx[subframe_rx%RX_NB_TH]);
+#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));
+#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));
+#endif
+#endif
 
-return (0);
+  LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+  return (0);
 }
-   
+
+#endif
+
 #if defined(Rel10) || defined(Rel14)
+
 int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
 {
-   
+
   int do_proc =0; // do nothing by default
-   
+
   switch(r_type) {
   case no_relay:
     do_proc=no_relay; // perform the normal UE operation
     break;
-     
+
   case multicast_relay:
     if (slot_rx > 12)
       do_proc = 0; // do nothing
     else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
       do_proc = multicast_relay ; // do PHY procedures UE RX
-     
+
     break;
-     
+
   default: // should'not be here
     LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
     do_proc= 0;
     break;
   }
-   
+
   return do_proc;
 }
 #endif
- 
- 
-void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
+
+void phy_procedures_UE_lte(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)
 {
 #if defined(ENABLE_ITTI)
@@ -5481,21 +5342,21 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
   unsigned int  Mod_id;
   int           result;
 #endif
-   
+
   int           frame_rx = proc->frame_rx;
   int           frame_tx = proc->frame_tx;
   int           subframe_rx = proc->subframe_rx;
   int           subframe_tx = proc->subframe_tx;
 #undef DEBUG_PHY_PROC
-   
+
   UE_L2_STATE_t ret;
   int slot;
 
   if (ue->mac_enabled == 0) {
     ue->UE_mode[eNB_id]=PUSCH;
   }
-   
-   
+
+
   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);
@@ -5505,61 +5366,61 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
   do {
     // Checks if a message has been sent to PHY sub-task
     itti_poll_msg (TASK_PHY_UE, &msg_p);
-     
+
     if (msg_p != NULL) {
       msg_name = ITTI_MSG_NAME (msg_p);
       instance = ITTI_MSG_INSTANCE (msg_p);
       Mod_id = instance - NB_eNB_INST;
-       
+
       switch (ITTI_MSG_ID(msg_p)) {
       case PHY_FIND_CELL_REQ:
-	LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
-	 
-	/* TODO process the message */
-	break;
-	 
+  LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
+
+  /* TODO process the message */
+  break;
+
       default:
-	LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
-	break;
+  LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
+  break;
       }
-       
+
       result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
       AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
     }
   } while(msg_p != NULL);
-   
+
 #endif
-   
+
   for (slot=0;slot<2;slot++) {
-     
+
     if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
-	(ue->frame_parms.frame_type == FDD)) {
+  (ue->frame_parms.frame_type == FDD)) {
       phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode,r_type);
     }
-     
+
     if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
-	(ue->frame_parms.frame_type == FDD)) {
+  (ue->frame_parms.frame_type == FDD)) {
 #if defined(Rel10) || defined(Rel14)
-       
+
       if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn);
     }
-     
+
     if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
-	(slot==1)) {
+  (slot==1)) {
       phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type);
     }
-       
+
     if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
-	(slot==0)) {
+  (slot==0)) {
 #if defined(Rel10) || defined(Rel14)
-	 
+
       if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn);
     }
-       
+
     if (ue->mac_enabled==1) {
       if (slot==0) {
         ret = mac_xface->ue_scheduler(ue->Mod_id,
@@ -5570,31 +5431,31 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
             subframe_select(&ue->frame_parms,subframe_tx),
             eNB_id,
             0/*FIXME CC_id*/);
-	   
-	if (ret == CONNECTION_LOST) {
-	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
-		frame_rx,subframe_tx);
-	  ue->UE_mode[eNB_id] = PRACH;
-	  //      mac_xface->macphy_exit("Connection lost");
-	} else if (ret == PHY_RESYNCH) {
-	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
-		ue->Mod_id,
-		frame_rx,subframe_tx);
-	  ue->UE_mode[eNB_id] = RESYNCH;
-	  //     mac_xface->macphy_exit("Connection lost");
-	} else if (ret == PHY_HO_PRACH) {
-	  LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
-		ue->Mod_id,frame_rx,subframe_tx);
-	  ue->UE_mode[eNB_id] = PRACH;
-	}
+
+  if (ret == CONNECTION_LOST) {
+    LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
+    frame_rx,subframe_tx);
+    ue->UE_mode[eNB_id] = PRACH;
+    //      mac_xface->macphy_exit("Connection lost");
+  } else if (ret == PHY_RESYNCH) {
+    LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
+    ue->Mod_id,
+    frame_rx,subframe_tx);
+    ue->UE_mode[eNB_id] = RESYNCH;
+    //     mac_xface->macphy_exit("Connection lost");
+  } else if (ret == PHY_HO_PRACH) {
+    LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
+    ue->Mod_id,frame_rx,subframe_tx);
+    ue->UE_mode[eNB_id] = PRACH;
+  }
       }
     }
-       
+
     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);
 #endif
   } // slot
 }
- 
- 
+
+
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 92e756fa7376ece8f4cdd0d79bf81e226cbcac74..6b46991e879b308d31124c7bee2ac2b3d4ddb7b3 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&0x1][eNB_id][0]->g_pucch;
+    ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->g_pucch);
+          ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[proc->subframe_rx%RX_NB_TH][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&0x1][eNB_id][0]->g_pucch);
+          ue->dlsch[proc->subframe_rx%RX_NB_TH][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 951b5f75f65c9450ee6b32f54308dff21a0c8af7..5613e0efc29ad3c4594074393f4f6b05e74d21b2 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -705,7 +705,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           dci_alloc[*num_dci].format     = format2A;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-          printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
+          //printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
           generate_eNB_dlsch_params_from_dci(0,
 					     subframe,
                                              &DLSCH_alloc_pdu_1[0],
@@ -846,7 +846,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           dci_alloc[*num_dci].firstCCE       = 0;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-          printf("Generating dlsch params for user %d\n",k);
+          //printf("Generating dlsch params for user %d\n",k);
           generate_eNB_dlsch_params_from_dci(0,
 					     subframe,
                                              &DLSCH_alloc_pdu_1[0],
@@ -866,7 +866,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
 
         }
 
-        printf("Generated DCI format 2A (Transmission Mode 3)\n");
+        //printf("Generated DCI format 2A (Transmission Mode 3)\n");
         break;
 
       case 4:
@@ -1292,7 +1292,6 @@ int main(int argc, char **argv)
   uint16_t tdd_config=3;
 
 
-
   SCM_t channel_model=Rayleigh1;
   //  unsigned char *input_data,*decoded_output;
 
@@ -1366,6 +1365,7 @@ int main(int argc, char **argv)
   int rballocset=0;
   int print_perf=0;
   int test_perf=0;
+  int test_passed=0;
   int dump_table=0;
 
   double effective_rate=0.0;
@@ -1391,10 +1391,13 @@ int main(int argc, char **argv)
 
   FILE *csv_fd=NULL;
   char csv_fname[32];
-  //int dci_flag=1;
+  int dci_flag=0;
   int two_thread_flag=0;
   int DLSCH_RB_ALLOC = 0;
 
+  int log_level = LOG_ERR;
+  int dci_received;
+
 #if defined(__arm__)
   FILE    *proc_fd = NULL;
   char buf[64];
@@ -1418,15 +1421,13 @@ int main(int argc, char **argv)
   //signal(SIGSEGV, handler);
   //signal(SIGABRT, handler);
 
-  logInit();
-
   // default parameters
   n_frames = 1000;
   snr0 = 0;
   //  num_layers = 1;
   perfect_ce = 0;
 
-  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXY")) != -1) {
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXYL:")) != -1) {
     switch (c) {
     case 'a':
       awgn_flag = 1;
@@ -1453,9 +1454,9 @@ int main(int argc, char **argv)
       Nid_cell = atoi(optarg);
       break;
 
-    //case 'd':
-    //  dci_flag = 1;
-    //  break;
+    case 'd':
+      dci_flag = 1;
+      break;
 
     case 'D':
       frame_type=TDD;
@@ -1482,7 +1483,7 @@ int main(int argc, char **argv)
     case 'i':
       input_fd = fopen(optarg,"r");
       input_file=1;
-      //dci_flag = 1;
+      dci_flag = 1;
       break;
 
     case 'I':
@@ -1722,7 +1723,9 @@ int main(int argc, char **argv)
       dump_table=1;
       break;
 
-
+    case 'L':
+      log_level=atoi(optarg);
+      break;
 
     case 'h':
     default:
@@ -1732,12 +1735,17 @@ int main(int argc, char **argv)
       printf("-c Number of PDCCH symbols\n");
       printf("-m MCS1 for TB 1\n");
       printf("-M MCS2 for TB 2\n");
-      printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n");
+      printf("-d Transmit the DCI and compute its error statistics\n");
       printf("-p Use extended prefix mode\n");
       printf("-n Number of frames to simulate\n");
       printf("-o Sample offset for receiver\n");
       printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step);
       printf("-f step size of SNR, default value is 1.\n");
+      printf("-C cell id\n");
+      printf("-S subframe\n");
+      printf("-D use TDD mode\n");
+      printf("-b TDD config\n");
+      printf("-B bandwidth configuration (in number of ressource blocks): 6, 25, 50, 100\n");
       printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
       printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n");
       printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
@@ -1757,6 +1765,16 @@ int main(int argc, char **argv)
     }
   }
 
+  logInit();
+  // enable these lines if you need debug info
+  set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
+  set_glog(log_level,LOG_HIGH);
+  // moreover you need to init itti with the following line
+  // however itti will catch all signals, so ctrl-c won't work anymore
+  // alternatively you can disable ITTI completely in CMakeLists.txt
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+
+
   if (common_flag == 0) {
     switch (N_RB_DL) {
     case 6:
@@ -2159,7 +2177,7 @@ int main(int argc, char **argv)
 	     TPC,
 	     mcs1,
 	     mcs2,
-	     0,
+	     1,
 	     0,
 	     &num_common_dci,
 	     &num_ue_spec_dci,
@@ -2318,10 +2336,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_errors[0] = 1;
-
-        while ((round < num_rounds) && (UE->dlsch_errors[0] > 0)) {
+        while ((round < num_rounds) && (UE->dlsch[subframe&0x1][eNB_id][0]->harq_ack[subframe].ack == 0)) {
 	  //	  printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
@@ -2361,11 +2379,12 @@ int main(int argc, char **argv)
 
                 eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
 
-		fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC,mcs1,mcs2,trials&1,round&3,&num_common_dci,&num_ue_spec_dci,&num_dci);
+		fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC,
+			 mcs1,mcs2,!(trials&1),round&3,&num_common_dci,&num_ue_spec_dci,&num_dci);
 	      }
 	      else {
 		fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC,
-			 (TB0_active==1)?mcs1:0,mcs2,trials&1,(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci);
+			 (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci);
 	      }
 	      for (i=num_common_dci; i<num_dci; i++) {
 
@@ -2419,7 +2438,7 @@ int main(int argc, char **argv)
 	    proc_eNB->subframe_tx = subframe;
 	    eNB->abstraction_flag=0;
 
-	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1);
+	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1,dci_flag);
 
 
 	    start_meas(&eNB->ofdm_mod_stats);
@@ -2455,7 +2474,7 @@ int main(int argc, char **argv)
 
 	    proc_eNB->subframe_tx = subframe+1;
 
-	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0);
+	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0,dci_flag);
 
 	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
 			  eNB->common_vars.txdata[eNB_id],
@@ -2496,7 +2515,7 @@ int main(int argc, char **argv)
 	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[subframe&1];
 	  proc->subframe_rx = subframe;
 	  UE->UE_mode[0] = PUSCH;
-	  UE->dlsch_errors[0] = 0;
+
 	  // first symbol has to be done separately in one-shot mode
 	  slot_fep(UE,
 		   0,
@@ -2506,12 +2525,46 @@ int main(int argc, char **argv)
 		   0);
 
 	  if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
-	  phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL);
 
-	  if (UE->dlsch[subframe&0x1][0][0]->active == 0) {
+	  if (dci_flag==0) {
+	    if (n_frames==1)
+	      printf("bypassing PDCCH/DCI detection\n");
+	    if  (generate_ue_dlsch_params_from_dci(proc->frame_rx,
+						   proc->subframe_rx,
+						   (void *)&dci_alloc[0].dci_pdu,
+						   n_rnti,
+						   dci_alloc[0].format,
+						   UE->dlsch[proc->subframe_rx&0x1][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],
+						   0)==0) {
+
+		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->pdcch_vars[proc->subframe_rx&0x1][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
+
+		UE->dlsch_received[eNB_id]++;
+	    } else {
+	      LOG_E(PHY,"Problem in DCI!\n");
+	    }
+	  }
+
+	  dci_received = UE->pdcch_vars[proc->subframe_rx & 0x1][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;
+
+	  if (dci_flag && (dci_received == 0)) {
 	    //printf("DCI not received\n");
 	    dci_errors[round]++;
-	    UE->dlsch_errors[0] = 1;
 
 	    /*
 	    write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
@@ -2582,7 +2635,7 @@ int main(int argc, char **argv)
 
 
 
-          if (UE->dlsch_errors[0] == 0) {
+          if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_ack[subframe].ack == 1) {
 
             avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt;
             iter_trials++;
@@ -2862,15 +2915,15 @@ int main(int argc, char **argv)
              errs2[0],
              round_trials[0],
              errs[1],
-             round_trials[0],
+             round_trials[1],
              errs[2],
-             round_trials[0],
+             round_trials[2],
              errs[3],
-             round_trials[0],
+             round_trials[3],
              (double)errs[0]/(round_trials[0]),
-             (double)errs[1]/(round_trials[0]),
-             (double)errs[2]/(round_trials[0]),
-             (double)errs[3]/(round_trials[0]),
+             (double)errs[1]/(round_trials[1]),
+             (double)errs[2]/(round_trials[2]),
+             (double)errs[3]/(round_trials[3]),
              dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3],
              round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
              (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]),
@@ -3193,9 +3246,11 @@ int main(int argc, char **argv)
         UE->dlsch_decoding_stats[subframe&1].trials);
         */
         printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
+	test_passed = 1;
         break;
       } else if (test_perf !=0 ) {
         printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
+	test_passed = 0;
       }
 
       if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
@@ -3246,8 +3301,10 @@ int main(int argc, char **argv)
     free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
   }
 
-
-  return(0);
+  if (test_perf && !test_passed)
+    return(-1);
+  else 
+    return(0);
 }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index 57742c5e13e4ec8d1f7fe13e0fe069a7ce1238c4..ee333ac74fecb9d2fed9a2692e0e878c31005d1d 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -56,10 +56,8 @@
 
 extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
 extern unsigned char offset_mumimo_llr_drange_fix;
-
-extern uint8_t interf_unaw_shift0;
-extern uint8_t interf_unaw_shift1;
-extern uint8_t interf_unaw_shift;
+extern int16_t dlsch_demod_shift;
+extern int16_t cond_num_threshold;
 
 #include "PHY/TOOLS/lte_phy_scope.h"
 
@@ -151,6 +149,8 @@ int main(int argc, char **argv)
   double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
   double iqim=0.0;
 
+  extern int use_sic_receiver;
+
   uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1, n_tx_phy=1, n_rx=1;
   uint16_t Nid_cell=0;
 
@@ -162,13 +162,19 @@ int main(int argc, char **argv)
   uint16_t tdd_config=3;
   uint16_t n_rnti=0x1234;
   int n_users = 1;
+  int active_tb0_sent[4]={0,0,0,0};
+  int active_tb1_sent[4]={0,0,0,0};
+  int failed_tb0[4]={0,0,0,0};
+  int failed_tb1[4]={0,0,0,0};
 
   int TB=0;
+
   RX_type_t rx_type=rx_standard;
   unsigned char  cur_harq_pid;
   int hold_rank1_precoder=0;
   int tpmi_retr=0;
   bool  is_first_time;
+  int rank_adapt =0;
   int updated_csi = 0;
 
   SCM_t channel_model=Rayleigh1;
@@ -195,6 +201,8 @@ int main(int argc, char **argv)
   char bler_fname[256];
   FILE *time_meas_fd;
   char time_meas_fname[256];
+  FILE *rankadapt_fd;
+  char rankadapt_fname[256];
 
   FILE *input_trch_fd=NULL;
   unsigned char input_trch_file=0;
@@ -251,6 +259,7 @@ int main(int argc, char **argv)
   FD_lte_phy_scope_ue *form_ue = NULL;
   char title[255];
   uint32_t DLSCH_RB_ALLOC = 0x1fff;
+  int log_level = LOG_ERR;
   int numCCE=0;
   int dci_length_bytes=0,dci_length=0;
   int common_flag=0,TPC=0;
@@ -258,6 +267,7 @@ int main(int argc, char **argv)
   double cpu_freq_GHz;
   //time_stats_t ts;//,sts,usts;
   int avg_iter[2],iter_trials[2];
+  int rank_indc[4]={0,0,0,0};
   int rballocset=0;
   int print_perf=0;
   int test_perf=0;
@@ -266,7 +276,8 @@ int main(int argc, char **argv)
 
   double effective_rate=0.0;
 
-  double thr_cw0_tm4 = 0.0;
+  double thr_cw0_tm4 = 0.0, throug_tb0=0.0, throug_tb1=0.0, throug_tb0_acc[4]={0,0,0,0}, throug_tb1_acc[4]={0,0,0,0}, throug_tb0_acc_aver[4]={0,0,0,0}, throug_tb1_acc_aver[4]={0,0,0,0};
+  double throug_tot_acc_aver[4]={0,0,0,0}, throug_tot_acc_aver_all_rounds=0;
   double thr_cw0_tm4_nonconst = 0.0;
   double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0;
   unsigned int tbs0_init=0, tbs1_init=0;
@@ -276,6 +287,7 @@ int main(int argc, char **argv)
 
   int TB0_active = 1;
   int TB1_active = 1;
+  int decoded_tb[2]={0,0};
 
   uint32_t perfect_ce = 0;
 
@@ -322,9 +334,6 @@ int main(int argc, char **argv)
   //signal(SIGSEGV, handler);
   //signal(SIGABRT, handler);
 
-  logInit();
-  set_glog(LOG_INFO, LOG_MED);
-
   // default parameters
   n_frames = 1000;
   snr0 = 0;
@@ -332,7 +341,7 @@ int main(int argc, char **argv)
   perfect_ce = 0;
 
 
-  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:U")) != -1) {
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:XYWv:V:J:K:UL:")) != -1) {
 
     switch (c) {
     case 'a':
@@ -397,10 +406,6 @@ int main(int argc, char **argv)
       input_trch_file=1;
       break;
 
-    case 'L':
-      llr8_flag=1;
-      break;
-
     case 'l':
       offset_mumimo_llr_drange_fix=atoi(optarg);
       break;
@@ -616,14 +621,14 @@ int main(int argc, char **argv)
       case 'Y':
         perfect_ce=1;
         break;
-      case 'V':
-        interf_unaw_shift0=atoi(optarg);
-        break;
       case 'W':
-        interf_unaw_shift1=atoi(optarg);
+        rank_adapt=1;
+        break;
+      case 'V':
+        cond_num_threshold = atoi(optarg);
         break;
       case 'J':
-        interf_unaw_shift=atoi(optarg);
+        dlsch_demod_shift = atoi(optarg);
         break;
       case 'K':
       tpmi_retr = atoi(optarg);
@@ -631,6 +636,9 @@ int main(int argc, char **argv)
       case 'U':
       updated_csi=1;
       break;
+      case 'L':
+      log_level=atoi(optarg);
+      break;
       case 'h':
       default:
       printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
@@ -664,6 +672,25 @@ int main(int argc, char **argv)
     }
   }
 
+  if (dlsch_demod_shift==0) {
+    if ((transmission_mode==3 || transmission_mode==4) && (rx_type>rx_standard)) {
+      if (mcs1<17)
+        dlsch_demod_shift=0;
+      else
+       dlsch_demod_shift=-2;
+    }
+  }
+
+
+  logInit();
+  // enable these lines if you need debug info
+  set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
+  set_glog(log_level,LOG_HIGH);
+  // moreover you need to init itti with the following line
+  // however itti will catch all signals, so ctrl-c won't work anymore
+  // alternatively you can disable ITTI completely in CMakeLists.txt
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+
   if (common_flag == 0) {
     switch (N_RB_DL) {
     case 6:
@@ -700,6 +727,12 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
+   if (transmission_mode==4 && rx_type == rx_SIC_dual_stream )
+    use_sic_receiver = 1;
+  else if (transmission_mode==4 && rx_type < rx_SIC_dual_stream )
+    use_sic_receiver = 0;
+
+
 
   if (xforms==1) {
   fl_initialize (&argc, argv, NULL, 0, 0);
@@ -707,15 +740,20 @@ int main(int argc, char **argv)
   sprintf (title, "LTE PHY SCOPE eNB");
   fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
 
-  /*
-  if (rx_type==rx_IC_single_stream) {
-    openair_daq_vars.use_ia_receiver = 1;
-    fl_set_button(form_ue->button_0,1);
-    fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+
+  if (transmission_mode==4 && use_sic_receiver == 1) {
+    use_sic_receiver = 1;
+    fl_set_button(form_ue->button_0, use_sic_receiver);
+    fl_set_object_label(form_ue->button_0, "SIC Receiver ON");
     fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+  }else if (transmission_mode==4 && use_sic_receiver == 0 ){
+    use_sic_receiver = 0;
+    fl_set_button(form_ue->button_0, use_sic_receiver);
+    fl_set_object_label(form_ue->button_0, "SIC Receiver OFF");
+    fl_set_object_color(form_ue->button_0, FL_RED, FL_RED);
   }
 
-  */
+
   }
 
   if (transmission_mode==5) {
@@ -746,9 +784,10 @@ int main(int argc, char **argv)
   printf("n_frames = %d\n",n_frames);
   printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
   printf("Using receiver type %d\n", rx_type);
-  printf("TM1 shift %d\n", interf_unaw_shift);
-  //printf("Using I_UA rec shift layer 1  %d\n", interf_unaw_shift0);
-  //printf("Using I_UA rec shift layer 2  %d\n", interf_unaw_shift1);
+  printf("dlsch_demod_shift %d\n", dlsch_demod_shift);
+  printf("rank adaptation %d\n", rank_adapt);
+  //printf("Using I_UA rec shift layer 1  %d\n", dlsch_demod_shift0);
+  //printf("Using I_UA rec shift layer 2  %d\n", dlsch_demod_shift1);
   snr1 = snr0+snr_int;
   printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
 
@@ -782,29 +821,53 @@ int main(int argc, char **argv)
     sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod);
   else if (abstx == 1){
     if (perfect_ce==1)
-      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,dlsch_demod_shift, tpmi_retr);
     else
-      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,dlsch_demod_shift, tpmi_retr);
   }
   else {//abstx=0
     if (perfect_ce==1){
       if (updated_csi==1){
-        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
       else{
-          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
     }
     else{
       if (updated_csi==1){
-        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
       else{
-          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
     }
   }
 
+  if (transmission_mode==3 || transmission_mode==4){
+    if (rank_adapt==1){
+      if (perfect_ce==1)
+        sprintf(rankadapt_fname,"rank_adapt1_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+      else
+        sprintf(rankadapt_fname,"rank_adapt1_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+    } else {
+        if (perfect_ce==1)
+          sprintf(rankadapt_fname,"rank_adapt0_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+        else
+          sprintf(rankadapt_fname,"rank_adapt0_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+    }
+
+  rankadapt_fd = fopen(rankadapt_fname,"w");
+    if (rankadapt_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",rankadapt_fname);
+      exit(-1);
+    }
+    if (rx_type == rx_SIC_dual_stream)
+      fprintf(rankadapt_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    else
+      fprintf(rankadapt_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+  }
+
   bler_fd = fopen(bler_fname,"w");
   if (bler_fd==NULL) {
     fprintf(stderr,"Cannot create file %s!\n",bler_fname);
@@ -812,11 +875,13 @@ int main(int argc, char **argv)
   }
 
   if ((transmission_mode != 3) && (transmission_mode != 4))
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n");
+    fprintf(bler_fd,"SNR; MCS1; TBS1; rate 0; err0; trials0; err1;trials1; err2;trials2; err3; trials3\n");
   else if (rx_type == rx_SIC_dual_stream)
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    fprintf(bler_fd,"SNR; rank_adapt; rank; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
   else
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    fprintf(bler_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+
+
 
   if (test_perf != 0) {
 
@@ -845,9 +910,9 @@ int main(int argc, char **argv)
 
     else
       if (perfect_ce==1)
-        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, dlsch_demod_shift, n_ch_rlz);
       else
-        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, dlsch_demod_shift, n_ch_rlz);
 
     csv_fd = fopen(csv_fname,"w");
     fprintf(csv_fd,"data_all%d=[",mcs1);
@@ -943,6 +1008,10 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
+  if ((transmission_mode == 3) && (transmission_mode == 4))
+    for (n=0; n<4; ++n)
+      rank_indc[n]=1;
+
   if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8))
     Kmimo=2;
   else
@@ -2048,7 +2117,6 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-
       UE->proc.proc_rxtx[0].frame_rx=0;
       for (i=0; i<4; i++) {
         errs[0][i]=0; //CW_0
@@ -2062,6 +2130,17 @@ int main(int argc, char **argv)
         round_trials[1][i] = 0;  // CW_1
         TB0_deact[i]=0;
         TB1_deact[i]=0;
+        throug_tb0_acc[i] = 0;
+        throug_tb1_acc[i] = 0;
+        throug_tb0_acc_aver[i]=0;
+        throug_tb1_acc_aver[i]=0;
+        throug_tot_acc_aver[i]=0;
+        active_tb0_sent[i]=0;
+        active_tb1_sent[i]=0;
+        failed_tb0[i]=0;
+        failed_tb1[i]=0;
+        throug_tot_acc_aver_all_rounds=0;
+
       }
       dci_errors=0;
 
@@ -2072,6 +2151,9 @@ int main(int argc, char **argv)
       iter_trials[0]=0;
       iter_trials[1]=0;
 
+      uint32_t clsm_counter=0;
+      uint32_t two_tb_flag=0;
+
       reset_meas(&eNB->phy_proc_tx); // total eNB tx
       reset_meas(&eNB->dlsch_scrambling_stats);
       reset_meas(&UE->dlsch_unscrambling_stats);
@@ -2128,7 +2210,7 @@ int main(int argc, char **argv)
         is_first_time = true;
 #ifdef DEBUG_HARQ
         printf("[DLSIM] TRIAL %d\n", trials);
-        printf("TPMI_retr= %d\n", tpmi_retr);
+        printf("[DLSIM] TPMI_retr= %d\n", tpmi_retr);
 #endif
 
         for (i=0; i<frame_parms->nb_antennas_tx; i++) {
@@ -2145,18 +2227,28 @@ int main(int argc, char **argv)
         TB0_active=1;
         TB1_active=1;
 
+
+        if (transmission_mode == 3 || transmission_mode == 4)
+          rank_indc[0]=1;
+
         while (((transmission_mode == 3 || transmission_mode == 4) &&
-               ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) ||
-               (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) ||
+               ((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 )))) ||
                ((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);
+
 #ifdef DEBUG_HARQ
         printf("\n [DLSIM] On top round is %d\n", round);
 #endif
 
-
           round_trials[0][round]++;
           round_trials[1][round]++;
+          decoded_tb[0]=0;
+          decoded_tb[1]=0;
 
           //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]);
 
@@ -2212,9 +2304,19 @@ int main(int argc, char **argv)
                   eNB->dlsch[0][1]->harq_processes[0]->rvidx = round&3;
 
               if (round == 0) {   // First round
-                TB0_active = 1;
-                TB1_active = 1;
-
+                if ((rank_indc[0]==1) || (rank_indc[0]==0 && rank_adapt==0)) {
+                  TB0_active = 1;
+                  TB1_active = 1;
+#ifdef DEBUG_HARQ
+                  printf("Simulating HARQ both active \n");
+#endif
+                }else {
+                  TB0_active = 1;
+                  TB1_active = 0;
+#ifdef DEBUG_HARQ
+                  printf("Simulating HARQ only TB0 active \n");
+#endif
+                }
                 if (eNB->frame_parms.frame_type == TDD) {
 
                   switch (transmission_mode) {
@@ -2276,47 +2378,98 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                     case 6:
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
-                      break;
-                    case 25:
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
-                      break;
-                    case 50:
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
-                      break;
-                    case 100:
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
-                      break;
+                    if ((TB0_active == 1) && (TB1_active == 1)) {
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                          break;
+                        }
+                    } else if ((TB0_active == 1) && (TB1_active == 0)) {
+                       switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                          break;
+                        }
+                        generate_eNB_dlsch_params_from_dci(0,
+                                                         subframe,
+                                                         &DLSCH_alloc_pdu_1[0],
+                                                         n_rnti+k,
+                                                         format2,
+                                                         eNB->dlsch[0],
+                                                         &eNB->frame_parms,
+                                                         eNB->pdsch_config_dedicated,
+                                                         SI_RNTI,
+                                                         0,
+                                                         P_RNTI,
+                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                         transmission_mode>=7?transmission_mode:0
+                                                         );
                     }
                     break;
                   case 5:
@@ -2326,8 +2479,7 @@ int main(int argc, char **argv)
                     memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
                     break;
                   }
-                }
-                else { // FDD
+                } else { // FDD
                   switch (transmission_mode) {
                     case 1:
                     case 2:
@@ -2387,49 +2539,101 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                     case 6:
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
-                      break;
-                    case 25:
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
-                      break;
-                    case 50:
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
-                      break;
-                    case 100:
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
-                      break;
+                    if ((TB0_active == 1) && (TB1_active == 1)) {
+                      switch (eNB->frame_parms.N_RB_DL) {
+                       case 6:
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+                        break;
+                      case 25:
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                        break;
+                      case 50:
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                        break;
+                      case 100:
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                        break;
+                      }
+                    } else if ((TB0_active == 1) && (TB1_active == 0)) {
+                       switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                          break;
+                        }
                     }
+                    generate_eNB_dlsch_params_from_dci(0,
+                                                       subframe,
+                                                       &DLSCH_alloc_pdu_1[0],
+                                                       n_rnti+k,
+                                                       format2,
+                                                       eNB->dlsch[0],
+                                                       &eNB->frame_parms,
+                                                       eNB->pdsch_config_dedicated,
+                                                       SI_RNTI,
+                                                       0,
+                                                       P_RNTI,
+                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
                     break;
+
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2557,134 +2761,179 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                    if ((rank_indc[0]==1 )|| ((rank_indc[0]==0) && (rank_adapt==0))){
+                      switch (eNB->frame_parms.N_RB_DL) {
+                      case 6:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr; // you have choice
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                         }
-                      else {  // deactivate TB1
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
-                      break;
-                    case 25:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] Requesting only TB1 from temp DCI\n");
-#endif
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] TDD Requesting only TB0 from temp DCI\n");
-#endif
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
-                      generate_eNB_dlsch_params_from_dci(0,
-                                                         subframe,
-                                                         &DLSCH_alloc_pdu_1[0],
-                                                         n_rnti+k,
-                                                         format2,
-                                                         eNB->dlsch[0],
-                                                         &eNB->frame_parms,
-                                                         eNB->pdsch_config_dedicated,
-                                                         SI_RNTI,
-                                                         0,
-                                                         P_RNTI,
-                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
-                                                         transmission_mode>=7?transmission_mode:0
-                                                         );
-                      break;
-                    case 50:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
-                      break;
-                    case 100:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                          }
+                        else {  // deactivate TB1
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                        break;
+                      case 25:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                        break;
+                      case 50:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                        break;
+                      case 100:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                        break;
                       }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
-                      break;
+                        generate_eNB_dlsch_params_from_dci(0,
+                                                           subframe,
+                                                           &DLSCH_alloc_pdu_1[0],
+                                                           n_rnti+k,
+                                                           format2,
+                                                           eNB->dlsch[0],
+                                                           &eNB->frame_parms,
+                                                           eNB->pdsch_config_dedicated,
+                                                           SI_RNTI,
+                                                           0,
+                                                           P_RNTI,
+                                                           UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                           transmission_mode>=7?transmission_mode:0
+                                                           );
+                    } else if (rank_indc[0]==0 && rank_adapt==1) {
+                      //in this case only TB0 is active for the retransmissions, deactivatiing TB1
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0; //no choice, only alamouti
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                        break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                        break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                        break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                           memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                        break;
                     }
+                    generate_eNB_dlsch_params_from_dci(0,
+                                                       subframe,
+                                                       &DLSCH_alloc_pdu_1[0],
+                                                       n_rnti+k,
+                                                       format2,
+                                                       eNB->dlsch[0],
+                                                       &eNB->frame_parms,
+                                                       eNB->pdsch_config_dedicated,
+                                                       SI_RNTI,
+                                                       0,
+                                                       P_RNTI,
+                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  }
                     break;
-
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2785,6 +3034,7 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
+                  if ((rank_indc[0]==1 )|| ((rank_indc[0]==0) && (rank_adapt==0))){
                     switch (eNB->frame_parms.N_RB_DL) {
                     case 6:
                       if (TB0_active == 1 && TB1_active == 1) {
@@ -2823,9 +3073,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                       }
                       else if (TB0_active == 0){  // deactivate TB0
-#ifdef DEBUG_HARQ
-                        printf("\n [DLSIM] Requesting only TB1 from temp DCI\n");
-#endif
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
@@ -2833,9 +3080,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                       }
                       else {  // deactivate TB1
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] FDD Requesting only TB0 from temp DCI\n");
-#endif
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
@@ -2843,20 +3087,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
                       }
                       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
-                      generate_eNB_dlsch_params_from_dci(0,
-                                                         subframe,
-                                                         &DLSCH_alloc_pdu_1[0],
-                                                         n_rnti+k,
-                                                         format2,
-                                                         eNB->dlsch[0],
-                                                         &eNB->frame_parms,
-                                                         eNB->pdsch_config_dedicated,
-                                                         SI_RNTI,
-                                                         0,
-                                                         P_RNTI,
-                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
-                                                         transmission_mode>=7?transmission_mode:0
-                                                         );
                       break;
                     case 50:
                       if (TB0_active == 1 && TB1_active == 1) {
@@ -2911,9 +3141,72 @@ int main(int argc, char **argv)
                       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
                       break;
                     }
-                    break;
-
-
+                    generate_eNB_dlsch_params_from_dci(0,
+                                                       subframe,
+                                                       &DLSCH_alloc_pdu_1[0],
+                                                       n_rnti+k,
+                                                       format2,
+                                                       eNB->dlsch[0],
+                                                       &eNB->frame_parms,
+                                                       eNB->pdsch_config_dedicated,
+                                                       SI_RNTI,
+                                                       0,
+                                                       P_RNTI,
+                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  } else if (rank_indc[0]==0 && rank_adapt==1) {
+                      //in this case only TB0 is active for the retransmissions, deactivatiing TB1
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0; //no choice, only alamouti
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+                        break;
+                        case 25:
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                        break;
+                        case 50:
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                        break;
+                        case 100:
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                           memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                        break;
+                    }
+                    generate_eNB_dlsch_params_from_dci(0,
+                                                       subframe,
+                                                       &DLSCH_alloc_pdu_1[0],
+                                                       n_rnti+k,
+                                                       format2,
+                                                       eNB->dlsch[0],
+                                                       &eNB->frame_parms,
+                                                       eNB->pdsch_config_dedicated,
+                                                       SI_RNTI,
+                                                       0,
+                                                       P_RNTI,
+                                                       UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  }
+                  break;
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2996,17 +3289,20 @@ 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);
+#endif
 
                 //if standard case when both TBs are active
                 if (transmission_mode == 4) {
                   if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && TB0_active == 1 && TB1_active == 1){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
 
                     eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      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);
@@ -3016,22 +3312,22 @@ int main(int argc, char **argv)
 
                     if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
                       eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,5,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      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);
                     }
 
                     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))){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
                       eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,6,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      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);
                     }
@@ -3081,6 +3377,9 @@ int main(int argc, char **argv)
 
                 }
             }
+#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);
+#endif
 
                 start_meas(&eNB->dlsch_encoding_stats);
                 if (dlsch_encoding(eNB,
@@ -3165,7 +3464,7 @@ int main(int argc, char **argv)
                           (subframe*2)+2,
                           &eNB->frame_parms);
 
-            if (n_frames==1) {
+            if (n_frames==2) {
               write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
               if (eNB->frame_parms.nb_antennas_tx>1)
                 write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
@@ -3179,7 +3478,7 @@ int main(int argc, char **argv)
             }
             tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
 
-            if (n_frames==1) {
+            if (n_frames==2) {
               write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
               if (eNB->frame_parms.nb_antennas_tx>1)
                 write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
@@ -3310,13 +3609,23 @@ int main(int argc, char **argv)
         }
 
         //AWGN
-	// tx_lev is the average energy over the whole subframe
-	// but SNR should be better defined wrt the energy in the reference symbols
-	sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR;
+  // tx_lev is the average energy over the whole subframe
+  // but SNR should be better defined wrt the energy in the reference symbols
+  sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR;
         sigma2 = pow(10,sigma2_dB/10);
         if (n_frames==1)
           printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated));
 
+        for (i=0; i<10*frame_parms->samples_per_tti; i++) {
+          for (aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++) {
+            //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
+            ((short*) UE->common_vars.rxdata[aa])[2*i] =
+              (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+            ((short*) UE->common_vars.rxdata[aa])[2*i+1] =
+              (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+          }
+        }
+
         for (i=0; i<2*frame_parms->samples_per_tti; i++) {
           for (aa=0;aa<eNB->frame_parms.nb_antennas_rx;aa++) {
             //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
@@ -3370,7 +3679,7 @@ int main(int argc, char **argv)
           for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) {
             for (l=0;l<pilot2;l++) {
               if (n_frames==1)
-          printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
+         // printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
               /*
           This function implements the OFDM front end processor (FEP).
 
@@ -3435,11 +3744,19 @@ int main(int argc, char **argv)
               }
 
               if ((Ns==((2*subframe))) && (l==0)) {
+                /*ue_rrc_measurements(UE,
+                                    0,
+                                    0);*/
                 lte_ue_measurements(UE,
                                     subframe*UE->frame_parms.samples_per_tti,
                                     1,
                                     0,
+                                    rank_adapt,
                                     subframe);
+
+                if ((transmission_mode == 3) || (transmission_mode == 4))
+                  rank_indc[round] = UE->measurements.rank[0];
+
                 //printf ("Trial %d, Measurements are done \n", trials);
                       /*
                         debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
@@ -3597,6 +3914,18 @@ int main(int argc, char **argv)
                         UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
                         UE->dlsch[subframe&0x1][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);
+#endif
+
+                   if (transmission_mode==4 && use_sic_receiver==1){
+                    if (rx_type>rx_IC_single_stream)
+                      rx_type=rx_SIC_dual_stream;
+                  }
+                  else if (transmission_mode==4 && use_sic_receiver==0){
+                    if (rx_type>rx_IC_single_stream)
+                      rx_type=rx_IC_dual_stream;
+                }
 
                       switch (transmission_mode) {
                       case 1:
@@ -3648,7 +3977,6 @@ int main(int argc, char **argv)
                                                           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);
-
                         break;
                       case 5:
                       case 6:
@@ -3775,15 +4103,14 @@ int main(int argc, char **argv)
               printf("[DLSIM] Skip TB0 \n");
 #endif
               TB++;
-
             }
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] process TB %d \n", TB);
+            printf("[DLSIM] process TB %d Kmimo %d \n", TB, Kmimo);
 #endif
 
             if (TB==1 && TB1_active == 0){
 #ifdef DEBUG_HARQ
-              printf("[DLSIM] Skip TB1 \n");
+              printf("[DLSIM] Skip TB1 round %d\n", round);
 #endif
               break;
             }
@@ -3844,21 +4171,25 @@ int main(int argc, char **argv)
                                0,
                                UE->dlsch[subframe&0x1][0][TB],
                                coded_bits_per_codeword[TB],
-                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],
+                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[TB],
                                TB,
                                subframe<<1);
             stop_meas(&UE->dlsch_unscrambling_stats);
 
             start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+#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);
+#endif
             ret[TB] = dlsch_decoding(UE,
-                                     UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],
+                                     UE->pdsch_vars[subframe&0x1][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],
                                      0,
-                                    subframe,
-                                    UE->dlsch[subframe&0x1][0][TB]->current_harq_pid,
-                                    1,llr8_flag);
+                                     subframe,
+                                     UE->dlsch[subframe&0x1][0][TB]->current_harq_pid,
+                                     1,
+                                     llr8_flag);
             stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
 #ifdef DEBUG_HARQ
             printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]);
@@ -3870,6 +4201,7 @@ int main(int argc, char **argv)
 
 
             if (ret[TB] <= UE->dlsch[subframe&0x1][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);
 #endif
@@ -3877,7 +4209,7 @@ int main(int argc, char **argv)
                 /*avg_iter[TB] += ret[TB];
                 iter_trials[TB]++;*/
 
-              if (n_frames==2) {
+              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++) {
@@ -4003,12 +4335,10 @@ int main(int argc, char **argv)
                   (rx_type==rx_SIC_dual_stream)) {
 #ifdef DEBUG_HARQ
                 printf("[DLSIM] Starting SIC procedure\n");
+                printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round);
+                printf("\n CW 0 is decoded, i go for , round %d\n", round);
+                printf("\n ret[TB0] = %d  round %d\n", ret[TB], round);
 #endif
-               // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round);
-
-
-              //printf("\n CW 0 is decoded, i go for , round %d\n", round);
-              //printf("\n ret[TB0] = %d  round %d\n", ret[TB], round);
                 sic_attempt[round]++;
 
                 for (round_sic = 0 ; round_sic < (round +1); round_sic++) {
@@ -4025,38 +4355,29 @@ int main(int argc, char **argv)
                 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;
-                dlsch0_eNB_harq->rvidx        = dlsch0_ue_harq->rvidx;
+                dlsch0_eNB_harq->rvidx        = round_sic;//dlsch0_ue_harq->rvidx;
+                //printf("dlsch0_eNB_harq->rvidx = %d \n", dlsch0_eNB_harq->rvidx);
                 dlsch0_eNB_harq->Nl           = dlsch0_ue_harq->Nl;
-                dlsch0_eNB_harq->round        = dlsch0_ue_harq->round;
+                dlsch0_eNB_harq->round        = round_sic; //dlsch0_ue_harq->round;
                 dlsch0_eNB_harq->TBS          = dlsch0_ue_harq->TBS;
                 dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
                 dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-                if (round_sic == 0){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 0;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=0;
-                }
-                  else if (round_sic == 1){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 1;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=1;
-                }
-                  else if (round_sic == 2){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 2;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=2;
-                }
-                  else{
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 3;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=3;
-                }
+                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]->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;
-
+#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);
+#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,,
                                num_pdcch_symbols,
-                               UE->dlsch_eNB[eNB_id],
+                               &UE->dlsch_eNB[0][0],
                                0,
                                subframe,
                                &UE->dlsch_rate_matching_stats,
@@ -4076,7 +4397,7 @@ int main(int argc, char **argv)
 
                 dlsch_scrambling(&UE->frame_parms,
                                  0,
-                                 UE->dlsch_eNB[eNB_id],
+                                 &UE->dlsch_eNB[0][0],
                                  coded_bits_per_codeword[0],
                                  0,
                                  subframe<<1);
@@ -4100,47 +4421,44 @@ 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][0]->current_harq_pid][round_sic],
+                                       UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][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][0]->current_harq_pid][round_sic],
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                       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],
                                        num_pdcch_symbols,
                                        dlsch0_eNB_harq->nb_rb,
                                        subframe,
-                                       dlsch0_eNB_harq->rb_alloc[0],
                                        get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
-                                       UE->dlsch[subframe&0x1][eNB_id][0]);
+                                       dlsch0_eNB_harq->rb_alloc[0]);
                   break;
 
                   case 4:
 
                     dlsch_16qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][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][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        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],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][1]->current_harq_pid][round_sic],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
-                                        dlsch0_eNB_harq->rb_alloc[0],
-                                        get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs),
-                                        UE->dlsch[subframe&0x1][eNB_id][0]);
+                                        get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+                                        dlsch0_eNB_harq->rb_alloc[0]);
                   break;
                   case 6:
                     dlsch_64qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][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][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        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],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        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],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
-                                        dlsch0_eNB_harq->rb_alloc[0],
                                         get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
-                                        UE->dlsch[subframe&0x1][eNB_id][TB]);
+                                        dlsch0_eNB_harq->rb_alloc[0]);
                   break;
                     }
                   //}// rouns sic
@@ -4165,7 +4483,7 @@ int main(int argc, char **argv)
                   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);
 
-                  if (n_frames==2) {
+                  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);
 
@@ -4203,7 +4521,7 @@ int main(int argc, char **argv)
                                    0,
                                    UE->dlsch[subframe&0x1][0][1],
                                    coded_bits_per_codeword[1],
-                                   UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                   UE->pdsch_vars[subframe&0x1][eNB_id]->llr[1],
                                    1,
                                    subframe<<1);
                 stop_meas(&UE->dlsch_unscrambling_stats);
@@ -4211,7 +4529,7 @@ int main(int argc, char **argv)
                 start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
 
                 ret[1] = dlsch_decoding(UE,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        UE->pdsch_vars[subframe&0x1][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],
@@ -4228,6 +4546,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 ) {
+                  decoded_tb[1]=1;
                   decoded_in_sic[round]++;
                   round_sic = round+1; // to exit round_sic
 #ifdef DEBUG_HARQ
@@ -4237,7 +4556,7 @@ int main(int argc, char **argv)
                   iter_trials[1]++;
 
 
-                  if (n_frames==2) {
+                  if (n_frames==1) {
                     printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
 
                     #ifdef PRINT_BYTES
@@ -4262,6 +4581,7 @@ int main(int argc, char **argv)
 
 
             if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){
+              decoded_tb[1]=0;
               errs[1][round]++;
 #ifdef DEBUG_HARQ
                   printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]);
@@ -4272,7 +4592,7 @@ int main(int argc, char **argv)
                   avg_iter[1] += ret[1]-1;
                   iter_trials[1]++;
 
-                  if (n_frames==2) {
+                  if (n_frames==1) {
                     //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
@@ -4296,6 +4616,10 @@ int main(int argc, char **argv)
             }//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++;
+
+            decoded_tb[TB]=0;
             errs[TB][round]++;
 #ifdef DEBUG_HARQ
             printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", TB, TB, round, errs[TB][round]);
@@ -4323,7 +4647,7 @@ int main(int argc, char **argv)
               }*/
 
 
-              if (n_frames==2) {
+              if (n_frames==1) {
           //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
@@ -4349,7 +4673,7 @@ int main(int argc, char **argv)
 
           stop_meas(&UE->phy_proc_rx[subframe&0x1]);
 
-          if (n_frames==1) {
+          if (n_frames==4) {
 
             //rxsig
             sprintf(fname,"rxsig0_r%d.m",round);
@@ -4444,66 +4768,139 @@ int main(int argc, char **argv)
             round++;
           }
 
+         /* if ((rank_indc[0]==0) && (rank_adapt==1))
+            errs[1][0]++;*/
+
 
           if (transmission_mode == 3 || transmission_mode == 4 ) {
-            if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-               ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
-              resend_both[round]++;
-              round++;
-              resend_cw0_cw1=1;  //resend both cws
-              resend_cw1=0;
-              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){
-              resend_one[round]++;
-              resend_cw0_cw1=0;
-              TB0_active=0;
-              TB1_active=1;
-              if (rx_type == rx_IC_dual_stream)
-                TB0_deact[round]++;
-              if(is_first_time) {
-                hold_rank1_precoder = 0;
-                is_first_time = false;
+
+              if (TB0_active==1)
+                active_tb0_sent[round]++;
+
+              if (TB1_active==1)
+                active_tb1_sent[round]++;
+
+              if (TB0_active==1 && decoded_tb[0]==0)
+                failed_tb0[round]++;
+
+              if (TB1_active==1 && decoded_tb[1]==0)
+                failed_tb1[round]++;
+
+              if (round==0){
+                if (rank_adapt==1){
+                  if (rank_indc[0]==1)
+                    clsm_counter++;
+                  }
               }
-              else
-                hold_rank1_precoder = 1;
 
+            if (rank_indc[0]==1 || (rank_indc[0]==0 && rank_adapt==0)){
+              if ((TB0_active==1) && (decoded_tb[0]==1)){
+                throug_tb0=rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/(round+1);
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
-            printf("[DLSIM] TB0 deactivated\n");
+                printf("rank 2 round %d, TB0 contributes to throughput throug_tb0 %f \n", round, throug_tb0 );
 #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){
-              resend_one[round]++;
-              resend_cw0_cw1=0;
-              TB0_active=1;
-              TB1_active=0;
-              if (rx_type == rx_IC_dual_stream)
-                TB1_deact[round]++;
-              if(is_first_time) {
-                hold_rank1_precoder = 0;
-                is_first_time = false;
+              } else if (((TB0_active==1) && (decoded_tb[0]==0)) || (TB0_active==0)){
+                throug_tb0=0;
+              }
+              throug_tb0_acc[round]+=throug_tb0;
+            } else if ((rank_indc[0]==0) && (rank_adapt==1)){
+                if ((TB0_active==1) && (decoded_tb[0]==1)){
+                  throug_tb0=rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/(round+1);
+#ifdef DEBUG_HARQ
+                  printf("rank 1 round %d, TB0 contributes to throughput throug_tb0 %f \n", round, throug_tb0 );
+#endif
+                } else if (((TB0_active==1) && (decoded_tb[0]==0)) || (TB0_active==0)){
+                  throug_tb0=0;
+                }
+                throug_tb0_acc[round]+=throug_tb0;
               }
-              else
-                hold_rank1_precoder = 1;
 
+            if (rank_indc[0]==1 || (rank_indc[0]==0 && rank_adapt==0)){
+              if ((TB1_active==1) && (decoded_tb[1]==1)){
+                throug_tb1=rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/(round+1);
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
-            printf("[DLSIM] TB1 deactivated\n");
+                printf("rank 2 round %d, TB1 contributes to throughput throug_tb1 %f \n", round, throug_tb1 );
 #endif
-            round++;
+              } else if (((TB1_active==1) && (decoded_tb[1]==0)) || (TB1_active==0)){
+                throug_tb1=0;
+              }
+              throug_tb1_acc[round]+=throug_tb1;
+              }
+
+            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){
+                resend_both[round]++;
+                round++;
+                resend_cw0_cw1=1;  //resend both cws
+                resend_cw1=0;
+                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){
+                resend_one[round]++;
+                resend_cw0_cw1=0;
+                TB0_active=0;
+                TB1_active=1;
+                if (rx_type == rx_IC_dual_stream)
+                  TB0_deact[round]++;
+                if(is_first_time) {
+                  hold_rank1_precoder = 0;
+                  is_first_time = false;
+                }
+                else
+                  hold_rank1_precoder = 1;
+
+#ifdef DEBUG_HARQ
+              printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+              printf("[DLSIM] TB0 deactivated\n");
+#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){
+                resend_one[round]++;
+                resend_cw0_cw1=0;
+                TB0_active=1;
+                TB1_active=0;
+                if (rx_type == rx_IC_dual_stream)
+                  TB1_deact[round]++;
+                if(is_first_time) {
+                  hold_rank1_precoder = 0;
+                  is_first_time = false;
+                }
+                else
+                  hold_rank1_precoder = 1;
+
+  #ifdef DEBUG_HARQ
+              printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+              printf("[DLSIM] TB1 deactivated\n");
+  #endif
+                round++;
+              }
+            } else if (rank_indc[0] == 0 && rank_adapt == 1){
+#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){
+                  resend_one[round]++;
+                  round++;
+                  resend_cw0_cw1=0;  //resend both cws
+                  resend_cw1=0;
+                  TB0_active=1;
+                  TB1_active=0;
+                }
             }
+
           }
 
+
 #ifdef DEBUG_HARQ
           printf("[DLSIM] Now round is %d, trial %d\n" , round, trials);
 #endif
-        }
 
+        }
 
         if(transmission_mode != 3 && transmission_mode !=4 ){
           if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) )
@@ -4561,9 +4958,9 @@ int main(int argc, char **argv)
               push_front(&time_vector_rx_demod, t_rx_demod);
               push_front(&time_vector_rx_dec, t_rx_dec);
 
-
             }   //trials
 
+
 #ifdef DEBUG_HARQ
         printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]);
         printf(" only one failed round 0  = %d, only one failed round 1  = %d, only one failed round 2  = %d, only one failed round 3  = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]);
@@ -4680,6 +5077,31 @@ int main(int argc, char **argv)
       */
 
       if (transmission_mode == 3 || transmission_mode == 4) {
+
+          throug_tb0_acc_aver[0]=throug_tb0_acc[0]/(double)round_trials[1][0];//active_tb0_sent[0];
+
+          throug_tb0_acc_aver[1]=throug_tb0_acc[1]/(double)round_trials[1][0];//active_tb0_sent[1];
+
+          throug_tb0_acc_aver[2]=throug_tb0_acc[2]/(double)round_trials[1][0];//active_tb0_sent[2];
+
+          throug_tb0_acc_aver[3]=throug_tb0_acc[3]/(double)round_trials[1][0];//active_tb0_sent[3];
+
+          throug_tb1_acc_aver[0]=throug_tb1_acc[0]/(double)round_trials[1][0];//active_tb1_sent[0];
+
+          throug_tb1_acc_aver[1]=throug_tb1_acc[1]/(double)round_trials[1][0];//active_tb1_sent[1];
+
+          throug_tb1_acc_aver[2]=throug_tb1_acc[2]/(double)round_trials[1][0];//active_tb1_sent[2];
+
+          throug_tb1_acc_aver[3]=throug_tb1_acc[3]/(double)round_trials[1][0];//active_tb1_sent[3];
+
+          throug_tot_acc_aver[0]= throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0];
+          throug_tot_acc_aver[1]= throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1];
+          throug_tot_acc_aver[2]= throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2];
+          throug_tot_acc_aver[3]= throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3];
+          throug_tot_acc_aver_all_rounds= throug_tot_acc_aver[0]+throug_tot_acc_aver[1]+throug_tot_acc_aver[2]+throug_tot_acc_aver[3];
+
+
+
         // FOR CW0
         thr_cw0[0] = rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]));
         if (num_rounds > 1)
@@ -4698,17 +5120,25 @@ int main(int argc, char **argv)
 #ifdef PRINT_THROUGHPUT
         printf("rate  %f \n", rate0_init);
         printf("rate*mod_order  %f \n", rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs));
-        printf("Probability  %f \n", (1-((double)errs[0][0]/(double)round_trials[0][0])));
         printf("Throughput cw0 sum =  %f \n", thr_cw0_tot);
         printf("Throughput cw0 round 0 =  %f \n", thr_cw0[0]);
         printf("Throughput cw0 round 1 =  %f \n", thr_cw0[1]);
         printf("Throughput cw0 round 2 =  %f \n", thr_cw0[2]);
         printf("Throughput cw0 round 3 =  %f \n", thr_cw0[3]);
+        printf("Accumulated throughput  TB0 round 0 =  %f \n", throug_tb0_acc_aver[0]);
+        printf("Accumulated throughput  TB0 round 1 =  %f \n", throug_tb0_acc_aver[1]);
+        printf("Accumulated throughput  TB0 round 2 =  %f \n", throug_tb0_acc_aver[2]);
+        printf("Accumulated throughput  TB0 round 3 =  %f \n", throug_tb0_acc_aver[3]);
+        printf("Accumulated throughput  TB1 round 0 =  %f \n", throug_tb1_acc_aver[0]);
+        printf("Accumulated throughput  TB1 round 1 =  %f \n", throug_tb1_acc_aver[1]);
+        printf("Accumulated throughput  TB1 round 2 =  %f \n", throug_tb1_acc_aver[2]);
+        printf("Accumulated throughput  TB1 round 3 =  %f \n", throug_tb1_acc_aver[3]);
         printf("round_trials =  %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \
         round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \
         errs[0][2], round_trials[0][3], errs[0][3]);
 #endif
 
+
         thr_cw1[0] = rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0]));
         if (num_rounds > 1)
           thr_cw1[1] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]);
@@ -4806,7 +5236,7 @@ int main(int argc, char **argv)
          thr_cw0_tot + thr_cw1_tot,
          rate[0],
          rate[1]);
-      }else{
+      }else if (((transmission_mode==3) || (transmission_mode==4)) && (rank_adapt==0)){
         printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d),"
                 "dci_errors %d/%d, thr TB0 = %f , thr TB1 = %f, overall thr = %f , rate 0 = %f , rate 1 = %f \n",
          errs[0][0],
@@ -4828,6 +5258,29 @@ int main(int argc, char **argv)
          thr_cw0_tot + thr_cw1_tot,
          rate0_init,
          rate1_init);
+      } else{
+         printf("Errors: r0 TB0 %d/%d TB1 %d/%d, r1 TB0 %d/%d TB1 %d/%d, r2 TB0 %d/%d TB1 %d/%d, r3 TB0 %d/%d TB1 %d/%d,"
+                "Through tot: TB0 = %f, TB1 = %f, overall thr = %f, clsm applied %d times\n",
+         failed_tb0[0],
+         active_tb0_sent[0],
+         failed_tb1[0],
+         active_tb1_sent[0],
+         failed_tb0[1],
+         active_tb0_sent[1],
+         failed_tb1[1],
+         active_tb1_sent[1],
+         failed_tb0[2],
+         active_tb0_sent[2],
+         failed_tb1[2],
+         active_tb1_sent[2],
+         failed_tb0[3],
+         active_tb0_sent[3],
+         failed_tb1[3],
+         active_tb1_sent[3],
+         throug_tb0_acc_aver[0]+throug_tb0_acc_aver[1]+throug_tb0_acc_aver[2]+throug_tb0_acc_aver[3],
+         throug_tb1_acc_aver[0]+throug_tb1_acc_aver[1]+throug_tb1_acc_aver[2]+throug_tb1_acc_aver[3],
+         throug_tot_acc_aver_all_rounds,
+         clsm_counter);
       }
 
       if (print_perf==1) {
@@ -4934,7 +5387,7 @@ int main(int argc, char **argv)
       }
 
       if ((transmission_mode != 3) && (transmission_mode != 4)) {
-        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
+        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n",
                 SNR,
                 mcs1,
                 eNB->dlsch[0][0]->harq_processes[0]->TBS,
@@ -4946,112 +5399,225 @@ int main(int argc, char **argv)
                 errs[0][2],
                 round_trials[0][2],
                 errs[0][3],
-                round_trials[0][3],
-                dci_errors);
-      }
-      else if ( rx_type== rx_SIC_dual_stream) {
-        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                round_trials[0][3]);
+      } else if(rx_type== rx_SIC_dual_stream){
+                fprintf(bler_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
                 SNR,
+                rank_adapt,
+                clsm_counter,
                 mcs1,
                 mcs2,
                 tbs0_init,
                 tbs1_init,
                 rate0_init,
                 rate1_init,
-                errs[0][0],
-                errs[1][0],
-                round_trials[0][0],
-                round_trials[1][0],
+                failed_tb0[0],
+                failed_tb1[0],
+                active_tb0_sent[0],
+                active_tb1_sent[0],
                 sic_attempt[0],
                 decoded_in_sic[0],
                 resend_both[0],
                 resend_one[0],
-                errs[0][1],
-                errs[1][1],
-                round_trials[0][1],
-                round_trials[1][1],
+                failed_tb0[1],
+                failed_tb1[1],
+                active_tb0_sent[1],
+                active_tb1_sent[1],
                 sic_attempt[1],
                 decoded_in_sic[1],
                 resend_both[1],
                 resend_one[1],
-                errs[0][2],
-                errs[1][2],
-                round_trials[0][2],
-                round_trials[1][2],
+                failed_tb0[2],
+                failed_tb1[2],
+                active_tb0_sent[2],
+                active_tb1_sent[2],
                 sic_attempt[2],
                 decoded_in_sic[2],
                 resend_both[2],
                 resend_one[2],
-                errs[0][3],
-                errs[1][3],
-                round_trials[0][3],
-                round_trials[1][3],
+                failed_tb0[3],
+                failed_tb1[3],
+                active_tb0_sent[3],
+                active_tb1_sent[3],
                 sic_attempt[3],
                 decoded_in_sic[3],
-                thr_cw0[0],
-                thr_cw1[0],
-                thr_cw0[0]+thr_cw1[0],
-                thr_cw0[1],
-                thr_cw1[1],
-                thr_cw0[1]+thr_cw1[1],
-                thr_cw0[2],
-                thr_cw1[2],
-                thr_cw0[2]+thr_cw1[2],
-                thr_cw0[3],
-                thr_cw1[3],
-                thr_cw0[3]+thr_cw1[3],
-                thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
-            }
-      else{
-        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                throug_tb0_acc_aver[0],
+                throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[1],
+                throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[2],
+                throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[3],
+                throug_tb1_acc_aver[3],
+                throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                throug_tot_acc_aver_all_rounds);
+        } else if ((rx_type!= rx_SIC_dual_stream)){
+              fprintf(bler_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                  SNR,
+                  rank_adapt,
+                  clsm_counter,
+                  mcs1,
+                  mcs2,
+                  tbs0_init,
+                  tbs1_init,
+                  rate0_init,
+                  rate1_init,
+                  failed_tb0[0],
+                  failed_tb1[0],
+                  active_tb0_sent[0],
+                  active_tb1_sent[0],
+                  TB0_deact[0],
+                  TB1_deact[0],
+                  resend_both[0],
+                  resend_one[0],
+                  failed_tb0[1],
+                  failed_tb1[1],
+                  active_tb0_sent[1],
+                  active_tb1_sent[1],
+                  TB0_deact[1],
+                  TB1_deact[1],
+                  resend_both[1],
+                  resend_one[1],
+                  failed_tb0[2],
+                  failed_tb1[2],
+                  active_tb0_sent[2],
+                  active_tb1_sent[2],
+                  TB0_deact[2],
+                  TB1_deact[2],
+                  resend_both[2],
+                  resend_one[2],
+                  failed_tb0[3],
+                  failed_tb1[3],
+                  active_tb0_sent[3],
+                  active_tb1_sent[3],
+                  throug_tb0_acc_aver[0],
+                  throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[1],
+                  throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[2],
+                  throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[3],
+                  throug_tb1_acc_aver[3],
+                  throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                  throug_tot_acc_aver_all_rounds);
+
+        }
+
+       if (transmission_mode==3 || transmission_mode==4){
+        if (rx_type== rx_SIC_dual_stream){
+         fprintf(rankadapt_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
                 SNR,
+                rank_adapt,
+                clsm_counter,
                 mcs1,
                 mcs2,
                 tbs0_init,
                 tbs1_init,
                 rate0_init,
                 rate1_init,
-                errs[0][0],
-                errs[1][0],
-                round_trials[0][0],
-                round_trials[1][0],
-                TB0_deact[0],
-                TB1_deact[0],
+                failed_tb0[0],
+                failed_tb1[0],
+                active_tb0_sent[0],
+                active_tb1_sent[0],
+                sic_attempt[0],
+                decoded_in_sic[0],
                 resend_both[0],
                 resend_one[0],
-                errs[0][1],
-                errs[1][1],
-                round_trials[0][1],
-                round_trials[1][1],
-                TB0_deact[1],
-                TB1_deact[1],
+                failed_tb0[1],
+                failed_tb1[1],
+                active_tb0_sent[1],
+                active_tb1_sent[1],
+                sic_attempt[1],
+                decoded_in_sic[1],
                 resend_both[1],
                 resend_one[1],
-                errs[0][2],
-                errs[1][2],
-                round_trials[0][2],
-                round_trials[1][2],
-                TB0_deact[2],
-                TB1_deact[2],
+                failed_tb0[2],
+                failed_tb1[2],
+                active_tb0_sent[2],
+                active_tb1_sent[2],
+                sic_attempt[2],
+                decoded_in_sic[2],
                 resend_both[2],
                 resend_one[2],
-                errs[0][3],
-                errs[1][3],
-                round_trials[0][3],
-                round_trials[1][3],
-                thr_cw0[0],
-                thr_cw1[0],
-                thr_cw0[0]+thr_cw1[0],
-                thr_cw0[1],
-                thr_cw1[1],
-                thr_cw0[1]+thr_cw1[1],
-                thr_cw0[2],
-                thr_cw1[2],
-                thr_cw0[2]+thr_cw1[2],
-                thr_cw0[3],
-                thr_cw1[3],
-                thr_cw0[3]+thr_cw1[3],
-                thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
+                failed_tb0[3],
+                failed_tb1[3],
+                active_tb0_sent[3],
+                active_tb1_sent[3],
+                sic_attempt[3],
+                decoded_in_sic[3],
+                throug_tb0_acc_aver[0],
+                throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[1],
+                throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[2],
+                throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[3],
+                throug_tb1_acc_aver[3],
+                throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                throug_tot_acc_aver_all_rounds);
+        }
+       else{
+          fprintf(rankadapt_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                  SNR,
+                  rank_adapt,
+                  clsm_counter,
+                  mcs1,
+                  mcs2,
+                  tbs0_init,
+                  tbs1_init,
+                  rate0_init,
+                  rate1_init,
+                  failed_tb0[0],
+                  failed_tb1[0],
+                  active_tb0_sent[0],
+                  active_tb1_sent[0],
+                  TB0_deact[0],
+                  TB1_deact[0],
+                  resend_both[0],
+                  resend_one[0],
+                  failed_tb0[1],
+                  failed_tb1[1],
+                  active_tb0_sent[1],
+                  active_tb1_sent[1],
+                  TB0_deact[1],
+                  TB1_deact[1],
+                  resend_both[1],
+                  resend_one[1],
+                  failed_tb0[2],
+                  failed_tb1[2],
+                  active_tb0_sent[2],
+                  active_tb1_sent[2],
+                  TB0_deact[2],
+                  TB1_deact[2],
+                  resend_both[2],
+                  resend_one[2],
+                  failed_tb0[3],
+                  failed_tb1[3],
+                  active_tb0_sent[3],
+                  active_tb1_sent[3],
+                  throug_tb0_acc_aver[0],
+                  throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[1],
+                  throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[2],
+                  throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[3],
+                  throug_tb1_acc_aver[3],
+                  throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                  throug_tot_acc_aver_all_rounds);
+       }
       }
 
 
@@ -5281,7 +5847,7 @@ int main(int argc, char **argv)
 
   }
 
-      if (n_frames==1)
+      if (n_frames==2)
   break;
 
       }// SNR
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index f117879d6b49fd43f390d3c9999dae237bc3a492..3b72e35d5761ecd16455be05c6390708c45841ca 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -937,6 +937,7 @@ int main(int argc, char **argv)
                                 0,
                                 1,
                                 0,
+                                0,
                                 0);
             /*
              if (trial%100 == 0) {
diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c
index 3869851f712d875c09f6c8bbd82db821eda52fb7..9deff20d350dcfc11f876486bb0b7e5306cd42ee 100644
--- a/openair1/SIMULATION/LTE_PHY/pucchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c
@@ -297,7 +297,7 @@ int main(int argc, char **argv)
   }
 
   logInit();
-  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
   g_log->log_component[PHY].level = LOG_DEBUG;
   g_log->log_component[PHY].flag = LOG_HIGH;
 
diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
index 84ec59a36bcb9906c8f9010a7dabfbfb2e62412e..33405805a6b6a480c684a98a7c5ea12e4075b68b 100644
--- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
+++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
@@ -87,8 +87,8 @@ UE0:
 
     SIM: {
         MSIN="0100001111";
-        USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f";
-        OPC="C42449363BBAD02B66D16BC975D77CC1";
+        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+        OPC="e734f8734007d6c5ce7a0508809e7e9c";
         MSISDN="33611123456";
     };
 
diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
index d70abbd9f118887daa19ecc563766f4af6f75418..ccc559231c2557d259a3b1482cca9e983bf202fe 100644
--- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
+++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
@@ -82,6 +82,48 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod
  * \returns 0 on success
  */
 int trx_brf_start(openair0_device *device) {
+  brf_state_t *brf = (brf_state_t*)device->priv;
+  int status;
+
+  brf->meta_tx.flags = 0;
+
+  if ((status = bladerf_sync_config(brf->dev,
+          BLADERF_MODULE_TX,
+          BLADERF_FORMAT_SC16_Q11_META,
+          brf->num_buffers,
+          brf->buffer_size,
+          brf->num_transfers,
+          100/*brf->tx_timeout_ms*/)) != 0 ) {
+    fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status = bladerf_sync_config(brf->dev,
+          BLADERF_MODULE_RX,
+          BLADERF_FORMAT_SC16_Q11_META,
+          brf->num_buffers,
+          brf->buffer_size,
+          brf->num_transfers,
+          100/*brf->rx_timeout_ms*/)) != 0 ) {
+    fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) {
+    fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) {
+    fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+
+  if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) {
+    fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) {
+    fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status));
+    abort();
+  }
 
   return 0;
 }
@@ -133,7 +175,7 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp,
   brf->tx_count++;
   
 
-  return(0);
+  return nsamps; //brf->meta_tx.actual_count;
 }
 
 /*! \brief Receive samples from hardware.
@@ -155,6 +197,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
   // BRF has only one rx/tx chain
   int16_t *samples = (int16_t*)buff[0];
   
+  brf->meta_rx.actual_count = 0;
   brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW;
   status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms);
   
@@ -170,6 +213,10 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
 	   brf->num_overflows,brf->meta_rx.timestamp,  brf->meta_rx.actual_count, nsamps);
   } 
 
+  if (brf->meta_rx.actual_count != nsamps) {
+    printf("RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count);
+  }
+
   //printf("Current RX timestampe  %u\n",  brf->meta_rx.timestamp);
   //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status));
   brf->rx_current_ts=brf->meta_rx.timestamp;
@@ -180,7 +227,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
   
   *ptimestamp = brf->meta_rx.timestamp;
  
-  return brf->meta_rx.actual_count;
+  return nsamps; //brf->meta_rx.actual_count;
 
 }
 
@@ -188,6 +235,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
  * \param device the hardware to use
  */
 void trx_brf_end(openair0_device *device) {
+abort();
 
   int status;
   brf_state_t *brf = (brf_state_t*)device->priv;
@@ -1081,6 +1129,15 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
 
   //  memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t));
 
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) {
+    fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) {
+    fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+
   return 0;
 }
 
diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h
index c9ba9fea1a4bf97d2c0c8134fd404e541f330245..99e3f7367a13aea276f0927a9c90b076c957ccdb 100644
--- a/targets/COMMON/threads_t.h
+++ b/targets/COMMON/threads_t.h
@@ -3,8 +3,9 @@
 
 typedef struct threads_s {
     int iq;
-    int odd;
-    int even;
+    int one;
+    int two;
+    int three;
 } threads_t;
 
 #endif /* _THREADS_T_H_ */
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
index 7dd8a500c3544b60fe2a27173199f951d874dc8a..4eacf1f8de58630796fdeb0e8d8071dccfdc4a1a 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
@@ -17,7 +17,7 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "10";
+    mobile_network_code =  "93";
 
        ////////// Physical parameters:
 
@@ -138,7 +138,7 @@ eNBs =
     };
     
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.188.2.2";
+    mme_ip_address      = ( { ipv4       = "10.0.1.2";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -147,11 +147,11 @@ eNBs =
 
     NETWORK_INTERFACES :
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "tun2";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.188.2.2/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.0.1.1/24";
 
-        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.1/8";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.0.1.1/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index a3ecbeb9142467eaaae9f90fa5209fbd027dd8c6..5cbe0fe1d4d2bb40bfd20c34512c0413d83234c3 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -450,7 +450,7 @@ void proc_tx_high0(PHY_VARS_eNB *eNB,
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB+offset, proc->frame_tx );
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB+offset, proc->subframe_tx );
 
-  phy_procedures_eNB_TX(eNB,proc,r_type,rn,1);
+  phy_procedures_eNB_TX(eNB,proc,r_type,rn,1,1);
 
   /* we're done, let the next one proceed */
   if (pthread_mutex_lock(&sync_phy_proc.mutex_phy_proc_tx) != 0) {
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 68fcbc49d5eb2e88dec2d63221044b53c2b5505f..5623231511f1609f6e459fcd8e0541c87f9b201c 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -222,7 +222,7 @@ double cpuf;
 char uecap_xer[1024],uecap_xer_in=0;
 
 int oaisim_flag=0;
-threads_t threads= {-1,-1,-1};
+threads_t threads= {-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
@@ -637,8 +637,9 @@ static void get_options (int argc, char **argv) {
         LONG_OPTION_WAIT_FOR_SYNC,
         LONG_OPTION_SINGLE_THREAD_DISABLE,
         LONG_OPTION_THREADIQ,
-        LONG_OPTION_THREADODDSUBFRAME,
-        LONG_OPTION_THREADEVENSUBFRAME,
+        LONG_OPTION_THREADONESUBFRAME,
+        LONG_OPTION_THREADTWOSUBFRAME,
+        LONG_OPTION_THREADTHREESUBFRAME,
         LONG_OPTION_DEMOD_SHIFT,
 #if T_TRACER
         LONG_OPTION_T_PORT,
@@ -673,8 +674,9 @@ static void get_options (int argc, char **argv) {
         {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC},
         {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
         {"threadIQ",  required_argument, NULL, LONG_OPTION_THREADIQ},
-        {"threadOddSubframe",  required_argument, NULL, LONG_OPTION_THREADODDSUBFRAME},
-        {"threadEvenSubframe",  required_argument, NULL, LONG_OPTION_THREADEVENSUBFRAME},
+        {"threadOneSubframe",  required_argument, NULL, LONG_OPTION_THREADONESUBFRAME},
+        {"threadTwoSubframe",  required_argument, NULL, LONG_OPTION_THREADTWOSUBFRAME},
+        {"threadThreeSubframe",  required_argument, NULL, LONG_OPTION_THREADTHREESUBFRAME},
         {"dlsch-demod-shift", required_argument,  NULL, LONG_OPTION_DEMOD_SHIFT},
 #if T_TRACER
         {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
@@ -800,12 +802,15 @@ static void get_options (int argc, char **argv) {
     case LONG_OPTION_THREADIQ:
        threads.iq=atoi(optarg);
        break;
-    case LONG_OPTION_THREADODDSUBFRAME:
-       threads.odd=atoi(optarg);
+    case LONG_OPTION_THREADONESUBFRAME:
+       threads.one=atoi(optarg);
        break;
-    case LONG_OPTION_THREADEVENSUBFRAME:
-       threads.even=atoi(optarg);
+    case LONG_OPTION_THREADTWOSUBFRAME:
+       threads.two=atoi(optarg);
        break;
+    case LONG_OPTION_THREADTHREESUBFRAME:
+       threads.three=atoi(optarg);
+    break;
     case LONG_OPTION_DEMOD_SHIFT: {
         extern int16_t dlsch_demod_shift;
         dlsch_demod_shift = atof(optarg);
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 791c4778f0699fcf2b52d701198de08f469da7b5..fda1c53d7eb12cb6801717e01952a65b2efb8786 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -498,10 +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)%2 == 0 && threads.even != -1 )
-        CPU_SET(1, &cpuset);
-    if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 )
-        CPU_SET(2, &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);
     init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
                 threadname);
 
@@ -546,7 +549,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
                        (sf_type==SF_UL? "SF_UL" :
                         (sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
             }
-            phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
+            phy_procedures_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
         }
 
 #if UE_TIMING_TRACE
@@ -635,6 +638,7 @@ void *UE_thread(void *arg) {
     int start_rx_stream = 0;
     int i;
     char threadname[128];
+    int th_id;
 
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
@@ -716,8 +720,11 @@ void *UE_thread(void *arg) {
                                                                UE->frame_parms.nb_antennas_rx),"");
                     }
                     UE->rx_offset=0;
-                    UE->proc.proc_rxtx[0].frame_rx++;
-                    UE->proc.proc_rxtx[1].frame_rx++;
+                    //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++) {
+                        UE->proc.proc_rxtx[th_id].frame_rx++;
+                    }
 
                     // read in first symbol
                     AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
@@ -734,7 +741,7 @@ void *UE_thread(void *arg) {
             } else {
                 sub_frame++;
                 sub_frame%=10;
-                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1];
+                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame%RX_NB_TH];
 
                 if (UE->mode != loop_through_memory) {
                     for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
@@ -801,11 +808,17 @@ void *UE_thread(void *arg) {
                     // operate on thread sf mod 2
                     AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
                     if(sub_frame == 0) {
-                        UE->proc.proc_rxtx[0].frame_rx++;
-                        UE->proc.proc_rxtx[1].frame_rx++;
+                        //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++) {
+                            UE->proc.proc_rxtx[th_id].frame_rx++;
+                        }
+                    }
+                    //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
+                    //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
+                    for (th_id=0; th_id < RX_NB_TH; th_id++) {
+                        UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
                     }
-                    UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
-                    UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
                     proc->subframe_rx=sub_frame;
                     proc->subframe_tx=(sub_frame+4)%10;
                     proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
@@ -1123,16 +1136,18 @@ void init_UE_threads(PHY_VARS_UE *UE) {
     pthread_cond_init(&UE->proc.cond_synch,NULL);
 
     // the threads are not yet active, therefore access is allowed without locking
-    int nb_threads=2;
+    int nb_threads=RX_NB_TH;
     for (int i=0; i<nb_threads; i++) {
         rtd = calloc(1, sizeof(struct rx_tx_thread_data));
         if (rtd == NULL) abort();
         rtd->UE = UE;
         rtd->proc = &UE->proc.proc_rxtx[i];
+
         pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
         pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
         UE->proc.proc_rxtx[i].sub_frame_start=i;
         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
diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c
index 3baf8fdad66b285b0019d4e7fb08cad62a499c4a..a68567a6d2fe49250a29615b279198d48c3338de 100644
--- a/targets/SIMU/USER/init_lte.c
+++ b/targets/SIMU/USER/init_lte.c
@@ -163,7 +163,7 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms,
 
   for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
       for (j=0; j<2; j++) { // 2CWs
-          for (int l=0; l<2; l++){ // 2Threads
+          for (int l=0; l<RX_NB_TH_MAX; l++){ // 2Threads
               PHY_vars_UE->dlsch[l][i][j]  = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
 
               if (!PHY_vars_UE->dlsch[l][i][j]) {