dlsim.c 37.1 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
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"

Laurent's avatar
Laurent committed
69 70
#include <openair2/LAYER2/MAC/mac_vars.h>
#include <openair2/RRC/LTE/rrc_vars.h>
71

72 73
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
74

75 76 77
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
78
uint32_t num_threads_pusch;
79 80
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];

81
double cpuf;
82

83
int sf_ahead=4 ;
84
int sl_ahead=0;
85
uint8_t nfapi_mode = 0;
86
uint64_t downlink_frequency[MAX_NUM_CCs][4];
87 88

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

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

101 102
void
rrc_data_ind(
103
  const protocol_ctxt_t *const ctxt_pP,
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  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;
}
119

120 121 122 123 124 125 126 127
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;
}
128

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

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

144
// Dummy function to avoid linking error at compilation of nr-dlsim
145 146 147 148 149
int is_x2ap_enabled(void)
{
  return 0;
}

150
// needed for some functions
151
openair0_config_t openair0_cfg[MAX_CARDS];
152

153

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
   dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
int g_mcsIndex = -1, g_rbStart = -1, g_rbSize = -1;
void nr_dlsim_preprocessor(module_id_t module_id,
                           frame_t frame,
                           sub_frame_t slot,
                           int num_slots_per_tdd) {
  NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
  AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n");
  NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];

  /* manually set free CCE to 0 */
  const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
  sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
  uint8_t nr_of_candidates;
  find_aggregation_candidates(&sched_ctrl->aggregation_level,
                              &nr_of_candidates,
                              sched_ctrl->search_space);
  sched_ctrl->coreset = get_coreset(
      sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
  sched_ctrl->cce_index = 0;

  /* set "any" value for PUCCH (simulator evaluates PDSCH only) */
  sched_ctrl->pucch_sched_idx = 0;
  sched_ctrl->pucch_occ_idx = 0;

  sched_ctrl->rbStart = g_rbStart;
  sched_ctrl->rbSize = g_rbSize;
  sched_ctrl->mcs = g_mcsIndex;
  sched_ctrl->time_domain_allocation = 2;
  sched_ctrl->mcsTableIdx = 0;
  AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart);
  AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize);
  AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs);
  sched_ctrl->numDmrsCdmGrpsNoData = 1;
}
190 191


192 193 194
int main(int argc, char **argv)
{
  char c;
195
  int i,aa;//,l;
196
  double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
197
  uint8_t snr1set=0;
198
  float roundStats[50];
199
  float effRate;
Francesco Mani's avatar
Francesco Mani committed
200
  //float psnr;
201
  float eff_tp_check = 0.7;
202
  uint8_t snrRun;
203
  uint32_t TBS;
204 205
  int **txdata;
  double **s_re,**s_im,**r_re,**r_im;
206 207
  //double iqim = 0.0;
  //unsigned char pbch_pdu[6];
208 209 210
  //  int sync_pos, sync_pos_slot;
  //  FILE *rx_frame_file;
  FILE *output_fd = NULL;
211
  //uint8_t write_output_file=0;
212
  //int result;
213
  //int freq_offset;
214
  //  int subframe_offset;
215
  //  char fname[40], vname[40];
Ahmed Hussein's avatar
Ahmed Hussein committed
216
  int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
217
  //int n_errors2, n_alamouti;
218
  uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
219 220
  uint8_t round;
  uint8_t num_rounds = 4;
221 222

  channel_desc_t *gNB2UE;
223 224 225
  //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0;
  //uint8_t extended_prefix_flag=0;
  //int8_t interf1=-21,interf2=-21;
226 227

  FILE *input_fd=NULL,*pbch_file_fd=NULL;
228
  //char input_val_str[50],input_val_str2[50];
229

230
  //uint8_t frame_mod4,num_pdcch_symbols = 0;
231 232 233

  SCM_t channel_model=AWGN;//Rayleigh1_anticorr;

Laurent's avatar
Laurent committed
234
  NB_UE_INST = 1;
235 236
  //double pbch_sinr;
  //int pbch_tx_ant;
Ahmed Hussein's avatar
Ahmed Hussein committed
237
  int N_RB_DL=106,mu=1;
238

239
  //unsigned char frame_type = 0;
240

241
  int frame=1,slot=1;
242
  int frame_length_complex_samples;
243
  //int frame_length_complex_samples_no_prefix;
244 245 246 247 248
  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;
249
  int cyclic_prefix_type = NFAPI_CP_NORMAL;
250
  int run_initial_sync=0;
251 252
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Raymond Knopp's avatar
Raymond Knopp committed
253
  int loglvl=OAILOG_INFO;
254

255
  //float target_error_rate = 0.01;
256
  int css_flag=0;
257 258 259

  cpuf = get_cpu_freq_GHz();

260
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
yilmazt's avatar
yilmazt committed
261
    exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
262 263 264 265
  }

  randominit(0);

266
  int print_perf             = 0;
267

268 269
  FILE *scg_fd=NULL;
  
Sakthivel Velumani's avatar
Sakthivel Velumani committed
270
  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) {
271
    switch (c) {
272 273
    case 'f':
      scg_fd = fopen(optarg,"r");
274

275
      if (scg_fd==NULL) {
276 277 278
        printf("Error opening %s\n",optarg);
        exit(-1);
      }
279
      break;
280

281
    /*case 'd':
282
      frame_type = 1;
283
      break;*/
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315

    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:
316
        printf("Unsupported channel model!\n");
317 318 319 320 321
        exit(-1);
      }

      break;

322
    /*case 'i':
323 324 325 326 327
      interf1=atoi(optarg);
      break;

    case 'j':
      interf2=atoi(optarg);
328
      break;*/
329 330 331 332 333 334 335

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

    case 's':
      snr0 = atof(optarg);
336
      printf("Setting SNR0 to %f\n",snr0);
337 338 339 340 341
      break;

    case 'S':
      snr1 = atof(optarg);
      snr1set=1;
342
      printf("Setting SNR1 to %f\n",snr1);
343 344 345 346 347 348 349
      break;

      /*
      case 't':
      Td= atof(optarg);
      break;
      */
350
    /*case 'p':
351
      extended_prefix_flag=1;
352
      break;*/
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

      /*
      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)) {
369
        printf("Unsupported transmission mode %d\n",transmission_mode);
370 371 372 373 374 375 376 377 378
        exit(-1);
      }

      break;

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

      if ((n_tx==0) || (n_tx>2)) {
379
        printf("Unsupported number of tx antennas %d\n",n_tx);
380 381 382 383 384 385 386 387 388
        exit(-1);
      }

      break;

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

      if ((n_rx==0) || (n_rx>2)) {
389
        printf("Unsupported number of rx antennas %d\n",n_rx);
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
        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':
410 411
      print_perf=1;
      opp_enabled=1;
412 413 414 415
      break;
      
    case 'I':
      run_initial_sync=1;
416
      //target_error_rate=0.1;
417
      slot = 0;
418 419 420 421 422 423
      break;

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

424

425 426 427
    case 'E':
	css_flag=1;
	break;
428

429

430
    case 'a':
431
      g_rbStart = atoi(optarg);
432 433 434
      break;

    case 'b':
435
      g_rbSize = atoi(optarg);
436 437 438
      break;

    case 'e':
439
      g_mcsIndex = atoi(optarg);
440 441
      break;

442 443 444
    case 'm':
      mu = atoi(optarg);
      break;
445

446 447 448 449
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
450 451 452 453
    case 'w':
      output_fd = fopen("txdata.dat", "w+");
      break;

454 455 456 457 458
    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");
459 460
      //printf("-p Use extended prefix mode\n");
      //printf("-d Use TDD\n");
461 462 463 464 465
      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");
466
      printf("-y Number of TX antennas used in gNB\n");
467
      printf("-z Number of RX antennas used in UE\n");
468 469
      //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");
470 471 472
      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");
473
      //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
474
      printf("-f raw file containing RRC configuration (generated by gNB)\n");
475
      printf("-F Input filename (.txt format) for RX conformance testing\n");
476
      printf("-E used CSS scheduler\n");
477
      printf("-o CORESET offset\n");
478 479
      printf("-a Start PRB for PDSCH\n");
      printf("-b Number of PRB for PDSCH\n");
480 481
      printf("-c Start symbol for PDSCH (fixed for now)\n");
      printf("-j Number of symbols for PDSCH (fixed for now)\n");
482
      printf("-e MSC index\n");
483
      printf("-t Acceptable effective throughput (in percentage)\n");
484
      printf("-P Print DLSCH performances\n");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
485
      printf("-w Write txdata to binary file (one frame)\n");
486 487 488 489
      exit (-1);
      break;
    }
  }
Raymond Knopp's avatar
Raymond Knopp committed
490
  
491 492 493 494
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

495 496
  get_softmodem_params()->phy_test = 1;
  
497 498 499 500
  if (snr1set==0)
    snr1 = snr0+10;


501 502 503
  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
504

505
  gNB = RC.gNB[0];
506 507 508 509 510 511
  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
512
  RC.nb_nr_macrlc_inst = 1;
cig's avatar
cig committed
513 514 515
  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
516 517
  mac_top_init_gNB();
  gNB_mac = RC.nrmac[0];
518
  gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
Raymond Knopp's avatar
Raymond Knopp committed
519
  gNB_RRC_INST rrc;
Raymond Knopp's avatar
Raymond Knopp committed
520
  memset((void*)&rrc,0,sizeof(rrc));
521

522
  /*
Raymond Knopp's avatar
Raymond Knopp committed
523
  // read in SCGroupConfig
Raymond Knopp's avatar
Raymond Knopp committed
524
  AssertFatal(scg_fd != NULL,"no reconfig.raw file\n");
Raymond Knopp's avatar
Raymond Knopp committed
525 526 527 528
  char buffer[1024];
  int msg_len=fread(buffer,1,1024,scg_fd);
  NR_RRCReconfiguration_t *NR_RRCReconfiguration;

Raymond Knopp's avatar
Raymond Knopp committed
529
  printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len);
Raymond Knopp's avatar
Raymond Knopp committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543
  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
544 545
  AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n");

Raymond Knopp's avatar
Raymond Knopp committed
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
  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);
  }      
  
561 562
  NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
  */
Raymond Knopp's avatar
Raymond Knopp committed
563

564 565 566 567 568 569 570 571 572

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

Francesco Mani's avatar
Francesco Mani committed
573 574
  fix_scc(scc,ssb_bitmap);

575 576 577 578 579 580 581 582
  fill_default_secondaryCellGroup(scc,
				  secondaryCellGroup,
				  0,
				  1,
				  n_tx,
				  0);

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

Raymond Knopp's avatar
Raymond Knopp committed
584 585
  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
586
  // common configuration
587
  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
588
  // UE dedicated configuration
589
  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
590
  phy_init_nr_gNB(gNB,0,0);
591
  N_RB_DL = gNB->frame_parms.N_RB_DL;
Raymond Knopp's avatar
Raymond Knopp committed
592
  // stub to configure frame_parms
Raymond Knopp's avatar
Raymond Knopp committed
593
  //  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
Raymond Knopp's avatar
Raymond Knopp committed
594 595
  // call MAC to configure common parameters

596 597 598 599 600 601
  /* rrc_mac_config_req_gNB() has created one user, so set the scheduling
   * parameters from command line in global variables that will be picked up by
   * scheduling preprocessor */
  if (g_mcsIndex < 0) g_mcsIndex = 9;
  if (g_rbStart < 0) g_rbStart=0;
  if (g_rbSize < 0) g_rbSize = N_RB_DL - g_rbStart;
Raymond Knopp's avatar
Raymond Knopp committed
602

603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
  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;
  }
621 622 623 624
  else if (mu == 3 && N_RB_DL == 66) {
    fs = 122.88e6;
    bw = 100e6;
  }
625 626 627 628
  else if (mu == 3 && N_RB_DL == 32) {
    fs = 61.44e6;
    bw = 50e6;
  }
629 630 631 632 633
  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,
634 635
 				fs,
				bw,
636
				30e-9,
637 638 639 640 641
                                0,
                                0,
                                0);

  if (gNB2UE==NULL) {
642
    printf("Problem generating channel model. Exiting.\n");
643 644 645 646
    exit(-1);
  }

  frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
647
  //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

  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));
669
    bzero(txdata[i],frame_length_complex_samples*sizeof(int));
670 671 672 673 674 675 676 677 678 679
  
  }

  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
680
  memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
681 682 683 684
  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
685

686
  if (run_initial_sync==1)  UE->is_synchronized = 0;
687
  else                      {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
688 689
                      
  UE->perfect_ce = 0;
690
  for (i=0;i<10;i++) UE->current_thread_id[i] = 0;
691 692 693 694 695 696 697

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

698 699
  init_nr_ue_transport(UE,0);

700
  nr_gold_pbch(UE);
701
  nr_gold_pdcch(UE,0,2);
702

703
  nr_l2_init_ue(NULL);
704
  UE_mac = get_mac_inst(0);
Guy De Souza's avatar
Guy De Souza committed
705
  
706 707 708
  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;
709
  UE->if_inst->dl_indication = nr_ue_dl_indication;
710 711 712
  UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
  

713
  UE_mac->if_module = nr_ue_if_module_init(0);
Ahmed Hussein's avatar
Ahmed Hussein committed
714
  
715
  unsigned int available_bits=0;
Ahmed Hussein's avatar
Ahmed Hussein committed
716 717 718 719 720
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
  unsigned int errors_bit    = 0;
  uint32_t errors_scrambling = 0;

721

Ahmed Hussein's avatar
Ahmed Hussein committed
722 723
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
724 725
  
  // generate signal
726 727 728
  AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
  gNB->pbch_configured = 1;
  gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
Raymond Knopp's avatar
Raymond Knopp committed
729

730
  //Configure UE
731 732
  rrc.carrier.MIB = (uint8_t*) malloc(4);
  rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
733

734
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
735

736 737 738 739 740 741 742 743

  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;
744
  
745 746 747 748 749 750 751
  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;
752
  
Francesco Mani's avatar
Francesco Mani committed
753

754
  nr_ue_phy_config_request(&UE_mac->phy_config);
755
  NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
Francesco Mani's avatar
Francesco Mani committed
756
  //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
757
  snrRun = 0;
758

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

761 762 763 764 765 766 767 768 769 770 771 772 773
    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);  

774 775
    clear_pdsch_stats(gNB);

776
    n_errors = 0;
777
    effRate = 0;
778 779
    //n_errors2 = 0;
    //n_alamouti = 0;
780
    errors_scrambling=0;
781
    n_false_positive = 0;
782 783
    if (n_trials== 1) num_rounds = 1;

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

786
      errors_bit = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
787
      //multipath channel
788
      //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
789

790 791 792 793 794 795 796
      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;
797 798 799

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

800
      int harq_pid = slot;
801 802 803
      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
804
      nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
805
      
806 807
      UE_harq_process->harq_ack.ack = 0;
      round = 0;
808 809
      UE_harq_process->round = round;
      UE_harq_process->first_tx = 1;
810 811 812 813
        
      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));
814
        clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
815

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

818

819 820
        UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
        UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid;
821
        gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
822
        for (int i=0; i<MAX_NUM_CORESET; i++)
823
          gNB_mac->UE_info.num_pdcch_cand[0][i] = 0;
824
      
825 826 827 828 829 830 831 832
        if (css_flag == 0) {
          const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
          const NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
          const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
          nr_schedule_ue_spec(0, frame, slot, num_slots_per_tdd);
        } else {
          nr_schedule_css_dlsch_phytest(0,frame,slot);
        }
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
        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) {
851
          LOG_M("txsigF0.m","txsF0", &gNB->common_vars.txdataF[0][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
852
          if (gNB->frame_parms.nb_antennas_tx>1)
853
          LOG_M("txsigF1.m","txsF1", &gNB->common_vars.txdataF[1][txdataF_offset],frame_parms->samples_per_slot_wCP,1,1);
854 855
        }
        int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
856
        if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
857 858 859 860
        
        //TODO: loop over slots
        for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
    
861 862 863 864 865 866 867
          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);
868
          } else {
869 870 871 872 873
            nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
                                 &txdata[aa][tx_offset],
                                 14,
                                 frame_parms);
          }
874 875 876
        }
       
        if (n_trials==1) {
877
          LOG_M("txsig0.m","txs0", &txdata[0][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
878
          if (gNB->frame_parms.nb_antennas_tx>1)
879
            LOG_M("txsig1.m","txs1", &txdata[1][tx_offset],frame_parms->get_samples_slot_timestamp(slot,frame_parms,0),1,1);
880
        }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
881 882
        if (output_fd) {
          printf("writing txdata to binary file\n");
883
          fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
884
        }
885

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

989
    roundStats[snrRun]/=((float)n_trials);
990
    effRate /= n_trials;
Ahmed Hussein's avatar
Ahmed Hussein committed
991 992
    printf("*****************************************\n");
    printf("SNR %f, (false positive %f)\n", SNR,
Sakthivel Velumani's avatar
Sakthivel Velumani committed
993
           (float) n_errors / (float) n_trials);
Ahmed Hussein's avatar
Ahmed Hussein committed
994 995
    printf("*****************************************\n");
    printf("\n");
996
    dump_pdsch_stats(gNB);
Francesco Mani's avatar
Francesco Mani committed
997
    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
998
    printf("\n");
999

1000
    if (print_perf==1) {
1001
      printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
1002
	     1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex,
1003 1004 1005
	     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));
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
      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");
      */
    }
1050 1051 1052 1053 1054 1055 1056 1057

    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);
1058
      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);
1059 1060 1061 1062
      break;
    }

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

1068
    snrRun++;
1069 1070
  } // NSR

1071
  /*if (n_trials>1) {
1072 1073 1074 1075 1076 1077
    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;
    }
1078
  }*/
1079

Ahmed Hussein's avatar
Ahmed Hussein committed
1080
  for (i = 0; i < 2; i++) {
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
    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
1093 1094 1095
  free(test_input_bit);
  free(estimated_output_bit);
  
1096 1097 1098 1099 1100 1101
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1102 1103
  if (scg_fd)
    fclose(scg_fd);
1104
  return(n_errors);
Raymond Knopp's avatar
Raymond Knopp committed
1105
  
1106
}