diff --git a/openair1/SIMULATION/LTE_FEMTO/femtoUtils.c b/openair1/SIMULATION/LTE_FEMTO/femtoUtils.c index 584e4f35aa..4d61e9d720 100644 --- a/openair1/SIMULATION/LTE_FEMTO/femtoUtils.c +++ b/openair1/SIMULATION/LTE_FEMTO/femtoUtils.c @@ -52,13 +52,14 @@ void _parseOptions(options_t *opts, int argc, char ** argv) { {"r", required_argument, 0, 'r'}, {"p", required_argument, 0, 'p'}, {"Q", required_argument, 0, 'Q'}, + {"O", required_argument, 0, 'O'}, {0, 0, 0, 0} }; int option_index = 0; - while ((c = getopt_long (argc, argv, "hs:S:T:n:xdt:y:z:I:j:N:o:g:faib:r:R:w:c:em:A:Dp:B:k:Q:",long_options, &option_index)) != -1) + while ((c = getopt_long (argc, argv, "hs:S:T:n:xdt:y:z:I:j:N:o:g:faib:r:R:w:c:em:A:Dp:B:k:Q:O:",long_options, &option_index)) != -1) { //printf("%c %s\n",c,optarg); switch (c) @@ -89,7 +90,7 @@ void _parseOptions(options_t *opts, int argc, char ** argv) { opts->dual_stream_UE=1; sprintf(opts->parameters,"%s -D",opts->parameters); break; - case 'e': + case 'e': opts->dci_flag=1; sprintf(opts->parameters,"%s -d",opts->parameters); break; @@ -109,6 +110,10 @@ void _parseOptions(options_t *opts, int argc, char ** argv) { case 'Q': opts->ratio=atoi(optarg); break; + case 'O': + opts->nprb1=atoi(optarg); + opts->search_prb2=1; + break; case 'T': opts->snr_step=atof(optarg); sprintf(opts->parameters,"%s -T%f",opts->parameters,opts->snr_step); diff --git a/openair1/SIMULATION/LTE_FEMTO/femtoUtils.h b/openair1/SIMULATION/LTE_FEMTO/femtoUtils.h index 9f2330685a..d2684c935b 100644 --- a/openair1/SIMULATION/LTE_FEMTO/femtoUtils.h +++ b/openair1/SIMULATION/LTE_FEMTO/femtoUtils.h @@ -54,7 +54,7 @@ typedef struct { int num_layers; u16 n_rnti; ///Modulation and code scheme - u8 mcs; + u8 mcs,mcs2; u8 pilot1,pilot2,pilot3; @@ -97,7 +97,9 @@ typedef struct { u8 p_b; s8 d_offset; int ratio; + u32 nprb1, nprb2; int prob_flag; + int search_prb2; char power[50]; diff --git a/openair1/SIMULATION/LTE_FEMTO/femtosim.c b/openair1/SIMULATION/LTE_FEMTO/femtosim.c index d6eded24cd..506117e96d 100644 --- a/openair1/SIMULATION/LTE_FEMTO/femtosim.c +++ b/openair1/SIMULATION/LTE_FEMTO/femtosim.c @@ -240,7 +240,9 @@ void _initDefaults(options_t *opts) { opts->TPC=0; opts->n_rnti=0x1234; //Ratio Network Temporary Identifiers - opts->mcs=0; + opts->mcs=0; + opts->nprb2=25; + opts->search_prb2=0; opts->extended_prefix_flag=0; //false opts->nsymb=14; // Prefix normal @@ -700,9 +702,9 @@ void _printResults(u32 *errs,u32 *round_trials,u32 dci_errors,double rate) errs[3], round_trials[3], (double)errs[0]/(round_trials[0]), - (double)errs[1]/(round_trials[1]), - (double)errs[2]/(round_trials[2]), - (double)errs[3]/(round_trials[3]), + (double)errs[1]/(round_trials[0]+round_trials[1]), + (double)errs[2]/(round_trials[0]+round_trials[1]+round_trials[2]), + (double)errs[3]/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]), dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), @@ -718,7 +720,7 @@ void _printFileResults(double SNR,double rate1, double rate,u32 *errs,u32 *rou fprintf(opts.outputFile,"%f %f;\n", SNR, (float)errs[0]/round_trials[0]); - fprintf(opts.outputBler,"%f;%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(opts.outputBler,"%f;%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, rate1, opts.mcs, @@ -732,7 +734,9 @@ void _printFileResults(double SNR,double rate1, double rate,u32 *errs,u32 *rou round_trials[2], errs[3], round_trials[3], - dci_errors); + dci_errors, + opts.nprb1, + opts.nprb2); fprintf(opts.outputBer,"%f %f;\n",SNR, BER); @@ -879,82 +883,112 @@ u8 _generate_dci_top(int num_ue_spec_dci,int num_common_dci,DCI_ALLOC_t *dci_all u32 _allocRBs(options_t *opts,int ind) { static u32 allocRB; - //double rho[16]={0.1686, 0.1759, 0.1845, 0.1946, 0.2062, 0.2194, 0.2344, 0.2510, 0.2692, 0.2889, 0.3098, 0.3318, 0.3543, 0.3772, 0.3998, 0.4220}; + static u32 allocRBs[25]={1,2,3,6,7,14,15,30,31,62,63,126,127,254,255,510,511,1022,1023,2046,2047,4094,4095,8190,8191}; switch (opts->N_RB_DL) { case 6: break; - case 25: + case 25: //search_prb2 is a flag that means nprb2 will be optimized + if (opts->search_prb2){ + switch(ind) + { + case 0: + case 2: + case 4: + case 6: + allocRB=allocRBs[opts->nprb1-1]; + //printf("nprb1: %d, mcs: %d, allocRB: %X\n",opts->nprb1,opts->mcs,allocRB); + break; + case 1: + case 3: + case 5: + case 7: + allocRB=allocRBs[opts->nprb2-1]; + opts->mcs2=29; + //printf("nprb2: %d, mcs: %d, allocRB: %X\n",opts->nprb2,opts->mcs,allocRB); + break; + } + } + else{ switch (opts->ratio){ case 1: // # of dimensions per round: 13/12 if (ind==0) { allocRB=0x7f; opts->mcs=4;} - else + else{ allocRB=0x1f80; + opts->mcs2=opts->mcs;} break; case 2: // 12/13 if (ind==0) { allocRB=0x1f80; opts->mcs=5;} - else + else{ allocRB=0x7f; + opts->mcs2=opts->mcs;} break; case 3: // 10/15 if (ind==0) { allocRB=0x1f00; opts->mcs=6;} - else + else{ allocRB=0xff; + opts->mcs2=opts->mcs;} break; case 4: // 8/17 if (ind==0) { allocRB=0x1e00; opts->mcs=7;} - else + else{ allocRB=0x1ff; + opts->mcs2=opts->mcs;} break; case 5: // 6/19 if (ind==0) { allocRB=0x1c00; opts->mcs=11;} - else + else{ allocRB=0x3ff; + opts->mcs2=opts->mcs;} break; case 6: // 4/21 if (ind==0) { allocRB=0x1800; opts->mcs=14;} - else + else{ allocRB=0x7ff; + opts->mcs2=opts->mcs;} break; case 7: // 2/23 if (ind==0) { allocRB=0x1000; opts->mcs=23;} - else + else{ allocRB=0xfff; + opts->mcs2=opts->mcs;} break; case 8: // 15/10 if (ind==0) { allocRB=0xff; opts->mcs=4;} - else + else{ allocRB=0x1f00; + opts->mcs2=opts->mcs;} break; case 9: // 17/8 if (ind==0) { allocRB=0x1ff; opts->mcs=3;} - else + else{ allocRB=0x1e00; + opts->mcs2=opts->mcs;} break; - case 91: // 2/23 force the 2nd round with QPSK + case 91: // 2/23 force the 2nd round with QPSK and llrclear if (ind==0) { allocRB=0x1000; - opts->mcs=4;} + opts->mcs=23;} else{ allocRB=0xfff; - opts->mcs=2;} + opts->mcs2=29;} break; case 92: // 6/19 force the 2nd round with QPSK if (ind==0) { @@ -962,7 +996,7 @@ u32 _allocRBs(options_t *opts,int ind) opts->mcs=11;} else{ allocRB=0x3ff; - opts->mcs=2;} + opts->mcs2=29;} break; case 93: // 4/21 force the 2nd round with QPSK if (ind==0) { @@ -970,26 +1004,45 @@ u32 _allocRBs(options_t *opts,int ind) opts->mcs=14;} else{ allocRB=0x7ff; - opts->mcs=2;} + opts->mcs2=29;} + break; + case 94: // 2/23 force the 2nd round with 16QAM + if (ind==0) { + allocRB=0x1000; + opts->mcs=23;} + else{ + allocRB=0xfff; + opts->mcs2=30;} break; case 10: // 19/6 if (ind==0) { allocRB=0x3ff; opts->mcs=3;} - else + else{ allocRB=0x1c00; + opts->mcs2=opts->mcs;} break; case 11: // 21/4 if (ind==0) { allocRB=0x7ff; opts->mcs=2;} - else + else{ allocRB=0x1800; + opts->mcs2=opts->mcs;} + break; + case 12: // 5/25 + if (ind==0) { + allocRB=0x1801; + opts->mcs=12;} + else{ + allocRB=0x7fe; + opts->mcs2=opts->mcs;} break; default: allocRB = 0x1fff; opts->mcs=0; - break;} + break;} + } break; case 50: break; @@ -999,6 +1052,12 @@ u32 _allocRBs(options_t *opts,int ind) return allocRB; } +void _get_nprb1(options_t *opts) +{ + static u32 nprb1[28]={25,23,18,14,12,10,8,7,6,6,6,5,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,1}; + opts->nprb1=nprb1[opts->mcs-1]; +} + void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC_t *dci_alloc_rx,u32 *NB_RB2,LTE_DL_FRAME_PARMS *frame_parms,u8 num_pdcch_symbols) { u32 *errs,*round_trials; @@ -1013,7 +1072,7 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC //Index and counters int aa; //Antennas index - int i,j; //General index for arrays + int i,j,prb2,ind,mcsi[1]={3}; //General index for arrays u32 round; double SNR; u32 dci_errors=0; @@ -1039,7 +1098,8 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC int eNB_id_i = 1;//Id Interferer; int idUser=0; //index of number of user, this program use just one user allowed in position 0 of PHY_vars_eNB->dlsch_eNB //Just allow transmision mode 1 - int numOFDMSymbSubcarrier; + double numOFDMSymbSubcarrier; + //Status flags s32 status; @@ -1076,13 +1136,18 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC printf("numOFDMSymbSubcarrier: %d\n",numOFDMSymbSubcarrier);*/ _initErrsRoundsTrials(&errs,&round_trials,1, opts); - - - + + for (ind=1; ind<2; ind++) + { + opts.mcs=mcsi[ind-1]; + _get_nprb1(&opts); for (SNR=opts.snr_init; SNR<=opts.snr_max; SNR+=opts.snr_step) { - printf("snr_init %f, snr_max %f \n",opts.snr_init,opts.snr_max); + opts.nprb2=PHY_vars_eNB->lte_frame_parms.N_RB_DL; + + printf("snr_init %f, snr_max %f, nprb1: %d, nprb2: %d, mcs: %d\n",opts.snr_init,opts.snr_max,opts.nprb1,opts.nprb2,opts.mcs); + for(prb2=1; prb2<=PHY_vars_eNB->lte_frame_parms.N_RB_DL; prb2++){ _initErrsRoundsTrials(&errs,&round_trials,0,opts); dci_errors=0; @@ -1093,8 +1158,8 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC totBits=0; totErrors=0; avg_ber = 0; - - for (cont_frames = 0; cont_framesfirst_run = 1; @@ -1155,7 +1220,7 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC if (round == 0) { // First round, set Ndi to 1 and rv to floor(round PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->Ndi = 1; - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (opts.transmission_mode) { @@ -1170,7 +1235,8 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC case 25: ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->ndi = 1; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rv = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc = DLSCH_RB_ALLOC2[0]; + // ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc = DLSCH_RB_ALLOC2[0]; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc = _allocRBs(&opts,0); ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->mcs = opts.mcs; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1,sizeof(DCI1_5MHz_TDD_t)); break; @@ -1189,6 +1255,8 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC } break; } + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_Qm = get_Qm(opts.mcs); + } else { // FDD TVT:not our case switch (opts.transmission_mode) { @@ -1241,7 +1309,8 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC case 25: ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->ndi = 0; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rv = round&3; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc = DLSCH_RB_ALLOC2[round]; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc = _allocRBs(&opts,round); + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->mcs = opts.mcs2; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1,sizeof(DCI1_5MHz_TDD_t)); //printf("round: %d\n",round); break; @@ -1311,10 +1380,12 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC _writeTxData("1","dci", 0, 2,opts,0,0); - /*****Sending******/ - + /*****Sending******/ //TVT:force it to use QPSK in the 2nd round + if (round==0) i_mod=get_Qm(opts.mcs); //Compute Q (modulation order) based on I_MCS. - + else + i_mod=get_Qm(opts.mcs2); + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[idUser][0]->nb_rb, PHY_vars_eNB->dlsch_eNB[idUser][0]->rb_alloc, @@ -1324,7 +1395,7 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC tbs = (double)dlsch_tbs25[get_I_TBS(PHY_vars_eNB->dlsch_eNB[idUser][0]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[idUser][0]->nb_rb-1]; - // printf("\nround: %d dlsch_enB=->nb_rb: %d mcs: %d\n",round,PHY_vars_eNB->dlsch_eNB[idUser][0]->nb_rb,opts.mcs); + //printf("\nround: %d dlsch_enB=->nb_rb: %d mcs: %d\n",round,PHY_vars_eNB->dlsch_eNB[idUser][0]->nb_rb,opts.mcs); //printf("PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->MCS %d\n",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs); //printf("tbs= %d, G=%d \n",tbs,coded_bits_per_codeword); @@ -1494,8 +1565,9 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC - _fillData(opts,data,2); - numOFDMSymbSubcarrier=PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB2[round]*12); + _fillData(opts,data,2); + NB_RB2[round]=conv_nprb(0,((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1)->rballoc,opts.N_RB_DL); + numOFDMSymbSubcarrier=(double)PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB2[round]*12.0); sigma2_dB = 10*log10((double)tx_lev) +10*log10(numOFDMSymbSubcarrier) - SNR- get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); @@ -1515,8 +1587,10 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(data.r_re,data.r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(data.r_re,data.r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); } - - i_mod = get_Qm(opts.mcs); + if (round==0) + i_mod = get_Qm(opts.mcs); + else + i_mod = get_Qm(opts.mcs2); /*********Reciver **************/ //TODO: Optimize and clean code @@ -1862,13 +1936,12 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC } //round if ((errs[0]>=opts.nframes/10) && (cont_frames>(opts.nframes/2))) - break; - - + break; } //cont_frames - + + printf("nprb1: %d, nprb2: %d, mcs: %d, mcs2: %d\n",opts.nprb1,opts.nprb2,opts.mcs, opts.mcs2); printf("\n---------------------------------------------------------------------\n"); printf("SNR = %f dB (tx_lev %f, sigma2_dB %f) BER (%f/%d=%f) BLER(%d/%d=%f)\n\t T (%d/%d = %f ) \n", SNR,(double)tx_lev_dB+10*log10(numOFDMSymbSubcarrier), @@ -1876,16 +1949,23 @@ void _makeSimulation(data_t data,options_t opts,DCI_ALLOC_t *dci_alloc,DCI_ALLOC errs[0],round_trials[0],((float)errs[0]/round_trials[0]), 0,0,0.0); - fprintf(opts.outputTrougput,"%f %f;\n",SNR, rate*((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]))); _printResults(errs,round_trials,dci_errors,rate); - _printFileResults( SNR, rate1, rate,errs,round_trials, dci_errors, opts,avg_ber/numresults); - - - if (((double)errs[0]/(round_trials[0]))<1e-2) break;//IF erros > 10% by standar + //_printFileResults( SNR, rate1, rate,errs,round_trials, dci_errors, opts,avg_ber/numresults); + //if (((double)errs[0]/(round_trials[0]))<1e-2) break;//IF errors > 1% + //TVT:if the outage is greater than some threshold stop, otherwise decrease the nprb2 + if (((double)errs[1]/(round_trials[0]+round_trials[1]))>1e-2){ //IF Pout2 > 1% + _printFileResults( SNR, rate1, rate,errs,round_trials, dci_errors, opts,avg_ber/numresults); + break; + } + opts.nprb2--; + }//nprb2 + if ((double)errs[0]/round_trials[0]<1e-2) //IF Pout1 > 1% + break; }// SNR + }//mcs }