ulsim.c 46.2 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"
Mahesh's avatar
Mahesh 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
#include "PHY/NR_REFSIG/ptrs_nr.h"
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>

dir's avatar
dir committed
66 67
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"

68
//#define DEBUG_ULSIM
69

70 71 72
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
rlc_info_t Rlc_info_um,Rlc_info_am_config;

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

78
int sf_ahead=4 ;
Aniq's avatar
Aniq committed
79
int slot_ahead=6 ;
80
int sl_ahead=0;
81
double cpuf;
82
//uint8_t nfapi_mode = 0;
83 84
uint64_t downlink_frequency[MAX_NUM_CCs][4];

85

86 87
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; }
88 89 90 91 92 93 94 95 96
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;}
97 98 99

void
rrc_data_ind(
100
  const protocol_ctxt_t *const ctxt_pP,
101 102 103 104 105 106
  const rb_id_t                Srb_id,
  const sdu_size_t             sdu_sizeP,
  const uint8_t   *const       buffer_pP
)
{
}
107

108 109 110 111 112 113 114 115
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;
}
116

117 118 119 120 121 122 123 124
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;
}
125

heshanyun's avatar
heshanyun committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
int
gtpv1u_create_ngu_tunnel(
  const instance_t instanceP,
  const gtpv1u_gnb_create_tunnel_req_t *  const create_tunnel_req_pP,
        gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){
  return 0;
}

int
gtpv1u_update_ngu_tunnel(
  const instance_t                              instanceP,
  const gtpv1u_gnb_create_tunnel_req_t *const  create_tunnel_req_pP,
  const rnti_t                                  prior_rnti
){
  return 0;
}

int
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
  const protocol_ctxt_t *const ctxt_pP,
  const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP,
  uint8_t                         *inde_list
){
  return 0;
}

152
// Dummy function to avoid linking error at compilation of nr-ulsim
153 154 155 156 157
int is_x2ap_enabled(void)
{
  return 0;
}

Mahesh's avatar
Mahesh committed
158 159 160 161 162 163
//nFAPI P7 dummy functions 

int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0);  }
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);  }
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0);  }
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0);  }
rmagueta's avatar
rmagueta committed
164 165 166
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
  return 0;
}
Mahesh's avatar
Mahesh committed
167

168 169 170 171 172 173
int nr_derive_key(int alg_type, uint8_t alg_id,
               const uint8_t key[32], uint8_t **out)
{
  return 0;
}

174 175 176
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
177
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; 
178

179 180 181 182 183
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];
184

185 186
int main(int argc, char **argv)
{
187
  char c;
laurent's avatar
laurent committed
188
  int i;
189 190
  double SNR, snr0 = -2.0, snr1 = 2.0;
  double sigma, sigma_dB;
191
  double snr_step = .2;
192
  uint8_t snr1set = 0;
Raymond Knopp's avatar
Raymond Knopp committed
193
  int slot = 8, frame = 1;
194
  FILE *output_fd = NULL;
195 196 197 198
  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};
199
  //uint8_t write_output_file = 0;
200
  int trial, n_trials = 1, n_false_positive = 0, delay = 0;
201
  double maxDoppler = 0.0;
202
  uint8_t n_tx = 1, n_rx = 1;
203
  //uint8_t transmission_mode = 1;
204
  //uint16_t Nid_cell = 0;
205
  channel_desc_t *UE2gNB;
206 207
  uint8_t extended_prefix_flag = 0;
  //int8_t interf1 = -21, interf2 = -21;
208
  FILE *input_fd = NULL;
209
  SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
210
  uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
211

Laurent's avatar
Laurent committed
212
  NB_UE_INST = 1;
213

214 215
  //unsigned char frame_type = 0;
  NR_DL_FRAME_PARMS *frame_parms;
216
  int loglvl = OAILOG_INFO;
217
  //uint64_t SSB_positions=0x01;
218
  uint16_t nb_symb_sch = 12;
219
  int start_symbol = 0;
220
  uint16_t nb_rb = 50;
221
  int Imcs = 9;
222
  uint8_t precod_nbr_layers = 1;
223
  int gNB_id = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
224
  int ap;
Khalid Ahmed's avatar
Khalid Ahmed committed
225
  int tx_offset;
Khalid Ahmed's avatar
Khalid Ahmed committed
226
  int32_t txlev;
Ahmed Hussein's avatar
Ahmed Hussein committed
227
  int start_rb = 0;
228
  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)
229
  float target_error_rate = 0.01;
230
  int print_perf = 0;
231
  cpuf = get_cpu_freq_GHz();
232
  int msg3_flag = 0;
233
  int rv_index = 0;
234 235
  float roundStats[50];
  float effRate; 
236
  //float eff_tp_check = 0.7;
237
  uint8_t snrRun;
238

239
  int enable_ptrs = 0;
240 241 242 243 244
  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
245 246 247
  uint16_t ptrsSymPos = 0;
  uint16_t ptrsSymbPerSlot = 0;
  uint16_t ptrsRePerSymb = 0;
248

dir's avatar
dir committed
249 250 251 252
  uint8_t transform_precoding = transform_precoder_disabled; // 0 - ENABLE, 1 - DISABLE
  uint8_t num_dmrs_cdm_grps_no_data = 1;
  uint8_t mcs_table = 0;

253
  UE_nr_rxtx_proc_t UE_proc;
254
  FILE *scg_fd=NULL;
255
  int file_offset = 0;
256

257
  double DS_TDL = .03;
258 259
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Francesco Mani's avatar
Francesco Mani committed
260
  int ibwps=24;
261
  int ibwp_rboffset=41;
262
  int params_from_file = 0;
yilmazt's avatar
yilmazt committed
263
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
yilmazt's avatar
yilmazt committed
264
    exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
265 266 267 268 269
  }

  //logInit();
  randominit(0);

270 271 272
  /* initialize the sin-cos table */
   InitSinLUT();

dir's avatar
dir committed
273
  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:Z")) != -1) {
274
    printf("handling optarg %c\n",c);
275
    switch (c) {
276 277 278 279 280

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

281 282 283 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
    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);
      }
310

311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
      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;
342 343 344

      case 'H':
        channel_model = TDL_C;
345
	DS_TDL = .030; // 30 ns
346 347 348 349
	break;
  
      case 'I':
	channel_model = TDL_C;
350
	DS_TDL = .3;  // 300ns
351 352 353 354
        break;
     
      case 'J':
	channel_model=TDL_D;
355
	DS_TDL = .03;
356 357
	break;

358 359 360 361 362 363 364
      default:
	printf("Unsupported channel model!\n");
	exit(-1);
      }
      
      break;
      
365 366 367
      /*case 'i':
        interf1 = atoi(optarg);
        break;
368 369
	
	case 'j':
370 371 372
        interf2 = atoi(optarg);
        break;*/

373 374 375 376
    case 'k':
      printf("Setting threequarter_fs_flag\n");
      openair0_cfg[0].threequarter_fs= 1;
      break;
377

378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
    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;
402 403

/*
404 405 406
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;
407
*/
408
      /*
409 410 411 412 413 414 415 416 417
	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;
      */
      
418 419 420
      /*case 'x':
        transmission_mode = atoi(optarg);
        break;*/
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
      
    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;
451 452 453 454 455 456 457 458 459

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

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

460
    case 'M':
Francesco Mani's avatar
Francesco Mani committed
461
     // SSB_positions = atoi(optarg);
462 463 464
      break;
      
    case 'N':
Francesco Mani's avatar
Francesco Mani committed
465
     // Nid_cell = atoi(optarg);
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
      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;
487 488 489

   case 'T':
      enable_ptrs=1;
490 491 492 493 494 495 496 497 498
      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++]);
499 500
      }
      break;
501

502 503 504 505
    case 'Q':
      params_from_file = 1;
      break;

dir's avatar
dir committed
506 507 508 509 510 511 512 513 514 515
    case 'Z':

      transform_precoding = transform_precoder_enabled; 
      num_dmrs_cdm_grps_no_data = 2;
      mcs_table = 3;
      
      printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n",  transform_precoding);

      break;

516 517
    default:
    case 'h':
dir's avatar
dir committed
518
      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 -Z Enable SC-FDMA in Uplink \n", argv[0]);
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
      //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");
537
      printf("-G Offset of samples to read from file (0 default)\n");
538 539 540 541
      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");
542
      printf("-t Acceptable effective throughput (in percentage)\n");
543 544
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-P Print ULSCH performances\n");
545
      printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
546
      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
547
      printf("-Q If -F used, read parameters from file\n");
dir's avatar
dir committed
548
      printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
549 550
      exit(-1);
      break;
551

552 553
    }
  }
554
  
555 556 557 558
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

559
  get_softmodem_params()->phy_test = 1;
560
  get_softmodem_params()->do_ra = 0;
Francesco Mani's avatar
Francesco Mani committed
561 562
  get_softmodem_params()->usim_test = 1;

563

564 565
  if (snr1set == 0)
    snr1 = snr0 + 10;
566 567 568
  double sampling_frequency;
  double bandwidth;

569 570
  if (N_RB_UL >= 217) sampling_frequency = 122.88;
  else if (N_RB_UL >= 106) sampling_frequency = 61.44;
571
  else { printf("Need at least 106 PRBs\b"); exit(-1); }
572 573 574
  if (N_RB_UL == 273) bandwidth = 100;
  else if (N_RB_UL == 217) bandwidth = 80;
  else if (N_RB_UL == 106) bandwidth = 40;
575 576
  else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
			   
577
  if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
578 579 580 581

  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
                                sampling_frequency,
                                bandwidth,
582
				DS_TDL,
583 584
                                0, 0, 0);

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

590 591
  UE2gNB->max_Doppler = maxDoppler;

592
  RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
593
  RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
594
  gNB = RC.gNB[0];
Sakthivel Velumani's avatar
Sakthivel Velumani committed
595 596
  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
Sakthi's avatar
Sakthi committed
597 598
  char tp_param[] = "n";
  initTpool(tp_param, gNB->threadPool, true);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
599
  initNotifiedFIFO(gNB->respDecode);
600
  //gNB_config = &gNB->gNB_config;
601

602
  //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
Francesco Mani's avatar
Francesco Mani committed
603 604 605 606
  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;
607
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
608 609


610 611 612 613 614 615
  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;

616

617 618 619 620 621
  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
622
  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
623 624 625
  gNB_RRC_INST rrc;
  memset((void*)&rrc,0,sizeof(rrc));

626 627 628 629 630 631 632 633
  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
634 635
  fix_scc(scc,ssb_bitmap);

636 637 638 639 640 641
  fill_default_secondaryCellGroup(scc,
				  secondaryCellGroup,
				  0,
				  1,
				  n_tx,
				  0);
642

643
  // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
644 645

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

647 648
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
  // common configuration
649
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
650
  // UE dedicated configuration
651
  rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
652 653
  phy_init_nr_gNB(gNB,0,0);
  N_RB_DL = gNB->frame_parms.N_RB_DL;
654

655 656 657

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

658 659 660
  //crcTableInit();

  //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
661 662 663 664


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
665 666 667 668
  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;
669 670 671 672 673 674 675 676 677
  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);
678 679 680
  init_nr_ue_transport(UE, 0);

  /*
laurent's avatar
laurent committed
681
  for (int sf = 0; sf < 2; sf++) {
682 683 684 685 686 687 688 689 690 691
    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);
        }
    }
  }
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
  */
  
  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);

709
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
710 711 712

  nr_ue_phy_config_request(&UE_mac->phy_config);

713

714
  unsigned char harq_pid = 0;
715

716 717
  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;
718 719 720 721 722
  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;

723 724
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

725
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
726

727 728
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
729
  uint32_t errors_decoding   = 0;
730
  
731

732 733
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
734

Ahmed Hussein's avatar
Ahmed Hussein committed
735 736
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
737
  fapi_nr_tx_request_t tx_req;
738
  
739 740 741 742 743
  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;
dir's avatar
dir committed
744
  
745
  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
746
  uint8_t max_rounds = 4;
747
  uint8_t crc_status = 0;
748

dir's avatar
dir committed
749 750
  unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
  uint16_t      code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
751 752 753 754 755

  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

756 757 758 759 760 761
  /* validate parameters othwerwise default values are used */
  /* -U flag can be used to set DMRS parameters*/
  if(modify_dmrs)
  {
    if(dmrs_arg[0] == 0)
    {
762
      mapping_type = typeA;
763 764 765
    }
    else if (dmrs_arg[0] == 1)
    {
766
      mapping_type = typeB;
767 768 769 770 771 772
    }
    /* Additional DMRS positions */
    if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
    {
      add_pos = dmrs_arg[1];
    }
773 774 775 776 777 778 779
    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;
dir's avatar
dir committed
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794

  if (transform_precoding == transform_precoder_enabled) {  

    AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");

    int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb);
	  AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
    
    dmrs_config_type = pusch_dmrs_type1;
	  nb_re_dmrs   = nb_re_dmrs * num_dmrs_cdm_grps_no_data;

    printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index);
  }


795 796 797
  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);

dir's avatar
dir committed
798
  
799 800 801 802
  printf("[ULSIM]: length_dmrs: %u, l_prime_mask: %u	number_dmrs_symbols: %u, mapping_type: %u add_pos: %d \n", length_dmrs, l_prime_mask, number_dmrs_symbols, mapping_type, add_pos);
  printf("[ULSIM]: CDM groups: %u, dmrs_config_type: %d, num_rbs: %u, nb_symb_sch: %u\n", num_dmrs_cdm_grps_no_data, dmrs_config_type, nb_rb, nb_symb_sch);
  printf("[ULSIM]: MCS: %d, mod order: %u, code_rate: %u\n", Imcs, mod_order, code_rate);
  printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS);
dir's avatar
dir committed
803 804 805
  

  
806 807 808 809 810
  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();
811 812
  }

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

817 818
  double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);

819 820 821 822 823 824 825 826 827 828 829 830 831
  /* -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;
832
    printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
833
  }
834

835 836
  if (input_fd != NULL) max_rounds=1;

837
  if(1<<ptrs_time_density >= nb_symb_sch)
838
    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
839

840
  printf("\n");
841

Sakthivel Velumani's avatar
Sakthivel Velumani committed
842
  //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
843
  snrRun = 0;
844
  int n_errs = 0;
845
  int read_errors=0;
846

847
  int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
848 849 850 851 852 853 854
  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);
  
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
    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);
884
    for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
885 886 887
           slot_offset,
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
888 889
  }
  
890
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
891
    varArray_t *table_rx=initVarArray(1000,sizeof(double));
892 893 894
    int error_flag = 0;
    n_false_positive = 0;
    effRate = 0;
895 896 897
    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
898 899 900 901 902 903 904 905 906 907 908
    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);
909

Raymond Knopp's avatar
Raymond Knopp committed
910
    clear_pusch_stats(gNB);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
911 912 913
    for (trial = 0; trial < n_trials; trial++) {
    uint8_t round = 0;

914 915
    crc_status = 1;
    errors_decoding    = 0;
916
    memset((void*)roundStats,0,50*sizeof(roundStats[0]));
917
    while (round<max_rounds && crc_status) {
918
      round_trials[round]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
919 920
      ulsch_ue[0]->harq_processes[harq_pid]->round = round;
      gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
921
      rv_index = nr_rv_round_map[round];
922

923 924
      UE_proc.thread_id = 0;
      UE_proc.nr_slot_tx = slot;
925 926
      UE_proc.frame_tx = frame;

927 928
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
929 930 931 932
      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));
933
      
934 935
      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
936
      int ibwp_size  = ibwps;
937 938 939 940 941 942 943
      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;
944
	start_rb = (ibwp_start - abwp_start);
945 946 947 948 949 950 951 952
	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;
      }

953
      pusch_pdu->pusch_data.tb_size = TBS/8;
954
      pusch_pdu->pdu_bit_map = pdu_bit_map;
955 956
      pusch_pdu->rnti = n_rnti;
      pusch_pdu->mcs_index = Imcs;
957
      pusch_pdu->mcs_table = mcs_table;
958 959
      pusch_pdu->target_code_rate = code_rate;
      pusch_pdu->qam_mod_order = mod_order;
dir's avatar
dir committed
960
      pusch_pdu->transform_precoding = transform_precoding;
961
      pusch_pdu->data_scrambling_id = *scc->physCellId;
962
      pusch_pdu->nrOfLayers = 1;
963
      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
964
      pusch_pdu->dmrs_config_type = dmrs_config_type;
965
      pusch_pdu->ul_dmrs_scrambling_id =  *scc->physCellId;
966
      pusch_pdu->scid = 0;
967
      pusch_pdu->dmrs_ports = 1;
968
      pusch_pdu->num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
969 970 971 972 973 974 975 976
      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
977
      pusch_pdu->pusch_data.rv_index = rv_index;
978
      pusch_pdu->pusch_data.harq_process_id = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
979
      pusch_pdu->pusch_data.new_data_indicator = trial & 0x1;
980
      pusch_pdu->pusch_data.num_cb = 0;
981 982
      pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
      pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
983 984
      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;
985

dir's avatar
dir committed
986 987 988 989 990 991 992
      if (transform_precoding == transform_precoder_enabled) { 

        pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 
        pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0;     // V as defined in 38.211 section 6.4.1.1.1.2
        pusch_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;        
      }

993 994
      // prepare ULSCH/PUSCH reception
      nr_schedule_response(Sched_INFO);
995

996
      // --------- setting parameters for UE --------
997 998 999 1000 1001

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
1002
      scheduled_response.thread_id = UE_proc.thread_id;
1003 1004
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
1005
      scheduled_response.tx_request = &tx_req;
1006
      
1007 1008 1009 1010 1011
      // Config UL TX PDU
      tx_req.slot = slot;
      tx_req.sfn = frame;
      // tx_req->tx_config // TbD
      tx_req.number_of_pdus = 1;
1012 1013 1014
      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];
1015

1016
      ul_config.slot = slot;
1017 1018
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
1019
      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
1020
      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
1021
      ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
1022 1023 1024 1025
      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;
1026
      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
1027
      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
1028
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
1029
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
1030 1031 1032 1033
      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;

1034
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1035 1036
      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;
1037
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
1038

1039 1040
      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;
1041 1042
      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;
1043

dir's avatar
dir committed
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
      ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;

      if (transform_precoding == transform_precoder_enabled) { 
   
        ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 
        ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2
        //ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map |= PUSCH_PDU_BITMAP_DFTS_OFDM; 
        ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;

      }


1056
      nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
1057

1058
      for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
Francesco Mani's avatar
Francesco Mani committed
1059
      if (input_fd == NULL) {
1060

1061 1062 1063 1064 1065 1066 1067
	  // set FAPI parameters for UE, put them in the scheduled response and call
	  nr_ue_scheduled_response(&scheduled_response);
	  
	  
	  /////////////////////////phy_procedures_nr_ue_TX///////////////////////
	  ///////////
	  
1068
	  phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
	  
	  
	  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);
      }	
      else n_trials = 1;
1083

1084
      if (input_fd == NULL ) {
1085

1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
	sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
	sigma    = pow(10,sigma_dB/10);


	if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb));

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

	if (UE2gNB->max_Doppler == 0) {
	  multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
			    slot_length,0,(n_trials==1)?1:0);
	} 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)((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)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
1111 1112 1113 1114 1115
            /* 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]);
            }
1116 1117 1118
	  }
	}

1119
      }
1120

1121 1122

      if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
1123 1124 1125 1126 1127 1128 1129
        set_ptrs_symb_idx(&ptrsSymPos,
                          pusch_pdu->nr_of_symbols,
                          pusch_pdu->start_symbol_index,
                          1<<ptrs_time_density,
                          pusch_pdu->ul_dmrs_symb_pos);
        ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymPos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols);
        ptrsRePerSymb = ((pusch_pdu->rb_size + ptrs_freq_density - 1)/ptrs_freq_density);
1130
        printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
1131
      }
1132 1133 1134 1135 1136 1137 1138
	////////////////////////////////////////////////////////////
	
	//----------------------------------------------------------
	//------------------- gNB phy procedures -------------------
	//----------------------------------------------------------
	gNB->UL_INFO.rx_ind.number_of_pdus = 0;
	gNB->UL_INFO.crc_ind.number_crcs = 0;
1139

1140
        start_meas(&gNB->phy_proc_rx);
Ahmed Hussein's avatar
Ahmed Hussein committed
1141
        phy_procedures_gNB_common_RX(gNB, frame, slot);
1142

1143 1144
        phy_procedures_gNB_uespec_RX(gNB, frame, slot);

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

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

1150
	}
1151 1152


1153
	if (n_trials == 1  && round==0) { 
1154 1155 1156 1157 1158 1159
#ifdef __AVX2__
	  int off = ((nb_rb&1) == 1)? 4:0;
#else
	  int off = 0;
#endif

1160
	  LOG_M("rxsigF0_ext.m","rxsF0_ext",
1161
		&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);
1162 1163 1164
	  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",
1165 1166
		&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);
1167
	  LOG_M("rxsigF0_comp.m","rxsF0_comp",
1168
		&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);
1169 1170
	  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);
1171
	}
1172
        start_meas(&gNB->phy_proc_rx);
1173
        ////////////////////////////////////////////////////////////
1174
	
1175
	if (gNB->ulsch[0][0]->last_iteration_cnt >= 
1176 1177
	    gNB->ulsch[0][0]->max_ldpc_iterations+1) {
	  error_flag = 1; 
1178 1179
	  n_errors[round]++;
	  crc_status = 1;
1180
	} else {
1181
	  crc_status = 0;
1182
	}
1183 1184
	if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);

Ahmed Hussein's avatar
Ahmed Hussein committed
1185
        //----------------------------------------------------------
1186
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
1187
        //----------------------------------------------------------
1188

1189
        if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
1190
            ptrs_symbols = 0;
1191 1192 1193 1194
            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 */
1195
            available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
1196
            printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
1197 1198
        }

1199 1200 1201 1202 1203 1204 1205 1206
	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]++;
1207 1208
	    }
	}
1209 1210
	round++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1211
    } // round
1212 1213
    
    if (n_trials == 1 && errors_scrambling[0] > 0) {
1214
      printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
    }
    
    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++;
1226
      }
1227 1228 1229 1230 1231 1232 1233 1234 1235
    }
    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]);*/
1236
	}
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
    }
    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
1253
    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", 
1254
	   SNR,
1255 1256 1257 1258 1259 1260 1261 1262 1263
	   (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
1264 1265 1266

    dump_pusch_stats(gNB);

1267 1268 1269 1270 1271
    printf("*****************************************\n");
    printf("\n");
    
    if (print_perf==1) {
      printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
1272 1273
      printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
      printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
1274
      printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
1275 1276
      printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
      printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
1277
      printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
1278
      printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
1279 1280
      printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
      printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1281 1282 1283
      //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");
1284
      printf("\n");
1285
    }
1286

1287 1288
    if(n_trials==1)
      break;
1289

1290 1291 1292 1293 1294 1295
    if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
      printf("*************\n");
      printf("PUSCH test OK\n");
      printf("*************\n");
      break;
    }
1296

1297
    snrRun++;
1298
    n_errs = n_errors[0];
1299
  } // SNR loop
Ahmed Hussein's avatar
Ahmed Hussein committed
1300
  printf("\n");
1301

Ahmed Hussein's avatar
Ahmed Hussein committed
1302 1303 1304
  free(test_input_bit);
  free(estimated_output_bit);

1305 1306 1307 1308 1309 1310
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1311 1312 1313
  if (scg_fd)
    fclose(scg_fd);

1314
  return (n_errs);
1315
}