From 7f34328b24bdfc844d82819352dfe96113d5eb23 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 8 Dec 2015 16:18:44 +0100 Subject: [PATCH] Changes: 1. Fixing precoder selection criteria for TM4 for tpmi2. TPMI 2 works now. 2. Temporarily replacing abstraction.c with an old version till fix the bug in init_freq_channel. 3. Commenting some extra printouts. --- cmake_targets/lte-simulators/CMakeLists.txt | 2 +- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 32 +-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 10 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- openair1/PHY/LTE_TRANSPORT/pcfich.c | 4 +- openair1/PHY/LTE_TRANSPORT/phich.c | 8 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 44 ++--- openair1/SIMULATION/TOOLS/abstraction.c | 187 +++++++++++++++++- openair1/SIMULATION/TOOLS/random_channel.c | 2 +- 10 files changed, 247 insertions(+), 52 deletions(-) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index 0b706c8748..5ed4d93d80 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -8,7 +8,7 @@ set(DEBUG_PHY False) set(MU_RECIEVER False) set(RANDOM_BF False) set(PBS_SIM False) -set(PERFECT_CE False) +set(PERFECT_CE True) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 9f7ae5fcbc..b43fc8b9ef 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -422,7 +422,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms; int nb_subbands,subband_size,last_subband_size; int N_RB_DL = frame_parms->N_RB_DL; - phy_vars_ue->PHY_measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; + phy_vars_ue->PHY_measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; if (phy_vars_ue->transmission_mode[eNB_id]!=4) phy_vars_ue->PHY_measurements.rank[eNB_id] = 0; @@ -597,10 +597,10 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, // pmi #if defined(__x86_64__) || defined(__i386__) - - pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); - pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); + pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); + pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); #elif defined(__arm__) + pmi128_re = vdupq_n_s32(0); pmi128_im = vdupq_n_s32(0); #endif @@ -613,22 +613,32 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, for (i=0; isubband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } - if (pmi_re >= pmi_im) + if (((pmi_re > pmi_im) && (pmi_re > -pmi_im)) || ((pmi_re < pmi_im) && (pmi_re < -pmi_im))) pmiq = PMI_2A_R1_11; - else //if (pmi_re < pmi_im) + else pmiq = PMI_2A_R1_1j; + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } else { @@ -5856,7 +5858,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) } } - //printf( "pmivect %d \n", pmivect); + // printf( "pmivect %d \n", pmivect); return(pmivect); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index dd708804fc..6f1a05ed4f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -428,11 +428,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode); - if (rx_type>rx_standard) { + /*if (rx_type>rx_standard) { // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } - else + else */ lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } @@ -1371,6 +1371,7 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { + // printf ("demod pmi=%d\n", pmi); // __m128i amp; // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; @@ -1384,7 +1385,7 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); } - else { + else { //ch0+j*ch1 ch0-j*ch1 tmp0 = ch0[0]; tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); @@ -1620,9 +1621,6 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // phy_measurements->precoded_cqi_dB[eNB_id][0]); - _mm_empty(); - _m_empty(); - #elif defined(__arm__) uint32_t rb,Nre; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 135552f279..48bbc51c3e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1270,7 +1270,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb if (mode <= PUSCH_PRECODING1) return((pmi_alloc>>((rb>>2)<<1))&3); else { - // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); + // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); return((pmi_alloc>>(rb>>2))&1); } break; diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c index f289fd3bd0..5f55a5c4c6 100644 --- a/openair1/PHY/LTE_TRANSPORT/pcfich.c +++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c @@ -78,9 +78,9 @@ void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) first_reg = pcfich_reg[3]; } - //#ifdef DEBUG_PCFICH + #ifdef DEBUG_PCFICH printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]); - //#endif + #endif } void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index e08ad239bd..a7c375b6ae 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -300,7 +300,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) Ngroup_PHICH<<=1; } - //#ifdef DEBUG_PHICH + #ifdef DEBUG_PHICH printf("Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), frame_parms->phich_config_common.phich_resource, @@ -310,7 +310,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) n0, n1, ((frame_parms->Nid_cell))%n0); - //#endif + #endif // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ... @@ -364,9 +364,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) frame_parms->phich_reg[mprime][2]++; - //#ifdef DEBUG_PHICH + #ifdef DEBUG_PHICH printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); - //#endif + #endif } else { // extended PHICH duration frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0; frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0d67003db3..eee78da23d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -776,8 +776,6 @@ int main(int argc, char **argv) nsymb = (PHY_vars_eNB->lte_frame_parms.Ncp == 0) ? 14 : 12; - - printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n", SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); @@ -788,17 +786,17 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); - else + else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); - else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + else + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); bler_fd = fopen(bler_fname,"w"); fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; dci_err\n"); - - if (test_perf != 0) { + if (test_perf != 0) { char hostname[1024]; + hostname[1023] = '\0'; gethostname(hostname, 1023); printf("Hostname: %s\n", hostname); @@ -1792,6 +1790,7 @@ n(tikz_fname,"w"); } + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); if (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) { // not a nice way to do it, fix later PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); @@ -1850,7 +1849,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; case 50: dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; @@ -2748,7 +2747,7 @@ n(tikz_fname,"w"); #endif rate = (double)tbs/(double)coded_bits_per_codeword; - if ((SNR==snr0) && (trials==0) && (round==0)) + if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), coded_bits_per_codeword, @@ -2930,19 +2929,18 @@ n(tikz_fname,"w"); else { if (transmission_mode==4) { r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - // printf("r_re0 = %d\n",r_re[0][i]); - //printf("r_im0 = %d\n",r_im[0][i]); - //printf("r_re1 = %d\n",r_re[1][i]); - //printf("r_im1 = %d\n",r_im[1][i]); - // r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - - // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //printf("r_re0 = %d\n",r_re[0][i]); + //printf("r_im0 = %d\n",r_im[0][i]); + //printf("r_re1 = %d\n",r_re[1][i]); + //printf("r_im1 = %d\n",r_im[1][i]); + //r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + //r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + //r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); } else { @@ -3152,6 +3150,7 @@ n(tikz_fname,"w"); subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, 1, 0); + // printf ("Trial %d, Measurements are done \n", trials); /* debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", PHY_vars_UE->PHY_measurements.rx_rssi_dBm[0] - ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0), @@ -3179,6 +3178,7 @@ n(tikz_fname,"w"); if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; + // printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); goto PMI_FEEDBACK; } } diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index d63d0b0fe9..03c3e59d4e 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -26,7 +26,7 @@ Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ -#include +/*#include #include #include #include @@ -309,3 +309,188 @@ double pbch_bler(double sinr) return(bler); } +*/ +#include +#include +#include +#include +#include + + +#include "PHY/TOOLS/defs.h" +#include "defs.h" + +void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { + + double delta_f,freq; // 90 kHz spacing + double delay; + int16_t f; + uint8_t aarx,aatx,l; + + delta_f = nb_rb*180000/(n_samples-1); + //write_output("channel.m","a",desc->a[0],desc->nb_taps,1,8); + for (f=-n_samples/2;fnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].x=0.0; + desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].y=0.0; + for (l=0;l<(int)desc->nb_taps;l++) { + if (desc->nb_taps==1) + delay = desc->delays[l]; + else + delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->BW; + desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*cos(2*M_PI*freq*delay)+ + desc->a[l][aarx+(aatx*desc->nb_rx)].y*sin(2*M_PI*freq*delay)); + desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*sin(2*M_PI*freq*delay)+ + desc->a[l][aarx+(aatx*desc->nb_rx)].y*cos(2*M_PI*freq*delay)); + } + // printf("chF(%d) => (%f,%f)\n",n_samples/2+f, + // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x, + // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y); + } + } + } +} + +double compute_pbch_sinr(channel_desc_t *desc, + channel_desc_t *desc_i1, + channel_desc_t *desc_i2, + double snr_dB,double snr_i1_dB, + double snr_i2_dB, + uint16_t nb_rb) { + + double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); + uint16_t f; + uint8_t aarx,aatx; + double S; + struct complex S_i1; + struct complex S_i2; + + avg_sinr=0.0; + // printf("nb_rb %d\n",nb_rb); + for (f=(nb_rb-6);f<(nb_rb+6);f++) { + S = 0.0; + S_i1.x =0.0; + S_i1.y =0.0; + S_i2.x =0.0; + S_i2.y =0.0; + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + // printf("%d %d chF[%d] => (%f,%f)\n",aarx,aatx,f,desc->chF[aarx+(aatx*desc->nb_rx)][f].x,desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + + if (desc_i1) { + S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + if (desc_i2) { + S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + } + } + // printf("snr %f f %d : S %f, S_i1 %f, S_i2 %f\n",snr,f-nb_rb,S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); + avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); + } + // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); + return(10*log10(avg_sinr/12.0)); +} + + +double compute_sinr(channel_desc_t *desc, + channel_desc_t *desc_i1, + channel_desc_t *desc_i2, + double snr_dB,double snr_i1_dB, + double snr_i2_dB, + uint16_t nb_rb) { + + double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); + uint16_t f; + uint8_t aarx,aatx; + double S; + struct complex S_i1; + struct complex S_i2; + + avg_sinr=0.0; + // printf("nb_rb %d\n",nb_rb); + for (f=0;f<2*nb_rb;f++) { + S = 0.0; + S_i1.x =0.0; + S_i1.y =0.0; + S_i2.x =0.0; + S_i2.y =0.0; + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + if (desc_i1) { + S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + if (desc_i2) { + S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + } + } + // printf("f %d : S %f, S_i1 %f, S_i2 %f\n",f-nb_rb,snr*S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); + avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); + } + // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); + return(10*log10(avg_sinr/(nb_rb*2))); +} + + uint8_t pbch_polynomial_degree; +double a[7]; + +void load_pbch_desc(FILE *pbch_file_fd) { + + int i; + char dummy[25]; + + fscanf(pbch_file_fd,"%d",&pbch_polynomial_degree); + if (pbch_polynomial_degree>6) { + printf("Illegal degree for pbch interpolation polynomial %d\n",pbch_polynomial_degree); + exit(-1); + } + + printf("PBCH polynomial : "); + + for (i=0;i<=pbch_polynomial_degree;i++) { + fscanf(pbch_file_fd,"%s",dummy); + a[i] = strtod(dummy,NULL); + printf("%f ",a[i]); + } + printf("\n"); +} + +double pbch_bler(double sinr) { + + int i; + double log10_bler=a[pbch_polynomial_degree]; + double sinrpow=sinr; + // printf("log10bler %f\n",log10_bler); + if (sinr<-7.9) + return(1.0); + else if (sinr>=0.0) + return(1e-4); + + for (i=1;i<=pbch_polynomial_degree;i++) { + // printf("sinrpow %f\n",sinrpow); + log10_bler += (a[pbch_polynomial_degree-i]*sinrpow); + sinrpow *= sinr; + // printf("log10bler %f\n",log10_bler); + } + return(pow(10.0,log10_bler)); +} diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index d4c1d45a75..528402a2f2 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -209,7 +209,7 @@ struct complex *R_sqrt_22_orthogonal[1] = {R_sqrt_22_orthogonal_tap}; struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}}; + {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_real_tap};