dlsim.c 35.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"
44
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
cig's avatar
cig committed
45
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
46
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
47
#include "SCHED_NR/fapi_nr_l1.h"
48
#include "SCHED_NR/sched_nr.h"
49
#include "SCHED_NR_UE/defs.h"
50 51 52 53
#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"

54
#include "LAYER2/NR_MAC_UE/mac_proto.h"
yilmazt's avatar
yilmazt committed
55 56
//#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
57
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
58
#include "NR_asn_constant.h"
59
#include "RRC/NR/MESSAGES/asn1_msg.h"
60 61 62
#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
63
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
64

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


Raymond Knopp's avatar
Raymond Knopp committed
70

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

76
double cpuf;
77

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

// dummy functions
Raymond Knopp's avatar
Raymond Knopp committed
85 86 87 88
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;}

89 90 91 92 93 94
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)
95 96 97 98 99
{
  return 0;
}


100
void pdcp_layer_init(void) {}
101 102 103 104 105 106 107 108 109 110
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);}

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

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

118 119 120 121 122 123 124 125 126
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;}
127
void nr_DRB_preconfiguration(void){}
128

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

132

133 134


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

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

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

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

  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;

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

183
  //unsigned char frame_type = 0;
184

185
  int frame=1,slot=1;
186 187 188 189 190 191 192
  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;
193
  int cyclic_prefix_type = NFAPI_CP_NORMAL;
194 195
  int run_initial_sync=0;
  int do_pdcch_flag=1;
196 197
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Raymond Knopp's avatar
Raymond Knopp committed
198
  int loglvl=OAILOG_INFO;
199 200

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

  cpuf = get_cpu_freq_GHz();

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

  randominit(0);

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

214 215
  FILE *scg_fd=NULL;
  
Sakthivel Velumani's avatar
Sakthivel Velumani committed
216
  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) {
217
    switch (c) {
218 219
    case 'f':
      scg_fd = fopen(optarg,"r");
220

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

227
    /*case 'd':
228
      frame_type = 1;
229
      break;*/
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 261

    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:
262
        printf("Unsupported channel model!\n");
263 264 265 266 267
        exit(-1);
      }

      break;

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

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

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

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

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

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

      /*
      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)) {
315
        printf("Unsupported transmission mode %d\n",transmission_mode);
316 317 318 319 320 321 322 323 324
        exit(-1);
      }

      break;

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

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

      break;

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

      if ((n_rx==0) || (n_rx>2)) {
335
        printf("Unsupported number of rx antennas %d\n",n_rx);
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
        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':
356 357
      print_perf=1;
      opp_enabled=1;
358 359 360 361 362
      break;
      
    case 'I':
      run_initial_sync=1;
      target_error_rate=0.1;
363
      slot = 0;
364 365 366 367 368 369
      break;

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

370

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

375

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

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

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

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

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

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

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

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


450 451 452
  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
453

454
  gNB = RC.gNB[0];
455 456 457 458 459 460
  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
461
  RC.nb_nr_macrlc_inst = 1;
cig's avatar
cig committed
462 463 464
  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
465 466 467
  mac_top_init_gNB();
  gNB_mac = RC.nrmac[0];
  gNB_RRC_INST rrc;
Raymond Knopp's avatar
Raymond Knopp committed
468
  memset((void*)&rrc,0,sizeof(rrc));
469

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

Raymond Knopp's avatar
Raymond Knopp committed
477
  printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len);
Raymond Knopp's avatar
Raymond Knopp committed
478 479 480 481 482 483 484 485 486 487 488 489 490 491
  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
492 493
  AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n");

Raymond Knopp's avatar
Raymond Knopp committed
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
  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);
  }      
  
509 510
  NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
  */
Raymond Knopp's avatar
Raymond Knopp committed
511

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

  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
530

Raymond Knopp's avatar
Raymond Knopp committed
531 532
  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
533
  // common configuration
534
  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
535
  // UE dedicated configuration
536
  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
537
  phy_init_nr_gNB(gNB,0,0);
538
  N_RB_DL = gNB->frame_parms.N_RB_DL;
Raymond Knopp's avatar
Raymond Knopp committed
539
  // stub to configure frame_parms
Raymond Knopp's avatar
Raymond Knopp committed
540
  //  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
Raymond Knopp's avatar
Raymond Knopp committed
541 542 543
  // call MAC to configure common parameters


544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
  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;
  }
562 563 564 565
  else if (mu == 3 && N_RB_DL == 66) {
    fs = 122.88e6;
    bw = 100e6;
  }
566 567 568 569
  else if (mu == 3 && N_RB_DL == 32) {
    fs = 61.44e6;
    bw = 50e6;
  }
570 571 572 573 574
  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,
575 576
 				fs,
				bw,
577
				30e-9,
578 579 580 581 582
                                0,
                                0,
                                0);

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

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

  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));
610
    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
611 612 613 614 615 616 617 618 619 620
  
  }

  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
621
  memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
622 623 624 625
  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
626

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

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

639 640
  init_nr_ue_transport(UE,0);

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

644
  nr_l2_init_ue(NULL);
645
  UE_mac = get_mac_inst(0);
Guy De Souza's avatar
Guy De Souza committed
646
  
647 648 649
  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;
650
  UE->if_inst->dl_indication = nr_ue_dl_indication;
651 652 653
  UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
  

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

662

Ahmed Hussein's avatar
Ahmed Hussein committed
663 664
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
665 666
  
  // generate signal
667 668 669 670 671
  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;
672
  
673
  if (rbStart_set==0) dlsch_config.rbStart=0;
674
  if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart;
Raymond Knopp's avatar
Raymond Knopp committed
675

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

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

682 683 684 685 686 687 688 689

  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;
690
  
691 692 693 694 695 696 697
  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;
698
  
Francesco Mani's avatar
Francesco Mani committed
699

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

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

707 708 709 710 711 712 713 714 715 716 717 718 719
    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);  

720 721
    clear_pdsch_stats(gNB);

722
    n_errors = 0;
723
    effRate = 0;
724 725
    //n_errors2 = 0;
    //n_alamouti = 0;
726
    errors_scrambling=0;
727
    n_false_positive = 0;
728 729
    if (n_trials== 1) num_rounds = 1;

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

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

736 737 738 739 740 741 742
      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;
743 744 745

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

746
      int harq_pid = slot;
747 748 749
      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
750
      nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
751
      
752 753
      UE_harq_process->harq_ack.ack = 0;
      round = 0;
754 755
      UE_harq_process->round = round;
      UE_harq_process->first_tx = 1;
756 757 758 759
        
      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));
760
        clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
761

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

764

765 766 767
        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;
768
      
769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
        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) {
789
          LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
790
          if (gNB->frame_parms.nb_antennas_tx>1)
791
          LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
792 793
        }
        int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
794
        if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
795 796 797 798
        
        //TODO: loop over slots
        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
    
799 800 801 802 803 804 805
          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);
806
          } else {/*
807 808 809 810
            nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
                                 &txdata[aa][tx_offset],
                                 14,
                                 frame_parms);
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
		  */
	    PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
			 (int*)&txdata[aa][tx_offset],
			 frame_parms->ofdm_symbol_size,
			 1,
			 frame_parms->nb_prefix_samples0,
			 CYCLIC_PREFIX);
	    	    
	    apply_nr_rotation(frame_parms,
			      (int16_t*)&txdata[aa][tx_offset],
			      slot,
			      0,
			      1,
			      frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
	    PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset+frame_parms->ofdm_symbol_size],
			 (int*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
			 frame_parms->ofdm_symbol_size,
			 13,
			 frame_parms->nb_prefix_samples,
			 CYCLIC_PREFIX);
	    apply_nr_rotation(frame_parms,
			      (int16_t*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
			      slot,
			      1,
			      13,
			      frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
	    
838
          }
839 840 841
        }
       
        if (n_trials==1) {
842
          LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
843
          if (gNB->frame_parms.nb_antennas_tx>1)
844
            LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
845
        }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
846 847
        if (output_fd) {
          printf("writing txdata to binary file\n");
848
          fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
849
        }
850

851
        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);
852 853 854 855
        
        //  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)); 
856 857 858 859 860 861 862
             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]);
          }
863 864 865 866 867 868 869 870
        }
        
        //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); 
871 872 873 874 875 876 877
             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)));
          }
878 879 880 881 882 883
        }
        
        nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
        nr_ue_scheduled_response(&scheduled_response);
        
        phy_procedures_nrUE_RX(UE,
884 885 886 887
                               &UE_proc,
                               0,
                               do_pdcch_flag,
                               normal_txrx);
888
        
889
        //printf("dlsim round %d ends\n",round);
890 891
        round++;
      } // round
892 893 894 895 896
      
      //----------------------------------------------------------
      //---------------------- count errors ----------------------
      //----------------------------------------------------------
      
897 898 899
      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++;
900
        
901 902 903
      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];
      
904
      TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
905
      uint16_t length_dmrs = 1;
906 907 908 909
      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;
910
      
911
      available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
912 913
      
      for (i = 0; i < available_bits; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
914
	
915 916 917 918 919 920
	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
921
	    }
922
	    errors_scrambling++;
Raymond Knopp's avatar
Raymond Knopp committed
923 924
	  }
	
925 926
      }
      for (i = 0; i < TBS; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
927
	
928 929
	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
930
	
931 932 933 934
	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
935 936
	}
	
937 938 939 940 941 942
      }
      
      ////////////////////////////////////////////////////////////
      
      if (errors_scrambling > 0) {
	if (n_trials == 1)
943
	  printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial);
944 945 946 947 948 949 950
      }
      
      if (errors_bit > 0) {
	n_false_positive++;
	if (n_trials == 1)
	  printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
      }
951
      roundStats[snrRun]+=((float)round); 
952
      if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
Ahmed Hussein's avatar
Ahmed Hussein committed
953
    } // noise trials
954

955
    roundStats[snrRun]/=((float)n_trials);
956
    effRate /= n_trials;
Ahmed Hussein's avatar
Ahmed Hussein committed
957 958
    printf("*****************************************\n");
    printf("SNR %f, (false positive %f)\n", SNR,
Sakthivel Velumani's avatar
Sakthivel Velumani committed
959
           (float) n_errors / (float) n_trials);
Ahmed Hussein's avatar
Ahmed Hussein committed
960 961
    printf("*****************************************\n");
    printf("\n");
962
    dump_pdsch_stats(gNB);
Francesco Mani's avatar
Francesco Mani committed
963
    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
964
    printf("\n");
965

966
    if (print_perf==1) {
967 968 969 970 971
      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));
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
      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");
      */
    }
1016 1017 1018 1019 1020 1021 1022 1023

    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);
1024
      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);
1025 1026 1027 1028 1029 1030 1031 1032 1033
      break;
    }

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

1034
    snrRun++;
1035 1036
  } // NSR

1037
  /*if (n_trials>1) {
1038 1039 1040 1041 1042 1043
    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;
    }
1044
  }*/
1045

Ahmed Hussein's avatar
Ahmed Hussein committed
1046
  for (i = 0; i < 2; i++) {
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
    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
1059 1060 1061
  free(test_input_bit);
  free(estimated_output_bit);
  
1062 1063 1064 1065 1066 1067
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1068 1069
  if (scg_fd)
    fclose(scg_fd);
1070
  return(n_errors);
Raymond Knopp's avatar
Raymond Knopp committed
1071
  
1072
}