mbmssim.c 20.9 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;
gauthier's avatar
gauthier committed
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];
gauthier's avatar
gauthier committed
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;
gauthier's avatar
gauthier committed
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

gauthier's avatar
gauthier committed
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};

gauthier's avatar
gauthier committed
171
  uint8_t N_RB_DL=25,osf=1;
knopp's avatar
   
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;

knopp's avatar
   
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
knopp's avatar
   
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)
knopp's avatar
   
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
Cedric Roux's avatar
Cedric Roux committed
586
587
588
589
      fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d  %d]; mch_trials_awgn_%d =[mch_trials_awgn_%d %d];\n",
              N_RB_DL,N_RB_DL,SNR,
              N_RB_DL,N_RB_DL,errs[0],
              N_RB_DL,N_RB_DL,trials);
590

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
}