ulsim.c 58.7 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
dir's avatar
dir committed
311 312 313
  uint8_t num_dmrs_cdm_grps_no_data = 1;
  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);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
668 669 670 671 672
  gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  initNotifiedFIFO(gNB->resp_L1_tx);
  notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->resp_L1_tx,NULL);
  processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
  msgDataTx->slot = -1;
Laurent THOMAS's avatar
Laurent THOMAS committed
673
  gNB->phy_proc_tx[0] = &msgDataTx->phy_proc_tx;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
674
  pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
675
  //gNB_config = &gNB->gNB_config;
676

677
  //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
Francesco Mani's avatar
Francesco Mani committed
678 679 680 681
  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;
682
  gNB->prb_interpolation = prb_inter;
683
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
684

685 686 687 688
  frame_parms->N_RB_DL = N_RB_DL;
  frame_parms->N_RB_UL = N_RB_UL;
  frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;

689 690 691 692
  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*));
693

694 695 696 697 698
  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
699
  //gNB_MAC_INST* gNB_mac = RC.nrmac[0];
700 701 702
  gNB_RRC_INST rrc;
  memset((void*)&rrc,0,sizeof(rrc));

703 704 705
  rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));

  NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
706
  NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
707 708 709 710 711
  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
712 713
  fix_scc(scc,ssb_bitmap);

714 715
  prepare_scd(scd);

francescomani's avatar
francescomani committed
716
  fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, 0, 1, n_tx, 0, 0, 0, 0);
717

718
  // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
719

720 721 722
  /* RRC parameter validation for secondaryCellGroup */
  fix_scd(scd);

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

725 726
  gNB->if_inst->NR_PHY_config_req      = nr_phy_config_request;
  // common configuration
727
  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,0, 0, NULL);
728
  // UE dedicated configuration
729
  rrc_mac_config_req_gNB(0,0, n_tx, n_rx, 0, scc, &rrc.carrier.mib,1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
730 731 732 733 734 735
  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);
736
  phy_init_nr_gNB(gNB,0,1);
737
  N_RB_DL = gNB->frame_parms.N_RB_DL;
738

739 740 741

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

742 743 744
  //crcTableInit();

  //nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
745 746 747 748


  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
749 750 751 752
  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;
753 754 755 756 757 758 759 760 761
  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);
762 763 764
  init_nr_ue_transport(UE, 0);

  /*
laurent's avatar
laurent committed
765
  for (int sf = 0; sf < 2; sf++) {
766 767 768 769 770 771 772 773 774 775
    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);
        }
    }
  }
776
  */
777 778 779 780 781 782 783 784 785 786

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

787 788 789 790 791 792 793 794 795 796
  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);

797
//  nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib, NULL, NULL, secondaryCellGroup);
798 799 800

  nr_ue_phy_config_request(&UE_mac->phy_config);

801

802
  unsigned char harq_pid = 0;
803

804 805
  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;
806 807 808 809 810
  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;

811 812
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

813
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
814

815 816
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
817
  uint32_t errors_decoding   = 0;
818
  
819

820 821
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
822

Ahmed Hussein's avatar
Ahmed Hussein committed
823 824
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
825
  fapi_nr_tx_request_t tx_req;
826 827 828 829 830

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

831 832 833 834 835
  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
836
  
837
  uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
838
  uint8_t max_rounds = 4;
839
  uint8_t crc_status = 0;
840

dir's avatar
dir committed
841 842
  unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table);
  uint16_t      code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
843 844 845 846 847

  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

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

  uint8_t  length_dmrs         = pusch_len1;
869
  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);
870
  uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
871
  printf("num dmrs sym %d\n",number_dmrs_symbols);
872
  uint8_t  nb_re_dmrs          = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
dir's avatar
dir committed
873

874
  // if transform precoding is enabled
875
  if (transform_precoding == 0) {
dir's avatar
dir committed
876 877 878 879 880 881 882 883 884 885 886

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

887
  nb_re_dmrs   = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
dir's avatar
dir committed
888

889 890 891
  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
892
  
893 894 895 896
  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
897 898 899
  

  
900 901 902 903 904
  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();
905 906
  }

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

911 912
  double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);

913 914 915 916 917 918 919 920 921 922 923 924 925
  /* -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;
926
    printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
927
  }
928

929
  if (input_fd != NULL || n_trials == 1) max_rounds=1;
930

931
  if(1<<ptrs_time_density >= nb_symb_sch)
932
    pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
933

934
  printf("\n");
935

936 937 938 939 940 941 942 943 944 945 946
  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
947
  //for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
948
  snrRun = 0;
949
  int n_errs = 0;
950
  int read_errors=0;
951

952
  int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
953 954 955 956 957 958 959
  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);
  
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
    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);
988 989 990 991
    if (read_errors==0) {
      printf("error reading file\n");
      exit(1);
    }
992 993 994 995
    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
996

997 998
    mod_order = nr_get_Qm_ul(Imcs, mcs_table);
    code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
999 1000
  }
  
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
  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);
1013
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1014
    varArray_t *table_rx=initVarArray(1000,sizeof(double));
1015 1016
    int error_flag = 0;
    n_false_positive = 0;
1017 1018
    effRate[snrRun] = 0;
    effTP[snrRun] = 0;
Sakthivel Velumani's avatar
fixes  
Sakthivel Velumani committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
    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);
1030 1031 1032 1033
    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);
1034

Raymond Knopp's avatar
Raymond Knopp committed
1035
    clear_pusch_stats(gNB);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1036 1037 1038
    for (trial = 0; trial < n_trials; trial++) {
    uint8_t round = 0;

1039 1040
    crc_status = 1;
    errors_decoding    = 0;
1041
    memset((void*)roundStats,0,50*sizeof(roundStats[0]));
1042
    while (round<max_rounds && crc_status) {
1043
      round_trials[round][snrRun]++;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1044 1045
      ulsch_ue[0]->harq_processes[harq_pid]->round = round;
      gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
1046
      rv_index = nr_rv_round_map[round];
1047

1048 1049
      UE_proc.thread_id = 0;
      UE_proc.nr_slot_tx = slot;
1050 1051
      UE_proc.frame_tx = frame;

1052 1053
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
1054 1055 1056 1057
      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));
1058
      
1059 1060
      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
1061
      int ibwp_size  = ibwps;
1062 1063 1064 1065 1066 1067 1068
      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;
1069
	start_rb = (ibwp_start - abwp_start);
1070 1071 1072 1073 1074 1075 1076 1077
	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;
      }

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

1111
      // if transform precoding is enabled
1112
      if (transform_precoding == 0) {
dir's avatar
dir committed
1113 1114 1115 1116 1117 1118

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

1119 1120
      // prepare ULSCH/PUSCH reception
      nr_schedule_response(Sched_INFO);
1121

1122
      // --------- setting parameters for UE --------
1123 1124 1125 1126 1127

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
1128
      scheduled_response.thread_id = UE_proc.thread_id;
1129 1130
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
1131
      scheduled_response.tx_request = &tx_req;
1132
      
1133 1134 1135 1136 1137
      // Config UL TX PDU
      tx_req.slot = slot;
      tx_req.sfn = frame;
      // tx_req->tx_config // TbD
      tx_req.number_of_pdus = 1;
1138 1139 1140
      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];
1141

1142
      ul_config.slot = slot;
1143 1144
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
1145
      ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
1146
      ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
1147
      ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
1148 1149 1150 1151
      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;
1152
      ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask;
1153
      ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
1154
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
1155
      ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
1156
      ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
1157 1158 1159
      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;

1160
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1161 1162
      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;
1163
      ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
1164

1165 1166
      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;
1167 1168
      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;
1169

dir's avatar
dir committed
1170 1171
      ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;

1172
      // if transform precoding is enabled
1173
      if (transform_precoding == 0) {
dir's avatar
dir committed
1174 1175 1176 1177 1178 1179 1180 1181 1182
   
        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;

      }


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

1185
      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
1186
      if (input_fd == NULL) {
1187

1188 1189 1190 1191 1192 1193 1194 1195 1196
        // 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);

1197 1198 1199 1200 1201
        /* 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);
1202 1203 1204 1205 1206 1207 1208

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

1211
        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],
1212
                              frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
1213 1214
      }	
      else n_trials = 1;
1215

1216
      if (input_fd == NULL ) {
1217

1218 1219
        sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
        sigma    = pow(10,sigma_dB/10);
1220 1221


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

1225
        for (i=0; i<slot_length; i++) {
1226
          for (int aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
1227 1228 1229 1230
            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]);
          }
        }
1231

1232

1233 1234 1235 1236 1237 1238 1239 1240 1241
        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)));
1242 1243 1244 1245 1246
            /* 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]);
            }
1247 1248
          }
        }
1249

1250
      } /*End input_fd */
1251

1252 1253

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

Ahmed Hussein's avatar
Ahmed Hussein committed
1271
        phy_procedures_gNB_common_RX(gNB, frame, slot);
1272

1273
        ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);
1274

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

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

1280
	}
1281 1282


1283
	if (n_trials == 1  && round==0) {
1284 1285 1286 1287 1288 1289
#ifdef __AVX2__
	  int off = ((nb_rb&1) == 1)? 4:0;
#else
	  int off = 0;
#endif

1290
	  LOG_M("rxsigF0_ext.m","rxsF0_ext",
1291
		&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);
1292 1293
	  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);
1294 1295
	  LOG_M("chestT0.m","chT0",
		&gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1);
1296
	  LOG_M("chestF0_ext.m","chF0_ext",
1297 1298
		&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);
1299
	  LOG_M("rxsigF0_comp.m","rxsF0_comp",
1300
		&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);
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 1346 1347 1348 1349 1350 1351 1352
    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);
    }

1353 1354
	  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);
1355
	}
1356
        ////////////////////////////////////////////////////////////
1357

1358
	if ((gNB->ulsch[0][0]->last_iteration_cnt >=
1359
	    gNB->ulsch[0][0]->max_ldpc_iterations+1) || ul_proc_error == 1) {
1360
	  error_flag = 1; 
1361
	  n_errors[round][snrRun]++;
1362
	  crc_status = 1;
1363
	} else {
1364
	  crc_status = 0;
1365
	}
1366 1367
	if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);

Ahmed Hussein's avatar
Ahmed Hussein committed
1368
        //----------------------------------------------------------
1369
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
1370
        //----------------------------------------------------------
1371

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

1382 1383 1384 1385 1386 1387 1388
	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);*/
1389
	      errors_scrambling[round][snrRun]++;
1390 1391
	    }
	}
1392 1393
	round++;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
1394
    } // round
1395
    
1396 1397
    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]);
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
    }
    
    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++;
1409
      }
1410 1411 1412 1413
    }
    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++) {
1414
	  if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
1415
	    /*printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
1416 1417 1418
	    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]);*/
1419
	}
1420 1421 1422 1423 1424 1425 1426
    }
    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);
1427
    if (!crc_status) effRate[snrRun] += ((double)TBS)/(double)round;
1428 1429 1430
    } // trial loop
    
    roundStats[snrRun]/=((float)n_trials);
1431
    effRate[snrRun] /= (double)n_trials;
1432 1433
    
    printf("*****************************************\n");
1434
    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);
1435
    printf("\n");
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
    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
1446
    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", 
1447
	   SNR,
1448 1449 1450 1451 1452 1453 1454 1455 1456
     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
1457

rmagueta's avatar
rmagueta committed
1458 1459
    FILE *fd=fopen("nr_ulsim.log","w");
    dump_pusch_stats(fd,gNB);
Raymond Knopp's avatar
Raymond Knopp committed
1460

1461 1462 1463 1464 1465
    printf("*****************************************\n");
    printf("\n");
    
    if (print_perf==1) {
      printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
1466 1467
      printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
      printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
1468
      printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
1469 1470
      printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
      printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
1471
      printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
1472
      printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
1473 1474
      printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
      printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
1475 1476 1477 1478 1479
      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
1480 1481 1482
      //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");
1483
      printf("\n");
1484
    }
1485

1486 1487
    if(n_trials==1)
      break;
1488

1489
    if ((float)n_errors[0][snrRun]/(float)n_trials <= target_error_rate) {
1490 1491 1492 1493 1494
      printf("*************\n");
      printf("PUSCH test OK\n");
      printf("*************\n");
      break;
    }
1495

1496
    snrStats[snrRun] = SNR;
1497
    snrRun++;
1498
    n_errs = n_errors[0][snrRun];
1499
  } // SNR loop
Ahmed Hussein's avatar
Ahmed Hussein committed
1500
  printf("\n");
1501

1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
  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
1530 1531 1532
  free(test_input_bit);
  free(estimated_output_bit);

1533 1534 1535 1536 1537 1538
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

1539 1540 1541
  if (scg_fd)
    fclose(scg_fd);

1542
  return (n_errs);
1543
}