ulsim.c 58.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"
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>

Raymond Knopp's avatar
Raymond Knopp committed
66
#include <executables/softmodem-common.h>
dir's avatar
dir committed
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
THREAD_STRUCT thread_struct;
nfapi_ue_release_request_body_t release_rntis;
rmagueta's avatar
rmagueta committed
86
uint32_t N_RB_DL = 106;
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

rmagueta's avatar
rmagueta committed
123 124 125 126 127 128
int ocp_gtpv1u_create_s1u_tunnel(instance_t instance,
                                 const gtpv1u_enb_create_tunnel_req_t  *create_tunnel_req,
                                 gtpv1u_enb_create_tunnel_resp_t *create_tunnel_resp) {
    return 0;
}

129 130 131 132 133 134 135 136
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;
}
137

rmagueta's avatar
rmagueta committed
138 139 140 141
int ocp_gtpv1u_delete_s1u_tunnel(const instance_t instance, const gtpv1u_enb_delete_tunnel_req_t *const req_pP) {
  return 0;
}

142 143 144 145 146 147 148 149
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;
}
150

heshanyun's avatar
heshanyun committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
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;
}

177
// Dummy function to avoid linking error at compilation of nr-ulsim
178 179 180 181 182
int is_x2ap_enabled(void)
{
  return 0;
}

183 184 185 186 187
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
{
  return;
}

188 189 190 191 192 193 194
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
195 196 197
  return 0;
}

rmagueta's avatar
rmagueta committed
198 199 200 201 202 203 204 205 206 207 208
int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t     module_idP,
                                            int             CC_idP,
                                            int             UE_id,
                                            rnti_t          rntiP,
                                            const uint8_t   *sduP,
                                            sdu_size_t      sdu_lenP,
                                            const uint8_t   *sdu2P,
                                            sdu_size_t      sdu2_lenP) {
  return 0;
}

209
//nFAPI P7 dummy functions
Mahesh's avatar
Mahesh committed
210 211 212 213 214

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);  }
Mahesh's avatar
Mahesh committed
215 216 217 218 219
int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { return(0);  }
int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { return(0);  }
int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return(0);  }
int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { return(0);  }
int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0);  }
Mahesh's avatar
Mahesh committed
220

221 222 223
int nr_derive_key(int alg_type, uint8_t alg_id,
               const uint8_t key[32], uint8_t **out)
{
rmagueta's avatar
rmagueta committed
224 225 226
  return 0;
}

Sakthivel Velumani's avatar
Sakthivel Velumani committed
227 228 229 230 231 232
typedef struct {
  uint64_t       optmask;   //mask to store boolean config options
  uint8_t        nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
  tpool_t        Tpool;             // thread pool 
} nrUE_params_t;

233 234
void processSlotTX(void *arg) {}

Sakthivel Velumani's avatar
Sakthivel Velumani committed
235 236 237 238 239
nrUE_params_t nrUE_params;

nrUE_params_t *get_nrUE_params(void) {
  return &nrUE_params;
}
240 241 242
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
243
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; 
244

245
channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX];
246

247 248
int main(int argc, char **argv)
{
249
  char c;
laurent's avatar
laurent committed
250
  int i;
251 252
  double SNR, snr0 = -2.0, snr1 = 2.0;
  double sigma, sigma_dB;
253
  double snr_step = .2;
254
  uint8_t snr1set = 0;
Raymond Knopp's avatar
Raymond Knopp committed
255
  int slot = 8, frame = 1;
256
  FILE *output_fd = NULL;
257
  double **s_re,**s_im,**r_re,**r_im;
258
  //uint8_t write_output_file = 0;
259
  int trial, n_trials = 1, n_false_positive = 0, delay = 0;
260
  double maxDoppler = 0.0;
261
  uint8_t n_tx = 1, n_rx = 1;
262
  //uint8_t transmission_mode = 1;
263
  //uint16_t Nid_cell = 0;
264
  channel_desc_t *UE2gNB;
265 266
  uint8_t extended_prefix_flag = 0;
  //int8_t interf1 = -21, interf2 = -21;
267
  FILE *input_fd = NULL;
268
  SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
269
  uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
270

Laurent's avatar
Laurent committed
271
  NB_UE_INST = 1;
272

273 274
  //unsigned char frame_type = 0;
  NR_DL_FRAME_PARMS *frame_parms;
275
  int loglvl = OAILOG_INFO;
276
  //uint64_t SSB_positions=0x01;
277
  uint16_t nb_symb_sch = 12;
278
  int start_symbol = 0;
279
  uint16_t nb_rb = 50;
280
  int Imcs = 9;
281
  uint8_t precod_nbr_layers = 1;
282
  int gNB_id = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
283
  int ap;
Khalid Ahmed's avatar
Khalid Ahmed committed
284
  int tx_offset;
285
  int32_t txlev=0;
Ahmed Hussein's avatar
Ahmed Hussein committed
286
  int start_rb = 0;
287
  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)
288
  float target_error_rate = 0.01;
289
  int print_perf = 0;
290
  cpuf = get_cpu_freq_GHz();
291
  int msg3_flag = 0;
292
  int rv_index = 0;
293 294 295
  float roundStats[100];
  double effRate[100]; 
  double effTP[100]; 
296
  //float eff_tp_check = 0.7;
297
  uint8_t snrRun;
298
  int prb_inter = 0;
299

300
  int enable_ptrs = 0;
301 302 303 304 305
  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
306 307 308
  uint16_t ptrsSymPos = 0;
  uint16_t ptrsSymbPerSlot = 0;
  uint16_t ptrsRePerSymb = 0;
309

310
  uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE
rmagueta's avatar
rmagueta committed
311
  uint8_t num_dmrs_cdm_grps_no_data = 1;
dir's avatar
dir committed
312 313
  uint8_t mcs_table = 0;

314
  UE_nr_rxtx_proc_t UE_proc;
315
  FILE *scg_fd=NULL;
316
  int file_offset = 0;
317

318
  double DS_TDL = .03;
Francesco Mani's avatar
Francesco Mani committed
319
  int ibwps=24;
320
  int ibwp_rboffset=41;
321
  int params_from_file = 0;
yilmazt's avatar
yilmazt committed
322
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
yilmazt's avatar
yilmazt committed
323
    exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
324
  }
325
  int ul_proc_error = 0; // uplink processing checking status flag
326 327 328
  //logInit();
  randominit(0);

329 330 331
  /* initialize the sin-cos table */
   InitSinLUT();

Sakthivel Velumani's avatar
Sakthivel Velumani committed
332
  while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) {
333
    printf("handling optarg %c\n",c);
334
    switch (c) {
335 336 337 338 339

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

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

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

      case 'H':
        channel_model = TDL_C;
404
	DS_TDL = .030; // 30 ns
405 406 407 408
	break;
  
      case 'I':
	channel_model = TDL_C;
409
	DS_TDL = .3;  // 300ns
410 411 412 413
        break;
     
      case 'J':
	channel_model=TDL_D;
414
	DS_TDL = .03;
415 416
	break;

417 418 419 420 421 422 423
      default:
	printf("Unsupported channel model!\n");
	exit(-1);
      }
      
      break;
      
424
    case 'i':
425
      prb_inter=1;
426
      break;
427 428 429 430 431
	
    case 'k':
      printf("Setting threequarter_fs_flag\n");
      openair0_cfg[0].threequarter_fs= 1;
      break;
432

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
    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;
457

Sakthivel Velumani's avatar
Sakthivel Velumani committed
458 459 460 461 462 463 464 465
    case 'u':
      mu = atoi(optarg);
      break;

    case 'w':
      start_rb = atoi(optarg);
      break;

466
/*
467 468 469
    case 't':
      eff_tp_check = (float)atoi(optarg)/100;
      break;
470
*/
471
      /*
472 473 474 475 476 477 478 479 480
	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;
      */
      
481 482 483
      /*case 'x':
        transmission_mode = atoi(optarg);
        break;*/
484 485 486 487 488 489 490 491 492 493 494 495 496 497
      
    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);
      
498
      if ((n_rx == 0) || (n_rx > 8)) {
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
	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;
514 515 516 517 518 519 520 521 522

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

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

523
    case 'M':
Francesco Mani's avatar
Francesco Mani committed
524
     // SSB_positions = atoi(optarg);
525 526 527
      break;
      
    case 'N':
Francesco Mani's avatar
Francesco Mani committed
528
     // Nid_cell = atoi(optarg);
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
      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;
550 551 552

   case 'T':
      enable_ptrs=1;
553 554 555 556 557 558 559 560 561
      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++]);
562 563
      }
      break;
564

565 566 567 568
    case 'Q':
      params_from_file = 1;
      break;

dir's avatar
dir committed
569 570
    case 'Z':

571
      transform_precoding = 0; // enabled
dir's avatar
dir committed
572 573 574 575 576 577 578
      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;

579 580
    default:
    case 'h':
dir's avatar
dir committed
581
      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]);
582 583 584 585 586
      //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");
587
      printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n");
588 589 590 591 592 593
      //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");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
594 595
      printf("-u Set the numerology\n");
      printf("-w Start PRB for PUSCH\n");
596 597 598 599 600 601
      //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");
602
      printf("-G Offset of samples to read from file (0 default)\n");
603 604 605 606
      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");
607
      printf("-t Acceptable effective throughput (in percentage)\n");
608 609
      printf("-S Ending SNR, runs from SNR0 to SNR1\n");
      printf("-P Print ULSCH performances\n");
610
      printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
611
      printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
612
      printf("-Q If -F used, read parameters from file\n");
dir's avatar
dir committed
613
      printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
614 615
      exit(-1);
      break;
616

617 618
    }
  }
619
  
620 621 622 623
  logInit();
  set_glog(loglvl);
  T_stdout = 1;

624
  get_softmodem_params()->phy_test = 1;
625
  get_softmodem_params()->do_ra = 0;
Francesco Mani's avatar
Francesco Mani committed
626 627
  get_softmodem_params()->usim_test = 1;

628

629 630
  if (snr1set == 0)
    snr1 = snr0 + 10;
631 632 633
  double sampling_frequency;
  double bandwidth;

634 635
  if (N_RB_UL >= 217) sampling_frequency = 122.88;
  else if (N_RB_UL >= 106) sampling_frequency = 61.44;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
636
  else if (N_RB_UL >= 32) sampling_frequency = 32.72;
637
  else { printf("Need at least 106 PRBs\b"); exit(-1); }
638 639 640
  if (N_RB_UL == 273) bandwidth = 100;
  else if (N_RB_UL == 217) bandwidth = 80;
  else if (N_RB_UL == 106) bandwidth = 40;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
641
  else if (N_RB_UL == 32) bandwidth = 50;
642 643
  else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
			   
644
  if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
645 646 647 648

  UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
                                sampling_frequency,
                                bandwidth,
649
				DS_TDL,
650
                                0, 0, 0, 0);
651

652
  if (UE2gNB == NULL) {
653
    printf("Problem generating channel model. Exiting.\n");
654 655 656
    exit(-1);
  }

657 658
  UE2gNB->max_Doppler = maxDoppler;

659
  RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
660
  RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
661
  gNB = RC.gNB[0];
662
  gNB->ofdm_offset_divisor = UINT_MAX;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
663 664
  gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
  gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
Sakthi's avatar
Sakthi committed
665
  char tp_param[] = "n";
666
  initTpool(tp_param, gNB->threadPool, false);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
667
  initNotifiedFIFO(gNB->respDecode);
668
  //gNB_config = &gNB->gNB_config;
669

670
  //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
Francesco Mani's avatar
Francesco Mani committed
671 672 673 674
  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;
675
  gNB->prb_interpolation = prb_inter;
676
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
677

678 679 680 681
  frame_parms->N_RB_DL = N_RB_DL;
  frame_parms->N_RB_UL = N_RB_UL;
  frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;

682 683 684 685
  s_re = malloc(n_tx*sizeof(double*));
  s_im = malloc(n_tx*sizeof(double*));
  r_re = malloc(n_rx*sizeof(double*));
  r_im = malloc(n_rx*sizeof(double*));
686

687 688 689 690 691
  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
692
  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
693 694 695
  gNB_RRC_INST rrc;
  memset((void*)&rrc,0,sizeof(rrc));

696 697 698
  rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));

  NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
699
  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
700 701 702 703 704
  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
705 706
  fix_scc(scc,ssb_bitmap);

707 708
  prepare_scd(scd);

709
  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0);
710

711
  // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
712

713 714 715
  /* RRC parameter validation for secondaryCellGroup */
  fix_scd(scd);

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

718 719
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
  // common configuration
720
  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,0, 0, NULL);
721
  // UE dedicated configuration
722
  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
723 724 725 726 727 728
  frame_parms->nb_antennas_tx = n_tx;
  frame_parms->nb_antennas_rx = n_rx;
  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
  cfg->carrier_config.num_tx_ant.value = n_tx;
  cfg->carrier_config.num_rx_ant.value = n_rx;
  nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01);
729
  phy_init_nr_gNB(gNB,0,1);
730
  N_RB_DL = gNB->frame_parms.N_RB_DL;
731

732 733 734

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

735 736 737
  //crcTableInit();

  //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
738 739 740 741


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
742 743 744 745
  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;
746 747 748 749 750 751 752 753 754
  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);
755 756 757
  init_nr_ue_transport(UE, 0);

  /*
laurent's avatar
laurent committed
758
  for (int sf = 0; sf < 2; sf++) {
759 760 761 762 763 764 765 766 767 768
    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);
        }
    }
  }
769
  */
770 771 772 773 774 775 776 777 778 779

  //Configure UE
  NR_UE_RRC_INST_t rrcue;
  memset(&rrcue,0,sizeof(NR_UE_RRC_INST_t));
  rrc.carrier.MIB = (uint8_t*) malloc(4);
  rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0);
  rrcue.mib = rrc.carrier.mib.message.choice.mib;
  rrcue.scell_group_config=secondaryCellGroup;
  nr_l2_init_ue(&rrcue);

780 781 782 783 784 785 786 787 788 789
  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);

790
//  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib, NULL, NULL, secondaryCellGroup);
791 792 793

  nr_ue_phy_config_request(&UE_mac->phy_config);

794

795
  unsigned char harq_pid = 0;
796

797 798
  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;
799 800 801 802 803
  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;

804 805
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

806
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
807

808 809
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
810
  uint32_t errors_decoding   = 0;
811
  
812

813 814
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
815

Ahmed Hussein's avatar
Ahmed Hussein committed
816 817
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
818
  fapi_nr_tx_request_t tx_req;
819 820 821 822 823

  memset(&scheduled_response, 0, sizeof(scheduled_response));
  memset(&ul_config, 0, sizeof(ul_config));
  memset(&tx_req, 0, sizeof(tx_req));

824 825 826 827 828
  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
829
  
830
  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
831
  uint8_t max_rounds = 4;
832
  uint8_t crc_status = 0;
833

dir's avatar
dir committed
834 835
  unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
  uint16_t      code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
836 837 838 839 840

  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

841 842 843 844 845 846
  /* validate parameters othwerwise default values are used */
  /* -U flag can be used to set DMRS parameters*/
  if(modify_dmrs)
  {
    if(dmrs_arg[0] == 0)
    {
847
      mapping_type = typeA;
848 849 850
    }
    else if (dmrs_arg[0] == 1)
    {
851
      mapping_type = typeB;
852 853 854 855 856 857
    }
    /* Additional DMRS positions */
    if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
    {
      add_pos = dmrs_arg[1];
    }
858
  }
859
  printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
860 861

  uint8_t  length_dmrs         = pusch_len1;
862
  uint16_t l_prime_mask        = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs, start_symbol, NR_MIB__dmrs_TypeA_Position_pos2);
863
  uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
864
  printf("num dmrs sym %d\n",number_dmrs_symbols);
865
  uint8_t  nb_re_dmrs          = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
dir's avatar
dir committed
866

867
  // if transform precoding is enabled
868
  if (transform_precoding == 0) {
dir's avatar
dir committed
869 870 871 872 873 874 875 876 877 878 879

    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;

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

880
  nb_re_dmrs   = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
dir's avatar
dir committed
881

882 883 884
  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
885
  
886 887 888 889
  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
890 891 892
  

  
893 894 895 896 897
  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();
898 899
  }

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

904 905
  double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);

906 907 908 909 910 911 912 913 914 915 916 917 918
  /* -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;
919
    printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
920
  }
921

922
  if (input_fd != NULL || n_trials == 1) max_rounds=1;
923

924
  if(1<<ptrs_time_density >= nb_symb_sch)
925
    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
926

927
  printf("\n");
928

929 930 931 932 933 934 935 936 937 938 939
  int frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
  for (int aatx=0; aatx<n_tx; aatx++) {
    s_re[aatx] = calloc(1,frame_length_complex_samples*sizeof(double));
    s_im[aatx] = calloc(1,frame_length_complex_samples*sizeof(double));
  }

  for (int aarx=0; aarx<n_rx; aarx++) {
    r_re[aarx] = calloc(1,frame_length_complex_samples*sizeof(double));
    r_im[aarx] = calloc(1,frame_length_complex_samples*sizeof(double));
  }

Sakthivel Velumani's avatar
Sakthivel Velumani committed
940
  //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
941
  snrRun = 0;
942
  int n_errs = 0;
943
  int read_errors=0;
944

945
  int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
946 947 948 949 950 951 952
  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);
  
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
    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);
981 982 983 984
    if (read_errors==0) {
      printf("error reading file\n");
      exit(1);
    }
985 986 987 988
    for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
				   slot_offset,
				   ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
				   ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
Raymond Knopp's avatar
Raymond Knopp committed
989

990 991
    mod_order = nr_get_Qm_ul(Imcs, mcs_table);
    code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
992 993
  }
  
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
  uint32_t errors_scrambling[4][100];
  int n_errors[4][100];
  int round_trials[4][100];
  double blerStats[4][100];
  double berStats[4][100];
  double snrStats[100];
  memset(errors_scrambling, 0, sizeof(uint32_t)*4*100);
  memset(n_errors, 0, sizeof(int)*4*100);
  memset(round_trials, 0, sizeof(int)*4*100);
  memset(blerStats, 0, sizeof(double)*4*100);
  memset(berStats, 0, sizeof(double)*4*100);
  memset(snrStats, 0, sizeof(double)*100);
1006
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1007
    varArray_t *table_rx=initVarArray(1000,sizeof(double));
1008 1009
    int error_flag = 0;
    n_false_positive = 0;
1010 1011
    effRate[snrRun] = 0;
    effTP[snrRun] = 0;
Sakthivel Velumani's avatar
fixes  
Sakthivel Velumani committed
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
    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);
1023 1024 1025 1026
    reset_meas(&UE->ulsch_ldpc_encoding_stats);
    reset_meas(&UE->ulsch_rate_matching_stats);
    reset_meas(&UE->ulsch_interleaving_stats);
    reset_meas(&UE->ulsch_encoding_stats);
1027

Raymond Knopp's avatar
Raymond Knopp committed
1028
    clear_pusch_stats(gNB);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1029 1030 1031
    for (trial = 0; trial < n_trials; trial++) {
    uint8_t round = 0;

1032 1033
    crc_status = 1;
    errors_decoding    = 0;
1034
    memset((void*)roundStats,0,50*sizeof(roundStats[0]));
1035
    while (round<max_rounds && crc_status) {
1036
      round_trials[round][snrRun]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1037 1038
      ulsch_ue[0]->harq_processes[harq_pid]->round = round;
      gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
1039
      rv_index = nr_rv_round_map[round];
1040

1041 1042
      UE_proc.thread_id = 0;
      UE_proc.nr_slot_tx = slot;
1043 1044
      UE_proc.frame_tx = frame;

1045 1046
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
1047 1048 1049 1050
      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));
1051
      
1052 1053
      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
1054
      int ibwp_size  = ibwps;
1055 1056 1057 1058 1059 1060 1061
      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;
1062
	start_rb = (ibwp_start - abwp_start);
1063 1064 1065 1066 1067 1068 1069 1070
	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;
      }

1071
      pusch_pdu->pusch_data.tb_size = TBS/8;
1072
      pusch_pdu->pdu_bit_map = pdu_bit_map;
1073 1074
      pusch_pdu->rnti = n_rnti;
      pusch_pdu->mcs_index = Imcs;
1075
      pusch_pdu->mcs_table = mcs_table;
1076 1077
      pusch_pdu->target_code_rate = code_rate;
      pusch_pdu->qam_mod_order = mod_order;
dir's avatar
dir committed
1078
      pusch_pdu->transform_precoding = transform_precoding;
1079
      pusch_pdu->data_scrambling_id = *scc->physCellId;
1080
      pusch_pdu->nrOfLayers = 1;
1081
      pusch_pdu->ul_dmrs_symb_pos = l_prime_mask;
1082
      pusch_pdu->dmrs_config_type = dmrs_config_type;
1083
      pusch_pdu->ul_dmrs_scrambling_id =  *scc->physCellId;
1084
      pusch_pdu->scid = 0;
1085
      pusch_pdu->dmrs_ports = 1;
1086
      pusch_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
1087 1088 1089 1090 1091 1092 1093 1094
      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
1095
      pusch_pdu->pusch_data.rv_index = rv_index;
1096
      pusch_pdu->pusch_data.harq_process_id = 0;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1097
      pusch_pdu->pusch_data.new_data_indicator = trial & 0x1;
1098
      pusch_pdu->pusch_data.num_cb = 0;
1099 1100
      pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
      pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
1101 1102
      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;
1103

1104
      // if transform precoding is enabled
1105
      if (transform_precoding == 0) {
dir's avatar
dir committed
1106 1107 1108 1109 1110 1111

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

1112 1113
      // prepare ULSCH/PUSCH reception
      nr_schedule_response(Sched_INFO);
1114

1115
      // --------- setting parameters for UE --------
1116 1117 1118 1119 1120

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
1121
      scheduled_response.thread_id = UE_proc.thread_id;
1122 1123
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
1124
      scheduled_response.tx_request = &tx_req;
1125
      
1126 1127 1128 1129 1130
      // Config UL TX PDU
      tx_req.slot = slot;
      tx_req.sfn = frame;
      // tx_req->tx_config // TbD
      tx_req.number_of_pdus = 1;
1131 1132 1133
      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];
1134

1135
      ul_config.slot = slot;
1136 1137
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
1138
      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
1139
      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
1140
      ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
1141 1142 1143 1144
      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;
1145
      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask;
1146
      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
1147
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
1148
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
1149
      ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
1150 1151 1152
      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;

1153
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1154 1155
      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;
1156
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
1157

1158 1159
      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;
1160 1161
      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;
1162

dir's avatar
dir committed
1163 1164
      ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;

1165
      // if transform precoding is enabled
1166
      if (transform_precoding == 0) {
dir's avatar
dir committed
1167 1168 1169 1170 1171 1172 1173 1174 1175
   
        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;

      }


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

1178
      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
1179
      if (input_fd == NULL) {
1180

1181 1182 1183 1184 1185 1186 1187 1188 1189
        // 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);

1190 1191 1192 1193 1194
        /* We need to call common sending function to send signal */
        LOG_D(PHY, "Sending Uplink data \n");
        nr_ue_pusch_common_procedures(UE,
                                      slot,
                                      &UE->frame_parms,1);
1195 1196 1197 1198 1199 1200 1201

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

1204
        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],
1205
                              frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
1206 1207
      }	
      else n_trials = 1;
1208

1209
      if (input_fd == NULL ) {
1210

1211 1212
        sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
        sigma    = pow(10,sigma_dB/10);
1213 1214


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

1218
        for (i=0; i<slot_length; i++) {
1219
          for (int aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
1220 1221 1222 1223
            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]);
          }
        }
1224

1225

1226 1227 1228 1229 1230 1231 1232 1233 1234
        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)));
1235 1236 1237 1238 1239
            /* 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]);
            }
1240 1241
          }
        }
1242

1243
      } /*End input_fd */
1244

1245 1246

      if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
1247 1248 1249 1250 1251 1252 1253
        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);
1254
        printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
1255
      }
1256 1257 1258 1259 1260 1261 1262
	////////////////////////////////////////////////////////////
	
	//----------------------------------------------------------
	//------------------- gNB phy procedures -------------------
	//----------------------------------------------------------
	gNB->UL_INFO.rx_ind.number_of_pdus = 0;
	gNB->UL_INFO.crc_ind.number_crcs = 0;
1263

Ahmed Hussein's avatar
Ahmed Hussein committed
1264
        phy_procedures_gNB_common_RX(gNB, frame, slot);
1265

1266
        ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);
1267

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

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

1273
	}
1274 1275


1276
	if (n_trials == 1  && round==0) {
1277 1278 1279 1280 1281 1282
#ifdef __AVX2__
	  int off = ((nb_rb&1) == 1)? 4:0;
#else
	  int off = 0;
#endif

1283
	  LOG_M("rxsigF0_ext.m","rxsF0_ext",
1284
		&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);
1285 1286
	  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);
1287 1288
	  LOG_M("chestT0.m","chT0",
		&gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1);
1289
	  LOG_M("chestF0_ext.m","chF0_ext",
1290 1291
		&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);
1292
	  LOG_M("rxsigF0_comp.m","rxsF0_comp",
1293
		&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);
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
    LOG_M("chmagF0.m","chmF0",
    &gNB->pusch_vars[0]->ul_ch_mag[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);
    LOG_M("chmagbF0.m","chmbF0",
    &gNB->pusch_vars[0]->ul_ch_magb[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);
    if (n_rx == 2) {
      LOG_MM("rxsigF0_comp.m","rxsF1_comp",
      &gNB->pusch_vars[0]->rxdataF_comp[1][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);
      LOG_MM("rxsigF0_ext.m","rxsF1_ext",
      &gNB->pusch_vars[0]->rxdataF_ext[1][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);
      LOG_MM("chestF0_ext.m","chF1_ext",
      &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(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);
      LOG_MM("chmagF0.m","chmF1",
      &gNB->pusch_vars[0]->ul_ch_mag[1][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);
      LOG_MM("chmagbF0.m","chmbF1",
      &gNB->pusch_vars[0]->ul_ch_magb[1][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);
    } else if (n_rx == 4) {
      LOG_MM("rxsigF0_comp.m","rxsF1_comp",
      &gNB->pusch_vars[0]->rxdataF_comp[1][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);
      LOG_MM("rxsigF0_comp.m","rxsF2_comp",
      &gNB->pusch_vars[0]->rxdataF_comp[2][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);
      LOG_MM("rxsigF0_comp.m","rxsF3_comp",
      &gNB->pusch_vars[0]->rxdataF_comp[3][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);
      LOG_MM("rxsigF0_ext.m","rxsF1_ext",
      &gNB->pusch_vars[0]->rxdataF_ext[1][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);
      LOG_MM("rxsigF0_ext.m","rxsF2_ext",
      &gNB->pusch_vars[0]->rxdataF_ext[2][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);
      LOG_MM("rxsigF0_ext.m","rxsF3_ext",
      &gNB->pusch_vars[0]->rxdataF_ext[3][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);
      LOG_MM("chestF0_ext.m","chF1_ext",
      &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(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);
      LOG_MM("chestF0_ext.m","chF2_ext",
      &gNB->pusch_vars[0]->ul_ch_estimates_ext[2][(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);
      LOG_MM("chestF0_ext.m","chF3_ext",
      &gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(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);
      LOG_MM("chmagF0.m","chmF1",
      &gNB->pusch_vars[0]->ul_ch_mag[1][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);
      LOG_MM("chmagF0.m","chmF2",
      &gNB->pusch_vars[0]->ul_ch_mag[2][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);
      LOG_MM("chmagF0.m","chmF3",
      &gNB->pusch_vars[0]->ul_ch_mag[3][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);
      LOG_MM("chmagbF0.m","chmbF1",
      &gNB->pusch_vars[0]->ul_ch_magb[1][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);
      LOG_MM("chmagbF0.m","chmbF2",
      &gNB->pusch_vars[0]->ul_ch_magb[2][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);
      LOG_MM("chmagbF0.m","chmbF3",
      &gNB->pusch_vars[0]->ul_ch_magb[3][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);
    }

1346 1347
	  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);
1348
	}
1349
        ////////////////////////////////////////////////////////////
1350

1351
	if ((gNB->ulsch[0][0]->last_iteration_cnt >=
1352
	    gNB->ulsch[0][0]->max_ldpc_iterations+1) || ul_proc_error == 1) {
1353
	  error_flag = 1; 
1354
	  n_errors[round][snrRun]++;
1355
	  crc_status = 1;
1356
	} else {
1357
	  crc_status = 0;
1358
	}
1359 1360
	if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);

Ahmed Hussein's avatar
Ahmed Hussein committed
1361
        //----------------------------------------------------------
1362
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
1363
        //----------------------------------------------------------
1364

1365
        if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
1366
            ptrs_symbols = 0;
1367 1368 1369 1370
            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 */
1371
            available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
1372
            printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
1373 1374
        }

1375 1376 1377 1378 1379
	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)))
	    {
1380 1381 1382
	      /*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][snrRun]++;
1383 1384
	    }
	}
1385 1386
	round++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1387
    } // round
1388
    
1389 1390 1391 1392
    if (n_trials == 1 && errors_scrambling[0][snrRun] > 0) {
      printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0][snrRun]);
    }
    
1393 1394 1395 1396 1397 1398 1399 1400 1401
    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++;
1402
      }
1403 1404 1405
    }
    if (n_trials == 1) {
      for (int r=0;r<ulsch_ue[0]->harq_processes[harq_pid]->C;r++) 
1406
	for (int i=0;i<ulsch_ue[0]->harq_processes[harq_pid]->K>>3;i++) {
1407
	  if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
1408
	    /*printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
1409 1410
	    i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i],
	    i,ulsch_gNB->harq_processes[harq_pid]->c[r][i],
1411
	    ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);*/
1412
	}
1413 1414 1415 1416 1417 1418 1419
    }
    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);
1420
    if (!crc_status) effRate[snrRun] += ((double)TBS)/(double)round;
1421 1422 1423
    } // trial loop
    
    roundStats[snrRun]/=((float)n_trials);
1424
    effRate[snrRun] /= (double)n_trials;
1425 1426
    
    printf("*****************************************\n");
1427
    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][snrRun], round_trials[0][snrRun],n_errors[1][snrRun], round_trials[1][snrRun],n_errors[2][snrRun], round_trials[2][snrRun],n_errors[3][snrRun], round_trials[3][snrRun], n_false_positive, n_trials, errors_scrambling[0][snrRun],available_bits*n_trials,errors_scrambling[1][snrRun],available_bits*n_trials,errors_scrambling[2][snrRun],available_bits*n_trials,errors_scrambling[3][snrRun],available_bits*n_trials);
1428
    printf("\n");
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
    blerStats[0][snrRun] = (double)n_errors[0][snrRun]/round_trials[0][snrRun];
    blerStats[1][snrRun] = (double)n_errors[1][snrRun]/round_trials[1][snrRun];
    blerStats[2][snrRun] = (double)n_errors[2][snrRun]/round_trials[2][snrRun];
    blerStats[3][snrRun] = (double)n_errors[3][snrRun]/round_trials[3][snrRun];

    berStats[0][snrRun] = (double)errors_scrambling[0][snrRun]/available_bits/round_trials[0][snrRun];
    berStats[1][snrRun] = (double)errors_scrambling[1][snrRun]/available_bits/round_trials[1][snrRun];
    berStats[2][snrRun] = (double)errors_scrambling[2][snrRun]/available_bits/round_trials[2][snrRun];
    berStats[3][snrRun] = (double)errors_scrambling[3][snrRun]/available_bits/round_trials[3][snrRun];
    effTP[snrRun] = effRate[snrRun]/(double)TBS*(double)100;
Raphael Defosseux's avatar
Raphael Defosseux committed
1439
    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", 
1440
	   SNR,
1441 1442 1443 1444 1445 1446 1447 1448 1449
     blerStats[0][snrRun],
     blerStats[1][snrRun],
     blerStats[2][snrRun],
     blerStats[3][snrRun],
     berStats[0][snrRun],
     berStats[1][snrRun],
     berStats[2][snrRun],
     berStats[3][snrRun],
	   roundStats[snrRun],effRate[snrRun],effTP[snrRun],TBS);
Raymond Knopp's avatar
Raymond Knopp committed
1450

rmagueta's avatar
rmagueta committed
1451 1452
    FILE *fd=fopen("nr_ulsim.log","w");
    dump_pusch_stats(fd,gNB);
Raymond Knopp's avatar
Raymond Knopp committed
1453

1454 1455 1456 1457 1458
    printf("*****************************************\n");
    printf("\n");
    
    if (print_perf==1) {
      printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
1459 1460
      printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
      printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
1461
      printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
1462 1463
      printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
      printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
1464
      printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
1465
      printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
1466 1467
      printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
      printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
1468 1469 1470 1471 1472
      printStatIndent(&UE->ulsch_encoding_stats,"ULSCH total encoding time");
      printStatIndent2(&UE->ulsch_segmentation_stats,"ULSCH segmentation time");
      printStatIndent2(&UE->ulsch_ldpc_encoding_stats,"ULSCH LDPC encoder time");
      printStatIndent2(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time");
      printStatIndent2(&UE->ulsch_interleaving_stats,"ULSCH interleaving time");
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1473 1474 1475
      //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");
1476
      printf("\n");
1477
    }
1478

1479 1480
    if(n_trials==1)
      break;
1481

1482
    if ((float)n_errors[0][snrRun]/(float)n_trials <= target_error_rate) {
1483 1484 1485
      printf("*************\n");
      printf("PUSCH test OK\n");
      printf("*************\n");
rmagueta's avatar
rmagueta committed
1486
      break;
1487
    }
1488

1489
    snrStats[snrRun] = SNR;
1490
    snrRun++;
1491
    n_errs = n_errors[0][snrRun];
1492
  } // SNR loop
Ahmed Hussein's avatar
Ahmed Hussein committed
1493
  printf("\n");
1494

1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
  printf( "Num RB:\t%d\n"
          "Num symbols:\t%d\n"
          "MCS:\t%d\n"
          "DMRS config type:\t%d\n"
          "DMRS add pos:\t%d\n"
          "PUSCH mapping type:\t%d\n"
          "DMRS length:\t%d\n"
          "DMRS CDM gr w/o data:\t%d\n",
          nb_rb,
          nb_symb_sch,
          Imcs,
          dmrs_config_type,
          add_pos,
          mapping_type,
          length_dmrs,
          num_dmrs_cdm_grps_no_data);
              
  LOG_M("ulsimStats.m","SNR",snrStats,snrRun,1,7);
  LOG_MM("ulsimStats.m","BLER_round0",blerStats[0],snrRun,1,7);
  LOG_MM("ulsimStats.m","BLER_round1",blerStats[1],snrRun,1,7);
  LOG_MM("ulsimStats.m","BLER_round2",blerStats[2],snrRun,1,7);
  LOG_MM("ulsimStats.m","BLER_round3",blerStats[3],snrRun,1,7);
  LOG_MM("ulsimStats.m","BER_round0",berStats[0],snrRun,1,7);
  LOG_MM("ulsimStats.m","BER_round1",berStats[1],snrRun,1,7);
  LOG_MM("ulsimStats.m","BER_round2",berStats[2],snrRun,1,7);
  LOG_MM("ulsimStats.m","BER_round3",berStats[3],snrRun,1,7);
  LOG_MM("ulsimStats.m","EffRate",effRate,snrRun,1,7);
  LOG_MM("ulsimStats.m","EffTP",effTP,snrRun,1,7);
Ahmed Hussein's avatar
Ahmed Hussein committed
1523 1524 1525
  free(test_input_bit);
  free(estimated_output_bit);

1526 1527 1528 1529 1530 1531
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1532 1533 1534
  if (scg_fd)
    fclose(scg_fd);

1535
  return (n_errs);
1536
}