ulsim.c 47.4 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
#include "PHY/NR_REFSIG/ptrs_nr.h"
60
#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
61
#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];

Laurent THOMAS's avatar
Laurent THOMAS committed
78
uint16_t sf_ahead=4 ;
Aniq's avatar
Aniq committed
79
int slot_ahead=6 ;
Laurent THOMAS's avatar
Laurent THOMAS committed
80
uint16_t sl_ahead=0;
81
double cpuf;
82
//uint8_t nfapi_mode = 0;
83
uint64_t downlink_frequency[MAX_NUM_CCs][4];
84 85 86
THREAD_STRUCT thread_struct;
nfapi_ue_release_request_body_t release_rntis;
msc_interface_t msc_interface;
87

88
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
89

90 91 92 93 94 95 96 97 98 99 100 101
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
                              const int CC_id,
                              const uint8_t gNB_index,
                              const frame_t frame,
                              const sub_frame_t sub_frame,
                              const rnti_t rnti,
                              const channel_t channel,
                              const uint8_t* pduP,
                              const sdu_size_t pdu_len)
{
  return 0;
}
102

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

void
rrc_data_ind(
115
  const protocol_ctxt_t *const ctxt_pP,
116 117 118 119 120 121
  const rb_id_t                Srb_id,
  const sdu_size_t             sdu_sizeP,
  const uint8_t   *const       buffer_pP
)
{
}
122

123 124 125 126 127 128 129 130
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;
}
131

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

heshanyun's avatar
heshanyun committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
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;
}

167
// Dummy function to avoid linking error at compilation of nr-ulsim
168 169 170 171 172
int is_x2ap_enabled(void)
{
  return 0;
}

173 174 175 176 177
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
{
  return;
}

178 179 180 181 182 183 184
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
                              const int         CC_id,
                              const uint8_t     gNB_id,
                              const frame_t     frameP,
                              const rb_id_t     Srb_id,
                              uint8_t           *buffer_pP)
{
rmagueta's avatar
rmagueta committed
185 186 187
  return 0;
}

188
//nFAPI P7 dummy functions
Mahesh's avatar
Mahesh committed
189 190 191 192 193 194

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

195 196 197
int nr_derive_key(int alg_type, uint8_t alg_id,
               const uint8_t key[32], uint8_t **out)
{
rmagueta's avatar
rmagueta committed
198 199 200
  return 0;
}

201 202 203
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
204
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; 
205

206 207 208 209 210
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];
211

212 213
int main(int argc, char **argv)
{
214
  char c;
laurent's avatar
laurent committed
215
  int i;
216 217
  double SNR, snr0 = -2.0, snr1 = 2.0;
  double sigma, sigma_dB;
218
  double snr_step = .2;
219
  uint8_t snr1set = 0;
Raymond Knopp's avatar
Raymond Knopp committed
220
  int slot = 8, frame = 1;
221
  FILE *output_fd = NULL;
222 223 224 225
  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};
226
  //uint8_t write_output_file = 0;
227
  int trial, n_trials = 1, n_false_positive = 0, delay = 0;
228
  double maxDoppler = 0.0;
229
  uint8_t n_tx = 1, n_rx = 1;
230
  //uint8_t transmission_mode = 1;
231
  //uint16_t Nid_cell = 0;
232
  channel_desc_t *UE2gNB;
233 234
  uint8_t extended_prefix_flag = 0;
  //int8_t interf1 = -21, interf2 = -21;
235
  FILE *input_fd = NULL;
236
  SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
237
  uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
238

Laurent's avatar
Laurent committed
239
  NB_UE_INST = 1;
240

241 242
  //unsigned char frame_type = 0;
  NR_DL_FRAME_PARMS *frame_parms;
243
  int loglvl = OAILOG_INFO;
244
  //uint64_t SSB_positions=0x01;
245
  uint16_t nb_symb_sch = 12;
246
  int start_symbol = 0;
247
  uint16_t nb_rb = 50;
248
  int Imcs = 9;
249
  uint8_t precod_nbr_layers = 1;
250
  int gNB_id = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
251
  int ap;
Khalid Ahmed's avatar
Khalid Ahmed committed
252
  int tx_offset;
Khalid Ahmed's avatar
Khalid Ahmed committed
253
  int32_t txlev;
Ahmed Hussein's avatar
Ahmed Hussein committed
254
  int start_rb = 0;
255
  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)
256
  float target_error_rate = 0.01;
257
  int print_perf = 0;
258
  cpuf = get_cpu_freq_GHz();
259
  int msg3_flag = 0;
260
  int rv_index = 0;
261 262
  float roundStats[50];
  float effRate; 
263
  //float eff_tp_check = 0.7;
264
  uint8_t snrRun;
265

266
  int enable_ptrs = 0;
267 268 269 270 271
  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
272 273 274
  uint16_t ptrsSymPos = 0;
  uint16_t ptrsSymbPerSlot = 0;
  uint16_t ptrsRePerSymb = 0;
275

dir's avatar
dir committed
276 277 278 279
  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;

280
  UE_nr_rxtx_proc_t UE_proc;
281
  FILE *scg_fd=NULL;
282
  int file_offset = 0;
283

284
  double DS_TDL = .03;
285 286
  int pusch_tgt_snrx10 = 200;
  int pucch_tgt_snrx10 = 200;
Francesco Mani's avatar
Francesco Mani committed
287
  int ibwps=24;
288
  int ibwp_rboffset=41;
289
  int params_from_file = 0;
yilmazt's avatar
yilmazt committed
290
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
yilmazt's avatar
yilmazt committed
291
    exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
292 293 294 295 296
  }

  //logInit();
  randominit(0);

297 298 299
  /* initialize the sin-cos table */
   InitSinLUT();

dir's avatar
dir committed
300
  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) {
301
    printf("handling optarg %c\n",c);
302
    switch (c) {
303 304 305 306 307

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

308 309 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
    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);
      }
337

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
      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;
369 370 371

      case 'H':
        channel_model = TDL_C;
372
	DS_TDL = .030; // 30 ns
373 374 375 376
	break;
  
      case 'I':
	channel_model = TDL_C;
377
	DS_TDL = .3;  // 300ns
378 379 380 381
        break;
     
      case 'J':
	channel_model=TDL_D;
382
	DS_TDL = .03;
383 384
	break;

385 386 387 388 389 390 391
      default:
	printf("Unsupported channel model!\n");
	exit(-1);
      }
      
      break;
      
392 393 394
      /*case 'i':
        interf1 = atoi(optarg);
        break;
395 396
	
	case 'j':
397 398 399
        interf2 = atoi(optarg);
        break;*/

400 401 402 403
    case 'k':
      printf("Setting threequarter_fs_flag\n");
      openair0_cfg[0].threequarter_fs= 1;
      break;
404

405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
    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;
429 430

/*
431 432 433
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;
434
*/
435
      /*
436 437 438 439 440 441 442 443 444
	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;
      */
      
445 446 447
      /*case 'x':
        transmission_mode = atoi(optarg);
        break;*/
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
      
    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;
478 479 480 481 482 483 484 485 486

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

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

487
    case 'M':
Francesco Mani's avatar
Francesco Mani committed
488
     // SSB_positions = atoi(optarg);
489 490 491
      break;
      
    case 'N':
Francesco Mani's avatar
Francesco Mani committed
492
     // Nid_cell = atoi(optarg);
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
      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;
514 515 516

   case 'T':
      enable_ptrs=1;
517 518 519 520 521 522 523 524 525
      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++]);
526 527
      }
      break;
528

529 530 531 532
    case 'Q':
      params_from_file = 1;
      break;

dir's avatar
dir committed
533 534 535 536 537 538 539 540 541 542
    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;

543 544
    default:
    case 'h':
dir's avatar
dir committed
545
      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]);
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
      //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");
564
      printf("-G Offset of samples to read from file (0 default)\n");
565 566 567 568
      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");
569
      printf("-t Acceptable effective throughput (in percentage)\n");
570 571
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-P Print ULSCH performances\n");
572
      printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
573
      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
574
      printf("-Q If -F used, read parameters from file\n");
dir's avatar
dir committed
575
      printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
576 577
      exit(-1);
      break;
578

579 580
    }
  }
581
  
582 583 584 585
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

586
  get_softmodem_params()->phy_test = 1;
587
  get_softmodem_params()->do_ra = 0;
Francesco Mani's avatar
Francesco Mani committed
588 589
  get_softmodem_params()->usim_test = 1;

590

591 592
  if (snr1set == 0)
    snr1 = snr0 + 10;
593 594 595
  double sampling_frequency;
  double bandwidth;

596 597
  if (N_RB_UL >= 217) sampling_frequency = 122.88;
  else if (N_RB_UL >= 106) sampling_frequency = 61.44;
598
  else { printf("Need at least 106 PRBs\b"); exit(-1); }
599 600 601
  if (N_RB_UL == 273) bandwidth = 100;
  else if (N_RB_UL == 217) bandwidth = 80;
  else if (N_RB_UL == 106) bandwidth = 40;
602 603
  else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
			   
604
  if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
605 606 607 608

  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
                                sampling_frequency,
                                bandwidth,
609
				DS_TDL,
610
                                0, 0, 0, 0);
611

612
  if (UE2gNB == NULL) {
613
    printf("Problem generating channel model. Exiting.\n");
614 615 616
    exit(-1);
  }

617 618
  UE2gNB->max_Doppler = maxDoppler;

619
  RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
620
  RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
621
  gNB = RC.gNB[0];
Sakthivel Velumani's avatar
Sakthivel Velumani committed
622 623
  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
Sakthi's avatar
Sakthi committed
624 625
  char tp_param[] = "n";
  initTpool(tp_param, gNB->threadPool, true);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
626
  initNotifiedFIFO(gNB->respDecode);
627
  //gNB_config = &gNB->gNB_config;
628

629
  //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
Francesco Mani's avatar
Francesco Mani committed
630 631 632 633
  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;
634
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
635 636


637 638
  //frame_parms->nb_antennas_tx = n_tx;
  //frame_parms->nb_antennas_rx = n_rx;
639 640 641 642
  frame_parms->N_RB_DL = N_RB_DL;
  frame_parms->N_RB_UL = N_RB_UL;
  frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;

643

644 645 646 647 648
  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
649
  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
650 651 652
  gNB_RRC_INST rrc;
  memset((void*)&rrc,0,sizeof(rrc));

653 654 655
  rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));

  NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
656
  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
657 658 659 660 661
  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
662 663
  fix_scc(scc,ssb_bitmap);

664 665
  prepare_scd(scd);

666
  fill_default_secondaryCellGroup(scc,
667
                                  scd,
668 669 670 671 672
				  secondaryCellGroup,
				  0,
				  1,
				  n_tx,
				  0);
673

674
  // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
675

676 677 678
  /* RRC parameter validation for secondaryCellGroup */
  fix_scd(scd);

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

681 682
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
  // common configuration
683
  rrc_mac_config_req_gNB(0,0,n_tx,n_rx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
684
  // UE dedicated configuration
685
  rrc_mac_config_req_gNB(0,0,1,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
686 687
  phy_init_nr_gNB(gNB,0,0);
  N_RB_DL = gNB->frame_parms.N_RB_DL;
688

689 690 691

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

692 693 694
  //crcTableInit();

  //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
695 696 697 698


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
699 700 701 702
  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;
703 704 705 706 707 708 709 710 711
  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);
712 713 714
  init_nr_ue_transport(UE, 0);

  /*
laurent's avatar
laurent committed
715
  for (int sf = 0; sf < 2; sf++) {
716 717 718 719 720 721 722 723 724 725
    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);
        }
    }
  }
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
  */
  
  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);

743
  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,secondaryCellGroup);
744 745 746

  nr_ue_phy_config_request(&UE_mac->phy_config);

747

748
  unsigned char harq_pid = 0;
749

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

757 758
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

759
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
760

761 762
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
763
  uint32_t errors_decoding   = 0;
764
  
765

766 767
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
768

Ahmed Hussein's avatar
Ahmed Hussein committed
769 770
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
771
  fapi_nr_tx_request_t tx_req;
772
  
773 774 775 776 777
  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
778
  
779
  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
780
  uint8_t max_rounds = 4;
781
  uint8_t crc_status = 0;
782

dir's avatar
dir committed
783 784
  unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
  uint16_t      code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
785 786 787 788 789

  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

790 791 792 793 794 795
  /* validate parameters othwerwise default values are used */
  /* -U flag can be used to set DMRS parameters*/
  if(modify_dmrs)
  {
    if(dmrs_arg[0] == 0)
    {
796
      mapping_type = typeA;
797 798 799
    }
    else if (dmrs_arg[0] == 1)
    {
800
      mapping_type = typeB;
801 802 803 804 805 806
    }
    /* Additional DMRS positions */
    if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
    {
      add_pos = dmrs_arg[1];
    }
807 808 809 810 811 812 813
    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
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828

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


829 830 831
  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
832
  
833 834 835 836
  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
837 838 839
  

  
840 841 842 843 844
  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();
845 846
  }

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

851 852
  double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);

853 854 855 856 857 858 859 860 861 862 863 864 865
  /* -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;
866
    printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
867
  }
868

869 870
  if (input_fd != NULL) max_rounds=1;

871
  if(1<<ptrs_time_density >= nb_symb_sch)
872
    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
873

874
  printf("\n");
875

Sakthivel Velumani's avatar
Sakthivel Velumani committed
876
  //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
877
  snrRun = 0;
878
  int n_errs = 0;
879
  int read_errors=0;
880

881
  int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
882 883 884 885 886 887 888
  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);
  
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
    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);
918
    for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
919 920 921
           slot_offset,
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
           ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
922 923
  }
  
924
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
925
    varArray_t *table_rx=initVarArray(1000,sizeof(double));
926 927 928
    int error_flag = 0;
    n_false_positive = 0;
    effRate = 0;
929 930 931
    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
932 933 934 935 936 937 938 939 940 941 942
    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);
943

Raymond Knopp's avatar
Raymond Knopp committed
944
    clear_pusch_stats(gNB);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
945 946 947
    for (trial = 0; trial < n_trials; trial++) {
    uint8_t round = 0;

948 949
    crc_status = 1;
    errors_decoding    = 0;
950
    memset((void*)roundStats,0,50*sizeof(roundStats[0]));
951
    while (round<max_rounds && crc_status) {
952
      round_trials[round]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
953 954
      ulsch_ue[0]->harq_processes[harq_pid]->round = round;
      gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
955
      rv_index = nr_rv_round_map[round];
956

957 958
      UE_proc.thread_id = 0;
      UE_proc.nr_slot_tx = slot;
959 960
      UE_proc.frame_tx = frame;

961 962
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
963 964 965 966
      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));
967
      
968 969
      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
970
      int ibwp_size  = ibwps;
971 972 973 974 975 976 977
      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;
978
	start_rb = (ibwp_start - abwp_start);
979 980 981 982 983 984 985 986
	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;
      }

987
      pusch_pdu->pusch_data.tb_size = TBS/8;
988
      pusch_pdu->pdu_bit_map = pdu_bit_map;
989 990
      pusch_pdu->rnti = n_rnti;
      pusch_pdu->mcs_index = Imcs;
991
      pusch_pdu->mcs_table = mcs_table;
992 993
      pusch_pdu->target_code_rate = code_rate;
      pusch_pdu->qam_mod_order = mod_order;
dir's avatar
dir committed
994
      pusch_pdu->transform_precoding = transform_precoding;
995
      pusch_pdu->data_scrambling_id = *scc->physCellId;
996
      pusch_pdu->nrOfLayers = 1;
997
      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
998
      pusch_pdu->dmrs_config_type = dmrs_config_type;
999
      pusch_pdu->ul_dmrs_scrambling_id =  *scc->physCellId;
1000
      pusch_pdu->scid = 0;
1001
      pusch_pdu->dmrs_ports = 1;
1002
      pusch_pdu->num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
1003 1004 1005 1006 1007 1008 1009 1010
      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
1011
      pusch_pdu->pusch_data.rv_index = rv_index;
1012
      pusch_pdu->pusch_data.harq_process_id = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1013
      pusch_pdu->pusch_data.new_data_indicator = trial & 0x1;
1014
      pusch_pdu->pusch_data.num_cb = 0;
1015 1016
      pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
      pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
1017 1018
      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;
1019

dir's avatar
dir committed
1020 1021 1022 1023 1024 1025 1026
      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;        
      }

1027 1028
      // prepare ULSCH/PUSCH reception
      nr_schedule_response(Sched_INFO);
1029

1030
      // --------- setting parameters for UE --------
1031 1032 1033 1034 1035

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
1036
      scheduled_response.thread_id = UE_proc.thread_id;
1037 1038
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
1039
      scheduled_response.tx_request = &tx_req;
1040
      
1041 1042 1043 1044 1045
      // Config UL TX PDU
      tx_req.slot = slot;
      tx_req.sfn = frame;
      // tx_req->tx_config // TbD
      tx_req.number_of_pdus = 1;
1046 1047 1048
      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];
1049

1050
      ul_config.slot = slot;
1051 1052
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
1053
      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
1054
      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
1055
      ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
1056 1057 1058 1059
      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;
1060
      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
1061
      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
1062
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
1063
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
1064 1065 1066 1067
      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;

1068
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1069 1070
      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;
1071
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
1072

1073 1074
      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;
1075 1076
      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;
1077

dir's avatar
dir committed
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
      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;

      }


1090
      //nr_fill_ulsch(gNB,frame,slot,pusch_pdu); // Not needed as its its already filled as apart of "nr_schedule_response(Sched_INFO);"
1091

1092
      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
1093
      if (input_fd == NULL) {
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
        // 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);


        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);
        }
        ///////////
        ////////////////////////////////////////////////////
1111
        tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
1112

1113
        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],
1114
                              frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
1115 1116
      }	
      else n_trials = 1;
1117

1118
      if (input_fd == NULL ) {
1119

1120 1121
        sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
        sigma    = pow(10,sigma_dB/10);
1122 1123


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

1127 1128 1129 1130 1131 1132
        for (i=0; i<slot_length; i++) {
          for (int aa=0; aa<frame_parms->nb_antennas_rx; 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]);
          }
        }
1133

1134

1135 1136 1137 1138 1139 1140 1141 1142 1143
        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)));
1144 1145 1146 1147 1148
            /* 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]);
            }
1149 1150
          }
        }
1151

1152
      } /*End input_fd */
1153

1154 1155

      if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
1156 1157 1158 1159 1160 1161 1162
        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);
1163
        printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
1164
      }
1165 1166 1167 1168 1169 1170 1171
	////////////////////////////////////////////////////////////
	
	//----------------------------------------------------------
	//------------------- gNB phy procedures -------------------
	//----------------------------------------------------------
	gNB->UL_INFO.rx_ind.number_of_pdus = 0;
	gNB->UL_INFO.crc_ind.number_crcs = 0;
1172

Ahmed Hussein's avatar
Ahmed Hussein committed
1173
        phy_procedures_gNB_common_RX(gNB, frame, slot);
1174

1175 1176
        phy_procedures_gNB_uespec_RX(gNB, frame, slot);

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

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

1182
	}
1183 1184


1185
	if (n_trials == 1  && round==0) { 
1186 1187 1188 1189 1190 1191
#ifdef __AVX2__
	  int off = ((nb_rb&1) == 1)? 4:0;
#else
	  int off = 0;
#endif

1192
	  LOG_M("rxsigF0_ext.m","rxsF0_ext",
1193
		&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);
1194 1195 1196
	  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",
1197 1198
		&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);
1199
	  LOG_M("rxsigF0_comp.m","rxsF0_comp",
1200
		&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);
1201 1202
	  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);
1203
	}
1204
        ////////////////////////////////////////////////////////////
1205
	
1206
	if (gNB->ulsch[0][0]->last_iteration_cnt >= 
1207 1208
	    gNB->ulsch[0][0]->max_ldpc_iterations+1) {
	  error_flag = 1; 
1209 1210
	  n_errors[round]++;
	  crc_status = 1;
1211
	} else {
1212
	  crc_status = 0;
1213
	}
1214 1215
	if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);

Ahmed Hussein's avatar
Ahmed Hussein committed
1216
        //----------------------------------------------------------
1217
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
1218
        //----------------------------------------------------------
1219

1220
        if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
1221
            ptrs_symbols = 0;
1222 1223 1224 1225
            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 */
1226
            available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
1227
            printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
1228 1229
        }

1230 1231 1232 1233 1234 1235 1236 1237
	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]++;
1238 1239
	    }
	}
1240 1241
	round++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1242
    } // round
1243 1244
    
    if (n_trials == 1 && errors_scrambling[0] > 0) {
1245
      printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
    }
    
    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++;
1257
      }
1258 1259 1260 1261 1262 1263 1264 1265 1266
    }
    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]);*/
1267
	}
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
    }
    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
1284
    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", 
1285
	   SNR,
1286 1287 1288 1289 1290 1291 1292 1293 1294
	   (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
1295 1296 1297

    dump_pusch_stats(gNB);

1298 1299 1300 1301 1302
    printf("*****************************************\n");
    printf("\n");
    
    if (print_perf==1) {
      printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
1303 1304
      printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
      printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
1305
      printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
1306 1307
      printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
      printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
1308
      printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
1309
      printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
1310 1311
      printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
      printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1312 1313 1314
      //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");
1315
      printf("\n");
1316
    }
1317

1318 1319
    if(n_trials==1)
      break;
1320

1321 1322 1323 1324 1325 1326
    if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
      printf("*************\n");
      printf("PUSCH test OK\n");
      printf("*************\n");
      break;
    }
1327

1328
    snrRun++;
1329
    n_errs = n_errors[0];
1330
  } // SNR loop
Ahmed Hussein's avatar
Ahmed Hussein committed
1331
  printf("\n");
1332

Ahmed Hussein's avatar
Ahmed Hussein committed
1333 1334 1335
  free(test_input_bit);
  free(estimated_output_bit);

1336 1337 1338 1339 1340 1341
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1342 1343 1344
  if (scg_fd)
    fclose(scg_fd);

1345
  return (n_errs);
1346
}