ulsim.c 64.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
23
24
/*! \file ulsim.c
 \brief Top-level DL simulator
 \author R. Knopp
25
 \date 2011 - 2014
26
27
28
29
30
31
32
 \version 0.1
 \company Eurecom
 \email: knopp@eurecom.fr
 \note
 \warning
*/

33
34
35
36
37
38
39
40
41
42
43
44
45
#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"

46
47
#include "unitary_defs.h"

48
49
#include "PHY/TOOLS/lte_phy_scope.h"

50
51
52
53
PHY_VARS_eNB *eNB;
PHY_VARS_UE *UE;


Florian Kaltenberger's avatar
Florian Kaltenberger committed
54

55

Florian Kaltenberger's avatar
Florian Kaltenberger committed
56
//#define MCS_COUNT 23//added for PHY abstraction
57
58
59
60

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
61
node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
62
63
64
node_desc_t *ue_data[NUMBER_OF_UE_MAX];
//double sinr_bler_map[MCS_COUNT][2][16];

gauthier's avatar
gauthier committed
65
extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16];
66
67
//extern  char* namepointer_chMag ;

68
int xforms=0;
69
70
71
FD_lte_phy_scope_enb *form_enb;
char title[255];

72
73
74
75
76
77
78
79
/*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 */

knopp's avatar
knopp committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mcs,int ndi,int cqi_flag) {

  switch (eNB->frame_parms.N_RB_UL) {
  case 6:
    break;

  case 25:
    if (eNB->frame_parms.frame_type == TDD) {
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->type    = 0;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->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,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->mcs     = mcs;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->ndi     = ndi;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->TPC     = 0;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->cshift  = 0;
      ((DCI0_5MHz_TDD_1_6_t*)UL_dci)->dai     = 1;
    } else {
      ((DCI0_5MHz_FDD_t*)UL_dci)->type    = 0;
      ((DCI0_5MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
      //      printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci);
      ((DCI0_5MHz_FDD_t*)UL_dci)->mcs     = mcs;
      ((DCI0_5MHz_FDD_t*)UL_dci)->ndi     = ndi;
      ((DCI0_5MHz_FDD_t*)UL_dci)->TPC     = 0;
      ((DCI0_5MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_5MHz_FDD_t*)UL_dci)->cshift  = 0;
    }

    break;

  case 50:
    if (eNB->frame_parms.frame_type == TDD) {
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->type    = 0;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->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,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->mcs     = mcs;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->ndi     = ndi;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->TPC     = 0;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->cshift  = 0;
      ((DCI0_10MHz_TDD_1_6_t*)UL_dci)->dai     = 1;
    } else {
      ((DCI0_10MHz_FDD_t*)UL_dci)->type    = 0;
      ((DCI0_10MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->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,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
      ((DCI0_10MHz_FDD_t*)UL_dci)->mcs     = mcs;
      ((DCI0_10MHz_FDD_t*)UL_dci)->ndi     = ndi;
      ((DCI0_10MHz_FDD_t*)UL_dci)->TPC     = 0;
      ((DCI0_10MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_10MHz_FDD_t*)UL_dci)->cshift  = 0;
    }

    break;

  case 100:
    if (eNB->frame_parms.frame_type == TDD) {
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->type    = 0;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc = computeRIV(eNB->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,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->mcs     = mcs;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->ndi     = ndi;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->TPC     = 0;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->cshift  = 0;
      ((DCI0_20MHz_TDD_1_6_t*)UL_dci)->dai     = 1;
    } else {
      ((DCI0_20MHz_FDD_t*)UL_dci)->type    = 0;
      ((DCI0_20MHz_FDD_t*)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb);// 12 RBs from position 8
      //   printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci);
      ((DCI0_20MHz_FDD_t*)UL_dci)->mcs     = mcs;
      ((DCI0_20MHz_FDD_t*)UL_dci)->ndi     = ndi;
      ((DCI0_20MHz_FDD_t*)UL_dci)->TPC     = 0;
      ((DCI0_20MHz_FDD_t*)UL_dci)->cqi_req = cqi_flag&1;
      ((DCI0_20MHz_FDD_t*)UL_dci)->cshift  = 0;
    }

    break;

  default:
    break;
  }

}

extern void eNB_fep_full(PHY_VARS_eNB *eNB);
166
extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB);
knopp's avatar
knopp committed
167

168
169
int main(int argc, char **argv)
{
170
171
172
173
174
175

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

  int aarx,aatx;
  double channelx,channely;
176
  double sigma2, sigma2_dB=10,SNR,SNR2,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
knopp's avatar
   
knopp committed
177
  double input_snr_step=.2,snr_int=30;
178
179
180
181
182
  double blerr;

  int **txdata;

  LTE_DL_FRAME_PARMS *frame_parms;
183
  double s_re[2][30720],s_im[2][30720],r_re[2][30720],r_im[2][30720];
184
185
  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
186
  uint8_t extended_prefix_flag=0;
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
  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;
204
  unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0};
205
  uint8_t transmission_mode=1,n_rx=1;
206

207
  FILE *bler_fd=NULL;
208
  char bler_fname[512];
209

210
211
  FILE *time_meas_fd=NULL;
  char time_meas_fname[256];
212

213
214
215
  FILE *input_fdUL=NULL,*trch_out_fdUL=NULL;
  //  unsigned char input_file=0;
  char input_val_str[50],input_val_str2[50];
216

217
  //  FILE *rx_frame_file;
218
  FILE *csv_fdUL=NULL;
219

220
  /*
221
  FILE *fperen=NULL;
222
223
  char fperen_name[512];

224
  FILE *fmageren=NULL;
225
  char fmageren_name[512];
226

227
  FILE *flogeren=NULL;
228
  char flogeren_name[512];
229
  */
230
231
232
233

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

235
236
237
  char csv_fname[512];
  int n_frames=5000;
  int n_ch_rlz = 1;
238
239
  int abstx = 0;
  int hold_channel=0;
240
241
  channel_desc_t *UE2eNB;

gauthier's avatar
gauthier committed
242
  uint8_t control_only_flag = 0;
243
244
  int delay = 0;
  double maxDoppler = 0.0;
gauthier's avatar
gauthier committed
245
  uint8_t srs_flag = 0;
246

gauthier's avatar
gauthier committed
247
  uint8_t N_RB_DL=25,osf=1;
248

gauthier's avatar
gauthier committed
249
250
251
252
  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;
253

gauthier's avatar
gauthier committed
254
  uint8_t N0=30;
255
256
257
258
259
260
261
  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;
262
  int test_perf=0;
263
264
  int dump_table =0;

265
266
  double effective_rate=0.0;
  char channel_model_input[10];
267

268
  uint8_t max_turbo_iterations=4;
269
  uint8_t parallel_flag=0;
270
  int nb_rb_set = 0;
271

272
  int threequarter_fs=0;
knopp's avatar
knopp committed
273
274
  int ndi;

knopp's avatar
   
knopp committed
275
276
  opp_enabled=1; // to enable the time meas

277
  cpu_freq_GHz = (double)get_cpu_freq_GHz();
278
279
280
281
282
283

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


  logInit();

284
  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) {
285
286
287
288
289
    switch (c) {
    case 'a':
      channel_model = AWGN;
      chMod = 1;
      break;
290

291
292
293
    case 'b':
      bundling_flag = 0;
      break;
294

295
296
297
    case 'd':
      delay = atoi(optarg);
      break;
298

299
300
301
    case 'D':
      maxDoppler = atoi(optarg);
      break;
302

303
304
305
    case 'm':
      mcs = atoi(optarg);
      break;
306

307
308
309
    case 'n':
      n_frames = atoi(optarg);
      break;
310

311
312
    case 'Y':
      n_ch_rlz = atoi(optarg);
313
314
      break;

315
316
    case 'X':
      abstx= atoi(optarg);
317
318
      break;

319
    case 'g':
320
      sprintf(channel_model_input,optarg,10);
321

322
      switch((char)*optarg) {
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
      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;

358
      case 'H':
359
360
361
362
        channel_model=Rayleigh8;
        chMod = 9;
        break;

363
      case 'I':
364
365
366
367
        channel_model=Rayleigh1;
        chMod = 10;
        break;

368
      case 'J':
369
370
371
372
        channel_model=Rayleigh1_corr;
        chMod = 11;
        break;

373
      case 'K':
374
375
376
377
        channel_model=Rayleigh1_anticorr;
        chMod = 12;
        break;

378
      case 'L':
379
380
381
382
        channel_model=Rice8;
        chMod = 13;
        break;

383
      case 'M':
384
385
386
387
        channel_model=Rice1;
        chMod = 14;
        break;

388
      case 'N':
389
390
391
392
        channel_model=AWGN;
        chMod = 1;
        break;

393
      default:
394
        printf("Unsupported channel model!\n");
395
396
        exit(-1);
        break;
397
      }
398

399
      break;
400

401
    case 's':
knopp's avatar
   
knopp committed
402
403
      snr0 = atof(optarg);
      break;
404

knopp's avatar
   
knopp committed
405
406
407
    case 'w':
      snr_int = atof(optarg);
      break;
408

knopp's avatar
   
knopp committed
409
410
    case 'e':
      input_snr_step= atof(optarg);
411
      break;
412

413
414
    case 'x':
      transmission_mode=atoi(optarg);
415

416
      if ((transmission_mode!=1) &&
417
          (transmission_mode!=2)) {
418
        printf("Unsupported transmission mode %d\n",transmission_mode);
419
        exit(-1);
420
      }
421

422
      break;
423

424
425
426
    case 'y':
      n_rx = atoi(optarg);
      break;
427

428
429
430
    case 'S':
      subframe = atoi(optarg);
      break;
431

432
433
434
435
    case 'T':
      tdd_config=atoi(optarg);
      frame_type=TDD;
      break;
436

437
438
439
    case 'p':
      extended_prefix_flag=1;
      break;
440

441
442
    case 'r':
      nb_rb = atoi(optarg);
443
      nb_rb_set = 1;
444
      break;
445

446
447
448
    case 'f':
      first_rb = atoi(optarg);
      break;
449

450
451
452
    case 'c':
      cyclic_shift = atoi(optarg);
      break;
453

454
455
456
457
    case 'E':
      threequarter_fs=1;
      break;

458
459
460
    case 'N':
      N0 = atoi(optarg);
      break;
461

462
463
464
465
466
467
    case 'o':
      srs_flag = 1;
      break;

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

470
      if (input_fdUL == (FILE*)NULL) {
471
        printf("Unknown file %s\n",optarg);
472
        exit(-1);
473
      }
474

475
476
      //      input_file=1;
      break;
477

478
479
    case 'A':
      beta_ACK = atoi(optarg);
480

481
      if (beta_ACK>15) {
482
483
        printf("beta_ack must be in (0..15)\n");
        exit(-1);
484
      }
485

486
      break;
487

488
489
    case 'C':
      beta_CQI = atoi(optarg);
490

491
      if ((beta_CQI>15)||(beta_CQI<2)) {
492
493
        printf("beta_cqi must be in (2..15)\n");
        exit(-1);
494
      }
495

496
      break;
497

498
499
    case 'R':
      beta_RI = atoi(optarg);
500

501
      if ((beta_RI>15)||(beta_RI<2)) {
502
503
        printf("beta_ri must be in (0..13)\n");
        exit(-1);
504
      }
505

506
      break;
507

508
509
510
    case 'Q':
      cqi_flag=1;
      break;
511

512
513
514
    case 'B':
      N_RB_DL=atoi(optarg);
      break;
515

516
517
    case 'P':
      dump_perf=1;
518
      opp_enabled=1;
519
      break;
520

521
522
523
524
    case 'O':
      test_perf=atoi(optarg);
      //print_perf =1;
      break;
525

526
    case 'L':
527
      parallel_flag=1;
528
      break;
529

530
531
532
    case 'I':
      max_turbo_iterations=atoi(optarg);
      break;
533

534
535
536
537
    case 'F':
      xforms=1;
      break;

538
539
540
    case 'Z':
      dump_table = 1;
      break;
541

542
543
    case 'h':
    default:
544
545
      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]);
546
547
548
549
      exit(1);
      break;
    }
  }
550

551
552
553
554
555
556
557
558
  lte_param_init(1,
		 n_rx,
		 1,
		 extended_prefix_flag,
		 frame_type,
		 0,
		 tdd_config,
		 N_RB_DL,
559
		 threequarter_fs,
560
561
		 osf,
		 0);
562

563
  if (nb_rb_set == 0)
564
    nb_rb = eNB->frame_parms.N_RB_UL;
565

566
  printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0][0]);
567
  printf("Setting mcs = %d\n",mcs);
568
  printf("n_frames = %d\n", n_frames);
569

knopp's avatar
   
knopp committed
570
  snr1 = snr0+snr_int;
571
572
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);

573
  frame_parms = &eNB->frame_parms;
574

575
  txdata = UE->common_vars.txdata;
576

577

578

579
  nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12;
580
581


582
  sprintf(bler_fname,"ULbler_mcs%d_nrb%d_ChannelModel%d_nsim%d.csv",mcs,nb_rb,chMod,n_frames);
583
  bler_fd = fopen(bler_fname,"w");
584
585
586
587
  if (bler_fd==NULL) {
    fprintf(stderr,"Problem creating file %s\n",bler_fname);
    exit(-1);
  }
588

589
  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");
590
591

  if (test_perf != 0) {
592
593
594
595
    char hostname[1024];
    hostname[1023] = '\0';
    gethostname(hostname, 1023);
    printf("Hostname: %s\n", hostname);
596
597
598
599
    //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",
600
            N_RB_DL,mcs,n_rx,channel_model_input,transmission_mode);
601
    time_meas_fd = fopen(time_meas_fname,"w");
602
603
604
605
    if (time_meas_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
      exit(-1);
    }
606
  }
607
608
609

  if(abstx) {
    // CSV file
610
611
    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");
612
613
614
615
    if (csv_fdUL == NULL) {
      fprintf(stderr,"Problem opening file %s\n",csv_fname);
      exit(-1);
    }
616
617
    fprintf(csv_fdUL,"data_all%d=[",mcs);
  }
618

619

620
621
622
623
624
625
  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);
  }
626

627
  UE->pdcch_vars[0]->crnti = 14;
628

629
630
631
632
633
  UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
  UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7;
  UE->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = 0;
  UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0;
  UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0;
634

635
636
  eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
  eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7;
637

638
639
640
641
642
643
  eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex = 1;
  eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth = 0;
  eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0;
  eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0;
  eNB->cooperation_flag = cooperation_flag;
  //  eNB->eNB_UE_stats[0].SRS_parameters = UE->SRS_parameters;
644

645
646
647
648
649
650
  eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
  eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index  = beta_RI;
  eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
  UE->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
  UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index  = beta_RI;
  UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
651

652
  UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1;
653

654
655
  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);

656
657
  UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
                                UE->frame_parms.nb_antennas_rx,
658
                                channel_model,
659
660
				N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
				N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
661
662
663
664
665
666
667
                                forgetting_factor,
                                delay,
                                0);
  // set Doppler
  UE2eNB->max_Doppler = maxDoppler;

  // NN: N_RB_UL has to be defined in ulsim
668
669
  eNB->ulsch[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0);
  UE->ulsch[0]   = new_ue_ulsch(N_RB_DL,0);
670

671
672
673
674
  if (parallel_flag == 1) {
    init_fep_thread(eNB,NULL);
    init_td_thread(eNB,NULL);
  }
675
  // Create transport channel structures for 2 transport blocks (MIMO)
676
  for (i=0; i<2; i++) {
677
678
    eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0);
    UE->dlsch[0][i]  = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
679

680
    if (!eNB->dlsch[0][i]) {
681
682
683
      printf("Can't get eNB dlsch structures\n");
      exit(-1);
    }
684

685
    if (!UE->dlsch[0][i]) {
686
687
688
      printf("Can't get ue dlsch structures\n");
      exit(-1);
    }
689

690
691
    eNB->dlsch[0][i]->rnti = 14;
    UE->dlsch[0][i]->rnti   = 14;
692

693
  } 
694

695

696
697


698
699
700
701
702
703
704
705
706
707
708
  UE->measurements.rank[0] = 0;
  UE->transmission_mode[0] = 2;
  UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing;
  eNB->transmission_mode[0] = 2;
  eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = bundling_flag == 1 ? bundling : multiplexing;
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
709
710


knopp's avatar
knopp committed
711
  UE->mac_enabled=0;
712
  
knopp's avatar
knopp committed
713
714
  eNB_rxtx_proc_t *proc_rxtx   = &eNB->proc.proc_rxtx[subframe&1];
  UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1];
knopp's avatar
knopp committed
715
716
  proc_rxtx->frame_rx=1;
  proc_rxtx->subframe_rx=subframe;
717

knopp's avatar
knopp committed
718
719
  proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe);
  proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe);
720

knopp's avatar
knopp committed
721
722
723
724
  proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx;
  proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx;
  proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
  proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx;
knopp's avatar
   
knopp committed
725

726
  printf("Init UL hopping UE\n");
727
  init_ul_hopping(&UE->frame_parms);
728
  printf("Init UL hopping eNB\n");
729
  init_ul_hopping(&eNB->frame_parms);
knopp's avatar
   
knopp committed
730

731

732
  UE->dlsch[0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1;
733

knopp's avatar
knopp committed
734
735
  UE->ulsch_Msg3_active[eNB_id] = 0;
  UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1;
knopp's avatar
knopp committed
736
  /*
737
  generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu,
738
                                    14,
knopp's avatar
knopp committed
739
                                    proc_rxtx->subframe_tx,
740
                                    format0,
741
                                    UE,
knopp's avatar
knopp committed
742
				    proc_rxtx_ue,
743
744
745
746
747
748
                                    SI_RNTI,
                                    0,
                                    P_RNTI,
                                    CBA_RNTI,
                                    0,
                                    srs_flag);
749
750
751

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

knopp's avatar
knopp committed
752
  generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx,
753
				     (void *)&UL_alloc_pdu,
754
755
756
                                     14,
                                     format0,
                                     0,
757
				     SI_RNTI,
758
759
760
761
                                     0,
                                     P_RNTI,
                                     CBA_RNTI,
                                     srs_flag);
knopp's avatar
knopp committed
762
  */
763

764
765
  coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb;

766
  if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O;
767
768
769
770

  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);
771
772


773
774
775

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

776
777
778
779
780
781
    /*
      if(abstx){
      int ulchestim_f[300*12];
      int ulchestim_t[2*(frame_parms->ofdm_symbol_size)];
      }
    */
782
783

    if(abstx) {
784
785
786
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
      saving_bler=1;
    }
787

788

knopp's avatar
   
knopp committed
789
    //    if ((subframe>5) || (subframe < 4))
790
    //      UE->frame++;
791
792

    for (SNR=snr0; SNR<snr1; SNR+=input_snr_step) {
793
794
795
796
797
798
799
800
801
802
803
804
805
      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;
806

807
808
      //randominit(0);

knopp's avatar
   
knopp committed
809

knopp's avatar
knopp committed
810
      harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe);
811
      input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8;
knopp's avatar
knopp committed
812
      input_buffer = (unsigned char *)memalign(32,input_buffer_length+64);
813
      //      printf("UL frame %d/subframe %d, harq_pid %d\n",UE->frame,subframe,harq_pid);
814
      if (input_fdUL == NULL) {
815

816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836

        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)) {
837
          ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2);
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859

          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);

860
861
      }

862
863
      avg_iter = 0;
      iter_trials=0;
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
      reset_meas(&UE->phy_proc_tx);
      reset_meas(&UE->ofdm_mod_stats);
      reset_meas(&UE->ulsch_modulation_stats);
      reset_meas(&UE->ulsch_encoding_stats);
      reset_meas(&UE->ulsch_interleaving_stats);
      reset_meas(&UE->ulsch_rate_matching_stats);
      reset_meas(&UE->ulsch_turbo_encoding_stats);
      reset_meas(&UE->ulsch_segmentation_stats);
      reset_meas(&UE->ulsch_multiplexing_stats);

      reset_meas(&eNB->phy_proc_rx);
      reset_meas(&eNB->ofdm_demod_stats);
      reset_meas(&eNB->ulsch_channel_estimation_stats);
      reset_meas(&eNB->ulsch_freq_offset_estimation_stats);
      reset_meas(&eNB->rx_dft_stats);
      reset_meas(&eNB->ulsch_decoding_stats);
      reset_meas(&eNB->ulsch_turbo_decoding_stats);
      reset_meas(&eNB->ulsch_deinterleaving_stats);
      reset_meas(&eNB->ulsch_demultiplexing_stats);
      reset_meas(&eNB->ulsch_rate_unmatching_stats);
      reset_meas(&eNB->ulsch_tc_init_stats);
      reset_meas(&eNB->ulsch_tc_alpha_stats);
      reset_meas(&eNB->ulsch_tc_beta_stats);
      reset_meas(&eNB->ulsch_tc_gamma_stats);
      reset_meas(&eNB->ulsch_tc_ext_stats);
      reset_meas(&eNB->ulsch_tc_intl1_stats);
      reset_meas(&eNB->ulsch_tc_intl2_stats);
891

knopp's avatar
knopp committed
892
      // initialization 
893
894
      struct list time_vector_tx;
      initialize(&time_vector_tx);
895
896
897
898
899
900
901
      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);

902
903
      struct list time_vector_rx;
      initialize(&time_vector_rx);
904
905
906
907
908
909
      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);
910

knopp's avatar
knopp committed
911
      ndi=0;
912
913
      for (trials = 0; trials<n_frames; trials++) {
        //      printf("*");
914
915
        //        UE->frame++;
        //        eNB->frame++;
knopp's avatar
knopp committed
916
	ndi = (1-ndi);
917
918
919
920
        fflush(stdout);
        round=0;

        while (round < 4) {
921
922
          eNB->ulsch[0]->harq_processes[harq_pid]->round=round;
          UE->ulsch[0]->harq_processes[harq_pid]->round=round;
knopp's avatar
knopp committed
923
	  //	  printf("Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_rx,proc_rxtx_ue->frame_rx);
924
925
926
          round_trials[round]++;


knopp's avatar
knopp committed
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
	  fill_ulsch_dci(eNB,(void*)&UL_alloc_pdu,first_rb,nb_rb,mcs,ndi,cqi_flag);

	  UE->ulsch_Msg3_active[eNB_id] = 0;
	  UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1;
	  generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu,
					    14,
					    proc_rxtx->subframe_tx,
					    format0,
					    UE,
					    proc_rxtx_ue,
					    SI_RNTI,
					    0,
					    P_RNTI,
					    CBA_RNTI,
					    0,
					    srs_flag);

	  generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx,
					     (void *)&UL_alloc_pdu,
					     14,
					     format0,
					     0,
					     SI_RNTI,
					     0,
					     P_RNTI,
					     CBA_RNTI,
					     srs_flag);
	  eNB->ulsch[0]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

          /////////////////////
          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) {

knopp's avatar
knopp committed
974
975
976
977
978
979
	    eNB->proc.frame_rx = 1;
	    eNB->proc.subframe_rx = subframe;
	    proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx;
	    proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx;
	    proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
	    proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx;
980

knopp's avatar
knopp committed
981
	    phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx,no_relay);
982

knopp's avatar
knopp committed
983
	    /*
984
            if (srs_flag)
985
              generate_srs_tx(UE,0,AMP,subframe);
986

knopp's avatar
knopp committed
987
            generate_drs_pusch(UE,proc_rxtx_ue,0,
988
                               AMP,subframe,
989
990
                               UE->ulsch[0]->harq_processes[harq_pid]->first_rb,
                               UE->ulsch[0]->harq_processes[harq_pid]->nb_rb,
991
992
993
                               0);

            if ((cqi_flag == 1) && (n_frames == 1) ) {
994
995
996
              printf("CQI information (O %d) %d %d\n",UE->ulsch[0]->O,
                     UE->ulsch[0]->o[0],UE->ulsch[0]->o[1]);
              print_CQI(UE->ulsch[0]->o,UE->ulsch[0]->uci_format,UE->frame_parms.N_RB_DL,0);
997
998
            }

999
            UE->ulsch[0]->o_ACK[0] = taus()&1;
1000

1001
            start_meas(&UE->ulsch_encoding_stats);
1002
1003

            if (ulsch_encoding(input_buffer,
1004
                               UE,
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
                               harq_pid,
                               eNB_id,
                               2, // transmission mode
                               control_only_flag,
                               1// Nbundled
                              )==-1) {
              printf("ulsim.c Problem with ulsch_encoding\n");
              exit(-1);
            }

1015
            stop_meas(&UE->ulsch_encoding_stats);
1016

1017
1018
            start_meas(&UE->ulsch_modulation_stats);
            ulsch_modulation(UE->common_vars.txdataF,AMP,
knopp's avatar
knopp committed
1019
                             proc_rxtx_ue->frame_tx,subframe,&UE->frame_parms,
1020
1021
                             UE->ulsch[0]);
            stop_meas(&UE->ulsch_modulation_stats);
knopp's avatar
knopp committed
1022
	    */
1023
1024
1025



knopp's avatar
knopp committed
1026
1027
1028

	    /*
	    for (aa=0; aa<1; aa++) {
1029
              if (frame_parms->Ncp == EXTENDED)
1030
1031
1032
                PHY_ofdm_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],        // input
                             &txdata[aa][eNB->frame_parms.samples_per_tti*subframe],         // output
                             UE->frame_parms.ofdm_symbol_size,
1033
                             nsymb,                 // number of symbols
1034
                             UE->frame_parms.nb_prefix_samples,               // number of prefix samples
1035
1036
                             CYCLIC_PREFIX);
              else
1037
1038
                normal_prefix_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],
                                  &txdata[aa][eNB->frame_parms.samples_per_tti*subframe],
1039
1040
1041
1042
                                  nsymb,
                                  frame_parms);


1043
1044
              apply_7_5_kHz(UE,UE->common_vars.txdata[aa],subframe<<1);
              apply_7_5_kHz(UE,UE->common_vars.txdata[aa],1+(subframe<<1));
1045

knopp's avatar
knopp committed
1046
*/
1047

knopp's avatar
knopp committed
1048
1049
1050
1051
1052
1053
1054
1055
	    tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe],
				   eNB->frame_parms.samples_per_tti);
	    
	    
            if (n_frames==1) {
              write_output("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1,
                           1);
              //write_output("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1);
1056
            }
knopp's avatar
knopp committed
1057
1058
1059
	    
	  }  // input_fd == NULL
	  
1060
1061
1062
          tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev);

          if (n_frames==1) {
1063
1064
            write_output("txsig0UL.m","txs0", &txdata[0][eNB->frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
            //        write_output("txsig1UL.m","txs1", &txdata[1][eNB->frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
1065
1066
1067
1068
          }

          //AWGN
          //Set target wideband RX noise level to N0
1069
          sigma2_dB = N0;//10*log10((double)tx_lev)  +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR;
1070
1071
1072
          sigma2 = pow(10,sigma2_dB/10);

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