dlsim.c 91.4 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * 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
 */
21 22 23 24

/*! \file dlsim.c
 \brief Top-level DL simulator
 \author R. Knopp
25
 \date 2011 - 2014
26 27 28 29 30 31 32
 \version 0.1
 \company Eurecom
 \email: knopp@eurecom.fr
 \note
 \warning
*/

33 34 35 36 37
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <execinfo.h>
#include <signal.h>
38 39 40 41
#include "common/config/config_load_configmodule.h"
#include "common/utils/LOG/log.h"
#include "LAYER2/MAC/mac_vars.h"
#include "nfapi/oai_integration/vendor_ext.h"
42
#include "PHY/types.h"
43 44 45
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/phy_vars.h"
46 47 48
#include "PHY/INIT/phy_init.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
49 50 51
#include "PHY/MODULATION/modulation_common.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
52
#include "PHY/TOOLS/lte_phy_scope.h"
53
#include "SCHED/sched_eNB.h"
54
#include "SCHED/sched_common_vars.h"
55
#include "SCHED_UE/sched_UE.h"
56 57 58 59 60 61
#include "SIMULATION/TOOLS/sim.h"
#include "UTIL/LISTS/list.h"
#include "OCG_vars.h"
#include "unitary_defs.h"
#include "dummy_functions.c"
#include "executables/thread-common.h"
laurent's avatar
laurent committed
62
#include "executables/split_headers.h"
Raymond Knopp's avatar
Raymond Knopp committed
63

64 65
void feptx_ofdm(RU_t *ru, int frame, int subframe);
void feptx_prec(RU_t *ru, int frame, int subframe);
66

67
double cpuf;
laurent's avatar
laurent committed
68 69 70
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
//#define MCS_COUNT 23//added for PHY abstraction
#include <openair1/SIMULATION/LTE_PHY/common_sim.h>
71

72
int otg_enabled=0;
73 74 75 76 77 78 79
/*the following parameters are used to control the processing times calculations*/
double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */
double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */
int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
80

Raymond Knopp's avatar
Raymond Knopp committed
81
int emulate_rf = 0;
laurent's avatar
laurent committed
82 83 84 85 86 87 88
int split73=0;
void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) {
  AssertFatal(false, "Must not be called in this context\n");
}
void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) {
  AssertFatal(false, "Must not be called in this context\n");
}
Raymond Knopp's avatar
Raymond Knopp committed
89

90
void handler(int sig) {
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  void *array[10];
  size_t size;
  // get void*'s for all entries on the stack
  size = backtrace(array, 10);
  // print out all the frames to stderr
  fprintf(stderr, "Error: signal %d:\n", sig);
  backtrace_symbols_fd(array, size, 2);
  exit(1);
}

//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2];

DCI1E_5MHz_2A_M10PRB_TDD_t  DLSCH_alloc_pdu2_1E[2];
uint64_t DLSCH_alloc_pdu_1[2];

#define UL_RB_ALLOC 0x1ff;
107
#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
108 109
//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
//#define DLSCH_RB_ALLOC 0x0001
110
void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) {
111 112 113 114 115 116 117 118
  int aa, slot_offset, slot_offset_F;
  slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
  slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);

  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
    //    printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
    if (frame_parms->Ncp == 1)
      PHY_ofdm_mod(&txdataF[aa][slot_offset_F],        // input
119
                   &txdata[aa][slot_offset],         // output
120
                   frame_parms->ofdm_symbol_size,
121 122 123
                   6,                 // number of symbols
                   frame_parms->nb_prefix_samples,               // number of prefix samples
                   CYCLIC_PREFIX);
124 125
    else {
      normal_prefix_mod(&txdataF[aa][slot_offset_F],
126 127 128
                        &txdata[aa][slot_offset],
                        7,
                        frame_parms);
129 130 131 132
    }
  }
}

133
void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4],
134
                double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) {
135 136 137 138
  int i,u;
  int aa,aarx,aatx;
  double channelx,channely;
  double sigma2_dB,sigma2;
139 140
  double iqim=0.0;

141 142
  //    printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag);
  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
143
    for (aa=0; aa<ru->frame_parms->nb_antennas_tx; aa++) {
144
      if (awgn_flag == 0) {
145 146
        s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
        s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
147
      } else {
148 149 150 151 152 153 154 155 156
        for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
          if (aa==0) {
            r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
            r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
          } else {
            r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
            r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
          }
        }
157 158 159
      }
    }
  }
160

161 162 163
  // Multipath channel
  if (awgn_flag == 0) {
    multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
164
                      2*UE->frame_parms.samples_per_tti,hold_channel);
165

166 167 168
    //      printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
    if(abstx==1 && num_rounds>1)
      if(round==0 && hold_channel==0) {
169 170 171
        random_channel(eNB2UE[1],0);
        random_channel(eNB2UE[2],0);
        random_channel(eNB2UE[3],0);
172
      }
173

174 175 176 177
    if (UE->perfect_ce==1) {
      // fill in perfect channel estimates
      freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
      /*
178 179
      LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
      LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8);
180 181 182
      */
    }
  }
183

184 185 186
  if(abstx) {
    if (trials==0 && round==0) {
      // calculate freq domain representation to compute SINR
187
      freq_channel(eNB2UE[0], ru->frame_parms->N_RB_DL,2*ru->frame_parms->N_RB_DL + 1);
188 189
      // snr=pow(10.0,.1*SNR);
      fprintf(csv_fd,"%f,",SNR);
190

191
      for (u=0; u<2*ru->frame_parms->N_RB_DL; u++) {
192 193 194 195 196 197 198
        for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) {
          for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) {
            channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
            channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
            fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
          }
        }
199 200
      }

201
      if(num_rounds>1) {
202
        freq_channel(eNB2UE[1], ru->frame_parms->N_RB_DL,2*ru->frame_parms->N_RB_DL + 1);
203

204
        for (u=0; u<2*ru->frame_parms->N_RB_DL; u++) {
205 206 207 208 209 210 211 212 213
          for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) {
            for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) {
              channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
              channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
              fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
            }
          }
        }

214
        freq_channel(eNB2UE[2], ru->frame_parms->N_RB_DL,2*ru->frame_parms->N_RB_DL + 1);
215

216
        for (u=0; u<2*ru->frame_parms->N_RB_DL; u++) {
217 218 219 220 221 222 223 224 225
          for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) {
            for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) {
              channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
              channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
              fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
            }
          }
        }

226
        freq_channel(eNB2UE[3], ru->frame_parms->N_RB_DL,2*ru->frame_parms->N_RB_DL + 1);
227

228
        for (u=0; u<2*ru->frame_parms->N_RB_DL; u++) {
229 230 231 232 233 234 235 236
          for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) {
            for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) {
              channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
              channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
              fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
            }
          }
        }
237 238 239
      }
    }
  }
240

241
  //AWGN
242 243
  // tx_lev is the average energy over the whole subframe
  // but SNR should be better defined wrt the energy in the reference symbols
244
  sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms->ofdm_symbol_size/(double)(ru->frame_parms->N_RB_DL*12)) - SNR;
245 246 247
  sigma2 = pow(10,sigma2_dB/10);

  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
248
    for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) {
249
      //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
250 251 252 253
      ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
        (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
      ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
        (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
254 255 256
    }
  }
}
257

258 259
uint16_t
fill_tx_req(nfapi_tx_request_body_t *tx_req_body,
260 261 262 263
            uint16_t                absSF,
            uint16_t                pdu_length,
            uint16_t                pdu_index,
            uint8_t                 *pdu) {
264 265
  nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus];
  LOG_D(MAC, "Filling TX_req %d for pdu length %d\n",
266
        tx_req_body->number_of_pdus, pdu_length);
267 268 269 270 271 272 273 274 275 276 277
  TX_req->pdu_length                 = pdu_length;
  TX_req->pdu_index                  = pdu_index;
  TX_req->num_segments               = 1;
  TX_req->segments[0].segment_length = pdu_length;
  TX_req->segments[0].segment_data   = pdu;
  tx_req_body->tl.tag                = NFAPI_TX_REQUEST_BODY_TAG;
  tx_req_body->number_of_pdus++;
  return (((absSF / 10) << 4) + (absSF % 10));
}

void
278 279 280 281 282 283 284 285 286 287 288 289 290 291
fill_dlsch_config(nfapi_dl_config_request_body_t *dl_req,
                  uint16_t length,
                  uint16_t pdu_index,
                  uint16_t rnti,
                  uint8_t resource_allocation_type,
                  uint8_t virtual_resource_block_assignment_flag,
                  uint16_t resource_block_coding,
                  uint8_t modulation,
                  uint8_t redundancy_version,
                  uint8_t transport_blocks,
                  uint8_t transport_block_to_codeword_swap_flag,
                  uint8_t transmission_scheme,
                  uint8_t number_of_layers,
                  uint8_t number_of_subbands,
292
                  //                             uint8_t codebook_index,
293 294 295 296 297 298 299 300
                  uint8_t ue_category_capacity,
                  uint8_t pa,
                  uint8_t delta_power_offset_index,
                  uint8_t ngap,
                  uint8_t nprb,
                  uint8_t transmission_mode,
                  uint8_t num_bf_prb_per_subband,
                  uint8_t num_bf_vector) {
301 302 303
  nfapi_dl_config_request_pdu_t *dl_config_pdu =
    &dl_req->dl_config_pdu_list[dl_req->number_pdu];
  memset((void *) dl_config_pdu, 0,
304
         sizeof(nfapi_dl_config_request_pdu_t));
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
  dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
  dl_config_pdu->pdu_size                                                        = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length                                 = length;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = pdu_index;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = rnti;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = resource_allocation_type;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = resource_block_coding;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = modulation;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = redundancy_version;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = transport_blocks;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = transport_block_to_codeword_swap_flag;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = transmission_scheme;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = number_of_layers;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = number_of_subbands;
  //  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = codebook_index;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = ue_category_capacity;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = pa;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = delta_power_offset_index;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = ngap;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = nprb;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = transmission_mode;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = num_bf_prb_per_subband;
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = num_bf_vector;
330
  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF;
331 332
  dl_req->number_pdu++;
}
333

334
void fill_DCI(PHY_VARS_eNB *eNB,
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
              int frame,
              int subframe,
              Sched_Rsp_t *sched_resp,
              uint8_t input_buffer[NUMBER_OF_UE_MAX][20000],
              int n_rnti,
              int n_users,
              int transmission_mode,
              int retrans,
              int common_flag,
              int NB_RB,
              int DLSCH_RB_ALLOC,
              int TPC,
              int mcs1,
              int mcs2,
              int ndi,
              int rv,
              int pa,
              int *num_common_dci,
              int *num_ue_spec_dci,
              int *num_dci) {
355
  int k;
356 357 358
  nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body;
  nfapi_dl_config_request_pdu_t  *dl_config_pdu;
  nfapi_tx_request_body_t        *TX_req=&sched_resp->TX_req->tx_request_body;
359
  int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC);
360 361 362 363
  dl_req->number_dci=0;
  dl_req->number_pdu=0;
  TX_req->number_of_pdus=0;

364 365
  for(k=0; k<n_users; k++) {
    switch(transmission_mode) {
366 367 368 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 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
      case 1:
      case 2:
      case 7:
        dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
        memset((void *) dl_config_pdu, 0,
               sizeof(nfapi_dl_config_request_pdu_t));
        dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
        dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2;  // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;  // equal to RS power
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC;  // dont adjust power when retransmitting
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB);
        //deactivate second codeword
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0;
        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0;
        dl_req->number_dci++;
        dl_req->number_pdu++;
        dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
        AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n");
        fill_dlsch_config(dl_req,
                          get_TBS_DL(mcs1,NB_RB4TBS),
                          (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */
                          (common_flag == 0) ? n_rnti : SI_RNTI,
                          0,  // type 0 allocation from 7.1.6 in 36.213
                          0,  // virtual_resource_block_assignment_flag, unused here
                          DLSCH_RB_ALLOC, // resource_block_coding,
                          get_Qm(mcs1),
                          rv, // redundancy version
                          1,  // transport blocks
                          0,  // transport block to codeword swap flag
                          transmission_mode == 1 ? 0 : 1, // transmission_scheme
                          1,  // number of layers
                          1,  // number of subbands
                          //                      uint8_t codebook_index,
                          4,  // UE category capacity
                          pa,    // pa
                          0,  // delta_power_offset for TM5
                          0,  // ngap
                          0,  // nprb
                          transmission_mode,
                          0,  //number of PRBs treated as one subband, not used here
                          0 // number of beamforming vectors, not used here
                         );
        fill_tx_req(TX_req,
                    (frame * 10) + subframe,
                    get_TBS_DL(mcs1,NB_RB4TBS),
                    0,
                    input_buffer[k]);
        break;
425

426 427 428 429 430 431 432 433
      case 3:
        if (common_flag == 0) {
          if (eNB->frame_parms.nb_antennas_tx == 2) {
            if (eNB->frame_parms.frame_type == TDD) {
            } else {
            }
          }
        }
434

435
        break;
436

437 438 439 440 441 442 443 444 445
      case 4:
        if (common_flag == 0) {
          if (eNB->frame_parms.nb_antennas_tx == 2) {
            if (eNB->frame_parms.frame_type == TDD) {
            } else {
            }
          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
          }
        } else {
446
        }
447

448
        break;
449

450 451 452
      case 5:
      case 6:
        break;
453

454 455 456 457
      default:
        printf("Unsupported Transmission Mode %d!!!\n",transmission_mode);
        exit(-1);
        break;
458
    }
459
  }
460

461 462 463
  *num_dci         = dl_req->number_dci;
  *num_ue_spec_dci = dl_req->number_dci;
  *num_common_dci  = 0;
464
}
465

466
int n_users = 1;
laurent's avatar
laurent committed
467
int subframe=7;
468 469
int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
uint16_t n_rnti=0x1234;
470

laurent's avatar
laurent committed
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
int abstx=0;
int Nid_cell=0;
int N_RB_DL=25;
int tdd_config=3;
int dci_flag=0;
int threequarter_fs=0;
double snr_step=1,input_snr_step=1, snr_int=30;
double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
int test_perf=0;
int n_frames;
int n_ch_rlz = 1;
int rx_sample_offset = 0;
int xforms=0;
int dump_table=0;
int loglvl=OAILOG_WARNING;
int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0;
int two_thread_flag=0;
int num_rounds = 4;//,fix_rounds=0;
int perfect_ce = 0;
int extended_prefix_flag=0;
int verbose=0, help=0;
double SNR,snr0=-2.0,snr1,rate = 0;
int print_perf=0;
494

495
int main(int argc, char **argv) {
496
  int k,i,j,aa;
Xiwen JIANG's avatar
Xiwen JIANG committed
497
  int re;
498 499
  int s,Kr,Kr_bytes;
  LTE_DL_FRAME_PARMS *frame_parms;
500 501
  double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2];
  double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2];
502 503 504 505
  double *s_re[2]= {s_re0,s_re1};
  double *s_im[2]= {s_im0,s_im1};
  double *r_re[2]= {r_re0,r_re1};
  double *r_im[2]= {r_im0,r_im1};
laurent's avatar
laurent committed
506
  uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
507
  int eNB_id = 0;
laurent's avatar
laurent committed
508
  unsigned char round;
509
  unsigned char i_mod = 2;
510
  int NB_RB;
511 512
  SCM_t channel_model=Rayleigh1;
  //  unsigned char *input_data,*decoded_output;
513 514
  DCI_ALLOC_t da;
  DCI_ALLOC_t *dci_alloc = &da;
515
  unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0;
516 517 518 519 520 521
  unsigned int tx_lev=0,tx_lev_dB=0,trials;
  unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers;
  memset(errs,0,4*sizeof(unsigned int));
  memset(errs2,0,4*sizeof(unsigned int));
  memset(round_trials,0,4*sizeof(unsigned int));
  memset(dci_errors,0,4*sizeof(unsigned int));
522
  //int re_allocated;
523 524 525
  char fname[32],vname[32];
  FILE *bler_fd;
  char bler_fname[256];
526
  FILE *time_meas_fd=NULL;
527 528 529 530 531 532 533 534
  char time_meas_fname[256];
  //  FILE *tikz_fd;
  //  char tikz_fname[256];
  FILE *input_trch_fd=NULL;
  unsigned char input_trch_file=0;
  FILE *input_fd=NULL;
  unsigned char input_file=0;
  channel_desc_t *eNB2UE[4];
535
  //uint8_t num_pdcch_symbols_2=0;
536 537
  //char stats_buffer[4096];
  //int len;
538
  //int u;
539
  int n=0;
540
  //int iii;
541
  int ch_realization;
542
  //int pmi_feedback=0;
543 544 545 546
  int hold_channel=0;
  // void *data;
  // int ii;
  //  int bler;
547
  double blerr[4];
548
  short *uncoded_ber_bit=NULL;
laurent's avatar
laurent committed
549
  int osf=1;
550 551 552 553
  frame_t frame_type = FDD;
  FD_lte_phy_scope_ue *form_ue = NULL;
  char title[255];
  int numCCE=0;
554
  //int dci_length_bytes=0,dci_length=0;
555 556 557 558 559 560
  //double channel_bandwidth = 5.0, sampling_rate=7.68;
  int common_flag=0,TPC=0;
  double cpu_freq_GHz;
  //  time_stats_t ts;//,sts,usts;
  int avg_iter,iter_trials;
  int rballocset=0;
561
  int test_passed=0;
562 563 564 565 566 567 568 569
  double effective_rate=0.0;
  char channel_model_input[10]="I";
  int TB0_active = 1;
  //  LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
  //  LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
  uint8_t Kmimo;
  uint8_t ue_category=4;
  uint32_t Nsoft;
570
  int sf;
571 572 573
  int CCE_table[800];
  opp_enabled=1; // to enable the time meas
  FILE *csv_fd=NULL;
laurent's avatar
laurent committed
574
  char csv_fname[FILENAME_MAX];
575
  int DLSCH_RB_ALLOC = 0;
576
  int dci_received;
577 578
  PHY_VARS_eNB *eNB;
  RU_t *ru;
frtabu's avatar
frtabu committed
579
  PHY_VARS_UE *UE=NULL;
580 581 582
  nfapi_dl_config_request_t DL_req;
  nfapi_ul_config_request_t UL_req;
  nfapi_hi_dci0_request_t HI_DCI0_req;
Cedric Roux's avatar
Cedric Roux committed
583
  nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU];
584 585 586 587
  nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU];
  nfapi_tx_request_t TX_req;
  Sched_Rsp_t sched_resp;
  int pa=dB0;
588 589 590
#if defined(__arm__)
  FILE    *proc_fd = NULL;
  char buf[64];
591
  memset(buf,0,sizeof(buf));
592
  proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
593

594
  if(!proc_fd)
595
    printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
596
  else {
597 598
    while(fgets(buf, 63, proc_fd))
      printf("%s", buf);
599
  }
600

601 602 603 604 605 606
  fclose(proc_fd);
  cpu_freq_GHz = ((double)atof(buf))/1e6;
#else
  cpu_freq_GHz = get_cpu_freq_GHz();
#endif
  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
607
  memset((void *)&sched_resp,0,sizeof(sched_resp));
608 609 610 611
  sched_resp.DL_req = &DL_req;
  sched_resp.UL_req = &UL_req;
  sched_resp.HI_DCI0_req = &HI_DCI0_req;
  sched_resp.TX_req = &TX_req;
612 613 614 615
  memset((void *)&DL_req,0,sizeof(DL_req));
  memset((void *)&UL_req,0,sizeof(UL_req));
  memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req));
  memset((void *)&TX_req,0,sizeof(TX_req));
616 617
  DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list;
  TX_req.tx_request_body.tx_pdu_list = tx_pdu_list;
618
  set_parallel_conf("PARALLEL_SINGLE_THREAD");
619
  cpuf = cpu_freq_GHz;
620 621 622 623 624 625 626
  //signal(SIGSEGV, handler);
  //signal(SIGABRT, handler);
  // default parameters
  n_frames = 1000;
  snr0 = 0;
  //  num_layers = 1;
  perfect_ce = 0;
627
  static paramdef_t options[] = {
laurent's avatar
laurent committed
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
    { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
    { "Abstx", "Turns on calibration mode for abstraction.", PARAMFLAG_BOOL, iptr:&abstx,  defintval:0, TYPE_INT, 0 },
    { "bTDD", "Set the tdd configuration mode",0, iptr:&tdd_config,  defintval:3, TYPE_INT, 0 },
    { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL,  defintval:25, TYPE_INT, 0 },
    { "cPdcch", "Number of PDCCH symbols",0, iptr:&num_pdcch_symbols,  defintval:1, TYPE_INT, 0 },
    { "CnidCell", "The cell id ",0, iptr:&Nid_cell,  defintval:0, TYPE_INT, 0 },
    { "dciFlag", "Transmit the DCI and compute its error statistics", PARAMFLAG_BOOL, iptr:&dci_flag,  defintval:0, TYPE_INT, 0 },
    { "Dtdd", "Enable tdd", PARAMFLAG_BOOL,  strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL },
    { "eRounds", "Number of rounds",0, iptr:NULL,  defintval:25, TYPE_INT, 0 },
    { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 },
    { "f_snr_step", "step size of SNR, default value is 1.",0, dblptr:&input_snr_step,  defdblval:1, TYPE_DOUBLE, 0 },
    { "Forgetting", "forgetting factor (0 new channel every trial, 1 channel constant)",0, dblptr:&forgetting_factor,  defdblval:0.0, TYPE_DOUBLE, 0 },
    { "input_file", "input IQ data file",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "Input_file_trch", " Input filename for TrCH data (binary)",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "WtwoThreads", "two_thread_flag", PARAMFLAG_BOOL, iptr:&two_thread_flag,  defintval:0, TYPE_INT, 0 },
    { "lMuMimo", "offset_mumimo_llr_drange_fix",0, u8ptr:&offset_mumimo_llr_drange_fix,  defintval:0, TYPE_UINT8, 0 },
    { "mcs1", "The MCS for TB 1", 0, iptr:&mcs1,  defintval:0, TYPE_INT, 0 },
    { "Mcs2", "The MCS for TB 2", 0, iptr:&mcs2,  defintval:0, TYPE_INT, 0 },
    { "Operf", "Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf,  defintval:0, TYPE_INT, 0 },
    { "tmcs_i", "MCS of interfering UE",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "nb_frame", "number of frame in a test",0, iptr:&n_frames,  defintval:1, TYPE_INT, 0 },
    { "offsetRxSample", "Sample offset for receiver", 0, iptr:&rx_sample_offset,  defintval:0, TYPE_INT, 0 },
    { "rballocset", "ressource block allocation (see  section 7.1.6.3 in 36.213)",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "snr", "Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated", dblptr:&snr0,  defdblval:-2.0, TYPE_DOUBLE, 0 },
    { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int,  defdblval:30, TYPE_DOUBLE, 0 },
    { "N_ch_rlzN0", "Determines the number of Channel Realizations in Abstraction mode. Default value is 1",0, iptr:&n_ch_rlz,  defintval:1, TYPE_INT, 0 },
    { "prefix_extended","Enable extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag,  defintval:0, TYPE_INT, 0 },
    { "RNumRound", "Number of HARQ rounds (fixed)",0, iptr:&num_rounds,  defintval:4, TYPE_INT, 0 },
    { "Subframe", "subframe ",0, iptr:&subframe,  defintval:7, TYPE_INT, 0 },
    { "Trnti", "rnti",0, u16ptr:&n_rnti,  defuintval:0x1234, TYPE_UINT16, 0 },
    { "vi_mod", "i_mod",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
laurent's avatar
laurent committed
659
    { "Qparallel", "Enable parallel execution",0, strptr:NULL,  defstrval:NULL, TYPE_STRING,  0 },
laurent's avatar
laurent committed
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
    { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL,  iptr:&print_perf,  defintval:0, TYPE_INT, 0 },
    { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL,  defintval:0, TYPE_INT, 0 },
    { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL,  defintval:25, TYPE_INT, 0 },
    { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL,  defintval:25, TYPE_INT, 0 },
    { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms,  defintval:0, TYPE_INT, 0 },
    { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce,  defintval:0, TYPE_INT, 0 },
    { "Zdump", "dump table",PARAMFLAG_BOOL,  iptr:&dump_table, defintval:0, TYPE_INT, 0 },
    { "Loglvl", "log level",0, iptr:&loglvl,  defintval:OAILOG_DEBUG, TYPE_INT, 0 },
    { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL,  defintval:2, TYPE_INT, 0 },
    { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'),  Rice8('L'), Rice1('M')",0, strptr:NULL,  defstrval:NULL, TYPE_STRING, 0 },
    { "verbose", "display debug text", PARAMFLAG_BOOL,  iptr:&verbose, defintval:0, TYPE_INT, 0 },
    { "help", "display help and exit", PARAMFLAG_BOOL,  iptr:&help, defintval:0, TYPE_INT, 0 },
    { "", "",0,  iptr:NULL, defintval:0, TYPE_INT, 0 },
  };
675
  struct option *long_options = parse_oai_options(options);
laurent's avatar
laurent committed
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
  int option_index;
  int res;

  while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) {
    if (options[option_index].voidptr != NULL ) {
      if (long_options[option_index].has_arg==no_argument)
        *(bool *)options[option_index].iptr=1;
      else switch (options[option_index].type) {
          case TYPE_INT:
            *(int *)options[option_index].iptr=atoi(optarg);
            break;

          case TYPE_DOUBLE:
            *(double *)options[option_index].dblptr=atof(optarg);
            break;
691 692 693 694 695 696 697 698 699 700

          case TYPE_UINT8:
            *(uint8_t *)options[option_index].dblptr=atoi(optarg);
            break;

          case TYPE_UINT16:
            *(uint16_t *)options[option_index].dblptr=atoi(optarg);
            break;

          default:
laurent's avatar
laurent committed
701 702 703
            printf("not decoded type.\n");
            exit(1);
        }
704

laurent's avatar
laurent committed
705 706
      continue;
    }
707

laurent's avatar
laurent committed
708
    switch (long_options[option_index].name[0]) {
709 710 711
      case 'a':
        awgn_flag = 1;
        channel_model = AWGN;
712
        break;
713

714
      case 'D':
715
        frame_type=TDD;
716
        break;
717

718 719 720 721
      case 'e':
        num_rounds=1;
        common_flag = 1;
        TPC = atoi(optarg);
722
        break;
723

724 725 726 727
      case 'i':
        input_fd = fopen(optarg,"r");
        input_file=1;
        dci_flag = 1;
728
        break;
729

730
      case 'I':
731 732
        input_trch_fd = fopen(optarg,"r");
        input_trch_file=1;
733
        break;
734

735 736 737
      case 't':
        mcs_i = atoi(optarg);
        i_mod = get_Qm(mcs_i);
738
        break;
739

740 741 742
      case 'r':
        DLSCH_RB_ALLOC = atoi(optarg);
        rballocset = 1;
743
        break;
744

745 746 747 748 749 750 751 752 753
      case 'g':
        strncpy(channel_model_input,optarg,9);
        struct tmp {
          char opt;
          int m;
          int M;
        }
        tmp[]= {
          {'A',SCM_A,2},
laurent's avatar
laurent committed
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
          {'B',SCM_B,3},
          {'C',SCM_C,4},
          {'D',SCM_D,5},
          {'E',EPA,6},
          {'F',EVA,6},
          {'G',ETU,8},
          {'H',Rayleigh8,9},
          {'I',Rayleigh1,10},
          {'J',Rayleigh1_corr,11},
          {'K',Rayleigh1_anticorr,12},
          {'L',Rice8,13},
          {'M',Rice1,14},
          {'N',AWGN,1},
          {0,0,0}
        };
        struct tmp *ptr;

        for (ptr=tmp; ptr->opt!=0; ptr++)
          if ( ptr->opt == optarg[0] ) {
            channel_model=ptr->m;
            break;
          }
776

laurent's avatar
laurent committed
777
        AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg );
778
        break;
779

780
      case 'u':
781
        dual_stream_UE=1;
782

783 784
        if (UE != NULL)
          UE->use_ia_receiver = 1;
frtabu's avatar
frtabu committed
785 786
        else {
          printf("UE  is NULL\n");
787 788
          exit(-1);
        }
789

790 791 792 793
        if ((n_tx_port!=2) || (transmission_mode!=5)) {
          printf("IA receiver only supported for TM5!");
          exit(-1);
        }
794

795
        break;
796

797 798
      case 'v':
        i_mod = atoi(optarg);
799

800 801 802 803
        if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
          printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
          exit(-1);
        }
804

805
        break;
Xiwen JIANG's avatar
Xiwen JIANG committed
806

807 808
      case 'q':
        n_tx_port=atoi(optarg);
Xiwen JIANG's avatar
Xiwen JIANG committed
809

810 811 812 813
        if ((n_tx_port==0) || ((n_tx_port>2))) {
          printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
          exit(-1);
        }
Xiwen JIANG's avatar
Xiwen JIANG committed
814

815
        break;
Xiwen JIANG's avatar
Xiwen JIANG committed
816

817 818 819 820 821 822 823 824 825 826 827 828 829
      case 'x':
        transmission_mode=atoi(optarg);

        if ((transmission_mode!=1) &&
            (transmission_mode!=2) &&
            (transmission_mode!=3) &&
            (transmission_mode!=4) &&
            (transmission_mode!=5) &&
            (transmission_mode!=6) &&
            (transmission_mode!=7)) {
          printf("Unsupported transmission mode %d\n",transmission_mode);
          exit(-1);
        }
830

831 832 833
        if (transmission_mode>1 && transmission_mode<7) {
          n_tx_port = 2;
        }
834

835
        break;
836

837 838
      case 'y':
        n_tx_phy=atoi(optarg);
839

840 841 842 843
        if (n_tx_phy < n_tx_port) {
          printf("n_tx_phy mush not be smaller than n_tx_port");
          exit(-1);
        }
844

845 846 847 848
        if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) {
          printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode);
          exit(-1);
        }
849

850 851 852 853
        if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) {
          printf("Physical number of antennas not supported for TM7.\n");
          exit(-1);
        }
854

855
        break;
856

857 858
      case 'z':
        n_rx=atoi(optarg);
859

860 861 862 863
        if ((n_rx==0) || (n_rx>2)) {
          printf("Unsupported number of rx antennas %d\n",n_rx);
          exit(-1);
        }
864

865
        break;
866

867
      case 'Q':
868
        set_parallel_conf(optarg);
869
        break;
870

871 872 873 874
      default:
        printf("Wrong option: %s\n",long_options[option_index].name);
        exit(1);
        break;
875 876
    }
  }
877

laurent's avatar
laurent committed
878 879 880 881
  if ( res != -1 ) {
    printf("A wrong option has been found\n");
    exit(1);
  }
882

laurent's avatar
laurent committed
883
  if (help || verbose )
884
    display_options_values(options, true);
885

laurent's avatar
laurent committed
886 887
  if (help)
    exit(0);
laurent's avatar
laurent committed
888
  if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD)
889
    set_worker_conf("WORKER_ENABLE");
890

891 892
  if (transmission_mode>1) pa=dBm3;

893
  printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa);
yilmazt's avatar
yilmazt committed
894
  AssertFatal(load_configmodule(argc,argv, CONFIG_ENABLECMDLINEONLY) != NULL, "Cannot load configuration module, exiting\n");
895
  logInit();
laurent's avatar
laurent committed
896
  set_glog_onlinelog(true);
897
  // enable these lines if you need debug info
898
  set_glog(loglvl);
laurent's avatar
laurent committed
899
  SET_LOG_DEBUG(UE_TIMING);
900 901 902 903
  // moreover you need to init itti with the following line
  // however itti will catch all signals, so ctrl-c won't work anymore
  // alternatively you can disable ITTI completely in CMakeLists.txt
  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
904
  T_stdout = 1;
905

906 907
  if (common_flag == 0) {
    switch (N_RB_DL) {
908 909
      case 6:
        if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
910

911 912
        num_pdcch_symbols = 3;
        break;
913

914 915
      case 25:
        if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
916

917 918 919 920 921 922 923 924 925 926 927
        break;

      case 50:
        if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;

        break;

      case 100:
        if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;

        break;
928
    }
929

930
    NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
931
  } else {
932 933
    if (rballocset==0) NB_RB = 8;
    else               NB_RB = DLSCH_RB_ALLOC;
934

935 936
    AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB);
  }
937

938 939 940 941 942
  if (xforms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
    form_ue = create_lte_phy_scope_ue();
    sprintf (title, "LTE PHY SCOPE eNB");
    fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
943

944
    if (!dual_stream_UE==0) {
frtabu's avatar
frtabu committed
945 946 947 948 949 950
      if (UE) {
        UE->use_ia_receiver = 1;
        fl_set_button(form_ue->button_0,1);
        fl_set_object_label(form_ue->button_0, "IA Receiver ON");
        fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
      } else {
951 952
        printf("UE  is NULL\n");
        exit(-1);
frtabu's avatar
frtabu committed
953
      }
954 955
    }
  }
956

957 958 959 960
  if (transmission_mode==5) {
    n_users = 2;
    printf("dual_stream_UE=%d\n", dual_stream_UE);
  }
961

962 963 964
  RC.nb_L1_inst = 1;
  RC.nb_RU = 1;
  lte_param_init(&eNB,&UE,&ru,
965 966 967
                 n_tx_port,
                 n_tx_phy,
                 1,
968
                 n_rx,
969 970 971 972 973 974 975 976 977 978 979
                 transmission_mode,
                 extended_prefix_flag,
                 frame_type,
                 Nid_cell,
                 tdd_config,
                 N_RB_DL,
                 pa,
                 threequarter_fs,
                 osf,
                 perfect_ce);
  RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **));
980 981 982 983 984
  RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *));
  RC.ru = (RU_t **)malloc(sizeof(RC.ru));
  RC.eNB[0][0] = eNB;
  RC.ru[0] = ru;
  printf("lte_param_init done\n");
985

986
  if ((transmission_mode==1) || (transmission_mode==7)) {
987
    for (aa=0; aa<ru->nb_tx; aa++)
988 989
      for (re=0; re<ru->frame_parms->ofdm_symbol_size; re++)
        ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx;
990 991
  }

992
  if (transmission_mode<7)
993
    ru->do_precoding=0;
994
  else
995
    ru->do_precoding=1;
996

997
  eNB->mac_enabled=1;
998

laurent's avatar
laurent committed
999
  if(get_thread_worker_conf() == WORKER_ENABLE) {
1000 1001 1002 1003
    extern void init_td_thread(PHY_VARS_eNB *);
    extern void init_te_thread(PHY_VARS_eNB *);
    init_td_thread(eNB);
    init_te_thread(eNB);
1004 1005
  }

1006
  // callback functions required for phy_procedures_tx
1007 1008 1009 1010 1011
  //  eNB_id_i = UE->n_connected_eNB;
  printf("Setting mcs1 = %d\n",mcs1);
  printf("Setting mcs2 = %d\n",mcs2);
  printf("NPRB = %d\n",NB_RB);
  printf("n_frames = %d\n",n_frames);
Xiwen JIANG's avatar
Xiwen JIANG committed
1012
  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
1013 1014
  snr1 = snr0+snr_int;
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
1015
  uint8_t input_buffer[NUMBER_OF_UE_MAX][20000];
1016

1017 1018
  for (i=0; i<n_users; i++)
    for (j=0; j<20000; j++) input_buffer[i][j] = (uint8_t)((taus())&255);
1019

1020 1021 1022 1023 1024
  frame_parms = &eNB->frame_parms;
  nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
  printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
  printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n",
         SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8);
1025

1026 1027 1028 1029 1030 1031
  if(transmission_mode==5)
    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod);
  else
    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1);

  bler_fd = fopen(bler_fname,"w");
1032

1033 1034 1035 1036
  if (bler_fd==NULL) {
    fprintf(stderr,"Cannot create file %s!\n",bler_fname);
    exit(-1);
  }
1037

1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
  fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");

  if (test_perf != 0) {
    char hostname[1024];
    hostname[1023] = '\0';
    gethostname(hostname, 1023);
    printf("Hostname: %s\n", hostname);
    //char dirname[FILENAME_MAX];
    //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
Xiwen JIANG's avatar
Xiwen JIANG committed
1048
            N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
1049 1050
    //mkdir(dirname,0777);
    time_meas_fd = fopen(time_meas_fname,"w");
1051

1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
    if (time_meas_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
      exit(-1);
    }
  }

  if(abstx) {
    // CSV file
    sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds);
    csv_fd = fopen(csv_fname,"w");
1062

1063 1064 1065 1066
    if (csv_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",csv_fname);
      exit(-1);
    }
1067 1068

    fprintf(csv_fd,"data_all%d=[",mcs1);
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
  }

  /*
  //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
  sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
  tikz_fd = fopen(tikz_fname,"w");
  //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
  switch (mcs)
    {
    case 0:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {");
      break;
    case 1:
      fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {");
      break;
    case 2:
      fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {");
      break;
    case 3:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {");
      break;
    case 4:
      fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {");
      break;
    case 5:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {");
      break;
    case 6:
      fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
      break;
    case 7:
      fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {");
      break;
    case 8:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {");
      break;
    case 9:
      fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {");
      break;
    case 10:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {");
      break;
    case 11:
      fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {");
      break;
    case 12:
      fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {");
      break;
    case 13:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {");
      break;
    case 14:
      fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {");
      break;
    case 15:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {");
      break;
    case 16:
      fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {");
      break;
    case 17:
      fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {");
      break;
    case 18:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {");
      break;
    case 19:
      fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {");
      break;
    case 20:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
      break;
    case 21:
      fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {");
      break;
    case 22:
      fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {");
      break;
    case 23:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {");
      break;
    case 24:
      fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {");
      break;
    case 25:
      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
      break;
    case 26:
      fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {");
      break;
    case 27:
      fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {");
      break;
    case 28:
      fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {");
      break;
    }
  */
gabrielC's avatar
gabrielC committed
1167
  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
1168
  UE->n_connected_eNB = 1;
1169
  printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx);
1170 1171 1172 1173
  eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
                                   UE->frame_parms.nb_antennas_rx,
                                   channel_model,
                                   N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
1174
                                   N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
1175 1176 1177
                                   forgetting_factor,
                                   rx_sample_offset,
                                   0);
1178 1179
  reset_meas(&eNB2UE[0]->random_channel);
  reset_meas(&eNB2UE[0]->interp_time);
1180

1181
  if(num_rounds>1) {
1182
    for(n=1; n<4; n++) {
1183 1184 1185
      eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
                                       UE->frame_parms.nb_antennas_rx,
                                       channel_model,
1186 1187 1188
                                       N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
                                       N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                       forgetting_factor,
1189 1190
                                       rx_sample_offset,
                                       0);
1191 1192 1193
      reset_meas(&eNB2UE[n]->random_channel);
      reset_meas(&eNB2UE[n]->interp_time);
    }
1194
  }
1195

1196
  if (eNB2UE[0]==NULL) {
1197
    printf("Problem generating channel model. Exiting.\n");
1198 1199 1200 1201 1202 1203 1204 1205 1206
    exit(-1);
  }

  if ((transmission_mode == 3) || (transmission_mode==4))
    Kmimo=2;
  else
    Kmimo=1;

  switch (ue_category) {
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
    case 1:
      Nsoft = 250368;
      break;

    case 2:
    case 3:
      Nsoft = 1237248;
      break;

    case 4:
      Nsoft = 1827072;
      break;

    default:
      printf("Unsupported UE category %d\n",ue_category);
      exit(-1);
      break;
1224 1225
  }

1226
  for (k=0; k<NUMBER_OF_UE_MAX; k++) {
1227 1228
    // Create transport channel structures for 2 transport blocks (MIMO)
    for (i=0; i<2; i++) {
1229
      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1230 1231 1232

      if (!eNB->dlsch[k][i]) {
        printf("Can't get eNB dlsch structures\n");
1233
        exit(-1);
1234 1235
      }

1236 1237 1238 1239
      eNB->dlsch[k][i]->rnti = n_rnti+k;
    }
  }

1240 1241 1242 1243 1244 1245 1246 1247
  /* allocate memory for both subframes (only one is really used
   * but there is now "copy_harq_proc_struct" which needs both
   * to be valid)
   * TODO: refine this somehow (necessary?)
   */
  for (sf = 0; sf < 2; sf++) {
    for (i=0; i<2; i++) {
      UE->dlsch[sf][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
1248

1249 1250 1251 1252
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
      }
1253

1254 1255
      UE->dlsch[sf][0][i]->rnti   = n_rnti;
    }
1256 1257
  }

1258 1259 1260
  UE->dlsch_SI[0]  = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
  UE->dlsch_ra[0]  = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
  UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
1261
  // structure for SIC at UE
1262
  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1263 1264

  if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
1265
    eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
1266

1267 1268
    if (n_users>1)
      eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
1269
  } else {
1270
    eNB->UE_stats[0].DL_pmi_single = 0;
1271

1272 1273
    if (n_users>1)
      eNB->UE_stats[1].DL_pmi_single = 0;
1274
  }
1275

1276
  L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc;
laurent's avatar
laurent committed
1277 1278 1279 1280 1281 1282
  proc_eNB->threadPool=(tpool_t*)malloc(sizeof(tpool_t));
  proc_eNB->respEncode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  proc_eNB->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
  initTpool("n", proc_eNB->threadPool, true);
  initNotifiedFIFO(proc_eNB->respEncode);
  initNotifiedFIFO(proc_eNB->respDecode);
1283

1284
  proc_eNB->frame_tx=0;
1285

1286
  if (input_fd==NULL) {
1287
    DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols;
1288 1289
    DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
    TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
1290 1291
    // UE specific DCI
    fill_DCI(eNB,
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
             proc_eNB->frame_tx,subframe,
             &sched_resp,
             input_buffer,
             n_rnti,
             n_users,
             transmission_mode,
             0,
             common_flag,
             NB_RB,
             DLSCH_RB_ALLOC,
             TPC,
             mcs1,
             mcs2,
             1,
             0,
             pa,
             &num_common_dci,
             &num_ue_spec_dci,
             &num_dci);
1311
    numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
1312

1313
    if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d, num_dci %d/%d/%d\n",num_pdcch_symbols,numCCE, num_dci,num_ue_spec_dci,num_common_dci);
1314
  }
1315

1316
  snr_step = input_snr_step;
1317 1318
  UE->high_speed_flag = 1;
  UE->ch_est_alpha=0;
1319

1320 1321
  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
    if(abstx) {
1322 1323 1324
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
    }

1325
    for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
tct-labo4's avatar
tct-labo4 committed
1326
      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
1327 1328 1329 1330
      errs[0]=0;
      errs[1]=0;
      errs[2]=0;
      errs[3]=0;
1331 1332 1333 1334
      errs2[0]=0;
      errs2[1]=0;
      errs2[2]=0;
      errs2[3]=0;
1335 1336 1337 1338
      round_trials[0] = 0;
      round_trials[1] = 0;
      round_trials[2] = 0;
      round_trials[3] = 0;
1339 1340 1341 1342
      dci_errors[0]=0;
      dci_errors[1]=0;
      dci_errors[2]=0;
      dci_errors[3]=0;
1343
      //      avg_ber = 0;
1344
      round=0;
1345 1346
      avg_iter = 0;
      iter_trials=0;
1347 1348 1349 1350 1351 1352 1353 1354 1355
      reset_meas(&eNB->phy_proc_tx); // total eNB tx
      reset_meas(&eNB->dlsch_scrambling_stats);
      reset_meas(&UE->dlsch_unscrambling_stats);
      reset_meas(&eNB->ofdm_mod_stats);
      reset_meas(&eNB->dlsch_modulation_stats);
      reset_meas(&eNB->dlsch_encoding_stats);
      reset_meas(&eNB->dlsch_interleaving_stats);
      reset_meas(&eNB->dlsch_rate_matching_stats);
      reset_meas(&eNB->dlsch_turbo_encoding_stats);
laurent's avatar
laurent committed
1356 1357
      reset_meas(&eNB->dlsch_common_and_dci);
      reset_meas(&eNB->dlsch_ue_specific);
1358

laurent's avatar
laurent committed
1359
      for (int i=0; i<RX_NB_TH; i++) {
1360 1361
        reset_meas(&UE->phy_proc_rx[i]); // total UE rx
        reset_meas(&UE->ue_front_end_stat[i]);
laurent's avatar
laurent committed
1362
        reset_meas(&UE->pdsch_procedures_stat[i]);
1363 1364 1365 1366
        reset_meas(&UE->dlsch_procedures_stat[i]);
        reset_meas(&UE->dlsch_decoding_stats[i]);
        reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]);
        reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]);
laurent's avatar
laurent committed
1367
      }
1368 1369

      reset_meas(&UE->ofdm_demod_stats);
laurent's avatar
laurent committed
1370
      reset_meas(&UE->crnti_procedures_stats);
1371 1372 1373
      reset_meas(&UE->dlsch_channel_estimation_stats);
      reset_meas(&UE->dlsch_freq_offset_estimation_stats);
      reset_meas(&UE->rx_dft_stats);
1374 1375
      reset_meas(&UE->dlsch_decoding_stats[0]);
      reset_meas(&UE->dlsch_decoding_stats[1]);
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
      reset_meas(&UE->dlsch_turbo_decoding_stats);
      reset_meas(&UE->dlsch_deinterleaving_stats);
      reset_meas(&UE->dlsch_rate_unmatching_stats);
      reset_meas(&UE->dlsch_tc_init_stats);
      reset_meas(&UE->dlsch_tc_alpha_stats);
      reset_meas(&UE->dlsch_tc_beta_stats);
      reset_meas(&UE->dlsch_tc_gamma_stats);
      reset_meas(&UE->dlsch_tc_ext_stats);
      reset_meas(&UE->dlsch_tc_intl1_stats);
      reset_meas(&UE->dlsch_tc_intl2_stats);
1386
      // initialization
1387
      // initialization
laurent's avatar
laurent committed
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
      varArray_t *table_tx=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_mod=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_enc=initVarArray(1000,sizeof(double));
      varArray_t *table_rx=initVarArray(1000,sizeof(double));
      time_stats_t phy_proc_rx_tot;
      time_stats_t pdsch_procedures_tot;
      time_stats_t dlsch_procedures_tot;
      time_stats_t dlsch_decoding_tot;
      time_stats_t dlsch_llr_tot;
      time_stats_t ue_front_end_tot;
      varArray_t *table_rx_fft=initVarArray(1000,sizeof(double));
      varArray_t *table_rx_demod=initVarArray(1000,sizeof(double));
      varArray_t *table_rx_dec=initVarArray(1000,sizeof(double));
1402

1403
      for (trials = 0; trials<n_frames; trials++) {
1404
        //printf("Trial %d\n",trials);
1405 1406 1407 1408
        fflush(stdout);
        round=0;
        //if (trials%100==0)
        eNB2UE[0]->first_run = 1;
1409 1410
        UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0;
        UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0;
1411

gabrielC's avatar
gabrielC committed
1412
        while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) {
1413
          //    printf("Trial %d, round %d\n",trials,round);
1414 1415
          round_trials[round]++;

1416 1417 1418 1419
          //if(transmission_mode>=5)
          //  pmi_feedback=1;
          //else
          //  pmi_feedback=0;
1420 1421 1422 1423 1424 1425 1426 1427 1428

          if (abstx) {
            if (trials==0 && round==0 && SNR==snr0)  //generate a new channel
              hold_channel = 0;
            else
              hold_channel = 1;
          } else
            hold_channel = 0;//(round==0) ? 0 : 1;

1429
          //PMI_FEEDBACK:
1430 1431

          //  printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
1432
          for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1433
            memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
1434 1435 1436 1437
          }

          if (input_fd==NULL) {
            // Simulate HARQ procedures!!!
1438
            memset(CCE_table,0,800*sizeof(int));
1439

1440 1441 1442 1443
            if (/*common_flag == 0*/ 1) {
              num_dci=0;
              num_common_dci=0;
              num_ue_spec_dci=0;
1444

1445 1446
              if (round == 0) {   // First round
                TB0_active = 1;
1447
                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
                DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
                TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
                fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC,
                         mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci);
              } else {
                DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
                TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
                fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC,
                         (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci);
              }
            }
1459

1460 1461 1462 1463
            proc_eNB->subframe_tx = subframe;
            sched_resp.subframe=subframe;
            sched_resp.frame=proc_eNB->frame_tx;
            eNB->abstraction_flag=0;
1464
            schedule_response(&sched_resp, proc_eNB);
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484
            phy_procedures_eNB_TX(eNB,proc_eNB,1);

            if (uncoded_ber_bit == NULL) {
              // this is for user 0 only
              printf("nb_rb %d, rb_alloc %x, mcs %d\n",
                     eNB->dlsch[0][0]->harq_processes[0]->nb_rb,
                     eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0],
                     eNB->dlsch[0][0]->harq_processes[0]->mcs);
              coded_bits_per_codeword = get_G(&eNB->frame_parms,
                                              eNB->dlsch[0][0]->harq_processes[0]->nb_rb,
                                              eNB->dlsch[0][0]->harq_processes[0]->rb_alloc,
                                              get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
                                              eNB->dlsch[0][0]->harq_processes[0]->Nl,
                                              num_pdcch_symbols,
                                              0,
                                              subframe,
                                              transmission_mode>=7?transmission_mode:0);
              uncoded_ber_bit = (short *) malloc(sizeof(short)*coded_bits_per_codeword);
              printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
            }
1485

1486
            start_meas(&eNB->ofdm_mod_stats);
1487
            ru->proc.tti_tx=subframe;
1488
            memcpy((void *)ru->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
1489 1490
            feptx_prec(ru,proc_eNB->frame_tx,subframe);
            feptx_ofdm(ru,proc_eNB->frame_tx,subframe);
1491 1492 1493 1494 1495 1496 1497
            stop_meas(&eNB->ofdm_mod_stats);
            // generate next subframe for channel estimation
            DL_req.dl_config_request_body.number_dci=0;
            DL_req.dl_config_request_body.number_pdu=0;
            TX_req.tx_request_body.number_of_pdus=0;
            proc_eNB->subframe_tx = subframe+1;
            sched_resp.subframe=subframe+1;
1498
            schedule_response(&sched_resp, proc_eNB);
1499
            phy_procedures_eNB_TX(eNB,proc_eNB,0);
1500
            ru->proc.tti_tx=(subframe+1)%10;
1501 1502
            feptx_prec(ru,proc_eNB->frame_tx,subframe+1);
            feptx_ofdm(ru,proc_eNB->frame_tx,subframe+1);
1503
            proc_eNB->frame_tx++;
1504
            tx_lev = 0;
1505

1506
            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1507
              tx_lev += signal_energy(&ru->common.txdata[aa]
1508 1509
                                      [subframe*eNB->frame_parms.samples_per_tti],
                                      eNB->frame_parms.samples_per_tti);
1510 1511
            }

1512
            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
1513

1514
            if (n_frames==1) {
1515
              printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB);
bruno mongazon's avatar
bruno mongazon committed
1516
              LOG_M("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1);
Xiwen JIANG's avatar
Xiwen JIANG committed
1517 1518

              if (transmission_mode<7) {
1519
                LOG_M("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
Xiwen JIANG's avatar
Xiwen JIANG committed
1520
              } else if (transmission_mode == 7) {
bruno mongazon's avatar
bruno mongazon committed
1521 1522
                LOG_M("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
                LOG_M("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1);
Xiwen JIANG's avatar
Xiwen JIANG committed
1523
              }
1524
            }
1525
          }
1526

1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
          DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd);
          UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
          proc->subframe_rx = subframe;
          UE->UE_mode[0] = PUSCH;
          // first symbol has to be done separately in one-shot mode
          slot_fep(UE,
                   0,
                   (proc->subframe_rx<<1),
                   UE->rx_offset,
                   0,
                   0);
1538

1539
          if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
1540

1541 1542 1543
          if (dci_flag==0) {
            memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t));
            UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
1544

1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
            if (n_frames==1)
              printf("bypassing PDCCH/DCI detection\n");

            if  (generate_ue_dlsch_params_from_dci(proc->frame_rx,
                                                   proc->subframe_rx,
                                                   (void *)&dci_alloc[0].dci_pdu,
                                                   common_flag == 0 ? n_rnti : SI_RNTI,
                                                   dci_alloc[0].format,
                                                   UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
                                                   UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
                                                   UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
                                                   &UE->frame_parms,
                                                   UE->pdsch_config_dedicated,
                                                   SI_RNTI,
                                                   0,
                                                   P_RNTI,
                                                   UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id],
                                                   0)==0) {
              dump_dci(&UE->frame_parms, &dci_alloc[0]);
              //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1;
              //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1;
              UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
              UE->dlsch_received[eNB_id]++;
            } else {
              LOG_E(PHY,"Problem in DCI!\n");
            }
          }
1572

1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
          dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
          phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx);
          dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;

          if (dci_flag && (dci_received == 0)) {
            printf("DCI not received\n");
            dci_errors[round]++;
            LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
            LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
            LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
            LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
            LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
            LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
            exit(-1);
          }
1588

1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600
          int bit_errors=0;

          if ((test_perf ==0 ) && (n_frames==1)) {
            dlsch_unscrambling(&eNB->frame_parms,
                               0,
                               UE->dlsch[UE->current_thread_id[subframe]][0][0],
                               coded_bits_per_codeword,
                               UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0],
                               0,
                               subframe<<1);

            for (i=0; i<coded_bits_per_codeword; i++)
laurent's avatar
laurent committed
1601 1602
              if ((eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
                  (eNB->dlsch[0][0]->harq_processes[0]->eDL[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
1603 1604
                uncoded_ber_bit[bit_errors++] = 1;
                printf("error in pos %d : %d => %d\n",i,
laurent's avatar
laurent committed
1605
                       eNB->dlsch[0][0]->harq_processes[0]->eDL[i],
1606 1607 1608 1609 1610 1611 1612 1613
                       UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
              } else {
                /*
                printf("no error in pos %d : %d => %d\n",i,
                       eNB->dlsch[0][0]->harq_processes[0]->e[i],
                       UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]);
                */
              }
1614

1615 1616
            LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
            LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
1617

1618 1619
            if (eNB->frame_parms.nb_antennas_tx>1)
              LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
1620

1621 1622 1623
            //common vars
            LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
            LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1624

1625 1626 1627 1628
            if (UE->frame_parms.nb_antennas_rx>1) {
              LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
              LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
            }
1629

1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
            LOG_M("dlsch00_r0.m","dl00_r0",
                  &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                  UE->frame_parms.ofdm_symbol_size*nsymb,1,1);

            if (UE->frame_parms.nb_antennas_rx>1)
              LOG_M("dlsch01_r0.m","dl01_r0",
                    &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                    UE->frame_parms.ofdm_symbol_size*nsymb,1,1);

            if (eNB->frame_parms.nb_antennas_tx>1)
              LOG_M("dlsch10_r0.m","dl10_r0",
                    &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                    UE->frame_parms.ofdm_symbol_size*nsymb,1,1);

            if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
              LOG_M("dlsch11_r0.m","dl11_r0",
                    &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                    UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);

            //pdsch_vars
            printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword);
            dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
laurent's avatar
laurent committed
1652
            LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->eDL,coded_bits_per_codeword,1,4);
1653 1654 1655 1656 1657 1658
            //pdcch_vars
            LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
            LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
            LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
            LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
          }
1659

gabrielC's avatar
gabrielC committed
1660 1661
          if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) {
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
1662 1663 1664
            iter_trials++;

            if (n_frames==1)
1665
              printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword);
1666

gabrielC's avatar
gabrielC committed
1667
            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
1668
            TB0_active = 0;
1669 1670
          } // DLSCH received ok
          else {
1671
            errs[round]++;
gabrielC's avatar
gabrielC committed
1672
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
1673 1674 1675 1676
            iter_trials++;

            if (n_frames==1) {
              //if ((n_frames==1) || (SNR>=30)) {
1677
              printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword);
1678

gabrielC's avatar
gabrielC committed
1679 1680 1681
              for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
                if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
1682
                else
gabrielC's avatar
gabrielC committed
1683
                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
1684 1685 1686 1687 1688

                Kr_bytes = Kr>>3;
                printf("Decoded_output (Segment %d):\n",s);

                for (i=0; i<Kr_bytes; i++)
1689 1690
                  printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],
                         UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
1691 1692 1693
              }

              sprintf(fname,"rxsig0_r%d.m",round);
1694
              sprintf(vname,"rxs0_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1695
              LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
1696
              sprintf(fname,"rxsigF0_r%d.m",round);
1697
              sprintf(vname,"rxs0F_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1698
              LOG_M(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1699

1700
              if (UE->frame_parms.nb_antennas_rx>1) {
1701 1702
                sprintf(fname,"rxsig1_r%d.m",round);
                sprintf(vname,"rxs1_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1703
                LOG_M(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
1704
                sprintf(fname,"rxsigF1_r%d.m",round);
1705
                sprintf(vname,"rxs1F_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1706
                LOG_M(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1707 1708 1709
              }

              sprintf(fname,"dlsch00_r%d.m",round);
1710
              sprintf(vname,"dl00_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1711
              LOG_M(fname,vname,
1712 1713
                    &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                    UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1714

1715
              if (UE->frame_parms.nb_antennas_rx>1) {
1716
                sprintf(fname,"dlsch01_r%d.m",round);
1717
                sprintf(vname,"dl01_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1718
                LOG_M(fname,vname,
1719 1720
                      &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                      UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1721 1722
              }

1723
              if (eNB->frame_parms.nb_antennas_tx>1) {
1724
                sprintf(fname,"dlsch10_r%d.m",round);
1725
                sprintf(vname,"dl10_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1726
                LOG_M(fname,vname,
1727 1728
                      &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                      UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1729 1730
              }

1731
              if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
1732
                sprintf(fname,"dlsch11_r%d.m",round);
1733
                sprintf(vname,"dl11_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1734
                LOG_M(fname,vname,
1735 1736
                      &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                      UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1737 1738 1739
              }

              //pdsch_vars
gabrielC's avatar
gabrielC committed
1740
              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
bruno mongazon's avatar
bruno mongazon committed
1741 1742 1743 1744
              //LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
              //LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
              //LOG_M("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
              //LOG_M("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
1745 1746 1747 1748 1749
              //pdcch_vars
              LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
              LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
              LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1);
              LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4);
1750

1751 1752 1753 1754 1755
              if (round == 3) exit(-1);
            }

            //      printf("round %d errors %d/%d\n",round,errs[round],trials);
            round++;
gabrielC's avatar
gabrielC committed
1756
            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
1757 1758
          }

1759 1760 1761 1762 1763 1764 1765
          if (xforms==1) {
            phy_scope_UE(form_ue,
                         UE,
                         eNB_id,
                         0,// UE_id
                         subframe);
          }
1766

1767 1768
          UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
        }  //round
1769 1770 1771 1772 1773 1774 1775 1776 1777

        //      printf("\n");

        if ((errs[0]>=n_frames/10) && (trials>(n_frames/2)))
          break;

        //len = chbch_stats_read(stats_buffer,NULL,0,4096);
        //printf("%s\n\n",stats_buffer);

tct-labo4's avatar
tct-labo4 committed
1778
        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
1779 1780 1781 1782
          UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
          LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
                UE->bitrate[eNB_id]/1000);
          UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id];
1783 1784 1785 1786 1787
        }

        /* calculate the total processing time for each packet,
         * get the max, min, and number of packets that exceed t>2000us
         */
1788
        double t_tx = inMicroS(eNB->phy_proc_tx.p_time);
laurent's avatar
laurent committed
1789 1790
        double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time);
        double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time);
1791 1792 1793 1794 1795 1796 1797
        sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]);
        sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]);
        sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]);
        sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]);
        sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]);
        sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]);
        double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time);
laurent's avatar
laurent committed
1798 1799 1800 1801
        double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time);
        double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time);

        if (t_tx > 2000 )// 2ms is too much time for a subframe
1802 1803
          n_tx_dropped++;

laurent's avatar
laurent committed
1804
        if (t_rx > 2000 )
1805 1806
          n_rx_dropped++;

1807
        appendVarArray(table_tx, &t_tx);
laurent's avatar
laurent committed
1808 1809 1810 1811 1812
        appendVarArray(table_tx_ifft, &t_tx_ifft);
        appendVarArray(table_rx, &t_rx );
        appendVarArray(table_rx_fft, &t_rx_fft );
        appendVarArray(table_rx_demod, &t_rx_demod );
        appendVarArray(table_rx_dec, &t_rx_dec );
1813
      }   //trials
1814

1815
      // round_trials[0]: number of code word : goodput the protocol
1816
      // sort table
laurent's avatar
laurent committed
1817 1818 1819 1820 1821 1822 1823 1824
      qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble);
      qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble);
1825

Navid Nikaein's avatar
Navid Nikaein committed
1826
      if (dump_table == 1 ) {
1827
        set_component_filelog(SIM);  // file located in /tmp/usim.txt
laurent's avatar
laurent committed
1828 1829
        LOG_UDUMPMSG(SIM,table_tx,table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n");
        LOG_UDUMPMSG(SIM,table_rx,table_rx->size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n");
Navid Nikaein's avatar
Navid Nikaein committed
1830
      }
1831

1832
      effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]));
1833
      printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n",
1834
             SNR,
1835
             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)));
1836
      printf("Errors (%u(%u)/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e), dci_errors %u/%u, Pe = %e => effective rate %f, normalized delay %f (%f)\n",
1837 1838 1839 1840
             errs[0],
             errs2[0],
             round_trials[0],
             errs[1],
1841
             round_trials[1],
1842
             errs[2],
1843
             round_trials[2],
1844
             errs[3],
1845
             round_trials[3],
1846
             (double)errs[0]/(round_trials[0]),
1847 1848 1849
             (double)errs[1]/(round_trials[1]),
             (double)errs[2]/(round_trials[2]),
             (double)errs[3]/(round_trials[3]),
1850 1851 1852 1853
             dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3],
             round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
             (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]),
             //rate*effective_rate,
1854
             100*effective_rate,
1855
             //rate,
gabrielC's avatar
gabrielC committed
1856
             //rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
1857
             (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
1858
             (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
1859
             (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
laurent's avatar
laurent committed
1860
      double timeBase=1/(1000*cpu_freq_GHz);
1861

1862
      if (print_perf==1) {
laurent's avatar
laurent committed
1863
        printf("\neNB TX function statistics (per 1ms subframe)\n");
1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
        printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx");
        printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time");
        printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time");
        printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time");
        printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time");
        printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time");
        printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time");
        printStatIndent2(&eNB->dlsch_scrambling_stats,  "DLSCH scrambling time");
        printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time");
        printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time");
laurent's avatar
laurent committed
1874
        printf("\nUE RX function statistics (per 1ms subframe)\n");
1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885
        printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx");
        printStatIndent(&ue_front_end_tot,"Front end processing");
        printStatIndent(&dlsch_llr_tot,"rx_pdsch processing");
        printStatIndent2(&pdsch_procedures_tot,"pdsch processing");
        printStatIndent2(&dlsch_procedures_tot,"dlsch processing");
        printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing");
        printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation");
        printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time");
        printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time");
        printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time ");
        printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time");
laurent's avatar
laurent committed
1886
        printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching");
1887 1888 1889 1890
        printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f       %.2f us (%d cycles, %d trials)\n",
               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ?
               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus :
               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
laurent's avatar
laurent committed
1891 1892 1893 1894
               UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials,
               (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase,
               (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials),
               UE->dlsch_turbo_decoding_stats.trials);
laurent's avatar
laurent committed
1895 1896 1897 1898 1899 1900 1901
        printStatIndent2(&UE->dlsch_tc_init_stats,"init");
        printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha");
        printStatIndent2(&UE->dlsch_tc_beta_stats,"beta");
        printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma");
        printStatIndent2(&UE->dlsch_tc_ext_stats,"ext");
        printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver");
        printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC");
1902 1903
      }

1904
      if ((transmission_mode != 3) && (transmission_mode != 4)) {
1905
        fprintf(bler_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n",
1906 1907
                SNR,
                mcs1,
1908
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
1909 1910 1911 1912 1913 1914 1915 1916 1917
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
1918
                dci_errors[0]);
1919
      } else {
1920
        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n",
1921 1922
                SNR,
                mcs1,mcs2,
1923 1924
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
                eNB->dlsch[0][1]->harq_processes[0]->TBS,
1925 1926 1927 1928 1929 1930 1931 1932 1933
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
1934
                dci_errors[0]);
1935
      }
1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947

      if(abstx) { //ABSTRACTION
        blerr[0] = (double)errs[0]/(round_trials[0]);

        if(num_rounds>1) {
          blerr[1] = (double)errs[1]/(round_trials[1]);
          blerr[2] = (double)errs[2]/(round_trials[2]);
          blerr[3] = (double)errs[3]/(round_trials[3]);
          fprintf(csv_fd,"%e,%e,%e,%e;\n",blerr[0],blerr[1],blerr[2],blerr[3]);
        } else {
          fprintf(csv_fd,"%e;\n",blerr[0]);
        }
1948
      } //ABStraction
1949

1950
      if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
1951 1952
        //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
        if ((transmission_mode != 3) && (transmission_mode != 4)) {
1953
          fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;",
1954 1955
                  SNR,
                  mcs1,
1956
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
1957 1958 1959 1960 1961 1962 1963 1964 1965
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
1966
                  dci_errors[0]);
1967
          //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
1968
          fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;",
1969 1970
                  SNR,
                  mcs1,
1971
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987
                  rate*effective_rate,
                  100*effective_rate,
                  rate,
                  (double)avg_iter/iter_trials,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
                  (double)errs[0]/(round_trials[0]),
                  (double)errs[1]/(round_trials[0]),
                  (double)errs[2]/(round_trials[0]),
                  (double)errs[3]/(round_trials[0]),
1988
                  dci_errors[0],
1989
                  round_trials[0],
1990
                  (double)dci_errors[0]/(round_trials[0]),
1991
                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
1992
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
1993 1994
                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
        } else {
1995
          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;",
1996 1997
                  SNR,
                  mcs1,mcs2,
1998 1999
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2000 2001 2002 2003 2004 2005 2006 2007 2008
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
2009
                  dci_errors[0]);
2010
          //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n");
2011
          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;",
2012 2013
                  SNR,
                  mcs1,mcs2,
2014 2015
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
                  rate*effective_rate,
                  100*effective_rate,
                  rate,
                  (double)avg_iter/iter_trials,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
                  (double)errs[0]/(round_trials[0]),
                  (double)errs[1]/(round_trials[0]),
                  (double)errs[2]/(round_trials[0]),
                  (double)errs[3]/(round_trials[0]),
2032
                  dci_errors[0],
2033
                  round_trials[0],
2034
                  (double)dci_errors[0]/(round_trials[0]),
2035
                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
2036
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2037 2038 2039 2040 2041
                  (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
        }

        //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n",
        fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;",
2042 2043 2044 2045 2046
                eNB->phy_proc_tx.trials,
                eNB->ofdm_mod_stats.trials,
                eNB->dlsch_modulation_stats.trials,
                eNB->dlsch_scrambling_stats.trials,
                eNB->dlsch_encoding_stats.trials,
laurent's avatar
laurent committed
2047
                phy_proc_rx_tot.trials,
2048 2049 2050 2051
                UE->ofdm_demod_stats.trials,
                UE->dlsch_rx_pdcch_stats.trials,
                UE->dlsch_llr_stats.trials,
                UE->dlsch_unscrambling_stats.trials,
tct-labo4's avatar
tct-labo4 committed
2052
                UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
2053 2054
               );
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
2055 2056 2057 2058 2059
                get_time_meas_us(&eNB->phy_proc_tx),
                get_time_meas_us(&eNB->ofdm_mod_stats),
                get_time_meas_us(&eNB->dlsch_modulation_stats),
                get_time_meas_us(&eNB->dlsch_scrambling_stats),
                get_time_meas_us(&eNB->dlsch_encoding_stats),
laurent's avatar
laurent committed
2060
                get_time_meas_us(&phy_proc_rx_tot),
2061 2062 2063 2064
                nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
                get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
                3*get_time_meas_us(&UE->dlsch_llr_stats),
                get_time_meas_us(&UE->dlsch_unscrambling_stats),
tct-labo4's avatar
tct-labo4 committed
2065
                get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
2066 2067
               );
        //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
laurent's avatar
laurent committed
2068
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped);
2069
        //fprintf(time_meas_fd,"IFFT;\n");
laurent's avatar
laurent committed
2070
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
2071
                squareRoot(&eNB->ofdm_mod_stats),
laurent's avatar
laurent committed
2072
                median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft));
2073
        //fprintf(time_meas_fd,"MOD;\n");
laurent's avatar
laurent committed
2074
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
2075
                squareRoot(&eNB->dlsch_modulation_stats),
laurent's avatar
laurent committed
2076
                median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod));
2077
        //fprintf(time_meas_fd,"ENC;\n");
laurent's avatar
laurent committed
2078
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
2079
                squareRoot(&eNB->dlsch_encoding_stats),
laurent's avatar
laurent committed
2080 2081 2082
                median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc));
        //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",
2083
                squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min,
laurent's avatar
laurent committed
2084
                median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped);
2085
        //fprintf(time_meas_fd,"FFT;\n");
laurent's avatar
laurent committed
2086
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
2087
                squareRoot(&UE->ofdm_demod_stats),
laurent's avatar
laurent committed
2088
                median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft));
2089
        //fprintf(time_meas_fd,"DEMOD;\n");
laurent's avatar
laurent committed
2090
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
2091
                squareRoot(&UE->dlsch_demodulation_stats),
laurent's avatar
laurent committed
2092
                median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod));
2093
        //fprintf(time_meas_fd,"DEC;\n");
laurent's avatar
laurent committed
2094
        fprintf(time_meas_fd,"%f;%f;%f;%f\n",
2095
                squareRoot(&UE->dlsch_decoding_stats[subframe]),
laurent's avatar
laurent committed
2096
                median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));
2097
        printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
2098
        test_passed = 1;
2099 2100 2101
        break;
      } else if (test_perf !=0 ) {
        printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
2102
        test_passed = 0;
2103 2104
      }

2105
      if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
2106 2107 2108 2109
        break;
    }// SNR
  } //ch_realization

2110
  fclose(bler_fd);
2111

2112 2113
  if (test_perf !=0)
    fclose (time_meas_fd);
2114

2115 2116
  //fprintf(tikz_fd,"};\n");
  //fclose(tikz_fd);
2117 2118 2119

  if (input_trch_file==1)
    fclose(input_trch_fd);
2120

2121 2122
  if (input_file==1)
    fclose(input_fd);
2123 2124

  if(abstx) { // ABSTRACTION
2125 2126 2127
    fprintf(csv_fd,"];");
    fclose(csv_fd);
  }
2128

2129 2130
  if (uncoded_ber_bit)
    free(uncoded_ber_bit);
2131 2132

  uncoded_ber_bit = NULL;
2133
  printf("Freeing dlsch structures\n");
2134 2135

  for (i=0; i<2; i++) {
2136
    printf("eNB %d\n",i);
2137
    free_eNB_dlsch(eNB->dlsch[0][i]);
2138
    printf("UE %d\n",i);
gabrielC's avatar
gabrielC committed
2139
    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
2140
  }
2141

2142 2143
  if (test_perf && !test_passed)
    return(-1);
Cedric Roux's avatar
Cedric Roux committed
2144
  else
2145
    return(0);
2146
}
2147 2148 2149 2150
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
uint64_t get_softmodem_optmask(void) {
  return 0;
}