From 8a9ef14e4f04f4dd2032cacecc925be219a5444e Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Sun, 8 Jan 2017 14:52:29 +0100 Subject: [PATCH 1/7] reduced the max number of antenna ports to 6 to save memory (we are not using antenna port >5 anyway) mult_cpx_conj_vector can now also do multiply add beam_precoding now uses mult_cpx_conj_vector Conflicts: openair1/PHY/MODULATION/beamforming.c --- openair1/PHY/INIT/lte_init.c | 4 +- .../lte_ul_channel_estimation.c | 9 ++-- openair1/PHY/MODULATION/beamforming.c | 43 ++++++++++--------- openair1/PHY/TOOLS/cmult_vv.c | 16 +++++-- openair1/PHY/TOOLS/defs.h | 4 +- openair1/PHY/impl_defs_lte.h | 2 +- openair1/PHY/impl_defs_top.h | 2 +- 7 files changed, 48 insertions(+), 32 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 12bd06bb81..accc54af54 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1304,7 +1304,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->txdataF[eNB_id] = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*)); common_vars->txdataF_BF[eNB_id] = (int32_t **)malloc16(fp->nb_antennas_tx*sizeof(int32_t*)); - for (i=0; i<14; i++) { + for (i=0; itxdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); #ifdef DEBUG_PHY msg("[openair][LTE_PHY][INIT] lte_common_vars->txdataF[%d][%d] = %p (%d bytes)\n", @@ -1326,7 +1326,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, #endif } - for (i=0; i<14; i++) { // 14 is the total number of antenna ports + for (i=0; ibeam_weights[eNB_id][i] = (int32_t **)malloc16_clear(fp->nb_antennas_tx*sizeof(int32_t*)); for (j=0; jnb_antennas_tx; j++) { common_vars->beam_weights[eNB_id][i][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index d2bc2e27c0..4fef74dd1c 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -720,10 +720,11 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, //write_output("eNB_srs.m","srs_eNB",common_vars->srs,(frame_parms->ofdm_symbol_size),1,1); mult_cpx_conj_vector((int16_t*) &common_vars->rxdataF[eNB_id][aa][2*frame_parms->ofdm_symbol_size*symbol], - (int16_t*) srs_vars->srs, - (int16_t*) srs_vars->srs_ch_estimates[eNB_id][aa], - frame_parms->ofdm_symbol_size, - 15); + (int16_t*) srs_vars->srs, + (int16_t*) srs_vars->srs_ch_estimates[eNB_id][aa], + frame_parms->ofdm_symbol_size, + 15, + 0); //msg("SRS channel estimation cmult out\n"); #ifdef USER_MODE diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 6557a47ee7..331c4e2421 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -64,27 +64,30 @@ int beam_precoding(int32_t **txdataF, memset(txdataF_BF[aa],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); for (p=0; p<14; p++) { - //if (p==0 || p==1 || p==5 || p>7) - // mult_cpx_conj_vector((int16_t*)txdataF[p], (int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15); - for (re=0;reofdm_symbol_size;re++) { - if ((p==0 || p==1 || p==5 || p>=7) && txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { - ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); - ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); - ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); + if (p==0 || p==1 || p==5) { + mult_cpx_conj_vector((int16_t*)beam_weights[p][aa], (int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15, 1); + //multadd_cpx_vector((int16_t*)txdataF[p],(int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], 0, frame_parms->ofdm_symbol_size, 15); - /* - printf("beamforming.c:txdataF[%d][%d]=%d+j%d, beam_weights[%d][%d][%d]=%d+j%d,txdata_BF[%d][%d]=%d+j%d\n", - p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re, - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0], - ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1], - p,aa,re, - ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1], - aa,re, - ((int16_t*)&txdataF_BF[aa][re])[0], - ((int16_t*)&txdataF_BF[aa][re])[1]); - */ - } + /* + for (re=0;reofdm_symbol_size;re++) { + if (txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { + ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); + ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); + ((int16_t*)&txdataF_BF[aa][re])[1] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); + + printf("beamforming.c:txdataF[%d][%d]=%d+j%d, beam_weights[%d][%d][%d]=%d+j%d,txdata_BF[%d][%d]=%d+j%d\n", + p,slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re, + ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0], + ((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1], + p,aa,re, + ((int16_t*)&beam_weights[p][aa][re])[0],((int16_t*)&beam_weights[p][aa][re])[1], + aa,re, + ((int16_t*)&txdataF_BF[aa][re])[0], + ((int16_t*)&txdataF_BF[aa][re])[1]); + } + } + */ } } return 0; diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index cefa972061..39bfe547e7 100644 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -41,7 +41,8 @@ int mult_cpx_conj_vector(int16_t *x1, int16_t *x2, int16_t *y, uint32_t N, - int output_shift) + int output_shift, + int madd) { // Multiply elementwise the complex conjugate of x1 with x2. // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| @@ -55,6 +56,8 @@ int mult_cpx_conj_vector(int16_t *x1, // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; // // output_shift - shift to be applied to generate output + // + // madd - add the output to y uint32_t i; // loop counter @@ -88,7 +91,11 @@ int mult_cpx_conj_vector(int16_t *x1, tmp_im = _mm_srai_epi32(tmp_im,output_shift); tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); - *y_128 = _mm_packs_epi32(tmpy0,tmpy1); + if (madd==0) + *y_128 = _mm_packs_epi32(tmpy0,tmpy1); + else + *y_128 += _mm_packs_epi32(tmpy0,tmpy1); + #elif defined(__arm__) tmp_re = vmull_s16(((simdshort_q15_t *)x1_128)[0], ((simdshort_q15_t*)x2_128)[0]); @@ -110,7 +117,10 @@ int mult_cpx_conj_vector(int16_t *x1, tmp_re = vqshlq_s32(tmp_re,shift); tmp_im = vqshlq_s32(tmp_im,shift); tmpy = vzip_s16(vmovn_s32(tmp_re),vmovn_s32(tmp_im)); - *y_128 = vcombine_s16(tmpy.val[0],tmpy.val[1]); + if (madd==0) + *y_128 = vcombine_s16(tmpy.val[0],tmpy.val[1]); + else + *y_128 += vcombine_s16(tmpy.val[0],tmpy.val[1]); #endif x1_128++; x2_128++; diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h index 453efc028a..273822c598 100644 --- a/openair1/PHY/TOOLS/defs.h +++ b/openair1/PHY/TOOLS/defs.h @@ -116,13 +116,15 @@ int rotate_cpx_vector(int16_t *x, @param y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| @param N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; @param output_shift - shift to be applied to generate output + @param madd - if not zero result is added to output */ int mult_cpx_conj_vector(int16_t *x1, int16_t *x2, int16_t *y, uint32_t N, - int output_shift); + int output_shift, + int madd); // lte_dfts.c void init_fft(uint16_t size, diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 6635573779..98d6e06f76 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -546,7 +546,7 @@ typedef struct { uint8_t nb_antennas_tx; /// Number of Receive antennas in node uint8_t nb_antennas_rx; - /// Number of Logical transmit antenna ports in eNodeB + /// Number of common transmit antenna ports in eNodeB (1 or 2) uint8_t nb_antenna_ports_eNB; /// PRACH_CONFIG PRACH_CONFIG_COMMON prach_config_common; diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 79e684215c..dd09749fbf 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -177,7 +177,7 @@ #define DMA_BLKS_PER_SLOT (SLOT_LENGTH_BYTES/2048) // Number of DMA blocks per slot #define SLOT_TIME_NS (SLOT_LENGTH_SAMPLES*(1e3)/7.68) // slot time in ns -#define NB_ANTENNA_PORTS_ENB 14 // total number of eNB antenna ports +#define NB_ANTENNA_PORTS_ENB 6 // total number of eNB antenna ports #ifdef EXMIMO #define TARGET_RX_POWER 55 // Target digital power for the AGC From ab57b0ddd3c687ecbc0e7c95e26c1cc4cddfd47b Mon Sep 17 00:00:00 2001 From: Xiwen JIANG Date: Mon, 9 Jan 2017 17:19:15 +0100 Subject: [PATCH 2/7] replace the conjugate vector multiplexing with direct vector multiplexing --- openair1/PHY/MODULATION/beamforming.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 331c4e2421..acf792b519 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -65,11 +65,11 @@ int beam_precoding(int32_t **txdataF, for (p=0; p<14; p++) { if (p==0 || p==1 || p==5) { - mult_cpx_conj_vector((int16_t*)beam_weights[p][aa], (int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15, 1); - //multadd_cpx_vector((int16_t*)txdataF[p],(int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], 0, frame_parms->ofdm_symbol_size, 15); + multadd_cpx_vector((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size],(int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], 0, frame_parms->ofdm_symbol_size, 15); + //mult_cpx_conj_vector((int16_t*)beam_weights[p][aa], (int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15, 1); - /* - for (re=0;reofdm_symbol_size;re++) { + // if check version + /*for (re=0;reofdm_symbol_size;re++) { if (txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re]!=0) { ((int16_t*)&txdataF_BF[aa][re])[0] += (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[0]*((int16_t*)&beam_weights[p][aa][re])[0])>>15); ((int16_t*)&txdataF_BF[aa][re])[0] -= (int16_t)((((int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size+re])[1]*((int16_t*)&beam_weights[p][aa][re])[1])>>15); @@ -86,8 +86,7 @@ int beam_precoding(int32_t **txdataF, ((int16_t*)&txdataF_BF[aa][re])[0], ((int16_t*)&txdataF_BF[aa][re])[1]); } - } - */ + }*/ } } return 0; From a5e6690dedac1222164afa7c2afad654431edcf4 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Jan 2017 09:33:39 +0100 Subject: [PATCH 3/7] adding multadd_cpx_vector --- openair1/PHY/TOOLS/cmult_vv.c | 79 +++++++++++++++++++++++++++++++++++ openair1/PHY/TOOLS/defs.h | 19 +++++++++ 2 files changed, 98 insertions(+) diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index 39bfe547e7..9d5079f52b 100644 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -27,6 +27,7 @@ #if defined(__x86_64__) || defined(__i386__) int16_t conjug[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; +int16_t conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; #define simd_q15_t __m128i #define simdshort_q15_t __m64 #elif defined(__arm__) @@ -134,3 +135,81 @@ int mult_cpx_conj_vector(int16_t *x1, return(0); } +int multadd_cpx_vector(int16_t *x1, + int16_t *x2, + int16_t *y, + uint8_t zero_flag, + uint32_t N, + int output_shift) +{ + // Multiply elementwise the complex conjugate of x1 with x2. + // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // We assume x1 with a dinamic of 15 bit maximum + // + // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // We assume x2 with a dinamic of 14 bit maximum + /// + // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // + // zero_flag - Set output (y) to zero prior to disable accumulation + // + // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; + // + // output_shift - shift to be applied to generate output + + uint32_t i; // loop counter + + simd_q15_t *x1_128; + simd_q15_t *x2_128; + simd_q15_t *y_128; +#if defined(__x86_64__) || defined(__i386__) + simd_q15_t tmp_re,tmp_im; + simd_q15_t tmpy0,tmpy1; +#elif defined(__arm__) + int32x4_t tmp_re,tmp_im; + int32x4_t tmp_re1,tmp_im1; + int16x4x2_t tmpy; + int32x4_t shift = vdupq_n_s32(-output_shift); +#endif + + x1_128 = (simd_q15_t *)&x1[0]; + x2_128 = (simd_q15_t *)&x2[0]; + y_128 = (simd_q15_t *)&y[0]; + + + // we compute 4 cpx multiply for each loop + for(i=0; i<(N>>2); i++) { +#if defined(__x86_64__) || defined(__i386__) + tmp_re = _mm_sign_epi16(*x1_128,*(__m128i*)&conjug2[0]); + tmp_re = _mm_madd_epi16(tmp_re,*x2_128); + tmp_im = _mm_shufflelo_epi16(*x1_128,_MM_SHUFFLE(2,3,0,1)); + tmp_im = _mm_shufflehi_epi16(tmp_im,_MM_SHUFFLE(2,3,0,1)); + tmp_im = _mm_madd_epi16(tmp_im,*x2_128); + tmp_re = _mm_srai_epi32(tmp_re,output_shift); + tmp_im = _mm_srai_epi32(tmp_im,output_shift); + tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); + //print_ints("unpack lo:",&tmpy0[i]); + tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); + //print_ints("unpack hi:",&tmpy1[i]); + + if (zero_flag == 1) + *y_128 = _mm_packs_epi32(tmpy0,tmpy1); + else + *y_128 = _mm_adds_epi16(*y_128,_mm_packs_epi32(tmpy0,tmpy1)); + //print_shorts("*y_128:",&y_128[i]); + +#elif defined(__arm__) + + msg("mult_cpx_vector not implemented for __arm__"); +#endif + x1_128++; + x2_128++; + y_128++; + } + + + _mm_empty(); + _m_empty(); + + return(0); +} diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h index 273822c598..8f0ae402bf 100644 --- a/openair1/PHY/TOOLS/defs.h +++ b/openair1/PHY/TOOLS/defs.h @@ -126,6 +126,25 @@ int mult_cpx_conj_vector(int16_t *x1, int output_shift, int madd); +/*! + Element-wise multiplication and accumulation of two complex vectors x1 and x2. + @param x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + We assume x1 with a dinamic of 15 bit maximum + @param x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + We assume x2 with a dinamic of 14 bit maximum + @param y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + @param zero_flag Set output (y) to zero prior to accumulation + @param N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; + @param output_shift - shift to be applied to generate output +*/ + +int multadd_cpx_vector(int16_t *x1, + int16_t *x2, + int16_t *y, + uint8_t zero_flag, + uint32_t N, + int output_shift); + // lte_dfts.c void init_fft(uint16_t size, uint8_t logsize, From 550759231df6b7401a802a1077230928cc599710 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Jan 2017 09:38:14 +0100 Subject: [PATCH 4/7] change loop limit to NB_ANTENNA_PORTS_ENB --- openair1/PHY/MODULATION/beamforming.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index acf792b519..6864ca110e 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -63,7 +63,7 @@ int beam_precoding(int32_t **txdataF, // clear txdata_BF[aa][re] for each call of ue_spec_beamforming memset(txdataF_BF[aa],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); - for (p=0; p<14; p++) { + for (p=0; pofdm_symbol_size],(int16_t*)beam_weights[p][aa], (int16_t*)txdataF_BF[aa], 0, frame_parms->ofdm_symbol_size, 15); //mult_cpx_conj_vector((int16_t*)beam_weights[p][aa], (int16_t*)&txdataF[p][slot_offset_F+symbol*frame_parms->ofdm_symbol_size], (int16_t*)txdataF_BF[aa], frame_parms->ofdm_symbol_size, 15, 1); From b0b5cb21e53fade58af575ac2cd0794af191803e Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Jan 2017 15:31:04 +0100 Subject: [PATCH 5/7] Beamforming is now only done when necessary. This patch is based on one from enhancement-10-harmony. --- openair1/PHY/INIT/lte_init.c | 1 + openair1/PHY/MODULATION/defs.h | 2 +- openair1/PHY/MODULATION/ofdm_mod.c | 22 +++++++++++----------- openair1/PHY/defs.h | 2 ++ openair1/SIMULATION/LTE_PHY/dlsim.c | 6 ++++-- targets/RT/USER/lte-enb.c | 20 ++++++++++++++------ 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index accc54af54..4d927dc5d3 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -684,6 +684,7 @@ void phy_config_dedicated_eNB(uint8_t Mod_id, break; case AntennaInfoDedicated__transmissionMode_tm7: lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti); + eNB->do_precoding = 1; eNB->transmission_mode[UE_id] = 7; break; default: diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h index 6937db6d9b..da599114a9 100644 --- a/openair1/PHY/MODULATION/defs.h +++ b/openair1/PHY/MODULATION/defs.h @@ -82,7 +82,7 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); -void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); +void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding); void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe); diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 74037b4a6e..8e09cea1ec 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -285,16 +285,16 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne } // OFDM modulation for each symbol -void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) +void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding) { - int aa, l, slot_offset; - int32_t **txdataF = eNB_common_vars->txdataF[eNB_id]; + int aa, l, slot_offset, slot_offsetF; + int32_t **txdataF = eNB_common_vars->txdataF[eNB_id]; int32_t **txdataF_BF = eNB_common_vars->txdataF_BF[eNB_id]; - int32_t **txdata = eNB_common_vars->txdata[eNB_id]; - - slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + int32_t **txdata = eNB_common_vars->txdata[eNB_id]; + slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + slot_offsetF = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==EXTENDED) ? 6 : 7); //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc()); for (l=0; lsymbols_per_tti>>1; l++) { @@ -302,13 +302,13 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1); - beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa); + if (do_precoding==1) beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights[eNB_id],next_slot,l,aa); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0); //PMCH case not implemented... - if (frame_parms->Ncp == 1) - PHY_ofdm_mod(txdataF_BF[aa], // input + if (frame_parms->Ncp == EXTENDED) + PHY_ofdm_mod((do_precoding == 1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output frame_parms->ofdm_symbol_size, 1, // number of symbols @@ -316,7 +316,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne CYCLIC_PREFIX); else { if (l==0) { - PHY_ofdm_mod(txdataF_BF[aa], // input + PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset], // output frame_parms->ofdm_symbol_size, 1, // number of symbols @@ -324,7 +324,7 @@ void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, int eNB_id, uint16_t ne CYCLIC_PREFIX); } else { - PHY_ofdm_mod(txdataF_BF[aa], // input + PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size], // input &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], // output frame_parms->ofdm_symbol_size, 1, // number of symbols diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index d462fe58cb..0bc7c6e1c1 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -415,6 +415,8 @@ typedef struct PHY_VARS_eNB_s { int single_thread_flag; openair0_rf_map rf_map; int abstraction_flag; + // indicator for precoding function (eNB,3GPP_eNB_BBU) + int do_precoding; void (*do_prach)(struct PHY_VARS_eNB_s *eNB); void (*fep)(struct PHY_VARS_eNB_s *eNB); int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f9a8acfa85..0682308ab7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2409,12 +2409,14 @@ int main(int argc, char **argv) do_OFDM_mod_symbol(&eNB->common_vars, eNB_id, (subframe*2), - &eNB->frame_parms); + &eNB->frame_parms, + eNB->do_precoding); do_OFDM_mod_symbol(&eNB->common_vars, eNB_id, (subframe*2)+1, - &eNB->frame_parms); + &eNB->frame_parms, + eNB->do_precoding); stop_meas(&eNB->ofdm_mod_stats); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a3d6d96e03..331a2b5fe1 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -296,16 +296,18 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,1); do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, - 0, - subframe<<1, - &phy_vars_eNB->frame_parms); + 0, + subframe<<1, + &phy_vars_eNB->frame_parms, + &phy_vars_eNB->do_precoding); // if S-subframe generate first slot only if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) { do_OFDM_mod_symbol(&phy_vars_eNB->common_vars, - 0, - 1+(subframe<<1), - &phy_vars_eNB->frame_parms); + 0, + 1+(subframe<<1), + &phy_vars_eNB->frame_parms, + &phy_vars_eNB->do_precoding); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0); @@ -1637,6 +1639,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst case NGFI_RRU_IF5: eNB->do_prach = NULL; eNB->fep = eNB_fep_rru_if5; + eNB->do_precoding = 0; eNB->td = NULL; eNB->te = NULL; eNB->proc_uespec_rx = NULL; @@ -1661,6 +1664,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } break; case NGFI_RRU_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = NULL; @@ -1690,6 +1694,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst break; case eNodeB_3GPP: + eNB->do_precoding = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1710,6 +1715,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst eNB->ifdevice.host_type = BBU_HOST; break; case eNodeB_3GPP_BBU: + eNB->do_precoding = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1742,6 +1748,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst } break; case NGFI_RCC_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = NULL; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1765,6 +1772,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst break; case NGFI_RAU_IF4p5: + eNB->do_precoding = 0; eNB->do_prach = do_prach; eNB->fep = NULL; From 0695828e4c67707fa8ded86f0d2cde37a6ce388e Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Jan 2017 16:43:02 +0100 Subject: [PATCH 6/7] some fixes --- .../CONF/enb.band4.tm1.usrpb210.conf | 14 ++++++++++---- targets/RT/USER/lte-enb.c | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.tm1.usrpb210.conf index 853db14393..4004b5faec 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band4.tm1.usrpb210.conf @@ -17,12 +17,15 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "93"; + mobile_network_code = "92"; ////////// Physical parameters: component_carriers = ( { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; frame_type = "FDD"; tdd_config = 3; tdd_config_s = 0; @@ -35,6 +38,7 @@ eNBs = Nid_cell_mbsfn = 0; nb_antennas_tx = 1; nb_antennas_rx = 1; + nb_antenna_ports = 1; tx_gain = 90; rx_gain = 128; prach_root = 0; @@ -97,6 +101,8 @@ eNBs = ue_TimersAndConstants_t311 = 10000; ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; } ); @@ -131,7 +137,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.11"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -141,10 +147,10 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 331a2b5fe1..52688ced49 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1694,7 +1694,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst break; case eNodeB_3GPP: - eNB->do_precoding = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB; + eNB->do_precoding = eNB->frame_parms.nb_antennas_tx!=eNB->frame_parms.nb_antenna_ports_eNB; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; @@ -1715,7 +1715,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst eNB->ifdevice.host_type = BBU_HOST; break; case eNodeB_3GPP_BBU: - eNB->do_precoding = eNB->frame_parms.nb_antennas_tx==eNB->frame_parms.nb_antenna_ports_eNB; + eNB->do_precoding = eNB->frame_parms.nb_antennas_tx!=eNB->frame_parms.nb_antenna_ports_eNB; eNB->do_prach = do_prach; eNB->fep = eNB_fep_full;//(single_thread_flag==1) ? eNB_fep_full_2thread : eNB_fep_full; eNB->td = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; From e0c74791226f8074219099fde184371f3d10fe26 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 19 Jan 2017 09:32:29 +0100 Subject: [PATCH 7/7] and one more fix --- targets/RT/USER/lte-enb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 52688ced49..5889b908c2 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -288,7 +288,6 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) slot_offset = subframe*phy_vars_eNB->frame_parms.samples_per_tti; - if ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_DL)|| ((subframe_select(&phy_vars_eNB->frame_parms,subframe)==SF_S))) { // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); @@ -299,7 +298,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) 0, subframe<<1, &phy_vars_eNB->frame_parms, - &phy_vars_eNB->do_precoding); + phy_vars_eNB->do_precoding); // if S-subframe generate first slot only if (subframe_select(&phy_vars_eNB->frame_parms,subframe) == SF_DL) { @@ -307,7 +306,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) 0, 1+(subframe<<1), &phy_vars_eNB->frame_parms, - &phy_vars_eNB->do_precoding); + phy_vars_eNB->do_precoding); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_OFDM_MODULATION,0);