diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 9bb062ba20279d0cb277dddd4786a311d0c8b3cf..e3d2bed6f4f9d7c9f7fae7ad095cf5c259b388fc 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -754,6 +754,7 @@ set(PHY_SRC
   ${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
diff --git a/common/utils/Makefile.inc b/common/utils/Makefile.inc
index b7a1c82379da96c817f5fc96213eeb59d260db99..8c4ebbe31eba2e64710c684583dbc8e0a6827cda 100644
--- a/common/utils/Makefile.inc
+++ b/common/utils/Makefile.inc
@@ -5,7 +5,7 @@ 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)
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 9adbe319160de019788c8d7db2d1d6c7430b341b..51c4939c56dcec8c6c919e6490db40a475ca351a 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -923,14 +923,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( frame_parms->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( frame_parms->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( frame_parms->nb_antennas_rx <= 2, "nb_antennas_rx > 2" );
@@ -941,13 +944,16 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS
     for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
       const int idx = (j<<1)+i;
       const size_t num = 7*2*frame_parms->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) * frame_parms->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) * num );
+      pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t*)malloc16_clear( sizeof(int32_t)*frame_parms->symbols_per_tti*(frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
+      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 );
     }
   }
 }
@@ -1268,10 +1274,10 @@ int phy_init_lte_eNB(PHY_VARS_eNB *phy_vars_eNB,
     if (abstraction_flag==0) {
 
       // TX vars
-      eNB_common_vars->txdata[eNB_id]  = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
-      eNB_common_vars->txdataF[eNB_id] = (mod_sym_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(mod_sym_t*) );
+      eNB_common_vars->txdata[eNB_id]  = (int32_t**)malloc16(phy_vars_eNB->nb_antennas_tx_phy*sizeof(int32_t*) );
+      eNB_common_vars->txdataF[eNB_id] = (mod_sym_t **)malloc16(phy_vars_eNB->nb_antennas_tx_phy*sizeof(mod_sym_t*) );
 
-      for (i=0; i<frame_parms->nb_antennas_tx; i++) {
+      for (i=0; i<phy_vars_eNB->nb_antennas_tx_phy; i++) {
 #ifdef USER_MODE
         eNB_common_vars->txdata[eNB_id][i]  = (int32_t*)malloc16_clear( FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(int32_t) );
         eNB_common_vars->txdataF[eNB_id][i] = (mod_sym_t*)malloc16_clear( FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t) );
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..557c54dddddb9ab23e2b6a86c5a6ac32e02ea440
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/bf_freq_domain_filters.m
@@ -0,0 +1,59 @@
+filter_length = 12;
+
+F = -3/4:1/4:7/4;
+F_l = zeros(8,12);
+F_r = zeros(8,12);
+F_m = zeros(8,12);
+
+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)]);
+  F_r(i+1,:)  = floor(16384*[zeros(1,4+i) F(4:end-i)]);
+  F_m(i+1,:)  = floor(16384*[F(4-i:8) F(7:-1:1+i)]);
+end
+
+for i=0:1
+  F_l(i+5,:)  = floor(16384*[F(8:-1:4-i) zeros(1,7-i)]);
+  F_r(i+5,:)  = floor(16384*[zeros(1,5+i) F2(5+i) F2(7:end-i)]);
+  F_m(i+5,:)  = floor(16384*[F(4-i:8) F2(8-i) F2(6:-1:1+i)]);
+end
+
+for i=2:3
+  F_l(i+5,:)  = floor(16384*[F2(end:-1:7) F2(8-i) zeros(1,5)]);
+  F_r(i+5,:)  = floor(16384*[zeros(1,4+i) F(4:end-i)]);
+  F_m(i+5,:)  = floor(16384*[F2(4-i:6) F2(4+i) F(8:-1:1+i)]);
+end
+
+
+fd = fopen("filt12_32.h","w");
+
+for i=0:3
+  fprintf(fd,"short filt12_l%d[12] = {\n",i);
+  fprintf(fd,"%d,",F_l(i+1,1:end-1));
+  fprintf(fd,"%d};\n\n",F_l(i+1,end));
+  
+  fprintf(fd,"short filt12_r%d[12] = {\n",i);
+  fprintf(fd,"%d,",F_r(i+1,1:end-1));
+  fprintf(fd,"%d};\n\n",F_r(i+1,end));
+  
+  fprintf(fd,"short filt12_m%d[12] = {\n",i);
+  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 filt12_l%d_dc[12] = {\n",i);
+  fprintf(fd,"%d,",F_l(i+5,1:end-1));
+  fprintf(fd,"%d};\n\n",F_l(i+5,end));
+  
+  fprintf(fd,"short filt12_r%d_dc[12] = {\n",i);
+  fprintf(fd,"%d,",F_r(i+5,1:end-1));
+  fprintf(fd,"%d};\n\n",F_r(i+5,end));
+  
+  fprintf(fd,"short filt12_m%d_dc[12] = {\n",i);
+  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 ee8d9d8c6f74f2214772d09e8b25af5da92552cb..47636025251e9bb1174a146823ca5b5bc8c60d1f 100644
--- a/openair1/PHY/LTE_ESTIMATION/defs.h
+++ b/openair1/PHY/LTE_ESTIMATION/defs.h
@@ -124,6 +124,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
                               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,
                                     uint8_t eNB_offset,
diff --git a/openair1/PHY/LTE_ESTIMATION/filt12_32.h b/openair1/PHY/LTE_ESTIMATION/filt12_32.h
new file mode 100644
index 0000000000000000000000000000000000000000..602f7c2c3f2caae700812db7c1a64842a42e4027
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/filt12_32.h
@@ -0,0 +1,72 @@
+short filt12_l0[12] = {
+16384,12288,8192,4096,0,0,0,0,0,0,0,0};
+
+short filt12_r0[12] = {
+0,0,0,0,0,4096,8192,12288,16384,20480,24576,28672};
+
+short filt12_m0[12] = {
+0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192,-12288};
+
+short filt12_l1[12] = {
+20480,16384,12288,8192,4096,0,0,0,0,0,0,0};
+
+short filt12_r1[12] = {
+0,0,0,0,0,0,4096,8192,12288,16384,20480,24576};
+
+short filt12_m1[12] = {
+-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096,-8192};
+
+short filt12_l2[12] = {
+24576,20480,16384,12288,8192,4096,0,0,0,0,0,0};
+
+short filt12_r2[12] = {
+0,0,0,0,0,0,0,4096,8192,12288,16384,20480};
+
+short filt12_m2[12] = {
+-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0,-4096};
+
+short filt12_l3[12] = {
+28672,24576,20480,16384,12288,8192,4096,0,0,0,0,0};
+
+short filt12_r3[12] = {
+0,0,0,0,0,0,0,0,4096,8192,12288,16384};
+
+short filt12_m3[12] = {
+-12288,-8192,-4096,0,4096,8192,12288,16384,12288,8192,4096,0};
+
+short filt12_l0_dc[12] = {
+16384,12288,8192,4096,0,0,0,0,0,0,0,0};
+
+short filt12_r0_dc[12] = {
+0,0,0,0,0,3276,9830,13107,16384,19660,22937,26214};
+
+short filt12_m0_dc[12] = {
+0,4096,8192,12288,16384,13107,6553,3276,0,-3277,-6554,-9831};
+
+short filt12_l1_dc[12] = {
+16384,12288,8192,4096,0,-4096,0,0,0,0,0,0};
+
+short filt12_r1_dc[12] = {
+0,0,0,0,0,0,6553,9830,13107,16384,19660,22937};
+
+short filt12_m1_dc[12] = {
+-4096,0,4096,8192,12288,16384,9830,6553,3276,0,-3277,-6554};
+
+short filt12_l2_dc[12] = {
+26214,22937,19660,16384,13107,9830,6553,0,0,0,0,0};
+
+short filt12_r2_dc[12] = {
+0,0,0,0,0,0,0,4096,8192,12288,16384,20480};
+
+short filt12_m2_dc[12] = {
+-6554,-3277,0,3276,6553,6553,16384,12288,8192,4096,0,-4096};
+
+short filt12_l3_dc[12] = {
+26214,22937,19660,16384,13107,9830,3276,0,0,0,0,0};
+
+short filt12_r3_dc[12] = {
+0,0,0,0,0,0,0,0,4096,8192,12288,16384};
+
+short filt12_m3_dc[12] = {
+-9831,-6554,-3277,0,3276,6553,9830,16384,12288,8192,4096,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..9707b15b3501162e0e36edd3d485aac387ec6f7d
--- /dev/null
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -0,0 +1,96 @@
+/*******************************************************************************
+    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 "filt12_32.h"
+//#define DEBUG_CH
+
+/*To be accomplished*/
+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 char aarx;
+  int uespec_pilot[9][200];
+  short *pil, *rxF;
+
+  //LTE_UE_PDSCH *lte_ue_pdsch_vars = phy_vars_ue->lte_ue_pdsch_vars[eNB_id];
+  int **rxdataF = phy_vars_ue->lte_ue_common_vars.rxdataF;
+  int32_t **dl_bf_ch_estimates = phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates;
+
+  int beamforming_mode = phy_vars_ue->transmission_mode>7?phy_vars_ue->transmission_mode : 0;
+  
+  // define interpolation filters
+  //....
+
+  //ch_offset     = phy_vars_ue->lte_frame_parms.ofdm_symbol_size*symbol;
+
+  //generate ue specific pilots
+  if(beamforming_mode==7)
+    lte_dl_ue_spec_rx(phy_vars_ue,&uespec_pilot[p-5][0],Ns,p,0);
+  else if (beamforming_mode>7)
+    lte_dl_ue_spec_rx(phy_vars_ue,&uespec_pilot[p-6][0],Ns,p,0);
+  else if (beamforming_mode==0)
+    msg("No beamforming is performed.\n");
+  else
+    msg("Beamforming mode not supported yet.\n");
+  
+
+  if(beamforming_mode==7) {
+   
+    for (aarx=0; aarx<phy_vars_ue->lte_frame_parms.nb_antennas_rx;aarx++) {
+
+    /*  pil   = (short *)&uespec_pilot[0][0];
+      rxF   = (short *)&rxdataF_uespec[aarx][(symbol-1)/3*frame_parms->N_RB_DL*(3+frame_parms->Ncp)];
+      dl_ch = (short *)&dl_bf_ch_estimates[aarx][ch_offset];
+
+      memset(dl_ch,0,4*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size));
+      //estimation and interpolation */
+    }
+
+  } else if (beamforming_mode==0){
+    msg("No beamforming is performed.\n");
+    return(-1);
+  } else {
+    msg("Beamforming mode is not supported yet.\n");
+    return(-1);
+  }
+  
+  //temporal interpolation
+
+  return(0);
+
+}
diff --git a/openair1/PHY/LTE_REFSIG/defs.h b/openair1/PHY/LTE_REFSIG/defs.h
index 2127380565c4d756ee3160b4e0e20af09f33bbc3..e9482060a7d028b9919e6cbdac8826f8b30357bb 100644
--- a/openair1/PHY/LTE_REFSIG/defs.h
+++ b/openair1/PHY/LTE_REFSIG/defs.h
@@ -52,12 +52,13 @@ 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);
+
 /*!\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);
 
@@ -84,6 +85,7 @@ 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
 */
@@ -92,6 +94,7 @@ int lte_dl_ue_spec(PHY_VARS_eNB *phy_vars_eNB,
                    mod_sym_t *output,
                    short amp,
                    uint8_t Ns,
+		   uint8_t lprime,
                    uint8_t p,
                    int SS_flag );
 
@@ -123,6 +126,12 @@ int lte_dl_cell_spec_rx(PHY_VARS_UE *phy_vars_ue,
                         unsigned char l,
                         unsigned char p);
 
+int lte_dl_ue_spec_rx(PHY_VARS_UE *phy_vars_ue,
+                      mod_sym_t *output,
+                      unsigned char Ns,
+                      unsigned char p,
+                      int SS_flag);
+
 int lte_dl_mbsfn_rx(PHY_VARS_UE *phy_vars_ue,
                     int *output,
                     int subframe,
diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_ue_spec.c b/openair1/PHY/LTE_REFSIG/lte_dl_ue_spec.c
new file mode 100644
index 0000000000000000000000000000000000000000..64c4e8782eea62fca654018addebac7ba1608322
--- /dev/null
+++ b/openair1/PHY/LTE_REFSIG/lte_dl_ue_spec.c
@@ -0,0 +1,393 @@
+/*******************************************************************************
+    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_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 X. Jiang
+* \date 2015
+* \version 0.1
+* \company Eurecom
+* \email: knopp@eurecom.fr xiwen.jiang@eurecom.fr
+* \note
+* \warning
+*/
+
+#ifdef USER_MODE
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "defs.h"
+#include "PHY/defs.h"
+#include "log.h"
+
+//extern unsigned int lte_gold_table[3][20][2][14];
+//#define DEBUG_DL_CELL_SPEC
+
+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 *phy_vars_eNB,
+                   uint8_t UE_id,
+                   mod_sym_t *output,
+                   short amp,
+                   uint8_t Ns,
+		   uint8_t lprime,
+                   uint8_t p,
+                   int SS_flag )
+{
+
+  mod_sym_t qpsk[4],nqpsk[4];
+  int16_t k=0,a;
+  int mprime,mprime_dword,mprime_qpsk_symb;
+  unsigned nushift,kprime;
+  //  LTE_eNB_DLSCH_t *dlsch = phy_vars_eNB->dlsch_eNB[UE_id][0];
+
+  a = (amp*ONE_OVER_SQRT2_Q15)>>15;
+  ((short *)&qpsk[0])[0] = a;
+  ((short *)&qpsk[0])[1] = a;
+  ((short *)&qpsk[1])[0] = -a;
+  ((short *)&qpsk[1])[1] = a;
+  ((short *)&qpsk[2])[0] = a;
+  ((short *)&qpsk[2])[1] = -a;
+  ((short *)&qpsk[3])[0] = -a;
+  ((short *)&qpsk[3])[1] = -a;
+
+  ((short *)&nqpsk[0])[0] = -a;
+  ((short *)&nqpsk[0])[1] = -a;
+  ((short *)&nqpsk[1])[0] = a;
+  ((short *)&nqpsk[1])[1] = -a;
+  ((short *)&nqpsk[2])[0] = -a;
+  ((short *)&nqpsk[2])[1] = a;
+  ((short *)&nqpsk[3])[0] = a;
+  ((short *)&nqpsk[3])[1] = a;
+
+  if (p==5) {
+    if (SS_flag==0) {
+      if (phy_vars_eNB->lte_frame_parms.Ncp == NORMAL) {
+      // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p=5
+      
+      nushift =  phy_vars_eNB->lte_frame_parms.Nid_cell%3;
+
+      if(lprime==0){
+        kprime=nushift;
+      }else{
+        kprime=(nushift+2*lprime)%4;
+      }
+
+      k = kprime+phy_vars_eNB->lte_frame_parms.first_carrier_offset;
+      printf("lte_dl_ue_spec:k=%d\n",k);
+ 
+      for (mprime=0;mprime<3*phy_vars_eNB->lte_frame_parms.N_RB_DL-1;mprime++) {
+        mprime_dword     = mprime>>4;
+        mprime_qpsk_symb = mprime&0xf;
+
+        //output[k] = qpsk[(phy_vars_eNB->lte_gold_uespec_port5_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+        output[k] = 0xffffffff;
+
+        k += 4;
+        if (k >= phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) {
+          k++;  // skip DC carrier
+          k-=phy_vars_eNB->lte_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 *phy_vars_ue,
+      mod_sym_t *output,
+      unsigned char Ns,
+      unsigned char p, 
+      int SS_flag)
+{
+  mod_sym_t qpsk[4],nqpsk[4],*qpsk_p,*output_p;
+  int16_t a;
+  int w,lprime,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;
+
+  // 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;
+
+  ((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 (phy_vars_ue->lte_frame_parms.Ncp == NORMAL) {
+        // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p>=7
+
+        output_p = output;
+
+        for (lprime=0; lprime<2; lprime++) {
+
+          ind = 3*lprime*phy_vars_ue->lte_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<phy_vars_ue->lte_frame_parms.N_RB_DL; nPRB+=2) {
+
+            // First pilot
+            w = Wbar_NCP[p-7][l];
+            qpsk_p = (w==1) ? qpsk : nqpsk;
+
+
+            ind_dword     = ind>>4;
+            ind_qpsk_symb = ind&0xf;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            output_p++;
+            ind++;
+
+            w =  Wbar_NCP[p-7][3-l];
+            qpsk_p = (w==1) ? qpsk : nqpsk;
+
+            // Second pilot
+            ind_dword     = ind>>4;
+            ind_qpsk_symb = ind&0xf;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            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;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            output_p++;
+            ind++;
+
+            // Fourth pilot
+            w = Wbar_NCP[p-7][3-l];
+            qpsk_p = (w==1) ? qpsk : nqpsk;
+
+
+            ind_dword     = ind>>4;
+            ind_qpsk_symb = ind&0xf;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            output_p++;
+            ind++;
+
+            w =  Wbar_NCP[p-7][l];
+            qpsk_p = (w==1) ? qpsk : nqpsk;
+
+            // Fifth pilot
+            ind_dword     = ind>>4;
+            ind_qpsk_symb = ind&0xf;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            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;
+
+            *output_p = qpsk_p[(phy_vars_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,ind_dword,ind_qpsk_symb);
+            LOG_D(PHY,"index = %d\n",(phy_vars_ue->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
+#endif
+
+            output_p++;
+            ind++;
+          }
+        }
+      } else {
+        LOG_E(PHY,"Special subframe not supported for UE specific pilots yet\n");
+      }
+    }
+  } else if (p==5) {
+    if (SS_flag==0) {
+        if (phy_vars_ue->lte_frame_parms.Ncp == NORMAL) {
+        
+        for (lprime=0;lprime<2;lprime++) {
+            ind = 3*lprime*phy_vars_ue->lte_frame_parms.N_RB_DL;    
+            
+            for (mprime=0;mprime<3*phy_vars_ue->lte_frame_parms.N_RB_DL-1;mprime++) {
+                ind_dword     = ind>>4;
+                ind_qpsk_symb = ind&0xf;
+                *output_p = qpsk_p[(phy_vars_ue->lte_gold_uespec_port5_table[Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3];
+                *output_p++;
+            }
+        }
+      }
+    }
+  } else {
+    LOG_E(PHY,"Illegal p %d UE specific pilots\n",p);
+  }
+
+  return(0);
+}
+
+
+
+#ifdef LTE_DL_CELL_SPEC_MAIN
+
+
+
+//extern int write_output(const char *,const char *,void *,int,int,char);
+// flag change eren
+extern int write_output(const char *,const char *,void *,int,int,char);
+main()
+{
+
+  unsigned short Nid_cell=0;
+  unsigned int Ncp = 0;
+  int output00[1024];
+  int output01[1024];
+  int output10[1024];
+  int output11[1024];
+
+  memset(output00,0,1024*sizeof(int));
+  memset(output01,0,1024*sizeof(int));
+  memset(output10,0,1024*sizeof(int));
+  memset(output11,0,1024*sizeof(int));
+
+  lte_gold(Nid_cell,Ncp);
+
+  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);
+}
+
+
+#endif
diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
index b40f6ddfda25e2bd2e2749d706848c499e40220b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
+++ b/openair1/PHY/LTE_REFSIG/lte_dl_uespec.c
@@ -1,362 +0,0 @@
-/*******************************************************************************
-    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_REFSIG/lte_dl_uespec.c
-* \brief Top-level routines for generating UE-specific Reference signals from 36-211, V11.3.0 2013-06
-* \author R. Knopp
-* \date 2014
-* \version 0.1
-* \company Eurecom
-* \email: knopp@eurecom.fr
-* \note
-* \warning
-*/
-
-#ifdef USER_MODE
-#include <stdio.h>
-#include <stdlib.h>
-#endif
-
-#include "defs.h"
-#include "PHY/defs.h"
-#include "log.h"
-
-//extern unsigned int lte_gold_table[3][20][2][14];
-//#define DEBUG_DL_CELL_SPEC
-
-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 *phy_vars_eNB,
-                   uint8_t UE_id,
-                   mod_sym_t *output,
-                   short amp,
-                   uint8_t Ns,
-                   uint8_t p,
-                   int SS_flag )
-{
-
-  mod_sym_t qpsk[4],nqpsk[4],*qpsk_p,*output_p;
-  int16_t a;
-  int w,lprime,ind,l,ind_dword,ind_qpsk_symb,nPRB;
-  //  LTE_eNB_DLSCH_t *dlsch = phy_vars_eNB->dlsch_eNB[UE_id][0];
-
-  a = (amp*ONE_OVER_SQRT2_Q15)>>15;
-  ((short *)&qpsk[0])[0] = a;
-  ((short *)&qpsk[0])[1] = a;
-  ((short *)&qpsk[1])[0] = -a;
-  ((short *)&qpsk[1])[1] = a;
-  ((short *)&qpsk[2])[0] = a;
-  ((short *)&qpsk[2])[1] = -a;
-  ((short *)&qpsk[3])[0] = -a;
-  ((short *)&qpsk[3])[1] = -a;
-
-  ((short *)&nqpsk[0])[0] = -a;
-  ((short *)&nqpsk[0])[1] = -a;
-  ((short *)&nqpsk[1])[0] = a;
-  ((short *)&nqpsk[1])[1] = -a;
-  ((short *)&nqpsk[2])[0] = -a;
-  ((short *)&nqpsk[2])[1] = a;
-  ((short *)&nqpsk[3])[0] = a;
-  ((short *)&nqpsk[3])[1] = a;
-
-  if (p>=7) {
-    if (SS_flag==0) {
-      if (phy_vars_eNB->lte_frame_parms.Ncp == NORMAL) {
-        // this is 3GPP 36-211 6.10.3.2, NORMAL CP, p>=7
-
-
-
-        // position output pointer to 5th symbol in slot
-        output_p = output+(60*phy_vars_eNB->lte_frame_parms.N_RB_DL);
-
-        // shift to 2nd RE in PRB for p=7,8,11,13
-        if ((p==7) || (p==8) || (p==11) || (p==13)) output_p++;
-
-
-        for (lprime=0; lprime<2; lprime++) {
-
-          ind = 3*lprime*phy_vars_eNB->lte_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<phy_vars_eNB->lte_frame_parms.N_RB_DL; nPRB+=2) {
-
-            // First pilot
-            w = Wbar_NCP[p-7][l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-
-
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
-
-            *output_p = qpsk_p[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=5;
-            ind++;
-
-            w =  Wbar_NCP[p-7][3-l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-
-            // Second pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
-
-            *output_p = qpsk_p[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=5;
-            ind++;
-
-            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[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=2;
-            ind++;
-
-            // Fourth pilot
-            w = Wbar_NCP[p-7][3-l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-
-
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
-
-            *output_p = qpsk_p[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=5;
-            ind++;
-
-            w =  Wbar_NCP[p-7][l];
-            qpsk_p = (w==1) ? qpsk : nqpsk;
-
-            // Fifth pilot
-            ind_dword     = ind>>4;
-            ind_qpsk_symb = ind&0xf;
-
-            *output_p = qpsk_p[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=5;
-            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;
-
-            *output_p = qpsk_p[(phy_vars_eNB->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",(phy_vars_eNB->lte_gold_uespec_table[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
-#endif
-
-            output_p+=2;
-            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");
-  } else {
-    LOG_E(PHY,"Illegal p %d UE specific pilots\n",p);
-  }
-
-  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->lte_frame_parms.N_RB_DL;
-
-  for (m=0;m<phy_vars_ue->lte_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
-
-
-
-//extern int write_output(const char *,const char *,void *,int,int,char);
-// flag change eren
-extern int write_output(const char *,const char *,void *,int,int,char);
-main()
-{
-
-  unsigned short Nid_cell=0;
-  unsigned int Ncp = 0;
-  int output00[1024];
-  int output01[1024];
-  int output10[1024];
-  int output11[1024];
-
-  memset(output00,0,1024*sizeof(int));
-  memset(output01,0,1024*sizeof(int));
-  memset(output10,0,1024*sizeof(int));
-  memset(output11,0,1024*sizeof(int));
-
-  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);
-}
-
-
-#endif
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c
index 2463d73b7953320a0be61ad6568d511b2358a583..456a2b17d1152f62a093c382f6922a3ce6427a0f 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold.c
@@ -142,6 +142,48 @@ 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][2][21],uint16_t Nid_cell, uint16_t n_rnti)
+{
+
+  unsigned char ns,l;
+  unsigned int n,x1,x2;
+
+
+  for (ns=0; ns<20; ns++) {
+
+    for (l=0; l<2; l++) {
+
+
+      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<14; 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][l][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/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index 5dd2f9b5f901b4caba1b36e70d55d11b4484a825..db95c2362cf61cbc642cede6764e8827a0efda03 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -259,6 +259,7 @@ int dlsch_encoding(unsigned char *a,
   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 transmission_mode_7to9=0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
 
@@ -266,7 +267,13 @@ int dlsch_encoding(unsigned char *a,
   // 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)
+    transmission_mode_7to9 = 7;
+  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8)
+    transmission_mode_7to9 = 8;
+  else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10)
+    transmission_mode_7to9 = 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,transmission_mode_7to9);
 
 
   //  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 a1f1173ede0bf5f9eeab07653c38108f66693cae..3aa3f723127e7a0b6f4f61ba8e60b5a0be219e99 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/******************************************************************************
     OpenAirInterface
     Copyright(c) 1999 - 2014 Eurecom
 
@@ -74,7 +74,6 @@ unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6,
 */
 unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
 
-
 extern void print_shorts(char *s,__m128i *x);
 
 int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
@@ -99,6 +98,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
   unsigned short nb_rb;
   int avgs, rb;
   LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
+  
+  uint8_t beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]<7?0:phy_vars_ue->transmission_mode[eNB_id];
 
   switch (type) {
   case SI_PDSCH:
@@ -162,7 +163,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
     pilots=0;
   */
 
-  if (frame_parms->nb_antennas_tx_eNB>1) {
+  if (frame_parms->nb_antennas_tx_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_ue[0],dlsch0_harq->rb_alloc[0]);
 #endif
@@ -204,8 +205,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
                                        phy_vars_ue->high_speed_flag,
                                        frame_parms);
     }
-  } // if n_tx>1
-  else {
+  } else if (beamforming_mode==0) {// if n_tx>1
     nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF,
                                      lte_ue_common_vars->dl_ch_estimates[eNB_id],
                                      lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
@@ -244,7 +244,21 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
                                          phy_vars_ue->high_speed_flag,
                                          frame_parms);
     }
-  } //else n_tx>1
+  } else if (beamforming_mode==7) { //else n_tx>1
+    nb_rb = dlsch_extract_rbs_TM7(lte_ue_common_vars->rxdataF,
+                                  lte_ue_common_vars->dl_ch_estimates[eNB_id],
+                                  lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
+                                  lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+				  dlsch0_harq->rb_alloc,
+                                  symbol,
+                                  subframe,
+                                  phy_vars_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) {
@@ -418,7 +432,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
     }
   } else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) { // single-layer precoding (TM5, TM6), potentially TM4 (Single-codeword)
     //    printf("Channel compensation for precoding\n");
-    //    if ((dual_stream_flag==1) && (eNB_id_i==NUMBER_OF_CONNECTED_eNB_MAX)) {
+    //    if ((dual_stream_flag==1) && (eNB_id_i==NUMBER_OF_CONNECTED_eNB_MAX)){
     if ((dual_stream_flag==1) && (eNB_id_i==phy_vars_ue->n_connected_eNB)) {  // TM5 two-user
 
       // Scale the channel estimates for interfering stream
@@ -531,6 +545,21 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
                                       lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                                       1);
     }
+  } else if (dlsch0_harq->mimo_mode==TM7) { //TM7
+
+    dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
+                               lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
+                               lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
+                               lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
+                               lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
+                               (aatx>1) ? lte_ue_pdsch_vars[eNB_id]->rho : NULL,
+                               frame_parms,
+                               symbol,
+                               first_symbol_flag,
+                               get_Qm(dlsch0_harq->mcs),
+                               nb_rb,
+                               lte_ue_pdsch_vars[eNB_id]->log2_maxh,
+                               phy_measurements); // log2_maxh+I0_shift
   }
 
   //  printf("MRC\n");
@@ -570,8 +599,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_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,
       lte_ue_pdsch_vars[eNB_id]->rxdataF_comp,
@@ -608,7 +637,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
                        lte_ue_pdsch_vars[eNB_id]->llr[0],
                        symbol,first_symbol_flag,nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol),
-                       lte_ue_pdsch_vars[eNB_id]->llr128);
+                       lte_ue_pdsch_vars[eNB_id]->llr128,
+                       beamforming_mode);
       else if (i_mod == 2) {
         dlsch_qpsk_qpsk_llr(frame_parms,
                             lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
@@ -4178,50 +4208,791 @@ 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_ch_estimates,
+                                     int **rxdataF_ext,
+                                     int **dl_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,*rxF_uespec;
 
-void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round)
-{
+  unsigned char symbol_mod,pilots=0,uespec_pilots=0,j=0,k=0,poffset=0,uespec_poffset=0;
+  int8_t uespec_nushift = frame_parms->Nid_cell%3;
 
-  unsigned int nsymb = (phy_vars_ue->lte_frame_parms.Ncp == 0) ? 14 : 12;
-  char fname[32],vname[32];
-  int N_RB_DL=phy_vars_ue->lte_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,phy_vars_ue->lte_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 (phy_vars_ue->lte_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,phy_vars_ue->lte_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,phy_vars_ue->lte_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 (phy_vars_ue->lte_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,phy_vars_ue->lte_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 (phy_vars_ue->lte_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,phy_vars_ue->lte_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 (phy_vars_ue->lte_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,phy_vars_ue->lte_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_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
+    else
+      dl_ch0     = &dl_ch_estimates[aarx][5];
+
+    dl_ch0_ext = &dl_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)))];
+    printf("symbol:%d, (symbol-1)/3:%d\n",symbol,(symbol-1)/3);
+    //rxF_uespec = &rxdataF_uespec_pilots[aarx][(symbol-1)/3*frame_parms->N_RB_DL*(3+frame_parms->Ncp)];
+    //printf("symbol, rxF_uespec offset:%d\n",symbol,(symbol-1)/3*frame_parms->N_RB_DL*(3+frame_parms->Ncp));
+
+    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;
+
+        // 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++;
+        }
+
+        if (rb_alloc_ind==1) {
+          //*pmi_ext = (pmi>>((rb>>2)<<1))&3;
+          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
+
+          /*
+              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) {
+            for (i=0; i<12; i++) {
+              rxF_ext[i]=rxF[i];
+              /*
+              printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),
+              ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/
+            }
+
+            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];
+                //            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                dl_ch0_ext[j++]=dl_ch0[i];
+
+              }
+            }
+
+            dl_ch0_ext+=10;
+            rxF_ext+=10;
+
+          } else if (pilots==0 && uespec_pilots==1) {
+            j=0;
+            k=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);
+          }
+
+          nb_rb++;
+        }
+
+        dl_ch0+=12;
+        rxF+=12;
+
+      }
+    else {  // Odd number of RBs
+      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
+        //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
+        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;
+
+
+        // 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==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==((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) {
+           // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+
+          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];
+
+              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)];
+
+              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];
+
+              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];
+                  //            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  dl_ch0_ext[j++]=dl_ch0[i];
+                }
+              }
+
+              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)];
+                  //            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  dl_ch0_ext[j++]=dl_ch0[i+6];
+                }
+              }
+
+              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];
+                  //            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  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;
+            k=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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];  
+                  }
+                } 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);
+            
+          }
+
+          nb_rb++;
+        }
+
+        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;
+
+
+
+      // 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)) {
+        //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];
+          }
+
+          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)];
+          }
+
+          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];
+             // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+            }
+          }
+
+          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)];
+              //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+            }
+          }
+
+          dl_ch0_ext+=10;
+          rxF_ext+=10;
+        } else if(pilots==0 && uespec_pilots==1) {
+          j=0;
+          k=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];
+                //printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+              }
+            } 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];
+               // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+              }
+            }
+	  }
+          
+          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)];
+                // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
+              }
+            } 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)];
+              }
+            }
+          }
+           
+          dl_ch0_ext+=9-frame_parms->Ncp;
+          rxF_ext+=9-frame_parms->Ncp; 
+          	  
+	}// symbol_mod==0
+
+        nb_rb++;
+      } // 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;
+
+
+
+        // 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==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==((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) {
+          //    printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
+          /*
+              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];
+
+              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)];
+
+              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];
+
+              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];
+                  //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  dl_ch0_ext[j++]=dl_ch0[i];
+                }
+              }
+
+              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)];
+                  //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  dl_ch0_ext[j++]=dl_ch0[i+6];
+                }
+              }
+
+              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];
+                  //printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
+                  dl_ch0_ext[j++]=dl_ch0[i];
+                }
+              }
+
+              dl_ch0_ext+=10;
+              rxF_ext+=10;
+            }
+          } else if(pilots==0 && uespec_pilots==1) {
+            j=0;
+            k=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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];
+                  }
+                }
+                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];  
+                  }
+                } 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; 
+
+            }
+	      
+          }// pilots=0
+
+          nb_rb++;
+        }
+
+        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 *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round)
+{
+
+  unsigned int nsymb = (phy_vars_ue->lte_frame_parms.Ncp == 0) ? 14 : 12;
+  char fname[32],vname[32];
+  int N_RB_DL=phy_vars_ue->lte_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,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+
+  if (phy_vars_ue->lte_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,phy_vars_ue->lte_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,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+
+  if (phy_vars_ue->lte_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,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
+  }
+
+  if (phy_vars_ue->lte_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,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+
+    if (phy_vars_ue->lte_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,phy_vars_ue->lte_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,phy_vars_ue->lte_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",lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],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 4990e94cf51725c6bc9e637e95e43cef1e60a3e7..951e4afcd0ec8d01625a144d1747b6083a6d1f7f 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -640,7 +640,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,
-                   short **llr32p)
+                   short **llr32p,
+		   uint8_t beamforming_mode)
 {
 
   uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
@@ -661,11 +662,16 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
 
   if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
-    if (frame_parms->mode1_flag==0)
+    if (frame_parms->mode1_flag==0 && beamforming_mode!=7)
       len = (nb_rb*8);// - (2*pbch_pss_sss_adjust/3);
     else
       len = (nb_rb*10);// - (5*pbch_pss_sss_adjust/6);
-  } else {
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12)){
+      len = (nb_rb*9);
+  } else if((beamforming_mode==7) && (frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==10)){
+      len = (nb_rb*8);
+  }
+  else {
     len = (nb_rb*12);// - pbch_pss_sss_adjust;
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index c4b0247d7531ee70b9f80a6c26f2cc9b3f9aabbe..d14c26c13ddb4e6054b2774fa3d65259de6287eb 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -1,42 +1,42 @@
 /*******************************************************************************
-    OpenAirInterface
-    Copyright(c) 1999 - 2014 Eurecom
+  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 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.
+  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/>.
+  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
+Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
 
  *******************************************************************************/
 
 /*! \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"
@@ -70,10 +70,33 @@ 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)
+uint8_t is_not_UEspecRS(uint8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
 {
+  uint8_t offset = (lprime==2)?2:0;
+  if(lprime==0)
+    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(1);
+  return(0);
 }
 
 void generate_64qam_table(void)
@@ -110,33 +133,33 @@ 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);  */
 }
 
-int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
+int allocate_REs_in_RB(PHY_VARS_eNB *phy_vars_eNB,
                        mod_sym_t **txdataF,
                        uint32_t *jj,
                        uint32_t *jj2,
@@ -151,10 +174,14 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
                        int16_t *qam_table_s1,
                        uint32_t *re_allocated,
                        uint8_t skip_dc,
-                       uint8_t skip_half)
+                       uint8_t skip_half,
+                       uint8_t lprime,
+                       uint8_t mprime,
+                       uint8_t Ns,
+                       int32_t **beamforming_weights)
 {
 
-
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
   uint8_t *x0             = dlsch0_harq->e;
   MIMO_mode_t mimo_mode   = dlsch0_harq->mimo_mode;
 
@@ -165,11 +192,11 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
   uint8_t *x1=NULL;
   uint8_t mod_order1=2;
+  uint8_t nb_antennas_tx_phy = phy_vars_eNB->nb_antennas_tx_phy;
+
   // Fill these in later for TM8-10
   //  int Nlayers1;
   //  int first_layer1;
-
-
   int use2ndpilots = (frame_parms->mode1_flag==1)?1:0;
 
   uint32_t tti_offset,aa;
@@ -195,10 +222,23 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   uint8_t first_re,last_re;
   int32_t tmp_sample1,tmp_sample2;
   int16_t tmp_amp=amp;
+  uint8_t layer;
   int s=1;
+        
+  uint8_t mprime2 = mprime,mprime_dword,mprime_qpsk_symb;
+  mod_sym_t qpsk[4];
 
   gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
   //  if (mimo_mode == LARGE_CDD) gain_lin_QPSK>>=1;
+  ((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;
@@ -210,151 +250,151 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
   }
 
   /*
-  switch (mod_order) {
-  case 2:
-    // QPSK single stream
-
-    break;
-  case 4:
-    //16QAM Single stream
-    gain_lin_16QAM1 = (int16_t)(((int32_t)amp*QAM16_n1)>>15);
-    gain_lin_16QAM2 = (int16_t)(((int32_t)amp*QAM16_n2)>>15);
-
-    break;
+     switch (mod_order) {
+     case 2:
+// QPSK single stream
+
+break;
+case 4:
+//16QAM Single stream
+gain_lin_16QAM1 = (int16_t)(((int32_t)amp*QAM16_n1)>>15);
+gain_lin_16QAM2 = (int16_t)(((int32_t)amp*QAM16_n2)>>15);
+
+break;
+
+case 6:
+//64QAM Single stream
+break;
+default:
+break;
+}
+   */
 
-  case 6:
-    //64QAM Single stream
-    break;
-  default:
-    break;
-  }
-  */
-
-#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]);
-#endif
+//#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]);
+//#endif
 
   first_re=0;
   last_re=12;
-
+  
   if (skip_half==1)
     last_re=6;
   else if (skip_half==2)
     first_re=6;
-
-  for (re=first_re; re<last_re; re++) {
-
-
+  
+    for (re=first_re; re<last_re; re++) {
+  
     if ((skip_dc == 1) && (re==6))
       re_off=re_off - frame_parms->ofdm_symbol_size+1;
 
-    tti_offset = symbol_offset + re_off + re;
 
+    tti_offset = symbol_offset + re_off + re;
+    // printf("tti_offset = %d\n", tti_offset);
     // check that RE is not from Cell-specific RS
 
     if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) {
-      //     printf("re %d (jj %d)\n",re,*jj);
+     //  printf("re %d (jj %d)\n",re,*jj);
 
 
       if (mimo_mode == SISO) {  //SISO mapping
         *re_allocated = *re_allocated + 1;
 
         switch (mod_order0) {
-        case 2:  //QPSK
+          case 2:  //QPSK
 
-          //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
-          }
+            //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
+            }
 
-          *jj = *jj + 1;
+            *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}
-          }
+            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}
+            }
 
-          *jj = *jj + 1;
+            *jj = *jj + 1;
 
-          // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-          break;
+            //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_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);
-          }
+            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);
+            }
 
-          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_s0[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_s0[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
-          }
+            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)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+              ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+            }
 
-          break;
+            break;
 
         }
       }
@@ -365,171 +405,171 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
         amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
 
         switch (mod_order0) {
-        case 2:  //QPSK
+          case 2:  //QPSK
 
-          // first antenna position n -> x0
+            // first antenna position n -> x0
 
-          ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-          *jj=*jj+1;
-          ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-          *jj=*jj+1;
+            ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+            *jj=*jj+1;
+            ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+            *jj=*jj+1;
 
-          // second antenna position n -> -x1*
+            // second antenna position n -> -x1*
 
-          ((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
-          *jj=*jj+1;
-          ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-          *jj=*jj+1;
+            ((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
+            *jj=*jj+1;
+            ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+            *jj=*jj+1;
 
-          // normalization for 2 tx antennas
-          ((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);
-          ((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);
+            // normalization for 2 tx antennas
+            ((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);
+            ((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);
 
-          break;
+            break;
 
-        case 4:  //16QAM
+          case 4:  //16QAM
 
-          // Antenna 0 position n
+            // Antenna 0 position n
 
-          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;
 
-          ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-          ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+            ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+            ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
-          // Antenna 1 position n Real part -> -x1*
+            // Antenna 1 position n Real part -> -x1*
 
-          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;
 
-          ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-          ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+            ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+            ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
 
-          break;
+            break;
 
-        case 6:   // 64-QAM
+          case 6:   // 64-QAM
 
-          // Antenna 0
-          qam64_table_offset_re = 0;
-          qam64_table_offset_im = 0;
+            // Antenna 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;
 
-          ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-          ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+            ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+            ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
 
-          // Antenna 1 => -x1*
-          qam64_table_offset_re = 0;
-          qam64_table_offset_im = 0;
+            // Antenna 1 => -x1*
+            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;
 
-          ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-          ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+            ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+            ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
-          break;
+            break;
         }
 
         // fill in the rest of the ALAMOUTI precoding
@@ -550,182 +590,182 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
 
         if (frame_parms->nb_antennas_tx == 2) {
           switch (mod_order0) {
-          default:
-            LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
-            xx0_re=xx0_im=0;
-            break;
-
-          case 2:  //QPSK
-            //    printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-            xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-            *jj = *jj + 1;
-            xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-            *jj = *jj + 1;
+            default:
+              LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
+              xx0_re=xx0_im=0;
+              break;
+
+            case 2:  //QPSK
+              // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+              xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj = *jj + 1;
+              xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj = *jj + 1;
 
 
 
-            // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-            break;
+              // 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_re0 = 0;
-            qam16_table_offset_im0 = 0;
+              qam16_table_offset_re0 = 0;
+              qam16_table_offset_im0 = 0;
 
-            if (x0[*jj] == 1)
-              qam16_table_offset_re0+=2;
+              if (x0[*jj] == 1)
+                qam16_table_offset_re0+=2;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam16_table_offset_im0+=2;
+              if (x0[*jj] == 1)
+                qam16_table_offset_im0+=2;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam16_table_offset_re0+=1;
+              if (x0[*jj] == 1)
+                qam16_table_offset_re0+=1;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam16_table_offset_im0+=1;
+              if (x0[*jj] == 1)
+                qam16_table_offset_im0+=1;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            xx0_re = qam_table_s0[qam16_table_offset_re0];
-            xx0_im = qam_table_s0[qam16_table_offset_im0];
+              xx0_re = qam_table_s0[qam16_table_offset_re0];
+              xx0_im = qam_table_s0[qam16_table_offset_im0];
 
-            break;
+              break;
 
-          case 6:  //64QAM
+            case 6:  //64QAM
 
 
-            qam64_table_offset_re0 = 0;
-            qam64_table_offset_im0 = 0;
+              qam64_table_offset_re0 = 0;
+              qam64_table_offset_im0 = 0;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_re0+=4;
+              if (x0[*jj] == 1)
+                qam64_table_offset_re0+=4;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_im0+=4;
+              if (x0[*jj] == 1)
+                qam64_table_offset_im0+=4;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_re0+=2;
+              if (x0[*jj] == 1)
+                qam64_table_offset_re0+=2;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_im0+=2;
+              if (x0[*jj] == 1)
+                qam64_table_offset_im0+=2;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_re0+=1;
+              if (x0[*jj] == 1)
+                qam64_table_offset_re0+=1;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            if (x0[*jj] == 1)
-              qam64_table_offset_im0+=1;
+              if (x0[*jj] == 1)
+                qam64_table_offset_im0+=1;
 
-            *jj=*jj+1;
+              *jj=*jj+1;
 
-            xx0_re = qam_table_s0[qam64_table_offset_re0];
-            xx0_im = qam_table_s0[qam64_table_offset_im0];
+              xx0_re = qam_table_s0[qam64_table_offset_re0];
+              xx0_im = qam_table_s0[qam64_table_offset_im0];
 
 
-            break;
+              break;
 
           }
 
           switch (mod_order1) {
-          default:
-            LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1);
-            xx1_re=xx1_im=0;
-            break;
+            default:
+              LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1);
+              xx1_re=xx1_im=0;
+              break;
 
-          case 2:  //QPSK
-            //    printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-            xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-            *jj2 = *jj2 + 1;
-            xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-            *jj2 = *jj2 + 1;
-            // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-            break;
+            case 2:  //QPSK
+              //    printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+              xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj2 = *jj2 + 1;
+              xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+              *jj2 = *jj2 + 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_re1 = 0;
-            qam16_table_offset_im1 = 0;
+              qam16_table_offset_re1 = 0;
+              qam16_table_offset_im1 = 0;
 
-            if (x1[*jj2] == 1)
-              qam16_table_offset_re1+=2;
+              if (x1[*jj2] == 1)
+                qam16_table_offset_re1+=2;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam16_table_offset_im1+=2;
+              if (x1[*jj2] == 1)
+                qam16_table_offset_im1+=2;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam16_table_offset_re1+=1;
+              if (x1[*jj2] == 1)
+                qam16_table_offset_re1+=1;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam16_table_offset_im1+=1;
+              if (x1[*jj2] == 1)
+                qam16_table_offset_im1+=1;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            xx1_re = qam_table_s1[qam16_table_offset_re1];
-            xx1_im = qam_table_s1[qam16_table_offset_im1];
+              xx1_re = qam_table_s1[qam16_table_offset_re1];
+              xx1_im = qam_table_s1[qam16_table_offset_im1];
 
-            break;
+              break;
 
-          case 6:  //64QAM
+            case 6:  //64QAM
 
-            qam64_table_offset_re1 = 0;
-            qam64_table_offset_im1 = 0;
+              qam64_table_offset_re1 = 0;
+              qam64_table_offset_im1 = 0;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_re1+=4;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_re1+=4;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_im1+=4;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_im1+=4;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_re1+=2;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_re1+=2;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_im1+=2;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_im1+=2;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_re1+=1;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_re1+=1;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            if (x1[*jj2] == 1)
-              qam64_table_offset_im1+=1;
+              if (x1[*jj2] == 1)
+                qam64_table_offset_im1+=1;
 
-            *jj2 = *jj2 + 1;
+              *jj2 = *jj2 + 1;
 
-            xx1_re = qam_table_s1[qam64_table_offset_re1];
-            xx1_im = qam_table_s1[qam64_table_offset_im1];
+              xx1_re = qam_table_s1[qam64_table_offset_re1];
+              xx1_im = qam_table_s1[qam64_table_offset_im1];
 
 
-            break;
+              break;
 
           }
 
@@ -740,10 +780,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
           ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1);
           ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1));
           /*
-          printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n",
-           xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1],
-           ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]);
-          */
+             printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n",
+             xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1],
+             ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]);
+           */
           // s alternates +1/-1 for each RE
           s = -s;
         }
@@ -753,246 +793,289 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
         amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
 
         switch (mod_order0) {
-        case 2:  //QPSK
+          case 2:  //QPSK
 
-          ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-          *jj = *jj + 1;
-          ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
-          *jj = *jj + 1;
+            ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+            *jj = *jj + 1;
+            ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
+            *jj = *jj + 1;
 
-          // normalization for 2 tx antennas
-          ((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);
+            // normalization for 2 tx antennas
+            ((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) {
-            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);
-          }
+            if (frame_parms->nb_antennas_tx == 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);
+            }
 
-          break;
+            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;
 
-          ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
-          ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
+            ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+            ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
-          ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
-          ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
+            ((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) {
-            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];
-          }
+            if (frame_parms->nb_antennas_tx == 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];
+            }
 
-          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;
 
-          ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
-          ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
+            ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+            ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
-          ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
-          ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
+            ((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) {
-            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];
-          }
+            if (frame_parms->nb_antennas_tx == 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];
+            }
 
-          break;
+            break;
 
         }
-      }
-
-      if (mimo_mode == ALAMOUTI) {
-        re++;  // adjacent carriers are taken care of by precoding
+      } else if(mimo_mode == TM7){
         *re_allocated = *re_allocated + 1;
 
-        if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==0) {
-          re++;
-          *re_allocated = *re_allocated + 1;
-        }
-      }
-
-      if (mimo_mode >= TM8) { //TM8,TM9,TM10
+        if (is_not_UEspecRS(lprime,re,frame_parms->Nid_cell%3,frame_parms->Ncp,7)) {
 
-        if (is_not_UEspecRS(first_layer0,re)) {
-          switch (mod_order0) {
-          case 2:  //QPSK
+          switch (mod_order0){
+            case 2:  //QPSK
 
-            //    printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-            for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
-              ((int16_t*)&txdataF[layer][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
+              ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
               *jj = *jj + 1;
-              ((int16_t*)&txdataF[layer][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
+              ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
               *jj = *jj + 1;
-            }
 
-            break;
+              //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
+              //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[1]);
+              for (aa=0; aa<nb_antennas_tx_phy; aa++) {
+                ((int16_t*)&txdataF[aa][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((uint16_t*)&beamforming_weights[re][aa])[0])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[0] +=-(int16_t)((((int16_t*)&tmp_sample1)[1]*((uint16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((uint16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*((uint16_t*)&beamforming_weights[re][aa])[0])>>15);
+               /* ((int16_t*)&txdataF[aa][tti_offset])[0] = ((int16_t*)&tmp_sample1)[0];
+                ((int16_t*)&txdataF[aa][tti_offset])[1] = ((int16_t*)&tmp_sample1)[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
-            if (is_not_UEspecRS(0/*layer (FIXME uninitialized!)*/,re)) {
               qam16_table_offset_re = 0;
               qam16_table_offset_im = 0;
 
               if (x0[*jj] == 1)
                 qam16_table_offset_re+=2;
 
-              *jj = *jj + 1;
+              *jj=*jj+1;
 
               if (x0[*jj] == 1)
                 qam16_table_offset_im+=2;
 
-              *jj = *jj + 1;
+              *jj=*jj+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;
 
-              *jj = *jj + 1;
+              *jj=*jj+1;
+
+              ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
+              ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
 
-              for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
-                ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam16_table_offset_re];
-                ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam16_table_offset_im];
+              for (aa=0; aa<nb_antennas_tx_phy; aa++) {
+                ((int16_t*)&txdataF[aa][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((int16_t*)&beamforming_weights[re][aa])[0])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[0] +=-(int16_t)((((int16_t*)&tmp_sample1)[1]*((int16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((int16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*((int16_t*)&beamforming_weights[re][aa])[0])>>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 (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
-              ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam64_table_offset_re];
-              ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam64_table_offset_im];
-            }
+              ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
+              ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
 
-            break;
+              for (aa=0; aa<nb_antennas_tx_phy; aa++) {
+                ((int16_t*)&txdataF[aa][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((int16_t*)&beamforming_weights[re][aa])[0])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[0] +=-(int16_t)((((int16_t*)&tmp_sample1)[1]*((int16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((int16_t*)&beamforming_weights[re][aa])[1])>>15);
+                ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*((int16_t*)&beamforming_weights[re][aa])[0])>>15);
+              }
+
+              break;
+
+          }
+        } else{
+          //precoding UE spec RS
+          //printf("precoding UE spec RS\n");
+
+          for (aa=0; aa<nb_antennas_tx_phy; aa++) {
+            mprime_dword     = mprime2>>4;
+            mprime_qpsk_symb = mprime2&0xf;
+
+            tmp_sample1 = qpsk[(phy_vars_eNB->lte_gold_uespec_port5_table[0][Ns][lprime][mprime_dword]>>(2*mprime_qpsk_symb))&3];
+            //printf("tmp_sample1=%d+i%d\n",((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[1]);
+            //printf("beamforing_weights[%d][%d]=%d+i%d\n",re,aa,((int16_t*)&beamforming_weights[re][aa])[0],((int16_t*)&beamforming_weights[re][aa])[1]);
+
+            ((int16_t*)&txdataF[aa][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((uint16_t*)&beamforming_weights[re][aa])[0])>>15);
+            ((int16_t*)&txdataF[aa][tti_offset])[0] +=-(int16_t)((((int16_t*)&tmp_sample1)[1]*((uint16_t*)&beamforming_weights[re][aa])[1])>>15);
+            ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[0]*((uint16_t*)&beamforming_weights[re][aa])[1])>>15);
+            ((int16_t*)&txdataF[aa][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*((uint16_t*)&beamforming_weights[re][aa])[0])>>15);
+
+            // ((int16_t*)&txdataF[aa][tti_offset])[0] = 0xffff;
+            // ((int16_t*)&txdataF[aa][tti_offset])[1] = 0xffff;
 
+            mprime2 = mprime2++;
+            //printf("**txdataF[%d][%d]= %d+i%d\n ",aa,tti_offset,((int16_t*)&txdataF[aa][tti_offset])[0],((int16_t*)&txdataF[aa][tti_offset])[1]);
           }
+
         }
-      } else if (mimo_mode>=TM9_10) {
+      } else if (mimo_mode == TM8) { //TM8
         msg("allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode);
         return(-1);
       }
+      if (mimo_mode == ALAMOUTI) {
+        re++;  // adjacent carriers are taken care of by precoding
+        *re_allocated = *re_allocated + 1;
+
+        if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==0) {
+          re++;
+          *re_allocated = *re_allocated + 1;
+        }
+      }
+
     }
 
 
   }
 
-  return(0);
+return(0);
 }
 
 int allocate_REs_in_RB_MCH(mod_sym_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;
@@ -1033,99 +1116,99 @@ int allocate_REs_in_RB_MCH(mod_sym_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
+        //      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
 
-      *jj = *jj + 1;
+        *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}
+        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}
 
-      *jj = *jj + 1;
+    *jj = *jj + 1;
 
-      //  printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
-      break;
+    //  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);
-      }
+    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);
+    }
 
-      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);
-      }
+    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);
+    }
 
-      break;
+    break;
 
     }
   }
@@ -1142,50 +1225,52 @@ 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;
   }
 }
 
 
-int dlsch_modulation(mod_sym_t **txdataF,
+int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
+                     mod_sym_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_eNB_DLSCH_t *dlsch1,
+                     int32_t **beamforming_weights)
 {
+  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
 
   uint8_t nsymb;
   uint8_t harq_pid = dlsch0->current_harq_pid;
@@ -1195,7 +1280,7 @@ int dlsch_modulation(mod_sym_t **txdataF,
   uint16_t l,rb,re_offset;
   uint32_t rb_alloc_ind;
   uint32_t *rb_alloc = dlsch0_harq->rb_alloc;
-  uint8_t pilots=0;
+  uint8_t pilots=0,ue_spec_rs=0;
   uint8_t skip_dc,skip_half;
   uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
   uint8_t mod_order1 = 0;
@@ -1203,6 +1288,11 @@ int dlsch_modulation(mod_sym_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,*qam_table_s1;
+  MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode;
+  uint8_t beamforming_mode = 0;
+  int32_t **beamforming_weights_RB = beamforming_weights;
+  uint8_t lprime, mprime=0,Ns;
+
 #ifdef DEBUG_DLSCH_MODULATION
   uint8_t Nl0 = dlsch0_harq->Nl;
   uint8_t Nl1;
@@ -1224,7 +1314,7 @@ int dlsch_modulation(mod_sym_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);
     }
@@ -1281,6 +1371,35 @@ int dlsch_modulation(mod_sym_t **txdataF,
         pilots=0;
     }
 
+    if(mimo_mode==TM7){ //36.211 V8.6.0 2009-03
+      beamforming_mode = 7;
+      mprime = 0;
+      if (frame_parms->Ncp==0) { // normal prefix
+        if ((l==6)||(l==12))
+          lprime=2;   // pilots in nushift+3, nushift+9
+        else if ((l==3)||(l==9))
+          lprime=1;   // pilots in nushift, nushift+6
+        else
+          lprime=0;
+      } else {
+        if ((l==7))
+          lprime=2;
+        else if ((l==4)||(l==10))
+          lprime=1;
+        else
+          lprime=0;
+      }
+    }else if(mimo_mode==TM8){
+      beamforming_mode = 8;
+    }else if(mimo_mode==TM9_10){
+      beamforming_mode = 9;
+    }
+  
+    if(l<=(nsymb>>2))
+      Ns=0;
+    else
+      Ns=1;
+
     re_offset = frame_parms->first_carrier_offset;
     symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
 
@@ -1392,7 +1511,7 @@ int dlsch_modulation(mod_sym_t **txdataF,
         if (frame_parms->frame_type == TDD) { // TDD
           //SSS
           if (((subframe_offset==0)||
-               (subframe_offset==5)) &&
+                (subframe_offset==5)) &&
               (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
               (rb<((frame_parms->N_RB_DL>>1)+3)) &&
               (l==nsymb-1) ) {
@@ -1401,7 +1520,7 @@ int dlsch_modulation(mod_sym_t **txdataF,
 
           //PSS
           if (((subframe_offset==1)||
-               (subframe_offset==6)) &&
+                (subframe_offset==6)) &&
               (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
               (rb<((frame_parms->N_RB_DL>>1)+3)) &&
               (l==2) ) {
@@ -1448,7 +1567,7 @@ int dlsch_modulation(mod_sym_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_in_RB(frame_parms,
+        allocate_REs_in_RB(phy_vars_eNB,
                            txdataF,
                            &jj,
                            &jj2,
@@ -1463,23 +1582,36 @@ int dlsch_modulation(mod_sym_t **txdataF,
                            qam_table_s1,
                            &re_allocated,
                            skip_dc,
-                           skip_half);
+                           skip_half,
+                           lprime,
+                           mprime,
+                           Ns,
+                           beamforming_weights_RB);
+
+        if(mimo_mode==TM7){
+           if(frame_parms->Ncp==0&&(l==3||l==6||l==9||l==12))
+             mprime +=3;
+        else if(frame_parms->Ncp==1&&(l==4||l==7||l==10))
+             mprime +=4;
+        }
 
       }
 
       re_offset+=12; // go to next RB
+      beamforming_weights_RB +=12;
 
 
       // check if we crossed the symbol boundary and skip DC
       if (re_offset >= frame_parms->ofdm_symbol_size) {
-        if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
-          re_offset=1;
-        else
-          re_offset=7;  // odd number of RBs
-      }
-    }
+              if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
+                re_offset=1;
+              else
+                re_offset=7;  // odd number of RBs
+          }
+              beamforming_weights_RB = beamforming_weights;
+               }
 
-  }
+      }
 
 
 
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
index 6e253c3b632133586db76bc814235455bfbbfc10..0c846f3aa7ca1bc183f1e7db4760176458710260 100644
--- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
+++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c
@@ -333,11 +333,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) {
@@ -348,9 +345,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
@@ -358,7 +357,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/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c
new file mode 100644
index 0000000000000000000000000000000000000000..310204eea98c8c2e826609385cdfbfd88952c713
--- /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,
+                     mod_sym_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<phy_vars_eNB->nb_antennas_tx_phy;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,
+                         mod_sym_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 3082bff917ab94fb4eca9ee3bed805714246aeb2..422f6074648f4f5df8e1c1a9432564cdfac4d517 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -304,7 +304,7 @@ void generate_mch(PHY_VARS_eNB *phy_vars_eNB,int sched_subframe,uint8_t *a,int a
               phy_vars_eNB->lte_frame_parms.N_RB_DL,
               phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->rb_alloc,
               get_Qm(phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->mcs),1,
-              2,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);
+              2,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,0);
 
     generate_mbsfn_pilot(phy_vars_eNB,
                          phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
@@ -319,8 +319,7 @@ void generate_mch(PHY_VARS_eNB *phy_vars_eNB,int sched_subframe,uint8_t *a,int a
                        subframe,
                        &phy_vars_eNB->dlsch_rate_matching_stats,
                        &phy_vars_eNB->dlsch_turbo_encoding_stats,
-                       &phy_vars_eNB->dlsch_interleaving_stats
-                      )<0)
+                       &phy_vars_eNB->dlsch_interleaving_stats)<0)
       mac_xface->macphy_exit("problem in dlsch_encoding");
 
     dlsch_scrambling(&phy_vars_eNB->lte_frame_parms,1,phy_vars_eNB->dlsch_eNB_MCH,G,0,subframe<<1);
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 5fe7518004db7f6ed4546d4373a3374676d25376..58a1177a37a6ca67579d7d57475c599d61f36d43 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/******************************************************************************
     OpenAirInterface
     Copyright(c) 1999 - 2014 Eurecom
 
@@ -157,11 +157,14 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
     \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 beamforming_weights_rb Beamforming weights applied on each antenna element and each carrier in case of TM7-10
     \param use2ndpilots Set to use the pilots from antenna port 1 for PDSCH
     \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,
                            mod_sym_t **txdataF,
                            uint32_t *jj,
                            uint32_t *jj2,
@@ -176,8 +179,11 @@ int32_t allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
                            int16_t *qam_table_s1,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
-                           uint8_t skip_half);
-
+                           uint8_t skip_half,
+                  			   uint8_t lprime,
+			                     uint8_t mprime,
+		                   	   uint8_t Ns,
+			                     int32_t **beamforming_weights);
 
 /** \fn int32_t dlsch_modulation(mod_sym_t **txdataF,
     int16_t amp,
@@ -194,15 +200,17 @@ 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
-
+    @param nb_antennas_tx_phy Physical antenna elements which can be different with antenna port number, especially in beamforming case
+    @param beamforming_weights Beamforming weights applied on each antenna element and each carrier in case of TM7-10
 */
-int32_t dlsch_modulation(mod_sym_t **txdataF,
+int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
+                         mod_sym_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);
+                         LTE_eNB_DLSCH_t *dlsch1,
+                   			 int32_t **beamforming_weights);
 /*
   \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH.
   @param txdataF Table of pointers for frequency-domain TX signals
@@ -295,6 +303,13 @@ int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
                              int16_t amp,
                              uint16_t subframe);
 
+void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
+                             uint8_t UE_id,
+                             mod_sym_t **txdataF,
+                             int16_t amp,
+                             uint16_t Ntti,
+		             uint8_t beamforming_mode);
+
 int32_t generate_pss(mod_sym_t **txdataF,
                      int16_t amp,
                      LTE_DL_FRAME_PARMS *frame_parms,
@@ -680,6 +695,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,
@@ -688,7 +704,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
@@ -904,6 +921,16 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
                                 uint32_t high_speed_flag,
                                 LTE_DL_FRAME_PARMS *frame_parms);
 
+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
@@ -1249,7 +1276,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);
@@ -1551,7 +1578,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);
 
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 670a852b6753a2bc341cf5374b05856d7f200f2d..5bbea87c887ce87e58a3fc9661a7ae134bc0d0a4 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -241,6 +241,15 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
 
       }
     }
+  // printf("slot_fep:transmission_mode[%d] = %d\n", eNB_id, phy_vars_ue->transmission_mode[eNB_id]);
+  if(phy_vars_ue->transmission_mode[eNB_id] == 7)
+    if(frame_parms->Ncp==0 && (symbol==3) || (symbol==6) || (symbol==9) || (symbol==12))
+      lte_dl_bf_channel_estimation(phy_vars_ue,eNB_id,0,Ns,5,symbol);
+    else if(frame_parms->Ncp==1 && (symbol==4) || (symbol==7) || (symbol==10))
+      msg("slot_fep(slot_fep.c):channel estimation not supported yet for TM7 extented CP.\n");
+ else if(phy_vars_ue->transmission_mode[eNB_id] > 7)
+   msg("slot_fep(slot_fep.c):transmission mode not supported yet.\n");
+
   }
 
 #ifdef DEBUG_FEP
diff --git a/openair1/PHY/Makefile.inc b/openair1/PHY/Makefile.inc
index 2105e1209d647cea7c6f173a886eb5c97913fb61..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
@@ -69,7 +71,7 @@ PHY_OBJS += $(TOP_DIR)/PHY/INIT/lte_init.o
 PHY_OBJS += $(TOP_DIR)/PHY/INIT/lte_parms.o
 PHY_OBJS += $(TOP_DIR)/PHY/INIT/init_top.o
 PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/file_output.o
-PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/fft.o
+#PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/fft.o
 PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/lte_dfts.o
 PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/log2_approx.o
 PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/cmult_sv.o
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 7a46d9c44430a958dc8b0b7d517cddce0013006d..80c6b4ef010af678a2ce6eee22e5024f221960f6 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -220,6 +220,7 @@ typedef struct PHY_VARS_eNB_s {
   eNB_proc_t           proc[NUM_ENB_THREADS];
   uint8_t              local_flag;
   uint32_t             rx_total_gain_eNB_dB;
+  uint8_t 	       nb_antennas_tx_phy;
   LTE_DL_FRAME_PARMS   lte_frame_parms;
   PHY_MEASUREMENTS_eNB PHY_measurements_eNB[NUMBER_OF_eNB_SECTORS_MAX]; /// Measurement variables
   LTE_eNB_COMMON       lte_eNB_common_vars;
@@ -241,6 +242,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][2][21];
+
   /// UE-specific reference symbols (p=7...14), TM 8/9/10
   uint32_t         lte_gold_uespec_table[2][20][2][21];
 
@@ -505,8 +509,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][2][21];
+
   /// 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 47c32d87c83984a63374930f8d4694db62d11bbb..a7574575a374787f7c902c443498d2285a3b6262 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -587,8 +587,9 @@ 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 struct {
@@ -784,6 +785,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[
@@ -797,6 +802,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[
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 3828a9be72454a8f632c0a43e64373154be2161a..32ff858996ec71a84234aa1c66c1438c1fdcaf0a 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -2203,7 +2203,9 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
                              phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->rb_alloc,
                              get_Qm(phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->mcs),
                              1,
-                             num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
+                             num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,
+			     subframe,
+			     (phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7?0:phy_vars_eNB->transmission_mode[(uint8_t)UE_id])),
                        0,
                        subframe<<1);
 
@@ -2211,13 +2213,14 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
 
       start_meas(&phy_vars_eNB->dlsch_modulation_stats);
       //      for (sect_id=0;sect_id<number_of_cards;sect_id++)
-      re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
+      re_allocated = dlsch_modulation(&phy_vars_eNB,
+                                      phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                       AMP,
                                       subframe,
-                                      &phy_vars_eNB->lte_frame_parms,
                                       num_pdcch_symbols,
                                       phy_vars_eNB->dlsch_eNB_SI,
-                                      (LTE_eNB_DLSCH_t *)NULL);
+                                      (LTE_eNB_DLSCH_t *)NULL,
+				      (int32_t **)NULL);
       stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
     }
 
@@ -2338,17 +2341,22 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
                                phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->rb_alloc,
                                get_Qm(phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->mcs),
                                1,
-                               num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
+                               num_pdcch_symbols,
+			       phy_vars_eNB->proc[sched_subframe].frame_tx,
+			       subframe,
+			       (phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7?0:phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7)),
                          0,
                          subframe<<1);
         //  for (sect_id=0;sect_id<number_of_cards;sect_id++)
-        re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
+        re_allocated = dlsch_modulation(phy_vars_eNB,
+					phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                         AMP,
                                         subframe,
-                                        &phy_vars_eNB->lte_frame_parms,
                                         num_pdcch_symbols,
                                         phy_vars_eNB->dlsch_eNB_ra,
-                                        (LTE_eNB_DLSCH_t *)NULL);
+                                        (LTE_eNB_DLSCH_t *)NULL,
+					(int32_t **)NULL);
+
       }
 
 #ifdef PHY_ABSTRACTION
@@ -2394,7 +2402,10 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
                   phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
                   get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
                   phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
-                  num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
+                  num_pdcch_symbols,
+		  phy_vars_eNB->proc[sched_subframe].frame_tx,
+		  subframe,
+	          (phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7?0:phy_vars_eNB->transmission_mode[(uint8_t)UE_id])),
             phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
             phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
             pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
@@ -2413,7 +2424,10 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
         		phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
         		get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
         		phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
-        		num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
+        		num_pdcch_symbols,
+			phy_vars_eNB->proc[sched_subframe].frame_tx,
+			subframe,
+			(phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7?0:phy_vars_eNB->transmission_mode[(uint8_t)UE_id]<7)),
         phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb,
         phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs,
         pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc),
@@ -2495,7 +2509,10 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
                                phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc,
                                get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs),
                                phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl,
-                               num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe),
+                               num_pdcch_symbols,
+                               phy_vars_eNB->proc[sched_subframe].frame_tx,
+                               subframe,
+			       phy_vars_eNB->transmission_mode[(uint8_t)UE_id]),
                          0,
                          subframe<<1);
         stop_meas(&phy_vars_eNB->dlsch_scrambling_stats);
@@ -2510,13 +2527,14 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
         //      if (UE_id == 1)
         //      LOG_I(PHY,"[MYEMOS] MCS_i %d\n", phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs);
 
-        re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
+        re_allocated = dlsch_modulation(phy_vars_eNB,
+                                        phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
                                         AMP,
                                         subframe,
-                                        &phy_vars_eNB->lte_frame_parms,
                                         num_pdcch_symbols,
                                         phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0],
-                                        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][1]);
+                                        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][1],
+					(int32_t **)NULL);
 
         stop_meas(&phy_vars_eNB->dlsch_modulation_stats);
       }
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 6394c7dff6fd451a82364cd27c93b5ffc857f9ed..7efee84b842ecc53f73fa7ecc9b6c6754bcdb98c 100755
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -138,7 +138,9 @@ void dump_dlsch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint8_t
                                   get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs),
                                   phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl,
                                   phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  phy_vars_ue->frame_rx,subframe);
+                                  phy_vars_ue->frame_rx,
+				  subframe,
+				  phy_vars_ue->transmission_mode[eNB_id]);
 
   write_output("rxsigF0.m","rxsF0", phy_vars_ue->lte_ue_common_vars.rxdataF[0],2*nsymb*phy_vars_ue->lte_frame_parms.ofdm_symbol_size,2,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", phy_vars_ue->lte_ue_pdsch_vars[0]->rxdataF_ext[0],2*nsymb*phy_vars_ue->lte_frame_parms.ofdm_symbol_size,1,1);
@@ -167,7 +169,9 @@ void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe)
                                   get_Qm(phy_vars_ue->dlsch_ue_SI[eNB_id]->harq_processes[0]->mcs),
                                   1,
                                   phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  phy_vars_ue->frame_rx,subframe);
+                                  phy_vars_ue->frame_rx,
+				  subframe,
+			          phy_vars_ue->transmission_mode[eNB_id]);
   LOG_D(PHY,"[UE %d] Dumping dlsch_SI : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         phy_vars_ue->Mod_id,
         phy_vars_ue->dlsch_ue_SI[eNB_id]->harq_processes[0]->nb_rb,
@@ -221,7 +225,9 @@ void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe)
                                   get_Qm(phy_vars_ue->dlsch_ue_ra[eNB_id]->harq_processes[0]->mcs),
                                   1,
                                   phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  phy_vars_ue->frame_rx,subframe);
+                                  phy_vars_ue->frame_rx,
+				  subframe,
+				  phy_vars_ue->transmission_mode[eNB_id]);
   LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         phy_vars_ue->Mod_id,
         phy_vars_ue->dlsch_ue_ra[eNB_id]->harq_processes[0]->nb_rb,
@@ -2625,7 +2631,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstrac
                 get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs),
                 phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl,
                 phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
-                frame_rx,subframe_prev);
+                frame_rx,
+		subframe_prev,
+	        phy_vars_ue->transmission_mode[eNB_id]);
             start_meas(&phy_vars_ue->dlsch_unscrambling_stats);
             dlsch_unscrambling(&phy_vars_ue->lte_frame_parms,
                                0,
@@ -2782,7 +2790,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstrac
                     phy_vars_ue->dlsch_ue_SI[eNB_id]->harq_processes[0]->rb_alloc,
                     get_Qm(phy_vars_ue->dlsch_ue_SI[eNB_id]->harq_processes[0]->mcs),1,
                     phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
-                    frame_rx,subframe_prev);
+                    frame_rx,
+		    subframe_prev,
+		    phy_vars_ue->transmission_mode[eNB_id]);
 
 #ifdef DEBUG_PHY_PROC
             LOG_D(PHY,"Decoding DLSCH_SI : rb_alloc %x : nb_rb %d G %d TBS %d, num_pdcch_sym %d\n",phy_vars_ue->dlsch_ue_SI[eNB_id]->harq_processes[0]->rb_alloc[0],
@@ -2926,7 +2936,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstrac
               get_Qm(phy_vars_ue->dlsch_ue_ra[eNB_id]->harq_processes[0]->mcs),1,
               phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
               frame_rx,
-              subframe_prev);
+              subframe_prev,
+	      phy_vars_ue->transmission_mode[eNB_id]);
 
 #ifdef DEBUG_PHY_PROC
           LOG_D(PHY,"[UE] decoding RA (subframe %d): G %d,rnti %x\n" ,subframe_prev,
@@ -3301,7 +3312,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstrac
               get_Qm(phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->mcs),
               1,
               2,
-              (subframe_rx==9?-1:0)+frame_rx,subframe_rx);
+              (subframe_rx==9?-1:0)+frame_rx,
+	      subframe_rx,
+	      phy_vars_ue->transmission_mode[eNB_id]);
 
           dlsch_unscrambling(&phy_vars_ue->lte_frame_parms,1,phy_vars_ue->dlsch_ue_MCH[0],
                              phy_vars_ue->dlsch_ue_MCH[0]->harq_processes[0]->G,
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 969e485b2376132bdb11d6b66a49ab7081c76274..7a3b3bba1d800e395e4d798c7c4f2bc952d1e34b 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -1,5 +1,5 @@
-/*******************************************************************************
-    OpenAirInterface
+/******************************************************************************
+    ipenAirInterface
     Copyright(c) 1999 - 2014 Eurecom
 
     OpenAirInterface is free software: you can redistribute it and/or modify
@@ -107,8 +107,7 @@ void handler(int sig)
   exit(1);
 }
 
-void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmission_mode,uint8_t extended_prefix_flag,uint8_t fdd_flag, uint16_t Nid_cell,uint8_t tdd_config,uint8_t N_RB_DL,
-                    uint8_t osf,uint32_t perfect_ce)
+void lte_param_init(unsigned char N_tx, unsigned char N_tx_phy, unsigned char N_rx,unsigned char transmission_mode,uint8_t extended_prefix_flag,uint8_t fdd_flag, uint16_t Nid_cell,uint8_t tdd_config,uint8_t N_RB_DL, uint8_t osf,uint32_t perfect_ce)
 {
 
   LTE_DL_FRAME_PARMS *lte_frame_parms;
@@ -123,7 +122,8 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi
 
   srand(0);
   randominit(0);
-  set_taus_seed(0);
+  //set_taus_seed(0);
+  set_taus_seed(1234);
 
   lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms);
 
@@ -142,7 +142,8 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi
   //  lte_frame_parms->Bsrs = 0;
   //  lte_frame_parms->kTC = 0;44
   //  lte_frame_parms->n_RRC = 0;
-  lte_frame_parms->mode1_flag = (transmission_mode == 1)? 1 : 0;
+  //lte_frame_parms->mode1_flag = (transmission_mode == 1)? 1 : 0;
+  lte_frame_parms->mode1_flag = (transmission_mode == 1 || transmission_mode ==7)? 1 : 0;
 
   init_frame_parms(lte_frame_parms,osf);
 
@@ -154,6 +155,11 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi
   PHY_vars_UE->lte_frame_parms = *lte_frame_parms;
   PHY_vars_eNB->lte_frame_parms = *lte_frame_parms;
 
+  PHY_vars_eNB->transmission_mode[0] = transmission_mode;
+  PHY_vars_UE->transmission_mode[0] = transmission_mode;
+  //printf("lte_param_init: transmission mode = %d\n",PHY_vars_eNB->transmission_mode[0]);
+  PHY_vars_eNB->nb_antennas_tx_phy = N_tx_phy;
+
   phy_init_lte_top(lte_frame_parms);
   dump_frame_parms(lte_frame_parms);
 
@@ -166,12 +172,14 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi
 
   phy_init_lte_ue(PHY_vars_UE,1,0);
   phy_init_lte_eNB(PHY_vars_eNB,0,0,0);
+  
 
   generate_pcfich_reg_mapping(&PHY_vars_UE->lte_frame_parms);
   generate_phich_reg_mapping(&PHY_vars_UE->lte_frame_parms);
 
   // DL power control init
-  if (transmission_mode == 1) {
+  //if (transmission_mode == 1) {
+  if (transmission_mode == 1 || transmission_mode ==7) {
     PHY_vars_eNB->pdsch_config_dedicated->p_a  = dB0; // 4 = 0dB
     ((PHY_vars_eNB->lte_frame_parms).pdsch_config_common).p_b = 0;
     PHY_vars_UE->pdsch_config_dedicated->p_a  = dB0; // 4 = 0dB
@@ -200,7 +208,7 @@ uint64_t DLSCH_alloc_pdu_1[2];
 #define CCCH_RB_ALLOC computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,0,2)
 //#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
 //#define DLSCH_RB_ALLOC 0x0001
-void do_OFDM_mod_l(mod_sym_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
+void do_OFDM_mod_l(mod_sym_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms, uint8_t nb_antennas_tx_phy)
 {
 
   int aa, slot_offset, slot_offset_F;
@@ -208,7 +216,7 @@ void do_OFDM_mod_l(mod_sym_t **txdataF, int32_t **txdata, uint16_t next_slot, LT
   slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
   slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
 
-  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+  for (aa=0; aa<nb_antennas_tx_phy; aa++) {
     //    printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
 
     if (frame_parms->Ncp == 1)
@@ -234,7 +242,7 @@ int main(int argc, char **argv)
 {
 
   char c;
-  int k,i,aa,aarx,aatx;
+  int k,i,aa,aarx,aatx,re;
 
   int s,Kr,Kr_bytes;
 
@@ -246,8 +254,9 @@ int main(int argc, char **argv)
   double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
   double iqim=0.0;
 
-  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=1,n_rx=2,n_tx_phy=1;
   uint16_t Nid_cell=0;
+  int32_t **beamforming_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;
@@ -285,7 +294,7 @@ int main(int argc, char **argv)
   char input_trch_val[16];
   double channelx,channely;
 
-  //  unsigned char pbch_pdu[6];
+  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;
@@ -525,13 +534,20 @@ int main(int argc, char **argv)
           (transmission_mode!=2) &&
           (transmission_mode!=3) &&
           (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) {
+      if (transmission_mode>1 && transmission_mode<7) {
         n_tx = 2;
+        n_tx_phy = n_tx;
+      }
+      if (transmission_mode>=7){
+        n_tx = 1;
+        n_tx_phy = 1;
+        n_rx = 1;
       }
 
       break;
@@ -539,9 +555,13 @@ int main(int argc, char **argv)
     case 'y':
       n_tx=atoi(optarg);
 
-      if ((n_tx==0) || (n_tx>2)) {
-        msg("Unsupported number of tx antennas %d\n",n_tx);
-        exit(-1);
+      if (transmission_mode<7){
+         n_tx_phy = n_tx; 
+
+         if ((n_tx==0) || ((n_tx>2))) {
+           msg("Unsupported number of tx antennas %d\n",n_tx);
+           exit(-1);
+         }
       }
 
       break;
@@ -633,7 +653,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");
@@ -648,7 +668,7 @@ 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("-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");
@@ -697,8 +717,8 @@ int main(int argc, char **argv)
 
   NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
 
-  if ((transmission_mode > 1) && (n_tx != 2))
-    printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode);
+  if ((transmission_mode > 1) && (n_tx_phy == 1))
+    printf("n_tx_phy must be >1 for transmission_mode %d\n",transmission_mode);
 
 #ifdef XFORMS
   fl_initialize (&argc, argv, NULL, 0, 0);
@@ -720,7 +740,19 @@ int main(int argc, char **argv)
     printf("dual_stream_UE=%d\n", dual_stream_UE);
   }
 
-  lte_param_init(n_tx,n_rx,transmission_mode,extended_prefix_flag,fdd_flag,Nid_cell,tdd_config,N_RB_DL,osf,perfect_ce);
+
+  lte_param_init(n_tx,n_tx_phy,n_rx,transmission_mode,extended_prefix_flag,fdd_flag,Nid_cell,tdd_config,N_RB_DL,osf,perfect_ce);
+
+  if (transmission_mode==7){
+    lte_gold_ue_spec_port5(PHY_vars_eNB->lte_gold_uespec_port5_table[0],Nid_cell,n_rnti);
+    lte_gold_ue_spec_port5(PHY_vars_UE->lte_gold_uespec_port5_table,Nid_cell,n_rnti);
+    beamforming_weights = (int32_t **)malloc(12*N_RB_DL*sizeof(int32_t*));
+    for(re=0;re<12*N_RB_DL;re++){
+      beamforming_weights[re]=(int32_t *)malloc(n_tx_phy*sizeof(int32_t));
+      for(aa=0;aa<n_tx_phy;aa++)
+	beamforming_weights[re][aa] = 0x00008000;
+    }
+  }
 
   eNB_id_i = PHY_vars_UE->n_connected_eNB;
 
@@ -728,7 +760,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);
@@ -745,8 +777,8 @@ int main(int argc, char **argv)
 
   frame_parms = &PHY_vars_eNB->lte_frame_parms;
 
-  s_re = malloc(2*sizeof(double*));
-  s_im = malloc(2*sizeof(double*));
+  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*));
@@ -883,9 +915,12 @@ int main(int argc, char **argv)
     }
   */
 
-  for (i=0; i<2; i++) {
+  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));
@@ -1028,6 +1063,7 @@ int main(int argc, char **argv)
       switch(transmission_mode) {
       case 1:
       case 2:
+      case 7:
         if (common_flag == 0) {
 
           if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) {
@@ -1157,6 +1193,9 @@ int main(int argc, char **argv)
                                              P_RNTI,
                                              PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single);
 
+          if(transmission_mode==7)
+	    PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mimo_mode = TM7; //Xiwen: to check about harq_pid
+
           num_dci++;
           num_ue_spec_dci++;
         } else {
@@ -1300,7 +1339,7 @@ int main(int argc, char **argv)
           num_dci++;
 
         }
-
+       
         break;
 
       case 3:
@@ -2027,13 +2066,15 @@ int main(int argc, char **argv)
                                   get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs),
                                   PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->Nl,
                                   num_pdcch_symbols,
-                                  0,subframe);
+                                  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;
-  PHY_vars_UE->high_speed_flag = 1;
+  PHY_vars_UE->high_speed_flag = 0; //1
   PHY_vars_UE->ch_est_alpha=0;
 
   for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
@@ -2118,10 +2159,10 @@ int main(int argc, char **argv)
         ret = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1;
 
         while ((round < num_rounds) && (ret > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) {
-          //    printf("Trial %d, round %d\n",trials,round);
+              printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
-          if(transmission_mode>=5)
+          if(transmission_mode>=5&&transmission_mode<7)
             pmi_feedback=1;
           else
             pmi_feedback=0;
@@ -2136,7 +2177,7 @@ int main(int argc, char **argv)
 
 PMI_FEEDBACK:
 
-          //  printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
+          printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
           for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
             memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t));
           }
@@ -2158,6 +2199,7 @@ PMI_FEEDBACK:
                   switch (transmission_mode) {
                   case 1:
                   case 2:
+                  case 7:
                     switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) {
                     case 6:
                       ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
@@ -2228,11 +2270,13 @@ PMI_FEEDBACK:
                     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 (PHY_vars_eNB->lte_frame_parms.N_RB_DL) {
                     case 6:
                       ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
@@ -2260,7 +2304,6 @@ PMI_FEEDBACK:
                     }
 
                     break;
-
                   case 3:
                     switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) {
                     case 6:
@@ -2315,6 +2358,7 @@ PMI_FEEDBACK:
                   switch (transmission_mode) {
                   case 1:
                   case 2:
+                  case 7:
                     switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) {
                     case 6:
                       ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
@@ -2422,6 +2466,7 @@ PMI_FEEDBACK:
                   switch (transmission_mode) {
                   case 1:
                   case 2:
+                  case 7:
                     switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) {
                     case 6:
                       ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
@@ -2551,7 +2596,9 @@ PMI_FEEDBACK:
                                                 get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs),
                                                 PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Nl,
                                                 num_pdcch_symbols,
-                                                0,subframe);
+                                                0,
+						subframe,
+						(transmission_mode<7?0:transmission_mode));
 
 #ifdef TBS_FIX   // This is for MESH operation!!!
                 tbs = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][cw]->nb_rb-1]/4;
@@ -2596,8 +2643,7 @@ PMI_FEEDBACK:
                                    0,subframe,
                                    &PHY_vars_eNB->dlsch_rate_matching_stats,
                                    &PHY_vars_eNB->dlsch_turbo_encoding_stats,
-                                   &PHY_vars_eNB->dlsch_interleaving_stats
-                                  )<0)
+                                   &PHY_vars_eNB->dlsch_interleaving_stats)<0)
                   exit(-1);
 
                 /*
@@ -2640,15 +2686,16 @@ PMI_FEEDBACK:
                   }
                 }
               }
-
+              
               start_meas(&PHY_vars_eNB->dlsch_modulation_stats);
-              re_allocated = dlsch_modulation(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
+              re_allocated = dlsch_modulation(PHY_vars_eNB,
+					      PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
                                               AMP,
                                               subframe,
-                                              &PHY_vars_eNB->lte_frame_parms,
                                               num_pdcch_symbols,
                                               PHY_vars_eNB->dlsch_eNB[k][0],
-                                              PHY_vars_eNB->dlsch_eNB[k][1]);
+                                              PHY_vars_eNB->dlsch_eNB[k][1],
+					      beamforming_weights);
               stop_meas(&PHY_vars_eNB->dlsch_modulation_stats);
               /*
               if (trials==0 && round==0)
@@ -2661,18 +2708,149 @@ PMI_FEEDBACK:
                             PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
                             AMP,
                             LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
+/*
+	    //PSS/SSS
+            if (PHY_vars_eNB->lte_frame_parms.frame_type == FDD) {
+              generate_pss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           0);
+              generate_sss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
+                           0);
+              generate_pss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           10);
+              generate_sss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4,
+                           10);
+	    }
+            else if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) {
+              generate_sss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           1);
+              generate_pss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           2,
+                           2);
+              generate_sss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_frame_parms,
+                           (PHY_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5,
+                           11);
+              generate_pss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                           AMP,
+                           &PHY_vars_eNB->lte_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 (PHY_vars_eNB->lte_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) |
+                            ((PHY_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10);
+
+              switch (PHY_vars_eNB->lte_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(&PHY_vars_eNB->lte_eNB_pbch,
+                          PHY_vars_eNB->lte_eNB_common_vars.txdataF[0],
+                          AMP,
+                          &PHY_vars_eNB->lte_frame_parms,
+                          pbch_pdu,
+                          0&3);
+*/
 
             start_meas(&PHY_vars_eNB->ofdm_mod_stats);
+/*
+	    for(i=0;i<20;i++){
+	      
+              do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
+                            PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id],
+                            i,
+                            &PHY_vars_eNB->lte_frame_parms,
+	   		    PHY_vars_eNB->nb_antennas_tx_phy);
+ 	      } 
 
+*/
             do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
                           PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id],
                           (subframe*2),
-                          &PHY_vars_eNB->lte_frame_parms);
+                          &PHY_vars_eNB->lte_frame_parms,
+			  PHY_vars_eNB->nb_antennas_tx_phy);
 
             do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
                           PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id],
                           (subframe*2)+1,
-                          &PHY_vars_eNB->lte_frame_parms);
+                          &PHY_vars_eNB->lte_frame_parms,
+			  PHY_vars_eNB->nb_antennas_tx_phy);
 
             stop_meas(&PHY_vars_eNB->ofdm_mod_stats);
             stop_meas(&PHY_vars_eNB->phy_proc_tx);
@@ -2680,20 +2858,21 @@ PMI_FEEDBACK:
             do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id],
                           PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id],
                           (subframe*2)+2,
-                          &PHY_vars_eNB->lte_frame_parms);
+                          &PHY_vars_eNB->lte_frame_parms,
+			  PHY_vars_eNB->nb_antennas_tx_phy);
 
             if (n_frames==1) {
               write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
                            nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
 
-              if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)
+              if (PHY_vars_eNB->nb_antennas_tx_phy>1)// to be updated
                 write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
                              nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
-            }
+            } 
 
             tx_lev = 0;
 
-            for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
+            for (aa=0; aa<PHY_vars_eNB->nb_antennas_tx_phy; aa++) {
               tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]
                                       [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti],
                                       PHY_vars_eNB->lte_frame_parms.samples_per_tti);
@@ -2703,9 +2882,8 @@ PMI_FEEDBACK:
 
             if (n_frames==1) {
               printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
-              write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti],
-
-                           PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1);
+              write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti],PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1);
+              // write_output("txsig0.m","txs0",&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][0*PHY_vars_eNB->lte_frame_parms.samples_per_tti],PHY_vars_eNB->lte_frame_parms.samples_per_tti*10,1,1);
             }
           }
 
@@ -2736,7 +2914,7 @@ PMI_FEEDBACK:
 
           //    printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,awgn_flag);
           for (i=0; i<2*frame_parms->samples_per_tti; i++) {
-            for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
+            for (aa=0; aa<PHY_vars_eNB->nb_antennas_tx_phy; aa++) {
               if (awgn_flag == 0) {
                 s_re[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) + (i<<1)]);
                 s_im[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]);
@@ -2745,6 +2923,7 @@ PMI_FEEDBACK:
                   if (aa==0) {
                     r_re[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]);
                     r_im[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_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 *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]);
                     r_im[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]);
@@ -2837,14 +3016,18 @@ PMI_FEEDBACK:
 
           for (i=0; i<2*frame_parms->samples_per_tti; i++) {
             for (aa=0; aa<PHY_vars_eNB->lte_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*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] =
+              // printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
+              /*((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] =
                 (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
               ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_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) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));*/
+              ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i]);
+              ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = (short) (r_im[aa][i] + (iqim*r_re[aa][i])); 
+              //printf("rxdata[%d][%d]=> %d, %d\n",aa,subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti+i,r_re[aa][i],r_im[aa][i]);
             }
           }
 
+
           //    lte_sync_time_init(PHY_vars_eNB->lte_frame_parms,lte_ue_common_vars);
           //    lte_sync_time(lte_ue_common_vars->rxdata, PHY_vars_eNB->lte_frame_parms);
           //    lte_sync_time_free();
@@ -2888,7 +3071,7 @@ PMI_FEEDBACK:
           for (Ns=(2*subframe); Ns<((2*subframe)+3); Ns++) {
             for (l=0; l<pilot2; l++) {
               if (n_frames==1)
-                printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
+              //  printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
 
               /*
               This function implements the OFDM front end processor (FEP).
@@ -2910,6 +3093,7 @@ PMI_FEEDBACK:
                        0,
                        0);
               stop_meas(&PHY_vars_UE->ofdm_demod_stats);
+              //write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (PHY_vars_UE->perfect_ce==1) {
                 if (awgn_flag==0) {
@@ -3045,7 +3229,12 @@ PMI_FEEDBACK:
                                                       get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs),
                                                       PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl,
                                                       PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,
-                                                      0,subframe);
+                                                      0,
+						      subframe,
+						      (transmission_mode<7?0:transmission_mode));
+          	    if (transmission_mode==7 && common_flag==0)
+       	    	      PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->mimo_mode = TM7; 
+
                       /*
                       rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword);
                       rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs);
@@ -3084,6 +3273,7 @@ PMI_FEEDBACK:
                   switch (transmission_mode) {
                   case 1:
                   case 2:
+                  case 7:
                     generate_ue_dlsch_params_from_dci(0,
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
@@ -3094,6 +3284,8 @@ PMI_FEEDBACK:
                                                       SI_RNTI,
                                                       0,
                                                       P_RNTI);
+          	    if(transmission_mode==7 && common_flag==0)
+       	    	      PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->mimo_mode = TM7; 
                     break;
 
                   case 3:
@@ -3210,6 +3402,7 @@ PMI_FEEDBACK:
                   for (m=pilot3;
                        m<PHY_vars_UE->lte_frame_parms.symbols_per_tti;
                        m++) {
+                    //printf("m=%d\n",m);
                     if (rx_pdsch(PHY_vars_UE,
                                  PDSCH,
                                  eNB_id,
@@ -3228,6 +3421,7 @@ PMI_FEEDBACK:
                   stop_meas(&PHY_vars_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);
@@ -3236,7 +3430,9 @@ PMI_FEEDBACK:
                       write_output("ch1.m","ch1",eNB2UE[0]->ch[PHY_vars_eNB->lte_frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
 
                     //common vars
-                    write_output("rxsig0.m","rxs0", &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1);
+                    //write_output("rxsig0.m","rxs0", &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1);
+                    write_output("rxsig0.m","rxs0", &PHY_vars_UE->lte_ue_common_vars.rxdata[0][subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1);
+                    //write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1);
                     write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1);
 
                     if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) {
@@ -3284,7 +3480,7 @@ PMI_FEEDBACK:
           //saving PMI in case of Transmission Mode > 5
 
           if(abstx) {
-            if (trials==0 && round==0 && transmission_mode>=5) {
+            if (trials==0 && round==0 && transmission_mode>=5 && transmission_mode<7) {
               for (iii=0; iii<NB_RB; iii++) {
                 //fprintf(csv_fd, "%d, %d", (PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii]));
                 fprintf(csv_fd,"%x,%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]));
@@ -3301,7 +3497,9 @@ PMI_FEEDBACK:
                                             get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs),
                                             PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->Nl,
                                             num_pdcch_symbols,
-                                            0,subframe);
+                                            0,
+					    subframe,
+					    (transmission_mode<7?0:transmission_mode));
 
             PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
 
@@ -3415,7 +3613,7 @@ PMI_FEEDBACK:
             iter_trials++;
 
             if (n_frames==1) {
-              //if ((n_frames==1) || (SNR>=30)) {
+              //if ((n_frames==1) || (SNR>=30)) 
               printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
 
               for (s=0; s<PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->C; s++) {
@@ -4054,9 +4252,12 @@ PMI_FEEDBACK:
 
   printf("Freeing channel I/O\n");
 
-  for (i=0; i<2; i++) {
+  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]);
   }
diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c
index b17ab4808700252d6c2bf85756244945b209c2ec..51df30a4ec16808b8f6448f2481bd6dec76c6b89 100644
--- a/openair1/SIMULATION/LTE_PHY/mbmssim.c
+++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c
@@ -551,7 +551,7 @@ int main(int argc, char **argv)
           PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->rb_alloc,
           get_Qm(PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->mcs),
           1,2,
-          PHY_vars_UE->frame_tx,subframe);
+          PHY_vars_UE->frame_tx,subframe,0);
       dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms,1,PHY_vars_UE->dlsch_ue_MCH[0],
                          PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G,
                          PHY_vars_UE->lte_ue_pdsch_vars_MCH[0]->llr[0],0,subframe<<1);
diff --git a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
index ad33d26123f4f68463c8c2008402ac89055db157..0ebf4a0a87fa7d099a1786a90f99a2e6c3740037 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
+++ b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/txsig.m
@@ -6,7 +6,7 @@ rxgain=0;
 txgain=0;
 eNB_flag = 0;
 card = 0;
-active_rf = [1 1 1 1];
+active_rf = [1 0 0 0];
 autocal = [1 1 1 1];
 resampling_factor = [2 2 2 2];
 limeparms;
@@ -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')