mbmssim.c 21 KB
Newer Older
ghaddab's avatar
ghaddab committed
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16
    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
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19 20 21 22 23
   see <http://www.gnu.org/licenses/>.

  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
ghaddab's avatar
ghaddab committed
27 28

 *******************************************************************************/
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include "SIMULATION/TOOLS/defs.h"
#include "SIMULATION/RF/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"
#include "MAC_INTERFACE/vars.h"
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

#ifdef XFORMS
50
#include "PHY/TOOLS/lte_phy_scope.h"
51 52 53 54 55 56 57 58 59
#endif //XFORMS


#include "OCG_vars.h"


PHY_VARS_eNB *PHY_vars_eNB;
PHY_VARS_UE *PHY_vars_UE;

60 61 62
void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmission_mode,uint8_t extended_prefix_flag,lte_frame_type_t frame_type, uint16_t Nid_cell,uint8_t tdd_config,
                    uint8_t N_RB_DL,uint8_t osf,uint32_t perfect_ce)
{
63 64 65 66 67 68 69 70 71 72 73 74 75

  LTE_DL_FRAME_PARMS *lte_frame_parms;


  printf("Start lte_param_init\n");
  PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB));
  PHY_vars_UE = malloc(sizeof(PHY_VARS_UE));
  //PHY_config = malloc(sizeof(PHY_CONFIG));
  mac_xface = malloc(sizeof(MAC_xface));

  srand(1);
  randominit(1);
  set_taus_seed(1);
76

77 78 79
  lte_frame_parms = &(PHY_vars_eNB->lte_frame_parms);

  lte_frame_parms->N_RB_DL            = N_RB_DL;   //50 for 10MHz and 25 for 5 MHz
80
  lte_frame_parms->N_RB_UL            = N_RB_DL;
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  lte_frame_parms->Ncp                = extended_prefix_flag;
  lte_frame_parms->Nid_cell           = Nid_cell;
  lte_frame_parms->Nid_cell_mbsfn     = 1;
  lte_frame_parms->nushift            = Nid_cell%6;
  lte_frame_parms->nb_antennas_tx     = N_tx;
  lte_frame_parms->nb_antennas_rx     = N_rx;
  lte_frame_parms->phich_config_common.phich_resource         = oneSixth;
  lte_frame_parms->tdd_config         = tdd_config;
  lte_frame_parms->frame_type         = frame_type;
  //  lte_frame_parms->Csrs = 2;
  //  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;

  init_frame_parms(lte_frame_parms,osf);
97

98
  //copy_lte_parms_to_phy_framing(lte_frame_parms, &(PHY_config->PHY_framing));
99

100 101 102 103 104 105 106 107 108 109 110
  PHY_vars_UE->is_secondary_ue = 0;
  PHY_vars_UE->lte_frame_parms = *lte_frame_parms;
  PHY_vars_eNB->lte_frame_parms = *lte_frame_parms;

  phy_init_lte_top(lte_frame_parms);
  dump_frame_parms(lte_frame_parms);

  PHY_vars_UE->PHY_measurements.n_adj_cells=2;
  PHY_vars_UE->PHY_measurements.adj_cell_id[0] = Nid_cell+1;
  PHY_vars_UE->PHY_measurements.adj_cell_id[1] = Nid_cell+2;

111 112
  lte_gold_mbsfn(lte_frame_parms,PHY_vars_UE->lte_gold_mbsfn_table,Nid_cell);
  lte_gold_mbsfn(lte_frame_parms,PHY_vars_eNB->lte_gold_mbsfn_table,Nid_cell);
113 114 115 116

  phy_init_lte_ue(PHY_vars_UE,1,0);
  phy_init_lte_eNB(PHY_vars_eNB,0,0,0);

117 118

  PHY_vars_UE->perfect_ce = perfect_ce;
119 120 121 122 123 124 125
  printf("Done lte_param_init\n");


}
DCI1E_5MHz_2A_M10PRB_TDD_t  DLSCH_alloc_pdu2_1E[2];
#define UL_RB_ALLOC 0x1ff;
#define CCCH_RB_ALLOC computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,0,2)
126 127
int main(int argc, char **argv)
{
128 129 130

  char c;

131
  int i,l,aa,aarx,k;
132
  double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0;
133
  uint8_t snr1set=0;
134 135 136 137 138 139
  double snr_step=1,input_snr_step=1;
  //mod_sym_t **txdataF;
  int **txdata;
  double **s_re,**s_im,**r_re,**r_im;
  double iqim = 0.0;
  int subframe=1;
140
  int sched_subframe;
141
  char fname[40];//, vname[40];
142 143
  uint8_t transmission_mode = 1,n_tx=1,n_rx=2;
  uint16_t Nid_cell=0;
144 145 146 147 148 149 150 151

  FILE *fd;

  int eNB_id = 0;
  unsigned char mcs=0,awgn_flag=0,round;

  int n_frames=1;
  channel_desc_t *eNB2UE;
152 153
  uint32_t nsymb,tx_lev,tx_lev_dB;
  uint8_t extended_prefix_flag=1;
154 155 156
  LTE_DL_FRAME_PARMS *frame_parms;
  int hold_channel=0;

157

158
  uint16_t NB_RB=25;
159 160

  int tdd_config=3;
161

162 163 164 165 166 167
  SCM_t channel_model=MBSFN;


  unsigned char *input_buffer;
  unsigned short input_buffer_length;
  unsigned int ret;
168 169 170

  unsigned int trials,errs[4]= {0,0,0,0}; //,round_trials[4]={0,0,0,0};

171
  uint8_t N_RB_DL=25,osf=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
172
  uint32_t perfect_ce = 0;
173

174
  lte_frame_type_t frame_type = FDD;
175

176
  uint32_t Nsoft = 1827072;
177

178
  /*
179
#ifdef XFORMS
180
  FD_lte_phy_scope_ue *form_ue;
181 182 183
  char title[255];

  fl_initialize (&argc, argv, NULL, 0, 0);
184
  form_ue = create_lte_phy_scope_ue();
185
  sprintf (title, "LTE DL SCOPE UE");
186
  fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
187
#endif
188
  */
189 190 191 192

  logInit();
  number_of_cards = 1;
  openair_daq_vars.rx_rf_mode = 1;
193

194 195 196 197
  /*
    rxdataF    = (int **)malloc16(2*sizeof(int*));
    rxdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
    rxdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
198

199 200 201 202
    rxdata    = (int **)malloc16(2*sizeof(int*));
    rxdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
    rxdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
  */
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  while ((c = getopt (argc, argv, "ahA:Cp:n:s:S:t:x:y:z:N:F:R:O:dm:i:Y")) != -1) {
    switch (c) {
    case 'a':
      awgn_flag=1;
      break;

    case 'd':
      frame_type = 0;
      break;

    case 'n':
      n_frames = atoi(optarg);
      break;

    case 'm':
      mcs=atoi(optarg);
      break;

    case 's':
      snr0 = atof(optarg);
      msg("Setting SNR0 to %f\n",snr0);
      break;

    case 'i':
      input_snr_step = atof(optarg);
      break;

    case 'S':
      snr1 = atof(optarg);
      snr1set=1;
      msg("Setting SNR1 to %f\n",snr1);
      break;

    case 'p': // subframe no;
      subframe=atoi(optarg);
      break;

    case 'z':
      n_rx=atoi(optarg);

      if ((n_rx==0) || (n_rx>2)) {
        msg("Unsupported number of rx antennas %d\n",n_rx);
        exit(-1);
      }

      break;

    case 'N':
      Nid_cell = atoi(optarg);
      break;

    case 'R':
      N_RB_DL = atoi(optarg);

Florian Kaltenberger's avatar
Florian Kaltenberger committed
257
      if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100))  {
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
        printf("Unsupported Bandwidth %d\n",N_RB_DL);
        exit(-1);
      }

      break;

    case 'O':
      osf = atoi(optarg);
      break;

    case 'Y':
      perfect_ce = 1;
      break;

    default:
    case 'h':
      printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]);
      printf("-h This message\n");
      printf("-a Use AWGN Channel\n");
      printf("-p Use extended prefix mode\n");
      printf("-d Use TDD\n");
      printf("-n Number of frames to simulate\n");
      printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB.  If n_frames is 1 then just SNR is simulated\n");
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-t Delay spread for multipath channel\n");
      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
      printf("-x Transmission mode (1,2,6 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("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
      printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
      printf("-N Nid_cell\n");
      printf("-R N_RB_DL\n");
      printf("-O oversampling factor (1,2,4,8,16)\n");
      printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
      printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
      printf("-f Output filename (.txt format) for Pe/SNR results\n");
      printf("-F Input filename (.txt format) for RX conformance testing\n");
      exit (-1);
      break;
298
    }
299 300
  }

301 302 303

  sched_subframe = (subframe+9)%10;

304 305 306 307 308 309 310
  if (awgn_flag == 1)
    channel_model = AWGN;

  // check that subframe is legal for eMBMS

  if ((subframe == 0) || (subframe == 5) ||    // TDD and FDD SFn 0,5;
      ((frame_type == FDD) && ((subframe == 4) || (subframe == 9))) || // FDD SFn 4,9;
311 312
      ((frame_type == TDD ) && ((subframe<3) || (subframe==6))))    {  // TDD SFn 1,2,6;

313 314
    printf("Illegal subframe %d for eMBMS transmission (frame_type %d)\n",subframe,frame_type);
    exit(-1);
315 316
  }

317 318 319
  if (transmission_mode==2)
    n_tx=2;

Raymond Knopp's avatar
 
Raymond Knopp committed
320
  lte_param_init(n_tx,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,tdd_config,N_RB_DL,osf,perfect_ce);
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335



  if (snr1set==0) {
    if (n_frames==1)
      snr1 = snr0+.1;
    else
      snr1 = snr0+5.0;
  }

  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);

  frame_parms = &PHY_vars_eNB->lte_frame_parms;

  if (awgn_flag == 0)
336
    sprintf(fname,"embms_%d_%d.m",mcs,N_RB_DL);
337 338
  else
    sprintf(fname,"embms_awgn_%d_%d.m",mcs,N_RB_DL);
339

340
  fd = fopen(fname,"w");
341 342

  if (awgn_flag==0)
343
    fprintf(fd,"SNR_%d_%d=[];errs_mch_%d_%d=[];mch_trials_%d_%d=[];\n",
344 345 346
            mcs,N_RB_DL,
            mcs,N_RB_DL,
            mcs,N_RB_DL);
347 348
  else
    fprintf(fd,"SNR_awgn_%d_%d=[];errs_mch_awgn_%d_%d=[];mch_trials_awgn_%d_%d=[];\n",
349 350 351 352
            mcs,N_RB_DL,
            mcs,N_RB_DL,
            mcs,N_RB_DL);

353 354 355 356 357 358 359 360 361 362 363
  fflush(fd);

  txdata = PHY_vars_eNB->lte_eNB_common_vars.txdata[0];

  s_re = malloc(2*sizeof(double*));
  s_im = malloc(2*sizeof(double*));
  r_re = malloc(2*sizeof(double*));
  r_im = malloc(2*sizeof(double*));
  nsymb = 12;

  printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, AWGN %d\n",NUMBER_OF_OFDM_CARRIERS,
364
         frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,awgn_flag);
365

366
  for (i=0; i<2; i++) {
367 368 369 370 371 372 373 374 375 376

    s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    bzero(s_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    bzero(s_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    bzero(r_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    bzero(r_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
  }
377

378
  eNB2UE = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
379 380
                                PHY_vars_UE->lte_frame_parms.nb_antennas_rx,
                                channel_model,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
381 382
				N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL),
				N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL),
383 384 385 386 387
                                0,
                                0,
                                0);

  // Create transport channel structures for 2 transport blocks (MIMO)
388
  PHY_vars_eNB->dlsch_eNB_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0);
389

390 391 392 393
  if (!PHY_vars_eNB->dlsch_eNB_MCH) {
    printf("Can't get eNB dlsch structures\n");
    exit(-1);
  }
394

395
  PHY_vars_UE->dlsch_ue_MCH[0]  = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0);
396 397 398 399 400 401 402 403 404 405 406 407

  PHY_vars_eNB->lte_frame_parms.num_MBSFN_config = 1;
  PHY_vars_eNB->lte_frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
  PHY_vars_eNB->lte_frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
  PHY_vars_eNB->lte_frame_parms.MBSFN_config[0].fourFrames_flag = 0;
  PHY_vars_eNB->lte_frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes
  PHY_vars_UE->lte_frame_parms.num_MBSFN_config = 1;
  PHY_vars_UE->lte_frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0;
  PHY_vars_UE->lte_frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0;
  PHY_vars_UE->lte_frame_parms.MBSFN_config[0].fourFrames_flag = 0;
  PHY_vars_UE->lte_frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes

408
  fill_eNB_dlsch_MCH(PHY_vars_eNB,mcs,1,0,0);
409
  fill_UE_dlsch_MCH(PHY_vars_UE,mcs,1,0,0);
410

411 412 413
  if (is_pmch_subframe(0,subframe,&PHY_vars_eNB->lte_frame_parms)==0) {
    printf("eNB is not configured for MBSFN in subframe %d\n",subframe);
    exit(-1);
414
  } else if (is_pmch_subframe(0,subframe,&PHY_vars_UE->lte_frame_parms)==0) {
415
    printf("UE is not configured for MBSFN in subframe %d\n",subframe);
416
    exit(-1);
417 418 419 420 421 422
  }


  input_buffer_length = PHY_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS/8;
  input_buffer = (unsigned char *)malloc(input_buffer_length+4);
  memset(input_buffer,0,input_buffer_length+4);
423 424

  for (i=0; i<input_buffer_length+4; i++) {
425 426 427 428 429
    input_buffer[i]= (unsigned char)(taus()&0xff);
  }


  snr_step = input_snr_step;
430 431

  for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
432
    PHY_vars_UE->frame_tx=0;
433 434
    PHY_vars_eNB->proc[sched_subframe].frame_tx=0;
    PHY_vars_eNB->proc[sched_subframe].subframe_tx=subframe;
435

436 437 438 439 440 441 442 443 444 445 446
    errs[0]=0;
    errs[1]=0;
    errs[2]=0;
    errs[3]=0;
    /*
    round_trials[0] = 0;
    round_trials[1] = 0;
    round_trials[2] = 0;
    round_trials[3] = 0;*/
    printf("********************** SNR %f (step %f)\n",SNR,snr_step);

447
    for (trials = 0; trials<n_frames; trials++) {
448 449 450
      //        printf("Trial %d\n",trials);
      fflush(stdout);
      round=0;
451

452 453 454 455 456
      //if (trials%100==0)
      //eNB2UE[0]->first_run = 1;
      eNB2UE->first_run = 1;
      memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t));

457 458
      generate_mch(PHY_vars_eNB,sched_subframe,input_buffer,0);

459 460

      PHY_ofdm_mod(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0],        // input,
461
                   txdata[0],         // output
462
                   frame_parms->ofdm_symbol_size,
463 464 465
                   LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb,                 // number of symbols
                   frame_parms->nb_prefix_samples,               // number of prefix samples
                   CYCLIC_PREFIX);
466 467

      if (n_frames==1) {
468
        write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
469 470 471
                     nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
        //if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)
        //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);
472 473 474
      }

      tx_lev = 0;
475

476
      for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
477 478 479
        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);
480
      }
481

482
      tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
483

484
      if (n_frames==1) {
485 486 487 488
        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[0][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti],

        //     PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1);
489
      }
490 491 492 493 494 495

      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++) {
          s_re[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[0][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[0][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]);
        }
496
      }
497

498 499
      //Multipath channel
      multipath_channel(eNB2UE,s_re,s_im,r_re,r_im,
500 501
                        2*frame_parms->samples_per_tti,hold_channel);

502
      //AWGN
Raymond Knopp's avatar
 
Raymond Knopp committed
503
      sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)) - SNR;
504
      sigma2 = pow(10,sigma2_dB/10);
505

506
      if (n_frames==1)
507 508
        printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB);

509
      for (i=0; i<2*frame_parms->samples_per_tti; i++) {
510 511 512 513 514 515 516
        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] =
            (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));
        }
517 518
      }

519 520 521 522 523 524 525
      for (l=2; l<12; l++) {

        slot_fep_mbsfn(PHY_vars_UE,
                       l,
                       subframe%10,
                       0,
                       0);
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
  
	if (PHY_vars_UE->perfect_ce==1) {
	  // fill in perfect channel estimates
	  freq_channel(eNB2UE,PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1);
	  for(k=0; k<NUMBER_OF_eNB_MAX; k++) {
	    for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
	      for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
		for (i=0; i<frame_parms->N_RB_DL*12; i++) {
		  ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
		  ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
		}
	      }
	    }
	  }
	}
	
	rx_pmch(PHY_vars_UE,
543 544 545
                0,
                subframe%10,
                l);
546 547 548
      }

      PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G = get_G(&PHY_vars_UE->lte_frame_parms,
549
          PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->nb_rb,
550
          PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->rb_alloc_even,
551 552 553
          get_Qm(PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->mcs),
          1,2,
          PHY_vars_UE->frame_tx,subframe);
554 555
      PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->Qm = get_Qm(PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->mcs);

556
      dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms,1,PHY_vars_UE->dlsch_ue_MCH[0],
557 558 559
                         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);

560
      ret = dlsch_decoding(PHY_vars_UE,
561 562 563 564 565 566 567
                           PHY_vars_UE->lte_ue_pdsch_vars_MCH[0]->llr[0],
                           &PHY_vars_UE->lte_frame_parms,
                           PHY_vars_UE->dlsch_ue_MCH[0],
                           PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0],
                           subframe,
                           0,0,0);

568
      if (n_frames==1)
569 570
        printf("MCH decoding returns %d\n",ret);

571
      if (ret == (1+PHY_vars_UE->dlsch_ue_MCH[0]->max_turbo_iterations))
572 573
        errs[0]++;

574
      PHY_vars_UE->frame_tx++;
575
      PHY_vars_eNB->proc[sched_subframe].frame_tx++;
576
    }
577

578 579 580
    printf("errors %d/%d (Pe %e)\n",errs[round],trials,(double)errs[round]/trials);

    if (awgn_flag==0)
Raymond Knopp's avatar
 
Raymond Knopp committed
581
      fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d  %d]; mch_trials_%d_%d =[mch_trials_%d_%d  %d];\n",
582 583 584
              mcs,N_RB_DL,mcs,N_RB_DL,SNR,
              mcs,N_RB_DL,mcs,N_RB_DL,errs[0],
              mcs,N_RB_DL,mcs,N_RB_DL,trials);
585
    else
thomasl's avatar
thomasl committed
586
      fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %d]; errs_mch_awgn_%d =[errs_mch_awgn_%f  %d]; mch_trials_awgn_%d =[mch_trials_awgn_%d %d];\n",
587 588 589 590
              mcs,N_RB_DL,mcs,N_RB_DL,SNR,
              mcs,N_RB_DL,mcs,N_RB_DL,errs[0],
              mcs,N_RB_DL,mcs,N_RB_DL,trials);

591
    fflush(fd);
592

593 594
    if (errs[0] == 0)
      break;
595
  }
596 597 598 599 600


  if (n_frames==1) {
    printf("Dumping PMCH files ( G %d)\n",PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G);
    dump_mch(PHY_vars_UE,0,
601 602
             PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G,
             subframe);
603
  }
604

605 606 607 608 609
  printf("Freeing dlsch structures\n");
  free_eNB_dlsch(PHY_vars_eNB->dlsch_eNB_MCH);
  free_ue_dlsch(PHY_vars_UE->dlsch_ue_MCH[0]);

  fclose(fd);
610

611
  printf("Freeing channel I/O\n");
612 613

  for (i=0; i<2; i++) {
614 615 616 617 618
    free(s_re[i]);
    free(s_im[i]);
    free(r_re[i]);
    free(r_im[i]);
  }
619

620 621 622 623
  free(s_re);
  free(s_im);
  free(r_re);
  free(r_im);
624

625
  //  lte_sync_time_free();
626

627
  return(0);
628 629
}