dlsim.c 34.5 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
/*
 * 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 <fcntl.h>
23 24
#include <math.h>
#include <string.h>
25 26
#include <sys/ioctl.h>
#include <sys/mman.h>
27 28
#include <unistd.h>
#include "common/ran_context.h"
29 30
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
31 32 33
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_UE/mac_defs.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
34
#include "PHY/defs_gNB.h"
35 36
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
37
#include "PHY/phy_vars_nr_ue.h"
38 39
#include "PHY/types.h"
#include "PHY/INIT/phy_init.h"
40
#include "PHY/MODULATION/modulation_eNB.h"
41
#include "PHY/MODULATION/nr_modulation.h"
42
#include "PHY/MODULATION/modulation_UE.h"
43
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
cig's avatar
cig committed
44
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
45
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
46
#include "SCHED_NR/fapi_nr_l1.h"
47
#include "SCHED_NR/sched_nr.h"
48
#include "SCHED_NR_UE/defs.h"
49 50 51 52
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
#include "NR_UE_PHY_INTERFACE/NR_IF_Module.h"

53
#include "LAYER2/NR_MAC_UE/mac_proto.h"
yilmazt's avatar
yilmazt committed
54 55
//#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
56
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
57
#include "NR_asn_constant.h"
58
#include "RRC/NR/MESSAGES/asn1_msg.h"
59 60 61
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
Raymond Knopp's avatar
Raymond Knopp committed
62
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
63

Raymond Knopp's avatar
Raymond Knopp committed
64
#include "NR_RRCReconfiguration.h"
65 66 67 68
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"


Raymond Knopp's avatar
Raymond Knopp committed
69

70 71 72
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
73 74
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];

75
double cpuf;
76

77
int sf_ahead=4 ;
78
int sl_ahead=0;
79
uint8_t nfapi_mode = 0;
yilmazt's avatar
yilmazt committed
80
uint16_t NB_UE_INST = 1;
81
uint64_t downlink_frequency[MAX_NUM_CCs][4];
82 83

// dummy functions
Raymond Knopp's avatar
Raymond Knopp committed
84 85 86 87
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info)              { return(0);  }

void pdcp_run (const protocol_ctxt_t *const  ctxt_pP) { return;}

88 89 90 91 92 93
int8_t nr_mac_rrc_data_ind_ue(const module_id_t     module_id,
			      const int             CC_id,
			      const uint8_t         gNB_index,
			      const int8_t          channel,
			      const uint8_t*        pduP,
			      const sdu_size_t      pdu_len)
94 95 96 97 98
{
  return 0;
}


99
void pdcp_layer_init(void) {}
100 101 102 103 104 105 106 107 108 109
boolean_t
pdcp_data_ind(
  const protocol_ctxt_t *const ctxt_pP,
  const srb_flag_t   srb_flagP,
  const MBMS_flag_t  MBMS_flagP,
  const rb_id_t      rb_idP,
  const sdu_size_t   sdu_buffer_sizeP,
  mem_block_t *const sdu_buffer_pP
) { return(false);}

110 111
int rrc_init_nr_global_param(void){return(0);}

112 113
void config_common(int Mod_idP,
                   int pdsch_AntennaPorts, 
114
		   NR_ServingCellConfigCommon_t *scc
Raymond Knopp's avatar
Raymond Knopp committed
115
		   );
116

117 118 119 120 121 122 123 124 125
int generate_dlsch_header(unsigned char *mac_header,
                          unsigned char num_sdus,
                          unsigned short *sdu_lengths,
                          unsigned char *sdu_lcids,
                          unsigned char drx_cmd,
                          unsigned short timing_advance_cmd,
                          unsigned char *ue_cont_res_id,
                          unsigned char short_padding,
                          unsigned short post_padding){return 0;}
126
void nr_DRB_preconfiguration(void){}
127

128
// needed for some functions
129
openair0_config_t openair0_cfg[MAX_CARDS];
130

131

132 133


134 135 136
int main(int argc, char **argv)
{
  char c;
137
  int i,aa;//,l;
138
  double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
139
  uint8_t snr1set=0;
140
  float roundStats[50];
141
  float effRate;
Francesco Mani's avatar
Francesco Mani committed
142
  //float psnr;
143
  float eff_tp_check = 0.7;
144
  uint8_t snrRun;
145
  uint32_t TBS;
146 147
  int **txdata;
  double **s_re,**s_im,**r_re,**r_im;
148 149
  //double iqim = 0.0;
  //unsigned char pbch_pdu[6];
150 151 152
  //  int sync_pos, sync_pos_slot;
  //  FILE *rx_frame_file;
  FILE *output_fd = NULL;
153
  //uint8_t write_output_file=0;
154
  //int result;
155
  //int freq_offset;
156
  //  int subframe_offset;
157
  //  char fname[40], vname[40];
Ahmed Hussein's avatar
Ahmed Hussein committed
158
  int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
159
  //int n_errors2, n_alamouti;
160
  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
161 162
  uint8_t round;
  uint8_t num_rounds = 4;
163 164

  channel_desc_t *gNB2UE;
165 166 167
  //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0;
  //uint8_t extended_prefix_flag=0;
  //int8_t interf1=-21,interf2=-21;
168 169

  FILE *input_fd=NULL,*pbch_file_fd=NULL;
170
  //char input_val_str[50],input_val_str2[50];
171

172
  //uint8_t frame_mod4,num_pdcch_symbols = 0;
173 174 175

  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;

176 177
  //double pbch_sinr;
  //int pbch_tx_ant;
Ahmed Hussein's avatar
Ahmed Hussein committed
178
  int N_RB_DL=106,mu=1;
179
  nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config;
180
  NR_sched_pucch pucch_sched;
181

182
  //unsigned char frame_type = 0;
183

184
  int frame=0,slot=1;
185 186 187 188 189 190 191
  int frame_length_complex_samples;
  int frame_length_complex_samples_no_prefix;
  NR_DL_FRAME_PARMS *frame_parms;
  UE_nr_rxtx_proc_t UE_proc;
  NR_Sched_Rsp_t Sched_INFO;
  gNB_MAC_INST *gNB_mac;
  NR_UE_MAC_INST_t *UE_mac;
192
  int cyclic_prefix_type = NFAPI_CP_NORMAL;
193 194
  int run_initial_sync=0;
  int do_pdcch_flag=1;
195 196
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Raymond Knopp's avatar
Raymond Knopp committed
197
  int loglvl=OAILOG_INFO;
198 199

  float target_error_rate = 0.01;
200
  int css_flag=0;
201 202 203

  cpuf = get_cpu_freq_GHz();

204
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
yilmazt's avatar
yilmazt committed
205
    exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
206 207 208 209
  }

  randominit(0);

210
  int mcsIndex_set=0,rbStart_set=0,rbSize_set=0;
211
  int print_perf             = 0;
212

213 214
  FILE *scg_fd=NULL;
  
Sakthivel Velumani's avatar
Sakthivel Velumani committed
215
  while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w")) != -1) {
216
    switch (c) {
217 218
    case 'f':
      scg_fd = fopen(optarg,"r");
219

220
      if (scg_fd==NULL) {
221 222 223
        printf("Error opening %s\n",optarg);
        exit(-1);
      }
224
      break;
225

226
    /*case 'd':
227
      frame_type = 1;
228
      break;*/
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260

    case 'g':
      switch((char)*optarg) {
      case 'A':
        channel_model=SCM_A;
        break;

      case 'B':
        channel_model=SCM_B;
        break;

      case 'C':
        channel_model=SCM_C;
        break;

      case 'D':
        channel_model=SCM_D;
        break;

      case 'E':
        channel_model=EPA;
        break;

      case 'F':
        channel_model=EVA;
        break;

      case 'G':
        channel_model=ETU;
        break;

      default:
261
        printf("Unsupported channel model!\n");
262 263 264 265 266
        exit(-1);
      }

      break;

267
    /*case 'i':
268 269 270 271 272
      interf1=atoi(optarg);
      break;

    case 'j':
      interf2=atoi(optarg);
273
      break;*/
274 275 276 277 278 279 280

    case 'n':
      n_trials = atoi(optarg);
      break;

    case 's':
      snr0 = atof(optarg);
281
      printf("Setting SNR0 to %f\n",snr0);
282 283 284 285 286
      break;

    case 'S':
      snr1 = atof(optarg);
      snr1set=1;
287
      printf("Setting SNR1 to %f\n",snr1);
288 289 290 291 292 293 294
      break;

      /*
      case 't':
      Td= atof(optarg);
      break;
      */
295
    /*case 'p':
296
      extended_prefix_flag=1;
297
      break;*/
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

      /*
      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;
      */
    case 'x':
      transmission_mode=atoi(optarg);

      if ((transmission_mode!=1) &&
          (transmission_mode!=2) &&
          (transmission_mode!=6)) {
314
        printf("Unsupported transmission mode %d\n",transmission_mode);
315 316 317 318 319 320 321 322 323
        exit(-1);
      }

      break;

    case 'y':
      n_tx=atoi(optarg);

      if ((n_tx==0) || (n_tx>2)) {
324
        printf("Unsupported number of tx antennas %d\n",n_tx);
325 326 327 328 329 330 331 332 333
        exit(-1);
      }

      break;

    case 'z':
      n_rx=atoi(optarg);

      if ((n_rx==0) || (n_rx>2)) {
334
        printf("Unsupported number of rx antennas %d\n",n_rx);
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
        exit(-1);
      }

      break;

    case 'R':
      N_RB_DL = atoi(optarg);
      break;

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

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

      break;

    case 'P':
355 356
      print_perf=1;
      opp_enabled=1;
357 358 359 360 361
      break;
      
    case 'I':
      run_initial_sync=1;
      target_error_rate=0.1;
362
      slot = 0;
363 364 365 366 367 368
      break;

    case 'L':
      loglvl = atoi(optarg);
      break;

369

370 371 372
    case 'E':
	css_flag=1;
	break;
373

374

375
    case 'a':
Raymond Knopp's avatar
Raymond Knopp committed
376
      dlsch_config.rbStart = atoi(optarg);
377
      rbStart_set=1;
378 379 380
      break;

    case 'b':
Raymond Knopp's avatar
Raymond Knopp committed
381
      dlsch_config.rbSize = atoi(optarg);
382
      rbSize_set=1;
383 384 385
      break;

    case 'e':
Raymond Knopp's avatar
Raymond Knopp committed
386
      dlsch_config.mcsIndex[0] = atoi(optarg);
387
      mcsIndex_set=1;
388 389
      break;

390 391 392
    case 'm':
      mu = atoi(optarg);
      break;
393

394 395 396 397
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
398 399 400 401
    case 'w':
      output_fd = fopen("txdata.dat", "w+");
      break;

402 403 404 405 406
    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");
407 408
      //printf("-p Use extended prefix mode\n");
      //printf("-d Use TDD\n");
409 410 411 412 413
      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");
414
      printf("-y Number of TX antennas used in gNB\n");
415
      printf("-z Number of RX antennas used in UE\n");
416 417
      //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n");
      //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n");
418 419 420
      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");
421
      //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
422
      printf("-f raw file containing RRC configuration (generated by gNB)\n");
423
      printf("-F Input filename (.txt format) for RX conformance testing\n");
424
      printf("-E used CSS scheduler\n");
425
      printf("-o CORESET offset\n");
426 427
      printf("-a Start PRB for PDSCH\n");
      printf("-b Number of PRB for PDSCH\n");
428 429
      printf("-c Start symbol for PDSCH (fixed for now)\n");
      printf("-j Number of symbols for PDSCH (fixed for now)\n");
430
      printf("-e MSC index\n");
431
      printf("-t Acceptable effective throughput (in percentage)\n");
432
      printf("-P Print DLSCH performances\n");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
433
      printf("-w Write txdata to binary file (one frame)\n");
434 435 436 437
      exit (-1);
      break;
    }
  }
Raymond Knopp's avatar
Raymond Knopp committed
438
  
439 440 441 442
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

443 444
  get_softmodem_params()->phy_test = 1;
  
445 446 447 448
  if (snr1set==0)
    snr1 = snr0+10;


449 450 451
  RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
  RC.gNB[0] = (PHY_VARS_gNB*) malloc(sizeof(PHY_VARS_gNB ));
  memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB));
Raymond Knopp's avatar
Raymond Knopp committed
452

453
  gNB = RC.gNB[0];
454 455 456 457 458 459
  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;
  frame_parms->N_RB_UL = N_RB_DL;

Raymond Knopp's avatar
Raymond Knopp committed
460
  RC.nb_nr_macrlc_inst = 1;
cig's avatar
cig committed
461 462 463
  RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int));
  for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
    RC.nb_nr_mac_CC[i] = 1;
Raymond Knopp's avatar
Raymond Knopp committed
464 465 466
  mac_top_init_gNB();
  gNB_mac = RC.nrmac[0];
  gNB_RRC_INST rrc;
Raymond Knopp's avatar
Raymond Knopp committed
467
  memset((void*)&rrc,0,sizeof(rrc));
468

469
  /*
Raymond Knopp's avatar
Raymond Knopp committed
470
  // read in SCGroupConfig
Raymond Knopp's avatar
Raymond Knopp committed
471
  AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
Raymond Knopp's avatar
Raymond Knopp committed
472 473 474 475
  char buffer[1024];
  int msg_len=fread(buffer,1,1024,scg_fd);
  NR_RRCReconfiguration_t *NR_RRCReconfiguration;

Raymond Knopp's avatar
Raymond Knopp committed
476
  printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len);
Raymond Knopp's avatar
Raymond Knopp committed
477 478 479 480 481 482 483 484 485 486 487 488 489 490
  asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
						  &asn_DEF_NR_RRCReconfiguration,
						  (void **)&NR_RRCReconfiguration,
						  (uint8_t *)buffer,
						  msg_len); 
  
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
    AssertFatal(1==0,"NR_RRCReConfiguration decode error\n");
    // free the memory
    SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, NR_RRCReconfiguration, 1 );
    exit(-1);
  }      
  fclose(scg_fd);

Raymond Knopp's avatar
Raymond Knopp committed
491 492
  AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n");

Raymond Knopp's avatar
Raymond Knopp committed
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
  NR_RRCReconfiguration_IEs_t *reconfig_ies = NR_RRCReconfiguration->criticalExtensions.choice.rrcReconfiguration;
  NR_CellGroupConfig_t *secondaryCellGroup;
  dec_rval = uper_decode_complete( NULL,
				   &asn_DEF_NR_CellGroupConfig,
				   (void **)&secondaryCellGroup,
				   (uint8_t *)reconfig_ies->secondaryCellGroup->buf,
				   reconfig_ies->secondaryCellGroup->size); 
  
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
    AssertFatal(1==0,"NR_CellGroupConfig decode error\n");
    // free the memory
    SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 );
    exit(-1);
  }      
  
508 509
  NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
  */
Raymond Knopp's avatar
Raymond Knopp committed
510

511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528

  rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));

  NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
  NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
  prepare_scc(rrc.carrier.servingcellconfigcommon);
  uint64_t ssb_bitmap;
  fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);

  fill_default_secondaryCellGroup(scc,
				  secondaryCellGroup,
				  0,
				  1,
				  n_tx,
				  0);
  fix_scc(scc,ssb_bitmap);

  xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
Raymond Knopp's avatar
Raymond Knopp committed
529

Raymond Knopp's avatar
Raymond Knopp committed
530 531
  AssertFatal((gNB->if_inst         = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
Raymond Knopp's avatar
Raymond Knopp committed
532
  // common configuration
533
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
Raymond Knopp's avatar
Raymond Knopp committed
534
  // UE dedicated configuration
535
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
Raymond Knopp's avatar
Raymond Knopp committed
536
  phy_init_nr_gNB(gNB,0,0);
537
  N_RB_DL = gNB->frame_parms.N_RB_DL;
Raymond Knopp's avatar
Raymond Knopp committed
538
  // stub to configure frame_parms
Raymond Knopp's avatar
Raymond Knopp committed
539
  //  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
Raymond Knopp's avatar
Raymond Knopp committed
540 541 542
  // call MAC to configure common parameters


543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
  double fs,bw;

  if (mu == 1 && N_RB_DL == 217) { 
    fs = 122.88e6;
    bw = 80e6;
  }					       
  else if (mu == 1 && N_RB_DL == 245) {
    fs = 122.88e6;
    bw = 90e6;
  }
  else if (mu == 1 && N_RB_DL == 273) {
    fs = 122.88e6;
    bw = 100e6;
  }
  else if (mu == 1 && N_RB_DL == 106) { 
    fs = 61.44e6;
    bw = 40e6;
  }
561 562 563 564
  else if (mu == 3 && N_RB_DL == 66) {
    fs = 122.88e6;
    bw = 100e6;
  }
565 566 567 568
  else if (mu == 3 && N_RB_DL == 32) {
    fs = 61.44e6;
    bw = 50e6;
  }
569 570 571 572 573
  else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);

  gNB2UE = new_channel_desc_scm(n_tx,
                                n_rx,
                                channel_model,
574 575
 				fs,
				bw,
576
				30e-9,
577 578 579 580 581
                                0,
                                0,
                                0);

  if (gNB2UE==NULL) {
582
    printf("Problem generating channel model. Exiting.\n");
583 584 585 586
    exit(-1);
  }

  frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
587
  frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608

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

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

    printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
    txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
609
    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
610 611 612 613 614 615 616 617 618 619
  
  }

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


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Raymond Knopp's avatar
Raymond Knopp committed
620
  memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
621 622 623 624
  PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**));
  PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
  PHY_vars_UE_g[0][0] = UE;
  memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
Raymond Knopp's avatar
Raymond Knopp committed
625

626
  if (run_initial_sync==1)  UE->is_synchronized = 0;
627
  else                      {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
628 629
                      
  UE->perfect_ce = 0;
630
  for (i=0;i<10;i++) UE->current_thread_id[i] = 0;
631 632 633 634 635 636 637

  if (init_nr_ue_signal(UE, 1, 0) != 0)
  {
    printf("Error at UE NR initialisation\n");
    exit(-1);
  }

638 639
  init_nr_ue_transport(UE,0);

640
  nr_gold_pbch(UE);
641
  nr_gold_pdcch(UE,0,2);
642

643
  nr_l2_init_ue(NULL);
644
  UE_mac = get_mac_inst(0);
Guy De Souza's avatar
Guy De Souza committed
645
  
646 647 648
  UE->if_inst = nr_ue_if_module_init(0);
  UE->if_inst->scheduled_response = nr_ue_scheduled_response;
  UE->if_inst->phy_config_request = nr_ue_phy_config_request;
649
  UE->if_inst->dl_indication = nr_ue_dl_indication;
650 651 652
  UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
  

653
  UE_mac->if_module = nr_ue_if_module_init(0);
Ahmed Hussein's avatar
Ahmed Hussein committed
654
  
655
  unsigned int available_bits=0;
Ahmed Hussein's avatar
Ahmed Hussein committed
656 657 658 659 660
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
  unsigned int errors_bit    = 0;
  uint32_t errors_scrambling = 0;

661

Ahmed Hussein's avatar
Ahmed Hussein committed
662 663
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
664 665
  
  // generate signal
666 667 668 669 670
  AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
  gNB->pbch_configured = 1;
  gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
  
  if (mcsIndex_set==0) dlsch_config.mcsIndex[0]=9;
671
  
672
  if (rbStart_set==0) dlsch_config.rbStart=0;
673
  if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart;
Raymond Knopp's avatar
Raymond Knopp committed
674

675
  //Configure UE
676 677
  rrc.carrier.MIB = (uint8_t*) malloc(4);
  rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
678

679
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
680

681 682 683 684 685 686 687 688

  nr_dcireq_t dcireq;
  nr_scheduled_response_t scheduled_response;
  memset((void*)&dcireq,0,sizeof(dcireq));
  memset((void*)&scheduled_response,0,sizeof(scheduled_response));
  dcireq.module_id = 0;
  dcireq.gNB_index = 0;
  dcireq.cc_id     = 0;
689
  
690 691 692 693 694 695 696
  scheduled_response.dl_config = &dcireq.dl_config_req;
  scheduled_response.ul_config = &dcireq.ul_config_req;
  scheduled_response.tx_request = NULL;
  scheduled_response.module_id = 0;
  scheduled_response.CC_id     = 0;
  scheduled_response.frame = frame;
  scheduled_response.slot  = slot;
697
  
Francesco Mani's avatar
Francesco Mani committed
698

699
  nr_ue_phy_config_request(&UE_mac->phy_config);
700
  NR_UE_list_t *UE_list = &RC.nrmac[0]->UE_list;
Francesco Mani's avatar
Francesco Mani committed
701
  //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
702
  snrRun = 0;
703

Ahmed Hussein's avatar
Ahmed Hussein committed
704
  for (SNR = snr0; SNR < snr1; SNR += .2) {
705

706 707 708 709 710 711 712 713 714 715 716 717 718
    varArray_t *table_tx=initVarArray(1000,sizeof(double));
    reset_meas(&gNB->phy_proc_tx); // total gNB tx
    reset_meas(&gNB->dlsch_scrambling_stats);
    reset_meas(&gNB->dlsch_interleaving_stats);
    reset_meas(&gNB->dlsch_rate_matching_stats);
    reset_meas(&gNB->dlsch_segmentation_stats);
    reset_meas(&gNB->dlsch_modulation_stats);
    reset_meas(&gNB->dlsch_encoding_stats);
    reset_meas(&gNB->tinput);
    reset_meas(&gNB->tprep);
    reset_meas(&gNB->tparity);
    reset_meas(&gNB->toutput);  

719
    n_errors = 0;
720
    effRate = 0;
721 722
    //n_errors2 = 0;
    //n_alamouti = 0;
723
    errors_scrambling=0;
724
    n_false_positive = 0;
725 726
    if (n_trials== 1) num_rounds = 1;

Ahmed Hussein's avatar
Ahmed Hussein committed
727
    for (trial = 0; trial < n_trials; trial++) {
728

729
      errors_bit = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
730
      //multipath channel
731
      //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
732

733 734 735 736 737 738 739
      UE->rx_offset=0;
      UE_proc.frame_rx = frame;
      UE_proc.nr_tti_rx= slot;
      UE_proc.subframe_rx = slot;
      
      dcireq.frame     = frame;
      dcireq.slot      = slot;
740 741 742

      NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0];

743
      int harq_pid = slot;
744 745 746
      NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];

      NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
Sakthivel Velumani's avatar
Sakthivel Velumani committed
747
      nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
748
      
749 750
      UE_harq_process->harq_ack.ack = 0;
      round = 0;
751 752
      UE_harq_process->round = round;
      UE_harq_process->first_tx = 1;
753 754 755 756
        
      while ((round<num_rounds) && (UE_harq_process->harq_ack.ack==0)) {
        memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
        memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
757
        clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
758

759
        UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
760

761

762 763 764
        UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;   
        UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid;
        gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
765
      
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
        if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
        else               nr_schedule_css_dlsch_phytest(0,frame,slot);
        Sched_INFO.module_id = 0;
        Sched_INFO.CC_id     = 0;
        Sched_INFO.frame     = frame;
        Sched_INFO.slot      = slot;
        Sched_INFO.DL_req    = &gNB_mac->DL_req[0];
        Sched_INFO.UL_tti_req    = &gNB_mac->UL_tti_req[0];
        Sched_INFO.UL_dci_req  = NULL;
        Sched_INFO.TX_req    = &gNB_mac->TX_req[0];
        nr_schedule_response(&Sched_INFO);
        
        if (run_initial_sync)
          nr_common_signal_procedures(gNB,frame,slot);
        else
          phy_procedures_gNB_TX(gNB,frame,slot,0);
            
        int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
        
        if (n_trials==1) {
786
          LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
787
          if (gNB->frame_parms.nb_antennas_tx>1)
788
          LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
789 790
        }
        int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
791
        if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
792 793 794 795
        
        //TODO: loop over slots
        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
    
796 797 798 799 800 801 802
          if (cyclic_prefix_type == 1) {
            PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
                         &txdata[aa][tx_offset],
                         frame_parms->ofdm_symbol_size,
                         12,
                         frame_parms->nb_prefix_samples,
                         CYCLIC_PREFIX);
803
          } else {
804 805 806 807 808
            nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
                                 &txdata[aa][tx_offset],
                                 14,
                                 frame_parms);
          }
809 810 811
        }
       
        if (n_trials==1) {
812
          LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
813
          if (gNB->frame_parms.nb_antennas_tx>1)
814
            LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
815
        }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
816 817
        if (output_fd) {
          printf("writing txdata to binary file\n");
818
          fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
819
        }
820

821
        int txlev = signal_energy(&txdata[0][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
822 823 824 825
        
        //  if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev));
        
        for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)); 
826 827 828 829 830 831 832
             i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0)); 
             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]);
          }
833 834 835 836 837 838 839 840
        }
        
        //AWGN
        sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
        sigma2    = pow(10, sigma2_dB/10);
        if (n_trials==1) printf("sigma2 %f (%f dB), txlev %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
        
        for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); 
841 842 843 844 845 846 847
             i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
             i++) {

          for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
            ((short*) UE->common_vars.rxdata[aa])[2*i]   = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
            ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
          }
848 849 850 851 852 853
        }
        
        nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
        nr_ue_scheduled_response(&scheduled_response);
        
        phy_procedures_nrUE_RX(UE,
854 855 856 857
                               &UE_proc,
                               0,
                               do_pdcch_flag,
                               normal_txrx);
858
        
859
        //printf("dlsim round %d ends\n",round);
860 861
        round++;
      } // round
862 863 864 865 866
      
      //----------------------------------------------------------
      //---------------------- count errors ----------------------
      //----------------------------------------------------------
      
867 868 869
      if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >= 
        UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1)
        n_errors++;
870
        
871 872 873
      NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]];
      int16_t *UE_llr = pdsch_vars[0]->llr[0];
      
874
      TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
875
      uint16_t length_dmrs = 1;
876 877 878 879
      uint16_t nb_rb       = rel15->rbSize;
      uint8_t  nb_re_dmrs  = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
      uint8_t  mod_order   = rel15->qamModOrder[0];
      uint8_t  nb_symb_sch = rel15->NrOfSymbols;
880
      
881
      available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
882 883
      
      for (i = 0; i < available_bits; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
884
	
885 886 887 888 889 890
	if(((gNB_dlsch->harq_processes[harq_pid]->f[i] == 0) && (UE_llr[i] <= 0)) || 
	   ((gNB_dlsch->harq_processes[harq_pid]->f[i] == 1) && (UE_llr[i] >= 0)))
	  {
	    if(errors_scrambling == 0) {
	      LOG_D(PHY,"\n");
	      LOG_D(PHY,"First bit in error in unscrambling = %d\n",i);
Raymond Knopp's avatar
Raymond Knopp committed
891
	    }
892
	    errors_scrambling++;
Raymond Knopp's avatar
Raymond Knopp committed
893 894
	  }
	
895 896
      }
      for (i = 0; i < TBS; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
897
	
898 899
	estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7);
	test_input_bit[i]       = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
Raymond Knopp's avatar
Raymond Knopp committed
900
	
901 902 903 904
	if (estimated_output_bit[i] != test_input_bit[i]) {
	  if(errors_bit == 0)
	    LOG_D(PHY,"First bit in error in decoding = %d (errors scrambling %d)\n",i,errors_scrambling);
	  errors_bit++;
Raymond Knopp's avatar
Raymond Knopp committed
905 906
	}
	
907 908 909 910 911 912
      }
      
      ////////////////////////////////////////////////////////////
      
      if (errors_scrambling > 0) {
	if (n_trials == 1)
913
	  printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial);
914 915 916 917 918 919 920
      }
      
      if (errors_bit > 0) {
	n_false_positive++;
	if (n_trials == 1)
	  printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
      }
921
      roundStats[snrRun]+=((float)round); 
922
      if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
Ahmed Hussein's avatar
Ahmed Hussein committed
923
    } // noise trials
924

925
    roundStats[snrRun]/=((float)n_trials);
926
    effRate /= n_trials;
Ahmed Hussein's avatar
Ahmed Hussein committed
927 928
    printf("*****************************************\n");
    printf("SNR %f, (false positive %f)\n", SNR,
Sakthivel Velumani's avatar
Sakthivel Velumani committed
929
           (float) n_errors / (float) n_trials);
Ahmed Hussein's avatar
Ahmed Hussein committed
930 931
    printf("*****************************************\n");
    printf("\n");
Francesco Mani's avatar
Francesco Mani committed
932
    printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
Ahmed Hussein's avatar
Ahmed Hussein committed
933
    printf("\n");
934

935
    if (print_perf==1) {
936 937 938 939 940
      printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
	     1000>>*scc->ssbSubcarrierSpacing,dlsch_config.rbSize,dlsch_config.mcsIndex[0],
	     gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3,
	     gNB->dlsch[0][0]->harq_processes[0]->K,
	     gNB->dlsch[0][0]->harq_processes[0]->K/((gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10));
941 942 943 944 945 946 947 948 949 950 951 952 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
      printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
      printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
      printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
      printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
      printStatIndent3(&gNB->tprep,"DLSCH LDPC input preparation time");
      printStatIndent3(&gNB->tparity,"DLSCH LDPC parity generation time");
      printStatIndent3(&gNB->toutput,"DLSCH LDPC output generation time");
      printStatIndent3(&gNB->dlsch_rate_matching_stats,"DLSCH Rate Mataching time");
      printStatIndent3(&gNB->dlsch_interleaving_stats,  "DLSCH Interleaving time");
      printStatIndent2(&gNB->dlsch_modulation_stats,"DLSCH modulation time");
      printStatIndent2(&gNB->dlsch_scrambling_stats,  "DLSCH scrambling time");


      printf("\nUE RX function statistics (per %d us slot)\n",1000>>*scc->ssbSubcarrierSpacing);
      /*
      printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx");
      printStatIndent(&ue_front_end_tot,"Front end processing");
      printStatIndent(&dlsch_llr_tot,"rx_pdsch processing");
      printStatIndent2(&pdsch_procedures_tot,"pdsch processing");
      printStatIndent2(&dlsch_procedures_tot,"dlsch processing");
      printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing");
      printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation");
      printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time");
      printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time");
      printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time ");
      printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time");
      printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching");
      printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f       %.2f us (%d cycles, %d trials)\n",
	     UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ?
	     UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus :
	     UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
	     UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials,
	     (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase,
	     (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials),
	     UE->dlsch_turbo_decoding_stats.trials);
      printStatIndent2(&UE->dlsch_tc_init_stats,"init");
      printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha");
      printStatIndent2(&UE->dlsch_tc_beta_stats,"beta");
      printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma");
      printStatIndent2(&UE->dlsch_tc_ext_stats,"ext");
      printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver");
      printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC");
      */
    }
985 986 987 988 989 990 991 992

    if (n_trials == 1) {
      
      LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
      if (UE->frame_parms.nb_antennas_rx>1)
	LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
      LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1);
      write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
993
      LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]][0]->llr[0],available_bits,1,0);
994 995 996 997 998 999 1000 1001 1002
      break;
    }

    //if ((float)n_errors/(float)n_trials <= target_error_rate) {
    if (effRate >= (eff_tp_check*TBS)) {
      printf("PDSCH test OK\n");
      break;
    }

1003
    snrRun++;
1004 1005
  } // NSR

1006
  /*if (n_trials>1) {
1007 1008 1009 1010 1011 1012
    printf("HARQ stats:\nSNR\tRounds\n");
    psnr = snr0;
    for (uint8_t i=0; i<snrRun; i++) {
      printf("%.1f\t%.2f\n",psnr,roundStats[i]);
      psnr+=0.2;
    }
1013
  }*/
1014

Ahmed Hussein's avatar
Ahmed Hussein committed
1015
  for (i = 0; i < 2; i++) {
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
    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);
Ahmed Hussein's avatar
Ahmed Hussein committed
1028 1029 1030
  free(test_input_bit);
  free(estimated_output_bit);
  
1031 1032 1033 1034 1035 1036
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1037 1038
  if (scg_fd)
    fclose(scg_fd);
1039
  return(n_errors);
Raymond Knopp's avatar
Raymond Knopp committed
1040
  
1041
}