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')