dlschsim.c 20 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * 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.1  (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
 */

#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

hongzhi wang's avatar
hongzhi wang committed
29
30
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
31
#include "common/ran_context.h"
hongzhi wang's avatar
hongzhi wang committed
32

33
34
35
36
37
38
#include "SIMULATION/TOOLS/sim.h"
#include "SIMULATION/RF/rf.h"
#include "PHY/types.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
hongzhi wang's avatar
hongzhi wang committed
39
40
41
42
43
44
45
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
46
47
48
49
#include "PHY/NR_TRANSPORT/nr_dlsch.h"

#include "SCHED_NR/sched_nr.h"

hongzhi wang's avatar
hongzhi wang committed
50
51
52
//#include "PHY/MODULATION/modulation_common.h"
//#include "common/config/config_load_configmodule.h"
//#include "UTIL/LISTS/list.h"
53
//#include "common/ran_context.h"
54
55
56
57
58
59
60
61
62
63

PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;


double cpuf;

// dummy functions
int nfapi_mode=0;
64
65
66
67
68
69
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
  return(0);
}
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) {
  return(0);
}
70

71
72
73
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
  return(0);
}
74

75
76
77
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
  return(0);
}
78

79
80
81
int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {
  return(0);
}
82

83
uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_earfcn) {
84
85
86
87
88
  return(0);
}
int32_t get_uldl_offset(int eutra_bandP) {
  return(0);
}
89

90
91
92
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
  return(NULL);
}
93

94
95
96
97
void exit_function(const char *file, const char *function, const int line,const char *s) {
  const char *msg= s==NULL ? "no comment": s;
  printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
  exit(-1);
hongzhi wang's avatar
hongzhi wang committed
98
}
99
100

// needed for some functions
101
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1]= {{NULL}};
102
103
uint16_t n_rnti=0x1234;

104
char quantize(double D,double x,unsigned char B) {
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  double qxd;
  short maxlev;
  qxd = floor(x/D);
  maxlev = 1<<(B-1);//(char)(pow(2,B-1));

  //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);

  if (qxd <= -maxlev)
    qxd = -maxlev;
  else if (qxd >= maxlev)
    qxd = maxlev-1;

  return((char)qxd);
}

120
int main(int argc, char **argv) {
121
  char c;
hongzhi wang's avatar
hongzhi wang committed
122
123
  int i; //,j,l,aa;
  double SNR,SNR_lin,snr0=-2.0,snr1=2.0;
124
125
126
127
128
129
130
131
132
133
  double snr_step = 0.1;
  uint8_t snr1set=0;
  int **txdata;
  double **s_re,**s_im,**r_re,**r_im;
  //  int sync_pos, sync_pos_slot;
  //  FILE *rx_frame_file;
  FILE *output_fd = NULL;
  uint8_t write_output_file=0;
  //  int subframe_offset;
  //  char fname[40], vname[40];
134
  int trial,n_trials=1,n_errors=0,n_false_positive=0;
135
136
137
138
139
140
  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
  uint16_t Nid_cell=0;
  channel_desc_t *gNB2UE;
  uint8_t extended_prefix_flag=0;
  int8_t interf1=-21,interf2=-21;
  FILE *input_fd=NULL,*pbch_file_fd=NULL;
yilmazt's avatar
yilmazt committed
141
  //char input_val_str[50],input_val_str2[50];
hongzhi wang's avatar
hongzhi wang committed
142
  //uint16_t NB_RB=25;
143
144
145
146
147
148
  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
  uint8_t N_RB_DL=106,mu=1;
  unsigned char frame_type = 0;
  unsigned char pbch_phase = 0;
  int frame=0,subframe=0;
  int frame_length_complex_samples;
hongzhi wang's avatar
hongzhi wang committed
149
  //int frame_length_complex_samples_no_prefix;
150
  NR_DL_FRAME_PARMS *frame_parms;
hongzhi wang's avatar
hongzhi wang committed
151
  //nfapi_nr_config_request_t *gNB_config;
yilmazt's avatar
yilmazt committed
152
153
  uint8_t Kmimo=0;
  uint32_t Nsoft=0;
154
155
156
  double sigma;
  unsigned char qbits=8;
  int ret;
yilmazt's avatar
yilmazt committed
157
  //int run_initial_sync=0;
hongzhi wang's avatar
hongzhi wang committed
158
159
  int loglvl=OAILOG_WARNING;
  float target_error_rate = 0.01;
160
161
162
163
164

  uint16_t nb_symb_sch =12;
  uint16_t nb_rb = 50;
  uint8_t Imcs=9;

165
166
167
168
169
170
  cpuf = get_cpu_freq_GHz();

  if ( load_configmodule(argc,argv) == 0) {
    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
  }

hongzhi wang's avatar
hongzhi wang committed
171
  //logInit();
172
173
  randominit(0);

174
  while ((c = getopt (argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:N:F:R:P:")) != -1) {
175
    switch (c) {
176
177
178
      case 'f':
        write_output_file=1;
        output_fd = fopen(optarg,"w");
179

180
181
182
183
        if (output_fd==NULL) {
          printf("Error opening %s\n",optarg);
          exit(-1);
        }
184
185
186

        break;

187
188
      case 'd':
        frame_type = 1;
189
190
        break;

191
192
193
194
195
      case 'g':
        switch((char)*optarg) {
          case 'A':
            channel_model=SCM_A;
            break;
196

197
198
199
          case 'B':
            channel_model=SCM_B;
            break;
200

201
202
203
          case 'C':
            channel_model=SCM_C;
            break;
204

205
206
207
          case 'D':
            channel_model=SCM_D;
            break;
208

209
210
211
          case 'E':
            channel_model=EPA;
            break;
212

213
214
215
          case 'F':
            channel_model=EVA;
            break;
216

217
218
219
          case 'G':
            channel_model=ETU;
            break;
220

221
222
223
224
          default:
            msg("Unsupported channel model!\n");
            exit(-1);
        }
225

226
        break;
227

228
229
230
      case 'i':
        interf1=atoi(optarg);
        break;
231

232
233
234
      case 'j':
        interf2=atoi(optarg);
        break;
235

236
237
238
      case 'n':
        n_trials = atoi(optarg);
        break;
239

240
241
242
243
244
245
246
247
248
249
250
251
252
253
      case 's':
        snr0 = atof(optarg);
        msg("Setting SNR0 to %f\n",snr0);
        break;

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

      case 'p':
        extended_prefix_flag=1;
        break;
254
255
256
257
258
259
260
261
262
263

      /*
      case 'r':
      ricean_factor = pow(10,-.1*atof(optarg));
      if (ricean_factor>1) {
        printf("Ricean factor must be between 0 and 1\n");
        exit(-1);
      }
      break;
      */
264
265
266
 
      case 'y':
        n_tx=atoi(optarg);
267

268
269
270
271
        if ((n_tx==0) || (n_tx>2)) {
          msg("Unsupported number of tx antennas %d\n",n_tx);
          exit(-1);
        }
272

273
        break;
274

275
276
      case 'z':
        n_rx=atoi(optarg);
277

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

283
        break;
284

285
286
287
      case 'N':
        Nid_cell = atoi(optarg);
        break;
288

289
290
291
      case 'R':
        N_RB_DL = atoi(optarg);
        break;
292

293
294
      case 'F':
        input_fd = fopen(optarg,"r");
295

296
297
298
299
        if (input_fd==NULL) {
          printf("Problem with filename %s\n",optarg);
          exit(-1);
        }
300

301
        break;
302

303
304
      case 'P':
        pbch_phase = atoi(optarg);
305

306
307
        if (pbch_phase>3)
          printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase);
308

309
        break;
310

yilmazt's avatar
yilmazt committed
311
312
313
      case 'm':
    	  Imcs = atoi(optarg);
    	  break;
314

yilmazt's avatar
yilmazt committed
315
316
317
      case 'l':
    	  nb_symb_sch = atoi(optarg);
    	  break;
318
      
yilmazt's avatar
yilmazt committed
319
320
321
322
323
324
325
326
      case 'r':
    	  nb_rb = atoi(optarg);
    	  break;

      case 'x':
    	  transmission_mode = atoi(optarg);
    	  break;

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
      default:
      case 'h':
        printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
               argv[0]);
        printf("-h This message\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;
353
354
355
    }
  }

hongzhi wang's avatar
hongzhi wang committed
356
357
358
359
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

360
361
362
363
364
365
  if (snr1set==0)
    snr1 = snr0+10;

  gNB2UE = new_channel_desc_scm(n_tx,
                                n_rx,
                                channel_model,
366
367
                                61.44e6, //N_RB2sampling_rate(N_RB_DL),
                                40e6, //N_RB2channel_bandwidth(N_RB_DL),
368
369
370
371
372
373
374
375
376
                                0,
                                0,
                                0);

  if (gNB2UE==NULL) {
    msg("Problem generating channel model. Exiting.\n");
    exit(-1);
  }

377
378
  RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **));
  RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
379
380
  RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
  gNB = RC.gNB[0][0];
hongzhi wang's avatar
hongzhi wang committed
381
  //gNB_config = &gNB->gNB_config;
382
383
384
385
386
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
  frame_parms->nb_antennas_tx = n_tx;
  frame_parms->nb_antennas_rx = n_rx;
  frame_parms->N_RB_DL = N_RB_DL;
  crcTableInit();
hongzhi wang's avatar
hongzhi wang committed
387
  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu);
388
389
390
  phy_init_nr_gNB(gNB,0,0);
  //init_eNB_afterRU();
  frame_length_complex_samples = frame_parms->samples_per_subframe;
hongzhi wang's avatar
hongzhi wang committed
391
  //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
392
393
394
395
396
  s_re = malloc(2*sizeof(double *));
  s_im = malloc(2*sizeof(double *));
  r_re = malloc(2*sizeof(double *));
  r_im = malloc(2*sizeof(double *));
  txdata = malloc(2*sizeof(int *));
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

  for (i=0; i<2; i++) {
    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));
    txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
    bzero(r_re[i],frame_length_complex_samples*sizeof(int));
  }

  if (pbch_file_fd!=NULL) {
    load_pbch_desc(pbch_file_fd);
  }

415
416
417
418
  /*  for (int k=0; k<2; k++) {
      // Create transport channel structures for 2 transport blocks (MIMO)
      for (i=0; i<2; i++) {
        gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config);
419

420
421
422
423
424
425
        if (!gNB->dlsch[k][i]) {
          printf("Can't get eNB dlsch structures\n");
          exit(-1);
        }
  gNB->dlsch[k][i]->Nsoft = 10;
        gNB->dlsch[k][i]->rnti = n_rnti+k;
426
      }
427
    }*/
428
429
430
  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
  memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
431

432
  //phy_init_nr_top(frame_parms);
433
  if (init_nr_ue_signal(UE, 1, 0) != 0) {
434
435
436
    printf("Error at UE NR initialisation\n");
    exit(-1);
  }
437

438
439
440
  //nr_init_frame_parms_ue(&UE->frame_parms);
  //init_nr_ue_transport(UE, 0);
  for (int sf = 0; sf < 2; sf++) {
441
442
    for (i=0; i<2; i++) {
      UE->dlsch[sf][0][i]  = new_nr_ue_dlsch(Kmimo,8,Nsoft,5,N_RB_DL,0);
443

444
445
446
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
447
448
      }

449
450
451
      UE->dlsch[sf][0][i]->rnti   = n_rnti;
    }
  }
452

453
454
  UE->dlsch_SI[0]  = new_nr_ue_dlsch(1,1,Nsoft,5,N_RB_DL,0);
  UE->dlsch_ra[0]  = new_nr_ue_dlsch(1,1,Nsoft,5,N_RB_DL,0);
hongzhi wang's avatar
hongzhi wang committed
455
  unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
456
  NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
457
  nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
yilmazt's avatar
yilmazt committed
458
459
  //time_stats_t *rm_stats, *te_stats, *i_stats;
  uint8_t is_crnti=0, llr8_flag=0;
460
461
462
463
464
465
466
  unsigned int TBS = 8424;
  unsigned int available_bits;
  uint8_t nb_re_dmrs = 6;
  uint16_t length_dmrs = 1;
  unsigned char mod_order;
  uint8_t Nl=1;
  uint8_t rvidx = 0;
hongzhi wang's avatar
hongzhi wang committed
467
468
469
470
  dlsch->rnti =1;
  /*dlsch->harq_processes[0]->mcs = Imcs;
  dlsch->harq_processes[0]->rvidx = rvidx;*/
  //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
471
  //    dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
hongzhi wang's avatar
hongzhi wang committed
472
  mod_order = nr_get_Qm(Imcs,1);
Hongzhi Wang's avatar
Hongzhi Wang committed
473
  available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,1);
474
475
  TBS= nr_compute_tbs(Imcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,Nl);
  printf("available bits %d TBS %d mod_order %d\n",available_bits, TBS, mod_order);
hongzhi wang's avatar
hongzhi wang committed
476
  //dlsch->harq_ids[subframe]= 0;
477
478
479
480
481
482
  rel15->n_prb = nb_rb;
  rel15->nb_symbols = nb_symb_sch;
  rel15->modulation_order = mod_order;
  rel15->nb_layers = Nl;
  rel15->nb_re_dmrs = nb_re_dmrs;
  rel15->transport_block_size = TBS;
483
484
485
486
487
488
489
490
  double *modulated_input = malloc16(sizeof(double) * 16*68*384);
  short *channel_output_fixed = malloc16(sizeof( short) *16* 68*384);
  short *channel_output_uncoded = malloc16(sizeof(unsigned short) *16* 68*384);
  double errors_bit_uncoded=0;
  unsigned char *estimated_output;
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
  unsigned int errors_bit =0;
491
492
493
  test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16*68*384);
  estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16*68*384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16*68*384);
494
495
496
497
498
499
500
  NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[UE->current_thread_id[subframe]][0][0];
  NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
  harq_process->mcs = Imcs;
  harq_process->Nl = Nl;
  harq_process->nb_rb = nb_rb;
  harq_process->Qm = mod_order;
  harq_process->rvidx = rvidx;
501
  printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm,nb_symb_sch);
502
503
  unsigned char *test_input;
  test_input=(unsigned char *)malloc16(sizeof(unsigned char) * TBS/8);
504
505
506

  for (i=0; i<TBS/8; i++)
    test_input[i]=(unsigned char) rand();
507
508
509

  estimated_output = harq_process->b;

Hongzhi Wang's avatar
Hongzhi Wang committed
510
  /*for (int i=0; i<TBS/8; i++)
511
    printf("test input[%d]=%d \n",i,test_input[i]);*/
512

hongzhi wang's avatar
hongzhi wang committed
513
  //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
514
515
516

  // generate signal
  if (input_fd==NULL) {
hongzhi wang's avatar
hongzhi wang committed
517
    nr_dlsch_encoding(test_input,
518
                      subframe,
519
                      dlsch,
hongzhi wang's avatar
hongzhi wang committed
520
                      frame_parms);
521
522
  }

523
524
525
526
527
  for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
    n_errors = 0;
    n_false_positive = 0;
    
    for (trial=0; trial < n_trials; trial++) {
528
      errors_bit_uncoded = 0;
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
      for (i = 0; i < available_bits; i++) {
#ifdef DEBUG_CODER

        if ((i&0xf)==0)
          printf("\ne %d..%d:    ",i,i+15);

#endif

        //if (i<16)
        //   printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
        if (dlsch->harq_processes[0]->f[i]==0)
          modulated_input[i]=1.0;///sqrt(2);  //QPSK
        else
          modulated_input[i]=-1.0;///sqrt(2);

        //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
        //SNR =10;
        SNR_lin = pow(10,SNR/10.0);
        sigma = 1.0/sqrt(2*SNR_lin);
        channel_output_fixed[i] = (short)quantize(sigma/4.0/4.0,modulated_input[i] + sigma*gaussdouble(0.0,1.0),qbits);
        //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
        //printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
        //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);

        //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);

        //if (i<16)   printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]);

        //Uncoded BER
        if (channel_output_fixed[i]<0)
          channel_output_uncoded[i]=1;  //QPSK demod
        else
          channel_output_uncoded[i]=0;

        if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i])
          errors_bit_uncoded = errors_bit_uncoded + 1;
      }

      //if (errors_bit_uncoded>10)
568
      //printf("errors bits uncoded %f\n", errors_bit_uncoded);
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
#ifdef DEBUG_CODER
      printf("\n");
      exit(-1);
#endif
      ret = nr_dlsch_decoding(UE,
                              channel_output_fixed,
                              &UE->frame_parms,
                              dlsch0_ue,
                              dlsch0_ue->harq_processes[0],
                              frame,
                              nb_symb_sch,
                              subframe,
                              harq_pid,
                              is_crnti,
                              llr8_flag);

      if (ret>dlsch0_ue->max_ldpc_iterations)
        n_errors++;

      //count errors
      errors_bit = 0;

      for (i=0; i<TBS; i++) {
        estimated_output_bit[i] = (estimated_output[i/8]&(1<<(i&7)))>>(i&7);
        test_input_bit[i] = (test_input[i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments

        if (estimated_output_bit[i] != test_input_bit[i]) {
          errors_bit++;
          //printf("estimated bits error occurs @%d ",i);
        }
      }

      if (errors_bit>0) {
	n_false_positive++;
	if (n_trials == 1)
	  printf("\n errors_bit %d (trial %d)\n", errors_bit,trial);
      }
606
    }
607
608
609
610
611
612
613

    printf("SNR %f, BLER %f (false positive %f)\n",SNR,(float)n_errors/(float)n_trials,(float)n_false_positive/(float)n_trials);

    if ((float)n_errors/(float)n_trials < target_error_rate)
      break;
  }

614
615
616
617
618
619
620
621
  /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
  if (gNB->frame_parms.nb_antennas_tx>1)
    LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/

  //TODO: loop over slots
  /*for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
    if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
      PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
622
623
624
625
626
       txdata[aa],
       frame_parms->ofdm_symbol_size,
       12,
       frame_parms->nb_prefix_samples,
       CYCLIC_PREFIX);
627
628
    } else {
      nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
629
630
631
         txdata[aa],
         14,
         frame_parms);
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    }
  }

  LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
  if (gNB->frame_parms.nb_antennas_tx>1)
    LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);


  for (i=0; i<frame_length_complex_samples; i++) {
    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
      r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
      r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
      }
    }*/

  for (i=0; i<2; i++) {
648
649
650
651
652
    printf("gNB %d\n",i);
    free_gNB_dlsch(gNB->dlsch[0][i]);
    printf("UE %d\n",i);
    free_nr_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
  }
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667

  for (i=0; i<2; i++) {
    free(s_re[i]);
    free(s_im[i]);
    free(r_re[i]);
    free(r_im[i]);
    free(txdata[i]);
  }

  free(s_re);
  free(s_im);
  free(r_re);
  free(r_im);
  free(txdata);

hongzhi wang's avatar
hongzhi wang committed
668
  if (output_fd)
669
670
    fclose(output_fd);

hongzhi wang's avatar
hongzhi wang committed
671
672
673
  if (input_fd)
    fclose(input_fd);

674
675
676
677
678
  return(n_errors);
}