diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index b6a02d12faa00bfdf2a127763f7158ead144159d..81ddf3750309b94118758a5e037a29698af7906e 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -119,6 +119,7 @@ endmacro(add_list_string_option)
 ####################################################
 # compilation flags
 #############################################
+#set(CMAKE_BUILD_TYPE "Debug")
 if (CMAKE_BUILD_TYPE STREQUAL "")
    set(CMAKE_BUILD_TYPE "RelWithDebInfo")
 endif()
@@ -476,7 +477,7 @@ include_directories ("${X2AP_DIR}")
 # Hardware dependant options
 ###################################
 add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
-add_list1_option(NB_ANTENNAS_TX "2" "Number of antennas in transmission" "1" "2" "4")
+add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
 add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4")
 
 add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR")
@@ -1070,11 +1071,14 @@ set(PHY_SRC
   ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
   ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
   ${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c
+  ${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c
+  ${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_timefreq.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+  ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
@@ -1967,7 +1971,7 @@ target_link_libraries (oaisim_nos1 ${T_LIB})
 # Unitary tests for each piece of L1: example, mbmssim is MBMS L1 simulator
 #####################################
 
-foreach(myExe dlsim ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
+foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
   add_executable(${myExe}
     ${OPENAIR_BIN_DIR}/messages_xml.h
     ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
@@ -2049,6 +2053,7 @@ if (${T_TRACER})
   add_dependencies(oaisim generate_T)
   add_dependencies(oaisim_nos1 generate_T)
   add_dependencies(dlsim generate_T)
+  add_dependencies(dlsim_tm7 generate_T)
   add_dependencies(ulsim generate_T)
   add_dependencies(pbchsim generate_T)
   add_dependencies(scansim generate_T)
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 0b04bb70d7128226bd62f488585aad07182844d6..0a64c0a672b416bdb2ed991ce60d051c42c3a026 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -335,7 +335,7 @@ function main() {
   #By default: EXMIMO: enable
   if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
      if [ "$HW" = "EXMIMO" ] ; then 
-        DEADLINE_SCHEDULER_FLAG_USER="False"
+        DEADLINE_SCHEDULER_FLAG_USER="True"
      elif [ "$HW" = "ETHERNET" ] ; then 
         DEADLINE_SCHEDULER_FLAG_USER="False"
      elif [ "$HW" = "OAI_USRP" ] ; then 
diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
index ebb4b32f49f736f6d57c61f02b696f4ffd9504ec..8e1670ea43e9208190d895d1948467e580c602bc 100644
--- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
+++ b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
@@ -1,6 +1,5 @@
 cmake_minimum_required(VERSION 2.8)
 
-set (  CMAKE_BUILD_TYPE "RelWithDebInfo" )
 set (  ADDR_CONF False )
 set (  DEBUG_OMG False )
 set (  DISABLE_XER_PRINT False )
diff --git a/common/utils/Makefile.inc b/common/utils/Makefile.inc
index b7a1c82379da96c817f5fc96213eeb59d260db99..33c126b8d73230a685451ff9d86136c608c1982d 100644
--- a/common/utils/Makefile.inc
+++ b/common/utils/Makefile.inc
@@ -5,14 +5,14 @@ linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi)
 
 
 CFLAGS += -std=gnu99 
-#CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing 
+CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing 
 
 # Need to force this option because default kernel module builder is wrong
 CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4)
 
 #For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION)
-CFLAGS += -O2
-CFLAGS +=  -funroll-loops 
+#CFLAGS += -O2
+#CFLAGS +=  -funroll-loops 
 CFLAGS += -Wno-packed-bitfield-compat 
 
 # This is the minimum CPU faetures for OAI
diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h
index 2b65bebc8d41d2954bcc8815849d53aeb07b3c9f..27303cb57dc91deb0e58968e1d23197ab03de19a 100644
--- a/openair1/PHY/INIT/defs.h
+++ b/openair1/PHY/INIT/defs.h
@@ -304,7 +304,8 @@ void phy_init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms);
 
 //void copy_lte_parms_to_phy_framing(LTE_DL_FRAME_PARMS *frame_parm, PHY_FRAMING *phy_framing);
 
-void lte_param_init(unsigned char N_tx, 
+void lte_param_init(unsigned char N_tx_port_eNB,
+		    unsigned char N_tx, 
 		    unsigned char N_rx,
 		    unsigned char transmission_mode,
 		    uint8_t extended_prefix_flag,
@@ -339,7 +340,8 @@ void phy_cleanup(void);
 int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
 void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
 
-void lte_param_init(unsigned char N_tx, 
+void lte_param_init(unsigned char N_tx_port_eNB, 
+                    unsigned char N_tx_phy,
 		    unsigned char N_rx,
 		    unsigned char transmission_mode,
 		    uint8_t extended_prefix_flag,
@@ -350,7 +352,6 @@ void lte_param_init(unsigned char N_tx,
 		    uint8_t threequarter_fs,
                     uint8_t osf,
 		    uint32_t perfect_ce);
-
 /** @} */
 #endif
 
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index c10e4dd3c14d082cc92d54271bc2998d3cb492a4..17338d85b531b89f7d8993689b3ef3340bd8fc56 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -46,13 +46,12 @@ void phy_config_mib(LTE_DL_FRAME_PARMS *fp,
                     uint8_t p_eNB,
                     PHICH_CONFIG_COMMON *phich_config)
 {
-
   fp->N_RB_DL                            = N_RB_DL;
   fp->Nid_cell                           = Nid_cell;
   fp->nushift                            = Nid_cell%6;
   fp->Ncp                                = Ncp;
   fp->frame_type                         = frame_type;
-  fp->nb_antennas_tx_eNB                 = p_eNB;
+  fp->nb_antenna_ports_eNB               = p_eNB;
   fp->phich_config_common.phich_resource = phich_config->phich_resource;
   fp->phich_config_common.phich_duration = phich_config->phich_duration;
 }
@@ -684,6 +683,7 @@ void phy_config_dedicated_eNB(uint8_t Mod_id,
 	eNB->transmission_mode[UE_id] = 6;
 	break;
       case AntennaInfoDedicated__transmissionMode_tm7:
+        lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
 	eNB->transmission_mode[UE_id] = 7;
 	break;
       default:
@@ -835,7 +835,6 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
     if (physicalConfigDedicated->antennaInfo) {
       phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode);
       LOG_D(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]);
-      LOG_D(PHY,"\n");
       switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
       case AntennaInfoDedicated__transmissionMode_tm1:
 	phy_vars_ue->transmission_mode[eNB_id] = 1;
@@ -856,6 +855,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
 	phy_vars_ue->transmission_mode[eNB_id] = 6;
 	break;
       case AntennaInfoDedicated__transmissionMode_tm7:
+        lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[eNB_id]->crnti);
 	phy_vars_ue->transmission_mode[eNB_id] = 7;
 	break;
       default:
@@ -1018,14 +1018,17 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
   pdsch->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) );
   // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
 
-  pdsch->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->rxdataF_comp0       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-  pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->dl_ch_rho2_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->dl_ch_mag0          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-  pdsch->dl_ch_magb0         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->rxdataF_ext            = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->rxdataF_uespec_pilots  = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->rxdataF_comp0          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->rho                    = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
+  pdsch->dl_ch_estimates_ext    = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_bf_ch_estimates     = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_rho_ext          = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_rho2_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_mag0             = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+  pdsch->dl_ch_magb0            = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
 
   // the allocated memory size is fixed:
   AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" );
@@ -1036,13 +1039,16 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
     for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
       const int idx = (j<<1)+i;
       const size_t num = 7*2*fp->N_RB_DL*12;
-      pdsch->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->rxdataF_comp0[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_rho2_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_mag0[idx]          = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_magb0[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->rxdataF_ext[idx]             = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->rxdataF_uespec_pilots[idx]   = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
+      pdsch->rxdataF_comp0[idx]           = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_ch_estimates_ext[idx]     = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_bf_ch_estimates[idx]      = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
+      pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_ch_rho_ext[idx]           = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_ch_rho2_ext[idx]          = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_ch_mag0[idx]              = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+      pdsch->dl_ch_magb0[idx]             = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
     }
   }
 }
@@ -1257,6 +1263,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   LTE_eNB_SRS* const srs_vars       = eNB->srs_vars;
   LTE_eNB_PRACH* const prach_vars   = &eNB->prach_vars;
   int i, j, eNB_id, UE_id; 
+  int re;
 
   eNB->total_dlsch_bitrate = 0;
   eNB->total_transmitted_bits = 0;
@@ -1283,9 +1290,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
       eNB->physicalConfigDedicated[UE_id] = NULL;
     }
     
-    eNB->first_run_I0_measurements =
-      1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
+    eNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
   }
+
   //  for (eNB_id=0; eNB_id<3; eNB_id++) {
   {
     eNB_id=0;
@@ -1293,39 +1300,72 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
       
       // TX vars
       if (eNB->node_function != NGFI_RCC_IF4p5)
-	common_vars->txdata[eNB_id]  = (int32_t**)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) );
-      common_vars->txdataF[eNB_id] = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) );
-      
+	common_vars->txdata[eNB_id]  = (int32_t**)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
+      common_vars->txdataF[eNB_id] = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*));
+      common_vars->txdataF_BF[eNB_id] = (int32_t **)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
+
+      for (i=0; i<14; i++) {
+        common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
+#ifdef DEBUG_PHY
+        msg("[openair][LTE_PHY][INIT] lte_common_vars->txdataF[%d][%d] = %p (%d bytes)\n",
+            eNB_id,i,common_vars->txdataF[eNB_id][i],
+            fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
+#endif
+      }
+
       for (i=0; i<fp->nb_antennas_tx; i++) {
+	common_vars->txdataF_BF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t) );
 	if (eNB->node_function != NGFI_RCC_IF4p5)
-	  common_vars->txdata[eNB_id][i]  = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
-	common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
+	  common_vars->txdata[eNB_id][i]  = (int32_t*)malloc16_clear(fp->samples_per_tti*10*sizeof(int32_t) );
+
 #ifdef DEBUG_PHY
-	printf("[openair][LTE_PHY][INIT] common_vars->txdata[%d][%d] = %p\n",eNB_id,i,common_vars->txdata[eNB_id][i]);
-	printf("[openair][LTE_PHY][INIT] common_vars->txdataF[%d][%d] = %p (%d bytes)\n",
-	    eNB_id,i,common_vars->txdataF[eNB_id][i],
-	    fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
+        msg("[openair][LTE_PHY][INIT] lte_common_vars->txdataF_BF[%d][%d] = %p (%d bytes)\n",
+            eNB_id,i,common_vars->txdataF_BF[eNB_id][i],
+            fp->ofdm_symbol_size*sizeof(int32_t)); 
+        msg("[openair][LTE_PHY][INIT] lte_common_vars->txdata[%d][%d] = %p\n",eNB_id,i,common_vars->txdata[eNB_id][i]);
 #endif
       }
       
+      for (i=0; i<14; i++) { // 14 is the total number of antenna ports
+        common_vars->beam_weights[eNB_id][i] = (int32_t **)malloc16_clear(fp->nb_antennas_tx*sizeof(int32_t*));
+        for (j=0; j<fp->nb_antennas_tx; j++) {
+          common_vars->beam_weights[eNB_id][i][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+	  // antenna ports 0-3 are mapped on antennas 0-3
+	  // antenna port 4 is mapped on antenna 0
+	  // antenna ports 5-14 are mapped on all antennas 
+	  if (((i<4) && (i==j)) || ((i==4) && (j==0))) {
+	    for (re=0; re<fp->ofdm_symbol_size; re++) 
+	      common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff; 
+	  }
+	  else if (i>4) {
+	    for (re=0; re<fp->ofdm_symbol_size; re++) 
+	      common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx; 
+	  }  
+#ifdef DEBUG_PHY
+	  msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%d bytes)\n",
+	      eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j],
+              fp->ofdm_symbol_size*sizeof(int32_t)); 
+#endif
+        }
+      }
+
       // RX vars
       if (eNB->node_function != NGFI_RCC_IF4p5) {
-	common_vars->rxdata[eNB_id]        = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-	common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+	common_vars->rxdata[eNB_id]        = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
+	common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
       }
-      common_vars->rxdataF[eNB_id]       = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-      
+      common_vars->rxdataF[eNB_id]       = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
+
       for (i=0; i<fp->nb_antennas_rx; i++) {
 	if (eNB->node_function != NGFI_RCC_IF4p5) {
 	  common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
 	  common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*sizeof(int32_t) );
-	}
-	
-	common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(fp->ofdm_symbol_size*fp->symbols_per_tti) );
 #ifdef DEBUG_PHY
-	printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata[eNB_id][i]);
-	printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i]);
+	  printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata[eNB_id][i]);
+	  printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i]);
 #endif
+	}
+        common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(fp->ofdm_symbol_size*fp->symbols_per_tti) );
       }
       
       if (eNB->node_function != NGFI_RRU_IF4p5) {
@@ -1465,5 +1505,5 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   } // node_function != NGFI_RRU_IF4p5
 
   return (0);
-}
 
+}
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index 9aca71612c66c84b12ca410190667507fc7ac426..4625eba4303eb959494dc28cf34e59eebe42dcf4 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -33,7 +33,8 @@
 extern PHY_VARS_eNB *eNB;
 extern PHY_VARS_UE *UE;
 
-void lte_param_init(unsigned char N_tx, 
+void lte_param_init(unsigned char N_tx_port_eNB, 
+                    unsigned char N_tx_phy,
 		    unsigned char N_rx,
 		    unsigned char transmission_mode,
 		    uint8_t extended_prefix_flag,
@@ -70,9 +71,9 @@ void lte_param_init(unsigned char N_tx,
   frame_parms->Ncp_UL             = extended_prefix_flag;
   frame_parms->Nid_cell           = Nid_cell;
   frame_parms->nushift            = Nid_cell%6;
-  frame_parms->nb_antennas_tx     = N_tx;
+  frame_parms->nb_antennas_tx     = N_tx_phy;
   frame_parms->nb_antennas_rx     = N_rx;
-  frame_parms->nb_antennas_tx_eNB = N_tx;
+  frame_parms->nb_antenna_ports_eNB = N_tx_port_eNB;
   frame_parms->phich_config_common.phich_resource         = oneSixth;
   frame_parms->phich_config_common.phich_duration         = normal;
   frame_parms->tdd_config         = tdd_config;
@@ -81,7 +82,7 @@ void lte_param_init(unsigned char N_tx,
   //  frame_parms->Bsrs = 0;
   //  frame_parms->kTC = 0;44
   //  frame_parms->n_RRC = 0;
-  frame_parms->mode1_flag = (transmission_mode == 1)? 1 : 0;
+  frame_parms->mode1_flag = (transmission_mode == 1 || transmission_mode ==7)? 1 : 0;
 
   init_frame_parms(frame_parms,osf);
 
@@ -93,6 +94,9 @@ void lte_param_init(unsigned char N_tx,
   UE->frame_parms = *frame_parms;
   eNB->frame_parms = *frame_parms;
 
+  eNB->transmission_mode[0] = transmission_mode;
+  UE->transmission_mode[0] = transmission_mode;
+
   phy_init_lte_top(frame_parms);
   dump_frame_parms(frame_parms);
 
@@ -110,7 +114,8 @@ void lte_param_init(unsigned char N_tx,
   generate_phich_reg_mapping(&UE->frame_parms);
 
   // DL power control init
-  if (transmission_mode == 1) {
+  //if (transmission_mode == 1) {
+  if (transmission_mode == 1 || transmission_mode ==7) {
     eNB->pdsch_config_dedicated->p_a  = dB0; // 4 = 0dB
     ((eNB->frame_parms).pdsch_config_common).p_b = 0;
     UE->pdsch_config_dedicated->p_a  = dB0; // 4 = 0dB
diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c
index 611a141656075197be7bd8b8a1789505a2dc285c..cd879b1a90e6634ef02de54d2adea067e6bdb7ee 100644
--- a/openair1/PHY/INIT/lte_parms.c
+++ b/openair1/PHY/INIT/lte_parms.c
@@ -184,7 +184,7 @@ void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms)
   printf("frame_parms->tdd_config=%d\n",frame_parms->tdd_config);
   printf("frame_parms->tdd_config_S=%d\n",frame_parms->tdd_config_S);
   printf("frame_parms->mode1_flag=%d\n",frame_parms->mode1_flag);
-  printf("frame_parms->nb_antennas_tx_eNB(nb_antenna_ports)=%d\n",frame_parms->nb_antennas_tx_eNB);
+  printf("frame_parms->nb_antenna_ports_eNB=%d\n",frame_parms->nb_antenna_ports_eNB);
   printf("frame_parms->nb_antennas_tx=%d\n",frame_parms->nb_antennas_tx);
   printf("frame_parms->nb_antennas_rx=%d\n",frame_parms->nb_antennas_rx);
   printf("frame_parms->ofdm_symbol_size=%d\n",frame_parms->ofdm_symbol_size);
diff --git a/openair1/PHY/LTE_ESTIMATION/bf_freq_domain_filters.m b/openair1/PHY/LTE_ESTIMATION/bf_freq_domain_filters.m
new file mode 100644
index 0000000000000000000000000000000000000000..e0c0a0f18fe243d68b793de911649721f805cdbd
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/bf_freq_domain_filters.m
@@ -0,0 +1,59 @@
+filt_len = 16;
+
+F = -3/4:1/4:7/4;
+F_l = zeros(8,filt_len);
+F_r = zeros(8,filt_len);
+F_m = zeros(8,filt_len);
+
+F2 =-3/5:1/5:8/5;
+
+for i=0:3
+  F_l(i+1,:)  = floor(16384*[F(8+i:-1:4) zeros(1,7-i) zeros(1,4)]);
+  F_r(i+1,:)  = floor(16384*[zeros(1,4+i) F(4:end-i) zeros(1,4)]);
+  F_m(i+1,:)  = floor(16384*[F(4-i:8) F(7:-1:1+i) zeros(1,4)]);
+end
+
+for i=0:1
+  F_l(i+5,:)  = floor(16384*[F(8:-1:4-i) zeros(1,7-i) zeros(1,4)]);
+  F_r(i+5,:)  = floor(16384*[zeros(1,5+i) F2(5+i) F2(7:end-i) zeros(1,4)]);
+  F_m(i+5,:)  = floor(16384*[F(4-i:8) F2(8-i) F2(6:-1:1+i) zeros(1,4)]);
+end
+
+for i=2:3
+  F_l(i+5,:)  = floor(16384*[F2(end:-1:7) F2(8-i) zeros(1,5) zeros(1,4)]);
+  F_r(i+5,:)  = floor(16384*[zeros(1,4+i) F(4:end-i) zeros(1,4)]);
+  F_m(i+5,:)  = floor(16384*[F2(4-i:6) F2(4+i) F(8:-1:1+i) zeros(1,4)]);
+end
+
+
+fd = fopen("filt16_32.h","w");
+
+for i=0:3
+  fprintf(fd,"short filt%d_l%d[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_l(i+1,1:end-1));
+  fprintf(fd,"%d};\n\n",F_l(i+1,end));
+  
+  fprintf(fd,"short filt%d_r%d[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_r(i+1,1:end-1));
+  fprintf(fd,"%d};\n\n",F_r(i+1,end));
+  
+  fprintf(fd,"short filt%d_m%d[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_m(i+1,1:end-1));
+  fprintf(fd,"%d};\n\n",F_m(i+1,end));
+end
+
+for i=0:3
+  fprintf(fd,"short filt%d_l%d_dc[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_l(i+5,1:end-1));
+  fprintf(fd,"%d};\n\n",F_l(i+5,end));
+  
+  fprintf(fd,"short filt%d_r%d_dc[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_r(i+5,1:end-1));
+  fprintf(fd,"%d};\n\n",F_r(i+5,end));
+  
+  fprintf(fd,"short filt%d_m%d_dc[%d] = {\n",filt_len,i,filt_len);
+  fprintf(fd,"%d,",F_m(i+5,1:end-1));
+  fprintf(fd,"%d};\n\n",F_m(i+5,end));
+end
+
+fclose(fd);
diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h
index 0a38265461ec38194fde6a34768af43a276cb670..3af9c2471f140cacdb0a84d8829d976cba237be8 100644
--- a/openair1/PHY/LTE_ESTIMATION/defs.h
+++ b/openair1/PHY/LTE_ESTIMATION/defs.h
@@ -116,6 +116,12 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
                               uint8_t l,
                               uint8_t symbol);
 
+int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
+                                 module_id_t eNB_id,
+                                 uint8_t eNB_offset,
+                                 uint8_t Ns,
+                                 uint8_t p,
+                                 uint8_t symbol);
 
 int lte_dl_msbfn_channel_estimation(PHY_VARS_UE *phy_vars_ue,
                                     module_id_t eNB_id,
diff --git a/openair1/PHY/LTE_ESTIMATION/filt16_32.h b/openair1/PHY/LTE_ESTIMATION/filt16_32.h
new file mode 100644
index 0000000000000000000000000000000000000000..3487fd3466739acc608acaee9ad3721c5face987
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/filt16_32.h
@@ -0,0 +1,86 @@
+short filt16_l0[16] = {
+16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_r0[16] = {
+0,0,0,0,0,4096,8192,12288,16384,20480,24576,28672,0,0,0,0};
+
+short filt16_m0[16] = {
+0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,-12288,0,0,0,0};
+
+short filt16_l1[16] = {
+20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_r1[16] = {
+0,0,0,0,0,0,4096,8192,12288,16384,20480,24576,0,0,0,0};
+
+short filt16_m1[16] = {
+-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,0,0,0,0};
+
+short filt16_l2[16] = {
+24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_r2[16] = {
+0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
+
+short filt16_m2[16] = {
+-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,0,0,0,0};
+
+short filt16_l3[16] = {
+28672,24576,20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0};
+
+short filt16_r3[16] = {
+0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
+
+short filt16_m3[16] = {
+-12288,-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,0,0,0,0};
+
+short filt16_l0_dc[16] = {
+16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_r0_dc[16] = {
+0,0,0,0,0,3276,9830,13107,16384,19660,22937,26214,0,0,0,0};
+
+short filt16_m0_dc[16] = {
+0,4096,8192,12288,16384,13107,6553,3276,0,-3277,-6554,-9831,0,0,0,0};
+
+short filt16_l1_dc[16] = {
+16384,12288,8192,4096,0,-4096,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_r1_dc[16] = {
+0,0,0,0,0,0,6553,9830,13107,16384,19660,22937,0,0,0,0};
+
+short filt16_m1_dc[16] = {
+-4096,0,4096,8192,12288,16384,9830,6553,3276,0,-3277,-6554,0,0,0,0};
+
+short filt16_l2_dc[16] = {
+26214,22937,19660,16384,13107,9830,6553,0,0,0,0,0,0,0,0,0};
+
+short filt16_r2_dc[16] = {
+0,0,0,0,0,0,0,4096,8192,12288,16384,20480,0,0,0,0};
+
+short filt16_m2_dc[16] = {
+-6554,-3277,0,3276,6553,6553,16384,12288,8192,4096,0,-4096,0,0,0,0};
+
+short filt16_l3_dc[16] = {
+26214,22937,19660,16384,13107,9830,3276,0,0,0,0,0,0,0,0,0};
+
+short filt16_r3_dc[16] = {
+0,0,0,0,0,0,0,0,4096,8192,12288,16384,0,0,0,0};
+
+short filt16_m3_dc[16] = {
+-9831,-6554,-3277,0,3276,6553,9830,16384,12288,8192,4096,0,0,0,0,0};
+
+short filt16_1[16] = {
+16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
+
+short filt16_2l0[16] = {
+16384,12288,8192,4096,-4096,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_2r0[16] = {
+0,4096,8192,12288,16384,20480,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_2l1[16] = {
+20480,16384,12288,8192,4096,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt16_2r1[16] = {
+-4096,0,4096,8192,12288,16384,0,0,0,0,0,0,0,0,0,0};
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b220c2c391897a8f5283c450fa75ab5d42232b0
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -0,0 +1,750 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
+
+  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+#ifdef USER_MODE
+#include <string.h>
+#endif
+#include "defs.h"
+#include "PHY/defs.h"
+#include "filt16_32.h"
+//#define DEBUG_BF_CH
+
+int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
+                                 uint8_t eNB_id,
+                                 uint8_t eNB_offset,
+                                 unsigned char Ns,
+                                 unsigned char p,
+                                 unsigned char symbol)
+{
+  
+  unsigned short rb,nb_rb=0;
+  unsigned char aarx,l,lprime,nsymb,skip_half=0,sss_symb,pss_symb=0,rb_alloc_ind,harq_pid,uespec_pilots=0;
+  int beamforming_mode, ch_offset;
+  uint8_t subframe;
+  int8_t uespec_nushift, uespec_poffset=0, pil_offset=0;
+  uint8_t pilot0,pilot1,pilot2,pilot3;
+
+  short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev;
+  short *fl, *fm, *fr, *fl_dc, *fm_dc, *fr_dc, *f1, *f2l, *f2r;
+
+  unsigned int *rballoc; 
+  int **rxdataF;
+  int32_t **dl_bf_ch_estimates;
+  int uespec_pilot[300];
+
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[eNB_id];
+  LTE_DL_UE_HARQ_t *dlsch0_harq; 
+
+  harq_pid    = dlsch_ue[0]->current_harq_pid; 
+  dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+
+  if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) ||
+      ((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
+    rballoc = dlsch0_harq->rb_alloc_odd;
+  else
+    rballoc = dlsch0_harq->rb_alloc_even;
+
+  rxdataF = phy_vars_ue->common_vars.rxdataF;
+
+  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[eNB_id]->dl_bf_ch_estimates;
+  beamforming_mode   = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
+
+  if (phy_vars_ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
+    ch_offset     = frame_parms->ofdm_symbol_size;
+  else
+    ch_offset     = frame_parms->ofdm_symbol_size*symbol;
+
+  
+  uespec_nushift = frame_parms->Nid_cell%3;
+  subframe = Ns>>1;
+ 
+
+    //generate ue specific pilots
+    lprime = symbol/3-1;
+    lte_dl_ue_spec_rx(phy_vars_ue,uespec_pilot,Ns,5,lprime,0,dlsch0_harq->nb_rb);
+    //write_output("uespec_pilot_rx.m","uespec_pilot",uespec_pilot,300,1,1);
+
+    if (frame_parms->Ncp==0){
+      if (symbol==3 || symbol==6 || symbol==9 || symbol==12)
+        uespec_pilots = 1;
+    } else{
+      if (symbol==4 || symbol==7 || symbol==10)
+        uespec_pilots = 1;
+    }
+   
+    if ((frame_parms->Ncp==0 && (symbol==6 ||symbol ==12)) || (frame_parms->Ncp==1 && symbol==7))
+      uespec_poffset = 2;
+
+    if (phy_vars_ue->frame_parms.Ncp == 0) { // normal prefix
+      pilot0 = 3;
+      pilot1 = 6;
+      pilot2 = 9;
+      pilot3 = 12;
+    } else { // extended prefix
+      pilot0 = 4;
+      pilot1 = 7;
+      pilot2 = 10;
+    }
+
+    //define the filter
+    pil_offset = (uespec_nushift+uespec_poffset)%3;
+    // printf("symbol=%d,pil_offset=%d\n",symbol,pil_offset);
+    switch (pil_offset) {
+    case 0:
+      fl = filt16_l0;
+      fm = filt16_m0;
+      fr = filt16_r0;
+      fl_dc = filt16_l0;
+      fm_dc = filt16_m0;
+      fr_dc = filt16_r0;
+      f1 = filt16_1;
+      f2l = filt16_2l0;
+      f2r = filt16_2r0;
+      break;
+
+    case 1:
+      fl = filt16_l1;
+      fm = filt16_m1;
+      fr = filt16_r1;
+      fl_dc = filt16_l1;
+      fm_dc = filt16_m1;
+      fr_dc = filt16_r1;
+      f1 = filt16_1;
+      f2l = filt16_2l1;
+      f2r = filt16_2r1;
+      break;
+
+    case 2:
+      fl = filt16_l2;
+      fm = filt16_m2;
+      fr = filt16_r2;
+      fl_dc = filt16_l2;
+      fm_dc = filt16_m2;
+      fr_dc = filt16_r2;
+      f1 = filt16_1;
+      f2l = filt16_2l0;
+      f2r = filt16_2r0;
+      break;
+
+    case 3:
+      fl = filt16_l3;
+      fm = filt16_m3;
+      fr = filt16_r3;
+      fl_dc = filt16_l3;
+      fm_dc = filt16_m3;
+      fr_dc = filt16_r3;
+      f1 = filt16_1;
+      f2l = filt16_2l1;
+      f2r = filt16_2r1;
+      break;
+    }
+ // beamforming mode extension
+ /* }
+  else if (beamforming_mode==0)
+    msg("lte_dl_bf_channel_estimation:No beamforming is performed.\n");
+  else
+    msg("lte_dl_bf_channel_estimation:Beamforming mode not supported yet.\n");*/
+  
+
+  l=symbol;
+  nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
+
+  if (frame_parms->frame_type == TDD) {  //TDD
+    sss_symb = nsymb-1;
+    pss_symb = 2;
+  } else {
+    sss_symb = (nsymb>>1)-2;
+    pss_symb = (nsymb>>1)-1;
+  }
+
+
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+
+    rxF  = (short *)&rxdataF[aarx][pil_offset + frame_parms->first_carrier_offset + symbol*frame_parms->ofdm_symbol_size];
+    pil  = (short *)uespec_pilot;
+    dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset];
+
+    memset(dl_bf_ch,0,4*(frame_parms->ofdm_symbol_size));
+    //memset(dl_bf_ch,0,2*(frame_parms->ofdm_symbol_size));
+
+    if (phy_vars_ue->high_speed_flag==0) {
+    // multiply previous channel estimate by ch_est_alpha
+      if (frame_parms->Ncp==0){
+        multadd_complex_vector_real_scalar(dl_bf_ch-(frame_parms->ofdm_symbol_size<<1),
+                                           phy_vars_ue->ch_est_alpha,dl_bf_ch-(frame_parms->ofdm_symbol_size<<1),
+                                           1,frame_parms->ofdm_symbol_size);
+      } else {
+        msg("lte_dl_bf_channel_estimation: beamforming channel estimation not supported for TM7 Extended CP.\n"); // phy_vars_ue->ch_est_beta should be defined equaling 1/3
+      }
+    }
+    //estimation and interpolation
+
+    if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+        if (rb < 32)
+          rb_alloc_ind = (rballoc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+        // For second half of RBs skip DC carrier
+        if (rb==(frame_parms->N_RB_DL>>1)) {
+          rxF       = (short *)&rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
+        }
+
+        if (rb_alloc_ind==1) {
+          if (uespec_pilots==1) {
+            if (beamforming_mode==7) {
+              if (frame_parms->Ncp==0) {
+
+                ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16);
+                
+                ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16);
+
+                ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16);
+              } else {
+                msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n");
+                exit(-1);
+              }
+            } else {
+              msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c): transmission mode not supported.\n");
+            }
+          }
+          nb_rb++;
+        }
+
+        rxF+=24;
+        dl_bf_ch+=24;
+      }
+    } else {  // Odd number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
+        skip_half=0;
+
+        if (rb < 32)
+          rb_alloc_ind = (rballoc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+        // PBCH
+        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
+          rb_alloc_ind = 0;
+        }
+
+        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
+        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=1;
+        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=2;
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) &&
+            (rb>((frame_parms->N_RB_DL>>1)-3)) &&
+            (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+            (l==sss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) &&
+            (rb==((frame_parms->N_RB_DL>>1)-3)) &&
+            (l==sss_symb))
+          skip_half=1;
+        else if (((subframe==0)||(subframe==5)) &&
+                 (rb==((frame_parms->N_RB_DL>>1)+3)) &&
+                 (l==sss_symb))
+          skip_half=2;
+
+        //PSS in subframe 0/5 if FDD
+        if (frame_parms->frame_type == FDD) {  //FDD
+          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
+          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        //printf("symbol=%d,pil_offset=%d\ni,rb_alloc_ind=%d,uespec_pilots=%d,beamforming_mode=%d,Ncp=%d,skip_half=%d\n",symbol,pil_offset,rb_alloc_ind,uespec_pilots,beamforming_mode,frame_parms->Ncp,skip_half);
+        if (rb_alloc_ind==1) {
+          if (uespec_pilots==1) {
+            if (beamforming_mode==7) {
+              if (frame_parms->Ncp==0) {
+                if (skip_half==1) {
+                  if (pil_offset<2) {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                    multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); 
+                    pil+=2;
+                    
+                    ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                    multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); 
+                    pil+=2;
+
+                  } else {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                    multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16);
+                    pil+=2;
+                  }
+                } else if (skip_half==2) {
+                  if (pil_offset<2) {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                    multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); 
+                    pil+=2;
+                    
+                  } else {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                    multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16);
+                    pil+=2;
+
+                    ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                    multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); 
+                    pil+=2;
+
+                  }
+                } else {
+
+                  ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                  multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+                  
+                  ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                  multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+
+                  ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                  multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[8]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[16],rxF[17],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+
+               }  
+             } else {
+              msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n");
+              exit(-1);
+             }
+          
+           } else {
+            msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):transmission mode not supported.\n");
+           }
+         }       
+         nb_rb++;
+       }
+
+        rxF+=24;
+        dl_bf_ch+=24;
+      } // first half loop
+
+      // Do middle RB (around DC) 
+      if (rb < 32)
+        rb_alloc_ind = (rballoc[0]>>rb) & 1;
+      else if (rb < 64)
+        rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
+      else if (rb < 96)
+        rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
+      else if (rb < 100)
+        rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
+      else
+        rb_alloc_ind = 0;
+
+      // PBCH
+      if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
+        rb_alloc_ind = 0;
+      }
+
+      //SSS
+      if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
+        rb_alloc_ind = 0;
+      }
+
+      if (frame_parms->frame_type == FDD) {
+       //PSS
+        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+      }
+
+      if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) {
+        //PSS
+        if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+      }
+
+      //printf("DC rb %d (%p)\n",rb,rxF);
+      if (rb_alloc_ind==1) {
+        if (pil_offset<2) {
+          ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+          multadd_real_vector_complex_scalar(fl_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+                  
+          ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+          multadd_real_vector_complex_scalar(fm_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+
+          rxF   = (short *)&rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)];
+
+          ch[0] = (short)(((int)pil[0]*rxF[6] - (int)pil[1]*rxF[7])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[7] + (int)pil[1]*rxF[6])>>15);
+          multadd_real_vector_complex_scalar(fr_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[3]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[6],rxF[7],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+        } else {
+          ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+          multadd_real_vector_complex_scalar(fl_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+                  
+          rxF   = (short *)&rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)];
+
+          ch[0] = (short)(((int)pil[0]*rxF[2] - (int)pil[1]*rxF[3])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[3] + (int)pil[1]*rxF[2])>>15);
+          multadd_real_vector_complex_scalar(fm_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[1]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[2],rxF[3],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+
+          ch[0] = (short)(((int)pil[0]*rxF[10] - (int)pil[1]*rxF[11])>>15);
+          ch[1] = (short)(((int)pil[0]*rxF[11] + (int)pil[1]*rxF[10])>>15);
+          multadd_real_vector_complex_scalar(fr_dc,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+          //printf("symbol=%d,rxF[5]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[10],rxF[11],pil[0],pil[1],ch[0],ch[1]);
+#endif
+          pil+=2;;
+        }
+      } // rballoc==1
+      else {
+        rxF       = (short *)&rxdataF[aarx][pil_offset+((symbol*(frame_parms->ofdm_symbol_size)))];
+      }
+
+      rxF+=14+2*pil_offset;
+      dl_bf_ch+=24;
+      rb++;
+
+      for (; rb<frame_parms->N_RB_DL; rb++) {
+        skip_half=0;
+
+        if (rb < 32)
+          rb_alloc_ind = (rballoc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+        // PBCH
+        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
+          rb_alloc_ind = 0;
+        }
+
+        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
+        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=1;
+        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=2;
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb))
+          skip_half=1;
+        else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb))
+          skip_half=2;
+
+        if (frame_parms->frame_type == FDD) {
+          //PSS
+          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          //PSS
+          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
+          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if (rb_alloc_ind==1) {
+          if (uespec_pilots==1) {
+            if (beamforming_mode==7) {
+              if (frame_parms->Ncp==0) {
+                if (skip_half==1) {
+                  if (pil_offset<2) {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                    multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16); 
+                    pil+=2;
+                    
+                    ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                    multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); 
+                    pil+=2;
+          
+
+                  } else {
+
+                    ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                    ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                    multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16);
+                    pil+=2;
+                  }
+                } else if (skip_half==2) {
+                   if (pil_offset<2) {
+
+                     ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                     ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                     multadd_real_vector_complex_scalar(f1,ch,dl_bf_ch,16); 
+                     pil+=2;
+                     
+                   } else {
+
+                     ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                     ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                     multadd_real_vector_complex_scalar(f2l,ch,dl_bf_ch,16);
+                     pil+=2;
+
+                     ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                     ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                     multadd_real_vector_complex_scalar(f2r,ch,dl_bf_ch,16); 
+                     pil+=2;
+
+                   }
+                } else {
+
+                  ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
+                  multadd_real_vector_complex_scalar(fl,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[0]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[0],rxF[1],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+                  
+                  ch[0] = (short)(((int)pil[0]*rxF[8] - (int)pil[1]*rxF[9])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[9] + (int)pil[1]*rxF[8])>>15);
+                  multadd_real_vector_complex_scalar(fm,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[4]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[8],rxF[9],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+
+                  ch[0] = (short)(((int)pil[0]*rxF[16] - (int)pil[1]*rxF[17])>>15);
+                  ch[1] = (short)(((int)pil[0]*rxF[17] + (int)pil[1]*rxF[16])>>15);
+                  multadd_real_vector_complex_scalar(fr,ch,dl_bf_ch,16);
+#ifdef DEBUG_BF_CH
+                  printf("symbol=%d,rxF[8]=(%d,%d),pil=(%d,%d),ch=(%d,%d)\n",symbol,rxF[16],rxF[17],pil[0],pil[1],ch[0],ch[1]);
+#endif
+                  pil+=2;
+
+                }
+              } else {
+                msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):TM7 beamgforming channel estimation not supported for extented CP\n");
+                exit(-1);
+              }
+            
+            } else {
+              msg("lte_dl_bf_channel_estimation(lte_dl_bf_channel_estimation.c):transmission mode not supported.\n");
+            }
+          }
+          nb_rb++;
+        }
+
+        rxF+=24;
+        dl_bf_ch+=24;
+      } // second half of RBs
+    } // odd number of RBs  
+
+    // Temporal Interpolation
+    if (phy_vars_ue->perfect_ce == 0) {
+
+      dl_bf_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset];
+#ifdef DEBUG_BF_CH
+      printf("[dlsch_bf_ch_est.c]:symbol %d, dl_bf_ch (%d,%d)\n",symbol,dl_bf_ch[0],dl_bf_ch[1]);
+#endif
+
+      if (phy_vars_ue->high_speed_flag == 0) {
+        multadd_complex_vector_real_scalar(dl_bf_ch,
+                                           32767-phy_vars_ue->ch_est_alpha,
+                                           dl_bf_ch-(frame_parms->ofdm_symbol_size<<1),0,frame_parms->ofdm_symbol_size);
+        //printf("dlsch_bf_ch_est.c:symbol %d,dl_bf_ch (%d,%d)\n",symbol,*(dl_bf_ch-512*2),*(dl_bf_ch-512*2+1));
+      } else { // high_speed_flag == 1
+        if (beamforming_mode==7) {
+          if (frame_parms->Ncp==0) {
+            if (symbol == pilot0) {
+              //      printf("Interpolating %d->0\n",4-phy_vars_ue->lte_frame_parms.Ncp);
+              //      dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][(4-phy_vars_ue->lte_frame_parms.Ncp)*(frame_parms->ofdm_symbol_size)];
+              dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot3*(frame_parms->ofdm_symbol_size)];
+#ifdef DEBUG_BF_CH
+              printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]);
+#endif
+              // pilot spacing 5 symbols (1/5,2/5,3/5,4/5 combination)
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,26214,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,6554,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,19661,dl_bf_ch-(3*2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,13107,dl_bf_ch-(3*2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,13107,dl_bf_ch-(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,19661,dl_bf_ch-(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size);
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,6554,dl_bf_ch-(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,26214,dl_bf_ch-(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+            } else if (symbol == pilot1) {
+              dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot0*(frame_parms->ofdm_symbol_size)];
+#ifdef DEBUG_BF_CH
+              printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]);
+#endif
+
+              // pilot spacing 3 symbols (1/3,2/3 combination)
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size);
+
+            } else if (symbol == pilot2) {
+              dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot1*(frame_parms->ofdm_symbol_size)];
+#ifdef DEBUG_BF_CH
+              printf("[dlsch_bf_ch_est.c] symbol=%d, dl_bf_ch_prev=(%d,%d), dl_bf_ch=(%d,%d)\n", symbol, dl_bf_ch_prev[0], dl_bf_ch_prev[1], dl_bf_ch[0], dl_bf_ch[1]);
+#endif
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+
+              multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size);
+              multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size);
+            } else { // symbol == pilot3
+            //      printf("Interpolating 0->%d\n",4-phy_vars_ue->lte_frame_parms.Ncp);
+            dl_bf_ch_prev = (short *)&dl_bf_ch_estimates[aarx][pilot2*(frame_parms->ofdm_symbol_size)];
+
+            // pilot spacing 3 symbols (1/3,2/3 combination)
+            multadd_complex_vector_real_scalar(dl_bf_ch_prev,21845,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),1,frame_parms->ofdm_symbol_size);
+            multadd_complex_vector_real_scalar(dl_bf_ch,10923,dl_bf_ch_prev+(2*(frame_parms->ofdm_symbol_size)),0,frame_parms->ofdm_symbol_size);
+
+            multadd_complex_vector_real_scalar(dl_bf_ch_prev,10923,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),1,frame_parms->ofdm_symbol_size);
+            multadd_complex_vector_real_scalar(dl_bf_ch,21845,dl_bf_ch_prev+(2*((frame_parms->ofdm_symbol_size)<<1)),0,frame_parms->ofdm_symbol_size);
+            }
+
+          } else {
+            msg("lte_dl_bf_channel_estimation:temporal interpolation not supported for TM7 extented CP.\n");
+          }
+        } else {
+          msg("lte_dl_bf_channel_estimation:temporal interpolation not supported for this beamforming mode.\n");
+        } 
+      }
+    }
+  } //aarx
+ 
+#ifdef DEBUG_BF_CH  
+    printf("[dlsch_bf_ch_est.c]: dl_bf_estimates[0][600] %d, %d \n",*(short *)&dl_bf_ch_estimates[0][600],*(short*)&phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0][600]);
+#endif
+
+  return(0);
+
+}
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
index 65e2101d99113932677085c92e9e533e92e83f96..45ed0f11c0d1a359fd19db11ccbf019a68091e4b 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -35,9 +35,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
                               unsigned char l,
                               unsigned char symbol)
 {
-
-
-
   int pilot[2][200] __attribute__((aligned(16)));
   unsigned char nu,aarx;
   unsigned short k;
@@ -735,7 +732,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
 
   // do ifft of channel estimate
   for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
-    for (p=0; p<ue->frame_parms.nb_antennas_tx_eNB; p++) {
+    for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
       if (ue->common_vars.dl_ch_estimates[eNB_offset][(p<<1)+aarx])
         idft((int16_t*) &ue->common_vars.dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
              (int16_t*) ue->common_vars.dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index b7b36efa0b5fec203f7726ac3a40af0bbdbccb42..90ebd07f60f2f45f1f64779ba601c8e3b98040f2 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -446,7 +446,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
   // signal measurements
   for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-      for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+      for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
         ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] =
           (signal_energy_nodc(&ue->common_vars.dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
                               (N_RB_DL*12)));
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index d8a627020db5f93cc6e320a88e1d57784f664b4d..d2bc2e27c0750b7e68a97c461f4fac2d29f1e519 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -78,7 +78,7 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
   int16_t ul_ch_estimates_re,ul_ch_estimates_im;
   int32_t rx_power_correction;
 
-  //uint8_t nb_antennas_rx = frame_parms->nb_antennas_tx_eNB;
+  //uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
   uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
   uint8_t cyclic_shift;
 
@@ -679,7 +679,7 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
 
   int T_SFC,aa;
   int N_symb,symbol;
-  uint8_t nb_antennas_rx = frame_parms->nb_antennas_tx_eNB;
+  uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB;
 #ifdef DEBUG_SRS
   char fname[40], vname[40];
 #endif
diff --git a/openair1/PHY/LTE_REFSIG/defs.h b/openair1/PHY/LTE_REFSIG/defs.h
index a1d2d3aaf8461f98ec4d8ba6e1ae95debef1c085..9c12458ff0fe18d7048dfc502a25665a213d6e92 100644
--- a/openair1/PHY/LTE_REFSIG/defs.h
+++ b/openair1/PHY/LTE_REFSIG/defs.h
@@ -45,12 +45,15 @@ unsigned int lte_gold_generic(unsigned int *x1, unsigned int *x2, unsigned char
 
 void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14],uint16_t Nid_cell);
 
+void lte_gold_ue_spec(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS);
+
+void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_t Nid_cell, uint16_t n_rnti);
+
 /*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL UE-specific reference signals for antenna ports 7..14.
 @param frame_parms LTE DL Frame parameters
 @param lte_gold_uespec_table pointer to table where sequences are stored
 @param Nid_cell Cell Id (to compute sequences for local and adjacent cells)
 @param n_idDMRS Scrambling identity for TM10*/
-void lte_gold_ue_spec(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS);
 
 void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_table[10][3][42],uint16_t Nid_MBSFN);
 
@@ -77,16 +80,18 @@ int lte_dl_cell_spec(PHY_VARS_eNB *phy_vars_eNB,
 @param output Output vector for OFDM symbol (Frequency Domain)
 @param amp Q15 amplitude
 @param Ns Slot number (0..19)
+@param lprime symbol (0,1)
 @param p antenna index
 @param SS_flag Flag to indicate special subframe
 */
-int lte_dl_ue_spec(PHY_VARS_eNB *phy_vars_eNB,
+/*int lte_dl_ue_spec(PHY_VARS_eNB *phy_vars_eNB,
                    uint8_t UE_id,
                    int32_t *output,
                    short amp,
                    uint8_t Ns,
+		   uint8_t lprime,
                    uint8_t p,
-                   int SS_flag );
+                   int SS_flag);*/
 
 /*! \brief This function generates the MBSFN reference signal sequence (36-211, Sec 6.10.1.2)
 @param phy_vars_eNB Pointer to eNB variables
@@ -116,6 +121,24 @@ int lte_dl_cell_spec_rx(PHY_VARS_UE *phy_vars_ue,
                         unsigned char l,
                         unsigned char p);
 
+/*!\brief This function generates the ue-specific reference signal
+ * sequence (36-211, Sec 6.10.3.1) for beamforming channel estimation upon reception
+@param phy_vars_ue Pointer to UE variables
+@param output Output vector for OFDM symbol (Frequency Domain)
+@param Ns Slot number (0..19)
+@param p antenna port intex
+@param lprime symbol (0,1)
+@param SS_flag Flag to indicate special subframe
+@param nRB_PDSCH number of allocated PDSCH RBs
+*/
+int lte_dl_ue_spec_rx(PHY_VARS_UE *phy_vars_ue,
+                      int32_t *output,
+                      unsigned char Ns,
+                      unsigned char p,
+                      int lprime,
+                      int SS_flag,
+                      uint16_t nRB_PDSCH);
+
 int lte_dl_mbsfn_rx(PHY_VARS_UE *phy_vars_ue,
                     int *output,
                     int subframe,
diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
index fba122eef4f4b8d8ca036234e60d8e49ffd506a2..3cf88fbb7639366ae9e696a2be0e983fefdc43f0 100644
--- a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
+++ b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
@@ -19,13 +19,13 @@
  *      contact@openairinterface.org
  */
 
-/*! \file PHY/LTE_REFSIG/lte_dl_uespec.c
+/*! \file PHY/LTE_REFSIG/lte_dl_ue_spec.c
 * \brief Top-level routines for generating UE-specific Reference signals from 36-211, V11.3.0 2013-06
-* \author R. Knopp
-* \date 2014
+* \author R. Knopp X. Jiang
+* \date 2015
 * \version 0.1
 * \company Eurecom
-* \email: knopp@eurecom.fr
+* \email: knopp@eurecom.fr xiwen.jiang@eurecom.fr
 * \note
 * \warning
 */
@@ -44,18 +44,21 @@
 
 int Wbar_NCP[8][4] = {{1,1,1,1},{1,-1,1,-1},{1,1,1,1},{1,-1,1,-1},{1,1,-1,-1},{-1,-1,1,1},{1,-1,-1,1},{-1,1,1,-1}};
 
+/*
 int lte_dl_ue_spec(PHY_VARS_eNB *eNB,
                    uint8_t UE_id,
                    int32_t *output,
                    short amp,
                    uint8_t Ns,
+		   uint8_t lprime,
                    uint8_t p,
-                   int SS_flag )
+                   int SS_flag)
 {
 
-  int32_t qpsk[4],nqpsk[4],*qpsk_p,*output_p;
-  int16_t a;
-  int w,lprime,ind,l,ind_dword,ind_qpsk_symb,nPRB;
+  int32_t qpsk[4],nqpsk[4];
+  int16_t k=0,a;
+  int mprime,ind,ind_dword,ind_qpsk_symb;
+  unsigned nushift,kprime;
   //  LTE_eNB_DLSCH_t *dlsch = eNB->dlsch_eNB[UE_id][0];
 
   a = (amp*ONE_OVER_SQRT2_Q15)>>15;
@@ -77,146 +80,230 @@ int lte_dl_ue_spec(PHY_VARS_eNB *eNB,
   ((short *)&nqpsk[3])[0] = a;
   ((short *)&nqpsk[3])[1] = a;
 
-  if (p>=7) {
+  if (p==5) {
     if (SS_flag==0) {
       if (eNB->frame_parms.Ncp == NORMAL) {
-        // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p>=7
+      // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p=5
+      
+      nushift =  eNB->frame_parms.Nid_cell%3;
+
+      if(lprime==0){
+        kprime=nushift;
+      }else{
+        kprime=(nushift+2*lprime)%4;
+      }
+
+      k = kprime+eNB->frame_parms.first_carrier_offset;
+      printf("lte_dl_ue_spec:k=%d\n",k);
+ 
+      for (mprime=0;mprime<3*nRB_PDSCH-1;mprime++) {
+        ind = 3*lprime*nRB_PDSCH+mprime;
+        ind_dword = ind>>4;
+        ind_qpsk_symb = ind&0xf;
+
+        output[k] = qpsk[(phy_vars_UE->lte_gold_uespec_port5_table[Ns][ind_dword]>>(2*ind_qpsk_symb))&3];
+        //output[k] = 0xffffffff;
+
+        k += 4;
+        if (k >= eNB->frame_parms.ofdm_symbol_size) {
+          k++;  // skip DC carrier
+          k-=eNB->frame_parms.ofdm_symbol_size;
+        }
+
+       }
+      }
+    }
+  } else if (p>=7) {
+    printf("lte_dl_ue_spec:antenna ports >=7 not supported yet!\n");
+  } else {
+    LOG_E(PHY,"Illegal p %d UE specific pilots\n",p);
+  }
+
+  return(0);
+}
+*/
+
 
+int lte_dl_ue_spec_rx(PHY_VARS_UE *ue,
+                      int32_t *output,
+                      unsigned char Ns,
+                      unsigned char p, 
+                      int lprime,
+                      int SS_flag,
+                      uint16_t nRB_PDSCH)
+{
+  int32_t qpsk[4],nqpsk[4],*qpsk_p,*output_p;
+  int w,mprime,ind,l,ind_dword,ind_qpsk_symb,nPRB;
+  short pamp;
 
+  // Compute the correct pilot amplitude, sqrt_rho_b = Q3.13
+  pamp = ONE_OVER_SQRT2_Q15;
 
-        // position output pointer to 5th symbol in slot
-        output_p = output+(60*eNB->frame_parms.N_RB_DL);
+  // This includes complex conjugate for channel estimation
+  ((short *)&qpsk[0])[0] = pamp;
+  ((short *)&qpsk[0])[1] = -pamp;
+  ((short *)&qpsk[1])[0] = -pamp;
+  ((short *)&qpsk[1])[1] = -pamp;
+  ((short *)&qpsk[2])[0] = pamp;
+  ((short *)&qpsk[2])[1] = pamp;
+  ((short *)&qpsk[3])[0] = -pamp;
+  ((short *)&qpsk[3])[1] = pamp;
 
-        // shift to 2nd RE in PRB for p=7,8,11,13
-        if ((p==7) || (p==8) || (p==11) || (p==13)) output_p++;
+  ((short *)&nqpsk[0])[0] = -pamp;
+  ((short *)&nqpsk[0])[1] = pamp;
+  ((short *)&nqpsk[1])[0] = pamp;
+  ((short *)&nqpsk[1])[1] = pamp;
+  ((short *)&nqpsk[2])[0] = -pamp;
+  ((short *)&nqpsk[2])[1] = -pamp;
+  ((short *)&nqpsk[3])[0] = pamp;
+  ((short *)&nqpsk[3])[1] = -pamp;
 
+  if (p>=7) {
+    if (SS_flag==0) {
+      if (ue->frame_parms.Ncp == NORMAL) {
+        // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p>=7
 
-        for (lprime=0; lprime<2; lprime++) {
+        output_p = output;
 
-          ind = 3*lprime*eNB->frame_parms.N_RB_DL;
-          l = lprime + ((Ns&1)<<1);
+        ind = 3*lprime*ue->frame_parms.N_RB_DL;
+        l = lprime + ((Ns&1)<<1);
 
-          // loop over pairs of PRBs, this is the periodicity of the W_bar_NCP sequence
-          // unroll the computations for the 6 pilots, select qpsk or nqpsk as function of W_bar_NCP
-          for (nPRB=0; nPRB<eNB->frame_parms.N_RB_DL; nPRB+=2) {
+        // loop over pairs of PRBs, this is the periodicity of the W_bar_NCP sequence
+        // unroll the computations for the 6 pilots, select qpsk or nqpsk as function of W_bar_NCP
+        for (nPRB=0; nPRB<ue->frame_parms.N_RB_DL; nPRB+=2) {
 
-            // First pilot
-            w = Wbar_NCP[p-7][l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
+          // First pilot
+          w = Wbar_NCP[p-7][l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
 
 
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=5;
-            ind++;
+          output_p++;
+          ind++;
 
-            w =  Wbar_NCP[p-7][3-l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
+          w =  Wbar_NCP[p-7][3-l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
 
-            // Second pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          // Second pilot
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=5;
-            ind++;
+          output_p++;
+          ind++;
 
-            w = Wbar_NCP[p-7][l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-            // Third pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          w = Wbar_NCP[p-7][l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
+          // Third pilot
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=2;
-            ind++;
+          output_p++;
+          ind++;
 
-            // Fourth pilot
-            w = Wbar_NCP[p-7][3-l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
+          // Fourth pilot
+          w = Wbar_NCP[p-7][3-l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
 
 
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=5;
-            ind++;
+          output_p++;
+          ind++;
 
-            w =  Wbar_NCP[p-7][l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
+          w =  Wbar_NCP[p-7][l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
 
-            // Fifth pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          // Fifth pilot
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=5;
-            ind++;
+          output_p++;
+          ind++;
 
-            w = Wbar_NCP[p-7][3-l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-            // Sixth pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
+          w = Wbar_NCP[p-7][3-l];
+          qpsk_p = (w==1) ? qpsk : nqpsk;
+          // Sixth pilot
+          ind_dword     = ind>>4;
+          ind_qpsk_symb = ind&0xf;
 
-            *output_p = qpsk_p[(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+          *output_p = qpsk_p[(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
 
 #ifdef DEBUG_DL_UESPEC
-            LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
-                  Ns,l,m,mprime_dword,mprime_qpsk_symb);
-            LOG_D(PHY,"index = %d\n",(eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+          LOG_D(PHY,"Ns %d, l %d, m %d,ind_dword %d, ind_qpsk_symbol %d\n",
+                Ns,l,m,ind_dword,ind_qpsk_symb);
+          LOG_D(PHY,"index = %d\n",(ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
 #endif
 
-            output_p+=2;
-            ind++;
-          }
+          output_p++;
+          ind++;
         }
       } else {
         LOG_E(PHY,"Special subframe not supported for UE specific pilots yet\n");
       }
     }
   } else if (p==5) {
-    LOG_E(PHY,"p=5 not supported for UE specific pilots yet\n");
+    if (SS_flag==0) {
+      output_p = output;
+
+      if (ue->frame_parms.Ncp == NORMAL) {
+        for (mprime=0;mprime<3*nRB_PDSCH;mprime++) {
+
+          ind = 3*lprime*nRB_PDSCH+mprime;
+          ind_dword = ind>>4;
+          ind_qpsk_symb = ind&0xf;
+
+          *output_p = qpsk[(ue->lte_gold_uespec_port5_table[Ns][ind_dword]>>(2*ind_qpsk_symb))&3];
+          //printf("lprime=%d,ind=%d,Ns=%d,output_p=(%d,%d)\n",lprime,ind,Ns,((short *)&output_p[0])[0],((short *)&output_p[0])[1]);
+          output_p++;
+      
+        }
+      }
+    }
   } else {
     LOG_E(PHY,"Illegal p %d UE specific pilots\n",p);
   }
@@ -224,60 +311,7 @@ int lte_dl_ue_spec(PHY_VARS_eNB *eNB,
   return(0);
 }
 
-/*
-int lte_dl_cell_spec_rx(PHY_VARS_UE *phy_vars_ue,
-      uint8_t eNB_offset,
-      int *output,
-      unsigned char Ns,
-      unsigned char l,
-      unsigned char p) {
-
-
-  unsigned char mprime,mprime_dword,mprime_qpsk_symb,m;
-  unsigned short k=0;
-  unsigned int qpsk[4];
-  short pamp;
 
-  // Compute the correct pilot amplitude, sqrt_rho_b = Q3.13
-  pamp = ONE_OVER_SQRT2_Q15;
-
-  // This includes complex conjugate for channel estimation
-
-  ((short *)&qpsk[0])[0] = pamp;
-  ((short *)&qpsk[0])[1] = -pamp;
-  ((short *)&qpsk[1])[0] = -pamp;
-  ((short *)&qpsk[1])[1] = -pamp;
-  ((short *)&qpsk[2])[0] = pamp;
-  ((short *)&qpsk[2])[1] = pamp;
-  ((short *)&qpsk[3])[0] = -pamp;
-  ((short *)&qpsk[3])[1] = pamp;
-
-  mprime = 110 - phy_vars_ue->frame_parms.N_RB_DL;
-
-  for (m=0;m<phy_vars_ue->frame_parms.N_RB_DL<<1;m++) {
-
-    mprime_dword     = mprime>>4;
-    mprime_qpsk_symb = mprime&0xf;
-
-    // this is r_mprime from 3GPP 36-211 6.10.1.2
-    output[k] = qpsk[(phy_vars_ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3];
-#ifdef DEBUG_DL_CELL_SPEC
-    printf("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
-     Ns,l,m,mprime_dword,mprime_qpsk_symb);
-    printf("index = %d (k %d)\n",(phy_vars_ue->lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
-#endif
-
-    mprime++;
-#ifdef DEBUG_DL_CELL_SPEC
-    if (m<4)
-    printf("Ns %d l %d output[%d] = (%d,%d)\n",Ns,l,k,((short *)&output[k])[0],((short *)&output[k])[1]);
-#endif
-    k++;
-  }
-  return(0);
-}
-
-*/
 
 #ifdef LTE_DL_CELL_SPEC_MAIN
 
@@ -303,51 +337,51 @@ main()
 
   lte_gold(Nid_cell,Ncp);
 
-  lte_dl_cell_spec(output00,
-                   ONE_OVER_SQRT2_Q15,
-                   50,
-                   Nid_cell,
-                   Ncp,
-                   0,
-                   0,
-                   0,
-                   0);
-
-  lte_dl_cell_spec(output10,
-                   ONE_OVER_SQRT2_Q15,
-                   50,
-                   Nid_cell,
-                   Ncp,
-                   0,
-                   1,
-                   0,
-                   0);
-
-  lte_dl_cell_spec(output01,
-                   ONE_OVER_SQRT2_Q15,
-                   50,
-                   Nid_cell,
-                   Ncp,
-                   0,
-                   0,
-                   1,
-                   0);
-
-  lte_dl_cell_spec(output11,
-                   ONE_OVER_SQRT2_Q15,
-                   50,
-                   Nid_cell,
-                   Ncp,
-                   0,
-                   1,
-                   1,
-                   0);
-
-
-  write_output("dl_cell_spec00.m","dl_cs00",output00,1024,1,1);
-  write_output("dl_cell_spec01.m","dl_cs01",output01,1024,1,1);
-  write_output("dl_cell_spec10.m","dl_cs10",output10,1024,1,1);
-  write_output("dl_cell_spec11.m","dl_cs11",output11,1024,1,1);
+  lte_dl_ue_spec(output00,
+                 ONE_OVER_SQRT2_Q15,
+                 50,
+                 Nid_cell,
+                 Ncp,
+                 0,
+                 0,
+                 0,
+                 0);
+
+  lte_dl_ue_spec(output10,
+                 ONE_OVER_SQRT2_Q15,
+                 50,
+                 Nid_cell,
+                 Ncp,
+                 0,
+                 1,
+                 0,
+                 0);
+
+  lte_dl_ue_spec(output01,
+                 ONE_OVER_SQRT2_Q15,
+                 50,
+                 Nid_cell,
+                 Ncp,
+                 0,
+                 0,
+                 1,
+                 0);
+
+  lte_dl_ue_spec(output11,
+                 ONE_OVER_SQRT2_Q15,
+                 50,
+                 Nid_cell,
+                 Ncp,
+                 0,
+                 1,
+                 1,
+                 0);
+
+
+  write_output("dl_ue_spec00.m","dl_cs00",output00,1024,1,1);
+  write_output("dl_ue_spec01.m","dl_cs01",output01,1024,1,1);
+  write_output("dl_ue_spec10.m","dl_cs10",output10,1024,1,1);
+  write_output("dl_ue_spec11.m","dl_cs11",output11,1024,1,1);
 }
 
 
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c
index 3f0a09a27e42f4419c57c56c33e50aae32dec67f..b15bc06cbdd1abf309f6c96862ae5dab1eae0d96 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold.c
@@ -131,6 +131,44 @@ void lte_gold_ue_spec(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_uespec_t
   }
 }
 
+void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_t Nid_cell, uint16_t n_rnti)
+{
+
+  unsigned char ns;
+  unsigned int n,x1,x2;
+
+
+  for (ns=0; ns<20; ns++) {
+
+    x2 = ((((ns>>1)+1)*((Nid_cell<<1)+1))<<16) + n_rnti;
+    //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
+    //n = 0
+    //printf("cinit (ns %d, l %d) => %d\n",ns,l,x2);
+    x1 = 1+ (1<<31);
+    x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
+
+    //skip first 50 double words (1600 bits)
+    //printf("n=0 : x1 %x, x2 %x\n",x1,x2);
+    for (n=1; n<50; n++) {
+      x1 = (x1>>1) ^ (x1>>4);
+      x1 = x1 ^ (x1<<31) ^ (x1<<28);
+      x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
+      x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
+      //printf("x1 : %x, x2 : %x\n",x1,x2);
+    }
+
+    for (n=0; n<38; n++) {
+      x1 = (x1>>1) ^ (x1>>4);
+      x1 = x1 ^ (x1<<31) ^ (x1<<28);
+      x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
+      x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
+      lte_gold_uespec_port5_table[ns][n] = x1^x2;
+      //printf("n=%d : c %x\n",n,x1^x2);
+    }
+
+  }
+}
+
 /*! \brief gold sequenquence generator
 \param x1
 \param x2 this should be set to c_init if reset=1
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index c27d156ad2be2d11c2e963e3da10cfbac1cd9c84..75583678176047ce1cb1f32484e9c5a6718675d5 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -66,7 +66,7 @@ uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t
 
   // compute REG based on symbol
   if ((lprime == 0)||
-      ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4)))
+      ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)))
     mprime = kprime/6;
   else
     mprime = kprime>>2;
@@ -293,7 +293,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
     for (row=0; row<RCC; row++) {
       //printf("col %d, index %d, row %d\n",col,index,row);
       if (index>=ND) {
-        for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
+        for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
           //printf("a %d k %d\n",a,k);
 
           wptr = &wtemp[a][k<<2];
@@ -317,7 +317,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
   // permutation
   for (i=0; i<Mquad; i++) {
 
-    for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
+    for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
 
       //wptr  = &wtemp[a][i<<2];
       //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
@@ -409,7 +409,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
               re_offset0++;
             }
           }
-        } else if ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4)) {
+        } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) {
           // LATER!!!!
         } else { // no pilots in this symbol
           kprime_mod12 = kprime%12;
@@ -647,7 +647,7 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
   int16x8_t *dl_ch128;
   int32x4_t *avg128P;
 #endif
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
 #if defined(__x86_64__) || defined(__i386__)
@@ -825,7 +825,7 @@ void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms,
   int32_t i;
 
   if (frame_parms->nb_antennas_rx>1) {
-    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
       //if (frame_parms->mode1_flag && (aatx>0)) break;
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -1391,8 +1391,8 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
   if (symbol==0)
     pilots=1;
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
-    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antennas_tx_eNB
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
+    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB
 
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
@@ -1598,7 +1598,7 @@ void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
   int32_t i;
 
   if (frame_parms->nb_antennas_rx>1) {
-    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
 #if defined(__x86_64__) || defined(__i386__)
       rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
@@ -1719,7 +1719,7 @@ int32_t rx_pdcch(LTE_UE_COMMON *common_vars,
                                high_speed_flag,
                                frame_parms);
 #endif //MU_RECEIVER
-    } else if (frame_parms->nb_antennas_tx_eNB>1) {
+    } else if (frame_parms->nb_antenna_ports_eNB>1) {
       pdcch_extract_rbs_dual(common_vars->rxdataF,
                              common_vars->dl_ch_estimates[eNB_id],
                              pdcch_vars[eNB_id]->rxdataF_ext,
@@ -1745,7 +1745,7 @@ int32_t rx_pdcch(LTE_UE_COMMON *common_vars,
 
   avgs = 0;
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
       avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
 
@@ -1986,10 +1986,10 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
   //if ((9*numCCE) <= (frame_parms->N_RB_DL*2))
   if (numCCE <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)))
     return(cmax(1,nCCEmin));
-  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 4 : 5)))
+  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5)))
   else if (numCCE <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)))
     return(cmax(2,nCCEmin));
-  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 7 : 8)))
+  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8)))
   else if (numCCE <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe)))
     return(cmax(3,nCCEmin));
   else if (frame_parms->N_RB_DL<=10) {
@@ -1999,10 +1999,10 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
              get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)),
              get_nCCE(3, frame_parms, get_mi(frame_parms, subframe)));
 
-      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 10 : 11)))
+      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11)))
         return(4);
     } else { // extended CP
-      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 9 : 10)))
+      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10)))
         return(4);
     }
   }
@@ -2247,7 +2247,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
         // Copy REG to TX buffer
 
         if ((lprime == 0)||
-            ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4))) {
+            ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) {
           // first symbol, or second symbol+4 TX antennas skip pilots
 
           kprime_mod12 = kprime%12;
@@ -2259,7 +2259,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
               if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) {
                 txdataF[0][tti_offset+i] = wbar[0][mprime];
 
-                if (frame_parms->nb_antennas_tx_eNB > 1)
+                if (frame_parms->nb_antenna_ports_eNB > 1)
                   txdataF[1][tti_offset+i] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2279,7 +2279,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
               for (i=0; i<4; i++) {
                 txdataF[0][tti_offset+i] = wbar[0][mprime];
 
-                if (frame_parms->nb_antennas_tx_eNB > 1)
+                if (frame_parms->nb_antenna_ports_eNB > 1)
                   txdataF[1][tti_offset+i] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2290,7 +2290,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
             } else {
               txdataF[0][tti_offset+0] = wbar[0][mprime];
 
-              if (frame_parms->nb_antennas_tx_eNB > 1)
+              if (frame_parms->nb_antenna_ports_eNB > 1)
                 txdataF[1][tti_offset+0] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2299,7 +2299,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
               mprime++;
               txdataF[0][tti_offset+1] = wbar[0][mprime];
 
-              if (frame_parms->nb_antennas_tx_eNB > 1)
+              if (frame_parms->nb_antenna_ports_eNB > 1)
                 txdataF[1][tti_offset+1] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2308,7 +2308,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
               mprime++;
               txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];
 
-              if (frame_parms->nb_antennas_tx_eNB > 1)
+              if (frame_parms->nb_antenna_ports_eNB > 1)
                 txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2318,7 +2318,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
               mprime++;
               txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];
 
-              if (frame_parms->nb_antennas_tx_eNB > 1)
+              if (frame_parms->nb_antenna_ports_eNB > 1)
                 txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
@@ -2936,12 +2936,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
       format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_1_5MHz_2A_TDD_t;
         format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_TDD_t;
         format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_1_5MHz_4A_TDD_t;
         format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_TDD_t;
@@ -2957,12 +2957,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
       format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_1_5MHz_2A_FDD_t;
         format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_FDD_t;
         format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_1_5MHz_4A_FDD_t;
         format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_FDD_t;
@@ -2984,12 +2984,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
       format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_5MHz_2A_TDD_t;
         format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_5MHz_2A_TDD_t;
         format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_5MHz_4A_TDD_t;
         format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_5MHz_4A_TDD_t;
@@ -3005,12 +3005,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
       format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_5MHz_2A_FDD_t;
         format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_5MHz_2A_FDD_t;
         format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_5MHz_4A_FDD_t;
         format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_5MHz_4A_FDD_t;
@@ -3031,12 +3031,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
       format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_10MHz_2A_TDD_t;
         format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_10MHz_2A_TDD_t;
         format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_10MHz_4A_TDD_t;
         format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_10MHz_4A_TDD_t;
@@ -3052,12 +3052,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
       format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_10MHz_2A_FDD_t;
         format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_10MHz_2A_FDD_t;
         format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_10MHz_4A_FDD_t;
         format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_10MHz_4A_FDD_t;
@@ -3078,12 +3078,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
       format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_20MHz_2A_TDD_t;
         format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_20MHz_2A_TDD_t;
         format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_20MHz_4A_TDD_t;
         format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t);
         format2A_size_bits  = sizeof_DCI2A_20MHz_4A_TDD_t;
@@ -3099,12 +3099,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
       format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
 
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         format2_size_bits  = sizeof_DCI2_20MHz_2A_FDD_t;
         format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_20MHz_2A_FDD_t;
         format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         format2_size_bits  = sizeof_DCI2_20MHz_4A_FDD_t;
         format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t);
         format2A_size_bits  = sizeof_DCI2A_20MHz_4A_FDD_t;
@@ -3368,7 +3368,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
 
   // These are for CRNTI based on transmission mode
-  if (tmode < 3) {
+  if ((tmode < 3) || (tmode == 7)) {
     // Now check UE_SPEC format 1 search spaces at aggregation 1
     old_dci_cnt=dci_cnt;
     dci_decoding_procedure0(pdcch_vars,0,subframe,
@@ -3737,7 +3737,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap1,
                             &CCEmap2);
     //#endif
-  } else if (tmode >=5) { // This is MU-MIMO
+  } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO
 
     // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1
 #ifdef DEBUG_DCI_DECODING
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index a1c118529adc99bc43b582a4b4ab6e529bc1779e..1dfbc9d7df4f5b322c7f460f679817c3522cdcbc 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -865,7 +865,8 @@ int generate_eNB_dlsch_params_from_dci(int frame,
                                        uint16_t si_rnti,
                                        uint16_t ra_rnti,
                                        uint16_t p_rnti,
-                                       uint16_t DL_pmi_single)
+                                       uint16_t DL_pmi_single,
+				       uint8_t beamforming_mode)
 {
 
   uint8_t harq_pid = UINT8_MAX;
@@ -1233,7 +1234,13 @@ int generate_eNB_dlsch_params_from_dci(int frame,
 
     dlsch0_harq->Nl          = 1;
     //    dlsch[0]->layer_index = 0;
-    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    if (beamforming_mode == 0)
+      dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    else if (beamforming_mode == 7)
+      dlsch0_harq->mimo_mode = TM7;
+    else
+      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
+      
     dlsch0_harq->dl_power_off = 1;
     /*
       if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
@@ -2682,7 +2689,7 @@ int generate_eNB_dlsch_params_from_dci(int frame,
   // compute DL power control parameters
   computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);
 
-  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
 
   return(0);
 }
@@ -3448,7 +3455,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
 
     if ((frame_parms->frame_type == TDD) &&
         (frame_parms->tdd_config>0)) {
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         switch(frame_parms->N_RB_DL) {
         case 6:
           LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
@@ -3527,7 +3534,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
           DevParam (frame_parms->N_RB_DL, 0, 0);
           break;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         switch(frame_parms->N_RB_DL) {
         case 6:
           LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%llx): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
@@ -3612,7 +3619,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
         }
       }
     } else if (frame_parms->frame_type == FDD) {
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         switch(frame_parms->N_RB_DL) {
         case 6:
           LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x):  rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
@@ -3686,7 +3693,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
           DevParam (frame_parms->N_RB_DL, 0, 0);
           break;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         switch(frame_parms->N_RB_DL) {
 
         case 6:
@@ -3810,7 +3817,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
-                                      uint16_t p_rnti)
+                                      uint16_t p_rnti,
+                                      uint8_t beamforming_mode)
 {
 
   uint8_t harq_pid=0;
@@ -4127,6 +4135,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
     dlsch0_harq->rvidx = rv;
     dlsch0_harq->Nl = 1;
     //    dlsch[0]->layer_index = 0;
+
     dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
     dlsch0_harq->dl_power_off = 1; //no power offset
 
@@ -4503,7 +4512,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
 
     dlsch[0]->rnti = rnti;
 
-    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    if (beamforming_mode == 0)
+      dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    else if (beamforming_mode == 7)
+      dlsch0_harq->mimo_mode   = TM7;
+    else
+      LOG_E(PHY,"Not supported beamforming mode %d\n",beamforming_mode);
+       
 
     dlsch0 = dlsch[0];
 
@@ -4513,7 +4528,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
     switch (frame_parms->N_RB_DL) {
 
     case 6:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4533,7 +4548,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
           tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -4554,13 +4569,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 25:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4582,7 +4597,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
           tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -4605,13 +4620,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 50:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4633,7 +4648,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tbswap    = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
           tpmi      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -4656,13 +4671,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 100:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4684,7 +4699,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tbswap    = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
           tpmi      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -4707,7 +4722,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
@@ -4902,7 +4917,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
     switch (frame_parms->N_RB_DL) {
 
     case 6:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4924,7 +4939,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
           tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -4949,13 +4964,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 25:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -4979,7 +4994,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
           tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -5006,13 +5021,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 50:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -5036,7 +5051,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
           tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -5063,13 +5078,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
 
     case 100:
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
@@ -5093,7 +5108,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
           tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
         }
-      } else if (frame_parms->nb_antennas_tx_eNB == 4) {
+      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
         if (frame_type == TDD) {
           mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
           mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
@@ -5120,7 +5135,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
           tpmi    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
         }
       } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
+        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
       }
 
       break;
@@ -5263,7 +5278,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
       }
     }
 
-    if (frame_parms->nb_antennas_tx_eNB == 2) {
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
       dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
 
@@ -5278,7 +5293,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0_harq->mimo_mode   = ALAMOUTI;
         dlsch1_harq->mimo_mode   = ALAMOUTI;
       }
-    } else if (frame_parms->nb_antennas_tx_eNB == 4) { // 4 antenna case
+    } else if (frame_parms->nb_antenna_ports_eNB == 4) { // 4 antenna case
       if ((dlsch0->active==1) && (dlsch1->active==1)) {
         switch (tpmi) {
         case 0: // one layer per transport block
@@ -5362,7 +5377,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
         }
       }
     } else {
-      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antennas_tx_eNB);
+      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antenna_ports_eNB);
     }
 
     if (mcs1 <= 28)
@@ -5575,7 +5590,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
   // compute DL power control parameters
   computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);
 
-  computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+  computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
 
   return(0);
 }
@@ -7791,7 +7806,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id)
   switch(transmission_mode) {
   case 1:
     for (count=0; count<frame_parms->N_RB_DL*12; count++) {
-      for(a_tx=0; a_tx<frame_parms->nb_antennas_tx_eNB; a_tx++) {
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
         for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
           s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],
                                  2)) - meas->n0_power_avg_dB;
@@ -7805,7 +7820,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id)
     for (count=0; count<frame_parms->N_RB_DL*12; count++) {
       abs_channel=0;
 
-      for(a_tx=0; a_tx<frame_parms->nb_antennas_tx_eNB; a_tx++) {
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
         for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
           abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2));
         }
@@ -7825,7 +7840,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id)
       qq = (q>>(((count/12)>>2)<<1))&3;
 
       //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
-      for(a_tx=0; a_tx<frame_parms->nb_antennas_tx_eNB; a_tx++) {
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
         for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
           switch(qq) {
           case 0:
@@ -7907,7 +7922,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id)
       qq = (q>>(((count/12)>>2)<<1))&3;
 
       //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
-      for(a_tx=0; a_tx<frame_parms->nb_antennas_tx_eNB; a_tx++) {
+      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
         for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
           switch(qq) {
           case 0:
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 442fd8216704a4f232396495d95ba1b77be93d8b..b6bbe09b31dcead2d2197ef17d9b34ffa2fee886 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -236,7 +236,11 @@ typedef struct {
 
 typedef struct {
   /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
-  uint32_t *txdataF[8];
+  int32_t *txdataF[8];
+  /// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
+  int32_t **ue_spec_bf_weights[4]; 
+  /// dl channel estimates (estimated from ul channel estimates)
+  int32_t **calib_dl_ch_estimates;
   /// Allocated RNTI (0 means DLSCH_t is not currently used)
   uint16_t rnti;
   /// Active flag for baseband transmitter processing
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 0284ca27adfd0ff34fed88b304b2732fd125080a..08279188639a026527a514c2327188aa266d8bc9 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -111,12 +111,14 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
   
 }
 
-LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag)
+LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms)
 {
 
   LTE_eNB_DLSCH_t *dlsch;
-  unsigned char exit_flag = 0,i,j,r;
+  unsigned char exit_flag = 0,i,j,r,aa,layer;
+  int re;
   unsigned char bw_scaling =1;
+  uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx;
 
   switch (N_RB_DL) {
   case 6:
@@ -145,6 +147,23 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
     dlsch->Mlimit = 4;
     dlsch->Nsoft = Nsoft;
 
+    for (layer=0; layer<4; layer++) {
+      dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
+  
+       for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+         dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
+         for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
+           dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
+         }
+       }
+     }
+
+     dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*));
+     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+       dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
+       
+     }
+
     for (i=0; i<10; i++)
       dlsch->harq_ids[i] = Mdlharq;
 
@@ -189,7 +208,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
         exit_flag=3;
       }
     }
-
+    
     if (exit_flag==0) {
       for (i=0; i<Mdlharq; i++) {
         dlsch->harq_processes[i]->round=0;
@@ -379,7 +398,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
 
   A = dlsch->harq_processes[harq_pid]->TBS; //6228
   mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
-  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe);
+  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0);
 
 
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
@@ -557,6 +576,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
   unsigned char mod_order;
   unsigned int Kr=0,Kr_bytes,r,r_offset=0;
   unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
+  uint8_t beamforming_mode=0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
 
@@ -564,7 +584,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
   // printf("Encoder: A: %d\n",A);
   mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
 
-  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe);
+  if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7)
+    beamforming_mode = 7;
+  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
+    beamforming_mode = 8;
+  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
+    beamforming_mode = 9;
+  G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode);
 
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index 036eb86b24c4a3bbcba645896ccd611b998ec021..33d798576871a02d75ee81e59e8c4cbe09f7e7b9 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -21,7 +21,7 @@
 
 /*! \file PHY/LTE_TRANSPORT/dlsch_demodulation.c
  * \brief Top-level routines for demodulating the PDSCH physical channel from 36-211, V8.6 2009-03
- * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert
+ * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert, X. Xiang
  * \date 2011
  * \version 0.1
  * \company Eurecom
@@ -89,9 +89,11 @@ int rx_pdsch(PHY_VARS_UE *ue,
   LTE_UE_DLSCH_t   **dlsch;
 
   unsigned char aatx,aarx;
-  unsigned short nb_rb;
+  unsigned short nb_rb=0;
   int avgs, rb;
   LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
+  
+  uint8_t beamforming_mode;
   uint32_t *rballoc;
 
   switch (type) {
@@ -99,12 +101,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
     pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
     dlsch          = &ue->dlsch_SI[eNB_id];
     dlsch0_harq       = dlsch[0]->harq_processes[harq_pid];
+    beamforming_mode  = 0;
     break;
 
   case RA_PDSCH:
     pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
     dlsch          = &ue->dlsch_ra[eNB_id];
     dlsch0_harq       = dlsch[0]->harq_processes[harq_pid];
+    beamforming_mode  = 0;
     break;
 
   case PDSCH:
@@ -112,6 +116,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     dlsch          = ue->dlsch[eNB_id];
     dlsch0_harq       = dlsch[0]->harq_processes[harq_pid];
     dlsch1_harq       = dlsch[1]->harq_processes[harq_pid];
+    beamforming_mode  = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
     break;
 
   default:
@@ -153,7 +158,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
   else
     rballoc = dlsch0_harq->rb_alloc_even;
 
-  if (frame_parms->nb_antennas_tx_eNB>1) {
+  if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
 #ifdef DEBUG_DLSCH_MOD
     LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]);
 #endif
@@ -195,8 +200,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                        ue->high_speed_flag,
                                        frame_parms);
     }
-  } // if n_tx>1
-  else {
+  } else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
     nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                      common_vars->dl_ch_estimates[eNB_id],
                                      pdsch_vars[eNB_id]->rxdataF_ext,
@@ -235,7 +239,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
 					 ue->high_speed_flag,
                                          frame_parms);
     }
-  } //else n_tx>1
+  } else if (beamforming_mode==7) { //else if beamforming_mode == 7
+    nb_rb = dlsch_extract_rbs_TM7(common_vars->rxdataF,
+                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates,
+                                  pdsch_vars[eNB_id]->rxdataF_ext,
+                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
+				  rballoc,
+                                  symbol,
+                                  subframe,
+                                  ue->high_speed_flag,
+                                  frame_parms);
+    
+  } else if(beamforming_mode>7) {
+    LOG_W(PHY,"dlsch_demodulation:beamforming mode not supported yet.\n");
+  }
 
   //  printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
   if (nb_rb==0) {
@@ -252,11 +269,19 @@ int rx_pdsch(PHY_VARS_UE *ue,
   nb_rb);
   */
   if (first_symbol_flag==1) {
-    dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
-                        frame_parms,
-                        avg,
-                        symbol,
-                        nb_rb);
+    if (beamforming_mode==0)
+       dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+                           frame_parms,
+                           avg,
+                           symbol,
+                           nb_rb);
+    else if (beamforming_mode==7)
+       dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
+                           frame_parms,
+                           avg,
+                           symbol,
+                           nb_rb);
+       
 #ifdef DEBUG_PHY
     LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
 #endif
@@ -266,7 +291,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     // in case of precoding we add an additional factor of two for the precoding gain
     avgs = 0;
 
-    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
         avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
 
@@ -274,7 +299,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
 
     pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1;
-    // + log2_approx(frame_parms->nb_antennas_tx_eNB-1) //-1 because log2_approx counts the number of bits
+    // + log2_approx(frame_parms->nb_antenna_ports_eNB-1) //-1 because log2_approx counts the number of bits
     //      + log2_approx(frame_parms->nb_antennas_rx-1);
 
     if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) &&
@@ -287,11 +312,11 @@ int rx_pdsch(PHY_VARS_UE *ue,
        Nb_tx*Nb_rx   in TM2,4,5
        Nb_tx^2*Nb_rx in TM6 */
     /*
-      K = frame_parms->nb_antennas_rx*frame_parms->nb_antennas_tx_eNB; //that also covers TM1 since Nb_tx=1
+      K = frame_parms->nb_antennas_rx*frame_parms->nb_antenna_ports_eNB; //that also covers TM1 since Nb_tx=1
       if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) &&
       (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) &&
       (dlsch0_harq->dl_power_off==1)) // we are in TM 6
-      K *= frame_parms->nb_antennas_tx_eNB;
+      K *= frame_parms->nb_antenna_ports_eNB;
 
       pdsch_vars[eNB_id]->log2_maxh = (log2_approx(K*avgs)/2);
     */
@@ -302,7 +327,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 #endif
   }
 
-  aatx = frame_parms->nb_antennas_tx_eNB;
+  aatx = frame_parms->nb_antenna_ports_eNB;
   aarx = frame_parms->nb_antennas_rx;
 
   if (dlsch0_harq->mimo_mode<LARGE_CDD) {// SISO or ALAMOUTI
@@ -363,7 +388,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
   } else if (dlsch0_harq->mimo_mode == LARGE_CDD) { // TM3
     //   LOG_I(PHY,"Running PDSCH RX for TM3\n");
-    if (frame_parms->nb_antennas_tx_eNB == 2) {
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
       if (first_symbol_flag==1) {
         // effective channel of desired user is always stronger than interfering eff. channel
         dlsch_channel_level_TM3(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
@@ -522,12 +547,28 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                       pdsch_vars[eNB_id]->log2_maxh,
                                       1);
     }
+  } else if (dlsch0_harq->mimo_mode==TM7) { //TM7
+
+    dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
+                               pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
+                               pdsch_vars[eNB_id]->dl_ch_mag0,
+                               pdsch_vars[eNB_id]->dl_ch_magb0,
+                               pdsch_vars[eNB_id]->rxdataF_comp0,
+                               (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
+                               frame_parms,
+                               symbol,
+                               first_symbol_flag,
+                               get_Qm(dlsch0_harq->mcs),
+                               nb_rb,
+                               //9,
+                               pdsch_vars[eNB_id]->log2_maxh,
+                               phy_measurements); // log2_maxh+I0_shift
   }
 
   //  printf("MRC\n");
   if (frame_parms->nb_antennas_rx > 1) {
     if (dlsch0_harq->mimo_mode == LARGE_CDD) {
-      if (frame_parms->nb_antennas_tx_eNB == 2) {
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
         dlsch_detection_mrc(frame_parms,
                             pdsch_vars[eNB_id]->rxdataF_comp0,
                             pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round],
@@ -561,8 +602,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
   //  printf("Combining");
   if ((dlsch0_harq->mimo_mode == SISO) ||
       ((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) &&
-       (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0))) {
-
+       (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0)) ||
+       (dlsch0_harq->mimo_mode == TM7)) {
     /*
       dlsch_siso(frame_parms,
       pdsch_vars[eNB_id]->rxdataF_comp,
@@ -599,7 +640,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                        pdsch_vars[eNB_id]->llr[0],
                        symbol,first_symbol_flag,nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128);
+                       pdsch_vars[eNB_id]->llr128,
+                       beamforming_mode);
       else if (i_mod == 2) {
         dlsch_qpsk_qpsk_llr(frame_parms,
                             pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -692,7 +734,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128);
+                      pdsch_vars[eNB_id]->llr128,
+                      beamforming_mode);
     } else if (i_mod == 2) {
       dlsch_16qam_qpsk_llr(frame_parms,
                            pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -738,7 +781,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       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]->llr128,
+                      beamforming_mode);
     } else if (i_mod == 2) {
       dlsch_64qam_qpsk_llr(frame_parms,
                            pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -781,7 +825,6 @@ int rx_pdsch(PHY_VARS_UE *ue,
     return(-1);
     break;
   }
-
   return(0);
 }
 
@@ -821,7 +864,7 @@ void dlsch_channel_compensation(int **rxdataF_ext,
       pilots=1;
   }
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
     if (mod_order == 4) {
       QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
       QAM_amp128b = _mm_setzero_si128();
@@ -1081,7 +1124,7 @@ void dlsch_channel_compensation(int **rxdataF_ext,
     }
   }
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
     if (mod_order == 4) {
       QAM_amp128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
       QAM_amp128b = vmovq_n_s16(0);
@@ -2594,7 +2637,7 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
 
   if (frame_parms->nb_antennas_rx>1) {
 
-    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
 
       rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
@@ -2654,7 +2697,7 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
 
   if (frame_parms->nb_antennas_rx>1) {
 
-    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
 
       rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
       rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
@@ -2736,7 +2779,7 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext,
 
   ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
       dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
@@ -2780,7 +2823,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
       avg128D = _mm_setzero_si128();
@@ -2837,7 +2880,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
       avg128D = vdupq_n_s32(0);
@@ -3054,6 +3097,76 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext,
 #endif
 }
 
+//compute average channel_level for TM7
+void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext,
+                         LTE_DL_FRAME_PARMS *frame_parms,
+                         int *avg,
+                         uint8_t symbol,
+                         unsigned short nb_rb)
+{
+
+#if defined(__x86_64__)||defined(__i386__)
+
+  short rb;
+  unsigned char aatx,aarx,nre=12,symbol_mod;
+  __m128i *dl_ch128,avg128D;
+
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
+    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+      //clear average level
+      avg128D = _mm_setzero_si128();
+      // 5 is always a symbol with no pilots for both normal and extended prefix
+
+      dl_ch128=(__m128i *)&dl_bf_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
+
+      for (rb=0; rb<nb_rb; rb++) {
+        //  printf("rb %d : ",rb);
+        //  print_shorts("ch",&dl_ch128[0]);
+        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
+        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
+
+        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
+          dl_ch128+=2;
+        } else {
+          avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
+          dl_ch128+=3;
+        }
+
+        /*
+          if (rb==0) {
+          print_shorts("dl_ch128",&dl_ch128[0]);
+          print_shorts("dl_ch128",&dl_ch128[1]);
+          print_shorts("dl_ch128",&dl_ch128[2]);
+          }
+        */
+      }
+
+      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1))))
+        nre=10;
+      else if ((frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12))
+        nre=9;
+      else if ((frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==9))
+        nre=8;
+      else
+        nre=12;
+
+      avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] +
+                             ((int*)&avg128D)[1] +
+                             ((int*)&avg128D)[2] +
+                             ((int*)&avg128D)[3])/(nb_rb*nre);
+
+      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
+    }
+
+  _mm_empty();
+  _m_empty();
+
+#elif defined(__arm__)
+
+#endif
+}
 
 void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
                     int **rxdataF_comp,
@@ -4183,50 +4296,907 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
   return(nb_rb/frame_parms->nb_antennas_rx);
 }
 
-//==============================================================================================
-// Auxiliary functions
-//==============================================================================================
+unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
+                                     int **dl_bf_ch_estimates,
+                                     int **rxdataF_ext,
+                                     int **dl_bf_ch_estimates_ext,
+                                     unsigned int *rb_alloc,
+                                     unsigned char symbol,
+                                     unsigned char subframe,
+                                     uint32_t high_speed_flag,
+                                     LTE_DL_FRAME_PARMS *frame_parms)
+{
 
-#ifdef USER_MODE
+  unsigned short rb,nb_rb=0;
+  unsigned char rb_alloc_ind;
+  unsigned char i,aarx,l,nsymb,skip_half=0,sss_symb,pss_symb=0;
+  int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
 
-void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round)
-{
+  unsigned char symbol_mod,pilots=0,uespec_pilots=0,j=0,poffset=0,uespec_poffset=0;
+  int8_t uespec_nushift = frame_parms->Nid_cell%3;
 
-  unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
-  char fname[32],vname[32];
-  int N_RB_DL=ue->frame_parms.N_RB_DL;
+  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+  pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
+  l=symbol;
+  nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
 
-  sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
-  sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+  if (frame_parms->Ncp==0){
+    if (symbol==3 || symbol==6 || symbol==9 || symbol==12)
+      uespec_pilots = 1;
+  } else{
+    if (symbol==4 || symbol==7 || symbol==10)
+      uespec_pilots = 1;
+  }
 
-  if (ue->frame_parms.nb_antennas_rx >1) {
-    sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
-    sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
+  if (frame_parms->frame_type == TDD) {// TDD
+    sss_symb = nsymb-1;
+    pss_symb = 2;
+  } else {
+    sss_symb = (nsymb>>1)-2;
+    pss_symb = (nsymb>>1)-1;
   }
 
-  sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
-  sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+  if (symbol_mod==(4-frame_parms->Ncp))
+    poffset=3;
 
-  if (ue->frame_parms.nb_antennas_rx == 2) {
-    sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
-    sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
-  }
+  if ((frame_parms->Ncp==0 && (symbol==6 ||symbol ==12)) || (frame_parms->Ncp==1 && symbol==7))
+    uespec_poffset=2;
 
-  if (ue->frame_parms.nb_antennas_tx_eNB == 2) {
-    sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
-    sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
-    if (ue->frame_parms.nb_antennas_rx == 2) {
-      sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
-      sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
-      write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
-    }
-  }
+    if (high_speed_flag == 1)
+      dl_ch0     = &dl_bf_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)];
+    else
+      dl_ch0     = &dl_bf_ch_estimates[aarx][0];
+
+    dl_ch0_ext = &dl_bf_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+
+    rxF_ext    = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
+    rxF        = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
+
+    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
+
+        if (rb < 32)
+          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+	if (rb_alloc_ind == 1)
+          nb_rb++;
+
+        // For second half of RBs skip DC carrier
+        if (rb==(frame_parms->N_RB_DL>>1)) {
+          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
+          //dl_ch0++;
+        }
+        
+        // PBCH
+        if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
+          rb_alloc_ind = 0;
+        }
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+
+
+        if (frame_parms->frame_type == FDD) {
+          //PSS
+          if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+        }
+
+        if ((frame_parms->frame_type == TDD) &&
+            (subframe==6)) { //TDD Subframe 6
+          if ((rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+        }
+
+        if (rb_alloc_ind==1) {
+
+          /*
+              printf("rb %d\n",rb);
+              for (i=0;i<12;i++)
+              printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
+              printf("\n");
+          */
+          if (pilots==0 && uespec_pilots==0) {
+            memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
+
+            for (i=0; i<12; i++) {
+              rxF_ext[i]=rxF[i];
+            }
+
+            dl_ch0_ext+=12;
+            rxF_ext+=12;
+          } else if(pilots==1 && uespec_pilots==0) {
+            j=0;
+
+            for (i=0; i<12; i++) {
+              if ((i!=(frame_parms->nushift+poffset)) &&
+                  (i!=((frame_parms->nushift+poffset+6)%12))) {
+                rxF_ext[j]=rxF[i];
+                dl_ch0_ext[j++]=dl_ch0[i];
+              }
+            }
+
+            dl_ch0_ext+=10;
+            rxF_ext+=10;
+
+          } else if (pilots==0 && uespec_pilots==1) {
+            j=0;
+
+
+	    for (i=0; i<12; i++){
+              if (frame_parms->Ncp==0){
+                if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){                
+		  rxF_ext[j] = rxF[i];
+                  dl_ch0_ext[j++]=dl_ch0[i];  
+                }
+              } else{
+                if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+		  rxF_ext[j] = rxF[i];
+                  dl_ch0_ext[j++]=dl_ch0[i];
+                }  
+              }
+  
+	    }
+             
+            dl_ch0_ext+=9-frame_parms->Ncp;
+            rxF_ext+=9-frame_parms->Ncp; 
+
+          } else {
+            msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
+            exit(-1);
+          }
+
+        }
+
+        dl_ch0+=12;
+        rxF+=12;
+
+      }
+    else {  // Odd number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
+        skip_half=0;
+
+        if (rb < 32)
+          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+        if (rb_alloc_ind == 1)
+          nb_rb++;
+
+        // PBCH
+        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
+          rb_alloc_ind = 0;
+        }
+
+        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
+        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=1;
+        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=2;
+
+        //SSS
+
+        if (((subframe==0)||(subframe==5)) &&
+            (rb>((frame_parms->N_RB_DL>>1)-3)) &&
+            (rb<((frame_parms->N_RB_DL>>1)+3)) &&
+            (l==sss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) &&
+            (rb==((frame_parms->N_RB_DL>>1)-3)) &&
+            (l==sss_symb))
+          skip_half=1;
+        else if (((subframe==0)||(subframe==5)) &&
+                 (rb==((frame_parms->N_RB_DL>>1)+3)) &&
+                 (l==sss_symb))
+          skip_half=2;
+
+        //PSS in subframe 0/5 if FDD
+        if (frame_parms->frame_type == FDD) {  //FDD
+          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
+          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+
+        if (rb_alloc_ind==1) {
+#ifdef DEBUG_DLSCH_DEMOD
+          printf("rb %d/symbol %d pilots %d, uespec_pilots %d, (skip_half %d)\n",rb,l,pilots,uespec_pilots,skip_half);
+#endif
+
+          if (pilots==0 && uespec_pilots==0) {
+            //printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+
+            if (skip_half==1) {
+              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
+
+              for (i=0; i<6; i++) {
+                rxF_ext[i]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+		printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+
+              dl_ch0_ext+=6;
+              rxF_ext+=6;
+            } else if (skip_half==2) {
+              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));
+
+              for (i=0; i<6; i++) {
+                rxF_ext[i]=rxF[(i+6)];
+#ifdef DEBUG_DLSCH_DEMOD
+		printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+
+              dl_ch0_ext+=6;
+              rxF_ext+=6;
+            } else {
+              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
+
+              for (i=0; i<12; i++){
+                rxF_ext[i]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+                printf("extract rb %d, re %d => (%d,%d)\n",symbol,rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
+#endif
+              }
+              dl_ch0_ext+=12;
+              rxF_ext+=12;
+            }
+          } else if (pilots==1 && uespec_pilots==0) {
+            // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+            j=0;
+
+            if (skip_half==1) {
+              for (i=0; i<6; i++) {
+                if (i!=((frame_parms->nushift+poffset)%6)) {
+                  rxF_ext[j]=rxF[i];
+                  dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+		printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                }
+              }
+
+              dl_ch0_ext+=5;
+              rxF_ext+=5;
+            } else if (skip_half==2) {
+              for (i=0; i<6; i++) {
+                if (i!=((frame_parms->nushift+poffset)%6)) {
+                  rxF_ext[j]=rxF[(i+6)];
+                  dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+		printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                }
+              }
+
+              dl_ch0_ext+=5;
+              rxF_ext+=5;
+            } else {
+              for (i=0; i<12; i++) {
+                if ((i!=(frame_parms->nushift+poffset)) &&
+                    (i!=((frame_parms->nushift+poffset+6)%12))) {
+                  rxF_ext[j]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+#endif
+                  dl_ch0_ext[j++]=dl_ch0[i];
+
+                }
+              }
+
+              dl_ch0_ext+=10;
+              rxF_ext+=10;
+            }
+          } else if(pilots==0 && uespec_pilots==1){
+            //printf("Extracting with uespec pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+            j=0;
+
+            if (skip_half==1) {
+              if (frame_parms->Ncp==0){
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+                    rxF_ext[j]=rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+       		    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
+                rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
+
+              } else{
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+                    rxF_ext[j]=rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+		    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=4;
+                rxF_ext+=4;
+              }
+
+            } else if (skip_half==2) {
+              if(frame_parms->Ncp==0){
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+                    rxF_ext[j]=rxF[(i+6)];
+                    dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+        	    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
+                rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
+
+              } else {
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+                    rxF_ext[j]=rxF[(i+6)];
+                    dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+		    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=4;
+                rxF_ext+=4;
+              }
+
+            } else {
+
+	      for (i=0; i<12; i++){
+                if (frame_parms->Ncp==0){
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+	            rxF_ext[j] = rxF[i];
+                    dl_ch0_ext[j++] = dl_ch0[i];  
+#ifdef DEBUG_DLSCH_DEMOD
+                    printf("extract rb %d, re %d, j %d => (%d,%d)\n",symbol,rb,i,j-1,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i]));
+#endif
+                  }
+                } else{
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+	            rxF_ext[j] = rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i]; 
+#ifdef DEBUG_DLSCH_DEMOD
+		    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  } 
+                }
+  
+	      }
+               
+              dl_ch0_ext+=9-frame_parms->Ncp;
+              rxF_ext+=9-frame_parms->Ncp; 
+	    }
+ 
+          } else {
+            msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
+            exit(-1);
+            
+          }
+        }
+
+        dl_ch0+=12;
+        rxF+=12;
+      } // first half loop
+
+
+      // Do middle RB (around DC)
+      if (rb < 32)
+        rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
+      else if (rb < 64)
+        rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
+      else if (rb < 96)
+        rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
+      else if (rb < 100)
+        rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
+      else
+        rb_alloc_ind = 0;
+
+      if (rb_alloc_ind == 1)
+        nb_rb++;
+
+      // PBCH
+      if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
+        rb_alloc_ind = 0;
+      }
+
+      //SSS
+      if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
+        rb_alloc_ind = 0;
+      }
+
+      if (frame_parms->frame_type == FDD) {
+        //PSS
+        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+      }
+
+      if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) {
+        //PSS
+        if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+      }
+
+      //printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+      //printf("DC rb %d (%p)\n",rb,rxF);
+      if (rb_alloc_ind==1) {
+        //printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+        if (pilots==0 && uespec_pilots==0) {
+          for (i=0; i<6; i++) {
+            dl_ch0_ext[i]=dl_ch0[i];
+            rxF_ext[i]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+          }
+
+          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+          for (; i<12; i++) {
+            dl_ch0_ext[i]=dl_ch0[i];
+            rxF_ext[i]=rxF[(1+i-6)];
+#ifdef DEBUG_DLSCH_DEMOD
+	    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+          }
+
+          dl_ch0_ext+=12;
+          rxF_ext+=12;
+        } else if(pilots==1 && uespec_pilots==0){ // pilots==1
+          j=0;
+
+          for (i=0; i<6; i++) {
+            if (i!=((frame_parms->nushift+poffset)%6)) {
+              dl_ch0_ext[j]=dl_ch0[i];
+              rxF_ext[j++]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	      printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+            }
+          }
+
+          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+          for (; i<12; i++) {
+            if (i!=((frame_parms->nushift+6+poffset)%12)) {
+              dl_ch0_ext[j]=dl_ch0[i];
+              rxF_ext[j++]=rxF[(1+i-6)];
+#ifdef DEBUG_DLSCH_DEMOD
+	      printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+            }
+          }
+
+          dl_ch0_ext+=10;
+          rxF_ext+=10;
+        } else if(pilots==0 && uespec_pilots==1) {
+          j=0;
+
+	  for (i=0; i<6; i++) {
+            if (frame_parms->Ncp==0){
+              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){                
+                dl_ch0_ext[j]=dl_ch0[i];  
+	        rxF_ext[j++] = rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+            } else {
+              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+                dl_ch0_ext[j]=dl_ch0[i];  
+	        rxF_ext[j++] = rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+    	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+            }
+	  }
+          
+          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+
+          for (; i<12; i++) {
+            if (frame_parms->Ncp==0){
+              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){                
+                dl_ch0_ext[j]=dl_ch0[i];
+                rxF_ext[j++]=rxF[(1+i-6)];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+            } else {
+              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
+                dl_ch0_ext[j]=dl_ch0[i];  
+	        rxF_ext[j++] = rxF[(1+i-6)];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+            }
+          }
+           
+          dl_ch0_ext+=9-frame_parms->Ncp;
+          rxF_ext+=9-frame_parms->Ncp; 
+          	  
+	}// symbol_mod==0
+
+      } // rballoc==1
+      else {
+        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
+      }
+
+      dl_ch0+=12;
+      rxF+=7;
+      rb++;
+
+      for (; rb<frame_parms->N_RB_DL; rb++) {
+        //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+        //  printf("rb %d (%p)\n",rb,rxF);
+        skip_half=0;
+
+        if (rb < 32)
+          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
+        else if (rb < 64)
+          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
+        else if (rb < 96)
+          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
+        else if (rb < 100)
+          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
+        else
+          rb_alloc_ind = 0;
+
+        if (rb_alloc_ind==1)
+          nb_rb++;
+
+        // PBCH
+        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
+          rb_alloc_ind = 0;
+        }
+
+        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
+        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=1;
+        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
+          skip_half=2;
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
+          rb_alloc_ind = 0;
+        }
+
+        //SSS
+        if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb))
+          skip_half=1;
+        else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb))
+          skip_half=2;
+
+        //PSS
+        if (frame_parms->frame_type == FDD) {
+          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
+          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
+            rb_alloc_ind = 0;
+          }
+
+          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
+            skip_half=1;
+          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
+            skip_half=2;
+        }
+
+        if (rb_alloc_ind==1) {
+#ifdef DEBUG_DLSCH_DEMOD
+           printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+#endif
+          /*
+              printf("rb %d\n",rb);
+            for (i=0;i<12;i++)
+            printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
+            printf("\n");
+          */
+          if (pilots==0 && uespec_pilots==0) {
+            //printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+            if (skip_half==1) {
+              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
+
+              for (i=0; i<6; i++) {
+                rxF_ext[i]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+
+              dl_ch0_ext+=6;
+              rxF_ext+=6;
+
+            } else if (skip_half==2) {
+              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));
+
+              for (i=0; i<6; i++) {
+                rxF_ext[i]=rxF[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+
+              dl_ch0_ext+=6;
+              rxF_ext+=6;
+
+            } else {
+              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
+              //printf("symbol %d, extract rb %d, => (%d,%d)\n",symbol,rb,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i]));
+
+              for (i=0; i<12; i++) {
+                rxF_ext[i]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+              }
+
+              dl_ch0_ext+=12;
+              rxF_ext+=12;
+            }
+          } else if (pilots==1 && uespec_pilots==0){
+            //printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
+            j=0;
+
+            if (skip_half==1) {
+              for (i=0; i<6; i++) {
+                if (i!=((frame_parms->nushift+poffset)%6)) {
+                  rxF_ext[j]=rxF[i];
+                  dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                }
+              }
+
+              dl_ch0_ext+=5;
+              rxF_ext+=5;
+            } else if (skip_half==2) {
+              for (i=0; i<6; i++) {
+                if (i!=((frame_parms->nushift+poffset)%6)) {
+                  rxF_ext[j]=rxF[(i+6)];
+                  dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+	          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                }
+              }
+
+              dl_ch0_ext+=5;
+              rxF_ext+=5;
+            } else {
+              for (i=0; i<12; i++) {
+                if ((i!=(frame_parms->nushift+poffset)) &&
+                    (i!=((frame_parms->nushift+poffset+6)%12))) {
+                  rxF_ext[j]=rxF[i];
+#ifdef DEBUG_DLSCH_DEMOD
+                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+#endif
+                  dl_ch0_ext[j++]=dl_ch0[i];
+                }
+              }
+
+              dl_ch0_ext+=10;
+              rxF_ext+=10;
+            }
+          } else if(pilots==0 && uespec_pilots==1) {
+            j=0;
+
+            if (skip_half==1) {
+              if (frame_parms->Ncp==0){
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+                    rxF_ext[j]=rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
+                rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
+
+              } else{
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+                    rxF_ext[j]=rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i];
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=4;
+                rxF_ext+=4;
+              }
+
+            } else if (skip_half==2) {
+              if(frame_parms->Ncp==0){
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+                    rxF_ext[j]=rxF[i+6];
+                    dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
+                rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
+
+              } else {
+                for (i=0; i<6; i++) {
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+                    rxF_ext[j]=rxF[(i+6)];
+                    dl_ch0_ext[j++]=dl_ch0[i+6];
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+                dl_ch0_ext+=4;
+                rxF_ext+=4;
+              }
+
+            } else {
+	      for (i=0; i<12; i++){
+                if (frame_parms->Ncp==0){
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
+	            rxF_ext[j] = rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i];  
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                } else{
+                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){                
+	            rxF_ext[j] = rxF[i];
+                    dl_ch0_ext[j++]=dl_ch0[i]; 
+#ifdef DEBUG_DLSCH_DEMOD
+	            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
+#endif
+                  }
+                }
+	      }
+               
+              dl_ch0_ext+=9-frame_parms->Ncp;
+              rxF_ext+=9-frame_parms->Ncp; 
+
+            }
+	      
+          }// pilots=0
+        }
+
+        dl_ch0+=12;
+        rxF+=12;
+      }
+    }
+  }
+
+  _mm_empty();
+  _m_empty();
+
+  return(nb_rb/frame_parms->nb_antennas_rx);
+}
+              
+
+              
+//==============================================================================================
+
+#ifdef USER_MODE
+
+void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round)
+{
+
+  unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
+  char fname[32],vname[32];
+  int N_RB_DL=ue->frame_parms.N_RB_DL;
+
+  sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
+  sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
+  write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+
+  if (ue->frame_parms.nb_antennas_rx >1) {
+    sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
+    sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
+    write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
+  }
+
+  sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
+  sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
+  write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+
+  if (ue->transmission_mode[eNB_id]==7){
+    sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
+    sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
+    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
+    //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);
+
+    sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
+    sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
+    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+  }
+
+  if (ue->frame_parms.nb_antennas_rx == 2) {
+    sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
+    sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
+    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
+  }
+
+  if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
+    sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
+    sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
+    write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+
+    if (ue->frame_parms.nb_antennas_rx == 2) {
+      sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
+      sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
+      write_output(fname,vname,ue->pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
+    }
+  }
+
+  sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
+  sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
+  write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
 
   /*
     write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
@@ -4240,7 +5210,7 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword
   sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
   write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
-  if (ue->frame_parms.nb_antennas_tx_eNB == 2) {
+  if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
     sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
     sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
     write_output(fname,vname,ue->pdsch_vars[eNB_id]->rxdataF_comp1[0][round],12*N_RB_DL*nsymb,1,1);
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index 92169858157a7dde25259b8ce6b2eaac9b708d2f..8165bc1f23f085e0df9a7b647cca08eaa3afbbf7 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -21,7 +21,7 @@
 
 /*! \file PHY/LTE_TRANSPORT/dlsch_llr_computation.c
  * \brief Top-level routines for LLR computation of the PDSCH physical channel from 36-211, V8.6 2009-03
- * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert, S. Wagner
+ * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert, S. Wagner, X Jiang
  * \date 2011
  * \version 0.1
  * \company Eurecom
@@ -632,7 +632,8 @@ 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)
+                   int16_t **llr32p,
+		   uint8_t beamforming_mode)
 {
 
   uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*frame_parms->N_RB_DL*12)];
@@ -657,6 +658,10 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
       len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
     else
       len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
   } else {
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
@@ -688,7 +693,8 @@ void dlsch_16qam_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)
+                     int16_t **llr32p,
+                     uint8_t beamforming_mode)
 {
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -731,11 +737,15 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
   if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
     if (frame_parms->mode1_flag==0)
-      len = nb_rb*8 - (2*pbch_pss_sss_adjust/3);
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
     else
-      len = nb_rb*10 - (5*pbch_pss_sss_adjust/6);
+      len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
   } else {
-    len = nb_rb*12 - pbch_pss_sss_adjust;
+    len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
   // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE)
@@ -811,7 +821,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,
+                     uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
   __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
@@ -841,11 +852,15 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
   if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
     if (frame_parms->mode1_flag==0)
-      len = nb_rb*8 - (2*pbch_pss_sss_adjust/3);
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
     else
-      len = nb_rb*10 - (5*pbch_pss_sss_adjust/6);
+      len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9) - (3*pbch_pss_sss_adjust/4);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3);
   } else {
-    len = nb_rb*12 - pbch_pss_sss_adjust;
+    len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
   llr2 = llr;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index bafa37b96f90922bbab35ae8d0114520c74d3b3e..d6e680344be663c9d330249ae627eb3006f51920 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -20,15 +20,15 @@
  */
 
 /*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c
-* \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03
-* \author R. Knopp, F. Kaltenberger
-* \date 2011
-* \version 0.1
-* \company Eurecom
-* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
-* \note
-* \warning
-*/
+ * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03
+ * \author R. Knopp, F. Kaltenberger
+ * \date 2011
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
+ * \note
+ * \warning
+ */
 #include "PHY/defs.h"
 #include "PHY/extern.h"
 #include "PHY/CODING/defs.h"
@@ -62,10 +62,36 @@ uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2nd
   return(0);
 }
 
-uint8_t is_not_UEspecRS(int first_layer,int re)
+/*uint8_t is_not_UEspecRS(int first_layer,int re)
 {
-
   return(1);
+}*/
+uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
+{
+  uint8_t offset = (lprime==1||lprime==3)?2:0;
+  if (lprime==-1)
+    return(1);
+
+  switch (beamforming_mode) {
+    case 7:
+      if (Ncp == NORMAL){
+        if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) &&  (re!=((nushift+8+offset)%12))) 
+          return(1);
+        /*else{
+          printf("(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset);
+        }*/
+      } else { 
+        if ((re!=nushift+offset) && (re!=((nushift+3+offset)%12)) && (re!=((nushift+6+offset)%12)) && (re!=((nushift+9+offset)%12)))
+          return(1);
+      }
+      break;
+
+    default:
+      msg("is_not_UEspecRS() [dlsch_modulation.c] : ERROR, unknown beamforming_mode %d\n",beamforming_mode);
+      return(-1);
+  }
+
+  return(0);
 }
 
 void generate_64qam_table(void)
@@ -102,36 +128,36 @@ void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t pr
 
   switch (precoding_index) {
 
-  case 0: // 1 1
-    *antenna1_sample=*antenna0_sample;
-    break;
+    case 0: // 1 1
+      *antenna1_sample=*antenna0_sample;
+      break;
 
-  case 1: // 1 -1
-    ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[0];
-    ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[1];
-    break;
+    case 1: // 1 -1
+      ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[0];
+      ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[1];
+      break;
 
-  case 2: // 1 j
-    ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[1];
-    ((int16_t *)antenna1_sample)[1] = ((int16_t *)antenna0_sample)[0];
-    break;
+    case 2: // 1 j
+      ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[1];
+      ((int16_t *)antenna1_sample)[1] = ((int16_t *)antenna0_sample)[0];
+      break;
 
-  case 3: // 1 -j
-    ((int16_t *)antenna1_sample)[0] = ((int16_t *)antenna0_sample)[1];
-    ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[0];
-    break;
+    case 3: // 1 -j
+      ((int16_t *)antenna1_sample)[0] = ((int16_t *)antenna0_sample)[1];
+      ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[0];
+      break;
   }
 
   // normalize
   /*  ((int16_t *)antenna0_sample)[0] = (int16_t)((((int16_t *)antenna0_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
-  ((int16_t *)antenna0_sample)[1] = (int16_t)((((int16_t *)antenna0_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  ((int16_t *)antenna1_sample)[0] = (int16_t)((((int16_t *)antenna1_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
-  ((int16_t *)antenna1_sample)[1] = (int16_t)((((int16_t *)antenna1_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  */
+      ((int16_t *)antenna0_sample)[1] = (int16_t)((((int16_t *)antenna0_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  ((int16_t *)antenna1_sample)[0] = (int16_t)((((int16_t *)antenna1_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
+      ((int16_t *)antenna1_sample)[1] = (int16_t)((((int16_t *)antenna1_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  */
 }
 
 uint32_t FOUR[2]={0,4};
 uint32_t TWO[2]={0,2};
 
-int allocate_REs_in_RB_no_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 					    int **txdataF,
 					    uint32_t *jj,
 					    uint32_t *jj2,
@@ -147,11 +173,14 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
 					    uint32_t *re_allocated,
 					    uint8_t skip_dc,
 					    uint8_t skip_half,
+					    uint8_t lprime,
+					    uint8_t mprime,
+					    uint8_t Ns,
 					    int *P1_SHIFT,
 					    int *P2_SHIFT)
 {
 
-
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
   uint8_t *x0             = dlsch0_harq->e;
   uint32_t qam16_table_offset_re = 0;
   uint32_t qam16_table_offset_im = 0;
@@ -205,7 +234,7 @@ int allocate_REs_in_RB_no_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
     return(0);
 }
 
-int allocate_REs_in_RB_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 					 int **txdataF,
 					 uint32_t *jj,
 					 uint32_t *jj2,
@@ -221,10 +250,14 @@ int allocate_REs_in_RB_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
 					 uint32_t *re_allocated,
 					 uint8_t skip_dc,
 					 uint8_t skip_half,
+					 uint8_t lprime,
+					 uint8_t mprime,
+					 uint8_t Ns,
 					 int *P1_SHIFT,
 					 int *P2_SHIFT)
 {
   
+  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
 
   uint8_t *x0             = dlsch0_harq->e;
   uint32_t qam16_table_offset_re = 0;
@@ -287,7 +320,7 @@ int allocate_REs_in_RB_pilots_16QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
   return(0);
 }
 
-int allocate_REs_in_RB_no_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 					    int **txdataF,
 					    uint32_t *jj,
 					    uint32_t *jj2,
@@ -303,10 +336,14 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
 					    uint32_t *re_allocated,
 					    uint8_t skip_dc,
 					    uint8_t skip_half,
+					    uint8_t lprime,
+					    uint8_t mprime,
+					    uint8_t Ns,
 					    int *P1_SHIFT,
 					    int *P2_SHIFT)
 {
 
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
 
   uint8_t *x0             = dlsch0_harq->e;
   uint32_t qam64_table_offset_re = 0;
@@ -423,7 +460,7 @@ int allocate_REs_in_RB_no_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
   return(0);
 }
 
-int allocate_REs_in_RB_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
 					 int **txdataF,
 					 uint32_t *jj,
 					 uint32_t *jj2,
@@ -439,10 +476,14 @@ int allocate_REs_in_RB_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
 					 uint32_t *re_allocated,
 					 uint8_t skip_dc,
 					 uint8_t skip_half,
+					 uint8_t lprime,
+					 uint8_t mprime,
+					 uint8_t Ns,
 					 int *P1_SHIFT,
 					 int *P2_SHIFT)
 {
   
+  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
 
   uint8_t *x0             = dlsch0_harq->e;
   uint32_t qam64_table_offset_re = 0;
@@ -511,7 +552,7 @@ int allocate_REs_in_RB_pilots_64QAM_siso(LTE_DL_FRAME_PARMS *frame_parms,
   return(0);
 }
 
-int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
                        int32_t **txdataF,
                        uint32_t *jj,
                        uint32_t *jj2,
@@ -527,11 +568,16 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
                        uint32_t *re_allocated,
                        uint8_t skip_dc,
                        uint8_t skip_half,
+		       uint8_t lprime,
+		       uint8_t mprime,
+		       uint8_t Ns,
 		       int *P1_SHIFT,
 		       int *P2_SHIFT)
 {
 
 
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
+
   uint8_t *x0             = dlsch0_harq->e;
   MIMO_mode_t mimo_mode   = dlsch0_harq->mimo_mode;
 
@@ -573,10 +619,21 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   int32_t tmp_sample1,tmp_sample2;
   int16_t tmp_amp=amp;
   int s=1;
+  int mprime2 = mprime,ind,ind_dword,ind_qpsk_symb;
 
   gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
   //  if (mimo_mode == LARGE_CDD) gain_lin_QPSK>>=1;
 
+  int32_t qpsk[4];
+  ((int16_t *)&qpsk[0])[0] = gain_lin_QPSK;
+  ((int16_t *)&qpsk[0])[1] = gain_lin_QPSK;
+  ((int16_t *)&qpsk[1])[0] = -gain_lin_QPSK;
+  ((int16_t *)&qpsk[1])[1] = gain_lin_QPSK;;
+  ((int16_t *)&qpsk[2])[0] = gain_lin_QPSK;;
+  ((int16_t *)&qpsk[2])[1] = -gain_lin_QPSK;;
+  ((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;;
+  ((int16_t *)&qpsk[3])[1] = -gain_lin_QPSK;
+
   if (dlsch1_harq) {
     x1             = dlsch1_harq->e;
     // Fill these in later for TM8-10
@@ -587,7 +644,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   }
 
 #ifdef DEBUG_DLSCH_MODULATION
-  printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]);
+  printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj],
+x0[1+*jj]);
 #endif
 
   first_re=0;
@@ -620,15 +678,11 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
         case 2:  //QPSK
 
 	  //          printf("re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
-          }
+	  ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
 
           *jj = *jj + 1;
 
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            ((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
-          }
+	  ((int16_t*)&txdataF[0][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
 
           *jj = *jj + 1;
 
@@ -661,12 +715,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
           *jj=*jj+1;
 
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
-            ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
-            //      ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-            //      ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
-          }
+	  ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
+	  ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
+	  //      ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+	  //      ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
           break;
 
@@ -706,10 +758,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
           *jj=*jj+1;
 
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];
-            ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];
-          }
+	  ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];
+	  ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];
 
           break;
 
@@ -912,7 +962,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
         *re_allocated = *re_allocated + 1;
 
-        if (frame_parms->nb_antennas_tx == 2) {
+        if (frame_parms->nb_antenna_ports_eNB == 2) {
           switch (mod_order0) {
           default:
             LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
@@ -1128,7 +1178,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
           ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
           ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
 
-          if (frame_parms->nb_antennas_tx == 2) {
+          if (frame_parms->nb_antenna_ports_eNB == 2) {
             layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
             ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
             ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
@@ -1168,7 +1218,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
           ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
           ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
 
-          if (frame_parms->nb_antennas_tx == 2) {
+          if (frame_parms->nb_antenna_ports_eNB == 2) {
             layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
             ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
             ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
@@ -1218,7 +1268,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
           ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
           ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
 
-          if (frame_parms->nb_antennas_tx == 2) {
+          if (frame_parms->nb_antenna_ports_eNB == 2) {
             layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
             ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
             ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
@@ -1226,7 +1276,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
           break;
 
-        }
+	}
       }
 
       if (mimo_mode == ALAMOUTI) {
@@ -1238,10 +1288,114 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
           *re_allocated = *re_allocated + 1;
         }
       }
+     
+      if (mimo_mode == TM7) {
+        *re_allocated = *re_allocated + 1;
+
+        if (is_not_UEspecRS(lprime,re,frame_parms->Nid_cell%3,frame_parms->Ncp,7)) {
+
+          switch (mod_order0){
+            case 2:  //QPSK
+
+              ((int16_t*)&txdataF[5][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj = *jj + 1;
+              ((int16_t*)&txdataF[5][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj = *jj + 1;
+
+              //printf("%d(%d) : %d,%d =>
+              //",tti_offset,*jj,((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[1]);
+              break;
+
+            case 4:  //16QAM
+
+              qam16_table_offset_re = 0;
+              qam16_table_offset_im = 0;
+
+              if (x0[*jj] == 1)
+                qam16_table_offset_re+=2;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam16_table_offset_im+=2;
+
+              *jj=*jj+1;
+
+
+              if (x0[*jj] == 1)
+                qam16_table_offset_re+=1;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam16_table_offset_im+=1;
+
+              *jj=*jj+1;
+
+              ((int16_t*)&txdataF[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+              ((int16_t*)&txdataF[5][tti_offset])[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+
+              break;
+
+            case 6:  //64QAM
+
+
+              qam64_table_offset_re = 0;
+              qam64_table_offset_im = 0;
 
-      if (mimo_mode >= TM8) { //TM8,TM9,TM10
+              if (x0[*jj] == 1)
+                qam64_table_offset_re+=4;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam64_table_offset_im+=4;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam64_table_offset_re+=2;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam64_table_offset_im+=2;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam64_table_offset_re+=1;
+
+              *jj=*jj+1;
+
+              if (x0[*jj] == 1)
+                qam64_table_offset_im+=1;
 
-        if (is_not_UEspecRS(first_layer0,re)) {
+              *jj=*jj+1;
+
+              ((int16_t*)&txdataF[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+              ((int16_t*)&txdataF[5][tti_offset])[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+
+              break;
+
+          }
+        } else {
+          //precoding UE spec RS
+          //printf("precoding UE spec RS\n");
+
+          ind = 3*lprime*dlsch0_harq->nb_rb+mprime2;
+          ind_dword = ind>>4;
+          ind_qpsk_symb = ind&0xf;
+
+          txdataF[5][tti_offset] = qpsk[(phy_vars_eNB->lte_gold_uespec_port5_table[0][Ns][ind_dword]>>(2*ind_qpsk_symb))&3];
+          mprime2++;
+
+        }
+
+      } else if (mimo_mode >= TM8) { //TM8,TM9,TM10
+	//uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
+
+        if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
           switch (mod_order0) {
           case 2:  //QPSK
 
@@ -1256,7 +1410,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
             break;
 
           case 4:  //16QAM
-            if (is_not_UEspecRS(0/*layer (FIXME uninitialized!)*/,re)) {
+            if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
               qam16_table_offset_re = 0;
               qam16_table_offset_im = 0;
 
@@ -1345,21 +1499,22 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   return(0);
 }
 
+
 int allocate_REs_in_RB_MCH(int32_t **txdataF,
                            uint32_t *jj,
-                           uint16_t re_offset,
-                           uint32_t symbol_offset,
-                           uint8_t *x0,
-                           uint8_t l,
-                           uint8_t mod_order,
-                           int16_t amp,
-                           int16_t *qam_table_s,
-                           uint32_t *re_allocated,
-                           uint8_t skip_dc,
-                           LTE_DL_FRAME_PARMS *frame_parms)
+                            uint16_t re_offset,
+                            uint32_t symbol_offset,
+                            uint8_t *x0,
+                            uint8_t l,
+                            uint8_t mod_order,
+                            int16_t amp,
+                            int16_t *qam_table_s,
+                            uint32_t *re_allocated,
+                            uint8_t skip_dc,
+                            LTE_DL_FRAME_PARMS *frame_parms)
 {
 
-  uint32_t tti_offset,aa;
+  uint32_t tti_offset;
   uint8_t re;
   uint8_t qam64_table_offset_re = 0;
   uint8_t qam64_table_offset_im = 0;
@@ -1397,99 +1552,91 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
 
 
     switch (mod_order) {
-    case 2:  //QPSK
+      case 2:  //QPSK
 
       //            printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
-        ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
+      ((int16_t*)&txdataF[4][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
 
       *jj = *jj + 1;
 
-      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
-        ((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
+      ((int16_t*)&txdataF[4][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
 
       *jj = *jj + 1;
 
       //      printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
       break;
 
-    case 4:  //16QAM
+      case 4:  //16QAM
 
-      qam16_table_offset_re = 0;
-      qam16_table_offset_im = 0;
+    qam16_table_offset_re = 0;
+    qam16_table_offset_im = 0;
 
-      if (x0[*jj] == 1)
-        qam16_table_offset_re+=2;
+    if (x0[*jj] == 1)
+      qam16_table_offset_re+=2;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam16_table_offset_im+=2;
+    if (x0[*jj] == 1)
+      qam16_table_offset_im+=2;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
 
-      if (x0[*jj] == 1)
-        qam16_table_offset_re+=1;
+    if (x0[*jj] == 1)
+      qam16_table_offset_re+=1;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam16_table_offset_im+=1;
+    if (x0[*jj] == 1)
+      qam16_table_offset_im+=1;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-        ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s[qam16_table_offset_re];
-        ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s[qam16_table_offset_im];
-        //      ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-        //      ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
-      }
+    ((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+    ((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
-      break;
+    break;
 
-    case 6:  //64QAM
+      case 6:  //64QAM
 
 
-      qam64_table_offset_re = 0;
-      qam64_table_offset_im = 0;
+    qam64_table_offset_re = 0;
+    qam64_table_offset_im = 0;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_re+=4;
+    if (x0[*jj] == 1)
+      qam64_table_offset_re+=4;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_im+=4;
+    if (x0[*jj] == 1)
+      qam64_table_offset_im+=4;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_re+=2;
+    if (x0[*jj] == 1)
+      qam64_table_offset_re+=2;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_im+=2;
+    if (x0[*jj] == 1)
+      qam64_table_offset_im+=2;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_re+=1;
+    if (x0[*jj] == 1)
+      qam64_table_offset_re+=1;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      if (x0[*jj] == 1)
-        qam64_table_offset_im+=1;
+    if (x0[*jj] == 1)
+      qam64_table_offset_im+=1;
 
-      *jj=*jj+1;
+    *jj=*jj+1;
 
-      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-        ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-        ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
-      }
+    ((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+    ((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
-      break;
+    break;
 
     }
   }
@@ -1506,38 +1653,38 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb)
 
   //  printf("Getting pmi for RB %d => %d\n",rb,(pmi_alloc>>((rb>>2)<<1))&3);
   switch (N_RB_DL) {
-  case 6:   // 1 PRB per subband
-    if (mode <= PUSCH_PRECODING1)
-      return((pmi_alloc>>(rb<<1))&3);
-    else
-      return((pmi_alloc>>rb)&1);
+    case 6:   // 1 PRB per subband
+      if (mode <= PUSCH_PRECODING1)
+        return((pmi_alloc>>(rb<<1))&3);
+      else
+        return((pmi_alloc>>rb)&1);
 
-    break;
+      break;
 
-  default:
-  case 25:  // 4 PRBs per subband
-    if (mode <= PUSCH_PRECODING1)
-      return((pmi_alloc>>((rb>>2)<<1))&3);
-    else
-      return((pmi_alloc>>(rb>>2))&1);
+    default:
+    case 25:  // 4 PRBs per subband
+      if (mode <= PUSCH_PRECODING1)
+        return((pmi_alloc>>((rb>>2)<<1))&3);
+      else
+        return((pmi_alloc>>(rb>>2))&1);
 
-    break;
+      break;
 
-  case 50: // 6 PRBs per subband
-    if (mode <= PUSCH_PRECODING1)
-      return((pmi_alloc>>((rb/6)<<1))&3);
-    else
-      return((pmi_alloc>>(rb/6))&1);
+    case 50: // 6 PRBs per subband
+      if (mode <= PUSCH_PRECODING1)
+        return((pmi_alloc>>((rb/6)<<1))&3);
+      else
+        return((pmi_alloc>>(rb/6))&1);
 
-    break;
+      break;
 
-  case 100: // 8 PRBs per subband
-    if (mode <= PUSCH_PRECODING1)
-      return((pmi_alloc>>((rb>>3)<<1))&3);
-    else
-      return((pmi_alloc>>(rb>>3))&1);
+    case 100: // 8 PRBs per subband
+      if (mode <= PUSCH_PRECODING1)
+        return((pmi_alloc>>((rb>>3)<<1))&3);
+      else
+        return((pmi_alloc>>(rb>>3))&1);
 
-    break;
+      break;
   }
 }
 
@@ -1679,14 +1826,15 @@ inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) {
 }
 
 
-int dlsch_modulation(int32_t **txdataF,
+int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
+                     int32_t **txdataF,
                      int16_t amp,
                      uint32_t subframe_offset,
-                     LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t num_pdcch_symbols,
                      LTE_eNB_DLSCH_t *dlsch0,
                      LTE_eNB_DLSCH_t *dlsch1)
 {
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
 
   uint8_t nsymb;
   uint8_t harq_pid = dlsch0->current_harq_pid;
@@ -1704,7 +1852,7 @@ int dlsch_modulation(int32_t **txdataF,
   int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8];
   int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8];
   int16_t *qam_table_s0=NULL,*qam_table_s1=NULL;
-  int (*allocate_REs)(LTE_DL_FRAME_PARMS *,
+  int (*allocate_REs)(PHY_VARS_eNB*,
 		      int **,
 		      uint32_t*,
 		      uint32_t*,
@@ -1720,10 +1868,17 @@ int dlsch_modulation(int32_t **txdataF,
 		      uint32_t *,
 		      uint8_t,
 		      uint8_t,
+		      uint8_t,
+		      uint8_t,
+		      uint8_t,
 		      int *,
 		      int *);
   int P1_SHIFT[13],P2_SHIFT[13];
   int offset,nushiftmod3;
+  MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode;
+  uint8_t mprime=0,Ns;
+  int8_t  lprime=-1;
+  int aa=0;
 
 #ifdef DEBUG_DLSCH_MODULATION
   uint8_t Nl0 = dlsch0_harq->Nl;
@@ -1746,7 +1901,7 @@ int dlsch_modulation(int32_t **txdataF,
   amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13);
 
   if (mod_order0 == 4)
-    for (i=0; i<4; i++) {
+    for (i=0;i<4; i++) {
       qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15);
       qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15);
     }
@@ -1804,6 +1959,39 @@ int dlsch_modulation(int32_t **txdataF,
         pilots=0;
     }
 
+    if(mimo_mode==TM7){ //36.211 V8.6.0 2009-03
+      mprime = 0;
+      if (frame_parms->Ncp==0) { // normal prefix
+        if (l==12)
+          lprime=3;   // pilots in nushift+3, nushift+9
+        else if (l==9)
+          lprime=2;   // pilots in nushift, nushift+6
+        else if (l==6)
+          lprime=1;   // pilots in nushift+3, nushift+9
+        else if (l==3)
+          lprime=0;   // pilots in nushift, nushift+6
+        else
+          lprime=-1;
+      } else {
+        if (l==10)
+          lprime=2;
+        else if (l==7)
+          lprime=1;
+        else if (l==4)
+          lprime=0;
+        else
+          lprime=-1;
+      }
+
+      // mapping ue specific beamforming weights from UE specified DLSCH structure to common space
+      for (aa=0;aa<frame_parms->nb_antennas_tx;aa++){
+        memcpy(phy_vars_eNB->common_vars.beam_weights[0][5][aa],dlsch0->ue_spec_bf_weights[0][aa],frame_parms->ofdm_symbol_size*sizeof(int32_t));
+      }
+ 
+    }
+  
+    Ns = 2*subframe_offset+(l>=(nsymb>>1));
+
     offset = (pilots==2)?3:0;
     nushiftmod3 = frame_parms->nushift%3;
 
@@ -1934,25 +2122,32 @@ int dlsch_modulation(int32_t **txdataF,
 
 
       if (rb_alloc_ind > 0) {
-	//	printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
-	allocate_REs(frame_parms,
-		     txdataF,
-		     &jj,
-		     &jj2,
-		     re_offset,
-		     symbol_offset,
-		     dlsch0->harq_processes[harq_pid],
-		     (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid],
-		     pilots,
-		     ((pilots) ? amp_rho_b : amp_rho_a),
-		     get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid],rb),
-		     qam_table_s0,
-		     qam_table_s1,
-		     &re_allocated,
-		     skip_dc,
-		     skip_half,
-		     P1_SHIFT,
-		     P2_SHIFT);
+        //      printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
+          allocate_REs(phy_vars_eNB,
+       		       txdataF,
+      		       &jj,
+      		       &jj2,
+      		       re_offset,
+      		       symbol_offset,
+      		       dlsch0->harq_processes[harq_pid],
+      		       (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid],
+      		       pilots,
+      		       ((pilots) ? amp_rho_b : amp_rho_a),
+      		       get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid],rb),
+      		       qam_table_s0,
+      		       qam_table_s1,
+      		       &re_allocated,
+      		       skip_dc,
+      		       skip_half,
+		       lprime,
+		       mprime,
+		       Ns,
+      		       P1_SHIFT,
+      		       P2_SHIFT);
+
+          if ((mimo_mode == TM7) && (lprime>=0))
+            mprime +=3+frame_parms->Ncp;
+
       }
       else {
 	//	printf("Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj);
@@ -1974,7 +2169,7 @@ int dlsch_modulation(int32_t **txdataF,
 
 
 #ifdef DEBUG_DLSCH_MODULATION
-  printf("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset));
+  printf("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1/*transmission mode*/));
 #endif
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
@@ -2073,7 +2268,7 @@ int mch_modulation(int32_t **txdataF,
 
 
 #ifdef DEBUG_DLSCH_MODULATION
-  printf("generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset));
+  printf("generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/));
 #endif
 
   return (re_allocated);
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index b77cb1bfa4534d5c4c8c1e7e1fe6883834274e97..75c558f52cba6042ce5249c83aae7924cc5fe513 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -152,7 +152,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 
   if (pbch_decoded) {
 
-    frame_parms->nb_antennas_tx_eNB = pbch_tx_ant;
+    frame_parms->nb_antenna_ports_eNB = pbch_tx_ant;
 
     // set initial transmission mode to 1 or 2 depending on number of detected TX antennas
     frame_parms->mode1_flag = (pbch_tx_ant==1);
@@ -522,7 +522,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 	  ue->frame_parms.N_RB_DL,
 	  ue->frame_parms.phich_config_common.phich_duration,
 	  phich_string[ue->frame_parms.phich_config_common.phich_resource],
-	  ue->frame_parms.nb_antennas_tx_eNB);
+	  ue->frame_parms.nb_antenna_ports_eNB);
 
 #if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
     LOG_I(PHY,"[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
index b4f158f8738e5b8b9fd27d4599f08be4f518836c..0abc1511ea78ad5877b9183163b3e018a803bd6c 100644
--- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
+++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -325,11 +325,8 @@ int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_orde
   return(0);
 }
 
-int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe)
+int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode)
 {
-
-
-
   int G_adj;
 
   if (is_pmch_subframe(frame,subframe,frame_parms) == 0) {
@@ -340,9 +337,11 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint
       // PDDDPDD PDDDPDD - 13 PDSCH symbols, 10 full, 3 w/ pilots = 10*12 + 3*8
       // PCDDPDD PDDDPDD - 12 PDSCH symbols, 9 full, 3 w/ pilots = 9*12 + 3*8
       // PCCDPDD PDDDPDD - 11 PDSCH symbols, 8 full, 3 w/pilots = 8*12 + 3*8
-      if (frame_parms->mode1_flag==0) // SISO
+      if (beamforming_mode==0 && frame_parms->mode1_flag==0) 
         return((((int)nb_rb * mod_order * ((11-num_pdcch_symbols)*12 + 3*8)) - G_adj)*Nl);
-      else
+      else if(beamforming_mode==7)
+        return(((int)nb_rb * mod_order * ((7-num_pdcch_symbols)*12 + 3*10 + 4*9)) - G_adj);
+      else //SISO
         return(((int)nb_rb * mod_order * ((11-num_pdcch_symbols)*12 + 3*10)) - G_adj);
     } else {
       // PDDPDD PDDPDD - 11 PDSCH symbols, 8 full, 3 w/ pilots = 8*12 + 3*8
@@ -350,7 +349,9 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint
       // PCCPDD PDDPDD - 9 PDSCH symbols, 6 full, 3 w/pilots = 6*12 + 3*8
       if (frame_parms->mode1_flag==0)
         return((((int)nb_rb * mod_order * ((9-num_pdcch_symbols)*12 + 3*8)) - G_adj)*Nl);
-      else
+      else if(beamforming_mode==7)
+        return(((int)nb_rb * mod_order * ((5-num_pdcch_symbols)*12 + 3*8 + 4*9)) - G_adj);
+      else //SISO
         return(((int)nb_rb * mod_order * ((9-num_pdcch_symbols)*12 + 3*10)) - G_adj);
     }
   } else { // This is an MBSFN subframe
diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c
index 03190de43ba00f50682133a31695efd63be8fd3a..8f6489861bcbba82daa2599e3927b86076be4fd9 100644
--- a/openair1/PHY/LTE_TRANSPORT/pbch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pbch.c
@@ -66,7 +66,7 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   MIMO_mode_t mimo_mode   = (frame_parms->mode1_flag==1)?SISO:ALAMOUTI;
 
 
-  uint32_t tti_offset,aa;
+  uint32_t tti_offset;
   uint8_t re;
   int16_t gain_lin_QPSK;
   int16_t re_off=re_offset;
@@ -91,15 +91,11 @@ int allocate_pbch_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
         *re_allocated = *re_allocated + 1;
 
         //    printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-        for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-          ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
-        }
+        ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
 
         *jj = *jj + 1;
 
-        for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-          ((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
-        }
+        ((int16_t*)&txdataF[0][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
 
         *jj = *jj + 1;
       } else if (mimo_mode == ALAMOUTI) {
@@ -192,7 +188,7 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch,
 
     /*
     // scramble crc with PBCH CRC mask (Table 5.3.1.1-1 of 3GPP 36.212-860)
-    switch (frame_parms->nb_antennas_tx_eNB) {
+    switch (frame_parms->nb_antenna_ports_eNB) {
     case 1:
     crc = crc ^ (uint16_t) 0;
     break;
@@ -224,7 +220,7 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch,
     if (frame_parms->mode1_flag == 1)
       amask = 0x0000;
     else {
-      switch (frame_parms->nb_antennas_tx_eNB) {
+      switch (frame_parms->nb_antenna_ports_eNB) {
       case 1:
         amask = 0x0000;
         break;
@@ -484,7 +480,7 @@ uint16_t pbch_extract(int **rxdataF,
       }
     }
 
-    for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antennas_tx_eNB;aatx++) {
+    for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) {
       if (high_speed_flag == 1)
         dl_ch0     = &dl_ch_estimates[(aatx<<1)+aarx][LTE_CE_OFFSET+ch_offset+(symbol*(frame_parms->ofdm_symbol_size))];
       else
@@ -546,7 +542,7 @@ int pbch_channel_level(int **dl_ch_estimates_ext,
   uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6;
   uint32_t symbol_mod = symbol % nsymb;
 
-  for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antennas_tx_eNB;aatx++)
+  for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       //clear average level
 
@@ -616,7 +612,7 @@ void pbch_channel_compensation(int **rxdataF_ext,
 #endif
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
-  for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antennas_tx_eNB;aatx++)
+  for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antenna_ports_eNB;aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
 
 #if defined(__x86_64__) || defined(__i386__)
@@ -723,7 +719,7 @@ void pbch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
   if (frame_parms->nb_antennas_rx>1) {
-    for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antennas_tx_eNB;aatx++) {
+    for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antenna_ports_eNB;aatx++) {
 #if defined(__x86_64__) || defined(__i386__)
       rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12];
       rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12];
@@ -1070,7 +1066,7 @@ uint16_t rx_pbch_emul(PHY_VARS_UE *phy_vars_ue,
   if (pbch_phase == (frame_rx % 4)) {
     if (uniformrandom() >= bler) {
       memcpy(phy_vars_ue->pbch_vars[eNB_id]->decoded_output,PHY_vars_eNB_g[eNB_id][CC_id]->pbch_pdu,PBCH_PDU_SIZE);
-      return(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.nb_antennas_tx_eNB);
+      return(PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.nb_antenna_ports_eNB);
     } else
       return(-1);
   } else
diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c
index 8af540eea16ec035f8ba451e25cdec6fe6a0033b..08a3d80904fb886948898cd227f45842f0e56d42 100644
--- a/openair1/PHY/LTE_TRANSPORT/pcfich.c
+++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c
@@ -208,7 +208,7 @@ void generate_pcfich(uint8_t num_pdcch_symbols,
       if ((i!=nushiftmod3)&&(i!=(nushiftmod3+3))) {
         txdataF[0][symbol_offset+reg_offset+i] = pcfich_d[0][m];
 
-        if (frame_parms->nb_antennas_tx_eNB>1)
+        if (frame_parms->nb_antenna_ports_eNB>1)
           txdataF[1][symbol_offset+reg_offset+i] = pcfich_d[1][m];
 
         m++;
diff --git a/openair1/PHY/LTE_TRANSPORT/pilots.c b/openair1/PHY/LTE_TRANSPORT/pilots.c
index a1f7d5bac6dfe29f7f4f837a89eb194338219517..a4d0fae2599d18c6a09ed229efd6b95e11d281a0 100644
--- a/openair1/PHY/LTE_TRANSPORT/pilots.c
+++ b/openair1/PHY/LTE_TRANSPORT/pilots.c
@@ -62,7 +62,7 @@ void generate_pilots(PHY_VARS_eNB *eNB,
     //    printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset);
     //Generate Pilots
 
-    //antenna 0 symbol 0 slot 0
+    //antenna port 0 symbol 0 slot 0
     lte_dl_cell_spec(eNB,&txdataF[0][tti_offset],
                      amp,
                      slot_offset,
@@ -71,7 +71,7 @@ void generate_pilots(PHY_VARS_eNB *eNB,
 
 
     //    printf("tti %d : second_pilot offset %d \n",tti,tti_offset+(second_pilot*samples_per_symbol));
-    //antenna 0 symbol 3/4 slot 0
+    //antenna port 0 symbol 3/4 slot 0
     lte_dl_cell_spec(eNB,&txdataF[0][tti_offset+(second_pilot*samples_per_symbol)],
                      amp,
                      slot_offset,
@@ -79,7 +79,7 @@ void generate_pilots(PHY_VARS_eNB *eNB,
                      0);
 
     //    printf("tti %d : third_pilot offset %d \n",tti,tti_offset+((Nsymb>>1)*samples_per_symbol));
-    //antenna 0 symbol 0 slot 1
+    //antenna port 0 symbol 0 slot 1
     lte_dl_cell_spec(eNB,&txdataF[0][tti_offset+((Nsymb>>1)*samples_per_symbol)],
                      amp,
                      1+slot_offset,
@@ -87,7 +87,7 @@ void generate_pilots(PHY_VARS_eNB *eNB,
                      0);
 
     //    printf("tti %d : third_pilot offset %d \n",tti,tti_offset+(((Nsymb>>1)+second_pilot)*samples_per_symbol));
-    //antenna 0 symbol 3/4 slot 1
+    //antenna port 0 symbol 3/4 slot 1
     lte_dl_cell_spec(eNB,&txdataF[0][tti_offset+(((Nsymb>>1)+second_pilot)*samples_per_symbol)],
                      amp,
                      1+slot_offset,
@@ -95,66 +95,35 @@ void generate_pilots(PHY_VARS_eNB *eNB,
                      0);
 
 
-    if (frame_parms->nb_antennas_tx > 1) {
-      if (frame_parms->mode1_flag) {
-        // antenna 1 symbol 0 slot 0
-        lte_dl_cell_spec(eNB,&txdataF[1][tti_offset],
-                         amp,
-                         slot_offset,
-                         0,
-                         0);
-
-        // antenna 1 symbol 3 slot 0
-        lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(second_pilot*samples_per_symbol)],
-                         amp,
-                         slot_offset,
-                         1,
-                         0);
+    if (frame_parms->nb_antenna_ports_eNB > 1) {
 
-        //antenna 1 symbol 0 slot 1
-        lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(Nsymb>>1)*samples_per_symbol],
-                         amp,
-                         1+slot_offset,
-                         0,
-                         0);
-
-        // antenna 1 symbol 3 slot 1
-        lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(((Nsymb>>1)+second_pilot)*samples_per_symbol)],
-                         amp,
-                         1+slot_offset,
-                         1,
-                         0);
-
-      } else {
-
-        // antenna 1 symbol 0 slot 0
+        // antenna port 1 symbol 0 slot 0
         lte_dl_cell_spec(eNB,&txdataF[1][tti_offset],
                          amp,
                          slot_offset,
                          0,
                          1);
 
-        // antenna 1 symbol 3 slot 0
+        // antenna port 1 symbol 3 slot 0
         lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(second_pilot*samples_per_symbol)],
                          amp,
                          slot_offset,
                          1,
                          1);
 
-        //antenna 1 symbol 0 slot 1
+        //antenna port 1 symbol 0 slot 1
         lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(Nsymb>>1)*samples_per_symbol],
                          amp,
                          1+slot_offset,
                          0,
                          1);
 
-        // antenna 1 symbol 3 slot 1
+        // antenna port 1 symbol 3 slot 1
         lte_dl_cell_spec(eNB,&txdataF[1][tti_offset+(((Nsymb>>1)+second_pilot)*samples_per_symbol)],
                          amp,
                          1+slot_offset,
                          1,
                          1);
-      }
     }
   }
 }
@@ -185,7 +154,7 @@ int generate_pilots_slot(PHY_VARS_eNB *eNB,
   //    printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset);
   //Generate Pilots
 
-  //antenna 0 symbol 0 slot 0
+  //antenna port 0 symbol 0 slot 0
   lte_dl_cell_spec(eNB,
                    &txdataF[0][slot_offset],
                    amp,
@@ -204,44 +173,24 @@ int generate_pilots_slot(PHY_VARS_eNB *eNB,
                      0);
   }
 
-  if (frame_parms->nb_antennas_tx > 1) {
-    if (frame_parms->mode1_flag) {
-      // antenna 1 symbol 0 slot 0
-      lte_dl_cell_spec(eNB,
-                       &txdataF[1][slot_offset],
-                       amp,
-                       slot,
-                       0,
-                       0);
+  if (frame_parms->nb_antenna_ports_eNB > 1) {
 
-      if (first_pilot_only==0) {
-        // antenna 1 symbol 3 slot 0
-        lte_dl_cell_spec(eNB,
-                         &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)],
-                         amp,
-                         slot,
-                         1,
-                         0);
-      }
-    } else {
+    // antenna port 1 symbol 0 slot 0
+    lte_dl_cell_spec(eNB,
+                     &txdataF[1][slot_offset],
+                     amp,
+                     slot,
+                     0,
+                     1);
 
-      // antenna 1 symbol 0 slot 0
+    if (first_pilot_only == 0) {
+      // antenna port 1 symbol 3 slot 0
       lte_dl_cell_spec(eNB,
-                       &txdataF[1][slot_offset],
+                       &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)],
                        amp,
                        slot,
-                       0,
+                       1,
                        1);
-
-      if (first_pilot_only == 0) {
-        // antenna 1 symbol 3 slot 0
-        lte_dl_cell_spec(eNB,
-                         &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)],
-                         amp,
-                         slot,
-                         1,
-                         1);
-      }
     }
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
new file mode 100644
index 0000000000000000000000000000000000000000..4a9010fca0daa712a9db006f0bbf87594283668f
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
@@ -0,0 +1,217 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
+
+  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+
+/*! \file PHY/LTE_TRANSPORT/uespec_pilots.c
+* \brief Top-level routines for generating DL ue-specific reference signals V12.5 2015-03
+* \author X.JIANG
+* \date 2011
+* \version 0.1
+* \company Eurecom
+* \email: xiwen.jiangeurecom.fr
+* \note
+* \warning
+*/
+//#include "defs.h"
+#include "PHY/defs.h"
+
+void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
+                     uint8_t UE_id,
+                     int32_t **txdataF,
+                     int16_t amp,
+                     uint16_t Ntti,
+		     uint8_t beamforming_mode)
+{
+
+  /*LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
+
+  uint32_t tti,tti_offset,slot_offset,Nsymb,samples_per_symbol;
+  uint8_t second_pilot,aa;
+
+  //  printf("Doing TX pilots Nsymb %d, second_pilot %d\n",Nsymb,second_pilot);
+  
+  switch(beamforming_mode){
+  case 7:
+    for (tti=0; tti<Ntti; tti++) {
+
+      tti_offset = tti*frame_parms->ofdm_symbol_size*Nsymb;
+      samples_per_symbol = frame_parms->ofdm_symbol_size;
+      slot_offset = (tti*2)%20;
+
+      //    printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset);
+      //Generate UE specific Pilots
+      printf("generate_dl_ue_spec:tti_offset=%d\n",tti_offset);
+
+      if(frame_parms->Ncp==0) {
+        for(aa=0;aa<frame_parms->nb_antennas_tx;aa++){ 
+          //antenna port 5 symbol 0 slot 0
+          lte_dl_ue_spec(phy_vars_eNB,
+                         UE_id,
+                         &txdataF[aa][tti_offset+3*samples_per_symbol],
+                         amp,
+                         slot_offset,
+              	         1,
+                         5,
+                         0);
+
+          //antenna port 5 symbol 1 slot 0
+          lte_dl_ue_spec(phy_vars_eNB,
+                         UE_id,
+                         &txdataF[aa][tti_offset+6*samples_per_symbol],
+                         amp,
+                         slot_offset,
+            	         1,
+                         5,
+                         0);
+
+          //antenna port 5 symbol 0 slot 1
+          lte_dl_ue_spec(phy_vars_eNB,
+                         UE_id,
+                         &txdataF[aa][tti_offset+9*samples_per_symbol],
+                         amp,
+                         slot_offset+1,
+            	         0,
+                         5,
+                         0);
+
+          //antenna port 5 symbol 1 slot 1
+          lte_dl_ue_spec(phy_vars_eNB,
+                         UE_id,
+                         &txdataF[aa][tti_offset+12*samples_per_symbol],
+                         amp,
+                         slot_offset+1,
+            	         1,
+                         5,
+                         0);
+	}
+      } else{
+      	msg("generate_ue_soec_pilots:Extented Cyclic Prefix for TM7 is not supported yet.\n");
+      }
+
+
+    }
+    break;
+
+  case 8:
+  case 9:
+  case 10:
+  default:
+    msg("[generate_ue_spec_pilots(in uespec_pilots.c)]ERROR:beamforming mode %d is not supported\n",beamforming_mode);
+    
+ }*/
+}
+
+/*int generate_ue_spec_pilots_slot(PHY_VARS_eNB *phy_vars_eNB,
+                         int32_t **txdataF,
+                         int16_t amp,
+                         uint16_t slot,
+                         int first_pilot_only)
+{
+
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
+  uint32_t slot_offset,Nsymb,samples_per_symbol;
+  uint8_t second_pilot;
+
+  if (slot<0 || slot>= 20) {
+    msg("generate_pilots_slot: slot not in range (%d)\n",slot);
+    return(-1);
+  }
+
+  Nsymb = (frame_parms->Ncp==0)?7:6;
+  second_pilot = (frame_parms->Ncp==0)?4:3;
+
+
+  slot_offset = slot*frame_parms->ofdm_symbol_size*Nsymb;
+  samples_per_symbol = frame_parms->ofdm_symbol_size;
+
+  //    printf("tti %d : offset %d (slot %d)\n",tti,tti_offset,slot_offset);
+  //Generate Pilots
+
+  //antenna 0 symbol 0 slot 0
+  lte_dl_cell_spec(phy_vars_eNB,
+                   &txdataF[0][slot_offset],
+                   amp,
+                   slot,
+                   0,
+                   0);
+
+
+  if (first_pilot_only==0) {
+    //antenna 0 symbol 3 slot 0
+    lte_dl_cell_spec(phy_vars_eNB,
+                     &txdataF[0][slot_offset+(second_pilot*samples_per_symbol)],
+                     amp,
+                     slot,
+                     1,
+                     0);
+  }
+
+  if (frame_parms->nb_antennas_tx > 1) {
+    if (frame_parms->mode1_flag) {
+      // antenna 1 symbol 0 slot 0
+      lte_dl_cell_spec(phy_vars_eNB,
+                       &txdataF[1][slot_offset],
+                       amp,
+                       slot,
+                       0,
+                       0);
+
+      if (first_pilot_only==0) {
+        // antenna 1 symbol 3 slot 0
+        lte_dl_cell_spec(phy_vars_eNB,
+                         &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)],
+                         amp,
+                         slot,
+                         1,
+                         0);
+      }
+    } else {
+
+      // antenna 1 symbol 0 slot 0
+      lte_dl_cell_spec(phy_vars_eNB,
+                       &txdataF[1][slot_offset],
+                       amp,
+                       slot,
+                       0,
+                       1);
+
+      if (first_pilot_only == 0) {
+        // antenna 1 symbol 3 slot 0
+        lte_dl_cell_spec(phy_vars_eNB,
+                         &txdataF[1][slot_offset+(second_pilot*samples_per_symbol)],
+                         amp,
+                         slot,
+                         1,
+                         1);
+      }
+    }
+  }
+
+  return(0);
+}*/
+
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index c4088a8a5b26de64e0fe2594a533418d4467836c..1a2838e5cfa3aa86839c9a56e4f4ed95dc60e8c9 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -305,7 +305,7 @@ void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a)
               eNB->frame_parms.N_RB_DL,
               eNB->dlsch_MCH->harq_processes[0]->rb_alloc,
               get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1,
-              2,proc->frame_tx,subframe);
+              2,proc->frame_tx,subframe,0);
 
     generate_mbsfn_pilot(eNB,proc,
                          eNB->common_vars.txdataF[0],
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 90971e4a846db58f8a9959c7c021bbd26183e58c..94aa21c7178362ace62b4161521e3f44472796e5 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -48,7 +48,7 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch);
 
 void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
 
-/** \fn new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
+/** \fn new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms)
     \brief This function allocates structures for a particular DLSCH at eNB
     @returns Pointer to DLSCH to be removed
     @param Kmimo Kmimo factor from 36-212/36-213
@@ -56,8 +56,9 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
     @param Nsoft Soft-LLR buffer size from UE-Category
     @params N_RB_DL total number of resource blocks (determine the operating BW)
     @param abstraction_flag Flag to indicate abstracted interface
+    @param frame_parms Pointer to frame descriptor structure
 */
-LTE_eNB_DLSCH_t *new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t N_RB_DL, uint8_t abstraction_flag);
+LTE_eNB_DLSCH_t *new_eNB_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms);
 
 /** \fn free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
     \brief This function frees memory allocated for a particular DLSCH at UE
@@ -158,6 +159,45 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
                          LTE_eNB_DLSCH_t *dlsch);
 
 
+// Functions below implement 36-211
+
+/** \fn allocate_REs_in_RB(int32_t **txdataF,
+    uint32_t *jj,
+    uint32_t *jj2,
+    uint16_t re_offset,
+    uint32_t symbol_offset,
+    LTE_DL_eNB_HARQ_t *dlsch0_harq,
+    LTE_DL_eNB_HARQ_t *dlsch1_harq,
+    uint8_t pilots,
+    int16_t amp,
+    int16_t *qam_table_s,
+    uint32_t *re_allocated,
+    uint8_t skip_dc,
+    uint8_t skip_half,
+    uint8_t use2ndpilots,
+    LTE_DL_FRAME_PARMS *frame_parms);
+
+    \brief Fills RB with data
+    \param txdataF pointer to output data (frequency domain signal)
+    \param jj index to output (from CW 1)
+    \param jj index to output (from CW 2)
+    \param re_offset index of the first RE of the RB
+    \param symbol_offset index to the OFDM symbol
+    \param dlsch0_harq Pointer to Transport block 0 HARQ structure
+    \param dlsch0_harq Pointer to Transport block 1 HARQ structure
+    \param pilots =1 if symbol_offset is an OFDM symbol that contains pilots, 0 otherwise
+    \param amp Amplitude for symbols
+    \param qam_table_s0 pointer to scaled QAM table for Transport Block 0 (by rho_a or rho_b)
+    \param qam_table_s1 pointer to scaled QAM table for Transport Block 1 (by rho_a or rho_b)
+    \param re_allocated pointer to allocation counter
+    \param skip_dc offset for positive RBs
+    \param skip_half indicate that first or second half of RB must be skipped for PBCH/PSS/SSS
+    \param ue_spec_rs UE specific RS indicator 
+    \param nb_antennas_tx_phy Physical antenna elements which can be different with antenna port number, especially in beamforming case
+    \param use2ndpilots Set to use the pilots from antenna port 1 for PDSCH
+    \param frame_parms Frame parameter descriptor
+*/
+
 // Functions below implement 36-211
 
 /** \fn allocate_REs_in_RB(int32_t **txdataF,
@@ -195,7 +235,7 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
     \param frame_parms Frame parameter descriptor
 */
 
-int32_t allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
+int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
                            int32_t **txdataF,
                            uint32_t *jj,
                            uint32_t *jj2,
@@ -211,6 +251,9 @@ int32_t allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
                            uint8_t skip_half,
+			   uint8_t lprime,
+			   uint8_t mprime,
+			   uint8_t Ns,
 			   int *P1_SHIFT,
 			   int *P2_SHIFT);
 
@@ -230,12 +273,11 @@ int32_t allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
     @param num_pdcch_symbols Number of PDCCH symbols in this subframe
     @param dlsch0 Pointer to Transport Block 0 DLSCH descriptor for this allocation
     @param dlsch1 Pointer to Transport Block 0 DLSCH descriptor for this allocation
-
 */
-int32_t dlsch_modulation(int32_t **txdataF,
+int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
+                         int32_t **txdataF,
                          int16_t amp,
                          uint32_t sub_frame_offset,
-                         LTE_DL_FRAME_PARMS *frame_parms,
                          uint8_t num_pdcch_symbols,
                          LTE_eNB_DLSCH_t *dlsch0,
                          LTE_eNB_DLSCH_t *dlsch1);
@@ -329,6 +371,13 @@ int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
 			     int32_t **txdataF,
                              int16_t amp);
 
+void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
+                             uint8_t UE_id,
+                             int32_t **txdataF,
+                             int16_t amp,
+                             uint16_t Ntti,
+		             uint8_t beamforming_mode);
+
 int32_t generate_pss(int32_t **txdataF,
                      int16_t amp,
                      LTE_DL_FRAME_PARMS *frame_parms,
@@ -714,6 +763,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     @param nb_rb number of RBs for this allocation
     @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
     @param llr128p pointer to pointer to symbol in dlsch_llr
+    @param beamforming_mode beamforming mode
 */
 int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                        int32_t **rxdataF_comp,
@@ -722,7 +772,8 @@ 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);
 
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -735,6 +786,7 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
    @param nb_rb number of RBs for this allocation
    @param pbch_pss_sss_adjust  Adjustment factor in RE for PBCH/PSS/SSS allocations
    @param llr128p pointer to pointer to symbol in dlsch_llr
+   @param beamforming_mode beamforming mode
 */
 
 void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
@@ -745,7 +797,8 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr128p);
+                     int16_t **llr128p,
+                     uint8_t beamforming_mode);
 
 /**
    \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
@@ -758,6 +811,7 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
    @param first_symbol_flag
    @param nb_rb number of RBs for this allocation
    @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
+   @param beamforming_mode beamforming mode
 */
 void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      int32_t **rxdataF_comp,
@@ -768,7 +822,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,
-                     short **llr_save);
+                     int16_t **llr_save,
+                     uint8_t beamforming_mode);
 
 /** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
     int32_t **rxdataF_comp,
@@ -939,6 +994,37 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
                                 uint32_t high_speed_flag,
                                 LTE_DL_FRAME_PARMS *frame_parms);
 
+/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
+    int32_t **dl_bf_ch_estimates,
+    int32_t **rxdataF_ext,
+    int32_t **dl_bf_ch_estimates_ext,
+    uint32_t *rb_alloc,
+    uint8_t symbol,
+    uint8_t subframe,
+    uint32_t high_speed_flag,
+    LTE_DL_FRAME_PARMS *frame_parms)
+    \brief This function extracts the received resource blocks, both channel estimates and data symbols,
+    for the current allocation and for single antenna eNB transmission.
+    @param rxdataF Raw FFT output of received signal
+    @param dl_bf_ch_estimates Beamforming channel estimates of current slot
+    @param rxdataF_ext FFT output for RBs in this allocation
+    @param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
+    @param rb_alloc RB allocation vector
+    @param symbol Symbol to extract
+    @param subframe Subframe number
+    @param high_speed_flag
+    @param frame_parms Pointer to frame descriptor
+*/
+uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
+                               int32_t **dl_bf_ch_estimates,
+                               int32_t **rxdataF_ext,
+                               int32_t **dl_bf_ch_estimates_ext,
+                               uint32_t *rb_alloc,
+                               uint8_t symbol,
+                               uint8_t subframe,
+                               uint32_t high_speed_flag,
+                               LTE_DL_FRAME_PARMS *frame_parms);
+
 /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation.  In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
     @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
     @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
@@ -1029,6 +1115,12 @@ void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext,
                               uint8_t symbol_mod,
                               uint16_t nb_rb);
 
+void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
+                         LTE_DL_FRAME_PARMS *frame_parms,
+                         int32_t *avg,
+                         uint8_t pilots_flag,
+                         uint16_t nb_rb);
+
 void dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
                          LTE_DL_FRAME_PARMS *frame_parms,
                          LTE_UE_DLSCH_t **dlsch_ue,
@@ -1293,7 +1385,7 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
 */
 uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
 
-int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe);
+int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
 
 int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
 int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
@@ -1406,7 +1498,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
-                                      uint16_t p_rnti);
+                                      uint16_t p_rnti,
+                                      uint8_t beamforming_mode);
 
 int32_t generate_eNB_dlsch_params_from_dci(int frame,
     uint8_t subframe,
@@ -1419,7 +1512,8 @@ int32_t generate_eNB_dlsch_params_from_dci(int frame,
     uint16_t si_rnti,
     uint16_t ra_rnti,
     uint16_t p_rnti,
-    uint16_t DL_pmi_single);
+    uint16_t DL_pmi_single,
+    uint8_t beamforming_mode);
 
 int32_t generate_eNB_ulsch_params_from_rar(uint8_t *rar_pdu,
     frame_t frame,
@@ -1636,7 +1730,7 @@ uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t s
     @param subframe Subframe of received/transmitted PHICH
     @returns frame of PUSCH transmission
 */
-uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe);;
+uint8_t phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe);
 
 void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
 
@@ -1838,6 +1932,8 @@ int is_pmch_subframe(frame_t frame, int subframe, LTE_DL_FRAME_PARMS *frame_parm
 
 uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots);
 
+uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
+
 uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
                                     LTE_DL_FRAME_PARMS *lte_frame_parms,
                                     LTE_UE_DLSCH_t *dlsch,
diff --git a/openair1/PHY/LTE_TRANSPORT/pss.c b/openair1/PHY/LTE_TRANSPORT/pss.c
index f74675157bb5d89a94bde9dcf71c14507c51af8f..44c7bffd9a5e051fede7f5080ab2bf8a569538b3 100644
--- a/openair1/PHY/LTE_TRANSPORT/pss.c
+++ b/openair1/PHY/LTE_TRANSPORT/pss.c
@@ -72,12 +72,12 @@ int generate_pss(int32_t **txdataF,
     return(-1);
   }
 
-  a = (frame_parms->nb_antennas_tx == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15;
+  a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15;
   //printf("[PSS] amp=%d, a=%d\n",amp,a);
 
   Nsymb = (frame_parms->Ncp==NORMAL)?14:12;
 
-  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+  for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
     //  aa = 0;
 
     // The PSS occupies the inner 6 RBs, which start at
diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c
index 39112725b12369d185e1e87126a1021d81223aa5..320d7ac75ad7604b964a075a58ae10b4ebda761b 100644
--- a/openair1/PHY/LTE_TRANSPORT/sss.c
+++ b/openair1/PHY/LTE_TRANSPORT/sss.c
@@ -59,10 +59,10 @@ int generate_sss(int32_t **txdataF,
 
   Nsymb = (frame_parms->Ncp==NORMAL)?14:12;
   k = frame_parms->ofdm_symbol_size-3*12+5;
-  a = (frame_parms->nb_antennas_tx == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15;
+  a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15;
 
   for (i=0; i<62; i++) {
-    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+    for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
 
       ((int16_t*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size +
                                  symbol*frame_parms->ofdm_symbol_size + k)] =
diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c
new file mode 100644
index 0000000000000000000000000000000000000000..6557a47ee7a35c6d31ea267cdb7762c0ffede9d5
--- /dev/null
+++ b/openair1/PHY/MODULATION/beamforming.c
@@ -0,0 +1,91 @@
+/*******************************************************************************
+  OpenAirInterface
+  Copyright(c) 1999 - 2014 Eurecom
+
+  OpenAirInterface is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+
+  OpenAirInterface is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with OpenAirInterface.The full GNU General Public License is
+  included in this distribution in the file called "COPYING". If not,
+  see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
+
+Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+
+/*! \file PHY/MODULATION/beamforming.c
+ * \brief 
+ * \author X. JIANG, F. Kaltenberger, R. KNOPP
+ * \date 2016
+ * \version 0.1
+ * \company Eurecom
+ * \email: xiwen.jiang@eurecom.fr,florian.kaltenberger@eurecom.fr,raymond.knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#include "PHY/defs.h"
+#include "PHY/extern.h"
+#include "PHY/CODING/defs.h"
+#include "PHY/CODING/extern.h"
+#include "PHY/CODING/lte_interleaver_inline.h"
+#include "PHY/LTE_TRANSPORT/defs.h"
+#include "defs.h"
+#include "UTIL/LOG/vcd_signal_dumper.h"
+
+int beam_precoding(int32_t **txdataF,
+	           int32_t **txdataF_BF,
+                   LTE_DL_FRAME_PARMS *frame_parms,
+	           int32_t ***beam_weights,
+                   int slot,
+                   int symbol,
+                   int aa)
+{
+  uint8_t p;
+  uint16_t re=0;
+  int slot_offset_F;
+  
+  slot_offset_F = slot*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
+
+  // clear txdata_BF[aa][re] for each call of ue_spec_beamforming
+  memset(txdataF_BF[aa],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
+
+  for (p=0; p<14; p++) {
+    //if (p==0 || p==1 || p==5 || p>7)
+    //  mult_cpx_conj_vector((int16_t*)txdataF[p], (int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15);
+    for (re=0;re<frame_parms->ofdm_symbol_size;re++) {
+      if ((p==0 || p==1 || p==5 || p>=7) && txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) {
+        ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15);
+        ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15);
+        ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15);
+        ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15);
+
+	  /*
+          printf("beamforming.c:txdataF[%d][%d]=%d+j%d, beam_weights[%d][%d][%d]=%d+j%d,txdata_BF[%d][%d]=%d+j%d\n",
+                 p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re,
+                 ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0],
+                 ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1],
+                 p,aa,re,
+                 ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1],
+                 aa,re,
+                 ((int16_t*)&txdataF_BF[aa][re])[0],
+                 ((int16_t*)&txdataF_BF[aa][re])[1]); 
+	  */
+      } 
+    }
+  }
+  return 0;
+}
diff --git a/openair1/PHY/MODULATION/compute_bf_weights.c b/openair1/PHY/MODULATION/compute_bf_weights.c
new file mode 100644
index 0000000000000000000000000000000000000000..32a91c11f50706718e3c75823ec48a67c6d9806c
--- /dev/null
+++ b/openair1/PHY/MODULATION/compute_bf_weights.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <stdint.h>
+#include "PHY/impl_defs_lte.h"
+
+int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs){
+
+  FILE *calibF_fd;
+  int i,j,l,calibF_e;
+  
+  calibF_fd = fopen(calibF_fname,"r");
+ 
+  if (calibF_fd) {
+    printf("Loading Calibration matrix from %s\n", calibF_fname);
+  
+    for(i=0;i<nb_ant;i++){
+      for(j=0;j<nb_freq*2;j++){
+  fscanf(calibF_fd, "%d", &calibF_e);
+        tdd_calib_coeffs[i][j] = (int16_t)calibF_e;
+      }
+    }
+    printf("%d\n",(int)tdd_calib_coeffs[0][0]);
+    printf("%d\n",(int)tdd_calib_coeffs[1][599]);
+  } else
+   printf("%s not found, running with defaults\n",calibF_fname);
+}
+
+
+int estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_estimates, int32_t **tdd_calib_coeffs, int nb_ant, int nb_freq) {
+
+
+}
+
+int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq) {
+  switch (precode_type) {
+  //case MRT
+  case 0 :
+  //case ZF
+  break;
+  case 1 :
+  //case MMSE
+  break;
+  case 2 :
+  break;
+  default :
+  break;  
+}
+} 
+
+// temporal test function
+/*
+void main(){
+  // initialization
+  // compare
+  printf("Hello world!\n");
+}
+*/
diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h
index fdf76e61aa41f7e3f351be65f820fa2dcc85d02f..6937db6d9bb19241c282ac115d82aa8a88f754d6 100644
--- a/openair1/PHY/MODULATION/defs.h
+++ b/openair1/PHY/MODULATION/defs.h
@@ -82,6 +82,8 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
 
 void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
 
+void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
+
 void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe);
 
 void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t subframe);
@@ -92,6 +94,32 @@ void remove_625_Hz(PHY_VARS_eNB *phy_vars_eNB,int16_t *prach);
 
 void apply_625_Hz(PHY_VARS_UE *phy_vars_ue,int16_t *prach);
 
+/** \brief This function performs beamforming precoding for common
+ * data
+    @param txdataF Table of pointers for frequency-domain TX signals
+    @param txdataF_BF Table of pointers for frequency-domain TX signals
+    @param frame_parms Frame descriptor structure
+after beamforming
+    @param beam_weights Beamforming weights applied on each
+antenna element and each carrier
+    @param slot Slot number
+    @param symbol Symbol index on which to act
+    @param aa physical antenna index*/
+int beam_precoding(int32_t **txdataF,
+	           int32_t **txdataF_BF,
+                   LTE_DL_FRAME_PARMS *frame_parms,
+	           int32_t ***beam_weights,
+                   int slot,
+                   int symbol,
+                   int aa);
+
+int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coeffs);
+
+int estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_estimates, int32_t **tdd_calib_coeffs, int nb_ant, int nb_freq);
+
+int compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, int nb_ant, int nb_freq);
+
+
 #endif
 /** @}*/
 #endif
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index ab8d376ac58bbe3e080dfeda2ad59a11c7fc4496..74037b4a6e0f9ba04432beacb239e1b8ac8bd368 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -31,6 +31,7 @@ This section deals with basic functions for OFDM Modulation.
 
 #include "PHY/defs.h"
 #include "UTIL/LOG/log.h"
+#include "UTIL/LOG/vcd_signal_dumper.h"
 
 //static short temp2[2048*4] __attribute__((aligned(16)));
 
@@ -283,4 +284,58 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne
 
 }
 
-/** @} */
+// OFDM modulation for each symbol
+void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
+{
+
+  int aa, l, slot_offset;
+  int32_t **txdataF = eNB_common_vars->txdataF[eNB_id];
+  int32_t **txdataF_BF = eNB_common_vars->txdataF_BF[eNB_id];
+  int32_t **txdata = eNB_common_vars->txdata[eNB_id];
+
+  slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
+
+  //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
+  for (l=0; l<frame_parms->symbols_per_tti>>1; l++) {
+  
+    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+
+      //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1);
+      beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0);
+
+      //PMCH case not implemented... 
+
+      if (frame_parms->Ncp == 1)
+        PHY_ofdm_mod(txdataF_BF[aa],         // input
+                     &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],            // output
+                     frame_parms->ofdm_symbol_size,       
+                     1,                                   // number of symbols
+                     frame_parms->nb_prefix_samples,      // number of prefix samples
+                     CYCLIC_PREFIX);
+      else {
+        if (l==0) {
+          PHY_ofdm_mod(txdataF_BF[aa],        // input
+                       &txdata[aa][slot_offset],           // output
+                       frame_parms->ofdm_symbol_size,      
+                       1,                                  // number of symbols
+                       frame_parms->nb_prefix_samples0,    // number of prefix samples
+                       CYCLIC_PREFIX);
+           
+        } else {
+          PHY_ofdm_mod(txdataF_BF[aa],        // input
+                       &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],           // output
+                       frame_parms->ofdm_symbol_size,      
+                       1,                                  // number of symbols
+                       frame_parms->nb_prefix_samples,     // number of prefix samples
+                       CYCLIC_PREFIX);
+
+          /* printf("txdata[%d][%d]=%d\n",aa,slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]);
+ * */
+        }
+      }
+    }
+  }
+
+}
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 0a592a1a19502f9f126f3cc7d48ce86819e990ec..94de0d3cbcae958fc5fd50d99186736a2f209973 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -47,6 +47,11 @@ int slot_fep(PHY_VARS_UE *ue,
   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
 
@@ -175,7 +180,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
   if (ue->perfect_ce == 0) {
     if ((l==0) || (l==(4-frame_parms->Ncp))) {
-      for (aa=0; aa<frame_parms->nb_antennas_tx_eNB; aa++) {
+      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);
@@ -215,6 +220,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
       }
     }
+
   }
 
 #ifdef DEBUG_FEP
diff --git a/openair1/PHY/Makefile.inc b/openair1/PHY/Makefile.inc
index 06f944748831600d34b9728c60028e087df6fa99..1586f353c0f623853f6149ca91f313630847b92a 100644
--- a/openair1/PHY/Makefile.inc
+++ b/openair1/PHY/Makefile.inc
@@ -1,6 +1,7 @@
 PHY_OBJS =  $(TOP_DIR)/PHY/LTE_TRANSPORT/pss.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/sss.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots.o
+PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots_ue_spec.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots_mbsfn.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_coding.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_modulation.o
@@ -40,6 +41,7 @@ PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_sync_time.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_sync_timefreq.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_adjust_sync.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.o
+PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_est_freq_offset.o
@@ -47,7 +49,7 @@ PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_ue_measurements.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_eNB_measurements.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/adjust_gain.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_cell_spec.o
-PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_uespec.o
+PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_ue_spec.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_gold.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_gold_mbsfn.o
 PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_mbsfn.o
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index 1465da6544533bfadcd25c9ee262f2fb4c044de2..768dedddf548c9275605742c12b80acc61dcd324 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -484,7 +484,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
   int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
   uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
-  uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx_eNB;
+  uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
   int16_t **rxsig_t;
   int16_t **chest_t;
   int16_t **chest_f;
@@ -507,6 +507,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   int coded_bits_per_codeword = 0;
   int mcs = 0;
   unsigned char harq_pid = 0;
+  int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
 
   if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) {
@@ -537,7 +538,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
                                     phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
                                     num_pdcch_symbols,
                                     frame,
-                                    subframe);
+                                    subframe,
+                                    beamforming_mode);
   } else {
     coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
   }
diff --git a/openair1/PHY/TOOLS/read_F.c b/openair1/PHY/TOOLS/read_F.c
new file mode 100644
index 0000000000000000000000000000000000000000..32ade0dfdb698c69c1ccc0cf757c10e739787822
--- /dev/null
+++ b/openair1/PHY/TOOLS/read_F.c
@@ -0,0 +1,24 @@
+#include<stdio.h>
+#include<stdint.h>
+
+int f_read(char *calibF_fname, int nb_antM, int nb_freq, int16_t (*calibF_mtx)[nb_freq*2]){
+
+  FILE *calibF_fd;
+  int i,j,l,calibF_e;
+  
+  calibF_fd = fopen(calibF_fname,"r");
+ 
+  if (calibF_fd) {
+    printf("Loading Calibration matrix from %s\n", calibF_fname);
+  
+    for(i=0;i<nb_antM;i++){
+      for(j=0;j<nb_freq*2;j++){
+	fscanf(calibF_fd, "%d", &calibF_e);
+        calibF_mtx[i][j] = (int16_t)calibF_e;
+      }
+    }
+    printf("%d\n",(int)calibF_mtx[0][0]);
+    printf("%d\n",(int)calibF_mtx[1][599]);
+  } else
+   printf("%s not found, running with defaults\n",calibF_fname);
+}
diff --git a/openair1/PHY/TOOLS/smbv.c b/openair1/PHY/TOOLS/smbv.c
index f00bc017a01381df019999f4cb5bb009d510d140..adc512d7e5a2aeac61db41b8ae0e87d9cfd3841f 100644
--- a/openair1/PHY/TOOLS/smbv.c
+++ b/openair1/PHY/TOOLS/smbv.c
@@ -119,7 +119,7 @@ int smbv_write_config_from_frame_parms(const char* fname, LTE_DL_FRAME_PARMS *fr
   fprintf(f_ptr, "BB:EUTR:TDD:SPSC %d\n",frame_parms->tdd_config_S);
 
   // MIMO
-  fprintf(f_ptr, "BB:EUTR:DL:MIMO:CONF TX%d\n",frame_parms->nb_antennas_tx_eNB);
+  fprintf(f_ptr, "BB:EUTR:DL:MIMO:CONF TX%d\n",frame_parms->nb_antenna_ports_eNB);
   fprintf(f_ptr, "BB:EUTR:DL:MIMO:ANTA ANT1\n");
   fprintf(f_ptr, "BB:EUTR:DL:MIMO:ANTB NONE\n");
 
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 0e69265d20ce2fe81b22c98edbcc19bddbe9e0bd..daf560a736739b5f46852d8cb2f4a8fce4d7a3d9 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -431,9 +431,6 @@ typedef struct PHY_VARS_eNB_s {
   LTE_eNB_COMMON       common_vars;
   LTE_eNB_SRS          srs_vars[NUMBER_OF_UE_MAX];
   LTE_eNB_PBCH         pbch;
-  /// \brief ?.
-  /// - first index: UE [0..NUMBER_OF_UE_MAX[ (hard coded)
-  /// - second index: UE [0..NUMBER_OF_UE_MAX[
   LTE_eNB_PUSCH       *pusch_vars[NUMBER_OF_UE_MAX];
   LTE_eNB_PRACH        prach_vars;
   LTE_eNB_DLSCH_t     *dlsch[NUMBER_OF_UE_MAX][2];   // Nusers times two spatial streams
@@ -446,6 +443,9 @@ typedef struct PHY_VARS_eNB_s {
   /// cell-specific reference symbols
   uint32_t         lte_gold_table[20][2][14];
 
+  /// UE-specific reference symbols (p=5), TM 7
+  uint32_t         lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX][20][38];
+
   /// UE-specific reference symbols (p=7...14), TM 8/9/10
   uint32_t         lte_gold_uespec_table[2][20][2][21];
 
@@ -706,8 +706,11 @@ typedef struct {
   /// cell-specific reference symbols
   uint32_t lte_gold_table[7][20][2][14];
 
+  /// UE-specific reference symbols (p=5), TM 7
+  uint32_t lte_gold_uespec_port5_table[20][38];
+
   /// ue-specific reference symbols
-  uint32_t         lte_gold_uespec_table[2][20][2][21];
+  uint32_t lte_gold_uespec_table[2][20][2][21];
 
   /// mbsfn reference symbols
   uint32_t lte_gold_mbsfn_table[10][3][42];
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 9005518e7b790b9bd59dcaffa7aebf799823baf2..7a30bff6abefa8ae8b0f4599cce5da4c9919994d 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -542,12 +542,12 @@ typedef struct {
   uint32_t samples_per_tti;
   /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
   uint16_t symbols_per_tti;
-  /// Number of Transmit antennas in node
+  /// Number of Physical transmit antennas in node
   uint8_t nb_antennas_tx;
   /// Number of Receive antennas in node
   uint8_t nb_antennas_rx;
-  /// Number of Transmit antennas in eNodeB
-  uint8_t nb_antennas_tx_eNB;
+  /// Number of Logical transmit antenna ports in eNodeB
+  uint8_t nb_antenna_ports_eNB;
   /// PRACH_CONFIG
   PRACH_CONFIG_COMMON prach_config_common;
   /// PUCCH Config Common (from 36-331 RRC spec)
@@ -601,10 +601,20 @@ typedef enum {
   DUALSTREAM_UNIFORM_PRECODING1=9,
   DUALSTREAM_UNIFORM_PRECODINGj=10,
   DUALSTREAM_PUSCH_PRECODING=11,
-  TM8=12,
-  TM9_10=13
+  TM7=12,
+  TM8=13,
+  TM9_10=14
 } MIMO_mode_t;
 
+typedef enum {
+  /// MRT
+  MRT=0,
+  /// ZF
+  ZF=1,
+  /// MMSE
+  MMSE=2
+} PRECODE_TYPE_t;
+
 typedef struct {
   /// \brief Holds the transmit data in time domain.
   /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
@@ -613,11 +623,17 @@ typedef struct {
   /// - third index:
   int32_t **txdata[3];
   /// \brief holds the transmit data in the frequency domain.
-  /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
+  /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
   /// - first index: eNB id [0..2] (hard coded)
-  /// - second index: tx antenna [0..nb_antennas_tx[
+  /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
   /// - third index: sample [0..]
   int32_t **txdataF[3];
+  /// \brief holds the transmit data after beamforming in the frequency domain.
+  /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: tx antenna [0..nb_antennas_tx[
+  /// - third index: sample [0..]
+  int32_t **txdataF_BF[3];
   /// \brief Holds the received data in time domain.
   /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
   /// - first index: sector id [0..2] (hard coded)
@@ -638,6 +654,17 @@ typedef struct {
   /// - first index: sector id [0..2] (hard coded)
   /// - second index: sample [0..samples_per_tti*10[
   uint32_t *sync_corr[3];
+  /// \brief Holds the beamforming weights
+  /// - first index: eNB id [0..2] (hard coded)
+  /// - second index: eNB antenna port index (hard coded)
+  /// - third index: tx antenna [0..nb_antennas_tx[
+  /// - fourth index: sample [0..]
+  int32_t **beam_weights[3][15];
+  /// \brief Holds the tdd reciprocity calibration coefficients 
+  /// - first index: eNB id [0..2] (hard coded) 
+  /// - second index: tx antenna [0..nb_antennas_tx[
+  /// - third index: frequency [0..]
+  int32_t **tdd_calib_coeffs[3];
 } LTE_eNB_COMMON;
 
 typedef struct {
@@ -798,6 +825,10 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **rxdataF_ext;
+  /// \brief Received frequency-domain ue specific pilots.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..12*N_RB_DL[
+  int32_t **rxdataF_uespec_pilots;
   /// \brief Received frequency-domain signal after extraction and channel compensation.
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
@@ -811,6 +842,14 @@ typedef struct {
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
   int32_t **dl_ch_estimates_ext;
+  /// \brief Downlink beamforming channel estimates in frequency domain.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
+  int32_t **dl_bf_ch_estimates;
+  /// \brief Downlink beamforming channel estimates.
+  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+  /// - second index: ? [0..168*N_RB_DL[
+  int32_t **dl_bf_ch_estimates_ext;
   /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS.
   /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
   /// - second index: ? [0..168*N_RB_DL[
@@ -1014,13 +1053,13 @@ typedef struct {
   /// first index: ? [0..1023] (hard coded)
   int16_t *prachF;
   /// \brief ?.
-  /// first index: rx antenna [0..3] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
+  /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
   /// second index: ? [0..ofdm_symbol_size*12[
-  int16_t *rxsigF[4];
+  int16_t *rxsigF[64];
   /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs)
-  /// first index: rx antenna [0..3] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
+  /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
   /// second index: ? [0..2047] (hard coded)
-  int16_t *prach_ifft[4];
+  int16_t *prach_ifft[64];
 } LTE_eNB_PRACH;
 
 typedef struct {
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index c9e468948ef685cb74f387734912ffc711e13eee..79e684215c7f815d1542670a44680b7cbec1f68f 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -177,6 +177,7 @@
 #define DMA_BLKS_PER_SLOT    (SLOT_LENGTH_BYTES/2048)                    // Number of DMA blocks per slot
 #define SLOT_TIME_NS         (SLOT_LENGTH_SAMPLES*(1e3)/7.68)            // slot time in ns
 
+#define NB_ANTENNA_PORTS_ENB  14                                         // total number of eNB antenna ports
 
 #ifdef EXMIMO
 #define TARGET_RX_POWER 55    // Target digital power for the AGC
diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c
index 7753e9c2e3a4db716357b26cf079a69907e7700a..cb22461656851884d7b3a0157974d5e4580edc67 100644
--- a/openair1/SCHED/phy_mac_stub.c
+++ b/openair1/SCHED/phy_mac_stub.c
@@ -70,6 +70,8 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   uint32_t bcch_pdu;
   uint64_t dlsch_pdu;
 
+  LOG_I(PHY,"frame %d, subframe %d, transmission_mode %d\n",proc->frame_tx,proc->subframe_tx,transmission_mode);
+
   DCI_pdu->Num_common_dci = 0;
   DCI_pdu->Num_ue_spec_dci=0;
 
@@ -233,7 +235,7 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
     DCI_pdu->dci_alloc[0].format     = format1;
     DCI_pdu->dci_alloc[0].ra_flag    = 0;
 
-    if (transmission_mode<3) {
+    if (transmission_mode<3 || transmission_mode == 7) {
       //user 1
       switch (eNB->frame_parms.N_RB_DL) {
       case 25:
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index ff12ac7fef5f70c07fbb62c3eb6d542e5956f055..12827d973425dbe5f1c963ca163d98da3b70fd1e 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -690,7 +690,8 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
 				       SI_RNTI,
 				       0,
 				       P_RNTI,
-				       eNB->UE_stats[0].DL_pmi_single);
+				       eNB->UE_stats[0].DL_pmi_single,
+				       0);
     
     
     eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
@@ -723,7 +724,8 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
 				       SI_RNTI,
 				       dci_alloc->rnti,
 				       P_RNTI,
-				       eNB->UE_stats[0].DL_pmi_single);
+				       eNB->UE_stats[0].DL_pmi_single,
+				       0);
     
     
     eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
@@ -772,7 +774,8 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC
 					 SI_RNTI,
 					 0,
 					 P_RNTI,
-					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single);
+					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single,
+					 eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]);
       LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
 	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
       
@@ -905,7 +908,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
 	      dlsch_harq->rb_alloc,
 	      get_Qm(dlsch_harq->mcs),
 	      dlsch_harq->Nl,
-	      num_pdcch_symbols,frame,subframe),
+	      num_pdcch_symbols,
+	      frame,
+	      subframe,
+	      dlsch_harq->mimo_mode==TM7?7:0),
 	dlsch_harq->nb_rb,
 	dlsch_harq->mcs,
 	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
@@ -924,7 +930,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
 			   dlsch_harq->rb_alloc,
 			   get_Qm(dlsch_harq->mcs),
 			   dlsch_harq->Nl,
-			   num_pdcch_symbols,frame,subframe),
+			   num_pdcch_symbols,
+			   frame,
+			   subframe,
+			   dlsch_harq->mimo_mode==TM7?7:0),
 		     dlsch_harq->nb_rb,
 		     dlsch_harq->mcs,
 		     pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
@@ -1081,7 +1090,9 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
 			   dlsch_harq->rb_alloc,
 			   get_Qm(dlsch_harq->mcs),
 			   dlsch_harq->Nl,
-			   num_pdcch_symbols,frame,subframe),
+			   num_pdcch_symbols,
+			   frame,subframe,
+			   0),
 		     0,
 		     subframe<<1);
     stop_meas(&eNB->dlsch_scrambling_stats);
@@ -1089,10 +1100,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
     start_meas(&eNB->dlsch_modulation_stats);
 
 
-    dlsch_modulation(eNB->common_vars.txdataF[0],
+    dlsch_modulation(eNB,
+		     eNB->common_vars.txdataF[0],
 		     AMP,
 		     subframe,
-		     fp,
 		     num_pdcch_symbols,
 		     dlsch,
 		     dlsch1);
@@ -1184,7 +1195,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   // clear the transmit data array for the current subframe
   if (eNB->abstraction_flag==0) {
-    for (aa=0; aa<fp->nb_antennas_tx_eNB; aa++) {      
+    for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) {      
       memset(&eNB->common_vars.txdataF[0][aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
              0,fp->ofdm_symbol_size*(fp->symbols_per_tti)*sizeof(int32_t));
     }
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 1409440ffda2deb43e275b9cd08e874a18dbc0d6..1c6aa6b20cdc3c7f03653dc83c8c719c07ec50cf 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -93,7 +93,9 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf
                                   ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm,
                                   ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  proc->frame_rx,subframe);
+                                  proc->frame_rx,
+				  subframe,
+				  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
 
   write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
@@ -122,7 +124,9 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   2,
                                   1,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  proc->frame_rx,subframe);
+                                  proc->frame_rx,
+				  subframe,
+				  0);
   LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
 	ue->frame_parms.ofdm_symbol_size,
@@ -228,7 +232,9 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   2,
                                   1,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  proc->frame_rx,subframe);
+                                  proc->frame_rx,
+				  subframe,
+				  0);
   LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
@@ -2593,7 +2599,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					     ue->pdsch_config_dedicated,
 					     SI_RNTI,
 					     0,
-					     P_RNTI)==0)) {
+					     P_RNTI,
+					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0)) {
 
 	ue->dlsch_received[eNB_id]++;
 	
@@ -2636,7 +2643,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    ue->pdsch_config_dedicated,
 					    SI_RNTI,
 					    0,
-					    P_RNTI)==0) {
+					    P_RNTI,
+					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) {
 
 	ue->dlsch_SI_received[eNB_id]++;
  
@@ -2665,7 +2673,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    ue->pdsch_config_dedicated,
 					    SI_RNTI,
 					    0,
-					    P_RNTI)==0) {
+					    P_RNTI,
+					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) {
 
 	ue->dlsch_p_received[eNB_id]++;
  
@@ -2699,7 +2708,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    ue->pdsch_config_dedicated,
 					    SI_RNTI,
 					    ue->prach_resources[eNB_id]->ra_RNTI,
-					    P_RNTI)==0) {
+					    P_RNTI,
+					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id])==0) {
 
 	ue->dlsch_ra_received[eNB_id]++;
 
@@ -2848,7 +2858,9 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 						       ue->dlsch_MCH[0]->harq_processes[0]->Qm,
 						       1,
 						       2,
-						       frame_rx,subframe_rx);
+						       frame_rx,
+						       subframe_rx,
+						       0);
 	
 	dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
 			   ue->dlsch_MCH[0]->harq_processes[0]->G,
@@ -2959,7 +2971,18 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
 	eNB_id_i = eNB_id+1;
 	i_mod = 0;
       }
-      
+
+      //TM7 UE specific channel estimation here!!!
+      if (ue->transmission_mode[eNB_id]==7) {
+        if (ue->frame_parms.Ncp==0) {
+          if ((m==3) || (m==6) || (m==9) || (m==12))
+            //LOG_D(PHY,"[UE %d] dlsch->active in subframe %d => %d, l=%d\n",phy_vars_ue->Mod_id,subframe_rx,phy_vars_ue->dlsch_ue[eNB_id][0]->active, l);
+            lte_dl_bf_channel_estimation(ue,eNB_id,0,subframe_rx*2+(m>6?1:0),5,m);
+        } else {
+          LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
+        }
+      }
+     
       if ((m==s0) && (m<4))
 	first_symbol_flag = 1;
       else
@@ -3132,7 +3155,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 						  dlsch0->harq_processes[harq_pid]->Qm,
 						  dlsch0->harq_processes[harq_pid]->Nl,
 						  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-						  frame_rx,subframe_rx);
+						  frame_rx,
+						  subframe_rx,
+						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
       start_meas(&ue->dlsch_unscrambling_stats);
       dlsch_unscrambling(&ue->frame_parms,
 			 0,
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 96c533bde50dddba3876991f1c687153037cd3a3..f9a8acfa85cbcd5ffac2014489e83e62472c2e48 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -275,6 +275,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
     case 1:
 
     case 2:
+
+    case 7:
       if (common_flag == 0) {
 	
 	if (eNB->frame_parms.frame_type == TDD) {
@@ -403,7 +405,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_dci = *num_dci+1;
           *num_ue_spec_dci = *num_ue_spec_dci+1;
@@ -543,7 +546,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_common_dci=*num_common_dci+1;
           *num_dci = *num_dci + 1;
@@ -710,7 +714,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_dci = *num_dci + 1;
           *num_ue_spec_dci = *num_ue_spec_dci + 1;
@@ -850,7 +855,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_common_dci = *num_common_dci + 1;
           *num_dci = *num_dci + 1;
@@ -1018,7 +1024,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_dci = *num_dci + 1;
           *num_ue_spec_dci = *num_ue_spec_dci + 1;
@@ -1158,7 +1165,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                              SI_RNTI,
                                              0,
                                              P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+                                             eNB->UE_stats[0].DL_pmi_single,
+					     transmission_mode>=7?transmission_mode:0);
 
           *num_common_dci = *num_common_dci + 1;
           *num_dci = *num_dci + 1;
@@ -1187,7 +1195,8 @@ void fill_DCI(PHY_VARS_eNB *eNB,
                                            SI_RNTI,
                                            0,
                                            P_RNTI,
-                                           eNB->UE_stats[k].DL_pmi_single);
+                                           eNB->UE_stats[k].DL_pmi_single,
+					   transmission_mode>=7?transmission_mode:0);
 
         dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
         *num_ue_spec_dci = *num_ue_spec_dci + 1;
@@ -1252,6 +1261,7 @@ int main(int argc, char **argv)
 
   int c;
   int k,i,aa;
+  int re;
 
   int s,Kr,Kr_bytes;
 
@@ -1268,7 +1278,7 @@ int main(int argc, char **argv)
   double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
 
 
-  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=2;
+  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
   uint16_t Nid_cell=0;
 
   int eNB_id = 0;
@@ -1409,7 +1419,7 @@ int main(int argc, char **argv)
   //  num_layers = 1;
   perfect_ce = 0;
 
-  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXY")) != -1) {
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXY")) != -1) {
     switch (c) {
     case 'a':
       awgn_flag = 1;
@@ -1610,7 +1620,7 @@ int main(int argc, char **argv)
       dual_stream_UE=1;
       UE->use_ia_receiver = 1;
 
-      if ((n_tx!=2) || (transmission_mode!=5)) {
+      if ((n_tx_port!=2) || (transmission_mode!=5)) {
         msg("IA receiver only supported for TM5!");
         exit(-1);
       }
@@ -1631,6 +1641,17 @@ int main(int argc, char **argv)
       print_perf=1;
       break;
 
+    case 'q':
+      n_tx_port=atoi(optarg);
+
+      if ((n_tx_port==0) || ((n_tx_port>2))) {
+        msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
+        exit(-1);
+      }
+
+      break;
+
+
     case 'x':
       transmission_mode=atoi(optarg);
 
@@ -1639,25 +1660,37 @@ int main(int argc, char **argv)
           (transmission_mode!=3) &&
           (transmission_mode!=4) &&
           (transmission_mode!=5) &&
-          (transmission_mode!=6)) {
+          (transmission_mode!=6) &&
+          (transmission_mode!=7)) {
         msg("Unsupported transmission mode %d\n",transmission_mode);
         exit(-1);
       }
 
-      if (transmission_mode>1) {
-        n_tx = 2;
+      if (transmission_mode>1 && transmission_mode<7) {
+        n_tx_port = 2;
       }
 
       break;
 
     case 'y':
-      n_tx=atoi(optarg);
+      n_tx_phy=atoi(optarg);
 
-      if ((n_tx==0) || (n_tx>2)) {
-        msg("Unsupported number of tx antennas %d\n",n_tx);
+      if (n_tx_phy < n_tx_port) {
+        msg("n_tx_phy mush not be smaller than n_tx_port");
         exit(-1);
       }
 
+      if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) {
+        msg("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode);
+        exit(-1);
+      }
+
+      if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) {
+        msg("Physical number of antennas not supported for TM7.\n");
+        exit(-1);
+      }
+
+      break;
       break;
 
     case 'X':
@@ -1686,7 +1719,7 @@ int main(int argc, char **argv)
 
     case 'h':
     default:
-      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
+      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]);
       printf("-h This message\n");
       printf("-a Use AWGN channel and not multipath\n");
       printf("-c Number of PDCCH symbols\n");
@@ -1701,7 +1734,8 @@ int main(int argc, char **argv)
       printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
       printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n");
       printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
-      printf("-x Transmission mode (1,2,6 for the moment)\n");
+      printf("-x Transmission mode (1,2,6,7 for the moment)\n");
+      printf("-q Number of TX antennas ports used in eNB\n");
       printf("-y Number of TX antennas used in eNB\n");
       printf("-z Number of RX antennas used in UE\n");
       printf("-t MCS of interfering UE\n");
@@ -1740,9 +1774,6 @@ int main(int argc, char **argv)
   } else
     NB_RB = 4;
 
-  if ((transmission_mode > 1) && (n_tx != 2))
-    printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode);
-
   if (xforms==1) {
     fl_initialize (&argc, argv, NULL, 0, 0);
     form_ue = create_lte_phy_scope_ue();
@@ -1762,7 +1793,8 @@ int main(int argc, char **argv)
     printf("dual_stream_UE=%d\n", dual_stream_UE);
   }
 
-  lte_param_init(n_tx,
+  lte_param_init(n_tx_port,
+		 n_tx_phy,
 		 n_rx,
 		 transmission_mode,
 		 extended_prefix_flag,
@@ -1774,6 +1806,12 @@ int main(int argc, char **argv)
 		 osf,
 		 perfect_ce);
 
+  if ((transmission_mode==1) || (transmission_mode==7)) {
+    for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) 
+     for (re=0; re<eNB->frame_parms.ofdm_symbol_size; re++) 
+       eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; 
+  }
+
   eNB->mac_enabled=1;
   if (two_thread_flag == 0) {
     eNB->te = dlsch_encoding;
@@ -1795,7 +1833,7 @@ int main(int argc, char **argv)
   printf("Setting mcs2 = %d\n",mcs2);
   printf("NPRB = %d\n",NB_RB);
   printf("n_frames = %d\n",n_frames);
-  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag);
+  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
 
   snr1 = snr0+snr_int;
   printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
@@ -1830,7 +1868,7 @@ int main(int argc, char **argv)
     //char dirname[FILENAME_MAX];
     //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
     sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
-            N_RB_DL,mcs1,n_tx,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
+            N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
     //mkdir(dirname,0777);
     time_meas_fd = fopen(time_meas_fname,"w");
     if (time_meas_fd==NULL) {
@@ -2042,7 +2080,7 @@ int main(int argc, char **argv)
   for (k=0; k<n_users; k++) {
     // Create transport channel structures for 2 transport blocks (MIMO)
     for (i=0; i<2; i++) {
-      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
+      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
 
       if (!eNB->dlsch[k][i]) {
         printf("Can't get eNB dlsch structures\n");
@@ -2065,7 +2103,7 @@ int main(int argc, char **argv)
   }
 
   // structure for SIC at UE
-  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
+  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
 
   if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
 
@@ -2159,7 +2197,9 @@ int main(int argc, char **argv)
                                   get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
                                   eNB->dlsch[0][0]->harq_processes[0]->Nl,
                                   num_pdcch_symbols,
-                                  0,subframe);
+                                  0,
+				  subframe,
+				  transmission_mode>=7?transmission_mode:0);
 
   uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword);
   printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
@@ -2354,6 +2394,7 @@ int main(int argc, char **argv)
 	    
 	    start_meas(&eNB->ofdm_mod_stats);
 	    
+            /*
 	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
 			  eNB->common_vars.txdata[eNB_id],
 			  (subframe*2),
@@ -2363,7 +2404,19 @@ int main(int argc, char **argv)
 			  eNB->common_vars.txdata[eNB_id],
 			  (subframe*2)+1,
 			  &eNB->frame_parms);
-	    
+	    */
+
+            do_OFDM_mod_symbol(&eNB->common_vars,
+                               eNB_id,
+                               (subframe*2),
+                               &eNB->frame_parms);
+
+            do_OFDM_mod_symbol(&eNB->common_vars,
+                               eNB_id,
+                               (subframe*2)+1,
+                               &eNB->frame_parms);
+
+
 	    stop_meas(&eNB->ofdm_mod_stats);
 	    
 	    // generate next subframe for channel estimation
@@ -2393,11 +2446,15 @@ int main(int argc, char **argv)
 	      
             if (n_frames==1) {
               printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
-              write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti],
 
-                           eNB->frame_parms.samples_per_tti,1,1);
-	      write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
-			   nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+              write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1);
+
+              if (transmission_mode<7) {
+	        write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+              } else if (transmission_mode == 7) {
+                write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+                write_output("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0],eNB->frame_parms.ofdm_symbol_size,1,1);
+              }
             }
 	  }
 
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
new file mode 100644
index 0000000000000000000000000000000000000000..66dea185de1a039af9cdda09e6660961af5837f6
--- /dev/null
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -0,0 +1,4326 @@
+ /******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+   included in this distribution in the file called "COPYING". If not,
+   see <http://www.gnu.org/licenses/>.
+
+  Contact Information
+  OpenAirInterface Admin: openair_admin@eurecom.fr
+  OpenAirInterface Tech : openair_tech@eurecom.fr
+  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+
+/*! \file dlsim.c
+ \brief Top-level DL simulator
+ \author R. Knopp
+ \date 2011 - 2014
+ \version 0.1
+ \company Eurecom
+ \email: knopp@eurecom.fr
+ \note
+ \warning
+*/
+
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include <execinfo.h>
+#include <signal.h>
+
+#include "SIMULATION/TOOLS/defs.h"
+#include "PHY/types.h"
+#include "PHY/defs.h"
+#include "PHY/vars.h"
+
+#include "SCHED/defs.h"
+#include "SCHED/vars.h"
+#include "LAYER2/MAC/vars.h"
+
+#include "OCG_vars.h"
+#include "UTIL/LOG/log.h"
+#include "UTIL/LISTS/list.h"
+
+#include "unitary_defs.h"
+
+extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
+extern unsigned char offset_mumimo_llr_drange_fix;
+
+#include "PHY/TOOLS/lte_phy_scope.h"
+
+PHY_VARS_eNB *eNB;
+PHY_VARS_UE *UE;
+
+int otg_enabled=0;
+/*the following parameters are used to control the processing times calculations*/
+double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
+double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
+double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */
+double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */
+int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
+int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
+
+void handler(int sig)
+{
+  void *array[10];
+  size_t size;
+
+  // get void*'s for all entries on the stack
+  size = backtrace(array, 10);
+
+  // print out all the frames to stderr
+  fprintf(stderr, "Error: signal %d:\n", sig);
+  backtrace_symbols_fd(array, size, 2);
+  exit(1);
+}
+
+
+
+//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2];
+
+DCI1E_5MHz_2A_M10PRB_TDD_t  DLSCH_alloc_pdu2_1E[2];
+uint64_t DLSCH_alloc_pdu_1[2];
+
+#define UL_RB_ALLOC 0x1ff;
+#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
+//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
+//#define DLSCH_RB_ALLOC 0x0001
+
+int main(int argc, char **argv)
+{
+
+  int c;
+  int k,i,j,aa,aarx,aatx;
+  int re;
+
+  int s,Kr,Kr_bytes;
+
+  double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate;
+  double snr_step=1,input_snr_step=1, snr_int=30;
+
+  LTE_DL_FRAME_PARMS *frame_parms;
+  double **s_re,**s_im,**r_re,**r_im;
+  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
+  double iqim=0.0;
+
+  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=1;
+  uint16_t Nid_cell=0;
+  int32_t **cell_spec_bf_weights;
+  int32_t *ue_spec_bf_weights;
+
+  int eNB_id = 0, eNB_id_i = 1;
+  unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round,dci_flag=0;
+  unsigned char i_mod = 2;
+  unsigned short NB_RB;
+  unsigned char Ns,l,m;
+  uint16_t tdd_config=3;
+  uint16_t n_rnti=0x1234;
+  int n_users = 1;
+
+  SCM_t channel_model=Rayleigh1;
+  //  unsigned char *input_data,*decoded_output;
+
+  unsigned char *input_buffer0[2],*input_buffer1[2];
+  unsigned short input_buffer_length0,input_buffer_length1;
+  unsigned int ret;
+  unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0;
+
+  unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors=0,dlsch_active=0;//,num_layers;
+  int re_allocated;
+  char fname[32],vname[32];
+  FILE *bler_fd;
+  char bler_fname[256];
+  FILE *time_meas_fd;
+  char time_meas_fname[256];
+  //  FILE *tikz_fd;
+  //  char tikz_fname[256];
+
+  FILE *input_trch_fd=NULL;
+  unsigned char input_trch_file=0;
+  FILE *input_fd=NULL;
+  unsigned char input_file=0;
+  //  char input_val_str[50],input_val_str2[50];
+
+  char input_trch_val[16];
+  double channelx,channely;
+
+  unsigned char pbch_pdu[6];
+
+  DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8];
+  int num_common_dci=0,num_ue_spec_dci=0,num_dci=0;
+
+  //  FILE *rx_frame_file;
+
+  int n_frames;
+  int n_ch_rlz = 1;
+  channel_desc_t *eNB2UE[4];
+  uint8_t num_pdcch_symbols=1,num_pdcch_symbols_2=0;
+  uint8_t pilot1,pilot2,pilot3;
+  uint8_t rx_sample_offset = 0;
+  //char stats_buffer[4096];
+  //int len;
+  uint8_t num_rounds = 4;//,fix_rounds=0;
+  uint8_t subframe=7;
+  int u;
+  int n=0;
+  int abstx=0;
+  int iii;
+  FILE *csv_fd=NULL;
+  char csv_fname[512];
+  int ch_realization;
+  int pmi_feedback=0;
+  int hold_channel=0;
+
+  // void *data;
+  // int ii;
+  //  int bler;
+  double blerr[4],uncoded_ber,avg_ber;
+  short *uncoded_ber_bit=NULL;
+  uint8_t N_RB_DL=25,osf=1;
+  frame_t frame_type = FDD;
+  int xforms=0;
+  FD_lte_phy_scope_ue *form_ue = NULL;
+  char title[255];
+  uint32_t DLSCH_RB_ALLOC = 0x1fff;
+  int numCCE=0;
+  int dci_length_bytes=0,dci_length=0;
+  //double channel_bandwidth = 5.0, sampling_rate=7.68;
+  int common_flag=0,TPC=0;
+
+  double cpu_freq_GHz;
+  //  time_stats_t ts;//,sts,usts;
+  int avg_iter,iter_trials;
+  int rballocset=0;
+  int print_perf=0;
+  int test_perf=0;
+  int dump_table=0;
+  int llr8_flag=0;
+
+  double effective_rate=0.0;
+  char channel_model_input[10]="I";
+
+  int TB0_active = 1;
+  uint32_t perfect_ce = 0;
+
+  //  LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
+  //  LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
+  uint8_t Kmimo;
+  uint8_t ue_category=4;
+  uint32_t Nsoft;
+
+
+
+  int CCE_table[800];
+
+  int threequarter_fs=0;
+
+  opp_enabled=1; // to enable the time meas
+
+#if defined(__arm__)
+  FILE    *proc_fd = NULL;
+  char buf[64];
+
+  proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
+  if(!proc_fd)
+     printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
+  else {
+     while(fgets(buf, 63, proc_fd))
+        printf("%s", buf);
+  }
+  fclose(proc_fd);
+  cpu_freq_GHz = ((double)atof(buf))/1e6;
+#else
+  cpu_freq_GHz = get_cpu_freq_GHz();
+#endif
+  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
+
+  //signal(SIGSEGV, handler);
+  //signal(SIGABRT, handler);
+
+  logInit();
+
+  // default parameters
+  n_frames = 1000;
+  snr0 = 0;
+  //  num_layers = 1;
+  perfect_ce = 0;
+
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:p:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XY")) != -1) {
+    switch (c) {
+    case 'a':
+      awgn_flag = 1;
+      channel_model = AWGN;
+      break;
+
+    case 'A':
+      abstx = 1;
+      break;
+
+    case 'b':
+      tdd_config=atoi(optarg);
+      break;
+
+    case 'B':
+      N_RB_DL=atoi(optarg);
+      break;
+
+    case 'c':
+      num_pdcch_symbols=atoi(optarg);
+      break;
+
+    case 'C':
+      Nid_cell = atoi(optarg);
+      break;
+
+    case 'd':
+      dci_flag = 1;
+      break;
+
+    case 'D':
+      frame_type=TDD;
+      break;
+
+    case 'e':
+      num_rounds=1;
+      common_flag = 1;
+      TPC = atoi(optarg);
+      break;
+      
+    case 'E':
+      threequarter_fs=1;
+      break;
+
+    case 'f':
+      input_snr_step= atof(optarg);
+      break;
+
+    case 'F':
+      forgetting_factor = atof(optarg);
+      break;
+
+    case 'i':
+      input_fd = fopen(optarg,"r");
+      input_file=1;
+      dci_flag = 1;
+      break;
+
+    case 'I':
+      input_trch_fd = fopen(optarg,"r");
+      input_trch_file=1;
+      break;
+
+    case 'L':
+      llr8_flag=1;
+      break;
+
+    case 'l':
+      offset_mumimo_llr_drange_fix=atoi(optarg);
+      break;
+
+    case 'm':
+      mcs1 = atoi(optarg);
+      break;
+
+    case 'M':
+      mcs2 = atoi(optarg);
+      break;
+
+    case 'O':
+      test_perf=atoi(optarg);
+      //print_perf =1;
+      break;
+
+    case 't':
+      mcs_i = atoi(optarg);
+      i_mod = get_Qm(mcs_i);
+      break;
+
+    case 'n':
+      n_frames = atoi(optarg);
+      break;
+
+    case 'o':
+      rx_sample_offset = atoi(optarg);
+      break;
+
+    case 'r':
+      DLSCH_RB_ALLOC = atoi(optarg);
+      rballocset = 1;
+      break;
+
+    case 's':
+      snr0 = atof(optarg);
+      break;
+
+    case 'w':
+      snr_int = atof(optarg);
+      break;
+
+    case 'N':
+      n_ch_rlz= atof(optarg);
+      break;
+
+    case 'p':
+      extended_prefix_flag=1;
+      break;
+
+    case 'g':
+      memcpy(channel_model_input,optarg,10);
+
+      switch((char)*optarg) {
+      case 'A':
+        channel_model=SCM_A;
+        break;
+
+      case 'B':
+        channel_model=SCM_B;
+        break;
+
+      case 'C':
+        channel_model=SCM_C;
+        break;
+
+      case 'D':
+        channel_model=SCM_D;
+        break;
+
+      case 'E':
+        channel_model=EPA;
+        break;
+
+      case 'F':
+        channel_model=EVA;
+        break;
+
+      case 'G':
+        channel_model=ETU;
+        break;
+
+      case 'H':
+        channel_model=Rayleigh8;
+        break;
+
+      case 'I':
+        channel_model=Rayleigh1;
+        break;
+
+      case 'J':
+        channel_model=Rayleigh1_corr;
+        break;
+
+      case 'K':
+        channel_model=Rayleigh1_anticorr;
+        break;
+
+      case 'L':
+        channel_model=Rice8;
+        break;
+
+      case 'M':
+        channel_model=Rice1;
+        break;
+
+      case 'N':
+        channel_model=AWGN;
+        break;
+      default:
+        msg("Unsupported channel model!\n");
+        exit(-1);
+      }
+
+      break;
+
+    case 'R':
+      num_rounds=atoi(optarg);
+      break;
+
+    case 'S':
+      subframe=atoi(optarg);
+      break;
+
+    case 'T':
+      n_rnti=atoi(optarg);
+      break;
+
+    case 'u':
+      dual_stream_UE=1;
+      UE->use_ia_receiver = 1;
+
+      if ((n_tx_port!=2) || (transmission_mode!=5)) {
+        msg("IA receiver only supported for TM5!");
+        exit(-1);
+      }
+
+      break;
+
+    case 'v':
+      i_mod = atoi(optarg);
+
+      if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
+        msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
+        exit(-1);
+      }
+
+      break;
+
+    case 'P':
+      print_perf=1;
+      break;
+
+    case 'q':
+      n_tx_port=atoi(optarg);
+
+      if ((n_tx_port==0) || ((n_tx_port>2))) {
+        msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
+        exit(-1);
+      }
+
+      break;
+
+
+    case 'x':
+      transmission_mode=atoi(optarg);
+
+      if ((transmission_mode!=1) &&
+          (transmission_mode!=2) &&
+          (transmission_mode!=3) &&
+          (transmission_mode!=4) &&
+          (transmission_mode!=5) &&
+          (transmission_mode!=6) &&
+          (transmission_mode!=7)) {
+        msg("Unsupported transmission mode %d\n",transmission_mode);
+        exit(-1);
+      }
+
+      if (transmission_mode>1 && transmission_mode<7) {
+        n_tx_port = 2;
+      }
+
+      break;
+
+    case 'y':
+      n_tx_phy=atoi(optarg);
+      
+      if (transmission_mode>1&&transmission_mode<7) {
+        if(n_tx_phy==1) {
+          msg("n_tx_phy must be >1 for transmission_mode %d\n",transmission_mode);
+          exit(-1);
+        } 
+      }
+
+      if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) {
+        msg("Physical number of antennas not supported for TM7.\n");
+        exit(-1);
+      }
+
+      break;
+
+    case 'X':
+      xforms=1;
+      break;
+
+    case 'Y':
+      perfect_ce=1;
+      break;
+
+    case 'z':
+      n_rx=atoi(optarg);
+
+      if ((n_rx==0) || (n_rx>2)) {
+        msg("Unsupported number of rx antennas %d\n",n_rx);
+        exit(-1);
+      }
+
+      break;
+
+    case 'Z':
+      dump_table=1;
+      break;
+
+
+
+    case 'h':
+    default:
+      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]);
+      printf("-h This message\n");
+      printf("-a Use AWGN channel and not multipath\n");
+      printf("-c Number of PDCCH symbols\n");
+      printf("-m MCS1 for TB 1\n");
+      printf("-M MCS2 for TB 2\n");
+      printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n");
+      printf("-p Use extended prefix mode\n");
+      printf("-n Number of frames to simulate\n");
+      printf("-o Sample offset for receiver\n");
+      printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step);
+      printf("-f step size of SNR, default value is 1.\n");
+      printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
+      printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n");
+      printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
+      printf("-x Transmission mode (1,2,6,7 for the moment)\n");
+      printf("-q Number of TX antennas ports used in eNB\n");
+      printf("-y Number of physical TX antennas used in eNB\n");
+      printf("-z Number of RX antennas used in UE\n");
+      printf("-t MCS of interfering UE\n");
+      printf("-R Number of HARQ rounds (fixed)\n");
+      printf("-A Turns on calibration mode for abstraction.\n");
+      printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
+      printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
+      printf("-I Input filename for TrCH data (binary)\n");
+      printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n");
+      exit(1);
+      break;
+    }
+  }
+
+  if (common_flag == 0) {
+    switch (N_RB_DL) {
+    case 6:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
+      num_pdcch_symbols = 3;
+      break;
+
+    case 25:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
+      break;
+
+    case 50:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
+      break;
+
+    case 100:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
+      break;
+    }
+
+    NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
+  } else
+    NB_RB = 4;
+
+
+  if (xforms==1) {
+    fl_initialize (&argc, argv, NULL, 0, 0);
+    form_ue = create_lte_phy_scope_ue();
+    sprintf (title, "LTE PHY SCOPE eNB");
+    fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+    
+    if (!dual_stream_UE==0) {
+      UE->use_ia_receiver = 1;
+      fl_set_button(form_ue->button_0,1);
+      fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+      fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+    }
+  }
+
+  if (transmission_mode==5) {
+    n_users = 2;
+    printf("dual_stream_UE=%d\n", dual_stream_UE);
+  }
+
+  lte_param_init(n_tx_port,n_tx_phy,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,tdd_config,N_RB_DL,threequarter_fs,osf,perfect_ce);
+
+  frame_parms = &eNB->frame_parms;
+
+  /*
+  cell_spec_bf_weights = eNB->common_vars.beam_weights[0][0];
+  for(aa=0;aa<n_tx_phy;aa++) {
+    for(re=0;re<frame_parms->ofdm_symbol_size;re++) {
+      if (n_tx_phy==1 || n_tx_phy==2)
+        cell_spec_bf_weights[aa][re] = 0x00007fff;
+      else if (n_tx_phy==4 || n_tx_phy==8)
+        cell_spec_bf_weights[aa][re] = 0x00007fff>>1;
+      else if (n_tx_phy==16)
+        cell_spec_bf_weights[aa][re] = 0x00007fff>>2;
+      else if (n_tx_phy==64)
+        cell_spec_bf_weights[aa][re] = 0x00007fff>>4;
+    }
+  } 
+
+  if (transmission_mode==7){
+    lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],Nid_cell,n_rnti);
+    lte_gold_ue_spec_port5(UE->lte_gold_uespec_port5_table,Nid_cell,n_rnti);
+  }*/
+
+    
+  eNB_id_i = UE->n_connected_eNB;
+
+  printf("Setting mcs1 = %d\n",mcs1);
+  printf("Setting mcs2 = %d\n",mcs2);
+  printf("NPRB = %d\n",NB_RB);
+  printf("n_frames = %d\n",n_frames);
+  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
+
+  snr1 = snr0+snr_int;
+  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
+
+
+  s_re = malloc(n_tx_phy*sizeof(double*));
+  s_im = malloc(n_tx_phy*sizeof(double*));
+  r_re = malloc(2*sizeof(double*));
+  r_im = malloc(2*sizeof(double*));
+  //  r_re0 = malloc(2*sizeof(double*));
+  //  r_im0 = malloc(2*sizeof(double*));
+
+  nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
+
+  printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
+  printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n",
+         SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8);
+
+  if(transmission_mode==5)
+    sprintf(bler_fname,"bler_tm%d_chan%d_perfce%d_ntx%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,perfect_ce,n_tx_phy,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod);
+  else
+    sprintf(bler_fname,"bler_tm%d_chan%d_perfce%d_ntx%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,perfect_ce,n_tx_phy,n_rx,mcs1);
+
+  bler_fd = fopen(bler_fname,"w");
+  if (bler_fd==NULL) {
+    fprintf(stderr,"Cannot create file %s!\n",bler_fname);
+    exit(-1);
+  }
+  fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
+
+  if (test_perf != 0) {
+    char hostname[1024];
+    hostname[1023] = '\0';
+    gethostname(hostname, 1023);
+    printf("Hostname: %s\n", hostname);
+    //char dirname[FILENAME_MAX];
+    //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
+    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
+            N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
+    //mkdir(dirname,0777);
+    time_meas_fd = fopen(time_meas_fname,"w");
+    if (time_meas_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
+      exit(-1);
+    }
+  }
+
+  if(abstx) {
+    // CSV file
+    sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds);
+    csv_fd = fopen(csv_fname,"w");
+    fprintf(csv_fd,"data_all%d=[",mcs1);
+    if (csv_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",csv_fname);
+      exit(-1);
+    }
+  }
+
+  /*
+  //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+  sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+  tikz_fd = fopen(tikz_fname,"w");
+  //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+  switch (mcs)
+    {
+    case 0:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {");
+      break;
+    case 1:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {");
+      break;
+    case 2:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {");
+      break;
+    case 3:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {");
+      break;
+    case 4:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {");
+      break;
+    case 5:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {");
+      break;
+    case 6:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+      break;
+    case 7:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {");
+      break;
+    case 8:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {");
+      break;
+    case 9:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {");
+      break;
+    case 10:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {");
+      break;
+    case 11:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {");
+      break;
+    case 12:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {");
+      break;
+    case 13:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {");
+      break;
+    case 14:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {");
+      break;
+    case 15:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {");
+      break;
+    case 16:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {");
+      break;
+    case 17:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {");
+      break;
+    case 18:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {");
+      break;
+    case 19:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {");
+      break;
+    case 20:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+      break;
+    case 21:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {");
+      break;
+    case 22:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {");
+      break;
+    case 23:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {");
+      break;
+    case 24:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {");
+      break;
+    case 25:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+      break;
+    case 26:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {");
+      break;
+    case 27:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {");
+      break;
+    case 28:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {");
+      break;
+    }
+  */
+
+  for (i=0; i<n_tx_phy; i++){
+    s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+  }
+
+  for (i=0; i<2; i++) {
+    r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    //    r_re0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    //    bzero(r_re0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    //    r_im0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    //    bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+  }
+
+
+  UE->pdcch_vars[0]->crnti = n_rnti;
+
+  // Fill in UL_alloc
+  UL_alloc_pdu.type    = 0;
+  UL_alloc_pdu.hopping = 0;
+  UL_alloc_pdu.rballoc = UL_RB_ALLOC;
+  UL_alloc_pdu.mcs     = 1;
+  UL_alloc_pdu.ndi     = 1;
+  UL_alloc_pdu.TPC     = 0;
+  UL_alloc_pdu.cqi_req = 1;
+
+  CCCH_alloc_pdu.type               = 0;
+  CCCH_alloc_pdu.vrb_type           = 0;
+  CCCH_alloc_pdu.rballoc            = CCCH_RB_ALLOC;
+  CCCH_alloc_pdu.ndi      = 1;
+  CCCH_alloc_pdu.mcs      = 1;
+  CCCH_alloc_pdu.harq_pid = 0;
+
+  DLSCH_alloc_pdu2_1E[0].rah              = 0;
+  DLSCH_alloc_pdu2_1E[0].rballoc          = DLSCH_RB_ALLOC;
+  DLSCH_alloc_pdu2_1E[0].TPC              = 0;
+  DLSCH_alloc_pdu2_1E[0].dai              = 0;
+  DLSCH_alloc_pdu2_1E[0].harq_pid         = 0;
+  //DLSCH_alloc_pdu2_1E[0].tb_swap          = 0;
+  DLSCH_alloc_pdu2_1E[0].mcs             = mcs1;
+  DLSCH_alloc_pdu2_1E[0].ndi             = 1;
+  DLSCH_alloc_pdu2_1E[0].rv              = 0;
+  // Forget second codeword
+  DLSCH_alloc_pdu2_1E[0].tpmi             = (transmission_mode>=5 ? 5 : 0);  // precoding
+  DLSCH_alloc_pdu2_1E[0].dl_power_off     = (transmission_mode==5 ? 0 : 1);
+
+  DLSCH_alloc_pdu2_1E[1].rah              = 0;
+  DLSCH_alloc_pdu2_1E[1].rballoc          = DLSCH_RB_ALLOC;
+  DLSCH_alloc_pdu2_1E[1].TPC              = 0;
+  DLSCH_alloc_pdu2_1E[1].dai              = 0;
+  DLSCH_alloc_pdu2_1E[1].harq_pid         = 0;
+  //DLSCH_alloc_pdu2_1E[1].tb_swap          = 0;
+  DLSCH_alloc_pdu2_1E[1].mcs             = mcs_i;
+  DLSCH_alloc_pdu2_1E[1].ndi             = 1;
+  DLSCH_alloc_pdu2_1E[1].rv              = 0;
+  // Forget second codeword
+  DLSCH_alloc_pdu2_1E[1].tpmi             = (transmission_mode>=5 ? 5 : 0) ;  // precoding
+  DLSCH_alloc_pdu2_1E[1].dl_power_off     = (transmission_mode==5 ? 0 : 1);
+
+  eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+                                   UE->frame_parms.nb_antennas_rx,
+                                   channel_model,
+                                   N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+				   N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+                                   forgetting_factor,
+                                   rx_sample_offset,
+                                   0);
+
+  if(num_rounds>1) {
+    for(n=1; n<4; n++)
+      eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+                                       UE->frame_parms.nb_antennas_rx,
+                                       channel_model,
+				       N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+				       N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+				       forgetting_factor,
+                                       rx_sample_offset,
+                                       0);
+  }
+
+  if (eNB2UE[0]==NULL) {
+    msg("Problem generating channel model. Exiting.\n");
+    exit(-1);
+  }
+
+  if ((transmission_mode == 3) || (transmission_mode==4))
+    Kmimo=2;
+  else
+    Kmimo=1;
+
+  switch (ue_category) {
+  case 1:
+    Nsoft = 250368;
+    break;
+  case 2:
+  case 3:
+    Nsoft = 1237248;
+    break;
+  case 4:
+    Nsoft = 1827072;
+    break;
+  default:
+    printf("Unsupported UE category %d\n",ue_category);
+    exit(-1);
+    break;
+  }
+
+  for (k=0; k<n_users; k++) {
+    // Create transport channel structures for 2 transport blocks (MIMO)
+    for (i=0; i<2; i++) {
+      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
+
+      if (!eNB->dlsch[k][i]) {
+        printf("Can't get eNB dlsch structures\n");
+        exit(-1);
+      } else {
+         // this initilisation may should be moved to another place
+        for (j=0; j<4; j++) {                                                            
+          for (aa=0; aa<n_tx_phy; aa++) {                                          
+            ue_spec_bf_weights = eNB->dlsch[k][i]->ue_spec_bf_weights[j][aa];
+
+            for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES;re++) {
+              if (n_tx_phy==1 || n_tx_phy==2)
+                ue_spec_bf_weights[re] = 0x00007fff;
+              else if (n_tx_phy==4 || n_tx_phy==8)
+                ue_spec_bf_weights[re] = 0x00007fff>>1;
+              else if (n_tx_phy==16)
+                ue_spec_bf_weights[re] = 0x00007fff>>2;
+              else if (n_tx_phy==64)
+                ue_spec_bf_weights[re] = 0x00007fff>>4;
+            }
+
+          }
+        } 
+
+      }
+
+      eNB->dlsch[k][i]->rnti = n_rnti+k;
+    }
+  }
+
+  for (i=0; i<2; i++) {
+    UE->dlsch[0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+
+    if (!UE->dlsch[0][i]) {
+      printf("Can't get ue dlsch structures\n");
+      exit(-1);
+    }
+
+    UE->dlsch[0][i]->rnti   = n_rnti;
+  }
+
+  // structure for SIC at UE
+  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
+
+  if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+
+    eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
+
+    if (n_users>1)
+      eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
+  } else {
+    eNB->UE_stats[0].DL_pmi_single = 0;
+
+    if (n_users>1)
+      eNB->UE_stats[1].DL_pmi_single = 0;
+  }
+
+  //TODO: allocate memory for calibration matrix and calib_dl_ch_estimates in init_lte.c
+  //for first tests initialze calibration matrix with idendity
+  //read_calibration_matrix(calib_fname, nb_ant, nb_freq, eNB->common_vars.tdd_calib_coeffs[0]);
+
+  if (input_fd==NULL) {
+
+
+    /*
+    // common DCI
+    memcpy(&dci_alloc[num_dci].dci_pdu[0],&CCCH_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
+    dci_alloc[num_dci].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+    dci_alloc[num_dci].L          = 2;
+    dci_alloc[num_dci].rnti       = SI_RNTI;
+    num_dci++;
+    num_common_dci++;
+    */
+
+    // UE specific DCI
+    for(k=0; k<n_users; k++) {
+      switch(transmission_mode) {
+      case 1:
+      case 2:
+      case 7:
+        if (common_flag == 0) {
+
+          if (eNB->frame_parms.frame_type == TDD) {
+
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1_1_5MHz_TDD_t;
+              dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1_5MHz_TDD_t;
+              dci_length_bytes = sizeof(DCI1_5MHz_TDD_t);
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1_10MHz_TDD_t;
+              dci_length_bytes = sizeof(DCI1_10MHz_TDD_t);
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1_20MHz_TDD_t;
+              dci_length_bytes = sizeof(DCI1_20MHz_TDD_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_5MHz_FDD_t);
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_10MHz_FDD_t);
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              dci_length = sizeof_DCI1_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_20MHz_FDD_t);
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = n_rnti+k;
+          dci_alloc[num_dci].format     = format1;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format1,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             transmission_mode<7?0:transmission_mode);
+
+          /*if (transmission_mode == 7)
+	    eNB->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7; //Xiwen: to check about harq_pid*/
+
+          num_dci++;
+          num_ue_spec_dci++;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
+
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = SI_RNTI;
+          dci_alloc[num_dci].format     = format1A;
+          dci_alloc[num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             0);
+
+          num_common_dci++;
+          num_dci++;
+
+        }
+       
+        break;
+
+      case 3:
+        if (common_flag == 0) {
+
+          if (eNB->frame_parms.nb_antennas_tx == 2) {
+
+            if (eNB->frame_parms.frame_type == TDD) {
+
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 25:
+                dci_length = sizeof_DCI2A_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 50:
+                dci_length = sizeof_DCI2A_10MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 100:
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                dci_length = sizeof_DCI2A_20MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
+                break;
+              }
+            }
+
+            else {
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 25:
+                dci_length = sizeof_DCI2A_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 50:
+                dci_length = sizeof_DCI2A_10MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 100:
+                dci_length = sizeof_DCI2A_20MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+              }
+            }
+          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
+
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = n_rnti+k;
+          dci_alloc[num_dci].format     = format2A;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format2A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             0);
+
+          num_dci++;
+          num_ue_spec_dci++;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
+
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = SI_RNTI;
+          dci_alloc[num_dci].format     = format1A;
+          dci_alloc[num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             0);
+
+          num_common_dci++;
+          num_dci++;
+
+        }
+
+        printf("Generated DCI format 2A (Transmission Mode 3)\n");
+        break;
+
+      case 4:
+        if (common_flag == 0) {
+
+          if (eNB->frame_parms.nb_antennas_tx == 2) {
+
+            if (eNB->frame_parms.frame_type == TDD) {
+
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 25:
+                dci_length = sizeof_DCI2_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 50:
+                dci_length = sizeof_DCI2_10MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 100:
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                dci_length = sizeof_DCI2_20MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
+                break;
+              }
+            }
+
+            else {
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 25:
+                dci_length = sizeof_DCI2_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 50:
+                dci_length = sizeof_DCI2_10MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+
+              case 100:
+                dci_length = sizeof_DCI2_20MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
+                break;
+              }
+            }
+          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
+
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = n_rnti+k;
+          dci_alloc[num_dci].format     = format2;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format2,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             0);
+
+          num_dci++;
+          num_ue_spec_dci++;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
+
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
+
+          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[num_dci].dci_length = dci_length;
+          dci_alloc[num_dci].L          = 1;
+          dci_alloc[num_dci].rnti       = SI_RNTI;
+          dci_alloc[num_dci].format     = format1A;
+          dci_alloc[num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single,
+                                             0);
+
+          num_common_dci++;
+          num_dci++;
+
+        }
+
+        break;
+
+      case 5:
+      case 6:
+        memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+        dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+        dci_alloc[num_dci].L          = 1;
+        dci_alloc[num_dci].rnti       = n_rnti+k;
+        dci_alloc[num_dci].format     = format1E_2A_M10PRB;
+        dci_alloc[num_dci].firstCCE       = 4*k;
+        printf("Generating dlsch params for user %d\n",k);
+        generate_eNB_dlsch_params_from_dci(0,
+					   subframe,
+                                           &DLSCH_alloc_pdu2_1E[k],
+                                           n_rnti+k,
+                                           format1E_2A_M10PRB,
+                                           eNB->dlsch[k],
+                                           &eNB->frame_parms,
+                                           eNB->pdsch_config_dedicated,
+                                           SI_RNTI,
+                                           0,
+                                           P_RNTI,
+                                           eNB->UE_stats[k].DL_pmi_single,
+                                           0);
+
+        dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+        num_ue_spec_dci++;
+        num_dci++;
+
+        break;
+
+      default:
+        printf("Unsupported Transmission Mode!!!");
+        exit(-1);
+        break;
+      }
+
+
+
+
+      /*
+      memcpy(&dci_alloc[1].dci_pdu[0],&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD0_t));
+      dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_0_t;
+      dci_alloc[1].L          = 2;
+      dci_alloc[1].rnti       = n_rnti;
+      */
+    }
+
+    if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE);
+
+    numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
+
+    if (n_frames==1) printf("%d\n",numCCE);
+
+    // apply RNTI-based nCCE allocation
+    memset(CCE_table,0,800*sizeof(int));
+
+    for (i=num_common_dci; i<num_dci; i++) {
+
+      dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table,
+						 1<<dci_alloc[i].L,
+						 numCCE,
+						 (dci_alloc[i].rnti==SI_RNTI)? 1 : 0,
+						 dci_alloc[i].rnti,
+						 subframe);
+
+      if (n_frames==1)
+        printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format,
+               dci_alloc[i].firstCCE,numCCE);
+    }
+
+    for (k=0; k<n_users; k++) {
+
+      input_buffer_length0 = eNB->dlsch[k][0]->harq_processes[0]->TBS/8;
+      input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4);
+      memset(input_buffer0[k],0,input_buffer_length0+4);
+      input_buffer_length1 = eNB->dlsch[k][1]->harq_processes[0]->TBS/8;
+      input_buffer1[k] = (unsigned char *)malloc(input_buffer_length1+4);
+      memset(input_buffer1[k],0,input_buffer_length1+4);
+
+      if (input_trch_file==0) {
+        for (i=0; i<input_buffer_length0; i++) {
+          //input_buffer0[k][i] = (unsigned char)(i&0xff);
+          input_buffer0[k][i] = (unsigned char)(taus()&0xff);
+        }
+
+        for (i=0; i<input_buffer_length1; i++) {
+          input_buffer1[k][i]= (unsigned char)(taus()&0xff);
+        }
+      }
+
+      else {
+        i=0;
+
+        while ((!feof(input_trch_fd)) && (i<input_buffer_length0<<3)) {
+          ret=fscanf(input_trch_fd,"%s",input_trch_val);
+
+          if (input_trch_val[0] == '1')
+            input_buffer0[k][i>>3]+=(1<<(7-(i&7)));
+
+          if (i<16)
+            printf("input_trch_val %d : %c\n",i,input_trch_val[0]);
+
+          i++;
+
+          if (((i%8) == 0) && (i<17))
+            printf("%x\n",input_buffer0[k][(i-1)>>3]);
+        }
+
+        printf("Read in %d bits\n",i);
+      }
+    }
+  }
+
+  // this is for user 0 only
+  coded_bits_per_codeword = get_G(&eNB->frame_parms,
+                                  eNB->dlsch[0][0]->harq_processes[0]->nb_rb,
+                                  eNB->dlsch[0][0]->harq_processes[0]->rb_alloc,
+                                  get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+                                  eNB->dlsch[0][0]->harq_processes[0]->Nl,
+                                  num_pdcch_symbols,
+                                  0,
+ 				  subframe,
+				  (transmission_mode<7?0:transmission_mode));
+
+  uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword);
+  printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
+
+  snr_step = input_snr_step;
+  UE->high_speed_flag = 0; //1
+  UE->ch_est_alpha=0;
+
+  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
+    if(abstx) {
+      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
+    }
+
+    for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
+      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
+      errs[0]=0;
+      errs[1]=0;
+      errs[2]=0;
+      errs[3]=0;
+      errs2[0]=0;
+      errs2[1]=0;
+      errs2[2]=0;
+      errs2[3]=0;
+      round_trials[0] = 0;
+      round_trials[1] = 0;
+      round_trials[2] = 0;
+      round_trials[3] = 0;
+
+      dci_errors=0;
+      //      avg_ber = 0;
+
+      round=0;
+      avg_iter = 0;
+      iter_trials=0;
+      reset_meas(&eNB->phy_proc_tx); // total eNB tx
+      reset_meas(&eNB->dlsch_scrambling_stats);
+      reset_meas(&UE->dlsch_unscrambling_stats);
+      reset_meas(&eNB->ofdm_mod_stats);
+      reset_meas(&eNB->dlsch_modulation_stats);
+      reset_meas(&eNB->dlsch_encoding_stats);
+      reset_meas(&eNB->dlsch_interleaving_stats);
+      reset_meas(&eNB->dlsch_rate_matching_stats);
+      reset_meas(&eNB->dlsch_turbo_encoding_stats);
+
+      reset_meas(&UE->phy_proc_rx); // total UE rx
+      reset_meas(&UE->ofdm_demod_stats);
+      reset_meas(&UE->dlsch_channel_estimation_stats);
+      reset_meas(&UE->dlsch_freq_offset_estimation_stats);
+      reset_meas(&UE->rx_dft_stats);
+      reset_meas(&UE->dlsch_decoding_stats);
+      reset_meas(&UE->dlsch_turbo_decoding_stats);
+      reset_meas(&UE->dlsch_deinterleaving_stats);
+      reset_meas(&UE->dlsch_rate_unmatching_stats);
+      reset_meas(&UE->dlsch_tc_init_stats);
+      reset_meas(&UE->dlsch_tc_alpha_stats);
+      reset_meas(&UE->dlsch_tc_beta_stats);
+      reset_meas(&UE->dlsch_tc_gamma_stats);
+      reset_meas(&UE->dlsch_tc_ext_stats);
+      reset_meas(&UE->dlsch_tc_intl1_stats);
+      reset_meas(&UE->dlsch_tc_intl2_stats);
+      // initialization
+      struct list time_vector_tx;
+      initialize(&time_vector_tx);
+      struct list time_vector_tx_ifft;
+      initialize(&time_vector_tx_ifft);
+      struct list time_vector_tx_mod;
+      initialize(&time_vector_tx_mod);
+      struct list time_vector_tx_enc;
+      initialize(&time_vector_tx_enc);
+
+      struct list time_vector_rx;
+      initialize(&time_vector_rx);
+      struct list time_vector_rx_fft;
+      initialize(&time_vector_rx_fft);
+      struct list time_vector_rx_demod;
+      initialize(&time_vector_rx_demod);
+      struct list time_vector_rx_dec;
+      initialize(&time_vector_rx_dec);
+
+      for (trials = 0; trials<n_frames; trials++) {
+        //  printf("Trial %d\n",trials);
+        fflush(stdout);
+        round=0;
+
+        //if (trials%100==0)
+        eNB2UE[0]->first_run = 1;
+
+        ret = UE->dlsch[0][0]->max_turbo_iterations+1;
+
+        while ((round < num_rounds) && (ret > UE->dlsch[0][0]->max_turbo_iterations)) {
+              //printf("Trial %d, round %d\n",trials,round);
+          round_trials[round]++;
+
+          if(transmission_mode>=5&&transmission_mode<7)
+            pmi_feedback=1;
+          else
+            pmi_feedback=0;
+
+          if (abstx) {
+            if (trials==0 && round==0 && SNR==snr0)  //generate a new channel
+              hold_channel = 0;
+            else
+              hold_channel = 1;
+          } else
+            hold_channel = 0;//(round==0) ? 0 : 1;
+
+PMI_FEEDBACK:
+
+	  //make sure dlsim is called with perfect channel estimation option (for freq_channel)
+	  //fill drs_ch_estimates with data from eNB2UE->chF
+	  for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+	    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+	      for (i=0; i<frame_parms->N_RB_DL*12; i++) {
+		for (l=0; l<frame_parms->symbols_per_tti; l++) {
+		  ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
+                          //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
+		  ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
+		}
+	      }
+	    }
+	  }
+
+	  estimate_DLCSI_from_ULCSI(eNB->dlsch[0][0]->calib_dl_ch_estimates,
+					 &eNB->pusch_vars[0]->drs_ch_estimates[0][0/*position of second DMRS*/],
+					 eNB->common_vars.tdd_calib_coeffs[0],
+					 frame_parms->nb_antennas_tx,
+					 frame_parms->N_RB_DL*12);
+	  
+	  compute_BF_weights(eNB->dlsch[0][0]->ue_spec_bf_weights[0],
+			     eNB->dlsch[0][0]->calib_dl_ch_estimates,
+			     MRT,
+			     frame_parms->nb_antennas_tx,
+			     frame_parms->N_RB_DL*12);
+
+          //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
+          for (aa=0; aa<NB_ANTENNA_PORTS_ENB; aa++) {
+            memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
+          }
+
+          if (input_fd==NULL) {
+
+            start_meas(&eNB->phy_proc_tx);
+
+            // Simulate HARQ procedures!!!
+            if (common_flag == 0) {
+
+              if (round == 0) {   // First round
+                TB0_active = 1;
+
+                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
+
+                if (eNB->frame_parms.frame_type == TDD) {
+
+                  switch (transmission_mode) {
+                  case 1:
+                  case 2:
+                  case 7:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 3:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 5:
+                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
+                    DLSCH_alloc_pdu2_1E[0].rv              = 0;
+                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+                    break;
+
+                  }
+                } else { // FDD
+                  switch (transmission_mode) {
+                  case 1:
+                  case 2:
+                  case 7:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
+                      break;
+                    }
+
+                    break;
+                  case 3:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 5:
+                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
+                    DLSCH_alloc_pdu2_1E[0].rv              = 0;
+                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+                    break;
+                  }
+
+                }
+              } else {
+                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
+
+                if (eNB->frame_parms.frame_type == TDD) {
+
+
+                  switch (transmission_mode) {
+                  case 1:
+                  case 2:
+                  case 7:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 3:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      if (TB0_active==1) {
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
+                      break;
+
+                    case 25:
+                      if (TB0_active==1) {
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
+                      break;
+
+                    case 50:
+                      if (TB0_active==1) {
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
+                      break;
+
+                    case 100:
+                      if (TB0_active==1) {
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 5:
+                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
+                    DLSCH_alloc_pdu2_1E[0].rv              = round&3;
+                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+                    break;
+                  }
+                } else {
+                  switch (transmission_mode) {
+                  case 1:
+                  case 2:
+                  case 7:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
+                      break;
+
+                    case 25:
+                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
+                      break;
+
+                    case 50:
+                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
+                      break;
+
+                    case 100:
+                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
+                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 3:
+                    switch (eNB->frame_parms.N_RB_DL) {
+                    case 6:
+                      if (TB0_active==1) {
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
+                      break;
+
+                    case 25:
+                      if (TB0_active==1) {
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
+                      break;
+
+                    case 50:
+                      if (TB0_active==1) {
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
+                      break;
+
+                    case 100:
+                      if (TB0_active==1) {
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      } else { // deactivate TB0
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                      }
+
+                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
+                      break;
+                    }
+
+                    break;
+
+                  case 5:
+                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
+                    DLSCH_alloc_pdu2_1E[0].rv              = round&3;
+                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+                    break;
+                  }
+                }
+              }
+            }
+	    
+            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
+                                                   num_common_dci,
+                                                   dci_alloc,
+                                                   0,
+                                                   AMP,
+                                                   &eNB->frame_parms,
+                                                   eNB->common_vars.txdataF[eNB_id],
+                                                   subframe);
+	    
+            if (num_pdcch_symbols_2 > num_pdcch_symbols) {
+              msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols);
+              exit(-1);
+            }
+
+            for (k=0; k<n_users; k++) {
+              for (int cw=0; cw<Kmimo; cw++) {
+                coded_bits_per_codeword = get_G(&eNB->frame_parms,
+                                                eNB->dlsch[k][cw]->harq_processes[0]->nb_rb,
+                                                eNB->dlsch[k][cw]->harq_processes[0]->rb_alloc,
+                                                get_Qm(eNB->dlsch[k][cw]->harq_processes[0]->mcs),
+                                                eNB->dlsch[k][cw]->harq_processes[0]->Nl,
+                                                num_pdcch_symbols,
+                                                0,
+						subframe,
+						(transmission_mode<7?0:transmission_mode));
+
+#ifdef TBS_FIX   // This is for MESH operation!!!
+                tbs = (double)3*TBStable[get_I_TBS(eNB->dlsch[k][cw]->harq_processes[0]->mcs)][eNB->dlsch[k][cw]->nb_rb-1]/4;
+#else
+                tbs = eNB->dlsch[k][cw]->harq_processes[0]->TBS;
+#endif
+                rate = (double)tbs/(double)coded_bits_per_codeword;
+
+                if ((SNR==snr0) && (trials==0) && (round==0))
+                  printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n",
+                         k,cw,rate,rate*get_Qm(eNB->dlsch[k][0]->harq_processes[0]->mcs),
+                         coded_bits_per_codeword,
+                         tbs,
+                         get_Qm(eNB->dlsch[k][0]->harq_processes[0]->mcs),
+                         num_pdcch_symbols,
+                         eNB->dlsch[0][0]->harq_processes[0]->round);
+
+                // use the PMI from previous trial
+                if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+                  eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
+                  UE->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+
+                  if (n_users>1)
+                    eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
+
+                  /*
+                    if ((trials<10) && (round==0)) {
+                    printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(eNB->dlsch[0][0]->pmi_alloc),pmi_feedback);
+                    if (transmission_mode ==5)
+                    printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(eNB->dlsch[1][0]->pmi_alloc));
+                    }
+                  */
+                }
+
+
+                start_meas(&eNB->dlsch_encoding_stats);
+
+                if (dlsch_encoding(eNB,
+				   ((cw==0) ? input_buffer0[k] : input_buffer1[k]),
+                                   num_pdcch_symbols,
+                                   eNB->dlsch[k][cw],
+                                   0,subframe,
+                                   &eNB->dlsch_rate_matching_stats,
+                                   &eNB->dlsch_turbo_encoding_stats,
+                                   &eNB->dlsch_interleaving_stats)<0)
+                  exit(-1);
+
+                /*
+                if (transmission_mode == 3) {
+                if (dlsch_encoding(input_buffer1[k],
+                   &eNB->frame_parms,
+                   num_pdcch_symbols,
+                   eNB->dlsch[k][1],
+                   0,subframe,
+                   &eNB->dlsch_rate_matching_stats,
+                   &eNB->dlsch_turbo_encoding_stats,
+                   &eNB->dlsch_interleaving_stats
+                   )<0)
+                exit(-1);
+                }
+                */
+                stop_meas(&eNB->dlsch_encoding_stats);
+
+                eNB->dlsch[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI;
+                start_meas(&eNB->dlsch_scrambling_stats);
+                dlsch_scrambling(&eNB->frame_parms,
+                                 0,
+                                 eNB->dlsch[k][cw],
+                                 coded_bits_per_codeword,
+                                 0,
+                                 subframe<<1);
+                stop_meas(&eNB->dlsch_scrambling_stats);
+
+                if (n_frames==1) {
+                  for (s=0; s<eNB->dlsch[k][cw]->harq_processes[0]->C; s++) {
+                    if (s<eNB->dlsch[k][cw]->harq_processes[0]->Cminus)
+                      Kr = eNB->dlsch[k][cw]->harq_processes[0]->Kminus;
+                    else
+                      Kr = eNB->dlsch[k][cw]->harq_processes[0]->Kplus;
+
+                    Kr_bytes = Kr>>3;
+
+                    for (i=0; i<Kr_bytes; i++)
+                      printf("%d : (%x)\n",i,eNB->dlsch[k][cw]->harq_processes[0]->c[s][i]);
+                  }
+                }
+              }
+              
+              start_meas(&eNB->dlsch_modulation_stats);
+              re_allocated = dlsch_modulation(eNB,
+					      eNB->common_vars.txdataF[eNB_id],
+                                              AMP,
+                                              subframe,
+                                              num_pdcch_symbols,
+                                              eNB->dlsch[k][0],
+                                              eNB->dlsch[k][1]);	      
+              /* avoid gcc warnings */
+              (void)re_allocated;
+
+              stop_meas(&eNB->dlsch_modulation_stats);
+              /*
+              if (trials==0 && round==0)
+              printf("RE count %d\n",re_allocated);
+              */
+            } //n_users
+
+
+            generate_pilots(eNB,
+                            eNB->common_vars.txdataF[eNB_id],
+                            AMP,
+                            LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
+/*
+	    //PSS/SSS
+            if (eNB->frame_parms.frame_type == FDD) {
+              generate_pss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           0);
+              generate_sss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4,
+                           0);
+              generate_pss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           10);
+              generate_sss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4,
+                           10);
+	    }
+            else if (eNB->frame_parms.frame_type == TDD) {
+              generate_sss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           1);
+              generate_pss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           2,
+                           2);
+              generate_sss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           11);
+              generate_pss(eNB->common_vars.txdataF[0],
+                           AMP,
+                           &eNB->frame_parms,
+                           2,
+                           12);
+            }
+
+              //PBCH
+              pbch_pdu[2] = 0;
+
+              // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
+                break;
+
+              case 15:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
+                break;
+
+              case 25:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
+                break;
+
+              case 50:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
+                break;
+
+              case 75:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
+                break;
+
+              case 100:
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
+                break;
+
+              default:
+                // FIXME if we get here, this should be flagged as an error, right?
+                pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
+                break;
+              }
+
+              pbch_pdu[2] = (pbch_pdu[2]&0xef) |
+                            ((eNB->frame_parms.phich_config_common.phich_duration << 4)&0x10);
+
+              switch (eNB->frame_parms.phich_config_common.phich_resource) {
+              case oneSixth:
+                pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
+                break;
+
+              case half:
+                pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
+                break;
+
+              case one:
+                pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
+                break;
+
+              case two:
+                pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
+                break;
+
+              default:
+                // unreachable
+                break;
+              
+
+              pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((0>>8)&0x3);
+              pbch_pdu[1] = 0&0xfc;
+              pbch_pdu[0] = 0;
+            }
+
+            generate_pbch(&eNB->lte_eNB_pbch,
+                          eNB->common_vars.txdataF[0],
+                          AMP,
+                          &eNB->frame_parms,
+                          pbch_pdu,
+                          0&3);
+*/
+
+            start_meas(&eNB->ofdm_mod_stats);
+/*
+	    for(i=0;i<20;i++){
+	      
+              do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
+                            eNB->common_vars.txdata[eNB_id],
+                            i,
+                            &eNB->frame_parms);
+ 	      } 
+
+*/
+            do_OFDM_mod_symbol(&eNB->common_vars,
+                          eNB_id,
+                          (subframe*2),
+                          &eNB->frame_parms);
+
+            do_OFDM_mod_symbol(&eNB->common_vars,
+                          eNB_id,
+                          (subframe*2)+1,
+                          &eNB->frame_parms);
+
+            stop_meas(&eNB->ofdm_mod_stats);
+            stop_meas(&eNB->phy_proc_tx);
+
+           /* do_OFDM_mod_l(&eNB->common_vars,
+                          eNB_id,
+                          (subframe*2)+2,
+                          &eNB->frame_parms); */
+
+            if (n_frames==1) {
+              if (transmission_mode<7)
+                write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
+                             nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+              else if (transmission_mode==7)
+                write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
+                             nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+              write_output("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0],
+                           eNB->frame_parms.ofdm_symbol_size,1,1);
+
+              if (eNB->frame_parms.nb_antennas_tx>1)// to be updated
+                write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
+                             nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
+            }
+            tx_lev = 0;
+
+            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
+              tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
+                                      [subframe*eNB->frame_parms.samples_per_tti],
+                                      eNB->frame_parms.samples_per_tti);
+            }
+
+            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
+
+            if (n_frames==1) {
+              printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
+              write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe*eNB->frame_parms.samples_per_tti],eNB->frame_parms.samples_per_tti,1,1);
+              // write_output("txsig0.m","txs0",&eNB->common_vars.txdata[eNB_id][0][0*eNB->frame_parms.samples_per_tti],eNB->frame_parms.samples_per_tti*10,1,1);
+            }
+          }
+
+          /*
+            else {  // Read signal from file
+            i=0;
+            while (!feof(input_fd)) {
+            fscanf(input_fd,"%s %s",input_val_str,input_val_str2);
+
+            if ((i%4)==0) {
+            ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL));
+            ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL));
+            if ((i/4)<100)
+            printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,);
+            }
+            i++;
+            if (i>(FRAME_LENGTH_SAMPLES))
+            break;
+            }
+            printf("Read in %d samples\n",i/4);
+            write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1);
+            //    write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
+            tx_lev = signal_energy(&txdata[0][0],
+            OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
+            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
+            }
+          */
+
+          //    printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag);
+          for (i=0; i<2*frame_parms->samples_per_tti; i++) {
+            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
+              if (awgn_flag == 0) {
+                s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
+                s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+              } else {
+                for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
+                  if (aa==0) {
+                    r_re[aarx][i] = (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)];
+                    r_im[aarx][i] = (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1];
+                    //printf("r[%d][%d]=> %f, %f\n",aarx,i,r_re[aarx][i],r_im[aarx][i]);
+                  } else {
+                    r_re[aarx][i] += (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)];
+                    r_im[aarx][i] += (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1];
+                  }
+
+                }
+              }
+            }
+          }
+
+          // Multipath channel
+          if (awgn_flag == 0) {
+            multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
+                              2*frame_parms->samples_per_tti,hold_channel);
+
+            //      printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
+            if(abstx==1 && num_rounds>1)
+              if(round==0 && hold_channel==0) {
+                random_channel(eNB2UE[1],0);
+                random_channel(eNB2UE[2],0);
+                random_channel(eNB2UE[3],0);
+              }
+	    
+	    if (UE->perfect_ce==1) {
+                  // fill in perfect channel estimates
+                  freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
+		  /*
+		  write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
+                  write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8);
+		  */
+	    }
+	  }
+
+          if(abstx) {
+            if (trials==0 && round==0) {
+              // calculate freq domain representation to compute SINR
+              freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1);
+              // snr=pow(10.0,.1*SNR);
+              fprintf(csv_fd,"%f,",SNR);
+
+              for (u=0; u<2*NB_RB; u++) {
+                for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) {
+                  for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) {
+                    channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
+                    channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
+                    fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+                  }
+                }
+              }
+
+              if(num_rounds>1) {
+                freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1);
+
+                for (u=0; u<2*NB_RB; u++) {
+                  for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) {
+                    for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) {
+                      channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
+                      channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
+                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+                    }
+                  }
+                }
+
+                freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1);
+
+                for (u=0; u<2*NB_RB; u++) {
+                  for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) {
+                    for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) {
+                      channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
+                      channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
+                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+                    }
+                  }
+                }
+
+                freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1);
+
+                for (u=0; u<2*NB_RB; u++) {
+                  for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) {
+                    for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) {
+                      channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
+                      channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
+                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+                    }
+                  }
+                }
+              }
+            }
+          }
+
+          //AWGN
+          // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A
+          sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated);
+          sigma2 = pow(10,sigma2_dB/10);
+
+          if (n_frames==1)
+            printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated));
+
+          for (i=0; i<2*frame_parms->samples_per_tti; i++) {
+            for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
+              // printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
+              ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
+                (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+              ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
+                (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+              //((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) r_re[aa][i];
+              //((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) r_im[aa][i]; 
+              //printf("rxdata[%d][%d]=> %d, %d\n",aa,subframe*UE->frame_parms.samples_per_tti+i,r_re[aa][i],r_im[aa][i]);
+            }
+          }
+
+
+          //    lte_sync_time_init(eNB->frame_parms,common_vars);
+          //    lte_sync_time(common_vars->rxdata, eNB->frame_parms);
+          //    lte_sync_time_free();
+
+          /*
+            // optional: read rx_frame from file
+            if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL)
+            {
+            printf("Cannot open rx_frame.m data file\n");
+            exit(0);
+            }
+
+            result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
+            printf("Read %d bytes\n",result);
+            result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
+            printf("Read %d bytes\n",result);
+
+            fclose(rx_frame_file);
+          */
+
+          if (n_frames==1) {
+            printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+            printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+            printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+            printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+          }
+
+          if (eNB->frame_parms.Ncp == 0) {  // normal prefix
+            pilot1 = 4;
+            pilot2 = 7;
+            pilot3 = 11;
+          } else { // extended prefix
+            pilot1 = 3;
+            pilot2 = 6;
+            pilot3 = 9;
+          }
+          
+
+          start_meas(&UE->phy_proc_rx);
+
+          // Inner receiver scheduling for 3 slots
+        
+          for (Ns=(2*subframe); Ns<((2*subframe)+3); Ns++) {
+            for (l=0; l<pilot2; l++) {
+              if (n_frames==1)
+                printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
+
+              /*
+              This function implements the OFDM front end processor (FEP).
+
+              Parameters:
+              frame_parms  LTE DL Frame Parameters
+              ue_common_vars   LTE UE Common Vars
+              l  symbol within slot (0..6/7)
+              Ns   Slot number (0..19)
+              sample_offset  offset within rxdata (points to beginning of subframe)
+              no_prefix  if 1 prefix is removed by HW
+
+              */
+
+              start_meas(&UE->ofdm_demod_stats);
+              slot_fep(UE,
+                       l,
+                       Ns%20,
+                       0,
+                       0,
+		       0);
+              stop_meas(&UE->ofdm_demod_stats);
+
+              if (UE->perfect_ce==1) {
+                if (awgn_flag==0) {
+                  for(k=0; k<NUMBER_OF_eNB_MAX; k++) {
+                    for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+                      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+                        for (i=0; i<frame_parms->N_RB_DL*12; i++) {
+                          ((int16_t *) UE->common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                                eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
+                          //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
+                          ((int16_t *) UE->common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                                eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
+
+                          if (transmission_mode == 7){
+			    //this should include the BF weights! Will not work for a random channel
+                            if (UE->high_speed_flag==0) {
+                              ((int16_t *)UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)(
+                                  eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
+                              ((int16_t *)UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)(
+                                  eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
+                              //printf("**,x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
+                            } else  {
+                              ((int16_t *)UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                                  eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
+                              ((int16_t *)UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                                  eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
+                                
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                } else {
+                  for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+                    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
+                      for (i=0; i<frame_parms->N_RB_DL*12; i++) {
+                          ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                          ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+                        if (transmission_mode == 7) {
+                          if (UE->high_speed_flag==0){
+                            ((int16_t *) UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2;
+                          } else {
+                            ((int16_t *) UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=0/2;
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+
+
+              if ((Ns==((2*subframe))) && (l==0)) {
+                lte_ue_measurements(UE,
+                                    subframe*UE->frame_parms.samples_per_tti,
+                                    1,
+                                    0);
+                /*
+                  debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
+                  UE->measurements.rx_rssi_dBm[0] - ((UE->frame_parms.nb_antennas_rx==2) ? 3 : 0),
+                  UE->measurements.wideband_cqi_dB[0][0],
+                  UE->measurements.wideband_cqi_dB[0][1],
+                  UE->measurements.wideband_cqi[0][0],
+                  UE->measurements.wideband_cqi[0][1],
+                  UE->measurements.rx_power_avg_dB[0],
+                  UE->measurements.rx_power_avg[0],
+                  UE->rx_total_gain_dB);
+                  debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
+                  UE->measurements.n0_power_tot_dBm,
+                  UE->measurements.n0_power_dB[0],
+                  UE->measurements.n0_power_dB[1],
+                  UE->measurements.n0_power[0],
+                  UE->measurements.n0_power[1],
+                  UE->measurements.n0_power_avg_dB,
+                  UE->measurements.n0_power_avg);
+                  debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n",
+                  UE->measurements.wideband_cqi_tot[0],
+                  UE->measurements.wideband_cqi_avg[0]);
+                */
+
+                if (transmission_mode==5 || transmission_mode==6) {
+                  if (pmi_feedback == 1) {
+                    pmi_feedback = 0;
+                    hold_channel = 1;
+                    goto PMI_FEEDBACK;
+                  }
+                }
+
+              }
+
+
+              if ((Ns==(2*subframe)) && (l==pilot1)) {// process symbols 0,1,2
+
+                if (dci_flag == 1) {
+                  UE->UE_mode[0] = PUSCH;
+                  start_meas(&UE->dlsch_rx_pdcch_stats);
+                  rx_pdcch(&UE->common_vars,
+                           UE->pdcch_vars,
+                           &UE->frame_parms,
+                           subframe,
+                           0,
+                           (UE->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+                           UE->high_speed_flag,
+                           0);
+                  stop_meas(&UE->dlsch_rx_pdcch_stats);
+                  // overwrite number of pdcch symbols
+                  UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
+
+                  dci_cnt = dci_decoding_procedure(UE,
+                                                   dci_alloc_rx,1,
+                                                   eNB_id,
+                                                   subframe);
+                  //printf("dci_cnt %d\n",dci_cnt);
+
+                  if (dci_cnt==0) {
+                    dlsch_active = 0;
+
+                    if (round==0) {
+                      dci_errors++;
+                      round=5;
+                      errs[0]++;
+                      //round_trials[0]++;
+
+                      if (n_frames==1)
+                        printf("DCI error trial %d errs[0] %d\n",trials,errs[0]);
+                    }
+
+                    //    for (i=1;i<=round;i++)
+                    //      round_trials[i]--;
+                    //    round=5;
+                  }
+
+                  for (i=0; i<dci_cnt; i++) {
+                    //        printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti);
+                    if (round == 0) UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->first_tx=1;
+
+                    if ((dci_alloc_rx[i].rnti == n_rnti) &&
+                        (generate_ue_dlsch_params_from_dci(0,
+							   subframe,
+                                                           dci_alloc_rx[i].dci_pdu,
+                                                           dci_alloc_rx[i].rnti,
+                                                           dci_alloc_rx[i].format,
+                                                           UE->dlsch[0],
+                                                           &UE->frame_parms,
+                                                           UE->pdsch_config_dedicated,
+                                                           SI_RNTI,
+                                                           0,
+                                                           P_RNTI==0,
+                                                           transmission_mode<7?0:transmission_mode))) {
+                      //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
+                      coded_bits_per_codeword = get_G(&eNB->frame_parms,
+                                                      UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl,
+                                                      UE->pdcch_vars[0]->num_pdcch_symbols,
+                                                      0,
+						      subframe,
+						      (transmission_mode<7?0:transmission_mode));
+          	    /*if (transmission_mode==7 && common_flag==0)
+       	    	      UE->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7; */
+
+                      /*
+                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs)][UE->dlsch[0][0]->nb_rb-1]/(coded_bits_per_codeword);
+                      rate*=get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs);
+                      */
+                      printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,
+                             UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->TBS);
+
+                      dlsch_active = 1;
+                    } else {
+                      dlsch_active = 0;
+
+                      if (round==0) {
+                        dci_errors++;
+                        errs[0]++;
+                        //round_trials[0]++;
+                        round=5;
+
+                        if (n_frames==1)
+                          printf("DCI misdetection trial %d\n",trials);
+
+                      }
+
+                      //      for (i=1;i<=round;i++)
+                      //        round_trials[i]--;
+                      //      round=5;
+                    }
+                  }
+                }  // if dci_flag==1
+                else { //dci_flag == 0
+
+                  UE->pdcch_vars[0]->crnti = n_rnti;
+                  UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
+
+                  if (round == 0) UE->dlsch[0][0]->harq_processes[0]->first_tx=1;
+
+                  switch (transmission_mode) {
+                  case 1:
+                  case 2:
+                  case 7:
+                    generate_ue_dlsch_params_from_dci(0,
+						      subframe,
+                                                      &DLSCH_alloc_pdu_1[0],
+                                                      (common_flag==0)? C_RNTI : SI_RNTI,
+                                                      (common_flag==0)? format1 : format1A,
+                                                      UE->dlsch[0],
+                                                      &UE->frame_parms,
+                                                      UE->pdsch_config_dedicated,
+                                                      SI_RNTI,
+                                                      0,
+                                                      P_RNTI,
+                                                      transmission_mode<7?0:transmission_mode);
+          	    /*if(transmission_mode==7 && common_flag==0)
+       	    	      UE->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7;*/ 
+                    break;
+
+                  case 3:
+                    //        printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx);
+                    generate_ue_dlsch_params_from_dci(0,
+						      subframe,
+                                                      &DLSCH_alloc_pdu_1[0],
+                                                      (common_flag==0)? C_RNTI : SI_RNTI,
+                                                      (common_flag==0)? format2A : format1A,
+                                                      UE->dlsch[0],
+                                                      &UE->frame_parms,
+                                                      UE->pdsch_config_dedicated,
+                                                      SI_RNTI,
+                                                      0,
+                                                      P_RNTI,
+                                                      0);
+                    //        printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx);
+                    break;
+
+                  case 4:
+                    generate_ue_dlsch_params_from_dci(0,
+						      subframe,
+                                                      &DLSCH_alloc_pdu_1[0],
+                                                      (common_flag==0)? C_RNTI : SI_RNTI,
+                                                      (common_flag==0)? format2 : format1A,
+                                                      UE->dlsch[0],
+                                                      &UE->frame_parms,
+                                                      UE->pdsch_config_dedicated,
+                                                      SI_RNTI,
+                                                      0,
+                                                      P_RNTI,
+                                                      0);
+                    break;
+
+                  case 5:
+                  case 6:
+                    generate_ue_dlsch_params_from_dci(0,
+						      subframe,
+                                                      &DLSCH_alloc_pdu2_1E[0],
+                                                      C_RNTI,
+                                                      format1E_2A_M10PRB,
+                                                      UE->dlsch[0],
+                                                      &UE->frame_parms,
+                                                      UE->pdsch_config_dedicated,
+                                                      SI_RNTI,
+                                                      0,
+                                                      P_RNTI,
+                                                      0);
+                    break;
+
+                  }
+
+                  dlsch_active = 1;
+                } // if dci_flag == 1
+              }
+
+              if (dlsch_active == 1) {
+                
+		if (transmission_mode==7) {
+		  if (UE->frame_parms.Ncp==0) {
+		    if ((Ns==(2*subframe)   && ((l==3) || (l==6))) ||
+			(Ns==(1+2*subframe) && ((l==2) || (l==5)))) {
+		      if (perfect_ce==0)
+			lte_dl_bf_channel_estimation(UE,eNB_id,0,Ns,5,l+7*(Ns%2==1)); 
+		    }
+		  } else {
+		    msg("Beamforming channel estimation not supported yet for TM7 extented CP.\n");
+		  }
+		}
+
+                if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix)
+
+                  if ((transmission_mode == 5) &&
+                      (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->dl_power_off==0) &&
+                      (UE->use_ia_receiver ==1)) {
+                    dual_stream_UE = 1;
+                  } else {
+                    dual_stream_UE = 0;
+                  }
+
+
+                  start_meas(&UE->dlsch_llr_stats);
+
+                  for (m=UE->pdcch_vars[0]->num_pdcch_symbols;
+                       m<pilot2;
+                       m++) {
+                    if (rx_pdsch(UE,
+                                 PDSCH,
+                                 eNB_id,
+                                 eNB_id_i,
+                                 subframe,
+                                 m,
+                                 (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0,
+                                 dual_stream_UE,
+                                 i_mod,
+                                 UE->dlsch[0][0]->current_harq_pid)==-1) {
+                      dlsch_active = 0;
+                      break;
+                    }
+                  }
+
+                  stop_meas(&UE->dlsch_llr_stats);
+                }
+
+                if ((Ns==(1+(2*subframe))) && (l==pilot1)) {
+                  // process symbols (6 Extended Prefix),7,8,9
+                  start_meas(&UE->dlsch_llr_stats);
+
+                  for (m=pilot2;
+                       m<pilot3;
+                       m++) {
+                    if (rx_pdsch(UE,
+                                 PDSCH,
+                                 eNB_id,
+                                 eNB_id_i,
+                                 subframe,
+                                 m,
+                                 0,
+                                 dual_stream_UE,
+                                 i_mod,
+                                 UE->dlsch[0][0]->current_harq_pid)==-1) {
+                      dlsch_active=0;
+                      break;
+                    }
+                  }
+
+                  stop_meas(&UE->dlsch_llr_stats);
+                }
+
+                if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI
+                  start_meas(&UE->dlsch_llr_stats);
+
+                  for (m=pilot3;
+                       m<UE->frame_parms.symbols_per_tti;
+                       m++) {
+                    //printf("m=%d\n",m);
+                    if (rx_pdsch(UE,
+                                 PDSCH,
+                                 eNB_id,
+                                 eNB_id_i,
+                                 subframe,
+                                 m,
+                                 0,
+                                 dual_stream_UE,
+                                 i_mod,
+                                 UE->dlsch[0][0]->current_harq_pid)==-1) {
+                      dlsch_active=0;
+                      break;
+                    }
+                  }
+
+                  stop_meas(&UE->dlsch_llr_stats);
+                }
+
+
+                if (test_perf ==0 ) {
+                  if ((n_frames==1) && (Ns==(2+(2*subframe))) && (l==0))  {
+                    write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
+
+                    if (eNB->frame_parms.nb_antennas_tx>1)
+                      write_output("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
+
+                    //common vars
+                    //write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+                    write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][subframe*UE->frame_parms.samples_per_tti],UE->frame_parms.samples_per_tti,1,1);
+                    //write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                    write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+                    if (UE->frame_parms.nb_antennas_rx>1) {
+                      write_output("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+                      write_output("rxsigF1.m","rxsF1", UE->common_vars.rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                    }
+
+                    write_output("dlsch00_r0.m","dl00_r0",
+                                 &(UE->common_vars.dl_ch_estimates[eNB_id][0][0]),
+                                 UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+                    if (UE->frame_parms.nb_antennas_rx>1)
+                      write_output("dlsch01_r0.m","dl01_r0",
+                                   &(UE->common_vars.dl_ch_estimates[eNB_id][1][0]),
+                                   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+                    if (eNB->frame_parms.nb_antennas_tx>1)
+                      write_output("dlsch10_r0.m","dl10_r0",
+                                   &(UE->common_vars.dl_ch_estimates[eNB_id][2][0]),
+                                   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+                    if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
+                      write_output("dlsch11_r0.m","dl11_r0",
+                                   &(UE->common_vars.dl_ch_estimates[eNB_id][3][0]),
+                                   UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+
+                    //pdsch_vars
+                    dump_dlsch2(UE,eNB_id,coded_bits_per_codeword,round);
+                    //dump_dlsch2(UE,eNB_id_i,coded_bits_per_codeword);
+                    write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+
+                    //pdcch_vars
+                    write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+                    write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+
+                    write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
+                    write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
+
+                  }
+                }
+              }
+            }
+          }
+
+          //saving PMI in case of Transmission Mode > 5
+
+          if(abstx) {
+            if (trials==0 && round==0 && transmission_mode>=5 && transmission_mode<7) {
+              for (iii=0; iii<NB_RB; iii++) {
+                //fprintf(csv_fd, "%d, %d", (UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
+                fprintf(csv_fd,"%x,%x,",(UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
+                printf("%x ",(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
+              }
+            }
+          }
+
+          for (int cw=Kmimo-1; cw>=0; cw--) {
+            UE->dlsch[0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+            coded_bits_per_codeword = get_G(&eNB->frame_parms,
+                                            eNB->dlsch[0][cw]->harq_processes[0]->nb_rb,
+                                            eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc,
+                                            get_Qm(eNB->dlsch[0][cw]->harq_processes[0]->mcs),
+                                            eNB->dlsch[0][cw]->harq_processes[0]->Nl,
+                                            num_pdcch_symbols,
+                                            0,
+					    subframe,
+					    (transmission_mode<7?0:transmission_mode));
+
+            UE->dlsch[0][cw]->harq_processes[UE->dlsch[0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
+
+
+	                
+            // calculate uncoded BLER
+            uncoded_ber=0;
+            for (i=0;i<coded_bits_per_codeword;i++)
+              if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[0]->llr[0][i]<0)) {
+                uncoded_ber_bit[i] = 1;
+                uncoded_ber++;
+              }
+              else
+                uncoded_ber_bit[i] = 0;
+
+            uncoded_ber/=coded_bits_per_codeword;
+            avg_ber += uncoded_ber;
+
+            if (n_frames==1)
+              write_output("uncoded_ber_bit.m","uncoded_ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+            
+
+            start_meas(&UE->dlsch_unscrambling_stats);
+            dlsch_unscrambling(&UE->frame_parms,
+                               0,
+                               UE->dlsch[0][cw],
+                               coded_bits_per_codeword,
+                               UE->pdsch_vars[eNB_id]->llr[cw],
+                               0,
+                               subframe<<1);
+            stop_meas(&UE->dlsch_unscrambling_stats);
+
+            start_meas(&UE->dlsch_decoding_stats);
+            ret = dlsch_decoding(UE,
+                                 UE->pdsch_vars[eNB_id]->llr[cw],
+                                 &UE->frame_parms,
+                                 UE->dlsch[0][cw],
+                                 UE->dlsch[0][cw]->harq_processes[UE->dlsch[0][cw]->current_harq_pid],
+                                 subframe,
+                                 UE->dlsch[0][cw]->current_harq_pid,
+                                 1,llr8_flag);
+            stop_meas(&UE->dlsch_decoding_stats);
+
+            if (cw==1) {
+              if (ret <= UE->dlsch[0][cw]->max_turbo_iterations) {
+              } else {
+                errs2[round]++;
+              }
+            }
+          }
+
+
+          stop_meas(&UE->phy_proc_rx);
+
+
+          if (ret <= UE->dlsch[0][0]->max_turbo_iterations) {
+
+            avg_iter += ret;
+            iter_trials++;
+
+            if (n_frames==1)
+              printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber);
+
+            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->TBS;
+            TB0_active = 0;
+
+            if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
+              /*
+              for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) {
+              // re-encoding of first stream
+              dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
+              dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc_even[0];
+              dlsch0_eNB_harq->nb_rb        = dlsch0_ue_harq->nb_rb;
+              dlsch0_eNB_harq->mcs          = dlsch0_ue_harq->mcs;
+              dlsch0_eNB_harq->rvidx        = dlsch0_ue_harq->rvidx;
+              dlsch0_eNB_harq->Nl           = dlsch0_ue_harq->Nl;
+
+              dlsch0_eNB_harq->TBS          = dlsch0_ue_harq->TBS;
+              dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
+              dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
+
+              UE->dlsch[eNB_id]->active       = UE->dlsch[eNB_id][0]->active;
+              UE->dlsch[eNB_id]->rnti         = UE->dlsch[eNB_id][0]->rnti;
+
+              dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b,
+                   &UE->frame_parms,
+                   num_pdcch_symbols,
+                   UE->dlsch[0],
+                   0,subframe,
+                   &UE->dlsch_rate_matching_stats,
+                   &UE->dlsch_turbo_encoding_stats,
+                   &UE->dlsch_interleaving_stats
+                   );
+
+                   //scrambling
+
+              //modulation
+
+              //stripping (from matched filter output?)
+
+              //detection of second stream
+              }
+              */
+            }
+          } else {
+            errs[round]++;
+
+            avg_iter += ret-1;
+            iter_trials++;
+
+            if (n_frames==1) {
+              //if ((n_frames==1) || (SNR>=30)) 
+              printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
+
+              for (s=0; s<UE->dlsch[0][0]->harq_processes[0]->C; s++) {
+                if (s<UE->dlsch[0][0]->harq_processes[0]->Cminus)
+                  Kr = UE->dlsch[0][0]->harq_processes[0]->Kminus;
+                else
+                  Kr = UE->dlsch[0][0]->harq_processes[0]->Kplus;
+
+                Kr_bytes = Kr>>3;
+
+                printf("Decoded_output (Segment %d):\n",s);
+
+                for (i=0; i<Kr_bytes; i++)
+                  printf("%d : %x (%x)\n",i,UE->dlsch[0][0]->harq_processes[0]->c[s][i],UE->dlsch[0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+              }
+
+              sprintf(fname,"rxsig0_r%d.m",round);
+              sprintf(vname,"rxs0_r%d",round);
+              write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+              sprintf(fname,"rxsigF0_r%d.m",round);
+              sprintf(vname,"rxs0F_r%d",round);
+              write_output(fname,vname, &UE->common_vars.rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+	     
+              if (UE->frame_parms.nb_antennas_rx>1) {
+                sprintf(fname,"rxsig1_r%d.m",round);
+                sprintf(vname,"rxs1_r%d.m",round);
+                write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+                sprintf(fname,"rxsig1F_r%d.m",round);
+                sprintf(vname,"rxs1F_r%d.m",round);
+                write_output(fname,vname, UE->common_vars.rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              }
+
+              sprintf(fname,"dlsch00_r%d.m",round);
+              sprintf(vname,"dl00_r%d",round);
+              write_output(fname,vname,
+                           &(UE->common_vars.dl_ch_estimates[eNB_id][0][0]),
+                           UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+
+              if (UE->frame_parms.nb_antennas_rx>1) {
+                sprintf(fname,"dlsch01_r%d.m",round);
+                sprintf(vname,"dl01_r%d",round);
+                write_output(fname,vname,
+                             &(UE->common_vars.dl_ch_estimates[eNB_id][1][0]),
+                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+              }
+
+              if (eNB->frame_parms.nb_antennas_tx>1) {
+                sprintf(fname,"dlsch10_r%d.m",round);
+                sprintf(vname,"dl10_r%d",round);
+                write_output(fname,vname,
+                             &(UE->common_vars.dl_ch_estimates[eNB_id][2][0]),
+                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+              }
+
+              if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
+                sprintf(fname,"dlsch11_r%d.m",round);
+                sprintf(vname,"dl11_r%d",round);
+                write_output(fname,vname,
+                             &(UE->common_vars.dl_ch_estimates[eNB_id][3][0]),
+                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+              }
+
+              //pdsch_vars
+              dump_dlsch2(UE,eNB_id,coded_bits_per_codeword,round);
+              /*
+              write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+              write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+              write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
+              write_output("dlsch_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              */
+
+              if (round == 3) exit(-1);
+            }
+
+            //      printf("round %d errors %d/%d\n",round,errs[round],trials);
+
+            round++;
+            //      UE->dlsch[0][0]->harq_processes[0]->round++;
+          }
+
+	  if (xforms==1) {
+	    phy_scope_UE(form_ue,
+			 UE,
+			 eNB_id,
+			 0,// UE_id
+			 subframe);
+	  }
+
+        }  //round
+
+        //      printf("\n");
+
+        if ((errs[0]>=n_frames/10) && (trials>(n_frames/2)))
+          break;
+
+        //len = chbch_stats_read(stats_buffer,NULL,0,4096);
+        //printf("%s\n\n",stats_buffer);
+
+        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
+          UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
+          LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
+                UE->bitrate[eNB_id]/1000);
+          UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id];
+        }
+
+
+        UE->proc.proc_rxtx[subframe&1].frame_rx++;
+
+        /* calculate the total processing time for each packet,
+         * get the max, min, and number of packets that exceed t>2000us
+         */
+        double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0;
+        double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0;
+        double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0;
+        double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
+
+
+        double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0;
+        double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
+        double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
+        double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0;
+
+        if (t_tx > t_tx_max)
+          t_tx_max = t_tx;
+
+        if (t_tx < t_tx_min)
+          t_tx_min = t_tx;
+
+        if (t_rx > t_rx_max)
+          t_rx_max = t_rx;
+
+        if (t_rx < t_rx_min)
+          t_rx_min = t_rx;
+
+        if (t_tx > 2000)
+          n_tx_dropped++;
+
+        if (t_rx > 2000)
+          n_rx_dropped++;
+
+        push_front(&time_vector_tx, t_tx);
+        push_front(&time_vector_tx_ifft, t_tx_ifft);
+        push_front(&time_vector_tx_mod, t_tx_mod);
+        push_front(&time_vector_tx_enc, t_tx_enc);
+
+        push_front(&time_vector_rx, t_rx);
+        push_front(&time_vector_rx_fft, t_rx_fft);
+        push_front(&time_vector_rx_demod, t_rx_demod);
+        push_front(&time_vector_rx_dec, t_rx_dec);
+
+
+      }   //trials
+
+      // round_trials[0]: number of code word : goodput the protocol
+      double table_tx[time_vector_tx.size];
+      totable(table_tx, &time_vector_tx);
+      double table_tx_ifft[time_vector_tx_ifft.size];
+      totable(table_tx_ifft, &time_vector_tx_ifft);
+      double table_tx_mod[time_vector_tx_mod.size];
+      totable(table_tx_mod, &time_vector_tx_mod);
+      double table_tx_enc[time_vector_tx_enc.size];
+      totable(table_tx_enc, &time_vector_tx_enc);
+
+      double table_rx[time_vector_rx.size];
+      totable(table_rx, &time_vector_rx);
+      double table_rx_fft[time_vector_rx_fft.size];
+      totable(table_rx_fft, &time_vector_rx_fft);
+      double table_rx_demod[time_vector_rx_demod.size];
+      totable(table_rx_demod, &time_vector_rx_demod);
+      double table_rx_dec[time_vector_rx_dec.size];
+      totable(table_rx_dec, &time_vector_rx_dec);
+
+
+      // sort table
+      qsort (table_tx, time_vector_tx.size, sizeof(double), &compare);
+      qsort (table_rx, time_vector_rx.size, sizeof(double), &compare);
+
+      if (dump_table == 1 ) {
+        set_component_filelog(USIM);  // file located in /tmp/usim.txt
+        int n;
+        LOG_F(USIM,"The transmitter raw data: \n");
+
+        for (n=0; n< time_vector_tx.size; n++) {
+          printf("%f ", table_tx[n]);
+          LOG_F(USIM,"%f ", table_tx[n]);
+        }
+
+        LOG_F(USIM,"\n");
+        LOG_F(USIM,"The receiver raw data: \n");
+
+        for (n=0; n< time_vector_rx.size; n++) {
+          // printf("%f ", table_rx[n]);
+          LOG_F(USIM,"%f ", table_rx[n]);
+        }
+
+        LOG_F(USIM,"\n");
+      }
+
+      double tx_median = table_tx[time_vector_tx.size/2];
+      double tx_q1 = table_tx[time_vector_tx.size/4];
+      double tx_q3 = table_tx[3*time_vector_tx.size/4];
+
+      double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2];
+      double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4];
+      double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4];
+
+      double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2];
+      double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4];
+      double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4];
+
+      double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2];
+      double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4];
+      double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4];
+
+      double rx_median = table_rx[time_vector_rx.size/2];
+      double rx_q1 = table_rx[time_vector_rx.size/4];
+      double rx_q3 = table_rx[3*time_vector_rx.size/4];
+
+      double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2];
+      double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4];
+      double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4];
+
+      double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2];
+      double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4];
+      double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4];
+
+      double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2];
+      double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4];
+      double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4];
+
+      double std_phy_proc_tx=0;
+      double std_phy_proc_tx_ifft=0;
+      double std_phy_proc_tx_mod=0;
+      double std_phy_proc_tx_enc=0;
+
+      double std_phy_proc_rx=0;
+      double std_phy_proc_rx_fft=0;
+      double std_phy_proc_rx_demod=0;
+      double std_phy_proc_rx_dec=0;
+
+      effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]));
+
+      printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n",
+             SNR,
+             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)),
+             sigma2_dB);
+
+      printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f  (%2.1f%%,%f, %f), normalized delay %f (%f)\n",
+             errs[0],
+             errs2[0],
+             round_trials[0],
+             errs[1],
+             round_trials[0],
+             errs[2],
+             round_trials[0],
+             errs[3],
+             round_trials[0],
+             (double)errs[0]/(round_trials[0]),
+             (double)errs[1]/(round_trials[0]),
+             (double)errs[2]/(round_trials[0]),
+             (double)errs[3]/(round_trials[0]),
+             dci_errors,
+             round_trials[0],
+             (double)dci_errors/(round_trials[0]),
+             rate*effective_rate,
+             100*effective_rate,
+             rate,
+             rate*get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs),
+             (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+             (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+             (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+
+      if (print_perf==1) {
+        printf("eNB TX function statistics (per 1ms subframe)\n\n");
+        std_phy_proc_tx = sqrt((double)eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/eNB->phy_proc_tx.trials - pow((double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc tx                 :%f us (%d trials)\n",(double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_tx.trials);
+        printf("|__ Statistcs                           std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3,
+               n_tx_dropped);
+        std_phy_proc_tx_ifft = sqrt((double)eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                    2)/eNB->ofdm_mod_stats.trials - pow((double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2));
+        printf("OFDM_mod time                     :%f us (%d trials)\n",(double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,eNB->ofdm_mod_stats.trials);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);
+        std_phy_proc_tx_mod = sqrt((double)eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/eNB->dlsch_modulation_stats.trials - pow((double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2));
+        printf("DLSCH modulation time             :%f us (%d trials)\n",(double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0,
+               eNB->dlsch_modulation_stats.trials);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);
+        printf("DLSCH scrambling time             :%f us (%d trials)\n",(double)eNB->dlsch_scrambling_stats.diff/eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0,
+               eNB->dlsch_scrambling_stats.trials);
+        std_phy_proc_tx_enc = sqrt((double)eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/eNB->dlsch_encoding_stats.trials - pow((double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2));
+        printf("DLSCH encoding time               :%f us (%d trials)\n",(double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0,
+               eNB->dlsch_modulation_stats.trials);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);
+        printf("|__ DLSCH turbo encoding time         :%f us (%d trials)\n",
+               ((double)eNB->dlsch_turbo_encoding_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+               eNB->dlsch_turbo_encoding_stats.diff/eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_turbo_encoding_stats.trials);
+        printf("|__ DLSCH rate-matching time          :%f us (%d trials)\n",
+               ((double)eNB->dlsch_rate_matching_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+               eNB->dlsch_rate_matching_stats.diff/eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_rate_matching_stats.trials);
+        printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n",
+               ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
+               eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
+
+        printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx.trials - pow((double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx.trials*2/3);
+        printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
+               rx_q1, rx_q3, n_rx_dropped);
+        std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->ofdm_demod_stats.trials - pow((double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2));
+        printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0,
+               UE->ofdm_demod_stats.trials*2/3);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3);
+        printf("|__ DLSCH rx dft                                        :%f us (%d trials)\n",
+               (nsymb*UE->frame_parms.nb_antennas_rx)*(double)UE->rx_dft_stats.diff/UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,UE->rx_dft_stats.trials*2/3);
+        printf("|__ DLSCH channel estimation time                       :%f us (%d trials)\n",
+               (4.0)*(double)UE->dlsch_channel_estimation_stats.diff/UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_channel_estimation_stats.trials*2/3);
+        printf("|__ DLSCH frequency offset estimation time              :%f us (%d trials)\n",
+               (4.0)*(double)UE->dlsch_freq_offset_estimation_stats.diff/UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0,
+               UE->dlsch_freq_offset_estimation_stats.trials*2/3);
+        printf("DLSCH rx pdcch                                       :%f us (%d trials)\n",(double)UE->dlsch_rx_pdcch_stats.diff/UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0,
+               UE->dlsch_rx_pdcch_stats.trials);
+        std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                     2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2));
+        printf("DLSCH Channel Compensation and LLR generation time  :%f us (%d trials)\n",(3)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0,
+               UE->dlsch_llr_stats.trials/3);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
+        printf("DLSCH unscrambling time                             :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
+               UE->dlsch_unscrambling_stats.trials);
+        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->dlsch_decoding_stats.trials - pow((double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2));
+        printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
+               eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials,
+               (double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats.trials,
+               (double)UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0);
+        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
+        printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
+               (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
+        printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
+               UE->dlsch[0][0]->harq_processes[0]->Cminus ? UE->dlsch[0][0]->harq_processes[0]->Kminus : UE->dlsch[0][0]->harq_processes[0]->Kplus,
+               (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
+        printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
+               (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/((double)avg_iter/iter_trials),
+               UE->dlsch_tc_init_stats.trials);
+        printf("    |__ alpha                                           %f us (cycles/iter %f, %d trials)\n",
+               (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials*2,
+               UE->dlsch_tc_alpha_stats.trials);
+        printf("    |__ beta                                            %f us (cycles/iter %f,%d trials)\n",
+               (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials*2,
+               UE->dlsch_tc_beta_stats.trials);
+        printf("    |__ gamma                                           %f us (cycles/iter %f,%d trials)\n",
+               (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials*2,
+               UE->dlsch_tc_gamma_stats.trials);
+        printf("    |__ ext                                             %f us (cycles/iter %f,%d trials)\n",
+               (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials*2,
+               UE->dlsch_tc_ext_stats.trials);
+        printf("    |__ intl1                                           %f us (cycles/iter %f,%d trials)\n",
+               (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials,
+               UE->dlsch_tc_intl1_stats.trials);
+        printf("    |__ intl2+HD+CRC                                    %f us (cycles/iter %f,%d trials)\n",
+               (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0,
+               (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials,
+               UE->dlsch_tc_intl2_stats.trials);
+      }
+
+      if ((transmission_mode != 3) && (transmission_mode != 4)) {
+        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
+                SNR,
+                mcs1,
+                eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                rate,
+                errs[0],
+                round_trials[0],
+                errs[1],
+                round_trials[1],
+                errs[2],
+                round_trials[2],
+                errs[3],
+                round_trials[3],
+                dci_errors);
+      } else {
+        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
+                SNR,
+                mcs1,mcs2,
+                eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                eNB->dlsch[0][1]->harq_processes[0]->TBS,
+                rate,
+                errs[0],
+                round_trials[0],
+                errs[1],
+                round_trials[1],
+                errs[2],
+                round_trials[2],
+                errs[3],
+                round_trials[3],
+                dci_errors);
+      }
+
+
+      if(abstx) { //ABSTRACTION
+        blerr[0] = (double)errs[0]/(round_trials[0]);
+
+        if(num_rounds>1) {
+          blerr[1] = (double)errs[1]/(round_trials[1]);
+          blerr[2] = (double)errs[2]/(round_trials[2]);
+          blerr[3] = (double)errs[3]/(round_trials[3]);
+          fprintf(csv_fd,"%e,%e,%e,%e;\n",blerr[0],blerr[1],blerr[2],blerr[3]);
+        } else {
+          fprintf(csv_fd,"%e;\n",blerr[0]);
+        }
+      } //ABStraction
+
+      if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
+        //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
+        if ((transmission_mode != 3) && (transmission_mode != 4)) {
+          fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+                  SNR,
+                  mcs1,
+                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  rate,
+                  errs[0],
+                  round_trials[0],
+                  errs[1],
+                  round_trials[1],
+                  errs[2],
+                  round_trials[2],
+                  errs[3],
+                  round_trials[3],
+                  dci_errors);
+
+          //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+          fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
+                  SNR,
+                  mcs1,
+                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  rate*effective_rate,
+                  100*effective_rate,
+                  rate,
+                  (double)avg_iter/iter_trials,
+                  errs[0],
+                  round_trials[0],
+                  errs[1],
+                  round_trials[1],
+                  errs[2],
+                  round_trials[2],
+                  errs[3],
+                  round_trials[3],
+                  (double)errs[0]/(round_trials[0]),
+                  (double)errs[1]/(round_trials[0]),
+                  (double)errs[2]/(round_trials[0]),
+                  (double)errs[3]/(round_trials[0]),
+                  dci_errors,
+                  round_trials[0],
+                  (double)dci_errors/(round_trials[0]),
+                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+        } else {
+          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+                  SNR,
+                  mcs1,mcs2,
+                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
+                  rate,
+                  errs[0],
+                  round_trials[0],
+                  errs[1],
+                  round_trials[1],
+                  errs[2],
+                  round_trials[2],
+                  errs[3],
+                  round_trials[3],
+                  dci_errors);
+
+          //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
+          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
+                  SNR,
+                  mcs1,mcs2,
+                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
+                  rate*effective_rate,
+                  100*effective_rate,
+                  rate,
+                  (double)avg_iter/iter_trials,
+                  errs[0],
+                  round_trials[0],
+                  errs[1],
+                  round_trials[1],
+                  errs[2],
+                  round_trials[2],
+                  errs[3],
+                  round_trials[3],
+                  (double)errs[0]/(round_trials[0]),
+                  (double)errs[1]/(round_trials[0]),
+                  (double)errs[2]/(round_trials[0]),
+                  (double)errs[3]/(round_trials[0]),
+                  dci_errors,
+                  round_trials[0],
+                  (double)dci_errors/(round_trials[0]),
+                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
+                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
+                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
+        }
+
+        //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n",
+        fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;",
+                eNB->phy_proc_tx.trials,
+                eNB->ofdm_mod_stats.trials,
+                eNB->dlsch_modulation_stats.trials,
+                eNB->dlsch_scrambling_stats.trials,
+                eNB->dlsch_encoding_stats.trials,
+                UE->phy_proc_rx.trials,
+                UE->ofdm_demod_stats.trials,
+                UE->dlsch_rx_pdcch_stats.trials,
+                UE->dlsch_llr_stats.trials,
+                UE->dlsch_unscrambling_stats.trials,
+                UE->dlsch_decoding_stats.trials
+               );
+        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
+                get_time_meas_us(&eNB->phy_proc_tx),
+                get_time_meas_us(&eNB->ofdm_mod_stats),
+                get_time_meas_us(&eNB->dlsch_modulation_stats),
+                get_time_meas_us(&eNB->dlsch_scrambling_stats),
+                get_time_meas_us(&eNB->dlsch_encoding_stats),
+                get_time_meas_us(&UE->phy_proc_rx),
+                nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
+                get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
+                3*get_time_meas_us(&UE->dlsch_llr_stats),
+                get_time_meas_us(&UE->dlsch_unscrambling_stats),
+                get_time_meas_us(&UE->dlsch_decoding_stats)
+               );
+        //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
+
+        //fprintf(time_meas_fd,"IFFT;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);
+
+        //fprintf(time_meas_fd,"MOD;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);
+
+        //fprintf(time_meas_fd,"ENC;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);
+
+
+        //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped);
+
+        //fprintf(time_meas_fd,"FFT;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3);
+
+        //fprintf(time_meas_fd,"DEMOD;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3);
+
+        //fprintf(time_meas_fd,"DEC;\n");
+        fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
+
+
+        /*
+        fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+        eNB->phy_proc_tx.trials,
+        eNB->ofdm_mod_stats.trials,
+        eNB->dlsch_modulation_stats.trials,
+        eNB->dlsch_scrambling_stats.trials,
+        eNB->dlsch_encoding_stats.trials,
+        UE->phy_proc_rx.trials,
+        UE->ofdm_demod_stats.trials,
+        UE->dlsch_rx_pdcch_stats.trials,
+        UE->dlsch_llr_stats.trials,
+        UE->dlsch_unscrambling_stats.trials,
+        UE->dlsch_decoding_stats.trials);
+        */
+        printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
+        break;
+      } else if (test_perf !=0 ) {
+        printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
+      }
+
+      if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
+        break;
+    }// SNR
+
+
+  } //ch_realization
+
+
+  fclose(bler_fd);
+
+  if (test_perf !=0)
+    fclose (time_meas_fd);
+
+  //fprintf(tikz_fd,"};\n");
+  //fclose(tikz_fd);
+
+  if (input_trch_file==1)
+    fclose(input_trch_fd);
+
+  if (input_file==1)
+    fclose(input_fd);
+
+  if(abstx) { // ABSTRACTION
+    fprintf(csv_fd,"];");
+    fclose(csv_fd);
+  }
+
+  if (uncoded_ber_bit)
+    free(uncoded_ber_bit);
+
+  uncoded_ber_bit = NULL;
+
+  for (k=0; k<n_users; k++) {
+    free(input_buffer0[k]);
+    free(input_buffer1[k]);
+    input_buffer0[k]=NULL;
+    input_buffer1[k]=NULL;
+  }
+
+  printf("Freeing dlsch structures\n");
+
+  for (i=0; i<2; i++) {
+    printf("eNB %d\n",i);
+    free_eNB_dlsch(eNB->dlsch[0][i]);
+    printf("UE %d\n",i);
+    free_ue_dlsch(UE->dlsch[0][i]);
+  }
+
+
+  printf("Freeing channel I/O\n");
+
+  for (i=0; i<n_tx_phy; i++){
+    free(s_re[i]);
+    free(s_im[i]);
+  }
+
+  for (i=0; i<2; i++) {
+    free(r_re[i]);
+    free(r_im[i]);
+  }
+
+
+  free(s_re);
+  free(s_im);
+  free(r_re);
+  free(r_im);
+
+  //  lte_sync_time_free();
+
+  //  printf("[MUMIMO] mcs %d, mcsi %d, offset %d, bler %f\n",mcs,mcs_i,offset_mumimo_llr_drange_fix,((double)errs[0])/((double)round_trials[0]));
+
+  return(0);
+}
+
+
diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c
index 9d6530414e4a95e361bb988c01ad1dff87df7b04..d056bea5d0eaad6fe28fe807658167d3ef60d748 100644
--- a/openair1/SIMULATION/LTE_PHY/framegen.c
+++ b/openair1/SIMULATION/LTE_PHY/framegen.c
@@ -394,7 +394,7 @@ void lte_param_init(  unsigned char transmission_mode,
   lte_frame_parms->Nid_cell           = Nid_cell;
   lte_frame_parms->nushift            = Nid_cell%6;
   lte_frame_parms->nb_antennas_tx     = (transmission_mode == 1) ? 1 : 2;
-  lte_frame_parms->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2;
+  lte_frame_parms->nb_antenna_ports_eNB = (transmission_mode == 1) ? 1 : 2;
   lte_frame_parms->nb_antennas_rx     = (transmission_mode == 1) ? 1 : 2;
   lte_frame_parms->mode1_flag = (transmission_mode == 1)? 1 : 0;
   lte_frame_parms->phich_config_common.phich_resource = oneSixth;
diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c
index 11c1760cb33e9b328e1387b9ac6461934bb2cf54..7849dec1ab4448b5eddc6ed8f1fc975975e1b74d 100644
--- a/openair1/SIMULATION/LTE_PHY/mbmssim.c
+++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c
@@ -238,6 +238,7 @@ int main(int argc, char **argv)
     n_tx=2;
 
   lte_param_init(n_tx,
+                 n_tx,
 		 n_rx,
 		 transmission_mode,
 		 extended_prefix_flag,
@@ -301,7 +302,7 @@ int main(int argc, char **argv)
                                 0);
 
   // Create transport channel structures for 2 transport blocks (MIMO)
-  eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0);
+  eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
 
   if (!eNB->dlsch_MCH) {
     printf("Can't get eNB dlsch structures\n");
@@ -475,11 +476,11 @@ int main(int argc, char **argv)
       }
 
       UE->dlsch_MCH[0]->harq_processes[0]->G = get_G(&UE->frame_parms,
-          UE->dlsch_MCH[0]->harq_processes[0]->nb_rb,
-          UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
-          get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs),
-          1,2,
-          UE->proc.proc_rxtx[0].frame_tx,subframe);
+						     UE->dlsch_MCH[0]->harq_processes[0]->nb_rb,
+						     UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
+						     get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs),
+						     1,2,
+						     UE->proc.proc_rxtx[0].frame_tx,subframe,0);
       UE->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs);
 
       dlsch_unscrambling(&UE->frame_parms,1,UE->dlsch_MCH[0],
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index f696cc8da4e32d6a11ddccfecfa88ee4e4ccc6f9..83906d73226dd476f2a2a6b472cf0403fb8984de 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -325,7 +325,7 @@ int main(int argc, char **argv)
   if (transmission_mode>=2)
     n_tx=2;
 
-  lte_param_init(n_tx,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,3,N_RB_DL,0,osf,0);
+  lte_param_init(n_tx, n_tx,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,3,N_RB_DL,0,osf,0);
 
   eNB1 = malloc(sizeof(PHY_VARS_eNB));
   eNB2 = malloc(sizeof(PHY_VARS_eNB));
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index 0b79ec52ba6b3036763819089d90a1992fb238d4..04b9d304b39d21be6cefb42d997d2b2bda9c99d2 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -694,6 +694,7 @@ int main(int argc, char **argv)
     n_tx=2;
 
   lte_param_init(n_tx,
+                 n_tx,
                  n_rx,
                  transmission_mode,
                  extended_prefix_flag,
@@ -737,7 +738,7 @@ int main(int argc, char **argv)
          subframe,NUMBER_OF_OFDM_CARRIERS,
          eNB->frame_parms.Ncp,eNB->frame_parms.samples_per_tti,nsymb);
 
-  eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx_eNB,
+  eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
                                 UE->frame_parms.nb_antennas_rx,
                                 channel_model,
 				N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
@@ -812,7 +813,7 @@ int main(int argc, char **argv)
     for (trial=0; trial<n_frames; trial++) {
       
       //    printf("DCI (SF %d): txdataF %p (0 %p)\n",subframe,&eNB->common_vars.txdataF[eNb_id][aa][512*14*subframe],&eNB->common_vars.txdataF[eNb_id][aa][0]);
-      for (aa=0; aa<eNB->frame_parms.nb_antennas_tx_eNB; aa++) {
+      for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
         memset(&eNB->common_vars.txdataF[eNb_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
 
       }
@@ -951,15 +952,14 @@ int main(int argc, char **argv)
         if (n_frames==1) {
           write_output("txsigF0.m","txsF0", eNB->common_vars.txdataF[eNb_id][0],4*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX,1,1);
 
-          if (eNB->frame_parms.nb_antennas_tx_eNB > 1)
+          if (eNB->frame_parms.nb_antenna_ports_eNB > 1)
             write_output("txsigF1.m","txsF1", eNB->common_vars.txdataF[eNb_id][1],4*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX,1,1);
         }
 
         tx_lev = 0;
 
 
-
-        for (aa=0; aa<eNB->frame_parms.nb_antennas_tx_eNB; aa++) {
+        for (aa=0; aa<eNB->frame_parms.nb_antenna_ports_eNB; aa++) {
           if (eNB->frame_parms.Ncp == 1)
             PHY_ofdm_mod(&eNB->common_vars.txdataF[eNb_id][aa][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],        // input,
                          &txdata[aa][subframe*eNB->frame_parms.samples_per_tti],         // output
@@ -982,7 +982,7 @@ int main(int argc, char **argv)
       }
 
       for (i=0; i<2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) {
-        for (aa=0; aa<eNB->frame_parms.nb_antennas_tx_eNB; aa++) {
+        for (aa=0; aa<eNB->frame_parms.nb_antenna_ports_eNB; aa++) {
           if (awgn_flag == 0) {
             s_re[aa][i] = ((double)(((short *)txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
             s_im[aa][i] = ((double)(((short *)txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)+1]);
@@ -1069,7 +1069,7 @@ int main(int argc, char **argv)
               }
             }
           } else {
-            for(aa=0; aa<frame_parms->nb_antennas_tx_eNB; aa++) {
+            for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
               for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                 for (i=0; i<frame_parms->N_RB_DL*12; i++) {
                   ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c
index ad57d17507e092986e8bcbd463e7d9bd9476c36e..7acc07528c4763cc3e23fb4d34bece13be8c7473 100644
--- a/openair1/SIMULATION/LTE_PHY/prachsim.c
+++ b/openair1/SIMULATION/LTE_PHY/prachsim.c
@@ -308,6 +308,7 @@ int main(int argc, char **argv)
     n_tx=2;
 
   lte_param_init(n_tx,
+                 n_tx,
 		 n_rx,
 		 transmission_mode,
 		 extended_prefix_flag,
diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c
index 843cd27a5453919d554fc9296b5bcb4007f39665..77bfcb18cf68682f2d80f87cd371c92c5e45d25d 100644
--- a/openair1/SIMULATION/LTE_PHY/pucchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c
@@ -296,6 +296,7 @@ int main(int argc, char **argv)
     n_tx=2;
 
   lte_param_init(n_tx,
+                 n_tx,
 		 n_rx,
 		 transmission_mode,
 		 extended_prefix_flag,
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 2bf96c3020f5e24a7ef34c3ce5e592426509eaa0..cf9e5aaa30ae9e42a850d2111626471ec2111f96 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -20,7 +20,7 @@
  */
 
 /*! \file ulsim.c
- \brief Top-level DL simulator
+ \brief Top-level UL simulator
  \author R. Knopp
  \date 2011 - 2014
  \version 0.1
@@ -554,6 +554,7 @@ int main(int argc, char **argv)
   }
 
   lte_param_init(1,
+                 1, 
 		 n_rx,
 		 1,
 		 extended_prefix_flag,
@@ -679,7 +680,7 @@ int main(int argc, char **argv)
   }
   // Create transport channel structures for 2 transport blocks (MIMO)
   for (i=0; i<2; i++) {
-    eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0);
+    eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms);
     UE->dlsch[0][i]  = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
     if (!eNB->dlsch[0][i]) {
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index fdf953597e79ce2e9b67c9184d9ab1892451416b..80e80bcb00419b4c146bb36bc1162b99b496268b 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -1072,14 +1072,14 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
 
               if ((nb_antennas_tx <1) || (nb_antennas_tx > 64))
                 AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antennas_tx choice: 1..4 !\n",
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antennas_tx choice: 1..64 !\n",
                              lib_config_file_name_pP, i, nb_antennas_tx);
 
               enb_properties.properties[enb_properties_index]->nb_antennas_rx[j] = nb_antennas_rx;
 
-              if ((nb_antennas_rx <1) || (nb_antennas_rx > 4))
+              if ((nb_antennas_rx <1) || (nb_antennas_rx > 64))
                 AssertFatal (0,
-                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antennas_rx choice: 1..4 !\n",
+                             "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antennas_rx choice: 1..64 !\n",
                              lib_config_file_name_pP, i, nb_antennas_rx);
 
               enb_properties.properties[enb_properties_index]->tx_gain[j] = tx_gain;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 91adb5fb2295ec43c64ab7106f8ac67bc8ab33c9..399fd701cec13119ab204a843398391a41f326fb 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -641,6 +641,7 @@ schedule_ue_spec(
           switch (mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) {
           case 1:
           case 2:
+          case 7:
           default:
             switch (frame_parms[CC_id]->N_RB_DL) {
             case 6:
@@ -725,7 +726,8 @@ schedule_ue_spec(
             }
 
             break;
-
+	    /* 
+	    // this code is disabled for now - needs to be done properly
           case 4:
             //    if (nb_rb>10) {
             ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0;
@@ -763,6 +765,7 @@ schedule_ue_spec(
             ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
             ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[UE_id];
             break;
+	    */
           }
 
           add_ue_dlsch_info(module_idP,
@@ -1417,8 +1420,9 @@ schedule_ue_spec(
 
             break;
 
+	    /*
+	    // disabled for now as this needs to be done properly
           case 4:
-            //  if (nb_rb>10) {
             ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs;
             ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
             ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1;
@@ -1426,15 +1430,6 @@ schedule_ue_spec(
             ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
 	    ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc;
 
-            //}
-            /* else {
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->mcs1 = eNB_UE_stats->DL_cqi[0];
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 1;
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3;
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->tpmi = 5;
-               ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
-               }*/
             break;
 
           case 5:
@@ -1465,6 +1460,7 @@ schedule_ue_spec(
 	    ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->TPC = tpc;
 
             break;
+	    */
           }
 
           // Toggle NDI for next time
@@ -1560,6 +1556,8 @@ fill_DLSCH_dci(
         case 1:
 
         case 2:
+
+        case 7:
           LOG_D(MAC,"[eNB %d] CC_id %d Adding UE %d spec DCI for %d PRBS \n",module_idP, CC_id, UE_id, nb_rb);
 
           if (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.frame_type == TDD) {
@@ -1744,9 +1742,9 @@ fill_DLSCH_dci(
 
           break;
 
+	  /*
         case 4:
 
-          //if (nb_rb>10) {
           // DCI format 2_2A
           ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
           ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rah = 0;
@@ -1758,17 +1756,6 @@ fill_DLSCH_dci(
                           sizeof_DCI2_5MHz_2A_TDD_t,
                           format2,
                           0);
-          /*}
-            else {
-            ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
-            add_ue_spec_dci(DCI_pdu,
-            DLSCH_dci,
-            rnti,
-            sizeof(DCI2_5MHz_2A_L10PRB_TDD_t),
-            2,//aggregation,
-            sizeof_DCI2_5MHz_2A_L10PRB_TDD_t,
-            format2_2A_L10PRB);
-            }*/
           break;
 
         case 5:
@@ -1798,6 +1785,7 @@ fill_DLSCH_dci(
                           format1E_2A_M10PRB,
                           0);
           break;
+	  */
 
         }
       }
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index b4290e8b9de4c61219a8580f9b67f7a9d881c5ae..5f9a8e0e2a735284cf8b0616ef4f512429a71405 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -99,7 +99,7 @@ int errno;
 # endif
 #endif
 
-//#define XER_PRINT
+#define XER_PRINT
 
 extern Enb_properties_array_t enb_properties;
 typedef struct xer_sprint_string_s {
diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c
index 1b22ae5d0bd5e6db7fc4ee8245fead9ea9c69bde..38d7121860b5c06c7bb8357623c1e8d769b4ea4e 100644
--- a/openair2/RRC/LITE/rrc_UE.c
+++ b/openair2/RRC/LITE/rrc_UE.c
@@ -98,7 +98,7 @@ extern UE_MAC_INST *UE_mac_inst;
 extern void *bigphys_malloc(int);
 #endif
 
-//#define XER_PRINT
+#define XER_PRINT
 
 extern int8_t dB_fixed2(uint32_t x,uint32_t y);
 
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 08d50da39cc92964d1ae44a8db1551924dce87d3..d279764528de3cee992bad917a43bb3b1fdd9bb0 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -3745,7 +3745,7 @@ rrc_eNB_generate_RRCConnectionSetup(
                           ue_context_pP,
                           CC_id,
                           (uint8_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.Payload,
-			  (fp->nb_antennas_tx_eNB==2)?2:1, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
+			  (fp->nb_antenna_ports_eNB==2)?2:1, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
                           rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
                           fp,
                           SRB_configList,
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c
index 86a7fbea3d2c1fa1cb498388602e52f179a7ef51..34fc8e97b8a8ede096c68451f891725ff7c91cd3 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.c
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.c
@@ -288,6 +288,8 @@ const char* eurecomFunctionsNames[] = {
   "phy_eNB_dlsch_encoding",
   "phy_eNB_dlsch_encoding_w",
   "phy_eNB_dlsch_scrambling",
+  "phy_eNB_beam_precoding",
+  "phy_eNB_ofdm_mod_l",
 
   /* MAC  signals  */
   "macxface_macphy_init",
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 19f5e8aab1f0bec4d736032c9bf4cae7d0693b3c..0d1c507b749b5b5583c5f40e3957571f843327e8 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -262,6 +262,8 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING,
   VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W,
   VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,
 
   /* MAC signals  */
   VCD_SIGNAL_DUMPER_FUNCTIONS_MACPHY_INIT,
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index a6c8e434839746360c5d40ab37b641e40c86d555..a366b54023bd86ab8bbe882e21ab9eb274e457ad 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -44,8 +44,9 @@
 #define BBU_LOCAL_RADIO_HEAD  0
 #define BBU_REMOTE_RADIO_HEAD 1
 
+#ifndef MAX_CARDS
 #define MAX_CARDS 8
-
+#endif
 
 typedef int64_t openair0_timestamp;
 typedef volatile int64_t openair0_vtimestamp;
diff --git a/targets/ARCH/EXMIMO/DEFS/openair_device.h b/targets/ARCH/EXMIMO/DEFS/openair_device.h
index 4dbd5ec171408d6d6ced690754a6da3cc9f49b41..b22cf1879b6736c1452cd23aa14c19846e95ed84 100644
--- a/targets/ARCH/EXMIMO/DEFS/openair_device.h
+++ b/targets/ARCH/EXMIMO/DEFS/openair_device.h
@@ -24,9 +24,8 @@
 
 
 // Maximum number of concurrently supported cards
-//
-#define MAX_CARDS   8
-#define INIT_ZEROS {0, 0, 0, 0, 0, 0, 0, 0};
+#define MAX_CARDS  16 
+#define INIT_ZEROS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 
 /** PCIe subsystem configuration Space
diff --git a/targets/ARCH/EXMIMO/DRIVER/eurecom/fileops.c b/targets/ARCH/EXMIMO/DRIVER/eurecom/fileops.c
index 7efdbd5ae83271cb3c67258109d974ce9d3116ea..5002cccc9836730bd89e03e0387a03f716b01b4e 100644
--- a/targets/ARCH/EXMIMO/DRIVER/eurecom/fileops.c
+++ b/targets/ARCH/EXMIMO/DRIVER/eurecom/fileops.c
@@ -271,14 +271,18 @@ int openair_device_ioctl(struct inode *inode,struct file *filp, unsigned int cmd
     printk("[openair][IOCTL] : openair_DUMP_CONFIG(%d):  exmimo_pci_kvirt[%d].exmimo_config_ptr = %p (phys %08x)\n",
            (int)arg, (int)arg, exmimo_pci_kvirt[(int)arg].exmimo_config_ptr, p_exmimo_pci_phys[(int)arg]->exmimo_config_ptr);
 
-    /*printk("EXMIMO_CONFIG: freq0 %d Hz, freq1 %d Hz, freqtx0 %d Hz, freqtx1 %d Hz, \nRX gain0 %d dB, RX Gain1 %d dB\n",
+    printk("[openair][IOCTL]: EXMIMO_CONFIG: freq0 %u Hz, freq1 %u Hz, freqtx0 %u Hz, freqtx1 %u Hz, \nRX gain0 %d dB, RX Gain1 %d dB, autocal (%d,%d,%d,%d)\n",
                 exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rf_freq_rx[0],
                 exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rf_freq_rx[1],
                 exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rf_freq_tx[0],
                 exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rf_freq_tx[1],
                 exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rx_gain[0][0],
-                exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rx_gain[1][0]);
-    */
+                exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.rx_gain[1][0],
+                exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.do_autocal[0],
+		exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.do_autocal[1],
+                exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.do_autocal[2],
+                exmimo_pci_kvirt[(int)arg].exmimo_config_ptr->rf.do_autocal[3]);
+    
 
     exmimo_send_pccmd((int)arg, EXMIMO_CONFIG);
 
diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
index 75aa4d26227b3294a285f1d33605f5029c8c138e..16754a84fb3ff37d203eb3fbae12834a08ce0709 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
+++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
@@ -63,7 +63,7 @@
 
 exmimo_pci_interface_bot_virtual_t openair0_exmimo_pci[MAX_CARDS]; // contains userspace pointers for each card
 
-char *bigshm_top[MAX_CARDS] = INIT_ZEROS;
+char *bigshm_top[MAX_CARDS];
 
 int openair0_fd;
 int openair0_num_antennas[MAX_CARDS];
@@ -126,7 +126,8 @@ int openair0_open(void)
 
   //printf("bigshm_top_kvirtptr (MAX_CARDS %d): %p  %p  %p  %p\n", MAX_CARDS,bigshm_top_kvirtptr[0], bigshm_top_kvirtptr[1], bigshm_top_kvirtptr[2], bigshm_top_kvirtptr[3]);
 
-
+  for( card=0; card < MAX_CARDS; card++)
+    bigshm_top[card] = NULL;
 
   for( card=0; card < openair0_num_detected_cards; card++) {
     bigshm_top[card] = (char *)mmap( NULL,
@@ -530,6 +531,7 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
     return(0);
   }
 
+  ret = pthread_mutex_lock(&exm->watchdog_mutex);
 
   switch (ret) {
   case EINVAL:
@@ -558,8 +560,6 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
     break;
   }
 
-  ret = pthread_mutex_lock(&exm->watchdog_mutex);
-
   ts = exm->ts;
   if (exm->wait_first_read==1) {
     exm->wait_first_read=0;
@@ -731,15 +731,17 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
     printf ("Detected %d number of cards, %d number of antennas.\n", openair0_num_detected_cards, openair0_num_antennas[0]);
   }
 
-  //  p_exmimo_config = openair0_exmimo_pci[0].exmimo_config_ptr;
-  p_exmimo_id     = openair0_exmimo_pci[0].exmimo_id_ptr;
+  for (card=0; card<openair0_num_detected_cards; card++) {
+    //  p_exmimo_config = openair0_exmimo_pci[0].exmimo_config_ptr;
+    p_exmimo_id     = openair0_exmimo_pci[card].exmimo_id_ptr;
 
-  printf("Card %d: ExpressMIMO %d, HW Rev %d, SW Rev 0x%d\n", 0, p_exmimo_id->board_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev);
+    printf("Card %d: ExpressMIMO %d, HW Rev %d, SW Rev 0x%d\n", card, p_exmimo_id->board_exmimoversion, p_exmimo_id->board_hwrev, p_exmimo_id->board_swrev);
 
-  // check if the software matches firmware
-  if (p_exmimo_id->board_swrev!=BOARD_SWREV_CNTL2) {
-    printf("Software revision %d and firmware revision %d do not match. Please update either the firmware or the software!\n",BOARD_SWREV_CNTL2,p_exmimo_id->board_swrev);
-    return(-1);
+    // check if the software matches firmware
+    if (p_exmimo_id->board_swrev!=BOARD_SWREV_CNTL2) {
+      printf("Software revision %d and firmware revision %d do not match. Please update either the firmware or the software!\n",BOARD_SWREV_CNTL2,p_exmimo_id->board_swrev);
+      return(-1);
+    }
   }
 
   device->type             = EXMIMO_DEV; 
@@ -850,6 +852,11 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
 #endif
 
     for (ant=0; ant<4; ant++) {
+      p_exmimo_config->rf.rf_freq_rx[ant] = 0;
+      p_exmimo_config->rf.rf_freq_tx[ant] = 0;
+      p_exmimo_config->rf.rf_mode[ant] = 0;
+      p_exmimo_config->rf.rx_gain[ant][0] = 0;
+      p_exmimo_config->rf.tx_gain[ant][0] = 0;
 
       openair0_cfg[card].rxbase[ant] = (int32_t*)openair0_exmimo_pci[card].adc_head[ant];
       openair0_cfg[card].txbase[ant] = (int32_t*)openair0_exmimo_pci[card].dac_head[ant];
@@ -858,7 +865,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
 	ACTIVE_RF += (1<<ant)<<5;
         p_exmimo_config->rf.rf_mode[ant] = RF_MODE_BASE;
         p_exmimo_config->rf.do_autocal[ant] = 1;//openair0_cfg[card].autocal[ant];
-	printf("card %d, antenna %d, autocal %d\n",card,ant,openair0_cfg[card].autocal[ant]);
+	printf("card %d, antenna %d, autocal %d\n",card,ant,p_exmimo_config->rf.do_autocal[ant]);
       }
 
       if (openair0_cfg[card].tx_freq[ant]>0) {
diff --git a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_get_frame.cc b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_get_frame.cc
index 6973fb2980330985987377ade5773ed27cdedcd8..b8ed0e92e5dc48619bffbdfddd053164798acad9 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_get_frame.cc
+++ b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_get_frame.cc
@@ -171,7 +171,7 @@ DEFUN_DLD (oarf_get_frame, args, nargout,"Get frame")
     printf("Info : Only resampling_factor of channel 0 is taken into account for copying received frame for all the other chains\n");
 
     
-    ComplexMatrix dx (FRAME_LENGTH_COMPLEX_SAMPLES*4, numant*openair0_num_detected_cards);
+    ComplexMatrix dx (FRAME_LENGTH_COMPLEX_SAMPLES*4, MAX_ANTENNAS*openair0_num_detected_cards);
     /*
     // set the tx buffer to 0x00010001 to put switch in rx mode
     for (aa=0; aa<numant; aa++) 
@@ -185,14 +185,14 @@ DEFUN_DLD (oarf_get_frame, args, nargout,"Get frame")
   
     for (j=0; j<openair0_num_detected_cards;j++)
     {
-      for (i=0; i<numant; i++)
+      for (i=0; i<MAX_ANTENNAS; i++)
       {
           //if ( numant == openair0_num_antennas[j] )
               rx_sig[i+(j*MAX_ANTENNAS)] = (short*) openair0_exmimo_pci[ j ].adc_head[ i ];
           //else
           //    rx_sig[i+(j*MAX_ANTENNAS)] = (short*) openair0_exmimo_pci[ i / (int)openair0_num_antennas[0] ].adc_head[i % openair0_num_antennas[0]];
             
-         // printf("Card %i adc_head[%i] = %p \n",j, i, rx_sig[i+(j*MAX_ANTENNAS)]);
+          //  printf("Card %i adc_head[%i] = %p \n",j, i, rx_sig[i+(j*MAX_ANTENNAS)]);
       }
     }
 
@@ -201,8 +201,8 @@ DEFUN_DLD (oarf_get_frame, args, nargout,"Get frame")
         openair0_get_frame(card);
 
   for (j=0; j<openair0_num_detected_cards;j++)
-    for (i=0; i<frame_length_samples[j]; i++)
-        for (aa=0; aa<numant; aa++)
+    for (i=0; i<frame_length_samples[j]; i++) 
+        for (aa=0; aa<MAX_ANTENNAS; aa++) 
             dx(i, aa+j*MAX_ANTENNAS) = Complex( rx_sig[aa+j*MAX_ANTENNAS][i*2], rx_sig[aa+j*MAX_ANTENNAS][i*2+1] );
     
     openair0_close();
diff --git a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
index 97fad27531e5bf5dcf91ade4beac5b909f08f9fd..77da351118ac44642a6fa2407e9d85de87b23453 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
+++ b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
@@ -38,14 +38,14 @@ rffe_band = B19G_TDD*[1 1 1 1];
 
 oarf_config_exmimo(card, freq_rx,freq_tx,tdd_config,syncmode,rxgain,txgain,eNB_flag,rf_mode,rf_rxdc,rf_local,rf_vcocal,rffe_rxg_low,rffe_rxg_final,rffe_band,autocal,resampling_factor);
 %oarf_config_exmimo(1, freq_rx,freq_tx,tdd_config,syncmode,rxgain,txgain,eNB_flag,rf_mode,rf_rxdc,rf_local,rf_vcocal,rffe_rxg_low,rffe_rxg_final,rffe_band,autocal,resampling_factor);
-amp = pow2(14)-1;
+amp = pow2(10)-1;
 n_bit = 16;
 
 length = 307200/pow2(resampling_factor(1));
 
 s = zeros(length,4);
 
-select = 1;
+select = 7;
 
 switch(select)
 
@@ -73,7 +73,8 @@ case 3
 case 4
   pss0_f0=[0,0,0,0,0,0,0,0,0,0,32767,0,-26120,-19785,11971,-30502,-24020,-22288,32117,6492,31311,9658,-16384,-28378,25100,-21063,-7292,-31946,20429,25618,14948,29158,11971,-30502,31311,9658,25100,-21063,-16384,28377,-24020,22287,32117,6492,-7292,31945,20429,25618,-26120,-19785,-16384,-28378,-16384,28377,-26120,-19785,-32402,4883,31311,-9659,32117,6492,-7292,-31946,32767,-1,25100,-21063,-24020,22287,-32402,4883,-32402,4883,-24020,22287,25100,-21063,32767,-1,-7292,-31946,32117,6492,31311,-9659,-32402,4883,-26120,-19785,-16384,28377,-16384,-28378,-26120,-19785,20429,25618,-7292,31945,32117,6492,-24020,22287,-16384,28377,25100,-21063,31311,9658,11971,-30502,14948,29158,20429,25618,-7292,-31946,25100,-21063,-16384,-28378,31311,9658,32117,6492,-24020,-22288,11971,-30502,-26120,-19785,32767,0,0,0,0,0,0,0,0,0,0,0];
 
-  pss0_f = pss0_f0(1:2:length(pss0_f0)) + sqrt(-1)*pss0_f0(2:2:length(pss0_f0));
+  %pss0_f = pss0_f0(1:2:length(pss0_f0)) + sqrt(-1)*pss0_f0(2:2:length(pss0_f0));
+  pss0_f = pss0_f0(1:2:size(pss0_f0,2)) + sqrt(-1)*pss0_f0(2:2:size(pss0_f0,2));
   
   pss0_f = [0 pss0_f(37:72) zeros(1,512-73) pss0_f(1:36)];
   pss0_t = ifft(pss0_f);
@@ -84,10 +85,15 @@ case 4
   pss0_t_fp_re = floor(real(8192*pss0_t/pss0_max)); 
   pss0_t_fp_im = floor(imag(8192*pss0_t/pss0_max)); 
   
+  %keyboard;
   s(38400+(1:length(pss0_t_fp_re)),1) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
   s(38400+(1:length(pss0_t_fp_re)),2) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
   s(38400+(1:length(pss0_t_fp_re)),3) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
   s(38400+(1:length(pss0_t_fp_re)),4) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
+  %s(38400+(1:size(pss0_t_fp_re,2)),1) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
+  %s(38400+(1:size(pss0_t_fp_re,2)),2) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
+  %s(38400+(1:size(pss0_t_fp_re,2)),3) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
+  %s(38400+(1:size(pss0_t_fp_re,2)),4) = 2*floor(pss0_t_fp_re) + 2*sqrt(-1)*floor(pss0_t_fp_im);
 
 case 5
   x=1:length;
@@ -108,7 +114,9 @@ case 6
   
   s(:,1) = OFDM_TX_FRAME(num_carriers,num_zeros,prefix_length,num_symbols_frame,preamble_length);
   s(:,1) = floor(amp*(s(:,1)./max([real(s(:,1)); imag(s(:,1))])));
-  
+
+case 7
+  s(:,1) = floor(txs0);
 
 otherwise 
   error('unknown case')
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm7.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm7.exmimo2.conf
new file mode 100644
index 0000000000000000000000000000000000000000..6209fbe150c06020ece001df690ac751edeb3bb2
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm7.exmimo2.conf
@@ -0,0 +1,172 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "93";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        frame_type					      = "TDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 0;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 38;
+        downlink_frequency      			      = 2580000000L;
+        uplink_frequency_offset 			      = 0; //-120000000;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 25;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 3;
+        nb_antennas_rx          			      = 3;
+        tx_gain                                            = 10; //25;
+        rx_gain                                            = 10; //20;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -26;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 0;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -85;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -108;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 2;
+        rach_preambleInitialReceivedTargetPower            = -100;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 7;
+      }
+    );
+
+
+    srb1_parameters :
+    {
+      # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+      timer_poll_retransmit    = 80;
+
+      # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+      timer_reordering         = 35;
+
+      # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+      timer_status_prohibit    = 0;
+
+      # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+      poll_pdu                 =  4;
+
+      # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+      poll_byte                =  99999;
+
+      # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+      max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+      # Number of streams to use in input/output
+      SCTP_INSTREAMS  = 2;
+      SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.70";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+      ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+      ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.212/24";
+
+      ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+      ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.212/24";
+      ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="debug";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.exmimo2.conf
new file mode 100644
index 0000000000000000000000000000000000000000..bf7861f66d305b51b1f5a3eafe902ef4e9a8ced7
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.exmimo2.conf
@@ -0,0 +1,147 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    # real_time choice in {hard, rt-preempt, no}
+    real_time       =  "no";
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+    
+    cell_type =  "CELL_MACRO_ENB";
+    
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+    
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+    
+    mobile_country_code =  "208";
+    
+    mobile_network_code =  "94";
+    
+       ////////// Physical parameters:
+  
+    component_carriers = (
+    		       	 {
+  			   frame_type					      = "FDD";	
+                           tdd_config 					      = 3;
+                           tdd_config_s            			      = 0;
+ 			   prefix_type             			      = "NORMAL";
+  			   eutra_band              			      = 4;
+                           downlink_frequency      			      = 2112500000L;
+                           uplink_frequency_offset 			      = -400000000;
+  
+  			   Nid_cell					      = 0;
+                           N_RB_DL                 			      = 25;
+                           Nid_cell_mbsfn          			      = 0;
+                           nb_antennas_tx          			      = 1;
+                           nb_antennas_rx          			      = 1;
+			   nb_antenna_ports				      = 1;
+			   tx_gain					      = 20;
+			   rx_gain			    		      = 20;
+                           prach_root              			      = 22;
+                           prach_config_index      			      = 0;
+                           prach_high_speed        			      = "DISABLE";
+  	                   prach_zero_correlation  			      = 1;
+                           prach_freq_offset       			      = 2;
+			   pucch_delta_shift       			      = 1;
+                           pucch_nRB_CQI           			      = 1;
+                           pucch_nCS_AN            			      = 0;
+                           pucch_n1_AN             			      = 32;
+                           pdsch_referenceSignalPower 			      = -25;
+                           pdsch_p_b                  			      = 0;
+                           pusch_n_SB                 			      = 1; 
+                           pusch_enable64QAM          			      = "DISABLE";
+			   pusch_hoppingMode                                  = "interSubFrame";
+			   pusch_hoppingOffset                                = 1;
+     	                   pusch_groupHoppingEnabled  			      = "ENABLE";
+	                   pusch_groupAssignment      			      = 0;
+	                   pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+	                   pusch_nDMRS1                                       = 0;
+	                   phich_duration                                     = "NORMAL";
+	                   phich_resource                                     = "ONESIXTH";
+	                   srs_enable                                         = "DISABLE";
+	               /*  srs_BandwidthConfig                                =;
+	                   srs_SubframeConfig                                 =;
+	                   srs_ackNackST                                      =;
+	                   srs_MaxUpPts                                       =;*/  
+
+	                   pusch_p0_Nominal                                   = -85; 
+	                   pusch_alpha                                        = "AL1";
+	                   pucch_p0_Nominal                                   = -96;
+	                   msg3_delta_Preamble                                = 6;
+	                   pucch_deltaF_Format1                               = "deltaF2";
+	                   pucch_deltaF_Format1b                              = "deltaF3";
+	                   pucch_deltaF_Format2                               = "deltaF0";
+	                   pucch_deltaF_Format2a                              = "deltaF0";
+  	                   pucch_deltaF_Format2b		    	      = "deltaF0";
+	
+                           rach_numberOfRA_Preambles                          = 64;
+                           rach_preamblesGroupAConfig                         = "DISABLE";
+/*
+                           rach_sizeOfRA_PreamblesGroupA                      = ;
+                           rach_messageSizeGroupA                             = ;
+                           rach_messagePowerOffsetGroupB                      = ; 
+*/
+                           rach_powerRampingStep                              = 2;
+	                   rach_preambleInitialReceivedTargetPower            = -100;
+                           rach_preambleTransMax                              = 10;
+	                   rach_raResponseWindowSize                          = 10;
+	                   rach_macContentionResolutionTimer                  = 48;
+	                   rach_maxHARQ_Msg3Tx                                = 4;
+
+			   pcch_default_PagingCycle                           = 128;
+			   pcch_nB                                            = "oneT";
+			   bcch_modificationPeriodCoeff			      = 2;
+			   ue_TimersAndConstants_t300			      = 1000;
+			   ue_TimersAndConstants_t301			      = 1000;
+			   ue_TimersAndConstants_t310			      = 1000;
+			   ue_TimersAndConstants_t311			      = 20000; //10000;
+			   ue_TimersAndConstants_n310			      = 20;
+			   ue_TimersAndConstants_n311			      = 1;
+
+			   ue_TransmissionMode 				      = 1;
+
+			 }
+			 );
+    
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.70";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES : 
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.212/24";
+
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.212/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+    
+    log_config : 
+    {
+	global_log_level                      ="info";
+    	global_log_verbosity                  ="high";
+	hw_log_level                          ="info"; 
+    	hw_log_verbosity                      ="high";
+	phy_log_level                         ="info"; 
+    	phy_log_verbosity                     ="high";
+	mac_log_level                         ="debug"; 
+    	mac_log_verbosity                     ="high";
+	rlc_log_level                         ="info"; 
+    	rlc_log_verbosity                     ="high";
+	pdcp_log_level                        ="info"; 
+    	pdcp_log_verbosity                    ="high";
+	rrc_log_level                         ="info"; 
+    	rrc_log_verbosity                     ="high";
+   };	
+   
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf
index c338656679ef925ed7d92f0578bbe55c3fd4e885..c190020e082e2b7b9de4ed8d2adcf269f0b75a12 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf
@@ -51,7 +51,7 @@ eNBs =
                            pucch_nCS_AN            			      = 0;
                            pucch_n1_AN             			      = 32;
                            pdsch_referenceSignalPower 			      = -24;
-                           pdsch_p_b                  			      = 0;
+                           pdsch_p_b                  			      = 1;
                            pusch_n_SB                 			      = 1; 
                            pusch_enable64QAM          			      = "DISABLE";
 			   pusch_hoppingMode                                  = "interSubFrame";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
index a2234cf5156178f1181fc3e819781950a54a7be3..84e947eecc651f6aae2a88f538e5c16281f0c279 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.conf
@@ -160,13 +160,13 @@ eNBs =
       global_log_verbosity                  ="medium";
       hw_log_level                          ="info";
       hw_log_verbosity                      ="medium";
-      phy_log_level                         ="warn";
+      phy_log_level                         ="debug";
       phy_log_verbosity                     ="medium";
-      mac_log_level                         ="warn";
+      mac_log_level                         ="debug";
       mac_log_verbosity                     ="medium";
-      rlc_log_level                         ="warn";
+      rlc_log_level                         ="info";
       rlc_log_verbosity                     ="medium";
-      pdcp_log_level                        ="warn";
+      pdcp_log_level                        ="info";
       pdcp_log_verbosity                    ="medium";
       rrc_log_level                         ="info";
       rrc_log_verbosity                     ="medium";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf
index 01cd014afc143fb80b8e88636ee341bee40beffa..2942832d940aea1908568321ef1af3cafb122433 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf
@@ -37,8 +37,8 @@ eNBs =
         N_RB_DL                 			      = 25;
         Nid_cell_mbsfn          			      = 0;
         nb_antenna_ports          			      = 1;
-        nb_antennas_tx          			      = 1;
-        nb_antennas_rx          			      = 1;
+        nb_antennas_tx          			      = 2;
+        nb_antennas_rx          			      = 2;
         tx_gain                                            = 90;
         rx_gain                                            = 125;
         prach_root              			      = 0;
@@ -68,9 +68,9 @@ eNBs =
         srs_ackNackST                                      =;
         srs_MaxUpPts                                       =;*/
 
-        pusch_p0_Nominal                                   = -96;
+        pusch_p0_Nominal                                   = -90;
         pusch_alpha                                        = "AL1";
-        pucch_p0_Nominal                                   = -103;
+        pucch_p0_Nominal                                   = -96;
         msg3_delta_Preamble                                = 6;
         pucch_deltaF_Format1                               = "deltaF2";
         pucch_deltaF_Format1b                              = "deltaF3";
@@ -137,7 +137,7 @@ eNBs =
 
     ////////// MME parameters:
 
-    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+    mme_ip_address      = ( { ipv4       = "192.168.12.70";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -147,10 +147,10 @@ eNBs =
     NETWORK_INTERFACES :
     {
 
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
-        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.4/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.147/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.147/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm7.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm7.exmimo2.conf
new file mode 100644
index 0000000000000000000000000000000000000000..52a8d8ee502c1d878d844b98b2c226300ed25354
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm7.exmimo2.conf
@@ -0,0 +1,182 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "93";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+        {
+        node_function                                         = "eNodeB_3GPP";
+        node_timing                                           = "synch_to_ext_device";
+        node_synch_ref                                        = 0;
+        frame_type					      = "FDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 0;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 7;
+        downlink_frequency      			      = 2680000000L;
+        uplink_frequency_offset 			      = -120000000;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 25;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 1;
+        nb_antennas_rx          			      = 1;
+        tx_gain                                            = 25;
+        rx_gain                                            = 20;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -26;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 0;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -80; /*-85;*/
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -108; /* -108 */
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 2;
+        rach_preambleInitialReceivedTargetPower            = -100;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 7;
+        }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.171";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth2";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.80/24";
+
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth2";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.80/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="debug";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="debug";
+      mac_log_verbosity                     ="medium";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+      gtpu_log_level                         ="error";
+      gtpu_log_verbosity                     ="medium";
+      udp_log_level                         ="error";
+      udp_log_verbosity                     ="medium";
+      osa_log_level                         ="warn";
+      osa_log_verbosity                     ="low";
+   };
+
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf
index 7941441d1da3d46964b4306643a07929770f062c..540edcd5b91c5e5f25c3bdf5e6b13a7a1f4fcfa6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf
@@ -7,125 +7,126 @@ eNBs =
  {
     ////////// Identification parameters:
     eNB_ID    =  0xe00;
-    
+
     cell_type =  "CELL_MACRO_ENB";
-    
+
     eNB_name  =  "eNB_Eurecom_LTEBox";
-    
+
     // Tracking area code, 0x0000 and 0xfffe are reserved values
     tracking_area_code  =  "1";
-    
+
     mobile_country_code =  "208";
-    
+
     mobile_network_code =  "94";
-    
+
        ////////// Physical parameters:
-  
+
     component_carriers = (
-    		       	 {
-  			   frame_type					      = "FDD";	
-                           tdd_config 					      = 3;
-                           tdd_config_s            			      = 0;
- 			   prefix_type             			      = "NORMAL";
-  			   eutra_band              			      = 7;
-                           downlink_frequency      			      = 2680000000L;
-                           uplink_frequency_offset 			      = -120000000;
-  			   Nid_cell					      = 0;
-                           N_RB_DL                 			      = 25;
-                           Nid_cell_mbsfn          			      = 0;
-			   nb_antenna_ports				      = 2;
-                           nb_antennas_tx          			      = 2;
-                           nb_antennas_rx          			      = 2; 
-			   tx_gain                                            = 90;
-			   rx_gain                                            = 125;
-                           prach_root              			      = 0;
-                           prach_config_index      			      = 0;
-                           prach_high_speed        			      = "DISABLE";
-  	                   prach_zero_correlation  			      = 1;
-                           prach_freq_offset       			      = 2;
-			   pucch_delta_shift       			      = 1;
-                           pucch_nRB_CQI           			      = 1;
-                           pucch_nCS_AN            			      = 0;
-                           pucch_n1_AN             			      = 32;
-                           pdsch_referenceSignalPower 			      = -26;
-                           pdsch_p_b                  			      = 0;
-                           pusch_n_SB                 			      = 1; 
-                           pusch_enable64QAM          			      = "DISABLE";
-			   pusch_hoppingMode                                  = "interSubFrame";
-			   pusch_hoppingOffset                                = 0;
-     	                   pusch_groupHoppingEnabled  			      = "ENABLE";
-	                   pusch_groupAssignment      			      = 0;
-	                   pusch_sequenceHoppingEnabled		   	      = "DISABLE";
-	                   pusch_nDMRS1                                       = 1;
-	                   phich_duration                                     = "NORMAL";
-	                   phich_resource                                     = "ONESIXTH";
-	                   srs_enable                                         = "DISABLE";
-	               /*  srs_BandwidthConfig                                =;
-	                   srs_SubframeConfig                                 =;
-	                   srs_ackNackST                                      =;
-	                   srs_MaxUpPts                                       =;*/  
-
-	                   pusch_p0_Nominal                                   = -90; 
-	                   pusch_alpha                                        = "AL1";
-	                   pucch_p0_Nominal                                   = -96;
-	                   msg3_delta_Preamble                                = 6;
-	                   pucch_deltaF_Format1                               = "deltaF2";
-	                   pucch_deltaF_Format1b                              = "deltaF3";
-	                   pucch_deltaF_Format2                               = "deltaF0";
-	                   pucch_deltaF_Format2a                              = "deltaF0";
-  	                   pucch_deltaF_Format2b		    	      = "deltaF0";
-	
-                           rach_numberOfRA_Preambles                          = 64;
-                           rach_preamblesGroupAConfig                         = "DISABLE";
-/*
-                           rach_sizeOfRA_PreamblesGroupA                      = ;
-                           rach_messageSizeGroupA                             = ;
-                           rach_messagePowerOffsetGroupB                      = ; 
-*/
-                           rach_powerRampingStep                              = 4;
-	                   rach_preambleInitialReceivedTargetPower            = -108;
-                           rach_preambleTransMax                              = 10;
-	                   rach_raResponseWindowSize                          = 10;
-	                   rach_macContentionResolutionTimer                  = 48;
-	                   rach_maxHARQ_Msg3Tx                                = 4;
-
-			   pcch_default_PagingCycle                           = 128;
-			   pcch_nB                                            = "oneT";
-			   bcch_modificationPeriodCoeff			      = 2;
-			   ue_TimersAndConstants_t300			      = 1000;
-			   ue_TimersAndConstants_t301			      = 1000;
-			   ue_TimersAndConstants_t310			      = 1000;
-			   ue_TimersAndConstants_t311			      = 10000;
-			   ue_TimersAndConstants_n310			      = 20;
-			   ue_TimersAndConstants_n311			      = 1;
-
-			   ue_TransmissionMode	   			      = 2;
-
-			 }
-			 );
+      {
+        node_function                                         = "eNodeB_3GPP";
+	node_timing                                           = "synch_to_ext_device";
+	node_synch_ref                                        = 0;
+        frame_type					      = "FDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 0;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 7;
+        downlink_frequency      			      = 2660000000L;
+        uplink_frequency_offset 			      = -120000000;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 25;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 2;
+        nb_antennas_tx          			      = 2;
+        nb_antennas_rx          			      = 2;
+        tx_gain                                            = 90;
+        rx_gain                                            = 125;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -24;
+        pdsch_p_b                  			      = 1;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 1;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -90;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -96;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 4;
+        rach_preambleInitialReceivedTargetPower            = -104;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
 
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 2;
+      }
+    );
 
     srb1_parameters :
     {
-        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] 
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
         timer_poll_retransmit    = 80;
-        
+
         # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
         timer_reordering         = 35;
-        
+
         # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
         timer_status_prohibit    = 0;
-        
+
         # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
         poll_pdu                 =  4;
-        
+
         # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
         poll_byte                =  99999;
-        
+
         # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
         max_retx_threshold       =  4;
     }
-    
+
     # ------- SCTP definitions
     SCTP :
     {
@@ -133,42 +134,41 @@ eNBs =
         SCTP_INSTREAMS  = 2;
         SCTP_OUTSTREAMS = 2;
     };
-    
+
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.168.12.171";
+    mme_ip_address      = ( { ipv4       = "192.168.12.70";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
                             }
                           );
 
-    NETWORK_INTERFACES : 
+    NETWORK_INTERFACES :
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.150/24";
 
-        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.150/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.147/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.147/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
-    
-    log_config : 
+
+    log_config :
     {
-	global_log_level                      ="info"; 
-    	global_log_verbosity                  ="medium";
-	hw_log_level                          ="info"; 
-    	hw_log_verbosity                      ="medium";
-	phy_log_level                         ="info"; 
-    	phy_log_verbosity                     ="medium";
-	mac_log_level                         ="info"; 
-    	mac_log_verbosity                     ="high";
-	rlc_log_level                         ="info"; 
-    	rlc_log_verbosity                     ="medium";
-	pdcp_log_level                        ="info"; 
-    	pdcp_log_verbosity                    ="medium";
-	rrc_log_level                         ="info"; 
-    	rrc_log_verbosity                     ="medium";
-   };	
-   
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="debug";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
   }
 );
diff --git a/targets/PROJECTS/TDDREC/s_init_params.m b/targets/PROJECTS/TDDREC/s_init_params.m
index 9683ed2d1747703901fba28e828c6f1b5a6cd793..be51524755af39c66fe26aedff74c2e3de3943cb 100644
--- a/targets/PROJECTS/TDDREC/s_init_params.m
+++ b/targets/PROJECTS/TDDREC/s_init_params.m
@@ -1,6 +1,7 @@
 clear all
 close all
 addpath([getenv('OPENAIR_TARGETS') '/ARCH/EXMIMO/USERSPACE/OCTAVE']);
+addpath([getenv('OPENAIR_DIR') '/cmake_targets/lte_build_oai/build']);
 
 %% -------- ExpressMIMO2 configuration --------
 limeparms;
diff --git a/targets/RT/USER/Makefile b/targets/RT/USER/Makefile
index 621f30c5f41268f8009ee53646d652dcd3628719..8c413d4e2e254048621c62d66f5d05634dcca154 100644
--- a/targets/RT/USER/Makefile
+++ b/targets/RT/USER/Makefile
@@ -193,7 +193,7 @@ CFLAGS += -DHARD_RT
 endif
 
 ifeq ($(EMOS),1)
-CFLAGS += -D_FILE_OFFSET_BITS=64 -DEMOS #-DEMOS_CHANNEL
+CFLAGS += -D_FILE_OFFSET_BITS=64 #-DEMOS -DEMOS_CHANNEL
 LDFLAGS += -lgps
 endif
 
@@ -320,6 +320,7 @@ drivers:
 #	cd $(OPENAIR2_DIR)/NAS/DRIVER/MESH/RB_TOOL && make clean && make
 	cd $(OPENAIR_TARGETS)/ARCH/EXMIMO/DRIVER/eurecom && make clean && make 
 	cd $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT && make clean && make 
+	cp $(OPENAIR_TARGETS)/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw $(OPENAIR_TARGETS)/bin/.
 
 run: condtest
 	rtai-load condtest --verbose
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index bdc281c8ea6cd5253a24676df8974220b785d60e..eebfb2da093e4e4d3c6b889a2aea3abaf849e4bc 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -128,6 +128,8 @@ extern pthread_cond_t sync_cond;
 extern pthread_mutex_t sync_mutex;
 extern int sync_var;
 
+extern transmission_mode;
+
 //pthread_t                       main_eNB_thread;
 
 time_stats_t softmodem_stats_mt; // main thread
@@ -273,27 +275,43 @@ static inline void wait_sync(char *thread_name) {
 
 }
 
-void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
-     
-  unsigned int aa,slot_offset, slot_offset_F;
-  int dummy_tx_b[7680*4] __attribute__((aligned(32)));
-  int i,j, tx_offset;
-  int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)*
-                   ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7);
-  int len,len2;
-  int16_t *txdata;
-//  int CC_id = phy_vars_eNB->proc.CC_id;
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
+void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
+{
 
-  slot_offset_F = (subframe<<1)*slot_sizeF;
+  unsigned int aa,slot_offset;
+  //int dummy_tx_b[7680*4] __attribute__((aligned(32)));
+  int i, tx_offset;
+  //int slot_sizeF = (phy_vars_eNB->frame_parms.ofdm_symbol_size)* ((phy_vars_eNB->frame_parms.Ncp==1) ? 6 : 7);
+  int len;
+  //int slot_offset_F = (subframe<<1)*slot_sizeF;
 
   slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti;
 
+  
   if ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_DL)||
       ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) {
     //    LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot);
 
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,1);
+
+    do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
+                  0,
+                  subframe<<1,
+                  &phy_vars_eNB->frame_parms);
+ 
+    // if S-subframe generate first slot only 
+    if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) {
+      do_OFDM_mod_symbol(&phy_vars_eNB->common_vars,
+                    0,
+                    1+(subframe<<1),
+                    &phy_vars_eNB->frame_parms);
+    }
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0);
+    
+
+/*
     for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
       if (phy_vars_eNB->frame_parms.Ncp == EXTENDED) {
         PHY_ofdm_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F],
@@ -315,13 +333,15 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
                           7,
                           &(phy_vars_eNB->frame_parms));
 	// if S-subframe generate first slot only
-	if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) 
+	if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL)
 	  normal_prefix_mod(&phy_vars_eNB->common_vars.txdataF[0][aa][slot_offset_F+slot_sizeF],
 			    dummy_tx_b+(phy_vars_eNB->frame_parms.samples_per_tti>>1),
 			    7,
 			    &(phy_vars_eNB->frame_parms));
       }
+    } */
 
+    for (aa=0; aa<phy_vars_eNB->frame_parms.nb_antennas_tx; aa++) {
       // if S-subframe generate first slot only
       if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S)
 	len = phy_vars_eNB->frame_parms.samples_per_tti>>1;
@@ -334,55 +354,36 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
 	dummy_tx_b[i+2] = 0xff00;
 	dummy_tx_b[i+3] = 0xff000000;
 	}*/
-      
-      if (slot_offset+time_offset[aa]<0) {
-	txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)+tx_offset];
-        len2 = -(slot_offset+time_offset[aa]);
-	len2 = (len2>len) ? len : len2;
-	for (i=0; i<(len2<<1); i++) {
-	  txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
-	}
-	if (len2<len) {
-	  txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][0];
-	  for (j=0; i<(len<<1); i++,j++) {
-	    txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
-	  }
-	}
-      }  
-      else if ((slot_offset+time_offset[aa]+len)>(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti)) {
-	tx_offset = (int)slot_offset+time_offset[aa];
-	txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset];
-	len2 = -tx_offset+LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
-	for (i=0; i<(len2<<1); i++) {
-	  txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
-	}
-	txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][0];
-	for (j=0; i<(len<<1); i++,j++) {
-	  txdata[j++] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
-	}
-      }
-      else {
-	tx_offset = (int)slot_offset+time_offset[aa];
-	txdata = (int16_t*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset];
+      for (i=0; i<len; i++) {
+        tx_offset = (int)slot_offset+time_offset[aa]+i;
 
-	for (i=0; i<(len<<1); i++) {
-	  txdata[i] = ((int16_t*)dummy_tx_b)[i]<<openair0_cfg[0].iq_txshift;
-	}
-      }
-      
+	
+        if (tx_offset<0)
+          tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
+
+        if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
+          tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
+
+/*	((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift;
+	
+	((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift; */
+
+	((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[0]<<openair0_cfg[0].iq_txshift;
+	
+	((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1] = ((short*)&phy_vars_eNB->common_vars.txdata[0][aa][tx_offset])[1]<<openair0_cfg[0].iq_txshift;
+     }
      // if S-subframe switch to RX in second subframe
-      /*
      if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_S) {
        for (i=0; i<len; i++) {
 	 phy_vars_eNB->common_vars.txdata[0][aa][tx_offset++] = 0x00010001;
        }
      }
-      */
+
      if ((((phy_vars_eNB->frame_parms.tdd_config==0) ||
-	   (phy_vars_eNB->frame_parms.tdd_config==1) ||
-	   (phy_vars_eNB->frame_parms.tdd_config==2) ||
-	   (phy_vars_eNB->frame_parms.tdd_config==6)) && 
-	   (subframe==0)) || (subframe==5)) {
+	  (phy_vars_eNB->frame_parms.tdd_config==1) ||
+	  (phy_vars_eNB->frame_parms.tdd_config==2) ||
+	  (phy_vars_eNB->frame_parms.tdd_config==6)) && 
+	  (subframe==0)) || (subframe==5)) {
        // turn on tx switch N_TA_offset before
        //LOG_D(HW,"subframe %d, time to switch to tx (N_TA_offset %d, slot_offset %d) \n",subframe,phy_vars_eNB->N_TA_offset,slot_offset);
        for (i=0; i<phy_vars_eNB->N_TA_offset; i++) {
@@ -390,17 +391,17 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) {
          if (tx_offset<0)
            tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
 	 
-         if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
-           tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
+	 if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti))
+	   tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->frame_parms.samples_per_tti;
 	 
-         phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000;
+	 phy_vars_eNB->common_vars.txdata[0][aa][tx_offset] = 0x00000000;
        }
      }
     }
   }
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
 }
 
+
 void tx_fh_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, proc->timestamp_tx&0xffffffff );
   send_IF5(eNB, proc->timestamp_tx, proc->subframe_tx, &seqno, IF5_RRH_GW_DL);
@@ -470,15 +471,16 @@ void proc_tx_full(PHY_VARS_eNB *eNB,
   if (eNB->tx_fh) eNB->tx_fh(eNB,proc);
 
   /*
-   if (proc->frame_tx>1000) {
-     write_output("/tmp/txsig0.m","txs0", &eNB->common_vars.txdata[eNB->Mod_id][0][0], eNB->frame_parms.samples_per_tti*10,1,1);
-     write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB->Mod_id][0][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
-     write_output("/tmp/txsig1.m","txs1", &eNB->common_vars.txdata[eNB->Mod_id][1][0], eNB->frame_parms.samples_per_tti*10,1,1);
-     write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB->Mod_id][1][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
-     //if (transmission_mode == 7) write_output("/tmp/txsigF5.m","txsF5", &eNB->common_vars.txdataF[eNB->Mod_id][5][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
-     exit_fun("");
-   }
-   */
+  if (proc->frame_tx>1000) {
+    write_output("/tmp/txsig0.m","txs0", &eNB->common_vars.txdata[eNB->Mod_id][0][0], eNB->frame_parms.samples_per_tti*10,1,1);
+    write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB->Mod_id][0][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
+    write_output("/tmp/txsig1.m","txs1", &eNB->common_vars.txdata[eNB->Mod_id][1][0], eNB->frame_parms.samples_per_tti*10,1,1);
+    write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB->Mod_id][1][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
+    if (transmission_mode == 7) 
+      write_output("/tmp/txsigF5.m","txsF5", &eNB->common_vars.txdataF[eNB->Mod_id][5][0],eNB->frame_parms.symbols_per_tti*eNB->frame_parms.ofdm_symbol_size*10,1,1);
+    exit_fun("");
+  }
+  */
 }
 
 void proc_tx_rru_if4p5(PHY_VARS_eNB *eNB,
@@ -1484,8 +1486,8 @@ void kill_eNB_proc(int inst) {
    antennas are mapped to successive RF chains on the same card. */
 int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg) {
 
-  int i, CC_id;
-  int j;
+  int i,j; 
+  int CC_id,card,ant;
 
   //uint16_t N_TA_offset = 0;
 
@@ -1516,10 +1518,12 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
     // replace RX signal buffers with mmaped HW versions
       
       for (i=0; i<frame_parms->nb_antennas_rx; i++) {
-	printf("Mapping eNB CC_id %d, rx_ant %d\n",CC_id,i);
+	card = i/4;
+	ant = i%4;
+	printf("Mapping eNB CC_id %d, rx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
 	free(phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
-	phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[CC_id].rxbase[i];
-
+	phy_vars_eNB[CC_id]->common_vars.rxdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].rxbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
+	
 	printf("rxdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i]);
 	for (j=0; j<16; j++) {
 	  printf("rxbuffer %d: %x\n",j,phy_vars_eNB[CC_id]->common_vars.rxdata[0][i][j]);
@@ -1528,9 +1532,11 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
       }
       
       for (i=0; i<frame_parms->nb_antennas_tx; i++) {
-	printf("Mapping eNB CC_id %d, tx_ant %d\n",CC_id,i);
+	card = i/4;
+	ant = i%4;
+	printf("Mapping eNB CC_id %d, tx_ant %d, on card %d, chain %d\n",CC_id,i,phy_vars_eNB[CC_id]->rf_map.card+card, phy_vars_eNB[CC_id]->rf_map.chain+ant);
 	free(phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
-	phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[CC_id].txbase[i];//(int32_t*) openair0_exmimo_pci[rf_map[CC_id].card].dac_head[rf_map[CC_id].chain+i];
+	phy_vars_eNB[CC_id]->common_vars.txdata[0][i] = openair0_cfg[phy_vars_eNB[CC_id]->rf_map.card+card].txbase[phy_vars_eNB[CC_id]->rf_map.chain+ant];
 	
 	printf("txdata[%d] @ %p\n",i,phy_vars_eNB[CC_id]->common_vars.txdata[0][i]);
 	
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 5e0acdc80b70627ab45340bb937d4e2ab0914805..012eb44e45518a92d88d91b1fdf64f20082f6d51 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -235,7 +235,7 @@ uint64_t num_missed_slots=0; // counter for the number of missed slots
 
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
-//int transmission_mode=1;
+int transmission_mode=1;
 
 int16_t           glog_level         = LOG_INFO;
 int16_t           glog_verbosity     = LOG_MED;
@@ -1128,13 +1128,13 @@ static void get_options (int argc, char **argv)
         frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
         frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
         frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
-        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
+        frame_parms[CC_id]->nb_antenna_ports_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
         frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
 
 	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id];
 	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[i]->prach_freq_offset[CC_id];
 
-	frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antennas_tx_eNB == 1) ? 1 : 0;
+	frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0;
 	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;
 
         //} // j
@@ -1196,8 +1196,13 @@ static void get_options (int argc, char **argv)
         printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
                enb_properties->properties[i]->downlink_frequency[CC_id],
                enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
+
       } // CC_id
     }// i
+
+    //this is needed for phy-test option
+    transmission_mode = enb_properties->properties[0]->ue_TransmissionMode[0]+1;
+
   } else if (UE_flag == 1) {
     if (conf_config_file_name != NULL) {
       
@@ -1232,7 +1237,7 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
     frame_parms[CC_id]->Ncp_UL              = NORMAL;
     frame_parms[CC_id]->Nid_cell            = 0;
     frame_parms[CC_id]->num_MBSFN_config    = 0;
-    frame_parms[CC_id]->nb_antennas_tx_eNB  = 1;
+    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
     frame_parms[CC_id]->nb_antennas_tx      = 1;
     frame_parms[CC_id]->nb_antennas_rx      = 1;
 
@@ -1366,7 +1371,7 @@ void init_openair0() {
 
 int main( int argc, char **argv )
 {
-  int i,aa;
+  int i,j,k,aa,re;
 #if defined (XFORMS)
   void *status;
 #endif
@@ -1527,7 +1532,7 @@ int main( int argc, char **argv )
     if (UE_flag==1) {
       frame_parms[CC_id]->nb_antennas_tx     = 1;
       frame_parms[CC_id]->nb_antennas_rx     = 1;
-      frame_parms[CC_id]->nb_antennas_tx_eNB = 1; //initial value overwritten by initial sync later
+      frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
     }
 
     init_ul_hopping(frame_parms[CC_id]);
@@ -1620,6 +1625,17 @@ int main( int argc, char **argv )
       PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6;
       PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs;
 
+      // initialization for phy-test
+      for (k=0;k<NUMBER_OF_UE_MAX;k++) {
+	PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode;
+	if (transmission_mode==7) 
+	  lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k);
+      }
+      if ((transmission_mode==1) || (transmission_mode==7)) {
+	  for (j=0; j<frame_parms[CC_id]->nb_antennas_tx; j++) 
+	    for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++) 
+	      PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; 
+      }
       if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0;
       else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1;
 
diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c
index 5a742e9e610cd9d41f61038c23733f7d4687ccaf..7da3c3dcd193cda9fd6914046f742e0911d336b7 100644
--- a/targets/SIMU/USER/init_lte.c
+++ b/targets/SIMU/USER/init_lte.c
@@ -44,7 +44,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
                            uint8_t abstraction_flag)
 {
 
-  int i,j;
+  int i,j,layer,aa,re;
   PHY_VARS_eNB* PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB));
   memset(PHY_vars_eNB,0,sizeof(PHY_VARS_eNB));
   PHY_vars_eNB->Mod_id=eNB_id;
@@ -64,7 +64,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
 
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
     for (j=0; j<2; j++) {
-      PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag);
+      PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag,frame_parms);
 
       if (!PHY_vars_eNB->dlsch[i][j]) {
         LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
@@ -84,7 +84,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
 
     // this is the transmission mode for the signalling channels
     // this will be overwritten with the real transmission mode by the RRC once the UE is connected
-    PHY_vars_eNB->transmission_mode[i] = frame_parms->nb_antennas_tx_eNB==1 ? 1 : 2;
+    PHY_vars_eNB->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2;
 #ifdef LOCALIZATION
     PHY_vars_eNB->ulsch[1+i]->aggregation_period_ms = 5000; // 5000 milliseconds // could be given as an argument (TBD))
     struct timeval ts;
@@ -116,11 +116,11 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
     exit(-1);
   }
 
-  PHY_vars_eNB->dlsch_SI  = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag);
+  PHY_vars_eNB->dlsch_SI  = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
   LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI);
-  PHY_vars_eNB->dlsch_ra  = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag);
+  PHY_vars_eNB->dlsch_ra  = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
   LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra);
-  PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0);
+  PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0, frame_parms);
   LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_MCH);
 
 
@@ -178,7 +178,7 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms,
     PHY_vars_UE->dlsch_SI[i]  = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
     PHY_vars_UE->dlsch_ra[i]  = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag);
 
-    PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antennas_tx_eNB==1 ? 1 : 2;
+    PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2;
   }
 
   PHY_vars_UE->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
@@ -248,8 +248,8 @@ void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs],
     (frame_parms[CC_id])->nushift            = (Nid_cell%6);
     (frame_parms[CC_id])->nb_antennas_tx     = nb_antennas_tx;
     (frame_parms[CC_id])->nb_antennas_rx     = nb_antennas_rx;
-    (frame_parms[CC_id])->nb_antennas_tx_eNB = nb_antenna_ports;
-    (frame_parms[CC_id])->mode1_flag          = (frame_parms[CC_id])->nb_antennas_tx_eNB==1 ? 1 : 0;
+    (frame_parms[CC_id])->nb_antenna_ports_eNB = nb_antenna_ports;
+    (frame_parms[CC_id])->mode1_flag           = (frame_parms[CC_id])->nb_antenna_ports_eNB==1 ? 1 : 0;
 
     init_frame_parms(frame_parms[CC_id],1);
 
@@ -286,8 +286,6 @@ void init_lte_vars(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs],
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       (frame_parms[CC_id])->nb_antennas_tx     = 1;
       (frame_parms[CC_id])->nb_antennas_rx     = nb_antennas_rx_ue;
-
-
       PHY_vars_UE_g[UE_id][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag);
       PHY_vars_UE_g[UE_id][CC_id]->Mod_id=UE_id;
       PHY_vars_UE_g[UE_id][CC_id]->CC_id=CC_id;
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 3592e72361340ec1cda70ecd960e98ce6cd142ca..130a3393905e0325aa60d3ba1612c1772d6ed9aa 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -720,7 +720,7 @@ void get_simulation_options(int argc, char *argv[])
       oai_emulation.info.transmission_mode[0] = atoi (optarg);
 
       if ((oai_emulation.info.transmission_mode[0] != 1) &&  (oai_emulation.info.transmission_mode[0] != 2) && (oai_emulation.info.transmission_mode[0] != 3)
-          && (oai_emulation.info.transmission_mode[0] != 5) && (oai_emulation.info.transmission_mode[0] != 6)) {
+          && (oai_emulation.info.transmission_mode[0] != 5) && (oai_emulation.info.transmission_mode[0] != 6) && (oai_emulation.info.transmission_mode[0] !=7)) {
         printf("Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode[0]);
         exit(-1);
       }
@@ -1194,12 +1194,12 @@ void init_openair1(void)
         PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
         PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_RI_Index  = beta_RI;
         PHY_vars_eNB_g[eNB_id][CC_id]->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
-        PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_A = rho_B
+        PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antenna_ports_eNB>1) ? 1 : 0; // rho_A = rho_B
 
         PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
         PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_RI_Index  = beta_RI;
         PHY_vars_UE_g[UE_id][CC_id]->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
-        PHY_vars_UE_g[UE_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antennas_tx_eNB>1) ? 1 : 0; // rho_A = rho_B
+        PHY_vars_UE_g[UE_id][CC_id]->frame_parms.pdsch_config_common.p_b = (frame_parms[CC_id]->nb_antenna_ports_eNB>1) ? 1 : 0; // rho_A = rho_B
       }
     }
   }