dlsim.c 35.9 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"


70 71 72
unsigned char NB_eNB_INST=0;
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
rlc_info_t Rlc_info_um,Rlc_info_am_config;
Raymond Knopp's avatar
Raymond Knopp committed
73

74 75 76
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
77 78
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];

79
double cpuf;
80

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

// dummy functions
Raymond Knopp's avatar
Raymond Knopp committed
88 89
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info)              { return(0);  }

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

100 101
void
rrc_data_ind(
102
  const protocol_ctxt_t *const ctxt_pP,
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
  const rb_id_t                Srb_id,
  const sdu_size_t             sdu_sizeP,
  const uint8_t   *const       buffer_pP
)
{
}

int
gtpv1u_create_s1u_tunnel(
  const instance_t                              instanceP,
  const gtpv1u_enb_create_tunnel_req_t *const  create_tunnel_req_pP,
  gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
) {
  return 0;
}
118

119 120 121 122 123 124 125 126
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
  const protocol_ctxt_t *const ctxt_pP,
  const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
  uint8_t                         *inde_list
) {
  return 0;
}
127

128 129
void config_common(int Mod_idP,
                   int pdsch_AntennaPorts, 
130
		   NR_ServingCellConfigCommon_t *scc
Raymond Knopp's avatar
Raymond Knopp committed
131
		   );
132

133 134 135 136 137 138 139 140 141
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;}
142

143
// needed for some functions
144
openair0_config_t openair0_cfg[MAX_CARDS];
145

146

147 148


149 150 151
int main(int argc, char **argv)
{
  char c;
152
  int i,aa;//,l;
153
  double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
154
  uint8_t snr1set=0;
155
  float roundStats[50];
156
  float effRate;
Francesco Mani's avatar
Francesco Mani committed
157
  //float psnr;
158
  float eff_tp_check = 0.7;
159
  uint8_t snrRun;
160
  uint32_t TBS;
161 162
  int **txdata;
  double **s_re,**s_im,**r_re,**r_im;
163 164
  //double iqim = 0.0;
  //unsigned char pbch_pdu[6];
165 166 167
  //  int sync_pos, sync_pos_slot;
  //  FILE *rx_frame_file;
  FILE *output_fd = NULL;
168
  //uint8_t write_output_file=0;
169
  //int result;
170
  //int freq_offset;
171
  //  int subframe_offset;
172
  //  char fname[40], vname[40];
Ahmed Hussein's avatar
Ahmed Hussein committed
173
  int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
174
  //int n_errors2, n_alamouti;
175
  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
176 177
  uint8_t round;
  uint8_t num_rounds = 4;
178 179

  channel_desc_t *gNB2UE;
180 181 182
  //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0;
  //uint8_t extended_prefix_flag=0;
  //int8_t interf1=-21,interf2=-21;
183 184

  FILE *input_fd=NULL,*pbch_file_fd=NULL;
185
  //char input_val_str[50],input_val_str2[50];
186

187
  //uint8_t frame_mod4,num_pdcch_symbols = 0;
188 189 190

  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;

191 192
  //double pbch_sinr;
  //int pbch_tx_ant;
Ahmed Hussein's avatar
Ahmed Hussein committed
193
  int N_RB_DL=106,mu=1;
194
  nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config;
195
  NR_sched_pucch pucch_sched;
196

197
  //unsigned char frame_type = 0;
198

199
  int frame=1,slot=1;
200
  int frame_length_complex_samples;
201
  //int frame_length_complex_samples_no_prefix;
202 203 204 205 206
  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;
207
  int cyclic_prefix_type = NFAPI_CP_NORMAL;
208
  int run_initial_sync=0;
209 210
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Raymond Knopp's avatar
Raymond Knopp committed
211
  int loglvl=OAILOG_INFO;
212

213
  //float target_error_rate = 0.01;
214
  int css_flag=0;
215 216 217

  cpuf = get_cpu_freq_GHz();

218
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
yilmazt's avatar
yilmazt committed
219
    exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
220 221 222 223
  }

  randominit(0);

224
  int mcsIndex_set=0,rbStart_set=0,rbSize_set=0;
225
  int print_perf             = 0;
226

227 228
  FILE *scg_fd=NULL;
  
Sakthivel Velumani's avatar
Sakthivel Velumani committed
229
  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) {
230
    switch (c) {
231 232
    case 'f':
      scg_fd = fopen(optarg,"r");
233

234
      if (scg_fd==NULL) {
235 236 237
        printf("Error opening %s\n",optarg);
        exit(-1);
      }
238
      break;
239

240
    /*case 'd':
241
      frame_type = 1;
242
      break;*/
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

    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:
275
        printf("Unsupported channel model!\n");
276 277 278 279 280
        exit(-1);
      }

      break;

281
    /*case 'i':
282 283 284 285 286
      interf1=atoi(optarg);
      break;

    case 'j':
      interf2=atoi(optarg);
287
      break;*/
288 289 290 291 292 293 294

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

    case 's':
      snr0 = atof(optarg);
295
      printf("Setting SNR0 to %f\n",snr0);
296 297 298 299 300
      break;

    case 'S':
      snr1 = atof(optarg);
      snr1set=1;
301
      printf("Setting SNR1 to %f\n",snr1);
302 303 304 305 306 307 308
      break;

      /*
      case 't':
      Td= atof(optarg);
      break;
      */
309
    /*case 'p':
310
      extended_prefix_flag=1;
311
      break;*/
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327

      /*
      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)) {
328
        printf("Unsupported transmission mode %d\n",transmission_mode);
329 330 331 332 333 334 335 336 337
        exit(-1);
      }

      break;

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

      if ((n_tx==0) || (n_tx>2)) {
338
        printf("Unsupported number of tx antennas %d\n",n_tx);
339 340 341 342 343 344 345 346 347
        exit(-1);
      }

      break;

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

      if ((n_rx==0) || (n_rx>2)) {
348
        printf("Unsupported number of rx antennas %d\n",n_rx);
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
        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':
369 370
      print_perf=1;
      opp_enabled=1;
371 372 373 374
      break;
      
    case 'I':
      run_initial_sync=1;
375
      //target_error_rate=0.1;
376
      slot = 0;
377 378 379 380 381 382
      break;

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

383

384 385 386
    case 'E':
	css_flag=1;
	break;
387

388

389
    case 'a':
Raymond Knopp's avatar
Raymond Knopp committed
390
      dlsch_config.rbStart = atoi(optarg);
391
      rbStart_set=1;
392 393 394
      break;

    case 'b':
Raymond Knopp's avatar
Raymond Knopp committed
395
      dlsch_config.rbSize = atoi(optarg);
396
      rbSize_set=1;
397 398 399
      break;

    case 'e':
Raymond Knopp's avatar
Raymond Knopp committed
400
      dlsch_config.mcsIndex[0] = atoi(optarg);
401
      mcsIndex_set=1;
402 403
      break;

404 405 406
    case 'm':
      mu = atoi(optarg);
      break;
407

408 409 410 411
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
412 413 414 415
    case 'w':
      output_fd = fopen("txdata.dat", "w+");
      break;

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

457 458
  get_softmodem_params()->phy_test = 1;
  
459 460 461 462
  if (snr1set==0)
    snr1 = snr0+10;


463 464 465
  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
466

467
  gNB = RC.gNB[0];
468 469 470 471 472 473
  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
474
  RC.nb_nr_macrlc_inst = 1;
cig's avatar
cig committed
475 476 477
  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
478 479 480
  mac_top_init_gNB();
  gNB_mac = RC.nrmac[0];
  gNB_RRC_INST rrc;
Raymond Knopp's avatar
Raymond Knopp committed
481
  memset((void*)&rrc,0,sizeof(rrc));
482

483
  /*
Raymond Knopp's avatar
Raymond Knopp committed
484
  // read in SCGroupConfig
Raymond Knopp's avatar
Raymond Knopp committed
485
  AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
Raymond Knopp's avatar
Raymond Knopp committed
486 487 488 489
  char buffer[1024];
  int msg_len=fread(buffer,1,1024,scg_fd);
  NR_RRCReconfiguration_t *NR_RRCReconfiguration;

Raymond Knopp's avatar
Raymond Knopp committed
490
  printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len);
Raymond Knopp's avatar
Raymond Knopp committed
491 492 493 494 495 496 497 498 499 500 501 502 503 504
  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
505 506
  AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n");

Raymond Knopp's avatar
Raymond Knopp committed
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
  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);
  }      
  
522 523
  NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
  */
Raymond Knopp's avatar
Raymond Knopp committed
524

525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542

  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
543

Raymond Knopp's avatar
Raymond Knopp committed
544 545
  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
546
  // common configuration
547
  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
548
  // UE dedicated configuration
549
  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
550
  phy_init_nr_gNB(gNB,0,0);
551
  N_RB_DL = gNB->frame_parms.N_RB_DL;
Raymond Knopp's avatar
Raymond Knopp committed
552
  // stub to configure frame_parms
Raymond Knopp's avatar
Raymond Knopp committed
553
  //  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
Raymond Knopp's avatar
Raymond Knopp committed
554 555 556
  // call MAC to configure common parameters


557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
  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;
  }
575 576 577 578
  else if (mu == 3 && N_RB_DL == 66) {
    fs = 122.88e6;
    bw = 100e6;
  }
579 580 581 582
  else if (mu == 3 && N_RB_DL == 32) {
    fs = 61.44e6;
    bw = 50e6;
  }
583 584 585 586 587
  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,
588 589
 				fs,
				bw,
590
				30e-9,
591 592 593 594 595
                                0,
                                0,
                                0);

  if (gNB2UE==NULL) {
596
    printf("Problem generating channel model. Exiting.\n");
597 598 599 600
    exit(-1);
  }

  frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
601
  //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622

  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));
623
    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
624 625 626 627 628 629 630 631 632 633
  
  }

  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
634
  memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
635 636 637 638
  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
639

640
  if (run_initial_sync==1)  UE->is_synchronized = 0;
641
  else                      {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
642 643
                      
  UE->perfect_ce = 0;
644
  for (i=0;i<10;i++) UE->current_thread_id[i] = 0;
645 646 647 648 649 650 651

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

652 653
  init_nr_ue_transport(UE,0);

654
  nr_gold_pbch(UE);
655
  nr_gold_pdcch(UE,0,2);
656

657
  nr_l2_init_ue(NULL);
658
  UE_mac = get_mac_inst(0);
Guy De Souza's avatar
Guy De Souza committed
659
  
660 661 662
  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;
663
  UE->if_inst->dl_indication = nr_ue_dl_indication;
664 665 666
  UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
  

667
  UE_mac->if_module = nr_ue_if_module_init(0);
Ahmed Hussein's avatar
Ahmed Hussein committed
668
  
669
  unsigned int available_bits=0;
Ahmed Hussein's avatar
Ahmed Hussein committed
670 671 672 673 674
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
  unsigned int errors_bit    = 0;
  uint32_t errors_scrambling = 0;

675

Ahmed Hussein's avatar
Ahmed Hussein committed
676 677
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
678 679
  
  // generate signal
680 681 682 683 684
  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;
685
  
686
  if (rbStart_set==0) dlsch_config.rbStart=0;
687
  if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart;
Raymond Knopp's avatar
Raymond Knopp committed
688

689
  //Configure UE
690 691
  rrc.carrier.MIB = (uint8_t*) malloc(4);
  rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
692

693
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
694

695 696 697 698 699 700 701 702

  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;
703
  
704 705 706 707 708 709 710
  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;
711
  
Francesco Mani's avatar
Francesco Mani committed
712

713
  nr_ue_phy_config_request(&UE_mac->phy_config);
714
  NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
Francesco Mani's avatar
Francesco Mani committed
715
  //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
716
  snrRun = 0;
717

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

720 721 722 723 724 725 726 727 728 729 730 731 732
    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);  

733 734
    clear_pdsch_stats(gNB);

735
    n_errors = 0;
736
    effRate = 0;
737 738
    //n_errors2 = 0;
    //n_alamouti = 0;
739
    errors_scrambling=0;
740
    n_false_positive = 0;
741 742
    if (n_trials== 1) num_rounds = 1;

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

745
      errors_bit = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
746
      //multipath channel
747
      //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
748

749 750 751 752 753 754 755
      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;
756 757 758

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

759
      int harq_pid = slot;
760 761 762
      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
763
      nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
764
      
765 766
      UE_harq_process->harq_ack.ack = 0;
      round = 0;
767 768
      UE_harq_process->round = round;
      UE_harq_process->first_tx = 1;
769 770 771 772
        
      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));
773
        clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
774

775
        UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
776

777

778 779
        UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
        UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid;
780
        gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
781 782
        for (int i=0; i<MAX_NUM_CORESET; i++)
          gNB_mac->UE_list.num_pdcch_cand[0][i] = 0;
783
      
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
        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) {
804
          LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
805
          if (gNB->frame_parms.nb_antennas_tx>1)
806
          LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
807 808
        }
        int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
809
        if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
810 811 812 813
        
        //TODO: loop over slots
        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
    
814 815 816 817 818 819 820
          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);
821
          } else {/*
822 823 824 825
            nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
                                 &txdata[aa][tx_offset],
                                 14,
                                 frame_parms);
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
		  */
	    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);
	    
853
          }
854 855 856
        }
       
        if (n_trials==1) {
857
          LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
858
          if (gNB->frame_parms.nb_antennas_tx>1)
859
            LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
860
        }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
861 862
        if (output_fd) {
          printf("writing txdata to binary file\n");
863
          fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
864
        }
865

866
        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);
867 868 869 870
        
        //  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)); 
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_tx; aa++) {
            r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
            r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
          }
878 879 880 881 882 883 884 885
        }
        
        //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); 
886 887 888 889 890 891 892
             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)));
          }
893 894 895 896 897 898
        }
        
        nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
        nr_ue_scheduled_response(&scheduled_response);
        
        phy_procedures_nrUE_RX(UE,
899 900 901
                               &UE_proc,
                               0,
                               normal_txrx);
902
        
903
        //printf("dlsim round %d ends\n",round);
904 905
        round++;
      } // round
906 907 908 909 910
      
      //----------------------------------------------------------
      //---------------------- count errors ----------------------
      //----------------------------------------------------------
      
911 912 913
      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++;
914
        
915 916 917
      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];
      
918
      TBS                  = UE_harq_process->TBS;//rel15->TBSize[0];
919
      uint16_t length_dmrs = 1;
920 921 922 923
      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;
924
      
925
      available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
926 927
      
      for (i = 0; i < available_bits; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
928
	
929 930 931 932 933 934
	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
935
	    }
936
	    errors_scrambling++;
Raymond Knopp's avatar
Raymond Knopp committed
937 938
	  }
	
939 940
      }
      for (i = 0; i < TBS; i++) {
Raymond Knopp's avatar
Raymond Knopp committed
941
	
942 943
	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
944
	
945 946 947 948
	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
949 950
	}
	
951 952 953 954 955 956
      }
      
      ////////////////////////////////////////////////////////////
      
      if (errors_scrambling > 0) {
	if (n_trials == 1)
957
	  printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial);
958 959 960 961 962 963 964
      }
      
      if (errors_bit > 0) {
	n_false_positive++;
	if (n_trials == 1)
	  printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
      }
965
      roundStats[snrRun]+=((float)round); 
966
      if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
Ahmed Hussein's avatar
Ahmed Hussein committed
967
    } // noise trials
968

969
    roundStats[snrRun]/=((float)n_trials);
970
    effRate /= n_trials;
Ahmed Hussein's avatar
Ahmed Hussein committed
971 972
    printf("*****************************************\n");
    printf("SNR %f, (false positive %f)\n", SNR,
Sakthivel Velumani's avatar
Sakthivel Velumani committed
973
           (float) n_errors / (float) n_trials);
Ahmed Hussein's avatar
Ahmed Hussein committed
974 975
    printf("*****************************************\n");
    printf("\n");
976
    dump_pdsch_stats(gNB);
Francesco Mani's avatar
Francesco Mani committed
977
    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
978
    printf("\n");
979

980
    if (print_perf==1) {
981 982 983 984 985
      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));
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 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
      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");
      */
    }
1030 1031 1032 1033 1034 1035 1036 1037

    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);
1038
      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);
1039 1040 1041 1042
      break;
    }

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

1048
    snrRun++;
1049 1050
  } // NSR

1051
  /*if (n_trials>1) {
1052 1053 1054 1055 1056 1057
    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;
    }
1058
  }*/
1059

Ahmed Hussein's avatar
Ahmed Hussein committed
1060
  for (i = 0; i < 2; i++) {
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
    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
1073 1074 1075
  free(test_input_bit);
  free(estimated_output_bit);
  
1076 1077 1078 1079 1080 1081
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1082 1083
  if (scg_fd)
    fclose(scg_fd);
1084
  return(n_errors);
Raymond Knopp's avatar
Raymond Knopp committed
1085
  
1086
}