void multipath_channel(channel_desc_t *desc, double **tx_sig_re, double **tx_sig_im, double **rx_sig_re, double **rx_sig_im, uint32_t length, uint8_t keep_channel) { int i,ii,j,l; int length1, length2, tail; __m128d rx_tmp128_re_f,rx_tmp128_im_f,rx_tmp128_re,rx_tmp128_im, rx_tmp128_1,rx_tmp128_2,rx_tmp128_3,rx_tmp128_4,tx128_re,tx128_im,ch128_x,ch128_y,pathloss128; double path_loss = pow(10,desc->path_loss_dB/20); int dd = abs(desc->channel_offset); pathloss128 = _mm_set1_pd(path_loss); #ifdef DEBUG_CH printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length); #endif if (keep_channel) { // do nothing - keep channel } else { random_channel(desc,0); } start_meas(&desc->convolution); #ifdef DEBUG_CH for (l = 0; l<(int)desc->channel_length; l++) { printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y); } printf("\n"); #endif tail = ((int)length-dd)%2; if(tail) length1 = ((int)length-dd)-1; else length1 = ((int)length-dd); length2 = length1/2; for (i=0; i<length2; i++) { // for (ii=0; ii<desc->nb_rx; ii++) { // rx_tmp.x = 0; // rx_tmp.y = 0; rx_tmp128_re_f = _mm_setzero_pd(); rx_tmp128_im_f = _mm_setzero_pd(); for (j=0; j<desc->nb_tx; j++) { for (l = 0; l<(int)desc->channel_length; l++) { if ((i>=0) && (i-l)>=0) { //SIMD correct only if length1 > 2*channel_length...which is almost always satisfied // tx.x = tx_sig_re[j][i-l]; // tx.y = tx_sig_im[j][i-l]; tx128_re = _mm_loadu_pd(&tx_sig_re[j][2*i-l]); // tx_sig_re[j][i-l+1], tx_sig_re[j][i-l] tx128_im = _mm_loadu_pd(&tx_sig_im[j][2*i-l]); } else { //tx.x =0; //tx.y =0; tx128_re = _mm_setzero_pd(); tx128_im = _mm_setzero_pd(); } ch128_x = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].x); ch128_y = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].y); // rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y); // rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y); rx_tmp128_1 = _mm_mul_pd(tx128_re,ch128_x); rx_tmp128_2 = _mm_mul_pd(tx128_re,ch128_y); rx_tmp128_3 = _mm_mul_pd(tx128_im,ch128_x); rx_tmp128_4 = _mm_mul_pd(tx128_im,ch128_y); rx_tmp128_re = _mm_sub_pd(rx_tmp128_1,rx_tmp128_4); rx_tmp128_im = _mm_add_pd(rx_tmp128_2,rx_tmp128_3); rx_tmp128_re_f = _mm_add_pd(rx_tmp128_re_f,rx_tmp128_re); rx_tmp128_im_f = _mm_add_pd(rx_tmp128_im_f,rx_tmp128_im); } //l } // j //rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss; //rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss; rx_tmp128_re_f = _mm_mul_pd(rx_tmp128_re_f,pathloss128); rx_tmp128_im_f = _mm_mul_pd(rx_tmp128_im_f,pathloss128); _mm_storeu_pd(&rx_sig_re[ii][2*i+dd],rx_tmp128_re_f); // max index: length-dd -1 + dd = length -1 _mm_storeu_pd(&rx_sig_im[ii][2*i+dd],rx_tmp128_im_f); /* if ((ii==0)&&((i%32)==0)) { printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]); } */ //rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]); //rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]); } // ii } // i stop_meas(&desc->convolution); }
//#define DEBUG_CH uint8_t multipath_channel_nosigconv(channel_desc_t *desc) { random_channel(desc,0); return(1); }
// Leosam 08/08: What are the arguments? int main (int argc, char **argv) { // Command line parsing int input_val = 1000; // Value serving as an input relatad to the SNR int max_num_ofdm_sym = 64; // Index of the last frame for the channel estimation int be_verbose = 0; // Operate in verbose mode int index; int c; unsigned int rx_energy[NB_ANTENNAS], n0_energy[NB_ANTENNAS]; if (argc == 1) { error (); exit (-1); } while ((c = getopt (argc, argv, "hVv:n:")) != -1) { switch (c) { case 'h': help (); exit (1); case 'V': be_verbose = 1; break; case 'v': input_val = atoi (optarg); break; return 1; case 'n': max_num_ofdm_sym = atoi (optarg); break; return 1; default: error (); exit (-1); } } // // Initialization stuff // int i, ii, j, ret, delay, l; short seed[3]; // Leosam 08/08: What is this amps? double amps[8] = { 1.0, .8, .4, .2, .1, .05, .025, .01 }; struct complex ch[NB_ANTENNAS * NB_ANTENNAS][10 + (int) (1 + 2 * BW * Td)]; struct complex rx_tmp, tx, n, phase; char *chbch_pdu; int chbch_size; int extension; unsigned char dummy_mac_pdu[120]; #ifdef USER_MODE char fname[40], vname[40]; #endif // USER_MODE if (be_verbose) printf ("Allocating memory for PHY_VARS\n"); // Memory allocation for PHY and MAC structures PHY_vars = malloc (sizeof (PHY_VARS)); PHY_config = malloc (sizeof (PHY_CONFIG)); mac_xface = malloc (sizeof (MAC_xface)); // Loading of the configuration data if ((config = fopen ("config.cfg", "r")) == NULL) // this can be configured { if (be_verbose) printf ("[Main USER] The openair configuration file <config.cfg> could not be found!\n"); exit (0); } if ((scenario = fopen ("scenario.scn", "r")) == NULL) { if (be_verbose) printf ("[Main USER] The openair scenario file <scenario.scn> could not be found!\n"); exit (0); } if (be_verbose) printf ("Opened configuration files\n"); reconfigure_MACPHY (scenario); if (be_verbose) dump_config (); // Leosam 08/08: This is repeated bellow. Is it necessary? mac_xface->is_cluster_head = 0; // Initialize the PHY and MAC variables phy_init (NB_ANTENNAS_TX); if (be_verbose) printf ("Initialized PHY variables\n"); // Fill MAC PDU buffer for CHBCH seed[0] = (short) time (NULL); seed[1] = (short) time (NULL); seed[2] = (short) time (NULL); seed48 (&seed[0]); randominit (); /* * for (i=0;i<mac_xface->mac_tch->bch_tx[0].size-4;i++) { * mac_xface->mac_tch->bch_tx[0].data[i] = i;//(u8)lrand48(); * } * * * printf("Filled CHBCH PDU with random data\n"); * * // Generate one CHBCH * phy_generate_chbch(0); * */ // // Preparation for the TX procedure // // Creation of the CHBCH chbch_size = (NUMBER_OF_CARRIERS_PER_GROUP * (NUMBER_OF_CHBCH_SYMBOLS) * 16) >> 3; if (be_verbose) printf ("chbch_size = %d\n", chbch_size); chbch_pdu = malloc (chbch_size); for (i = 0; i < chbch_size - 4; i++) { chbch_pdu[i] = i; } if (be_verbose) printf ("Filled CHBCH PDU (%d bytes) with data\n", chbch_size); // Leosam 08/08: O.o delay = 1032; // delay = 0; // Generation of the CHBCH phy_generate_chbch (0, 1, NB_ANTENNAS_TX, chbch_pdu); // Generation of the pilot symbols for (i = 16; i < max_num_ofdm_sym; i++) { phy_generate_sch (0, i, 0xFFFF, 1, NB_ANTENNAS_TX); } mac_xface->is_cluster_head = 0; if (be_verbose) { for (ii=0; ii<NB_ANTENNAS; ii++) { sprintf (fname, "txsig%d.m", ii); sprintf (vname, "txs%d", ii); write_output (fname, vname, (s16 *) PHY_vars->tx_vars[ii].TX_DMA_BUFFER, NUMBER_OF_SYMBOLS_PER_FRAME * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES, 1, 1); } } // generate channels if (be_verbose) printf ("Generating MIMO Channels\n"); phase.r = 0; phase.i = 0; printf("Phase pointer %0x\n",&phase); for (i = 0; i < NB_ANTENNAS; i++) { for (j = 0; j < NB_ANTENNAS; j++) { random_channel (amps, Td, 8, BW, ch[j + (i * NB_ANTENNAS)],0.0,&phase); } } if (be_verbose) printf ("chbch_pdu %x (%d)\n", PHY_vars->chbch_data[0].demod_pdu, chbch_size); if (be_verbose) { for (l = 0; l < (1 + 2 * BW * Td); l++) { printf ("(%f,%f)\n", ch[0][l]); } } // // TX procedure // // Transmission // ////////////////////////// // Foreach symbol for (i = 0; i < (max_num_ofdm_sym) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { // Foreach RX antenna for (ii = 0; ii < NB_ANTENNAS; ii++) { rx_tmp.r = 0; rx_tmp.i = 0; n.r = gaussdouble (0.0, 10.0); n.i = gaussdouble (0.0, 10.0); // Foreach TX antenna for (j = 0; j < NB_ANTENNAS; j++) { // Foreach symbol for (l = 0; l < (1 + 2 * BW * Td); l++) { tx.r = (double) (((s16 *) & PHY_vars->tx_vars[j]. TX_DMA_BUFFER[0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]) [2 * (i - l)]) / sqrt (1.0 * input_val); tx.i = (double) (((s16 *) & PHY_vars->tx_vars[j]. TX_DMA_BUFFER[0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]) [1 + (2 * (i - l))]) / sqrt (1.0 * input_val); rx_tmp.r += (tx.r * ch[j + (ii * NB_ANTENNAS)][l].r) - (tx.i * ch[j + (ii * NB_ANTENNAS)][l].i); rx_tmp.i += (tx.i * ch[j + (ii * NB_ANTENNAS)][l].r) + (tx.r * ch[j + (ii * NB_ANTENNAS)][l].i); } } ((s16 *) & PHY_vars->rx_vars[ii]. RX_DMA_BUFFER[delay + (0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)])[2 * i] = (short) (rx_tmp.r + n.r); ((s16 *) & PHY_vars->rx_vars[ii]. RX_DMA_BUFFER[delay + (0 * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)])[1 + (2 * i)] = (short) (rx_tmp.i + n.i); } } if (be_verbose) { for (ii=0; ii<NB_ANTENNAS; ii++) { sprintf (fname, "rxsig%d.m", ii); sprintf (vname, "rxs%d", ii); write_output (fname, vname, (s16 *) PHY_vars->rx_vars[ii].RX_DMA_BUFFER, NUMBER_OF_SYMBOLS_PER_FRAME * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES, 1, 1); } } // // RX procedure // if (be_verbose) printf ("Starting RX\n"); // Sync phy_synch_time (PHY_vars->rx_vars[0].RX_DMA_BUFFER, &sync_pos, FRAME_LENGTH_COMPLEX_SAMPLES, 768, CHSCH, 0); // Forcing sync to 0 since were running offline if (be_verbose) msg ("sync_pos = %d\n", sync_pos); PHY_vars->rx_vars[0].offset = 0; //sync_pos; // estamte the signal and noise energy for (ii=0; ii < NB_ANTENNAS; ii++) { rx_energy[ii] = signal_energy((int *)&PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); n0_energy[ii] = signal_energy((int *)&PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH + (NUMBER_OF_CHSCH_SYMBOLS+NUMBER_OF_CHBCH_SYMBOLS+1) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); //msg("CYCLIC_PREFIX_LENGTH=%d, NUMBER_OF_CHSCH_SYMBOLS=%d, NUMBER_OF_CHBCH_SYMBOLS=%d, OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n", CYCLIC_PREFIX_LENGTH, NUMBER_OF_CHSCH_SYMBOLS, NUMBER_OF_CHBCH_SYMBOLS, OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); msg("symbol = %d\n", PHY_vars->rx_vars[ii].RX_DMA_BUFFER[PHY_vars->rx_vars[0].offset+CYCLIC_PREFIX_LENGTH + (NUMBER_OF_CHSCH_SYMBOLS+NUMBER_OF_CHBCH_SYMBOLS) * OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]); msg("SNR Ant %d = %d / %d \n", ii, rx_energy[ii], n0_energy[ii]); } // CHBCH channel estimation phy_channel_estimation_top(PHY_vars->rx_vars[0].offset,0,0,0,NB_ANTENNAS,0); //phy_channel_estimation_top (PHY_vars->rx_vars[0].offset, 0, 0, 0); phy_decode_chbch (0, &dummy_mac_pdu[0], NB_ANTENNAS, NB_ANTENNAS_TX, 120); if (be_verbose) { for (i = 0; i < chbch_size; i++) { msg ("Data %x : %x\n", i, PHY_vars->chbch_data[0].demod_pdu[i]); } } printf("PERROR_SHIFT: %d\n", PERROR_SHIFT); // // Channel estimation procedure // // for (i = 0; i < max_num_ofdm_sym; i++) // { // phy_channel_estimation_top(PHY_vars->rx_vars[0].offset,i,0,0,1); // } phy_channel_est_emos(16, 16, max_num_ofdm_sym-1, TRUE, 0); phy_cleanup (); if (be_verbose) printf ("Exiting\n"); }
void multipath_channel(channel_desc_t *desc, double **tx_sig_re, double **tx_sig_im, double **rx_sig_re, double **rx_sig_im, uint32_t length, uint8_t keep_channel) { int i,ii,j,l; struct complex rx_tmp,tx; double path_loss = pow(10,desc->path_loss_dB/20); int dd; dd = abs(desc->channel_offset); #ifdef DEBUG_CH printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length); #endif if (keep_channel) { // do nothing - keep channel } else { random_channel(desc,0); } #ifdef DEBUG_CH for (l = 0; l<(int)desc->channel_length; l++) { printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y); } printf("\n"); #endif for (i=0; i<((int)length-dd); i++) { for (ii=0; ii<desc->nb_rx; ii++) { rx_tmp.x = 0; rx_tmp.y = 0; for (j=0; j<desc->nb_tx; j++) { for (l = 0; l<(int)desc->channel_length; l++) { if ((i>=0) && (i-l)>=0) { tx.x = tx_sig_re[j][i-l]; tx.y = tx_sig_im[j][i-l]; } else { tx.x =0; tx.y =0; } rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y); rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y); } //l } // j rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss; rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss; /* if ((ii==0)&&((i%32)==0)) { printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]); } */ //rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]); //rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]); } // ii } // i }
int main() { int enb_count = 16; int ue_count = 50; double sect_angle[3]= {0,2*PI/3,4*PI/3}; double gain_max; double theta; double min_path_loss = 0; int att_enb_index; node_desc_t *enb_data[enb_count]; node_desc_t *ue_data[ue_count]; channel_desc_t *ul_channel[ue_count][enb_count]; channel_desc_t *dl_channel[ue_count][enb_count]; int count; int mcs; int ue_index, enb_index; int return_value; int nb_rb = 25; //No. of resource blocks double sinr[enb_count][2*nb_rb]; double sinr_eff[ue_count][MCS_COUNT]; double bler[ue_count][MCS_COUNT]; double gain_sec[3]; double thermal_noise; double interference; double coupling; FILE *fp; char buffer[100]; char *sinr_bler; double tlu_sinr; double tlu_bler; int line_num; char *file_name[]= {"bler_1.csv", "bler_2.csv", "bler_3.csv", "bler_4.csv", "bler_5.csv", "bler_6.csv", "bler_7.csv", "bler_8.csv", "bler_9.csv", "bler_10.csv", "bler_11.csv", "bler_12.csv", "bler_13.csv", "bler_14.csv", "bler_15.csv", "bler_16.csv", "bler_17.csv", "bler_18.csv", "bler_19.csv", "bler_20.csv", "bler_21.csv", "bler_22.csv" }; double beta[MCS_COUNT] = {0, 0, 0, 0, 0.9459960937499999, 1.2912109374999994, 1.0133789062499998, 1.000390625, 1.02392578125, 1.8595703124999998, 2.424389648437498, 2.3946533203124982, 2.5790039062499988, 2.4084960937499984, 2.782617187499999, 2.7868652343749996, 3.92099609375, 4.0392578125, 4.56109619140625, 5.03338623046875, 5.810888671875, 6.449108886718749 }; double enb_position[][2] = {{1100,1100},{1100,2100},{1100,3100},{1100,4100}, {2100,1100},{2100,2100},{2100,3100},{2100,4100}, {3100,1100},{3100,2100},{3100,3100},{3100,4100}, {4100,1100},{4100,2100},{4100,3100},{4100,4100} }; double ue_position[][2] = {{3340,4740},{1500,620},{1780,4220},{1300,3540},{780,3100}, {1140,540},{1340,3660},{860,1220},{2700,2140},{3860,3060}, {3740,1060},{1700,3060},{2180,1620},{4420,1060},{1300,3340}, {3700,3180},{3780,540},{1700,4380},{4140,4740},{820,4380}, {3300,1540},{2100,1780},{1780,2260},{1940,2620},{1580,1700}, {1460,1940},{940,1340},{2100,3540},{1260,4340},{2940,4060}, {3980,940},{540,2220},{3060,2140},{4620,3940},{4260,2820}, {3860,3500},{4140,4140},{3900,3500},{1500,2140},{2620,3820}, {3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500}, {3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300} }; randominit(0); ///////////////////////////////////////////////////////////////////////////////////////////////// int tabl_len=0; double local_table[MCS_COUNT][9][9]; for (mcs = 5; mcs <= MCS_COUNT; mcs++) { fp = fopen(file_name[mcs - 1],"r"); if (fp == NULL) { printf("ERROR: Unable to open the file\n"); } else { fgets(buffer, 100, fp); tabl_len=0; while (!feof(fp)) { sinr_bler = strtok(buffer, ";"); local_table[mcs-1][0][tabl_len] = atof(sinr_bler); sinr_bler = strtok(NULL,";"); local_table[mcs-1][1][tabl_len] = atof(sinr_bler); tabl_len++; fgets(buffer, 100, fp); } fclose(fp); } printf("\n table for mcs %d\n",mcs); for (tabl_len=0; tabl_len<9; tabl_len++) printf("%lf %lf \n ",local_table[mcs-1][0][tabl_len],local_table[mcs-1][1][tabl_len]); } //////////////////////////////////////////////////////////////////////////////////////////////////// for (enb_index = 0; enb_index < enb_count; enb_index++) enb_data[enb_index] = (node_desc_t *)(malloc(sizeof(node_desc_t))); for (ue_index = 0; ue_index < ue_count; ue_index++) ue_data[ue_index] = (node_desc_t *)(malloc(sizeof(node_desc_t))); for (enb_index = 0; enb_index < enb_count; enb_index++) { enb_data[enb_index]->x = enb_position[enb_index][0]; enb_data[enb_index]->y = enb_position[enb_index][1]; enb_data[enb_index]->tx_power_dBm = 40; enb_data[enb_index]->ant_gain_dBi = 15; enb_data[enb_index]->rx_noise_level = 5; //value in db enb_data[enb_index]->n_sectors = 3; } for (ue_index = 0; ue_index < ue_count; ue_index++) { ue_data[ue_index]->x = ue_position[ue_index][0]; ue_data[ue_index]->y = ue_position[ue_index][1]; ue_data[ue_index]->phi_rad = 2 * PI; ue_data[ue_index]->tx_power_dBm = 20; ue_data[ue_index]->ant_gain_dBi = 0; ue_data[ue_index]->rx_noise_level = 9; //value in db } for (ue_index = 0; ue_index < ue_count; ue_index++) { min_path_loss = 10000; for (enb_index = 0; enb_index < enb_count; enb_index++) { ul_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0); dl_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0); //printf("ue %d enb %d\n", ue_index, enb_index); /* Calculating the angle in the range -pi to pi from the slope */ //(ue_data[ue_index])->alpha_rad[enb_index] = (double)(atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y))); ue_data[ue_index]->alpha_rad[enb_index] = atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y)); //printf("angle is tan %lf\n", ue_data[ue_index]->alpha_rad[enb_index]); if ((ue_data[ue_index]->alpha_rad[enb_index]) < 0) { ue_data[ue_index]->alpha_rad[enb_index] = 2*PI + ue_data[ue_index]->alpha_rad[enb_index]; //printf("angle in radians is %lf\n", ue_data[ue_index]->alpha_rad[enb_index]); } for(count = 0; count < enb_data[enb_index]->n_sectors; count++) { theta = sect_angle[count] - ue_data[ue_index]->alpha_rad[enb_index]; gain_sec[count] = -(Am < (12 * pow((theta/theta_3dB),2)) ? Am : (12 * pow((theta/theta_3dB),2))); } /* gain = -min(Am , 12 * (theta/theta_3dB)^2) */ gain_max = (gain_sec[SEC1] > gain_sec[SEC2]) ? ((gain_sec[SEC1] > gain_sec[SEC3]) ? gain_sec[SEC1]:gain_sec[SEC3]) : ((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]); get_chan_desc(enb_data[enb_index], ue_data[ue_index], ul_channel[ue_index][enb_index], &scenario); get_chan_desc(enb_data[enb_index], ue_data[ue_index], dl_channel[ue_index][enb_index], &scenario); //printf("Path loss for link between ue %d and enb %d is %lf and gain is %lf \n", ue_index, enb_index, dl_channel[ue_index][enb_index]->path_loss_dB, gain_max); if (dl_channel[ue_index][enb_index]->path_loss_dB < min_path_loss) { min_path_loss = dl_channel[ue_index][enb_index]->path_loss_dB; att_enb_index = enb_index; } //return_value = random_channel(ul_channel[ue_index][enb_index]); return_value = random_channel(dl_channel[ue_index][enb_index]); /* Thermal noise is calculated using 10log10(K*T*B) K = Boltzmann´s constant T = room temperature B = bandwidth */ /* Taken as constant for the time being since the BW is not changing */ thermal_noise = -105; //value in dBm if (0 == return_value) { //freq_channel(ul_channel[ue_index][enb_index], nb_rb); freq_channel(dl_channel[ue_index][enb_index], nb_rb); coupling = MCL > (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max)) ? MCL : (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max)); //printf ("coupling factor is %lf\n", coupling); for (count = 0; count < (2 * nb_rb); count++) { sinr[enb_index][count] = enb_data[enb_index]->tx_power_dBm - coupling - (thermal_noise + ue_data[ue_index]->rx_noise_level) + 10 * log10 (pow(dl_channel[ue_index][enb_index]->chF[0][count].r, 2) + pow(dl_channel[ue_index][enb_index]->chF[0][count].i, 2)); //printf("Dl_link SNR for res. block %d is %lf\n", count, sinr[enb_index][count]); } } } for (count = 0; count < 2 * nb_rb; count++) { interference = 0; for (enb_index = 0; enb_index < enb_count; enb_index++) { if (att_enb_index != enb_index) { interference += pow(10, 0.1 * sinr[enb_index][count]); } } sinr[att_enb_index][count] -= 10*log10(1 + interference); //printf("***Dl_link SINR for res. block %d is %lf\n", count, sinr[att_enb_index][count]); for (mcs = 5; mcs <= MCS_COUNT; mcs++) { sinr_eff[ue_index][mcs-1] += exp(-(pow(10, (sinr[att_enb_index][count])/10))/beta[mcs-1]); //printf("Effective snr %lf\n",sinr_eff[ue_index][mcs-1]); //sinr_eff[ue_index][mcs] += exp(-(sinr[att_enb_index][count])/beta[mcs]); } } for (mcs = 5; mcs <= MCS_COUNT; mcs++) { //printf("mcs value %d \n",mcs); //printf("beta value %lf \n",-beta[mcs-1]); //printf("snr_eff value %lf \n",log(sinr_eff[ue_index][mcs-1])); sinr_eff[ue_index][mcs-1] = -beta[mcs-1] *log((sinr_eff[ue_index][mcs-1])/(2*nb_rb));// //printf("snr_eff value %lf \n",sinr_eff[ue_index][mcs-1]); sinr_eff[ue_index][mcs-1] = 10 * log10(sinr_eff[ue_index][mcs-1]); sinr_eff[ue_index][mcs-1] *= 10; sinr_eff[ue_index][mcs-1] = floor(sinr_eff[ue_index][mcs-1]); if ((int)sinr_eff[ue_index][mcs-1]%2) { sinr_eff[ue_index][mcs-1] += 1; } sinr_eff[ue_index][mcs-1] /= 10; //printf("Effective snr %lf \n",sinr_eff[ue_index][mcs-1]); bler[ue_index][mcs-1] = 0; /*line_num = 0; fp = fopen(file_name[mcs - 1],"r"); if (fp == NULL) { printf("ERROR: Unable to open the file\n"); } else { fgets(buffer, 100, fp); while (!feof(fp)) { line_num++; sinr_bler = strtok(buffer, ";"); tlu_sinr = atof(sinr_bler); sinr_bler = strtok(NULL,";"); tlu_bler = atof(sinr_bler); if (1 == line_num) { if (sinr_eff[ue_index][mcs-1] < tlu_sinr) { bler[ue_index][mcs-1] = 1; break; } } if (sinr_eff[ue_index][mcs-1] == tlu_sinr) { bler[ue_index][mcs-1] = tlu_bler; } fgets(buffer, 100, fp); } fclose(fp);*/ for (tabl_len=0; tabl_len<9; tabl_len++) { if(tabl_len==0) if (sinr_eff[ue_index][mcs-1] < local_table[mcs-1][0][tabl_len]) { bler[ue_index][mcs-1] = 1; break; } if (sinr_eff[ue_index][mcs-1] == local_table[mcs-1][0][tabl_len]) { bler[ue_index][mcs-1] = local_table[mcs-1][1][tabl_len]; } } //printf("\n###Dl_link UE %d attached to eNB %d \n MCS %d effective SNR %lf BLER %lf", ue_index, att_enb_index, mcs,sinr_eff[ue_index][mcs-1],bler[ue_index][mcs-1]); } //printf("\n\n"); printf("\n Ue_ix enb_ix mcs5 mcs6 mcs7 mcs8 mcs9 mcs10 mcs11 mcs12 mcs13\ mcs14 mcs15 mcs16 mcs17 mcs18 mcs19 mcs20 mcs21 mcs22\n"); printf("SINR %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\ %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", ue_index, att_enb_index, sinr_eff[ue_index][4], sinr_eff[ue_index][5], sinr_eff[ue_index][6], sinr_eff[ue_index][7], sinr_eff[ue_index][8], sinr_eff[ue_index][9], sinr_eff[ue_index][10], sinr_eff[ue_index][11], sinr_eff[ue_index][12], sinr_eff[ue_index][13], sinr_eff[ue_index][14], sinr_eff[ue_index][15], sinr_eff[ue_index][16], sinr_eff[ue_index][17], sinr_eff[ue_index][18], sinr_eff[ue_index][19], sinr_eff[ue_index][20], sinr_eff[ue_index][21], sinr_eff[ue_index][22]); printf("BLER %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\ %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", ue_index, att_enb_index, bler[ue_index][4], bler[ue_index][5], bler[ue_index][6], bler[ue_index][7], bler[ue_index][8], bler[ue_index][9], bler[ue_index][10], bler[ue_index][11], bler[ue_index][12], bler[ue_index][13], bler[ue_index][14], bler[ue_index][15], bler[ue_index][16], bler[ue_index][17], bler[ue_index][18], bler[ue_index][19], bler[ue_index][20], bler[ue_index][21], bler[ue_index][22]); } }