ulsim.c 41.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1  (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
*      contact@openairinterface.org
*/

#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
28
#include "common/ran_context.h"
29 30
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
31
#include "PHY/defs_gNB.h"
32 33
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
34
#include "PHY/phy_vars_nr_ue.h"
35
#include "PHY/types.h"
36 37
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
38 39 40
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
41
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
42 43
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
44 45
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
46
#include "PHY/TOOLS/tools_defs.h"
Francesco Mani's avatar
Francesco Mani committed
47
#include "SCHED_NR/fapi_nr_l1.h"
48
#include "SCHED_NR/sched_nr.h"
49
#include "SCHED_NR_UE/defs.h"
50
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
51 52 53
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
Francesco Mani's avatar
Francesco Mani committed
54
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
Raymond Knopp's avatar
Raymond Knopp committed
55
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
56
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
57
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
Sakthivel Velumani's avatar
Sakthivel Velumani committed
58
#include "common/utils/threadPool/thread-pool.h"
59

60 61
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
62

Laurent's avatar
Laurent committed
63 64 65
#include <openair2/LAYER2/MAC/mac_vars.h>
#include <openair2/RRC/LTE/rrc_vars.h>

66
//#define DEBUG_ULSIM
67

68 69 70
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
rlc_info_t Rlc_info_um,Rlc_info_am_config;

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
int sf_ahead=4 ;
77
int sl_ahead=0;
78
double cpuf;
79
uint8_t nfapi_mode = 0;
80 81
uint64_t downlink_frequency[MAX_NUM_CCs][4];

82

83 84
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) { return 0; }
85 86 87 88 89 90 91 92 93
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;}
94 95 96

void
rrc_data_ind(
97
  const protocol_ctxt_t *const ctxt_pP,
98 99 100 101 102 103
  const rb_id_t                Srb_id,
  const sdu_size_t             sdu_sizeP,
  const uint8_t   *const       buffer_pP
)
{
}
104

105 106 107 108 109 110 111 112
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;
}
113

114 115 116 117 118 119 120 121
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;
}
122

123
// Dummy function to avoid linking error at compilation of nr-ulsim
124 125 126 127 128
int is_x2ap_enabled(void)
{
  return 0;
}

129 130 131
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
132
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; 
133

134 135 136 137 138
channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX];
double s_re0[122880],s_im0[122880],r_re0[122880],r_im0[122880];
double s_re1[122880],s_im1[122880],r_re1[122880],r_im1[122880];
double r_re2[122880],r_im2[122880];
double r_re3[122880],r_im3[122880];
139

140 141
int main(int argc, char **argv)
{
142
  char c;
laurent's avatar
laurent committed
143
  int i;
144 145
  double SNR, snr0 = -2.0, snr1 = 2.0;
  double sigma, sigma_dB;
146
  double snr_step = .2;
147
  uint8_t snr1set = 0;
Raymond Knopp's avatar
Raymond Knopp committed
148
  int slot = 8, frame = 1;
149
  FILE *output_fd = NULL;
150 151 152 153
  double *s_re[2]= {s_re0,s_re1};
  double *s_im[2]= {s_im0,s_im1};
  double *r_re[4]= {r_re0,r_re1,r_re2,r_re3};
  double *r_im[4]= {r_im0,r_im1,r_im2,r_im3};
154
  //uint8_t write_output_file = 0;
155
  int trial, n_trials = 1, n_false_positive = 0, delay = 0;
156
  double maxDoppler = 0.0;
157
  uint8_t n_tx = 1, n_rx = 1;
158
  //uint8_t transmission_mode = 1;
159
  //uint16_t Nid_cell = 0;
160
  channel_desc_t *UE2gNB;
161 162
  uint8_t extended_prefix_flag = 0;
  //int8_t interf1 = -21, interf2 = -21;
163
  FILE *input_fd = NULL;
164
  SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
165
  uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
166 167
  double tx_gain=1.0;
  double N0=30;
Laurent's avatar
Laurent committed
168
  NB_UE_INST = 1;
169

170 171
  //unsigned char frame_type = 0;
  NR_DL_FRAME_PARMS *frame_parms;
172
  int loglvl = OAILOG_INFO;
173
  //uint64_t SSB_positions=0x01;
174
  uint16_t nb_symb_sch = 12;
175
  int start_symbol = 0;
176
  uint16_t nb_rb = 50;
177
  int Imcs = 9;
178
  uint8_t precod_nbr_layers = 1;
179
  int gNB_id = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
180
  int ap;
Khalid Ahmed's avatar
Khalid Ahmed committed
181
  int tx_offset;
Khalid Ahmed's avatar
Khalid Ahmed committed
182 183
  double txlev_float;
  int32_t txlev;
Ahmed Hussein's avatar
Ahmed Hussein committed
184
  int start_rb = 0;
185
  int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
186
  float target_error_rate = 0.01;
187
  int print_perf = 0;
188
  cpuf = get_cpu_freq_GHz();
189
  int msg3_flag = 0;
190
  int rv_index = 0;
191 192
  float roundStats[50];
  float effRate; 
193
  //float eff_tp_check = 0.7;
194
  uint8_t snrRun;
195

196
  int enable_ptrs = 0;
197 198 199 200 201
  int modify_dmrs = 0;
  /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
  int ptrs_arg[2] = {-1,-1};// Invalid values
  /* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
  int dmrs_arg[2] = {-1,-1};// Invalid values
202

203
  UE_nr_rxtx_proc_t UE_proc;
204
  FILE *scg_fd=NULL;
205
  int file_offset = 0;
206

207
  double DS_TDL = .03;
208 209
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Francesco Mani's avatar
Francesco Mani committed
210
  int ibwps=24;
211
  int ibwp_rboffset=41;
212
  int params_from_file = 0;
yilmazt's avatar
yilmazt committed
213
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
yilmazt's avatar
yilmazt committed
214
    exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
215 216 217 218 219
  }

  //logInit();
  randominit(0);

220
  while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
221
    printf("handling optarg %c\n",c);
222
    switch (c) {
223 224 225 226 227

      /*case 'd':
        frame_type = 1;
        break;*/

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
    case 'a':
      start_symbol = atoi(optarg);
      AssertFatal(start_symbol >= 0 && start_symbol < 13,"start_symbol %d is not in 0..12\n",start_symbol);
      break;

    case 'b':
      nb_symb_sch = atoi(optarg);
      AssertFatal(nb_symb_sch > 0 && nb_symb_sch < 15,"start_symbol %d is not in 1..14\n",nb_symb_sch);
      break;
    case 'c':
      n_rnti = atoi(optarg);
      AssertFatal(n_rnti > 0 && n_rnti<=65535,"Illegal n_rnti %x\n",n_rnti);
      break;

    case 'd':
      delay = atoi(optarg);
      break;
      
    case 'e':
      msg3_flag = 1;
      break;
      
    case 'f':
      scg_fd = fopen(optarg, "r");
      
      if (scg_fd == NULL) {
	printf("Error opening %s\n", optarg);
	exit(-1);
      }
257

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
      break;
      
    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;
289 290 291

      case 'H':
        channel_model = TDL_C;
292
	DS_TDL = .030; // 30 ns
293 294 295 296
	break;
  
      case 'I':
	channel_model = TDL_C;
297
	DS_TDL = .3;  // 300ns
298 299 300 301
        break;
     
      case 'J':
	channel_model=TDL_D;
302
	DS_TDL = .03;
303 304
	break;

305 306 307 308 309 310 311
      default:
	printf("Unsupported channel model!\n");
	exit(-1);
      }
      
      break;
      
312 313 314
      /*case 'i':
        interf1 = atoi(optarg);
        break;
315 316
	
	case 'j':
317 318 319
        interf2 = atoi(optarg);
        break;*/

320 321 322 323
    case 'k':
      printf("Setting threequarter_fs_flag\n");
      openair0_cfg[0].threequarter_fs= 1;
      break;
324

325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
    case 'l':
      nb_symb_sch = atoi(optarg);
      break;
      
    case 'm':
      Imcs = atoi(optarg);
      break;
      
    case 'n':
      n_trials = atoi(optarg);
      break;
      
    case 'p':
      extended_prefix_flag = 1;
      break;
      
    case 'r':
      nb_rb = atoi(optarg);
      break;
      
    case 's':
      snr0 = atof(optarg);
      printf("Setting SNR0 to %f\n", snr0);
      break;
349 350

/*
351 352 353
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;
354
*/
355
      /*
356 357 358 359 360 361 362 363 364
	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;
      */
      
365 366 367
      /*case 'x':
        transmission_mode = atoi(optarg);
        break;*/
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
      
    case 'y':
      n_tx = atoi(optarg);
      
      if ((n_tx == 0) || (n_tx > 2)) {
	printf("Unsupported number of tx antennas %d\n", n_tx);
	exit(-1);
      }
      
      break;
      
    case 'z':
      n_rx = atoi(optarg);
      
      if ((n_rx == 0) || (n_rx > 2)) {
	printf("Unsupported number of rx antennas %d\n", n_rx);
	exit(-1);
      }
      
      break;
      
    case 'F':
      input_fd = fopen(optarg, "r");
      
      if (input_fd == NULL) {
	printf("Problem with filename %s\n", optarg);
	exit(-1);
      }
      
      break;
398 399 400 401 402 403 404 405 406

    case 'G':
      file_offset = atoi(optarg);
      break;

    case 'H':
      slot = atoi(optarg);
      break;

407
    case 'M':
Francesco Mani's avatar
Francesco Mani committed
408
     // SSB_positions = atoi(optarg);
409 410 411
      break;
      
    case 'N':
Francesco Mani's avatar
Francesco Mani committed
412
     // Nid_cell = atoi(optarg);
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
      break;
      
    case 'R':
      N_RB_DL = atoi(optarg);
      N_RB_UL = N_RB_DL;
      break;
      
    case 'S':
      snr1 = atof(optarg);
      snr1set = 1;
      printf("Setting SNR1 to %f\n", snr1);
      break;
      
    case 'P':
      print_perf=1;
      opp_enabled=1;
      break;
      
    case 'L':
      loglvl = atoi(optarg);
      break;
434 435 436

   case 'T':
      enable_ptrs=1;
437 438 439 440 441 442 443 444 445
      for(i=0; i < atoi(optarg); i++){
        ptrs_arg[i] = atoi(argv[optind++]);
      }
      break;

    case 'U':
      modify_dmrs = 1;
      for(i=0; i < atoi(optarg); i++){
        dmrs_arg[i] = atoi(argv[optind++]);
446 447
      }
      break;
448

449 450 451 452
    case 'Q':
      params_from_file = 1;
      break;

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
    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("-d Use TDD\n");
      printf("-d Introduce delay in terms of number of samples\n");
      printf("-f Number of frames to simulate\n");
      printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
      printf("-h This message\n");
      //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
      //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
      printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
      printf("-m MCS value\n");
      printf("-n Number of trials to simulate\n");
      printf("-p Use extended prefix mode\n");
      printf("-t Delay spread for multipath channel\n");
      //printf("-x Transmission mode (1,2,6 for the moment)\n");
      printf("-y Number of TX antennas used in eNB\n");
      printf("-z Number of RX antennas used in UE\n");
      printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
      //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
      printf("-F Input filename (.txt format) for RX conformance testing\n");
474
      printf("-G Offset of samples to read from file (0 default)\n");
475 476 477 478
      printf("-M Multiple SSB positions in burst\n");
      printf("-N Nid_cell\n");
      printf("-O oversampling factor (1,2,4,8,16)\n");
      printf("-R N_RB_DL\n");
479
      printf("-t Acceptable effective throughput (in percentage)\n");
480 481
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-P Print ULSCH performances\n");
482
      printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
483
      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
484
      printf("-Q If -F used, read parameters from file\n");
485 486
      exit(-1);
      break;
487

488 489
    }
  }
490
  
491 492 493 494
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

495
  get_softmodem_params()->phy_test = 1;
496
  get_softmodem_params()->do_ra = 0;
Francesco Mani's avatar
Francesco Mani committed
497 498
  get_softmodem_params()->usim_test = 1;

499

500 501
  if (snr1set == 0)
    snr1 = snr0 + 10;
502 503 504
  double sampling_frequency;
  double bandwidth;

505 506
  if (N_RB_UL >= 217) sampling_frequency = 122.88;
  else if (N_RB_UL >= 106) sampling_frequency = 61.44;
507
  else { printf("Need at least 106 PRBs\b"); exit(-1); }
508 509 510
  if (N_RB_UL == 273) bandwidth = 100;
  else if (N_RB_UL == 217) bandwidth = 80;
  else if (N_RB_UL == 106) bandwidth = 40;
511 512
  else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
			   
513
  if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
514 515 516 517

  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
                                sampling_frequency,
                                bandwidth,
518
				DS_TDL,
519 520
                                0, 0, 0);

521
  if (UE2gNB == NULL) {
522
    printf("Problem generating channel model. Exiting.\n");
523 524 525
    exit(-1);
  }

526 527
  UE2gNB->max_Doppler = maxDoppler;

528
  RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
529
  RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
530
  gNB = RC.gNB[0];
Sakthivel Velumani's avatar
Sakthivel Velumani committed
531 532
  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
Sakthi's avatar
Sakthi committed
533 534
  char tp_param[] = "n";
  initTpool(tp_param, gNB->threadPool, true);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
535
  initNotifiedFIFO(gNB->respDecode);
536
  //gNB_config = &gNB->gNB_config;
537

538
  //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
Francesco Mani's avatar
Francesco Mani committed
539 540 541 542
  gNB->UL_INFO.rx_ind.pdu_list = (nfapi_nr_rx_data_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_rx_data_pdu_t));
  gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t));
  gNB->UL_INFO.rx_ind.number_of_pdus = 0;
  gNB->UL_INFO.crc_ind.number_crcs = 0;
543
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
544 545


546 547 548 549 550 551
  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_UL;
  frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;

552

553 554 555 556 557
  RC.nb_nr_macrlc_inst = 1;
  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;
  mac_top_init_gNB();
laurent's avatar
laurent committed
558
  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
559 560 561
  gNB_RRC_INST rrc;
  memset((void*)&rrc,0,sizeof(rrc));

562 563 564 565 566 567 568 569
  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
570 571
  fix_scc(scc,ssb_bitmap);

572 573 574 575 576 577
  fill_default_secondaryCellGroup(scc,
				  secondaryCellGroup,
				  0,
				  1,
				  n_tx,
				  0);
578

579
  // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
580 581

  AssertFatal((gNB->if_inst         = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
582

583 584
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
  // common configuration
585
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
586
  // UE dedicated configuration
587
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
588 589
  phy_init_nr_gNB(gNB,0,0);
  N_RB_DL = gNB->frame_parms.N_RB_DL;
590

591 592 593

  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];

594 595 596
  //crcTableInit();

  //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
597 598 599 600


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
601 602 603 604
  memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
  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;
605 606 607 608 609 610 611 612 613
  memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));

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

  //nr_init_frame_parms_ue(&UE->frame_parms);
614 615 616
  init_nr_ue_transport(UE, 0);

  /*
laurent's avatar
laurent committed
617
  for (int sf = 0; sf < 2; sf++) {
618 619 620 621 622 623 624 625 626 627
    for (i = 0; i < 2; i++) {

        UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0);

        if (!UE->ulsch[sf][0][i]) {
          printf("Can't get ue ulsch structures\n");
          exit(-1);
        }
    }
  }
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
  */
  
  nr_l2_init_ue(NULL);
  NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
  
  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;
  UE->if_inst->dl_indication = nr_ue_dl_indication;
  UE->if_inst->ul_indication = nr_ue_ul_indication;
  
  UE_mac->if_module = nr_ue_if_module_init(0);

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

645
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
646 647 648

  nr_ue_phy_config_request(&UE_mac->phy_config);

649

650
  unsigned char harq_pid = 0;
651

652 653
  NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
  //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
654 655 656 657 658
  nfapi_nr_ul_tti_request_t     *UL_tti_req  = malloc(sizeof(*UL_tti_req));
  NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
  memset((void*)Sched_INFO,0,sizeof(*Sched_INFO));
  Sched_INFO->UL_tti_req=UL_tti_req;

659 660
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

661
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
662

663 664
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
665
  uint32_t errors_decoding   = 0;
666
  
667

668 669
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
670

Ahmed Hussein's avatar
Ahmed Hussein committed
671 672
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
673
  fapi_nr_tx_request_t tx_req;
674
  
675 676 677 678 679
  uint8_t ptrs_mcs1 = 2;
  uint8_t ptrs_mcs2 = 4;
  uint8_t ptrs_mcs3 = 10;
  uint16_t n_rb0 = 25;
  uint16_t n_rb1 = 75;
680
  uint8_t mcs_table = 0;
681
  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
682
  uint8_t max_rounds = 4;
683
  uint8_t crc_status = 0;
684

685 686 687 688 689 690 691
  unsigned char mod_order = nr_get_Qm_ul(Imcs, 0);
  uint16_t      code_rate = nr_get_code_rate_ul(Imcs, 0);

  uint8_t mapping_type = typeB; // Default Values
  pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values
  pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos0; // Default Values

692 693 694 695 696 697
  /* validate parameters othwerwise default values are used */
  /* -U flag can be used to set DMRS parameters*/
  if(modify_dmrs)
  {
    if(dmrs_arg[0] == 0)
    {
698
      mapping_type = typeA;
699 700 701
    }
    else if (dmrs_arg[0] == 1)
    {
702
      mapping_type = typeB;
703 704 705 706 707 708
    }
    /* Additional DMRS positions */
    if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
    {
      add_pos = dmrs_arg[1];
    }
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
    printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
  }

  uint8_t  length_dmrs         = pusch_len1;
  uint16_t l_prime_mask        = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
  uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
  uint8_t  nb_re_dmrs          = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
  unsigned int available_bits  = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
  unsigned int TBS             = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);

  uint8_t ulsch_input_buffer[TBS/8];

  ulsch_input_buffer[0] = 0x31;
  for (i = 1; i < TBS/8; i++) {
    ulsch_input_buffer[i] = (unsigned char) rand();
724 725
  }

726
  uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
727
  uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
728 729
  int     ptrs_symbols      = 0; // to calculate total PTRS RE's in a slot

730 731
  double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);

732 733 734 735 736 737 738 739 740 741 742 743 744
  /* -T option enable PTRS */
  if(enable_ptrs)
  {
    /* validate parameters othwerwise default values are used */
    if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 )
    {
      ptrs_time_density = ptrs_arg[0];
    }
    if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 )
    {
      ptrs_freq_density = ptrs_arg[1];
    }
    pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
745
    printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
746
  }
747

748 749
  if (input_fd != NULL) max_rounds=1;

750
  if(1<<ptrs_time_density >= nb_symb_sch)
751
    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
752

753
  printf("\n");
754

Sakthivel Velumani's avatar
Sakthivel Velumani committed
755
  //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
756
  snrRun = 0;
757
  int n_errs = 0;
758
  int read_errors=0;
759

760
  int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
761 762 763 764 765 766 767
  int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);

  if (input_fd != NULL)	{
    AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
    // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
    AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
  
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
    if (params_from_file) {
      fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
      read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
      printf("rnti %x\n",n_rnti);
      read_errors+=fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
      printf("nb_rb %d\n",nb_rb);
      int16_t dummy;
      read_errors+=fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
      //fread((void*)&dummy,sizeof(int16_t),1,input_fd);
      printf("rb_start %d\n",start_rb);
      read_errors+=fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
      //fread((void*)&dummy,sizeof(int16_t),1,input_fd);
      printf("nb_symb_sch %d\n",nb_symb_sch);
      read_errors+=fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
      printf("start_symbol %d\n",start_symbol);
      read_errors+=fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
      printf("mcs %d\n",Imcs);
      read_errors+=fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
      printf("rv_index %d\n",rv_index);
      //    fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
      read_errors+=fread((void*)&dummy,sizeof(int16_t),1,input_fd);
      printf("harq_pid %d\n",harq_pid);
    }
    fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
    read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
    sizeof(int16_t),
    slot_length<<1,
    input_fd);
    if (read_errors==0) exit(1);
797
    for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
798 799 800
           slot_offset,
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
801 802
  }
  
803
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
804
    varArray_t *table_rx=initVarArray(1000,sizeof(double));
805 806 807
    int error_flag = 0;
    n_false_positive = 0;
    effRate = 0;
808 809 810
    int n_errors[4] = {0,0,0,0};;
    int round_trials[4]={0,0,0,0};
    uint32_t errors_scrambling[4] = {0,0,0,0};
Sakthivel Velumani's avatar
fixes  
Sakthivel Velumani committed
811 812 813 814 815 816 817 818 819 820 821
    reset_meas(&gNB->phy_proc_rx);
    reset_meas(&gNB->rx_pusch_stats);
    reset_meas(&gNB->ulsch_decoding_stats);
    reset_meas(&gNB->ulsch_deinterleaving_stats);
    reset_meas(&gNB->ulsch_rate_unmatching_stats);
    reset_meas(&gNB->ulsch_ldpc_decoding_stats);
    reset_meas(&gNB->ulsch_unscrambling_stats);
    reset_meas(&gNB->ulsch_channel_estimation_stats);
    reset_meas(&gNB->ulsch_llr_stats);
    reset_meas(&gNB->ulsch_channel_compensation_stats);
    reset_meas(&gNB->ulsch_rbs_extraction_stats);
822

Raymond Knopp's avatar
Raymond Knopp committed
823
    clear_pusch_stats(gNB);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
824 825 826
    for (trial = 0; trial < n_trials; trial++) {
    uint8_t round = 0;

827 828
    crc_status = 1;
    errors_decoding    = 0;
829
    memset((void*)roundStats,0,50*sizeof(roundStats[0]));
830
    while (round<max_rounds && crc_status) {
831
      round_trials[round]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
832 833
      ulsch_ue[0]->harq_processes[harq_pid]->round = round;
      gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
834
      rv_index = nr_rv_round_map[round];
835

836 837 838
      UE_proc.nr_tti_tx = slot;
      UE_proc.frame_tx = frame;

839 840
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
841 842 843 844
      UL_tti_req->n_pdus = 1;
      UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
      UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
      memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
845
      
846 847
      int abwp_size  = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
      int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
Francesco Mani's avatar
Francesco Mani committed
848
      int ibwp_size  = ibwps;
849 850 851 852 853 854 855
      int ibwp_start = ibwp_rboffset;
      if (msg3_flag == 1) {
	if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
	  pusch_pdu->bwp_start = abwp_start;
	else
	  pusch_pdu->bwp_start = ibwp_start;
	pusch_pdu->bwp_size = ibwp_size;
856
	start_rb = (ibwp_start - abwp_start);
857 858 859 860 861 862 863 864
	printf("msg3: ibwp_size %d, abwp_size %d, ibwp_start %d, abwp_start %d\n",
	       ibwp_size,abwp_size,ibwp_start,abwp_start);
      }
      else {
	pusch_pdu->bwp_start = abwp_start;
	pusch_pdu->bwp_size = abwp_size;
      }

865
      pusch_pdu->pusch_data.tb_size = TBS/8;
866
      pusch_pdu->pdu_bit_map = pdu_bit_map;
867 868
      pusch_pdu->rnti = n_rnti;
      pusch_pdu->mcs_index = Imcs;
869
      pusch_pdu->mcs_table = mcs_table;
870 871
      pusch_pdu->target_code_rate = code_rate;
      pusch_pdu->qam_mod_order = mod_order;
872
      pusch_pdu->transform_precoding = 1;
873
      pusch_pdu->data_scrambling_id = *scc->physCellId;
874
      pusch_pdu->nrOfLayers = 1;
875
      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
876
      pusch_pdu->dmrs_config_type = dmrs_config_type;
877
      pusch_pdu->ul_dmrs_scrambling_id =  *scc->physCellId;
878
      pusch_pdu->scid = 0;
879
      pusch_pdu->dmrs_ports = 1;
880
      pusch_pdu->num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
881 882 883 884 885 886 887 888
      pusch_pdu->resource_alloc = 1; 
      pusch_pdu->rb_start = start_rb;
      pusch_pdu->rb_size = nb_rb;
      pusch_pdu->vrb_to_prb_mapping = 0;
      pusch_pdu->frequency_hopping = 0;
      pusch_pdu->uplink_frequency_shift_7p5khz = 0;
      pusch_pdu->start_symbol_index = start_symbol;
      pusch_pdu->nr_of_symbols = nb_symb_sch;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
889
      pusch_pdu->pusch_data.rv_index = rv_index;
890
      pusch_pdu->pusch_data.harq_process_id = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
891
      pusch_pdu->pusch_data.new_data_indicator = trial & 0x1;
892
      pusch_pdu->pusch_data.num_cb = 0;
893 894
      pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
      pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
895 896
      pusch_pdu->pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
      pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
897

898 899
      // prepare ULSCH/PUSCH reception
      nr_schedule_response(Sched_INFO);
900

901
      // --------- setting parameters for UE --------
902 903 904 905 906 907 908

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
909
      scheduled_response.tx_request = &tx_req;
910
      
911 912 913 914 915
      // Config UL TX PDU
      tx_req.slot = slot;
      tx_req.sfn = frame;
      // tx_req->tx_config // TbD
      tx_req.number_of_pdus = 1;
916 917 918
      tx_req.tx_request_body[0].pdu_length = TBS/8;
      tx_req.tx_request_body[0].pdu_index = 0;
      tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0];
919

920
      ul_config.slot = slot;
921 922
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
923
      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
924
      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
925
      ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
926 927 928 929
      ul_config.ul_config_list[0].pusch_config_pdu.rb_size = nb_rb;
      ul_config.ul_config_list[0].pusch_config_pdu.rb_start = start_rb;
      ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
      ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
930
      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
931
      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
932
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
933
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
934 935 936 937
      ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
      ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
      ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;

938
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
939 940
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
941
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
942

943 944
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
945 946
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list   = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
947

948
      nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
949

950
      for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
951 952
      double scale = 1;

Francesco Mani's avatar
Francesco Mani committed
953
      if (input_fd == NULL) {
954

955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975
	  // set FAPI parameters for UE, put them in the scheduled response and call
	  nr_ue_scheduled_response(&scheduled_response);
	  
	  
	  /////////////////////////phy_procedures_nr_ue_TX///////////////////////
	  ///////////
	  
	  phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);
	  
	  
	  if (n_trials==1) {
	    LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
	    LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
	  }
	  ///////////
	  ////////////////////////////////////////////////////
	  tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
	  
	  txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 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);
	  
976
	  txlev_float = (double)txlev/scale; // output of signal_energy is fixed point representation
977 978 979 980
	  
	  
      }	
      else n_trials = 1;
981

982
      if (input_fd == NULL ) {
983

984 985
	sigma_dB = N0;
	sigma    = pow(10,sigma_dB/10);
Ahmed Hussein's avatar
Ahmed Hussein committed
986

987 988
	tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/txlev_float);
	if(n_trials==1) printf("txlev_float %f, sigma_dB %f, tx_gain %f tx_offset %d, slot_offset %d\n",10*log10(txlev_float),sigma_dB,tx_gain,tx_offset,slot_offset);
Ahmed Hussein's avatar
Ahmed Hussein committed
989

990 991 992 993
	for (i=0; i<slot_length; i++) {
	  for (int aa=0; aa<1; aa++) {
	    s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
	    s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
994 995
	  }
	}
996
	
997

998 999
	if (UE2gNB->max_Doppler == 0) {
	  multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
1000
			    slot_length,0,(n_trials==1)?1:0);
1001 1002 1003 1004 1005 1006 1007 1008
	} else {
	  multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
			       2*slot_length,0);
	}
	for (i=0; i<slot_length; i++) {
	  for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
	    ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)]   = (int16_t)((tx_gain*r_re[ap][i])   + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
	    ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)]   = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
1009 1010 1011 1012
            /* Add phase noise if enabled */
            if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
              phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
                          &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
1013
            }
1014
	  }
1015
	}
1016 1017

      }
1018

1019 1020 1021 1022 1023 1024 1025
	////////////////////////////////////////////////////////////
	
	//----------------------------------------------------------
	//------------------- gNB phy procedures -------------------
	//----------------------------------------------------------
	gNB->UL_INFO.rx_ind.number_of_pdus = 0;
	gNB->UL_INFO.crc_ind.number_crcs = 0;
1026

1027
        start_meas(&gNB->phy_proc_rx);
Ahmed Hussein's avatar
Ahmed Hussein committed
1028
        phy_procedures_gNB_common_RX(gNB, frame, slot);
1029

1030 1031
        phy_procedures_gNB_uespec_RX(gNB, frame, slot);

1032
	if (n_trials==1 && round==0) {
1033
	  LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1);
1034

1035
	  LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
1036

1037
	}
1038 1039


1040
	if (n_trials == 1  && round==0) { 
1041 1042 1043 1044 1045 1046
#ifdef __AVX2__
	  int off = ((nb_rb&1) == 1)? 4:0;
#else
	  int off = 0;
#endif

1047
	  LOG_M("rxsigF0_ext.m","rxsF0_ext",
1048
		&gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
1049 1050 1051
	  LOG_M("chestF0.m","chF0",
		&gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
	  LOG_M("chestF0_ext.m","chF0_ext",
1052 1053
		&gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
		(nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
1054
	  LOG_M("rxsigF0_comp.m","rxsF0_comp",
1055
		&gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
1056 1057
	  LOG_M("rxsigF0_llr.m","rxsF0_llr",
		&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
1058
	}
1059
        start_meas(&gNB->phy_proc_rx);
1060
        ////////////////////////////////////////////////////////////
1061
	
1062
	if (gNB->ulsch[0][0]->last_iteration_cnt >= 
1063 1064
	    gNB->ulsch[0][0]->max_ldpc_iterations+1) {
	  error_flag = 1; 
1065 1066
	  n_errors[round]++;
	  crc_status = 1;
1067
	} else {
1068
	  crc_status = 0;
1069
	}
1070 1071
	if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);

Ahmed Hussein's avatar
Ahmed Hussein committed
1072
        //----------------------------------------------------------
1073
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
1074
        //----------------------------------------------------------
1075

1076
        if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
1077
            ptrs_symbols = 0;
1078 1079 1080 1081
            for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){
               ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
            }
            /*  2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
1082
            available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
1083
            printf("After PTRS subtraction available_bits are : %u \n", available_bits);
1084 1085
        }

1086 1087 1088 1089 1090 1091 1092 1093
	for (i = 0; i < available_bits; i++) {
	  
	  if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
	     ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
	    {
	      /*if(errors_scrambling == 0)
		printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
	      errors_scrambling[round]++;
1094 1095
	    }
	}
1096 1097
	round++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1098
    } // round
1099 1100
    
    if (n_trials == 1 && errors_scrambling[0] > 0) {
1101
      printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
    }
    
    for (i = 0; i < TBS; i++) {
      
      estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
      test_input_bit[i]       = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
      
      if (estimated_output_bit[i] != test_input_bit[i]) {
	/*if(errors_decoding == 0)
	  printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding     = %d\n" "\x1B[0m", frame, trial, i);*/
	errors_decoding++;
1113
      }
1114 1115 1116 1117 1118 1119 1120 1121 1122
    }
    if (n_trials == 1) {
      for (int r=0;r<ulsch_ue[0]->harq_processes[harq_pid]->C;r++) 
	for (int i=0;i<ulsch_ue[0]->harq_processes[harq_pid]->K>>3;i++) {
	  /*if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
	    printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
	    i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i],
	    i,ulsch_gNB->harq_processes[harq_pid]->c[r][i],
	    ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);*/
1123
	}
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
    }
    if (errors_decoding > 0 && error_flag == 0) {
      n_false_positive++;
      if (n_trials==1)
	printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding     = %u\n" "\x1B[0m", frame, trial, errors_decoding);
    } 
    roundStats[snrRun] += ((float)round);
    if (!crc_status) effRate += ((float)TBS)/round;
    } // trial loop
    
    roundStats[snrRun]/=((float)n_trials);
    effRate /= n_trials;
    
    printf("*****************************************\n");
    printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n", SNR, n_errors[0], round_trials[0],n_errors[1], round_trials[1],n_errors[2], round_trials[2],n_errors[3], round_trials[3], n_false_positive, n_trials, errors_scrambling[0],available_bits*n_trials,errors_scrambling[1],available_bits*n_trials,errors_scrambling[2],available_bits*n_trials,errors_scrambling[3],available_bits*n_trials);
    printf("\n");
Raphael Defosseux's avatar
Raphael Defosseux committed
1140
    printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", 
1141
	   SNR,
1142 1143 1144 1145 1146 1147 1148 1149 1150
	   (double)n_errors[0]/round_trials[0],
	   (double)n_errors[1]/round_trials[0],
	   (double)n_errors[2]/round_trials[0],
	   (double)n_errors[3]/round_trials[0],
	   (double)errors_scrambling[0]/available_bits/round_trials[0],
	   (double)errors_scrambling[1]/available_bits/round_trials[0],
	   (double)errors_scrambling[2]/available_bits/round_trials[0],
	   (double)errors_scrambling[3]/available_bits/round_trials[0],
	   roundStats[snrRun],effRate,effRate/TBS*100,TBS);
Raymond Knopp's avatar
Raymond Knopp committed
1151 1152 1153

    dump_pusch_stats(gNB);

1154 1155 1156 1157 1158
    printf("*****************************************\n");
    printf("\n");
    
    if (print_perf==1) {
      printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
1159 1160
      printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
      printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
1161
      printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
1162 1163
      printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
      printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
1164
      printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
1165
      printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
1166 1167
      printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
      printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1168 1169 1170
      //printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
      //printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
      //printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
1171
      printf("\n");
1172
    }
1173

1174 1175
    if(n_trials==1)
      break;
1176

1177 1178 1179 1180 1181 1182
    if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
      printf("*************\n");
      printf("PUSCH test OK\n");
      printf("*************\n");
      break;
    }
1183

1184
    snrRun++;
1185
    n_errs = n_errors[0];
1186
  } // SNR loop
Ahmed Hussein's avatar
Ahmed Hussein committed
1187
  printf("\n");
1188

Ahmed Hussein's avatar
Ahmed Hussein committed
1189 1190 1191
  free(test_input_bit);
  free(estimated_output_bit);

1192 1193 1194 1195 1196 1197
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1198 1199 1200
  if (scg_fd)
    fclose(scg_fd);

1201
  return (n_errs);
1202
}