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
141
  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;
  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;
152
153
154
155
156
  uint8_t Kmimo;
  uint32_t Nsoft;
  double sigma;
  unsigned char qbits=8;
  int ret;
hongzhi wang's avatar
hongzhi wang committed
157
158
159
  int run_initial_sync=0;
  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

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

315
316
317
318
319
320
    case 'l':
      nb_symb_sch = atoi(optarg);
      break;
      
    case 'r':
      nb_rb = atoi(optarg);
321
      break;
322
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
	
      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;
349
350
351
    }
  }

hongzhi wang's avatar
hongzhi wang committed
352
353
354
355
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

356
357
358
359
360
361
  if (snr1set==0)
    snr1 = snr0+10;

  gNB2UE = new_channel_desc_scm(n_tx,
                                n_rx,
                                channel_model,
362
363
                                61.44e6, //N_RB2sampling_rate(N_RB_DL),
                                40e6, //N_RB2channel_bandwidth(N_RB_DL),
364
365
366
367
368
369
370
371
372
                                0,
                                0,
                                0);

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

373
374
  RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **));
  RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
375
376
  RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
  gNB = RC.gNB[0][0];
hongzhi wang's avatar
hongzhi wang committed
377
  //gNB_config = &gNB->gNB_config;
378
379
380
381
382
  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
383
  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu);
384
385
386
  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
387
  //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
388
389
390
391
392
  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 *));
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

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

411
412
413
414
  /*  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);
415

416
417
418
419
420
421
        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;
422
      }
423
    }*/
424
425
426
  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
  memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
427

428
  //phy_init_nr_top(frame_parms);
429
  if (init_nr_ue_signal(UE, 1, 0) != 0) {
430
431
432
    printf("Error at UE NR initialisation\n");
    exit(-1);
  }
433

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

440
441
442
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
443
444
      }

445
446
447
      UE->dlsch[sf][0][i]->rnti   = n_rnti;
    }
  }
448

449
450
  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
451
  unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
452
  NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
453
  nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
454
455
456
457
458
459
460
461
462
463
464
465
  time_stats_t *rm_stats;
  time_stats_t *te_stats;
  time_stats_t *i_stats;
  uint8_t is_crnti;
  uint8_t llr8_flag;
  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
466
467
468
469
  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],
470
  //    dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
hongzhi wang's avatar
hongzhi wang committed
471
  mod_order = nr_get_Qm(Imcs,1);
Hongzhi Wang's avatar
Hongzhi Wang committed
472
  available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,1);
473
474
  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
475
  //dlsch->harq_ids[subframe]= 0;
476
477
478
479
480
481
  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;
482
483
484
485
486
487
488
489
  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;
490
491
492
  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);
493
494
495
496
497
498
499
  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;
500
  printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm,nb_symb_sch);
501
502
  unsigned char *test_input;
  test_input=(unsigned char *)malloc16(sizeof(unsigned char) * TBS/8);
503
504
505

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

  estimated_output = harq_process->b;

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

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

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

522
523
524
525
526
  for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
    n_errors = 0;
    n_false_positive = 0;
    
    for (trial=0; trial < n_trials; trial++) {
527
      errors_bit_uncoded = 0;
528
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
      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)
567
      //printf("errors bits uncoded %f\n", errors_bit_uncoded);
568
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
#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);
      }
605
    }
606
607
608
609
610
611
612

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

613
614
615
616
617
618
619
620
  /*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],
621
622
623
624
625
       txdata[aa],
       frame_parms->ofdm_symbol_size,
       12,
       frame_parms->nb_prefix_samples,
       CYCLIC_PREFIX);
626
627
    } else {
      nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
628
629
630
         txdata[aa],
         14,
         frame_parms);
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
    }
  }

  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++) {
647
648
649
650
651
    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]);
  }
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

  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
667
  if (output_fd)
668
669
    fclose(output_fd);

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

673
674
675
676
677
  return(n_errors);
}