diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 990c3a1c262c2d381f294539152f631f051188a9..0d933dfd7456f85cb16a2b2350cd8760cd2e477d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -5138,10 +5138,70 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
    return(1);
 }
 
+void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
+                        LTE_UE_PDCCH *pdcch_vars,
+                        LTE_UE_PDSCH *pdsch_vars,
+                        LTE_DL_UE_HARQ_t *dlsch0_harq,
+                        uint8_t nb_rb_alloc,
+                        uint8_t subframe)
+{
+    uint32_t pbch_pss_sss_re;
+    uint32_t crs_re;
+    uint32_t granted_re;
+    uint32_t data_re;
+    uint32_t llr_offset;
+    uint8_t symbol;
+    uint8_t symbol_mod;
+
+    pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0;
+
+    LOG_I(PHY,"compute_llr_offset:  nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm);
+
+    //dlsch0_harq->rb_alloc_even;
+    //dlsch0_harq->rb_alloc_odd;
+
+    for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++)
+    {
+        symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+        if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
+        {
+            if (frame_parms->mode1_flag==0)
+                crs_re = 4;
+            else
+                crs_re = 2;
+        }
+        else
+        {
+            crs_re = 0;
+        }
+
+        granted_re = nb_rb_alloc * (12-crs_re);
+        pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
+        pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
+        data_re = granted_re - pbch_pss_sss_re;
+        llr_offset = data_re * dlsch0_harq->Qm * 2;
+
+        pdsch_vars->llr_length[symbol]   = data_re;
+        if(symbol < (frame_parms->symbols_per_tti-1))
+          pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset;
+
+        //LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb);
+        //LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re);
+        //LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re);
+        //LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re);
+
+
+
+        //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol,
+        //      pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]);
+    }
+}
 void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                                     uint8_t N_RB_DL,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint8_t  subframe,
                                     uint16_t rnti,
 									uint16_t tc_rnti,
@@ -5163,12 +5223,27 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     uint8_t  dai       = pdci_info_extarcted->dai;
 
     uint8_t  NPRB    = 0;
+    uint8_t  nb_rb_alloc = 0;
 
     if(dci_format == format1A)
     {
         if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
         {
             NPRB = (TPC&1) + 2;
+            switch (N_RB_DL) {
+            case 6:
+                nb_rb_alloc     = RIV2nb_rb_LUT6[rballoc];//NPRB;
+                break;
+            case 25:
+                nb_rb_alloc     = RIV2nb_rb_LUT25[rballoc];//NPRB;
+                break;
+            case 50:
+                nb_rb_alloc     = RIV2nb_rb_LUT50[rballoc];//NPRB;
+                break;
+            case 100:
+                nb_rb_alloc     = RIV2nb_rb_LUT100[rballoc];//NPRB;
+                break;
+            }
         }
         else
         {
@@ -5186,6 +5261,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                 NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                 break;
             }
+            nb_rb_alloc = NPRB;
         }
     }
     else // format1
@@ -5345,7 +5421,6 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
         pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2];
         pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3];
     }
-
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
         pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1];
@@ -5359,11 +5434,20 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
             pdlsch0_harq->Qm  = get_Qm(mcs1);
         }
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       nb_rb_alloc,
+                       subframe);
 }
 
 void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
                                   DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                   LTE_DL_FRAME_PARMS *frame_parms,
+                                  LTE_UE_PDCCH *pdcch_vars,
+                                  LTE_UE_PDSCH *pdsch_vars,
                                   uint32_t rnti,
                                   uint32_t si_rnti,
                                   uint32_t ra_rnti,
@@ -5466,6 +5550,14 @@ void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
         AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
         break;
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       pdlsch0_harq->nb_rb,
+                       subframe);
+
 }
 
 void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq)
@@ -5639,6 +5731,8 @@ void compute_precoding_info_format2A(uint8_t tpmi,
 void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint16_t rnti,
                                     uint8_t subframe,
                                     LTE_DL_UE_HARQ_t *dlsch0_harq,
@@ -5890,9 +5984,16 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             dlsch1_harq->Qm = (mcs2-28)<<1;
       }
 
-//#ifdef DEBUG_HARQ
+
+      compute_llr_offset(frame_parms,
+                         pdcch_vars,
+                         pdsch_vars,
+                         dlsch0_harq,
+                         dlsch0_harq->nb_rb,
+                         subframe);
+#ifdef DEBUG_HARQ
       printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-//#endif
+#endif
 
   #ifdef DEBUG_HARQ
       if (dlsch0 != NULL && dlsch1 != NULL)
@@ -5909,6 +6010,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
@@ -5998,6 +6101,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -6048,6 +6153,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
       prepare_dl_decoding_format1C(frame_parms->N_RB_DL,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    si_rnti,
                                    ra_rnti,
@@ -6099,6 +6206,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -6153,6 +6262,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
         prepare_dl_decoding_format2_2A(format2,
                 &dci_info_extarcted,
                 frame_parms,
+                pdcch_vars,
+                pdsch_vars,
                 rnti,
                 subframe,
                 dlsch0_harq,
@@ -6207,6 +6318,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
     prepare_dl_decoding_format2_2A(format2A,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    subframe,
                                    dlsch0_harq,
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 6761f6e335d12f6f7fd44a004e931e25d507cbcf..f2a743898431f2ccdc397e20ad1d35e6914bbf25 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -91,6 +91,7 @@ extern void print_shorts(char *s,int16_t *x);
 
 
 int rx_pdsch(PHY_VARS_UE *ue,
+             UE_rxtx_proc_t *proc,
              PDSCH_t type,
              unsigned char eNB_id,
              unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
@@ -747,18 +748,35 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 
   //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
+  // compute LLRs
+  // -> // compute @pointer where llrs should filled for this ofdm-symbol
+  int8_t  *pllr_symbol_cw0;
+  int8_t  *pllr_symbol_cw1;
+  uint32_t llr_offset_symbol;
+  llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol];
+  pllr_symbol_cw0  = (int8_t*)pdsch_vars[eNB_id]->llr[0];
+  pllr_symbol_cw1  = (int8_t*)pdsch_vars[eNB_id]->llr[1];
+  pllr_symbol_cw0 += llr_offset_symbol;
+  pllr_symbol_cw1 += llr_offset_symbol;
+
+  /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
+             proc->frame_rx, proc->subframe_rx,symbol,
+             nb_rb,dlsch0_harq->Qm,
+             pdsch_vars[eNB_id]->llr_length[symbol],
+             pdsch_vars[eNB_id]->llr_offset[symbol],
+             (int16_t*)pdsch_vars[eNB_id]->llr[0],
+             pllr_symbol);*/
 
   switch (dlsch0_harq->Qm) {
   case 2 :
     if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
                        symbol,
                        first_symbol_flag,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
     }
       else if (rx_type >= rx_IC_single_stream) {
@@ -918,12 +936,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1))  {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
@@ -980,10 +998,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               dl_ch_mag_ptr,//i
                               pdsch_vars[eNB_id]->dl_ch_rho2_ext,
-                              pdsch_vars[eNB_id]->llr[0],
+                              (int16_t*)pllr_symbol_cw0,
                               symbol,first_symbol_flag,nb_rb,
                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                              pdsch_vars[eNB_id]->llr128);
+                              pdsch_vars[eNB_id]->llr_offset[symbol]);
         if (rx_type==rx_IC_dual_stream) {
           dlsch_64qam_64qam_llr(frame_parms,
                                 rxdataF_comp_ptr,
@@ -991,10 +1009,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                 dl_ch_mag_ptr,
                                 pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                 pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                pdsch_vars[eNB_id]->llr[1],
+                                (int16_t*)pllr_symbol_cw1,
                                 symbol,first_symbol_flag,nb_rb,
                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
-                                pdsch_vars[eNB_id]->llr128_2ndstream);
+                                pdsch_vars[eNB_id]->llr_offset[symbol]);
         }
       }
     }
@@ -1010,10 +1028,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
                        symbol,first_symbol_flag,nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
     }
     break;
@@ -1033,12 +1050,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
   }
     break;
@@ -1096,6 +1113,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
              2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
 #endif
 
+  if(symbol == (ue->frame_parms.symbols_per_tti>>1)) //(first_symbol_flag)
+      proc->first_symbol_available = 1;
+
   return(0);
 
 }
@@ -4604,7 +4624,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
                                       unsigned char subframe,
                                       uint32_t high_speed_flag,
                                       LTE_DL_FRAME_PARMS *frame_parms,
-                                                              MIMO_mode_t mimo_mode) {
+                                      MIMO_mode_t mimo_mode) {
 
   int prb,nb_rb=0;
   int prb_off,prb_off2;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index e2de78f9caf4b903bb30051095fc83d9774b8b1d..9e102a1c65f4f45ec152650c6118bb1ba79479c2 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -636,7 +636,6 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint16_t pbch_pss_sss_adjust,
-                   int16_t **llr32p,
                    uint8_t beamforming_mode)
 {
 
@@ -645,12 +644,14 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int i,len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
+  /*
   if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
   } else {
     llr32 = (uint32_t*)(*llr32p);
-  }
+  }*/
 
+  llr32 = (uint32_t*)dlsch_llr;
   if (!llr32) {
     msg("dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
     return(-1);
@@ -672,6 +673,13 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
 
   //printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             llr32);*/
+
   //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag);
   for (i=0; i<len; i++) {
     *llr32 = *rxF;
@@ -680,7 +688,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
     llr32++;
   }
 
-  *llr32p = (int16_t *)llr32;
+  //*llr32p = (int16_t *)llr32;
 
   return(0);
 }
@@ -1043,7 +1051,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
@@ -1057,11 +1066,18 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   unsigned char symbol_mod,len_mod4;
   short *llr;
   int16_t *llr2;
+  int8_t *pllr_symbol;
 
+  /*
   if (first_symbol_flag==1)
     llr = dlsch_llr;
   else
     llr = *llr_save;
+  */
+  llr = dlsch_llr;
+
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
@@ -1085,6 +1101,15 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+//  printf("dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+
+/*  LOG_I(PHY,"dlsch_64qam_llr [symb %d / FirstSym %d / Length %d]: @LLR Buff %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             pllr_symbol);*/
+
   llr2 = llr;
   llr += (len*6);
 
@@ -1179,7 +1204,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
   }
 
-  *llr_save = llr;
 #if defined(__x86_64__) || defined(__i386__)
   _mm_empty();
   _m_empty();
@@ -8794,7 +8818,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t first_symbol_flag,
                           uint16_t nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          int16_t **llr16p)
+                          //int16_t **llr16p,
+                          uint32_t llr_offset)
 {
 
   int16_t *rxF      = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
@@ -8803,16 +8828,18 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *rho      = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *llr16;
+  int8_t  *pllr_symbol; // pointer where llrs should filled for this ofdm symbol
   int len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
   //first symbol has different structure due to more pilots
-  if (first_symbol_flag == 1) {
+  /*if (first_symbol_flag == 1) {
     llr16 = (int16_t*)dlsch_llr;
   } else {
     llr16 = (int16_t*)(*llr16p);
-  }
+  }*/
 
+  llr16 = (int16_t*)dlsch_llr;
   if (!llr16) {
     msg("dlsch_64qam_64qam_llr: llr is null, symbol %d\n",symbol);
     return(-1);
@@ -8831,6 +8858,18 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
+  //printf("dlsch_64qam_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_64qam_64qam_llr [symb %d / FirstSym %d / Length %d / LLR Offset %d]: @LLR Buff %x, @LLR Buff(symb) %x, , @Compute LLR Buff(symb) %x  \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             llr_offset,
+             (int16_t*)dlsch_llr,
+             llr16,
+             pllr_symbol);*/
+
 #ifdef __AVX2__
 
   // Round length up to multiple of 16 words
@@ -8864,6 +8903,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    (int32_t *) rho_256i,
                    len);
 #endif
+  
   free16(rxF_256i, sizeof(rxF_256i));
   free16(rxF_i_256i, sizeof(rxF_i_256i));
   free16(ch_mag_256i, sizeof(ch_mag_256i));
@@ -8881,6 +8921,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
 
   llr16 += (6*len);
-  *llr16p = (short *)llr16;
+  //*llr16p = (short *)llr16;
+
   return(0);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 2100f07805e58cf2a8542837060aa4431bcc0ae5..c4df9f79bebdc39672f01fa4f3c682fd8930029f 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -802,7 +802,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           unsigned char first_symbol_flag,
                           unsigned short nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          short **llr16p);
+                          //short **llr16p,
+                          uint32_t llr_offset);
 
 
 /** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@@ -823,7 +824,7 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                        uint8_t first_symbol_flag,
                        uint16_t nb_rb,
                        uint16_t pbch_pss_sss_adj,
-                       int16_t **llr128p,
+                       //int16_t **llr128p,
                        uint8_t beamforming_mode);
 
 /**
@@ -912,7 +913,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 
@@ -1297,6 +1299,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     @param i_mod Modulation order of the interfering stream
 */
 int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue,
+                 UE_rxtx_proc_t *proc,
                  PDSCH_t type,
                  uint8_t eNB_id,
                  uint8_t eNB_id_i,
@@ -1646,6 +1649,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       rnti_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h
index da599114a91919c05cb66631bc751c2dc1ce3ab4..d68c157445405521458b38c09b2e466cee9451a3 100644
--- a/openair1/PHY/MODULATION/defs.h
+++ b/openair1/PHY/MODULATION/defs.h
@@ -78,6 +78,17 @@ int slot_fep_ul(LTE_DL_FRAME_PARMS *frame_parms,
                 unsigned char eNb_id,
                 int no_prefix);
 
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix);
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+            int reset_freq_est);
+
 void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
 
 void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 4fc17348410c45fe2454ae238ef885df4406ef8a..6a9bbb354a746fcf291bbcd45e50d3da1371d8cb 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -240,3 +240,215 @@ int slot_fep(PHY_VARS_UE *ue,
 #endif
   return(0);
 }
+
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+  unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+  unsigned int subframe_offset;//,subframe_offset_F;
+  unsigned int slot_offset;
+  unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
+  unsigned int rx_offset;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  void (*dft)(int16_t *,int16_t *, int);
+  int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
+
+  switch (frame_parms->ofdm_symbol_size) {
+  case 128:
+    dft = dft128;
+    break;
+
+  case 256:
+    dft = dft256;
+    break;
+
+  case 512:
+    dft = dft512;
+    break;
+
+  case 1024:
+    dft = dft1024;
+    break;
+
+  case 1536:
+    dft = dft1536;
+    break;
+
+  case 2048:
+    dft = dft2048;
+    break;
+
+  default:
+    dft = dft512;
+    break;
+  }
+
+  if (no_prefix) {
+    subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
+  } else {
+    subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
+    slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
+  }
+
+  //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+
+
+  if (l<0 || l>=7-frame_parms->Ncp) {
+    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
+    return(-1);
+  }
+
+  if (Ns<0 || Ns>=20) {
+    printf("slot_fep: Ns must be between 0 and 19\n");
+    return(-1);
+  }
+
+
+
+  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));
+
+    rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
+    // Align with 256 bit
+    //    rx_offset = rx_offset&0xfffffff8;
+
+    if (l==0) {
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
+               (short *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+        start_meas(&ue->rx_dft_stats);
+
+        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+        stop_meas(&ue->rx_dft_stats);
+
+      }
+    } else {
+      rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
+      //                   (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
+
+#ifdef DEBUG_FEP
+      //  if (ue->frame <100)
+      LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
+          nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
+#endif
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
+               (void *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      start_meas(&ue->rx_dft_stats);
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].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);
+      }
+
+      stop_meas(&ue->rx_dft_stats);
+
+
+    }
+
+    #ifdef DEBUG_FEP
+        //  if (ue->frame <100)
+        printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset);
+    #endif
+  }
+  return(0);
+}
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int reset_freq_est)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  int i;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  if (ue->perfect_ce == 0) {
+    if ((l==0) || (l==(4-frame_parms->Ncp))) {
+      for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+
+#ifdef DEBUG_FEP
+        printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
+#endif
+        start_meas(&ue->dlsch_channel_estimation_stats);
+        lte_dl_channel_estimation(ue,eNB_id,0,
+                                  Ns,
+                                  aa,
+                                  l,
+                                  symbol);
+        stop_meas(&ue->dlsch_channel_estimation_stats);
+
+        for (i=0; i<ue->measurements.n_adj_cells; i++) {
+          lte_dl_channel_estimation(ue,eNB_id,i+1,
+                                    Ns,
+                                    aa,
+                                    l,
+                                    symbol);
+        }
+      }
+
+
+      // do frequency offset estimation here!
+      // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
+#ifdef DEBUG_FEP
+      printf("Frequency offset estimation\n");
+#endif
+
+      if (l==(4-frame_parms->Ncp)) {
+        start_meas(&ue->dlsch_freq_offset_estimation_stats);
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[0],
+                            frame_parms,
+                            l,
+                            &common_vars->freq_offset,
+                reset_freq_est);
+        stop_meas(&ue->dlsch_freq_offset_estimation_stats);
+
+      }
+    }
+
+  }
+  return(0);
+}
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 272051000664a4dc4917c5917e9f90b286df2389..55a14923d3ddb9730a5b52f76dfd01d76b07e07b 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -392,6 +392,25 @@ typedef struct {
   pthread_mutex_t mutex_rxtx;
   /// scheduling parameters for RXn-TXnp4 thread
   struct sched_param sched_param_rxtx;
+
+  /// internal This variable is protected by ref mutex_fep_slot1.
+  int instance_cnt_fep_slot1;
+  /// pthread descriptor fep_slot1 thread
+  pthread_t pthread_fep_slot1;
+  /// pthread attributes for fep_slot1 processing thread
+  pthread_attr_t attr_fep_slot1;
+  /// condition variable for UE fep_slot1 thread;
+  pthread_cond_t cond_fep_slot1;
+  /// mutex for UE synch thread
+  pthread_mutex_t mutex_fep_slot1;
+  //
+  uint8_t chan_est_pilot0_slot1_available;
+  uint8_t llr_slot1_available;
+  uint8_t dci_slot0_available;
+  uint8_t first_symbol_available;
+  /// scheduling parameters for fep_slot1 thread
+  struct sched_param sched_param_fep_slot1;
+
   int sub_frame_start;
   int sub_frame_step;
   unsigned long long gotIQs;
@@ -931,6 +950,14 @@ typedef struct {
 
 } PHY_VARS_UE;
 
+/* this structure is used to pass both UE phy vars and
+ * proc to the function UE_thread_rxn_txnp4
+ */
+struct rx_tx_thread_data {
+  PHY_VARS_UE    *UE;
+  UE_rxtx_proc_t *proc;
+};
+
 void exit_fun(const char* s);
 
 static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) {
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 5707aedd27ccdff32b079a7ce142d77522dddd5e..f40e8ae3e4a6c4e2febb35297e0f212431aaadc1 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -925,6 +925,10 @@ typedef struct {
   //uint32_t *rb_alloc;
   //uint8_t Qm[2];
   //MIMO_mode_t mimo_mode;
+  // llr offset per ofdm symbol
+  uint32_t llr_offset[14];
+  // llr length per ofdm symbol
+  uint32_t llr_length[14];
 } LTE_UE_PDSCH;
 
 typedef struct {
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 10d9d69c5219287de740513132754ca1d77cf10d..bb71e0deb9a1a534f2128cce67b5f34b0a0b8417 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -140,6 +140,8 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t
 */
 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);
 
+void *UE_thread_fep_slot1(void *arg);
+
 /*! \brief Scheduling for UE TX procedures in TDD S-subframes.
   @param phy_vars_ue Pointer to UE variables on which to act
   @param eNB_id Local id of eNB on which to act
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 389eb5a6943b7fa96a3d4e9f04c40ea43ab2e106..ef1db033e4ca700b4534f1cea62f13ac4ab86133 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -3166,6 +3166,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					     (void *)&dci_alloc_rx[i].dci_pdu,
 					     ue->pdcch_vars[subframe_rx & 0x1][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->frame_parms,
 					     ue->pdsch_config_dedicated,
@@ -3222,6 +3224,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    (void *)&dci_alloc_rx[i].dci_pdu,
 					    SI_RNTI,
 					    dci_alloc_rx[i].format,
+					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+					    ue->pdsch_vars_SI[eNB_id],
 					    &ue->dlsch_SI[eNB_id],
 					    &ue->frame_parms,
 					    ue->pdsch_config_dedicated,
@@ -3253,6 +3257,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    (void *)&dci_alloc_rx[i].dci_pdu,
 						P_RNTI,
 					    dci_alloc_rx[i].format,
+					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+					    ue->pdsch_vars_p[eNB_id],
 					    &ue->dlsch_SI[eNB_id],
 					    &ue->frame_parms,
 					    ue->pdsch_config_dedicated,
@@ -3289,6 +3295,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
 					    ue->prach_resources[eNB_id]->ra_RNTI,
 					    format1A,
+					    ue->pdcch_vars[subframe_rx & 0x1][eNB_id],
+					    ue->pdsch_vars_ra[eNB_id],
 					    &ue->dlsch_ra[eNB_id],
 					    &ue->frame_parms,
 					    ue->pdsch_config_dedicated,
@@ -3647,6 +3655,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
 #endif
       // process DLSCH received in first slot
       rx_pdsch(ue,
+           proc,
 	       pdsch,
 	       eNB_id,
 	       eNB_id_i,
@@ -4136,19 +4145,72 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 
 
 }
-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,
-			 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;
 
-  
+#if 0
+/*!
+ * \brief This is the UE synchronize thread.
+ * It performs band scanning and synchonization.
+ * \param arg is a pointer to a \ref PHY_VARS_UE structure.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+#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;
+
+    proc->instance_cnt_fep_slot1=-1;
+
+    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");
+        }
+        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");
+        }
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+        // Start Thread Processing
+        LOG_I(PHY," [Th-Slave] ==> execute fep slot1 thread for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
+#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));
 
@@ -4166,37 +4228,254 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   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
 
-  pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
+        // 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);
 
-  // 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_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");
+        }
+    }
 
-  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);
+    // thread finished
+    free(arg);
+    return &UE_thread_rxtx_retval;
+
+
+}
 #endif
 
-  if (ue->frame_parms.Ncp == 0) {  // normal prefix
-    pilot1 = 4;
-  } else { // extended prefix
-    pilot1 = 3;
-  }
-  
-  
+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,
+			 relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) {
+
+
+    int l,l2;
+    int pmch_flag=0;
+    int frame_rx = proc->frame_rx;
+    int subframe_rx = proc->subframe_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot0;
+    uint8_t slot1;
+    uint8_t first_ofdm_sym;
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+
+  #if T_TRACER
+    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
+  #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));
+
+    // 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);
+
+    pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
+
+
+    // 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
@@ -4204,399 +4483,453 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   } 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
-    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    l=0;
-  } else {
-    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
-    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-    l=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
-    }
     
-    ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
-    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);
-      
-      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 & 0x1][eNB_id]->num_pdcch_symbols);
+    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;
     }
-    
-  } // 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;
-  }
-
-  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
+    //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;
+
+
+    //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");
+      }
+    } 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,"");
+
+    /**** FFT Slot0 + Slot1 ****/
+    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
+
+    // 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
 
-#endif
+    // 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);
+    }
 
-  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&0x1][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&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);
-  }
+    // 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 & 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);
-  }
+    //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 & 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);
-  }
 
-  // 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 & 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);
-  }    
-  
-  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 (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
-      }
-      
-      ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
-      
-    } // for l=1..l2
+    // If this is PMCH, call procedures and return
+    if (pmch_flag == 1) {
+      ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
+      return 0;
+    }
 
+#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)
     {
-      slot_fep(ue,
-         0,
-         (next_subframe_rx<<1),
-         0,
-         0,
-         0);
+        LOG_I(PHY,"FFT symbol %d slot %d \n", pilot0, next_subframe_slot0);
+        front_end_fft(ue,
+                pilot0,
+                next_subframe_slot0,
+                0,
+                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
-
-#endif
-
-  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);
-  }
-   
-  // 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&0x1][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&0x1][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&0x1][eNB_id][0],
-			ue->dlsch[subframe_rx&0x1][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
+    LOG_I(PHY,"FFT symbol %d slot %d \n",pilot1,slot1);
+    front_end_fft(ue,
+            pilot1,
+            slot1,
+            0,
+            0);
 
-#endif
+    // 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
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    // 3- perform Channel Estimation for slot1
+    for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+    {
+        if(l == pilot0)
+        {
+            //wait until channel estimation for pilot0/slot1 is available
+            uint32_t wait = 0;
+            while(proc->chan_est_pilot0_slot1_available == 0)
+            {
+              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,
+            0);
 
-  }
-#if UE_TIMING_TRACE
-  start_meas(&ue->generic_stat);
+    if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
+    {
+      ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
+    }
 #endif
 
-#if 0
-  if(subframe_rx==5 &&  ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][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);
+    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 ****/
+
+
+    /**** 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 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);
+    }
 
-       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].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)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+    // 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);
+    }
 
-       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+    stop_meas(&ue->generic_stat);
+    printf("------LLR-Slot0  [SFN %d]: %5.2f ------\n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+
+#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);
+    }
 
-       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].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&0x1][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&0x1][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&0x1][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&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+    // 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);
+    }
 
-       AssertFatal (0,"");
-  }
+    // 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;
 #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_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_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
-
-  uint8_t          current_harq_pid        = ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid;
-  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[current_harq_pid];
-  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_processes[current_harq_pid];
+    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]);
+
+        ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
+        ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
+      }
 
-  harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_ack[subframe_rx];
-  harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)&0x1][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);
+      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 (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 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
 
-      ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
-      ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
     }
 
+    //printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*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);
-    }
+  #ifdef EMOS
+    phy_procedures_emos_UE_RX(ue,slot,eNB_id);
   #endif
 
-  }
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
+    stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
 
-#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);
-#endif
+    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);
 
-     
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
-#if UE_TIMING_TRACE
-  stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
-#if DISABLE_LOG_X
-  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].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&0x1].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);
-}
+    return (0);
+  }
    
 #if defined(Rel10) || defined(Rel14)
 int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 1ab22b6104a57dfd73b172e2ccb4d1aa594fd82a..aab70aebaa8f621899648863d3a3dc49aa750c89 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -476,15 +476,6 @@ static void *UE_thread_synch(void *arg) {
     return &UE_thread_synch_retval;
 }
 
-
-/* this structure is used to pass both UE phy vars and
- * proc to the function UE_thread_rxn_txnp4
- */
-struct rx_tx_thread_data {
-  PHY_VARS_UE    *UE;
-  UE_rxtx_proc_t *proc;
-};
-
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
  * This thread performs the phy_procedures_UE_RX() on every received slot.
@@ -508,9 +499,9 @@ static void *UE_thread_rxn_txnp4(void *arg) {
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
     if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 )
-        CPU_SET(threads.even, &cpuset);
+        CPU_SET(1, &cpuset);
     if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 )
-        CPU_SET(threads.odd, &cpuset);
+        CPU_SET(2, &cpuset);
     init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
                 threadname);
 
@@ -852,16 +843,273 @@ void *UE_thread(void *arg) {
     return NULL;
 }
 
+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;
+
+    proc->instance_cnt_fep_slot1=-1;
+
+    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");
+        }
+        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);
+#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;
+        }
+
+        // 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
+
+        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;
+}
 /*!
  * \brief Initialize the UE theads.
  * Creates the UE threads:
  * - UE_thread_rxtx0
  * - UE_thread_rxtx1
  * - UE_thread_synch
+ * - UE_thread_fep_slot0
+ * - UE_thread_fep_slot1
+ * - UE_thread_dlsch_proc_slot0
+ * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
 void init_UE_threads(PHY_VARS_UE *UE) {
     struct rx_tx_thread_data *rtd;
+    struct fep_slot1_thread_data *fep_slot1_data;
 
     pthread_attr_init (&UE->proc.attr_ue);
     pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
@@ -881,9 +1129,12 @@ void init_UE_threads(PHY_VARS_UE *UE) {
         UE->proc.proc_rxtx[i].sub_frame_start=i;
         UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
         pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
+
+        pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_fep_slot1,NULL);
+        pthread_cond_init(&UE->proc.proc_rxtx[i].cond_fep_slot1,NULL);
+        pthread_create(&UE->proc.proc_rxtx[i].pthread_fep_slot1,NULL,UE_thread_fep_slot1, rtd);
     }
     pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
-
 }