ulsim.c 23.6 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 41
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_REFSIG/dmrs_nr.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
42
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
43 44 45
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
46 47
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
48
#include "PHY/TOOLS/tools_defs.h"
49
#include "SCHED_NR/sched_nr.h"
50
#include "SCHED_NR_UE/defs.h"
51
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
52 53 54 55 56
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
57
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
58

59
//#define DEBUG_ULSIM
60

61 62 63
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
64 65
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];

66 67
double cpuf;
int nfapi_mode = 0;
yilmazt's avatar
yilmazt committed
68
uint16_t NB_UE_INST = 1;
69

70 71
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
                              const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
void mac_rlc_data_ind ( const module_id_t         module_idP,
			const rnti_t              rntiP,
			const eNB_index_t         eNB_index,
			const frame_t             frameP,
			const eNB_flag_t          enb_flagP,
			const MBMS_flag_t         MBMS_flagP,
			const logical_chan_id_t   channel_idP,
			char                     *buffer_pP,
			const tb_size_t           tb_sizeP,
			num_tb_t                  num_tbP,
			crc_t                    *crcs_pP){}
mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t       module_idP,
					  const rnti_t            rntiP,
					  const eNB_index_t       eNB_index,
					  const frame_t           frameP,
					  const sub_frame_t 	  subframeP,
					  const eNB_flag_t        enb_flagP,
					  const MBMS_flag_t       MBMS_flagP,
					  const logical_chan_id_t channel_idP,
					  const tb_size_t         tb_sizeP,
					  const uint32_t sourceL2Id,
					  const uint32_t destinationL2Id)
{mac_rlc_status_resp_t  mac_rlc_status_resp; return mac_rlc_status_resp;}
tbs_size_t mac_rlc_data_req(  const module_id_t       module_idP,
			      const rnti_t            rntiP,
			      const eNB_index_t       eNB_index,
			      const frame_t           frameP,
			      const eNB_flag_t        enb_flagP,
			      const MBMS_flag_t       MBMS_flagP,
			      const logical_chan_id_t channel_idP,
			      const tb_size_t         tb_sizeP,
			      char             *buffer_pP,
			      const uint32_t sourceL2Id,
			      const uint32_t destinationL2Id )
{return 0;}
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;}
116
uint64_t get_softmodem_optmask(void) {return 0;}
117
int rlc_module_init (int enb) {return(0);}
118 119
void pdcp_layer_init (void) {}
void nr_ip_over_LTE_DRB_preconfiguration(void){}
120

121 122 123 124
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];

125 126
int main(int argc, char **argv)
{
127
  char c;
128
  int i,sf;
129 130
  double SNR, snr0 = -2.0, snr1 = 2.0;
  double sigma, sigma_dB;
131 132
  double snr_step = 0.1;
  uint8_t snr1set = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
133
  int slot = 0;
134 135
  FILE *output_fd = NULL;
  //uint8_t write_output_file = 0;
136
  int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
137
  uint8_t n_tx = 1, n_rx = 1;
138 139 140 141 142
  //uint8_t transmission_mode = 1;
  uint16_t Nid_cell = 0;
  channel_desc_t *gNB2UE;
  uint8_t extended_prefix_flag = 0;
  //int8_t interf1 = -21, interf2 = -21;
143
  FILE *input_fd = NULL;
144
  SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
145
  uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
146
  //unsigned char frame_type = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
147
  int number_of_frames = 1;
laurent's avatar
laurent committed
148
  int frame_length_complex_samples;
149 150 151 152
  NR_DL_FRAME_PARMS *frame_parms;
  int loglvl = OAILOG_WARNING;
  uint64_t SSB_positions=0x01;
  uint16_t nb_symb_sch = 12;
153
  int start_symbol = NR_SYMBOLS_PER_SLOT - nb_symb_sch;
154 155
  uint16_t nb_rb = 50;
  uint8_t Imcs = 9;
156
  uint8_t precod_nbr_layers = 1;
157
  int gNB_id = 0;
Khalid Ahmed's avatar
Khalid Ahmed committed
158
  int ap;
Khalid Ahmed's avatar
Khalid Ahmed committed
159
  int tx_offset;
Khalid Ahmed's avatar
Khalid Ahmed committed
160 161
  double txlev_float;
  int32_t txlev;
Ahmed Hussein's avatar
Ahmed Hussein committed
162
  int start_rb = 0;
163 164
  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)

165 166
  cpuf = get_cpu_freq_GHz();

167

168
  UE_nr_rxtx_proc_t UE_proc;
169 170


yilmazt's avatar
yilmazt committed
171
  if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
yilmazt's avatar
yilmazt committed
172
    exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
173 174 175 176 177
  }

  //logInit();
  randominit(0);

178
  while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:L:")) != -1) {
179
    switch (c) {
180 181 182 183 184 185 186 187 188 189 190 191 192

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

      case 'd':
        delay = atoi(optarg);
        break;

      case 'f':
        number_of_frames = atoi(optarg);
        break;

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
      /*case 'f':
         write_output_file = 1;
         output_fd = fopen(optarg, "w");

         if (output_fd == NULL) {
             printf("Error opening %s\n", optarg);
             exit(-1);
         }

         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;

          default:
235
            printf("Unsupported channel model!\n");
236 237 238 239 240 241 242 243 244 245 246 247 248
            exit(-1);
        }

        break;

      /*case 'i':
        interf1 = atoi(optarg);
        break;

      case 'j':
        interf2 = atoi(optarg);
        break;*/

249 250
      case 'l':
        nb_symb_sch = atoi(optarg);
251 252
        break;

253 254
      case 'm':
        Imcs = atoi(optarg);
255 256
        break;

257 258
      case 'n':
        n_trials = atoi(optarg);
259 260 261 262 263 264
        break;

      case 'p':
        extended_prefix_flag = 1;
        break;

265 266 267 268 269 270 271 272 273
      case 'r':
        nb_rb = atoi(optarg);
        break;

      case 's':
        snr0 = atof(optarg);
        printf("Setting SNR0 to %f\n", snr0);
        break;

274 275 276 277 278 279 280 281 282 283
      /*
       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;
       */

284 285 286 287
      /*case 'x':
        transmission_mode = atoi(optarg);
        break;*/

288 289 290 291
      case 'y':
        n_tx = atoi(optarg);

        if ((n_tx == 0) || (n_tx > 2)) {
292
          printf("Unsupported number of tx antennas %d\n", n_tx);
293 294 295 296 297 298 299 300 301
          exit(-1);
        }

        break;

      case 'z':
        n_rx = atoi(optarg);

        if ((n_rx == 0) || (n_rx > 2)) {
302
          printf("Unsupported number of rx antennas %d\n", n_rx);
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
          exit(-1);
        }

        break;

      case 'F':
        input_fd = fopen(optarg, "r");

        if (input_fd == NULL) {
            printf("Problem with filename %s\n", optarg);
            exit(-1);
        }

        break;

318 319
      case 'M':
        SSB_positions = atoi(optarg);
320 321
        break;

322 323
      case 'N':
        Nid_cell = atoi(optarg);
324 325
        break;

326 327 328
      case 'R':
        N_RB_DL = atoi(optarg);
        N_RB_UL = N_RB_DL;
329 330
        break;

331 332 333 334 335
      case 'S':
        snr1 = atof(optarg);
        snr1set = 1;
        printf("Setting SNR1 to %f\n", snr1);
        break;
336

337 338 339 340
    case 'L':
      loglvl = atoi(optarg);
      break;	

341 342 343
      default:
        case 'h':
          printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
344 345 346 347
          //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");
348
          printf("-h This message\n");
349 350 351 352 353
          //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
          //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
          printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
          printf("-m MCS value\n");
          printf("-n Number of trials to simulate\n");
354 355 356 357 358
          printf("-p Use extended prefix mode\n");
          printf("-t Delay spread for multipath channel\n");
          //printf("-x Transmission mode (1,2,6 for the moment)\n");
          printf("-y Number of TX antennas used in eNB\n");
          printf("-z Number of RX antennas used in UE\n");
359

360 361 362
          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");
363 364 365 366 367
          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");
          printf("-S Ending SNR, runs from SNR0 to SNR1\n");
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
          exit(-1);
          break;
    }
  }

  logInit();
  set_glog(loglvl);
  T_stdout = 1;

  if (snr1set == 0)
    snr1 = snr0 + 10;

  gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
                                61.44e6, //N_RB2sampling_rate(N_RB_DL),
                                40e6, //N_RB2channel_bandwidth(N_RB_DL),
                                0, 0, 0);

  if (gNB2UE == NULL) {
386
    printf("Problem generating channel model. Exiting.\n");
387 388 389
    exit(-1);
  }

390 391 392
  RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
  RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
  gNB = RC.gNB[0];
393
  //gNB_config = &gNB->gNB_config;
394

395 396 397 398 399 400 401 402 403
  frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
  frame_parms->nb_antennas_tx = n_tx;
  frame_parms->nb_antennas_rx = n_rx;
  frame_parms->N_RB_DL = N_RB_DL;
  frame_parms->N_RB_UL = N_RB_UL;
  frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;

  crcTableInit();

Ahmed Hussein's avatar
Ahmed Hussein committed
404
  nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
405 406 407 408 409

  phy_init_nr_gNB(gNB, 0, 0);
  //init_eNB_afterRU();

  frame_length_complex_samples = frame_parms->samples_per_subframe;
laurent's avatar
laurent committed
410
  //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
411 412 413

  //configure UE
  UE = malloc(sizeof(PHY_VARS_NR_UE));
Florian Kaltenberger's avatar
Florian Kaltenberger committed
414 415 416 417
  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;
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
  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);
  //init_nr_ue_transport(UE, 0);
  for (sf = 0; sf < 2; sf++) {
    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);
        }

    }
  }

441
  unsigned char harq_pid = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
442
  unsigned int TBS;
443
  unsigned int available_bits;
laurent's avatar
laurent committed
444
  uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4);
445
  uint8_t length_dmrs = 1;
446
  unsigned char mod_order;
447
  uint16_t code_rate;
Khalid Ahmed's avatar
Khalid Ahmed committed
448

449 450
  mod_order      = nr_get_Qm_ul(Imcs, 0);
  code_rate      = nr_get_code_rate_ul(Imcs, 0);
451
  available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
452
  TBS            = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers);
453

454 455 456
  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;
  nfapi_nr_ul_tti_request_t     *UL_tti_req  = &gNB->UL_tti_req;
457 458
  nfapi_nr_pusch_pdu_t  *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;

459
  NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
460
  
461 462
  unsigned char *estimated_output_bit;
  unsigned char *test_input_bit;
463
  uint32_t errors_decoding   = 0;
464
  uint32_t errors_scrambling = 0;
465
  uint32_t is_frame_in_error = 0;
466

467 468
  test_input_bit       = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
  estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
469

Ahmed Hussein's avatar
Ahmed Hussein committed
470 471
  nr_scheduled_response_t scheduled_response;
  fapi_nr_ul_config_request_t ul_config;
472 473
  
  printf("\n");
474

475
  for (SNR = snr0; SNR < snr1; SNR += snr_step) {
476

477 478 479 480 481 482 483 484 485 486
    printf("-------------------\n");
    printf("SNR %f\n", SNR);
    printf("-------------------\n");

    is_frame_in_error = 0;
    for (int frame = 0; frame < number_of_frames; frame++) {

      UE_proc.nr_tti_tx = slot;
      UE_proc.frame_tx = frame;

487 488
      // --------- setting parameters for gNB --------
      /*
489 490 491 492 493 494 495 496 497 498 499 500
      rel15_ul->rnti                           = n_rnti;
      rel15_ul->ulsch_pdu_rel15.start_rb       = start_rb;
      rel15_ul->ulsch_pdu_rel15.number_rbs     = nb_rb;
      rel15_ul->ulsch_pdu_rel15.start_symbol   = start_symbol;
      rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
      rel15_ul->ulsch_pdu_rel15.nb_re_dmrs     = nb_re_dmrs;
      rel15_ul->ulsch_pdu_rel15.length_dmrs    = length_dmrs;
      rel15_ul->ulsch_pdu_rel15.Qm             = mod_order;
      rel15_ul->ulsch_pdu_rel15.mcs            = Imcs;
      rel15_ul->ulsch_pdu_rel15.rv             = 0;
      rel15_ul->ulsch_pdu_rel15.ndi            = 0;
      rel15_ul->ulsch_pdu_rel15.n_layers       = precod_nbr_layers;
501
      rel15_ul->ulsch_pdu_rel15.R              = code_rate; 
502
      ///////////////////////////////////////////////////
503 504
      */

505 506
      UL_tti_req->SFN = frame;
      UL_tti_req->Slot = slot;
507 508 509 510
      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));
511
      
512 513 514 515
      pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;  
      pusch_pdu->rnti = n_rnti;
      pusch_pdu->mcs_index = Imcs;
      pusch_pdu->mcs_table = 0; 
516 517
      pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); 
      pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
      pusch_pdu->transform_precoding = 0;
      pusch_pdu->data_scrambling_id = 0;
      pusch_pdu->nrOfLayers = 1;
      pusch_pdu->ul_dmrs_symb_pos = 1;
      pusch_pdu->dmrs_config_type = 0;
      pusch_pdu->ul_dmrs_scrambling_id =  0;
      pusch_pdu->scid = 0;
      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;
      pusch_pdu->pusch_data.rv_index = 0;
      pusch_pdu->pusch_data.harq_process_id = 0;
      pusch_pdu->pusch_data.new_data_indicator = 0;
      pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index,
537
						     pusch_pdu->target_code_rate,
538 539
						     pusch_pdu->rb_size,
						     pusch_pdu->nr_of_symbols,
540 541
						     nb_re_dmrs*length_dmrs,
						     0,
542 543 544 545
						     pusch_pdu->nrOfLayers = 1);
      pusch_pdu->pusch_data.num_cb = 0;


546
      // --------- setting parameters for UE --------
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579

      scheduled_response.module_id = 0;
      scheduled_response.CC_id = 0;
      scheduled_response.frame = frame;
      scheduled_response.slot = slot;
      scheduled_response.dl_config = NULL;
      scheduled_response.ul_config = &ul_config;
      scheduled_response.dl_config = NULL;

      ul_config.sfn_slot = slot;
      ul_config.number_pdus = 1;
      ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
      ul_config.ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
      ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
      //there are plenty of other parameters that we don't seem to be using for now. e.g.
      //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0;

      // set FAPI parameters for UE, put them in the scheduled response and call
      nr_ue_scheduled_response(&scheduled_response);

      /////////////////////////phy_procedures_nr_ue_TX///////////////////////
      ///////////

      phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);

580 581
      //LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_length_complex_samples,1,1);

582 583 584 585 586 587 588 589
      ///////////
      ////////////////////////////////////////////////////
      tx_offset = slot*frame_parms->samples_per_slot;

      txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
              frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);

      txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation
Ahmed Hussein's avatar
Ahmed Hussein committed
590 591 592 593 594 595 596 597 598 599 600

      n_errors = 0;
      n_false_positive = 0;

      //AWGN
      sigma_dB = 10*log10(txlev_float)-SNR;
      sigma    = pow(10,sigma_dB/10);

      for (trial = 0; trial < n_trials; trial++) {

        errors_scrambling  = 0;
601
        errors_decoding    = 0;
Ahmed Hussein's avatar
Ahmed Hussein committed
602

603 604 605
        //----------------------------------------------------------
        //------------------------ add noise -----------------------
        //----------------------------------------------------------
Ahmed Hussein's avatar
Ahmed Hussein committed
606 607
        for (i=0; i<frame_length_complex_samples; i++) {
          for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
608 609
            ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)]   = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)])   + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point
            ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)]   = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP);
Ahmed Hussein's avatar
Ahmed Hussein committed
610
          }
611
        }
612
        ////////////////////////////////////////////////////////////
613

614 615 616
        //----------------------------------------------------------
        //------------------- gNB phy procedures -------------------
        //----------------------------------------------------------
Ahmed Hussein's avatar
Ahmed Hussein committed
617
        phy_procedures_gNB_common_RX(gNB, frame, slot);
618

619 620
	//LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1);

621
        phy_procedures_gNB_uespec_RX(gNB, frame, slot);
622
        ////////////////////////////////////////////////////////////
623

Ahmed Hussein's avatar
Ahmed Hussein committed
624
        //----------------------------------------------------------
625
        //----------------- count and print errors -----------------
Ahmed Hussein's avatar
Ahmed Hussein committed
626
        //----------------------------------------------------------
627

Ahmed Hussein's avatar
Ahmed Hussein committed
628
        for (i = 0; i < available_bits; i++) {
629

Ahmed Hussein's avatar
Ahmed Hussein committed
630 631 632
          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)))
          {
633 634
            if(errors_scrambling == 0)
              printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);
Ahmed Hussein's avatar
Ahmed Hussein committed
635
            errors_scrambling++;
636
          }
637 638
        }

639 640 641
        if (errors_scrambling > 0) {
          printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling);
        }
642

Ahmed Hussein's avatar
Ahmed Hussein committed
643
        for (i = 0; i < TBS; i++) {
644

Ahmed Hussein's avatar
Ahmed Hussein committed
645
          estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
646
          test_input_bit[i]       = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
647

Ahmed Hussein's avatar
Ahmed Hussein committed
648
          if (estimated_output_bit[i] != test_input_bit[i]) {
649 650 651
            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++;
652
          }
653 654
        }

655 656
        if (errors_decoding > 0) {
          is_frame_in_error = 1;
Ahmed Hussein's avatar
Ahmed Hussein committed
657
          n_false_positive++;
658 659 660 661
          printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding     = %d\n" "\x1B[0m", frame, trial, errors_decoding);
        } else {
          is_frame_in_error = 0;
          break;
662
        }
663 664
        ////////////////////////////////////////////////////////////
      } // trial loop
665

666
      if (is_frame_in_error == 1)
Ahmed Hussein's avatar
Ahmed Hussein committed
667
        break;
668
    } // frame loop
669

670
    if(is_frame_in_error == 0 || number_of_frames==1)
671
      break;
672 673 674
  } // SNR loop

  if(is_frame_in_error == 0) {
675
    printf("\n");
Ahmed Hussein's avatar
Ahmed Hussein committed
676 677 678 679
    printf("*************\n");
    printf("PUSCH test OK\n");
    printf("*************\n");
  }
680

Ahmed Hussein's avatar
Ahmed Hussein committed
681
  printf("\n");
682

Ahmed Hussein's avatar
Ahmed Hussein committed
683 684 685
  free(test_input_bit);
  free(estimated_output_bit);

686 687 688 689 690 691 692 693
  if (output_fd)
    fclose(output_fd);

  if (input_fd)
    fclose(input_fd);

  return (n_errors);
}