ulsim.c 74.2 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5
6
7
8
    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.
9
10


ghaddab's avatar
ghaddab committed
11
12
13
14
    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.
15

ghaddab's avatar
ghaddab committed
16
    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
   see <http://www.gnu.org/licenses/>.
20
21

  Contact Information
ghaddab's avatar
ghaddab committed
22
23
  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
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29
30
31
32

/*! \file ulsim.c
 \brief Top-level DL simulator
 \author R. Knopp
33
 \date 2011 - 2014
34
35
36
37
38
39
40
 \version 0.1
 \company Eurecom
 \email: knopp@eurecom.fr
 \note
 \warning
*/

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <string.h>
#include <math.h>
#include <unistd.h>
#include "SIMULATION/TOOLS/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"

#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"
#include "OCG_vars.h"

#include "PHY/TOOLS/lte_phy_scope.h"

extern unsigned short dftsizes[33];
extern short *ul_ref_sigs[30][2][33];
Florian Kaltenberger's avatar
Florian Kaltenberger committed
58

59
60
61
PHY_VARS_eNB *PHY_vars_eNB;
PHY_VARS_UE *PHY_vars_UE;

Florian Kaltenberger's avatar
Florian Kaltenberger committed
62
//#define MCS_COUNT 23//added for PHY abstraction
63
64
65
66

channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
//Added for PHY abstraction
67
node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
68
69
70
node_desc_t *ue_data[NUMBER_OF_UE_MAX];
//double sinr_bler_map[MCS_COUNT][2][16];

gauthier's avatar
gauthier committed
71
extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16];
72
73
//extern  char* namepointer_chMag ;

74
int xforms=0;
75
76
77
FD_lte_phy_scope_enb *form_enb;
char title[255];

78
79
80
81
82
83
84
85
/*the following parameters are used to control the processing times*/
double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */
double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */
int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */

86
87
int main(int argc, char **argv)
{
88
89
90
91
92
93

  char c;
  int i,j,aa,u;

  int aarx,aatx;
  double channelx,channely;
94
  double sigma2, sigma2_dB=10,SNR,SNR2,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
knopp's avatar
   
knopp committed
95
  double input_snr_step=.2,snr_int=30;
96
97
98
99
100
101
102
103
  double blerr;

  int **txdata;

  LTE_DL_FRAME_PARMS *frame_parms;
  double **s_re,**s_im,**r_re,**r_im;
  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
  double iqim=0.0;
gauthier's avatar
gauthier committed
104
  uint8_t extended_prefix_flag=0;
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  int cqi_flag=0,cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives;
  int ch_realization;
  int eNB_id = 0;
  int chMod = 0 ;
  int UE_id = 0;
  unsigned char nb_rb=25,first_rb=0,mcs=0,round=0,bundling_flag=1;
  unsigned char l;

  unsigned char awgn_flag = 0 ;
  SCM_t channel_model=Rice1;


  unsigned char *input_buffer,harq_pid;
  unsigned short input_buffer_length;
  unsigned int ret;
  unsigned int coded_bits_per_codeword,nsymb;
  int subframe=3;
122
  unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0};
123
  uint8_t transmission_mode=1,n_rx=1;
124

125
  FILE *bler_fd=NULL;
126
  char bler_fname[512];
127

128
129
  FILE *time_meas_fd=NULL;
  char time_meas_fname[256];
130

131
132
133
  FILE *input_fdUL=NULL,*trch_out_fdUL=NULL;
  //  unsigned char input_file=0;
  char input_val_str[50],input_val_str2[50];
134

135
  //  FILE *rx_frame_file;
136
  FILE *csv_fdUL=NULL;
137

138
  /*
139
  FILE *fperen=NULL;
140
141
  char fperen_name[512];

142
  FILE *fmageren=NULL;
143
  char fmageren_name[512];
144

145
  FILE *flogeren=NULL;
146
  char flogeren_name[512];
147
  */
148
149
150
151

  /* FILE *ftxlev;
     char ftxlev_name[512];
  */
152

153
154
155
  char csv_fname[512];
  int n_frames=5000;
  int n_ch_rlz = 1;
156
157
  int abstx = 0;
  int hold_channel=0;
158
159
  channel_desc_t *UE2eNB;

gauthier's avatar
gauthier committed
160
  uint8_t control_only_flag = 0;
161
162
  int delay = 0;
  double maxDoppler = 0.0;
gauthier's avatar
gauthier committed
163
  uint8_t srs_flag = 0;
164

gauthier's avatar
gauthier committed
165
  uint8_t N_RB_DL=25,osf=1;
166

gauthier's avatar
gauthier committed
167
168
169
170
  uint8_t cyclic_shift = 0;
  uint8_t cooperation_flag = 0; //0 no cooperation, 1 delay diversity, 2 Alamouti
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
  uint8_t tdd_config=3,frame_type=FDD;
171

gauthier's avatar
gauthier committed
172
  uint8_t N0=30;
173
174
175
176
177
178
179
  double tx_gain=1.0;
  double cpu_freq_GHz;
  int avg_iter,iter_trials;

  uint32_t UL_alloc_pdu;
  int s,Kr,Kr_bytes;
  int dump_perf=0;
180
  int test_perf=0;
181
182
  int dump_table =0;

183
184
  double effective_rate=0.0;
  char channel_model_input[10];
185

186
187
  uint8_t max_turbo_iterations=4;
  uint8_t llr8_flag=0;
188
  int nb_rb_set = 0;
knopp's avatar
   
knopp committed
189
  int sf;
190

191
  int threequarter_fs=0;
knopp's avatar
   
knopp committed
192
193
  opp_enabled=1; // to enable the time meas

194
  cpu_freq_GHz = (double)get_cpu_freq_GHz();
195
196
197
198
199
200

  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);


  logInit();

201
  while ((c = getopt (argc, argv, "hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF")) != -1) {
202
203
204
205
206
    switch (c) {
    case 'a':
      channel_model = AWGN;
      chMod = 1;
      break;
207

208
209
210
    case 'b':
      bundling_flag = 0;
      break;
211

212
213
214
    case 'd':
      delay = atoi(optarg);
      break;
215

216
217
218
    case 'D':
      maxDoppler = atoi(optarg);
      break;
219

220
221
222
    case 'm':
      mcs = atoi(optarg);
      break;
223

224
225
226
    case 'n':
      n_frames = atoi(optarg);
      break;
227

228
229
    case 'Y':
      n_ch_rlz = atoi(optarg);
230
231
      break;

232
233
    case 'X':
      abstx= atoi(optarg);
234
235
      break;

236
    case 'g':
237
      sprintf(channel_model_input,optarg,10);
238

239
      switch((char)*optarg) {
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
      case 'A':
        channel_model=SCM_A;
        chMod = 2;
        break;

      case 'B':
        channel_model=SCM_B;
        chMod = 3;
        break;

      case 'C':
        channel_model=SCM_C;
        chMod = 4;
        break;

      case 'D':
        channel_model=SCM_D;
        chMod = 5;
        break;

      case 'E':
        channel_model=EPA;
        chMod = 6;
        break;

      case 'F':
        channel_model=EVA;
        chMod = 7;
        break;

      case 'G':
        channel_model=ETU;
        chMod = 8;
        break;

275
      case 'H':
276
277
278
279
        channel_model=Rayleigh8;
        chMod = 9;
        break;

280
      case 'I':
281
282
283
284
        channel_model=Rayleigh1;
        chMod = 10;
        break;

285
      case 'J':
286
287
288
289
        channel_model=Rayleigh1_corr;
        chMod = 11;
        break;

290
      case 'K':
291
292
293
294
        channel_model=Rayleigh1_anticorr;
        chMod = 12;
        break;

295
      case 'L':
296
297
298
299
        channel_model=Rice8;
        chMod = 13;
        break;

300
      case 'M':
301
302
303
304
        channel_model=Rice1;
        chMod = 14;
        break;

305
      case 'N':
306
307
308
309
        channel_model=AWGN;
        chMod = 1;
        break;

310
      default:
311
        printf("Unsupported channel model!\n");
312
313
        exit(-1);
        break;
314
      }
315

316
      break;
317

318
    case 's':
knopp's avatar
   
knopp committed
319
320
      snr0 = atof(optarg);
      break;
321

knopp's avatar
   
knopp committed
322
323
324
    case 'w':
      snr_int = atof(optarg);
      break;
325

knopp's avatar
   
knopp committed
326
327
    case 'e':
      input_snr_step= atof(optarg);
328
      break;
329

330
331
    case 'x':
      transmission_mode=atoi(optarg);
332

333
      if ((transmission_mode!=1) &&
334
          (transmission_mode!=2)) {
335
        printf("Unsupported transmission mode %d\n",transmission_mode);
336
        exit(-1);
337
      }
338

339
      break;
340

341
342
343
    case 'y':
      n_rx = atoi(optarg);
      break;
344

345
346
347
    case 'S':
      subframe = atoi(optarg);
      break;
348

349
350
351
352
    case 'T':
      tdd_config=atoi(optarg);
      frame_type=TDD;
      break;
353

354
355
356
    case 'p':
      extended_prefix_flag=1;
      break;
357

358
359
    case 'r':
      nb_rb = atoi(optarg);
360
      nb_rb_set = 1;
361
      break;
362

363
364
365
    case 'f':
      first_rb = atoi(optarg);
      break;
366

367
368
369
    case 'c':
      cyclic_shift = atoi(optarg);
      break;
370

371
372
373
374
    case 'E':
      threequarter_fs=1;
      break;

375
376
377
    case 'N':
      N0 = atoi(optarg);
      break;
378

379
380
381
382
383
384
    case 'o':
      srs_flag = 1;
      break;

    case 'i':
      input_fdUL = fopen(optarg,"r");
385
      printf("Reading in %s (%p)\n",optarg,input_fdUL);
386

387
      if (input_fdUL == (FILE*)NULL) {
388
        printf("Unknown file %s\n",optarg);
389
        exit(-1);
390
      }
391

392
393
      //      input_file=1;
      break;
394

395
396
    case 'A':
      beta_ACK = atoi(optarg);
397

398
      if (beta_ACK>15) {
399
400
        printf("beta_ack must be in (0..15)\n");
        exit(-1);
401
      }
402

403
      break;
404

405
406
    case 'C':
      beta_CQI = atoi(optarg);
407

408
      if ((beta_CQI>15)||(beta_CQI<2)) {
409
410
        printf("beta_cqi must be in (2..15)\n");
        exit(-1);
411
      }
412

413
      break;
414

415
416
    case 'R':
      beta_RI = atoi(optarg);
417

418
      if ((beta_RI>15)||(beta_RI<2)) {
419
420
        printf("beta_ri must be in (0..13)\n");
        exit(-1);
421
      }
422

423
      break;
424

425
426
427
    case 'Q':
      cqi_flag=1;
      break;
428

429
430
431
    case 'B':
      N_RB_DL=atoi(optarg);
      break;
432

433
434
    case 'P':
      dump_perf=1;
435
      opp_enabled=1;
436
      break;
437

438
439
440
441
    case 'O':
      test_perf=atoi(optarg);
      //print_perf =1;
      break;
442

443
444
445
    case 'L':
      llr8_flag=1;
      break;
446

447
448
449
    case 'I':
      max_turbo_iterations=atoi(optarg);
      break;
450

451
452
453
454
    case 'F':
      xforms=1;
      break;

455
456
457
    case 'Z':
      dump_table = 1;
      break;
458

459
460
    case 'h':
    default:
461
462
      printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -c cyclic_shift -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n",
             argv[0]);
463
464
465
466
      exit(1);
      break;
    }
  }
467

468
469
470
471
472
473
474
475
  lte_param_init(1,
		 n_rx,
		 1,
		 extended_prefix_flag,
		 frame_type,
		 0,
		 tdd_config,
		 N_RB_DL,
476
		 threequarter_fs,
477
478
		 osf,
		 0);
479

480
  if (nb_rb_set == 0)
481
    nb_rb = PHY_vars_eNB->lte_frame_parms.N_RB_UL;
482

483
484
  printf("1 . rxdataF_comp[0] %p\n",PHY_vars_eNB->lte_eNB_pusch_vars[0]->rxdataF_comp[0][0]);
  printf("Setting mcs = %d\n",mcs);
485
  printf("n_frames = %d\n", n_frames);
486

knopp's avatar
   
knopp committed
487
  snr1 = snr0+snr_int;
488
489
490
491
492
493
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);

  /*
    txdataF    = (int **)malloc16(2*sizeof(int*));
    txdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
    txdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
494

495
496
497
498
499
500
501
502
503
    txdata    = (int **)malloc16(2*sizeof(int*));
    txdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
    txdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
  */

  frame_parms = &PHY_vars_eNB->lte_frame_parms;

  txdata = PHY_vars_UE->lte_ue_common_vars.txdata;

504

505
506
507
508
509
510
511
  s_re = malloc(2*sizeof(double*));
  s_im = malloc(2*sizeof(double*));
  r_re = malloc(2*sizeof(double*));
  r_im = malloc(2*sizeof(double*));
  //  r_re0 = malloc(2*sizeof(double*));
  //  r_im0 = malloc(2*sizeof(double*));

512
  nsymb = (PHY_vars_eNB->lte_frame_parms.Ncp == NORMAL) ? 14 : 12;
513
514


515
  sprintf(bler_fname,"ULbler_mcs%d_nrb%d_ChannelModel%d_nsim%d.csv",mcs,nb_rb,chMod,n_frames);
516
  bler_fd = fopen(bler_fname,"w");
517
518
519
520
  if (bler_fd==NULL) {
    fprintf(stderr,"Problem creating file %s\n",bler_fname);
    exit(-1);
  }
521

522
  fprintf(bler_fd,"#SNR;mcs;nb_rb;TBS;rate;errors[0];trials[0];errors[1];trials[1];errors[2];trials[2];errors[3];trials[3]\n");
523
524

  if (test_perf != 0) {
525
526
527
528
    char hostname[1024];
    hostname[1023] = '\0';
    gethostname(hostname, 1023);
    printf("Hostname: %s\n", hostname);
529
530
531
532
    //char dirname[FILENAME_MAX];
    //sprintf(dirname, "%s//SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname);
    //mkdir(dirname, 0777);
    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_antrx%d_channel%s_tx%d.csv",
533
            N_RB_DL,mcs,n_rx,channel_model_input,transmission_mode);
534
    time_meas_fd = fopen(time_meas_fname,"w");
535
536
537
538
    if (time_meas_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
      exit(-1);
    }
539
  }
540

541
  /*
542
  if(abstx) {
543
544
545
    sprintf(fperen_name,"ULchan_estims_F_mcs%d_rb%d_chanMod%d_nframes%d_chanReal%d.m",mcs,nb_rb,chMod,n_frames,n_ch_rlz);
    fperen = fopen(fperen_name,"a+");
    fprintf(fperen,"chest_f = [");
546
547
    fclose(fperen);

548
549
550
    sprintf(fmageren_name,"ChanMag_F_mcs%d_rb%d_chanMod%d_nframes%d_chanReal%d.m",mcs,nb_rb,chMod,n_frames,n_ch_rlz);
    fmageren = fopen(fmageren_name,"a+");
    fprintf(fmageren,"mag_f = [");
551
552
    fclose(fmageren);

553
554
555
    sprintf(flogeren_name,"Log2Max_mcs%d_rb%d_chanMod%d_nframes%d_chanReal%d.m",mcs,nb_rb,chMod,n_frames,n_ch_rlz);
    flogeren = fopen(flogeren_name,"a+");
    fprintf(flogeren,"mag_f = [");
556
    fclose(flogeren);
557
  }
558
  */
559

560
561
562
563
  /*
    sprintf(ftxlev_name,"txlevel_mcs%d_rb%d_chanMod%d_nframes%d_chanReal%d.m",mcs,nb_rb,chMod,n_frames,n_ch_rlz);
    ftxlev = fopen(ftxlev_name,"a+");
    fprintf(ftxlev,"txlev = [");
564
    fclose(ftexlv);
565
  */
566
567
568

  if(abstx) {
    // CSV file
569
570
    sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_mode,mcs,nb_rb,chMod,n_frames);
    csv_fdUL = fopen(csv_fname,"w");
571
572
573
574
    if (csv_fdUL == NULL) {
      fprintf(stderr,"Problem opening file %s\n",csv_fname);
      exit(-1);
    }
575
576
    fprintf(csv_fdUL,"data_all%d=[",mcs);
  }
577

578
  for (i=0; i<2; i++) {
579
580
581
582
583
584
585
586
587
588
589
    s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    //    r_re0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    //    bzero(r_re0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    //    r_im0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
    //    bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
  }


590
591
592
593
594
595
  if (xforms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
    form_enb = create_lte_phy_scope_enb();
    sprintf (title, "LTE PHY SCOPE eNB");
    fl_show_form (form_enb->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
  }
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

  PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = 14;

  PHY_vars_UE->lte_frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
  PHY_vars_UE->lte_frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7;
  PHY_vars_UE->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = 0;
  PHY_vars_UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0;
  PHY_vars_UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0;

  PHY_vars_eNB->lte_frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
  PHY_vars_eNB->lte_frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7;

  PHY_vars_eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex = 1;
  PHY_vars_eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth = 0;
  PHY_vars_eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0;
  PHY_vars_eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0;
  PHY_vars_eNB->cooperation_flag = cooperation_flag;
  //  PHY_vars_eNB->eNB_UE_stats[0].SRS_parameters = PHY_vars_UE->SRS_parameters;

  PHY_vars_eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
  PHY_vars_eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index  = beta_RI;
  PHY_vars_eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
  PHY_vars_UE->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
  PHY_vars_UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index  = beta_RI;
  PHY_vars_UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
621
622

  PHY_vars_UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1;
623

624
625
626
627
628
  printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8);

  UE2eNB = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
                                PHY_vars_UE->lte_frame_parms.nb_antennas_rx,
                                channel_model,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
629
630
				N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_UL),
				N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_UL),
631
632
633
634
635
636
637
                                forgetting_factor,
                                delay,
                                0);
  // set Doppler
  UE2eNB->max_Doppler = maxDoppler;

  // NN: N_RB_UL has to be defined in ulsim
638
639
  PHY_vars_eNB->ulsch_eNB[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0);
  PHY_vars_UE->ulsch_ue[0]   = new_ue_ulsch(N_RB_DL,0);
640

641
  // Create transport channel structures for 2 transport blocks (MIMO)
642
  for (i=0; i<2; i++) {
643
644
    PHY_vars_eNB->dlsch_eNB[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0);
    PHY_vars_UE->dlsch_ue[0][i]  = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
645

646
647
648
649
    if (!PHY_vars_eNB->dlsch_eNB[0][i]) {
      printf("Can't get eNB dlsch structures\n");
      exit(-1);
    }
650

651
652
653
654
    if (!PHY_vars_UE->dlsch_ue[0][i]) {
      printf("Can't get ue dlsch structures\n");
      exit(-1);
    }
655

656
657
658
    PHY_vars_eNB->dlsch_eNB[0][i]->rnti = 14;
    PHY_vars_UE->dlsch_ue[0][i]->rnti   = 14;

659
  } 
660

661
662
663
664

  switch (PHY_vars_eNB->lte_frame_parms.N_RB_UL) {
  case 6:
    break;
665

666
667
668
669
670
671
672
673
674
675
676
  case 25:
    if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) {
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->cshift  = 0;
      ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu)->dai     = 1;
677
    } else {
678
679
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
gauthier's avatar
gauthier committed
680
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
681
682
683
684
685
686
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu)->cshift  = 0;
    }
687

688
    break;
689

690
691
692
693
694
695
696
697
698
699
700
  case 50:
    if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) {
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->cshift  = 0;
      ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu)->dai     = 1;
701
    } else {
702
703
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
gauthier's avatar
gauthier committed
704
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
705
706
707
708
709
710
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu)->cshift  = 0;
    }
711

712
    break;
713

714
715
716
717
718
719
720
721
722
723
724
  case 100:
    if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) {
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->cshift  = 0;
      ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu)->dai     = 1;
725
    } else {
726
727
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->type    = 0;
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
gauthier's avatar
gauthier committed
728
      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,PHY_vars_eNB->lte_frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->rballoc,*(uint32_t *)&UL_alloc_pdu);
729
730
731
732
733
734
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->mcs     = mcs;
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->ndi     = 1;
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->TPC     = 0;
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->cqi_req = cqi_flag&1;
      ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu)->cshift  = 0;
    }
735

736
    break;
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
  default:
    break;
  }


  PHY_vars_UE->PHY_measurements.rank[0] = 0;
  PHY_vars_UE->transmission_mode[0] = 2;
  PHY_vars_UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing;
  PHY_vars_eNB->transmission_mode[0] = 2;
  PHY_vars_eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing;
  PHY_vars_UE->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  PHY_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  PHY_vars_UE->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  PHY_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  PHY_vars_UE->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
  PHY_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
knopp's avatar
   
knopp committed
754
  PHY_vars_UE->frame_tx=1;
knopp's avatar
   
knopp committed
755

756
757
  for (sf=0; sf<10; sf++) {
    PHY_vars_eNB->proc[sf].frame_tx=1;
knopp's avatar
   
knopp committed
758
759
760
761
    PHY_vars_eNB->proc[sf].subframe_tx=sf;
    PHY_vars_eNB->proc[sf].frame_rx=1;
    PHY_vars_eNB->proc[sf].subframe_rx=sf;
  }
knopp's avatar
   
knopp committed
762

763
  printf("Init UL hopping UE\n");
764
  init_ul_hopping(&PHY_vars_UE->lte_frame_parms);
765
  printf("Init UL hopping eNB\n");
766
767
  init_ul_hopping(&PHY_vars_eNB->lte_frame_parms);

knopp's avatar
   
knopp committed
768
  PHY_vars_eNB->proc[subframe].frame_rx = PHY_vars_UE->frame_tx;
769

knopp's avatar
   
knopp committed
770
  if (ul_subframe2pdcch_alloc_subframe(&PHY_vars_eNB->lte_frame_parms,subframe) > subframe) // allocation was in previous frame
knopp's avatar
   
knopp committed
771
    PHY_vars_eNB->proc[ul_subframe2pdcch_alloc_subframe(&PHY_vars_eNB->lte_frame_parms,subframe)].frame_tx = (PHY_vars_UE->frame_tx-1)&1023;
knopp's avatar
   
knopp committed
772

773
774
775
  PHY_vars_UE->dlsch_ue[0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&PHY_vars_eNB->lte_frame_parms,subframe)].send_harq_status = 1;


knopp's avatar
   
knopp committed
776
  //  printf("UE frame %d, eNB frame %d (eNB frame_tx %d)\n",PHY_vars_UE->frame,PHY_vars_eNB->proc[subframe].frame_rx,PHY_vars_eNB->proc[ul_subframe2pdcch_alloc_subframe(&PHY_vars_eNB->lte_frame_parms,subframe)].frame_tx);
knopp's avatar
   
knopp committed
777
  PHY_vars_UE->frame_tx = (PHY_vars_UE->frame_tx-1)&1023;
778
779

  generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu,
780
781
782
783
784
785
786
787
788
789
                                    14,
                                    ul_subframe2pdcch_alloc_subframe(&PHY_vars_UE->lte_frame_parms,subframe),
                                    format0,
                                    PHY_vars_UE,
                                    SI_RNTI,
                                    0,
                                    P_RNTI,
                                    CBA_RNTI,
                                    0,
                                    srs_flag);
790
791
792
793

  //  printf("RIV %d\n",UL_alloc_pdu.rballoc);

  generate_eNB_ulsch_params_from_dci((void *)&UL_alloc_pdu,
794
795
796
797
798
799
800
801
802
803
                                     14,
                                     ul_subframe2pdcch_alloc_subframe(&PHY_vars_eNB->lte_frame_parms,subframe),
                                     format0,
                                     0,
                                     PHY_vars_eNB,
                                     SI_RNTI,
                                     0,
                                     P_RNTI,
                                     CBA_RNTI,
                                     srs_flag);
804

805
806
807
808
809
810
811
  coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb;

  if (cqi_flag == 1) coded_bits_per_codeword-=PHY_vars_UE->ulsch_ue[0]->O;

  rate = (double)dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1]/(coded_bits_per_codeword);

  printf("Rate = %f (mod %d), coded bits %d\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword);
812
813


knopp's avatar
   
knopp committed
814
  PHY_vars_UE->frame_tx = (PHY_vars_UE->frame_tx+1)&1023;
815
816
817
818


  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {

819
820
821
822
823
824
    /*
      if(abstx){
      int ulchestim_f[300*12];
      int ulchestim_t[2*(frame_parms->ofdm_symbol_size)];
      }
    */
825
826

    if(abstx) {
827
828
829
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
      saving_bler=1;
    }
830

831

knopp's avatar
   
knopp committed
832
833
    //    if ((subframe>5) || (subframe < 4))
    //      PHY_vars_UE->frame++;
834
835

    for (SNR=snr0; SNR<snr1; SNR+=input_snr_step) {
836
837
838
839
840
841
842
843
844
845
846
847
848
      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;
      cqi_errors=0;
      ack_errors=0;
      cqi_crc_falsepositives=0;
      cqi_crc_falsenegatives=0;
      round=0;
849

850
851
      //randominit(0);

knopp's avatar
   
knopp committed
852

knopp's avatar
   
knopp committed
853
      harq_pid = subframe2harq_pid(&PHY_vars_UE->lte_frame_parms,PHY_vars_UE->frame_tx,subframe);
854
855
      input_buffer_length = PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->TBS/8;
      input_buffer = (unsigned char *)malloc(input_buffer_length+4);
knopp's avatar
   
knopp committed
856
      //      printf("UL frame %d/subframe %d, harq_pid %d\n",PHY_vars_UE->frame,subframe,harq_pid);
857
      if (input_fdUL == NULL) {
858

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879

        if (n_frames == 1) {
          trch_out_fdUL= fopen("ulsch_trchUL.txt","w");

          for (i=0; i<input_buffer_length; i++) {
            input_buffer[i] = taus()&0xff;

            for (j=0; j<8; j++)
              fprintf(trch_out_fdUL,"%d\n",(input_buffer[i]>>(7-j))&1);
          }

          fclose(trch_out_fdUL);
        } else {
          for (i=0; i<input_buffer_length; i++)
            input_buffer[i] = taus()&0xff;
        }
      } else {
        n_frames=1;
        i=0;

        while (!feof(input_fdUL)) {
880
          ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2);
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

          if ((i%4)==0) {
            ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL));
            ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL));

            if ((i/4)<100)
              printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,);
          }

          i++;

          if (i>(FRAME_LENGTH_SAMPLES))
            break;
        }

        printf("Read in %d samples\n",i/4);
        //      write_output("txsig0UL.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1);
        //    write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
        tx_lev = signal_energy(&txdata[0][0],
                               OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
        tx_lev_dB = (unsigned int) dB_fixed(tx_lev);

903
904
      }

905
906
      avg_iter = 0;
      iter_trials=0;
907
      reset_meas(&PHY_vars_UE->phy_proc_tx);
908
909
910
911
912
913
914
915
      reset_meas(&PHY_vars_UE->ofdm_mod_stats);
      reset_meas(&PHY_vars_UE->ulsch_modulation_stats);
      reset_meas(&PHY_vars_UE->ulsch_encoding_stats);
      reset_meas(&PHY_vars_UE->ulsch_interleaving_stats);
      reset_meas(&PHY_vars_UE->ulsch_rate_matching_stats);
      reset_meas(&PHY_vars_UE->ulsch_turbo_encoding_stats);
      reset_meas(&PHY_vars_UE->ulsch_segmentation_stats);
      reset_meas(&PHY_vars_UE->ulsch_multiplexing_stats);
916

917
      reset_meas(&PHY_vars_eNB->phy_proc_rx);
918
919
920
921
922
923
924
925
926
      reset_meas(&PHY_vars_eNB->ofdm_demod_stats);
      reset_meas(&PHY_vars_eNB->ulsch_channel_estimation_stats);
      reset_meas(&PHY_vars_eNB->ulsch_freq_offset_estimation_stats);
      reset_meas(&PHY_vars_eNB->rx_dft_stats);
      reset_meas(&PHY_vars_eNB->ulsch_decoding_stats);
      reset_meas(&PHY_vars_eNB->ulsch_turbo_decoding_stats);
      reset_meas(&PHY_vars_eNB->ulsch_deinterleaving_stats);
      reset_meas(&PHY_vars_eNB->ulsch_demultiplexing_stats);
      reset_meas(&PHY_vars_eNB->ulsch_rate_unmatching_stats);
927
      reset_meas(&PHY_vars_eNB->ulsch_tc_init_stats);
928
929
930
931
932
933
934
      reset_meas(&PHY_vars_eNB->ulsch_tc_alpha_stats);
      reset_meas(&PHY_vars_eNB->ulsch_tc_beta_stats);
      reset_meas(&PHY_vars_eNB->ulsch_tc_gamma_stats);
      reset_meas(&PHY_vars_eNB->ulsch_tc_ext_stats);
      reset_meas(&PHY_vars_eNB->ulsch_tc_intl1_stats);
      reset_meas(&PHY_vars_eNB->ulsch_tc_intl2_stats);

935
936
937
      // initialization
      struct list time_vector_tx;
      initialize(&time_vector_tx);
938
939
940
941
942
943
944
      struct list time_vector_tx_ifft;
      initialize(&time_vector_tx_ifft);
      struct list time_vector_tx_mod;
      initialize(&time_vector_tx_mod);
      struct list time_vector_tx_enc;
      initialize(&time_vector_tx_enc);

945
946
      struct list time_vector_rx;
      initialize(&time_vector_rx);
947
948
949
950
951
952
      struct list time_vector_rx_fft;
      initialize(&time_vector_rx_fft);
      struct list time_vector_rx_demod;
      initialize(&time_vector_rx_demod);
      struct list time_vector_rx_dec;
      initialize(&time_vector_rx_dec);
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999

      for (trials = 0; trials<n_frames; trials++) {
        //      printf("*");
        //        PHY_vars_UE->frame++;
        //        PHY_vars_eNB->frame++;

        fflush(stdout);
        round=0;

        while (round < 4) {
          PHY_vars_eNB->ulsch_eNB[0]->harq_processes[harq_pid]->round=round;
          PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->round=round;
          //  printf("Trial %d : Round %d ",trials,round);
          round_trials[round]++;

          if (round == 0) {
            //PHY_vars_eNB->ulsch_eNB[0]->harq_processes[harq_pid]->Ndi = 1;
            PHY_vars_eNB->ulsch_eNB[0]->harq_processes[harq_pid]->rvidx = round>>1;
            //PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->Ndi = 1;
            PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->rvidx = round>>1;
          } else {
            //PHY_vars_eNB->ulsch_eNB[0]->harq_processes[harq_pid]->Ndi = 0;
            PHY_vars_eNB->ulsch_eNB[0]->harq_processes[harq_pid]->rvidx = round>>1;
            //PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->Ndi = 0;
            PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->rvidx = round>>1;
          }


          /////////////////////
          if (abstx) {
            if (trials==0 && round==0 && SNR==snr0) { //generate a new channel
              hold_channel = 0;
              flagMag=0;
            } else {
              hold_channel = 1;
              flagMag = 1;
            }
          } else {
            hold_channel = 0;
            flagMag=1;
          }

          ///////////////////////////////////////

          if (input_fdUL == NULL) {

            start_meas(&PHY_vars_UE->phy_proc_tx);
1000

1001
#ifdef OFDMA_ULSCH
1002
1003
1004
1005
1006
1007

            if (srs_flag)
              generate_srs_tx(PHY_vars_UE,0,AMP,subframe);

            generate_drs_pusch(PHY_vars_UE,0,AMP,subframe,first_rb,nb_rb,0);

1008
#else
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044

            if (srs_flag)
              generate_srs_tx(PHY_vars_UE,0,AMP,subframe);

            generate_drs_pusch(PHY_vars_UE,0,
                               AMP,subframe,
                               PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->first_rb,
                               PHY_vars_UE->ulsch_ue[0]->harq_processes[harq_pid]->nb_rb,
                               0);
#endif

            if ((cqi_flag == 1) && (n_frames == 1) ) {
              printf("CQI information (O %d) %d %d\n",PHY_vars_UE->ulsch_ue[0]->O,
                     PHY_vars_UE->ulsch_ue[0]->o[0],PHY_vars_UE->ulsch_ue[0]->o[1]);
              print_CQI(PHY_vars_UE->ulsch_ue[0]->o,PHY_vars_UE->ulsch_ue[0]->uci_format,PHY_vars_UE->lte_frame_parms.N_RB_DL,0);
            }

            PHY_vars_UE->ulsch_ue[0]->o_ACK[0] = taus()&1;

            start_meas(&PHY_vars_UE->ulsch_encoding_stats);

            if (ulsch_encoding(input_buffer,
                               PHY_vars_UE,
                               harq_pid,
                               eNB_id,
                               2, // transmission mode
                               control_only_flag,
                               1// Nbundled
                              )==-1) {
              printf("ulsim.c Problem with ulsch_encoding\n");
              exit(-1);
            }

            stop_meas(&PHY_vars_UE->ulsch_encoding_stats);

            start_meas(&PHY_vars_UE->ulsch_modulation_stats);
1045
#ifdef OFDMA_ULSCH
1046
1047
1048
1049
1050
1051
1052
            ulsch_modulation(PHY_vars_UE->lte_ue_common_vars.txdataF,AMP,
                             PHY_vars_UE->frame_tx,subframe,&PHY_vars_UE->lte_frame_parms,PHY_vars_UE->ulsch_ue[0]);
#else
            //    printf("Generating PUSCH in subframe %d with amp %d, nb_rb %d\n",subframe,AMP,nb_rb);
            ulsch_modulation(PHY_vars_UE->lte_ue_common_vars.txdataF,AMP,
                             PHY_vars_UE->frame_tx,subframe,&PHY_vars_UE->lte_frame_parms,
                             PHY_vars_UE->ulsch_ue[0]);
1053
#endif
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
            stop_meas(&PHY_vars_UE->ulsch_modulation_stats);

            if (n_frames==1) {
              write_output("txsigF0UL.m","txsF0", &PHY_vars_UE->lte_ue_common_vars.txdataF[0][PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size*nsymb*subframe],PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size*nsymb,1,
                           1);
              //write_output("txsigF1.m","txsF1", PHY_vars_UE->lte_ue_common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1);
            }

            tx_lev=0;
            start_meas(&PHY_vars_UE->ofdm_mod_stats);

            for (aa=0; aa<1; aa++) {
1066
              if (frame_parms->Ncp == EXTENDED)
1067
1068
                PHY_ofdm_mod(&PHY_vars_UE->lte_ue_common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],        // input
                             &txdata[aa][PHY_vars_eNB->lte_frame_parms.samples_per_tti*subframe],         // output
1069
                             PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,
1070
1071
1072
1073
1074
1075
1076
1077
1078
                             nsymb,                 // number of symbols
                             PHY_vars_UE->lte_frame_parms.nb_prefix_samples,               // number of prefix samples
                             CYCLIC_PREFIX);
              else
                normal_prefix_mod(&PHY_vars_UE->lte_ue_common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],
                                  &txdata[aa][PHY_vars_eNB->lte_frame_parms.samples_per_tti*subframe],
                                  nsymb,
                                  frame_parms);

1079
#ifndef OFDMA_ULSCH
1080
1081
              apply_7_5_kHz(PHY_vars_UE,PHY_vars_UE->lte_ue_common_vars.txdata[aa],subframe<<1);
              apply_7_5_kHz(PHY_vars_UE,PHY_vars_UE->lte_ue_common_vars.txdata[aa],1+(subframe<<1));
1082
#endif
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

              stop_meas(&PHY_vars_UE->ofdm_mod_stats);
              stop_meas(&PHY_vars_UE->phy_proc_tx);
              tx_lev += signal_energy(&txdata[aa][PHY_vars_eNB->lte_frame_parms.samples_per_tti*subframe],
                                      PHY_vars_eNB->lte_frame_parms.samples_per_tti);

            }
          }  // input_fd == NULL


          tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev);

          if (n_frames==1) {
            write_output("txsig0UL.m","txs0", &txdata[0][PHY_vars_eNB->lte_frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
            //        write_output("txsig1UL.m","txs1", &txdata[1][PHY_vars_eNB->lte_frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
          }

          //AWGN
          //Set target wideband RX noise level to N0
          sigma2_dB = N0;//10*log10((double)tx_lev)  +10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(PHY_vars_UE->lte_frame_parms.N_RB_DL*12)) - SNR;
          sigma2 = pow(10,sigma2_dB/10);

          // compute tx_gain to achieve target SNR (per resource element!)
          tx_gain = sqrt(pow(10.0,.1*(N0+SNR))*(nb_rb*12/(double)PHY_vars_UE->lte_frame_parms.ofdm_symbol_size)/(double)tx_lev);

          if (n_frames==1)
            printf("tx_lev = %d (%d.%d dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain));


          // fill measurement symbol (19) with noise
          for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) {
            for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) {

              ((short*) &PHY_vars_eNB->lte_eNB_common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
              ((short*) &PHY_vars_eNB->lte_eNB_common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
            }
          }

          // multipath channel

          for (i=0; i<PHY_vars_eNB->lte_frame_parms.samples_per_tti; i++) {