dlsim.c 85.5 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 38
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <execinfo.h>
#include <signal.h>

39
#include "SIMULATION/TOOLS/sim.h"
40
#include "PHY/types.h"
41 42 43
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/phy_vars.h"
44

45 46 47
#include "SCHED/sched_eNB.h"
#include "SCHED/sched_common_vars.h"
#include "LAYER2/MAC/mac_vars.h"
48 49

#include "OCG_vars.h"
50
#include "common/utils/LOG/log.h"
51
#include "UTIL/LISTS/list.h"
52

53 54
#include "unitary_defs.h"

55 56 57

#include "PHY/TOOLS/lte_phy_scope.h"

58 59
#include "dummy_functions.c"

60 61 62 63 64 65 66
#include "PHY/MODULATION/modulation_common.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "SCHED/sched_eNB.h"
#include "SCHED_UE/sched_UE.h"
67 68 69
#include "common/config/config_load_configmodule.h"
#include "PHY/INIT/phy_init.h"

Raymond Knopp's avatar
Raymond Knopp committed
70

71 72
void feptx_ofdm(RU_t *ru);
void feptx_prec(RU_t *ru);
73

74
double cpuf;
laurent's avatar
laurent committed
75 76 77
#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>
78

79
int otg_enabled=0;
80 81 82 83 84 85 86
/*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 */
87

88 89
char *parallel_config = NULL;
char *worker_config = NULL;
90
static THREAD_STRUCT thread_struct;
91
void set_parallel_conf(char *parallel_conf)
92
{
93 94 95 96
  if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0)           thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD;
  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0)        thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT;
  else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0)    thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT;
  printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf);
97
} 
98
void set_worker_conf(char *worker_conf)
99
{
100 101 102
  if(strcmp(worker_conf,"WORKER_DISABLE")==0)                     thread_struct.worker_conf = WORKER_DISABLE;
  else if(strcmp(worker_conf,"WORKER_ENABLE")==0)                 thread_struct.worker_conf = WORKER_ENABLE;
  printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf);
103 104 105 106 107 108 109 110 111
} 
PARALLEL_CONF_t get_thread_parallel_conf(void)
{
  return thread_struct.parallel_conf;
} 
WORKER_CONF_t get_thread_worker_conf(void)
{
  return thread_struct.worker_conf;
} 
112

Raymond Knopp's avatar
Raymond Knopp committed
113 114
int emulate_rf = 0;

115 116
void handler(int sig)
{
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  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;
137
#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
138 139
//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
//#define DLSCH_RB_ALLOC 0x0001
140
void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
141
{
142 143 144 145 146 147 148 149 150 151 152

  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
153
                   &txdata[aa][slot_offset],         // output
154
                   frame_parms->ofdm_symbol_size,
155 156 157
                   6,                 // number of symbols
                   frame_parms->nb_prefix_samples,               // number of prefix samples
                   CYCLIC_PREFIX);
158 159
    else {
      normal_prefix_mod(&txdataF[aa][slot_offset_F],
160 161 162
                        &txdata[aa][slot_offset],
                        7,
                        frame_parms);
163
    }
164

165 166

  }
167

168 169
}

170
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],
171
		double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) {
172

173 174 175 176
  int i,u;
  int aa,aarx,aatx;
  double channelx,channely;
  double sigma2_dB,sigma2;
177 178
  double iqim=0.0;

179 180
  //    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++) {
181
    for (aa=0; aa<ru->frame_parms.nb_antennas_tx; aa++) {
182
      if (awgn_flag == 0) {
183 184
	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]);
185 186 187
      } else {
	for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
	  if (aa==0) {
188 189
	    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]);
190
	  } else {
191 192
	    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]);
193
	  }
194

195 196 197 198
	}
      }
    }
  }
199

200 201 202 203
  // Multipath channel
  if (awgn_flag == 0) {
    multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
		      2*UE->frame_parms.samples_per_tti,hold_channel);
204

205 206 207 208 209 210 211
    //      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) {
	random_channel(eNB2UE[1],0);
	random_channel(eNB2UE[2],0);
	random_channel(eNB2UE[3],0);
      }
212

213 214 215 216
    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);
      /*
bruno mongazon's avatar
bruno mongazon committed
217 218
	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);
219 220 221
      */
    }
  }
222 223


224 225 226
  if(abstx) {
    if (trials==0 && round==0) {
      // calculate freq domain representation to compute SINR
227
      freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
228 229
      // snr=pow(10.0,.1*SNR);
      fprintf(csv_fd,"%f,",SNR);
230

231
      for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
232 233 234 235 236 237 238
	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);
	  }
	}
239 240
      }

241
      if(num_rounds>1) {
242
	freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
243

244
	for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
245 246 247 248 249 250 251 252
	  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);
	    }
	  }
	}
253

254
	freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
255

256
	for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
257 258 259 260 261 262 263 264
	  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);
	    }
	  }
	}
265

266
	freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
267

268
	for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
269 270 271 272 273 274 275 276 277 278 279
	  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);
	    }
	  }
	}
      }
    }
  }
280

281
  //AWGN
282 283
  // tx_lev is the average energy over the whole subframe
  // but SNR should be better defined wrt the energy in the reference symbols
284
  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;
285 286 287
  sigma2 = pow(10,sigma2_dB/10);

  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
288
    for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) {
289 290 291 292 293 294 295 296
      //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
      ((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));
    }
  }
}
297

298 299
uint16_t
fill_tx_req(nfapi_tx_request_body_t *tx_req_body,
Cedric Roux's avatar
Cedric Roux committed
300
	    uint16_t                absSF,
301
	    uint16_t                pdu_length,
Cedric Roux's avatar
Cedric Roux committed
302
	    uint16_t                pdu_index,
303 304 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 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
	    uint8_t                 *pdu)
{
  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",
	tx_req_body->number_of_pdus, pdu_length);

  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
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,
		  //                             uint8_t codebook_index,
		  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)
{
  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,
	 sizeof(nfapi_dl_config_request_pdu_t));

  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;
  dl_req->number_pdu++;
}
377

378
void fill_DCI(PHY_VARS_eNB *eNB,
379
	      int frame,
380
	      int subframe,
381 382
	      Sched_Rsp_t *sched_resp,
	      uint8_t input_buffer[NUMBER_OF_UE_MAX][20000],
383 384 385
	      int n_rnti,
	      int n_users,
	      int transmission_mode,
386
	      int retrans,
387
	      int common_flag,
388
	      int NB_RB,
389 390 391 392 393 394
	      int DLSCH_RB_ALLOC,
	      int TPC,
	      int mcs1,
	      int mcs2,
	      int ndi,
	      int rv,
395
	      int pa,
396 397 398 399 400 401
	      int *num_common_dci,
	      int *num_ue_spec_dci,
	      int *num_dci) {

  int k;

402 403 404 405 406 407 408 409
  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;

  dl_req->number_dci=0;
  dl_req->number_pdu=0;
  TX_req->number_of_pdus=0;

410 411 412
  for(k=0; k<n_users; k++) {
    switch(transmission_mode) {
    case 1:
413

414
    case 2:
Xiwen JIANG's avatar
Xiwen JIANG committed
415 416

    case 7:
417
      if (common_flag == 0) {
418

419 420 421 422 423 424 425 426 427 428 429
	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 = NFAPI_DL_DCI_FORMAT_1;
	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 = n_rnti+k;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1;	// 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
Cedric Roux's avatar
Cedric Roux committed
430

431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
	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 = ndi;
	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 = DLSCH_RB_ALLOC;
	//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;


Cedric Roux's avatar
Cedric Roux committed
449 450
	fill_dlsch_config(dl_req,
			  get_TBS_DL(mcs1,NB_RB),
451
			  (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */
Cedric Roux's avatar
Cedric Roux committed
452
			  n_rnti,
453 454
			  0,	// type 0 allocation from 7.1.6 in 36.213
			  0,	// virtual_resource_block_assignment_flag, unused here
Cedric Roux's avatar
Cedric Roux committed
455 456
			  DLSCH_RB_ALLOC,	// resource_block_coding,
			  get_Qm(mcs1),
457 458 459 460 461 462 463 464
			  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
Cedric Roux's avatar
Cedric Roux committed
465
			  pa,    // pa
466 467 468 469 470 471 472 473 474
			  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,
Cedric Roux's avatar
Cedric Roux committed
475
		    get_TBS_DL(mcs1,NB_RB),
476 477 478 479
		    0,
		    input_buffer[k]);
      }
      else {
480

481
      }
482

483
      break;
484

485 486
    case 3:
      if (common_flag == 0) {
Cedric Roux's avatar
Cedric Roux committed
487

488
	if (eNB->frame_parms.nb_antennas_tx == 2) {
Cedric Roux's avatar
Cedric Roux committed
489

490
	  if (eNB->frame_parms.frame_type == TDD) {
Cedric Roux's avatar
Cedric Roux committed
491

492 493
	  }
	  else {
Cedric Roux's avatar
Cedric Roux committed
494

495 496 497 498
	  }
	}
      }
      break;
Cedric Roux's avatar
Cedric Roux committed
499

500 501
    case 4:
      if (common_flag == 0) {
Cedric Roux's avatar
Cedric Roux committed
502

503
	if (eNB->frame_parms.nb_antennas_tx == 2) {
Cedric Roux's avatar
Cedric Roux committed
504

505
	  if (eNB->frame_parms.frame_type == TDD) {
Cedric Roux's avatar
Cedric Roux committed
506

507

508
	  }
509

510
	  else {
511

512 513
	  }
	} else if (eNB->frame_parms.nb_antennas_tx == 4) {
514

515
	}
516

517 518
      }
      else {
519

520
        }
521

522
        break;
523

524 525
      case 5:
      case 6:
526

527
        break;
528

529 530 531 532
    default:
      printf("Unsupported Transmission Mode %d!!!\n",transmission_mode);
      exit(-1);
      break;
533
    }
534 535 536 537
  }
  *num_dci         = dl_req->number_dci;
  *num_ue_spec_dci = dl_req->number_dci;
  *num_common_dci  = 0;
538
}
539

540
int n_users = 1;
laurent's avatar
laurent committed
541
int subframe=7;
542 543
int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
uint16_t n_rnti=0x1234;
laurent's avatar
laurent committed
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
int nfapi_mode=0;
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;
568

569 570
int main(int argc, char **argv)
{
571

572
  int k,i,j,aa;
Xiwen JIANG's avatar
Xiwen JIANG committed
573
  int re;
574

575
  int s,Kr,Kr_bytes;
576 577


578
  LTE_DL_FRAME_PARMS *frame_parms;
579 580 581 582 583 584
  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];
  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};
585

586

laurent's avatar
laurent committed
587
  uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
588

589
  int eNB_id = 0;
laurent's avatar
laurent committed
590
  unsigned char round;
591 592
  unsigned char i_mod = 2;
  unsigned short NB_RB;
593

594

595 596
  SCM_t channel_model=Rayleigh1;
  //  unsigned char *input_data,*decoded_output;
597

598 599
  DCI_ALLOC_t da;
  DCI_ALLOC_t *dci_alloc = &da;
600

601
  unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0;
602

603 604 605 606 607 608 609
  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));

610
  //int re_allocated;
611 612 613 614 615 616 617
  char fname[32],vname[32];
  FILE *bler_fd;
  char bler_fname[256];
  FILE *time_meas_fd;
  char time_meas_fname[256];
  //  FILE *tikz_fd;
  //  char tikz_fname[256];
618

619 620 621 622
  FILE *input_trch_fd=NULL;
  unsigned char input_trch_file=0;
  FILE *input_fd=NULL;
  unsigned char input_file=0;
623

624
  channel_desc_t *eNB2UE[4];
625
  //uint8_t num_pdcch_symbols_2=0;
626 627
  //char stats_buffer[4096];
  //int len;
628

629
  //int u;
630
  int n=0;
631
  //int iii;
632

633
  int ch_realization;
634
  //int pmi_feedback=0;
635
  int hold_channel=0;
636

637 638 639
  // void *data;
  // int ii;
  //  int bler;
640
  double blerr[4];
641
  short *uncoded_ber_bit=NULL;
laurent's avatar
laurent committed
642
  int osf=1;
643 644 645
  frame_t frame_type = FDD;
  FD_lte_phy_scope_ue *form_ue = NULL;
  char title[255];
646

647
  int numCCE=0;
648
  //int dci_length_bytes=0,dci_length=0;
649 650
  //double channel_bandwidth = 5.0, sampling_rate=7.68;
  int common_flag=0,TPC=0;
651

652 653 654 655
  double cpu_freq_GHz;
  //  time_stats_t ts;//,sts,usts;
  int avg_iter,iter_trials;
  int rballocset=0;
656
  int test_passed=0;
657

658 659
  double effective_rate=0.0;
  char channel_model_input[10]="I";
660

661
  int TB0_active = 1;
662

663 664 665 666 667
  //  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;
668
  int sf;
669 670
  int CCE_table[800];
  opp_enabled=1; // to enable the time meas
671

672
  FILE *csv_fd=NULL;
laurent's avatar
laurent committed
673
  char csv_fname[FILENAME_MAX];
674
  int DLSCH_RB_ALLOC = 0;
675

676
  int dci_received;
677 678 679 680 681 682
  PHY_VARS_eNB *eNB;
  RU_t *ru;
  PHY_VARS_UE *UE;
  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
683
  nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU];
684 685 686 687
  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;
688

689 690 691
#if defined(__arm__)
  FILE    *proc_fd = NULL;
  char buf[64];
692

693 694 695 696 697 698
  proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
  if(!proc_fd)
     printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
  else {
     while(fgets(buf, 63, proc_fd))
        printf("%s", buf);
699
  }
700 701 702 703 704 705
  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);
706 707 708 709 710 711 712 713 714 715 716 717
  memset((void*)&sched_resp,0,sizeof(sched_resp));
  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;
  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));

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

719 720
  cpuf = cpu_freq_GHz;

721 722
  //signal(SIGSEGV, handler);
  //signal(SIGABRT, handler);
723

724 725 726 727 728
  // default parameters
  n_frames = 1000;
  snr0 = 0;
  //  num_layers = 1;
  perfect_ce = 0;
laurent's avatar
laurent committed
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
  static paramdef_t options[] = {
    { "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 },
    { "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 },
  };
776

laurent's avatar
laurent committed
777 778 779
  
  struct option * long_options = parse_oai_options(options); 
  
780

laurent's avatar
laurent committed
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
  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;
	    
	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:
            printf("not decoded type.\n");
            exit(1);
        }
810

laurent's avatar
laurent committed
811 812
      continue;
    }
813

laurent's avatar
laurent committed
814 815 816 817
    switch (long_options[option_index].name[0]) {
    case 'a':
      awgn_flag = 1;
      channel_model = AWGN;
818
      break;
819

820 821 822
    case 'D':
      frame_type=TDD;
      break;
823

824 825 826 827 828
    case 'e':
      num_rounds=1;
      common_flag = 1;
      TPC = atoi(optarg);
      break;
829

830 831 832
    case 'i':
      input_fd = fopen(optarg,"r");
      input_file=1;
833
      dci_flag = 1;
834
      break;
835

836 837 838 839
    case 'I':
      input_trch_fd = fopen(optarg,"r");
      input_trch_file=1;
      break;
840

841 842 843 844
    case 't':
      mcs_i = atoi(optarg);
      i_mod = get_Qm(mcs_i);
      break;
845

846 847 848 849
    case 'r':
      DLSCH_RB_ALLOC = atoi(optarg);
      rballocset = 1;
      break;
850

851
    case 'g':
laurent's avatar
laurent committed
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
    strncpy(channel_model_input,optarg,9);
    struct tmp {
      char opt;
      int m;
      int M;
    }
    tmp[]= {
      {'A',SCM_A,2},
          {'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;
          }
882

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

886 887 888
    case 'u':
      dual_stream_UE=1;
      UE->use_ia_receiver = 1;
889

Xiwen JIANG's avatar
Xiwen JIANG committed
890
      if ((n_tx_port!=2) || (transmission_mode!=5)) {
891
        printf("IA receiver only supported for TM5!");
892 893
        exit(-1);
      }
894

895
      break;
896

897 898
    case 'v':
      i_mod = atoi(optarg);
899

900
      if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
901
        printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
902 903
        exit(-1);
      }
904

905
      break;
906

Xiwen JIANG's avatar
Xiwen JIANG committed
907 908 909 910
    case 'q':
      n_tx_port=atoi(optarg);

      if ((n_tx_port==0) || ((n_tx_port>2))) {
911
        printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
Xiwen JIANG's avatar
Xiwen JIANG committed
912 913 914 915 916 917
        exit(-1);
      }

      break;


918 919
    case 'x':
      transmission_mode=atoi(optarg);
920

921 922 923 924 925
      if ((transmission_mode!=1) &&
          (transmission_mode!=2) &&
          (transmission_mode!=3) &&
          (transmission_mode!=4) &&
          (transmission_mode!=5) &&
Xiwen JIANG's avatar
Xiwen JIANG committed
926 927
          (transmission_mode!=6) &&
          (transmission_mode!=7)) {
928
        printf("Unsupported transmission mode %d\n",transmission_mode);
929 930
        exit(-1);
      }
931

Xiwen JIANG's avatar
Xiwen JIANG committed
932 933
      if (transmission_mode>1 && transmission_mode<7) {
        n_tx_port = 2;
934
      }
935

936
      break;
937

938
    case 'y':
Xiwen JIANG's avatar
Xiwen JIANG committed
939
      n_tx_phy=atoi(optarg);
940

Xiwen JIANG's avatar
Xiwen JIANG committed
941
      if (n_tx_phy < n_tx_port) {
942
        printf("n_tx_phy mush not be smaller than n_tx_port");
943 944
        exit(-1);
      }
945

Xiwen JIANG's avatar
Xiwen JIANG committed
946
      if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) {
947
        printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode);
Xiwen JIANG's avatar
Xiwen JIANG committed
948 949
        exit(-1);
      }
950

Xiwen JIANG's avatar
Xiwen JIANG committed
951
      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)) {
952
        printf("Physical number of antennas not supported for TM7.\n");
953 954
        exit(-1);
      }
955

956
      break;
957

958 959
    case 'z':
      n_rx=atoi(optarg);
960

961
      if ((n_rx==0) || (n_rx>2)) {
962
        printf("Unsupported number of rx antennas %d\n",n_rx);
963 964
        exit(-1);
      }
965

966
      break;
967

968
    default:
laurent's avatar
laurent committed
969
      printf("Wrong option: %s\n",long_options[option_index].name);
970 971 972 973
      exit(1);
      break;
    }
  }
laurent's avatar
laurent committed
974 975 976 977 978 979 980 981 982 983 984

  if ( res != -1 ) {
    printf("A wrong option has been found\n");
    exit(1);
  }

  if (help || verbose )
     display_options_values(options, true);
  if (help)
    exit(0);
  
985 986
  set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT");
  set_worker_conf("WORKER_ENABLE");
987

988 989 990 991 992
  if (transmission_mode>1) pa=dBm3;
  printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa);

  AssertFatal(load_configmodule(argc,argv) != NULL,
	      "cannot load configuration module, exiting\n");
993
  logInit();
laurent's avatar
laurent committed
994
  set_glog_onlinelog(true);
995
  // enable these lines if you need debug info
996
  set_glog(loglvl);
laurent's avatar
laurent committed
997
  SET_LOG_DEBUG(UE_TIMING);
998 999 1000 1001 1002 1003
  // 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);


1004 1005 1006 1007 1008 1009
  if (common_flag == 0) {
    switch (N_RB_DL) {
    case 6:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
      num_pdcch_symbols = 3;
      break;
1010

1011 1012 1013
    case 25:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
      break;
1014

1015 1016 1017
    case 50:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
      break;
1018

1019 1020 1021 1022
    case 100:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
      break;
    }
1023

1024 1025 1026
    NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
  } else
    NB_RB = 4;
1027

1028 1029 1030 1031 1032
  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);
1033

1034 1035 1036 1037 1038 1039 1040
    if (!dual_stream_UE==0) {
      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);
    }
  }
1041

1042 1043 1044 1045
  if (transmission_mode==5) {
    n_users = 2;
    printf("dual_stream_UE=%d\n", dual_stream_UE);
  }
1046 1047
  RC.nb_L1_inst = 1;
  RC.nb_RU = 1;
1048

1049 1050
  lte_param_init(&eNB,&UE,&ru,
		 n_tx_port,
Xiwen JIANG's avatar
Xiwen JIANG committed
1051
		 n_tx_phy,
1052 1053
		 1,
                 n_rx,
1054 1055 1056 1057 1058 1059
		 transmission_mode,
		 extended_prefix_flag,
		 frame_type,
		 Nid_cell,
		 tdd_config,
		 N_RB_DL,
1060
		 pa,
1061 1062 1063
		 threequarter_fs,
		 osf,
		 perfect_ce);
1064 1065 1066 1067 1068 1069
  RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **));
  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");
1070
  if ((transmission_mode==1) || (transmission_mode==7)) {
1071 1072 1073
    for (aa=0; aa<ru->nb_tx; aa++)
     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;
1074 1075
  }

1076
  if (transmission_mode<7)
1077
     ru->do_precoding=0;
1078
  else
1079
     ru->do_precoding=1;
1080

1081
  eNB->mac_enabled=1;
1082 1083 1084 1085 1086
  if (two_thread_flag == 0) {
    eNB->te = dlsch_encoding;
  }
  else {
    eNB->te = dlsch_encoding_2threads;
1087 1088 1089 1090
    extern void init_td_thread(PHY_VARS_eNB *);
    extern void init_te_thread(PHY_VARS_eNB *);
    init_td_thread(eNB);
    init_te_thread(eNB);
1091 1092
  }

1093 1094
  // callback functions required for phy_procedures_tx

1095
  //  eNB_id_i = UE->n_connected_eNB;
1096

1097 1098 1099 1100
  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
1101
  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
1102

1103 1104
  snr1 = snr0+snr_int;
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
1105

1106
  uint8_t input_buffer[NUMBER_OF_UE_MAX][20000];
1107

Cedric Roux's avatar
Cedric Roux committed
1108
  for (i=0;i<n_users;i++)
1109
    for (j=0;j<20000;j++) input_buffer[i][j] = (uint8_t)((taus())&255);
1110

1111
  frame_parms = &eNB->frame_parms;
1112

1113
  nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
1114

1115 1116 1117
  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);
1118

1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
  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");
  if (bler_fd==NULL) {
    fprintf(stderr,"Cannot create file %s!\n",bler_fname);
    exit(-1);
  }
  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
1139
            N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
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 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
    //mkdir(dirname,0777);
    time_meas_fd = fopen(time_meas_fname,"w");
    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");
    fprintf(csv_fd,"data_all%d=[",mcs1);
    if (csv_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",csv_fname);
      exit(-1);
    }
  }

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

1256

gabrielC's avatar
gabrielC committed
1257
  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
1258
  UE->n_connected_eNB = 1;
1259

1260
  printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx);
1261 1262 1263 1264 1265 1266 1267 1268 1269
  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),
				   N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
                                   forgetting_factor,
                                   rx_sample_offset,
                                   0);

1270 1271
  reset_meas(&eNB2UE[0]->random_channel);
  reset_meas(&eNB2UE[0]->interp_time);
1272
  if(num_rounds>1) {
1273
    for(n=1; n<4; n++) {
1274 1275 1276 1277 1278 1279 1280 1281
      eNB2UE[n] = 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),
				       N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
				       forgetting_factor,
                                       rx_sample_offset,
                                       0);
1282 1283 1284
      reset_meas(&eNB2UE[n]->random_channel);
      reset_meas(&eNB2UE[n]->interp_time);
    }
1285
  }
1286
  
1287
  if (eNB2UE[0]==NULL) {
1288
    printf("Problem generating channel model. Exiting.\n");
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313
    exit(-1);
  }

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

  switch (ue_category) {
  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;
  }

1314
  for (k=0; k<NUMBER_OF_UE_MAX; k++) {
1315 1316
    // Create transport channel structures for 2 transport blocks (MIMO)
    for (i=0; i<2; i++) {
1317
      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1318 1319 1320

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

1324 1325 1326 1327
      eNB->dlsch[k][i]->rnti = n_rnti+k;
    }
  }

1328 1329 1330 1331 1332 1333 1334 1335
  /* 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);
1336

1337 1338 1339 1340
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
      }
1341

1342 1343
      UE->dlsch[sf][0][i]->rnti   = n_rnti;
    }
1344 1345
  }

1346 1347
    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);
1348
    UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
1349

1350
  // structure for SIC at UE
1351
  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364

  if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {

    eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);

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

    if (n_users>1)
      eNB->UE_stats[1].DL_pmi_single = 0;
  }
1365

1366
  eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]];
1367

1368
  if (input_fd==NULL) {
1369

1370
    DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols;
1371 1372
    DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
    TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
1373 1374
    // UE specific DCI
    fill_DCI(eNB,
1375 1376 1377
	     proc_eNB->frame_tx,subframe,
	     &sched_resp,
	     input_buffer,
1378 1379 1380
	     n_rnti,
	     n_users,
	     transmission_mode,
1381
	     0,
1382
	     common_flag,
1383
	     NB_RB,
1384 1385 1386 1387
	     DLSCH_RB_ALLOC,
	     TPC,
	     mcs1,
	     mcs2,
1388
	     1,
1389
	     0,
1390
	     pa,
1391 1392 1393
	     &num_common_dci,
	     &num_ue_spec_dci,
	     &num_dci);
1394

1395
    numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
1396

1397
    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);
1398

1399

1400

1401
  }
1402

1403
  snr_step = input_snr_step;
1404 1405
  UE->high_speed_flag = 1;
  UE->ch_est_alpha=0;
1406

1407 1408
  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
    if(abstx) {
1409 1410 1411
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
    }

1412
    for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
tct-labo4's avatar
tct-labo4 committed
1413
      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
1414 1415 1416 1417
      errs[0]=0;
      errs[1]=0;
      errs[2]=0;
      errs[3]=0;
1418 1419 1420 1421
      errs2[0]=0;
      errs2[1]=0;
      errs2[2]=0;
      errs2[3]=0;
1422 1423 1424 1425 1426
      round_trials[0] = 0;
      round_trials[1] = 0;
      round_trials[2] = 0;
      round_trials[3] = 0;

1427 1428 1429 1430
      dci_errors[0]=0;
      dci_errors[1]=0;
      dci_errors[2]=0;
      dci_errors[3]=0;
1431
      //      avg_ber = 0;
1432 1433

      round=0;
1434 1435
      avg_iter = 0;
      iter_trials=0;
1436 1437 1438 1439 1440 1441 1442 1443 1444
      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
1445 1446 1447 1448 1449 1450 1451 1452 1453
      for (int i=0; i<RX_NB_TH; i++) {
	reset_meas(&UE->phy_proc_rx[i]); // total UE rx
	reset_meas(&UE->ue_front_end_stat[i]);
        reset_meas(&UE->pdsch_procedures_stat[i]);
	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]);
      }
1454
      reset_meas(&UE->ofdm_demod_stats);
laurent's avatar
laurent committed
1455
      reset_meas(&UE->crnti_procedures_stats);
1456 1457 1458
      reset_meas(&UE->dlsch_channel_estimation_stats);
      reset_meas(&UE->dlsch_freq_offset_estimation_stats);
      reset_meas(&UE->rx_dft_stats);
1459 1460
      reset_meas(&UE->dlsch_decoding_stats[0]);
      reset_meas(&UE->dlsch_decoding_stats[1]);
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
      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);
1471
      // initialization
laurent's avatar
laurent committed
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486
            // initialization
      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));
1487

1488
      for (trials = 0; trials<n_frames; trials++) {
1489
	//printf("Trial %d\n",trials);
1490 1491 1492 1493 1494
        fflush(stdout);
        round=0;

        //if (trials%100==0)
        eNB2UE[0]->first_run = 1;
gabrielC's avatar
gabrielC committed
1495 1496
	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;
1497

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

1502 1503 1504 1505
          //if(transmission_mode>=5)
          //  pmi_feedback=1;
          //else
          //  pmi_feedback=0;
1506 1507 1508 1509 1510 1511 1512 1513 1514

          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;

1515
	  //PMI_FEEDBACK:
1516 1517

          //  printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
1518
          for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1519
            memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
1520 1521 1522 1523 1524 1525
          }

          if (input_fd==NULL) {


            // Simulate HARQ procedures!!!
1526
	    memset(CCE_table,0,800*sizeof(int));
1527 1528
            if (common_flag == 0) {

1529 1530 1531 1532
	      num_dci=0;
	      num_common_dci=0;
	      num_ue_spec_dci=0;

1533 1534 1535
              if (round == 0) {   // First round
                TB0_active = 1;

1536
                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
1537 1538 1539 1540
		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);
1541 1542
	      }
	      else {
1543 1544 1545 1546
		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);
1547
	      }
1548
	    }
Cedric Roux's avatar
Cedric Roux committed
1549

1550
	    proc_eNB->subframe_tx = subframe;
1551 1552
	    sched_resp.subframe=subframe;
	    sched_resp.frame=proc_eNB->frame_tx;
1553

1554 1555
	    eNB->abstraction_flag=0;
	    schedule_response(&sched_resp);
1556
	    phy_procedures_eNB_TX(eNB,proc_eNB,1);
1557 1558 1559 1560 1561

	    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,
1562
		     eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0],
1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573
		     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);
Cedric Roux's avatar
Cedric Roux committed
1574

1575 1576 1577
	      uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword);
	      printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
	    }
1578

1579
	    start_meas(&eNB->ofdm_mod_stats);
1580

1581 1582 1583 1584
	    ru->proc.subframe_tx=subframe;
	    memcpy((void*)&ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
	    feptx_prec(ru);
	    feptx_ofdm(ru);
1585

1586
	    stop_meas(&eNB->ofdm_mod_stats);
1587 1588 1589



1590
	    // generate next subframe for channel estimation
1591

1592 1593 1594
	    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;
1595
	    proc_eNB->subframe_tx = subframe+1;
1596 1597
	    sched_resp.subframe=subframe+1;
	    schedule_response(&sched_resp);
1598
	    phy_procedures_eNB_TX(eNB,proc_eNB,0);
1599 1600


1601 1602 1603
	    ru->proc.subframe_tx=(subframe+1)%10;
	    feptx_prec(ru);
	    feptx_ofdm(ru);
1604

1605

1606
	    proc_eNB->frame_tx++;
1607

1608
            tx_lev = 0;
1609

1610
            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1611
              tx_lev += signal_energy(&ru->common.txdata[aa]
1612 1613
                                      [subframe*eNB->frame_parms.samples_per_tti],
                                      eNB->frame_parms.samples_per_tti);
1614 1615
            }

1616
            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
1617

1618

1619

1620 1621
            if (n_frames==1) {
              printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
1622

bruno mongazon's avatar
bruno mongazon committed
1623
              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
1624 1625

              if (transmission_mode<7) {
bruno mongazon's avatar
bruno mongazon committed
1626
	        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
1627
              } else if (transmission_mode == 7) {
bruno mongazon's avatar
bruno mongazon committed
1628 1629
                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
1630
              }
1631
            }
1632
	  }
1633

1634
	  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);
1635

1636

tct-labo4's avatar
tct-labo4 committed
1637
	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
1638 1639
	  proc->subframe_rx = subframe;
	  UE->UE_mode[0] = PUSCH;
1640

1641 1642 1643 1644 1645 1646 1647
	  // first symbol has to be done separately in one-shot mode
	  slot_fep(UE,
		   0,
		   (proc->subframe_rx<<1),
		   UE->rx_offset,
		   0,
		   0);
1648

1649
	  if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
1650 1651

	  if (dci_flag==0) {
1652 1653
	    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;
1654 1655 1656 1657 1658 1659 1660
	    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,
						   n_rnti,
						   dci_alloc[0].format,
tct-labo4's avatar
tct-labo4 committed
1661 1662
						   UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
						   UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
1663
						   UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
1664 1665 1666 1667 1668 1669 1670 1671 1672 1673
						   &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]);

gabrielC's avatar
gabrielC committed
1674 1675
		//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;
1676

gabrielC's avatar
gabrielC committed
1677
		UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
1678 1679 1680 1681 1682 1683 1684

		UE->dlsch_received[eNB_id]++;
	    } else {
	      LOG_E(PHY,"Problem in DCI!\n");
	    }
	  }

gabrielC's avatar
gabrielC committed
1685
	  dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
1686

1687
	  phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx);
1688

gabrielC's avatar
gabrielC committed
1689
	  dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
1690 1691

	  if (dci_flag && (dci_received == 0)) {
1692
	    printf("DCI not received\n");
1693 1694
	    dci_errors[round]++;

bruno mongazon's avatar
bruno mongazon committed
1695 1696
	    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);
1697

bruno mongazon's avatar
bruno mongazon committed
1698 1699
	    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);
Cedric Roux's avatar
Cedric Roux committed
1700

bruno mongazon's avatar
bruno mongazon committed
1701 1702
	    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);
1703

Cedric Roux's avatar
Cedric Roux committed
1704

1705
	    exit(-1);
Cedric Roux's avatar
Cedric Roux committed
1706

1707
	  }
1708

1709
	  int bit_errors=0;
1710
	  if ((test_perf ==0 ) && (n_frames==1)) {
1711

1712 1713 1714 1715 1716 1717 1718
	    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);
Cedric Roux's avatar
Cedric Roux committed
1719
	    for (i=0;i<coded_bits_per_codeword;i++)
1720
	      if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)||
Cedric Roux's avatar
Cedric Roux committed
1721
		  (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733
		uncoded_ber_bit[bit_errors++] = 1;
		printf("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]);
	      }
	      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]);
		*/
	      }
Cedric Roux's avatar
Cedric Roux committed
1734

bruno mongazon's avatar
bruno mongazon committed
1735 1736
	    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);
Cedric Roux's avatar
Cedric Roux committed
1737

1738
	    if (eNB->frame_parms.nb_antennas_tx>1)
bruno mongazon's avatar
bruno mongazon committed
1739
	      LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
1740

1741
	    //common vars
bruno mongazon's avatar
bruno mongazon committed
1742
	    LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
1743

bruno mongazon's avatar
bruno mongazon committed
1744
	    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);
1745

1746
	    if (UE->frame_parms.nb_antennas_rx>1) {
bruno mongazon's avatar
bruno mongazon committed
1747 1748
	      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);
1749
	    }
1750

bruno mongazon's avatar
bruno mongazon committed
1751
	    LOG_M("dlsch00_r0.m","dl00_r0",
gabrielC's avatar
gabrielC committed
1752
			 &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
1753
			 UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1754

1755
	    if (UE->frame_parms.nb_antennas_rx>1)
bruno mongazon's avatar
bruno mongazon committed
1756
	      LOG_M("dlsch01_r0.m","dl01_r0",
gabrielC's avatar
gabrielC committed
1757
			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
1758
			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1759

1760
	    if (eNB->frame_parms.nb_antennas_tx>1)
bruno mongazon's avatar
bruno mongazon committed
1761
	      LOG_M("dlsch10_r0.m","dl10_r0",
gabrielC's avatar
gabrielC committed
1762
			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
1763
			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1764

1765
	    if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
bruno mongazon's avatar
bruno mongazon committed
1766
	      LOG_M("dlsch11_r0.m","dl11_r0",
gabrielC's avatar
gabrielC committed
1767
			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
1768
			   UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1769

1770
	    //pdsch_vars
1771
	    printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword);
1772

gabrielC's avatar
gabrielC committed
1773
	    dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
1774

bruno mongazon's avatar
bruno mongazon committed
1775
	    LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
1776

1777
	    //pdcch_vars
bruno mongazon's avatar
bruno mongazon committed
1778 1779
	    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);
1780

bruno mongazon's avatar
bruno mongazon committed
1781 1782
	    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);
1783

1784
	  }
1785 1786


1787 1788


gabrielC's avatar
gabrielC committed
1789
          if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) {
1790

gabrielC's avatar
gabrielC committed
1791
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
1792 1793 1794
            iter_trials++;

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

gabrielC's avatar
gabrielC committed
1797
            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;
1798 1799
            TB0_active = 0;

1800

1801 1802
	  } // DLSCH received ok
	  else {
1803 1804
            errs[round]++;

gabrielC's avatar
gabrielC committed
1805
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
1806 1807 1808
            iter_trials++;

            if (n_frames==1) {
1809 1810


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

gabrielC's avatar
gabrielC committed
1814 1815 1816
              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;
1817
                else
gabrielC's avatar
gabrielC committed
1818
                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
1819 1820 1821 1822 1823 1824

                Kr_bytes = Kr>>3;

                printf("Decoded_output (Segment %d):\n",s);

                for (i=0; i<Kr_bytes; i++)
gabrielC's avatar
gabrielC committed
1825
                  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]);
1826 1827 1828
              }

              sprintf(fname,"rxsig0_r%d.m",round);
1829
              sprintf(vname,"rxs0_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1830
              LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
1831
              sprintf(fname,"rxsigF0_r%d.m",round);
1832
              sprintf(vname,"rxs0F_r%d",round);
1833

bruno mongazon's avatar
bruno mongazon committed
1834
              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);
1835

1836
              if (UE->frame_parms.nb_antennas_rx>1) {
1837 1838
                sprintf(fname,"rxsig1_r%d.m",round);
                sprintf(vname,"rxs1_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1839
                LOG_M(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
1840
                sprintf(fname,"rxsigF1_r%d.m",round);
1841
                sprintf(vname,"rxs1F_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1842
                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);
1843 1844 1845
              }

              sprintf(fname,"dlsch00_r%d.m",round);
1846
              sprintf(vname,"dl00_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1847
              LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1848
                           &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
1849
                           UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1850

1851
              if (UE->frame_parms.nb_antennas_rx>1) {
1852
                sprintf(fname,"dlsch01_r%d.m",round);
1853
                sprintf(vname,"dl01_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1854
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1855
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
1856
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1857 1858
              }

1859
              if (eNB->frame_parms.nb_antennas_tx>1) {
1860
                sprintf(fname,"dlsch10_r%d.m",round);
1861
                sprintf(vname,"dl10_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1862
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1863
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
1864
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1865 1866
              }

1867
              if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
1868
                sprintf(fname,"dlsch11_r%d.m",round);
1869
                sprintf(vname,"dl11_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1870
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1871
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
1872
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1873 1874 1875
              }

              //pdsch_vars
gabrielC's avatar
gabrielC committed
1876
              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
1877

1878

bruno mongazon's avatar
bruno mongazon committed
1879 1880 1881 1882
              //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);
1883
	      //pdcch_vars
bruno mongazon's avatar
bruno mongazon committed
1884 1885
	      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);
1886

bruno mongazon's avatar
bruno mongazon committed
1887 1888
	      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);
1889

1890 1891 1892 1893 1894 1895
              if (round == 3) exit(-1);
            }

            //      printf("round %d errors %d/%d\n",round,errs[round],trials);

            round++;
gabrielC's avatar
gabrielC committed
1896
            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
1897 1898
          }

1899 1900
	  if (xforms==1) {
	    phy_scope_UE(form_ue,
1901
			 UE,
1902 1903 1904 1905
			 eNB_id,
			 0,// UE_id
			 subframe);
	  }
1906

tct-labo4's avatar
tct-labo4 committed
1907
	  UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
1908
	}  //round
1909 1910 1911 1912 1913 1914 1915 1916 1917

        //      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
1918
        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
1919 1920 1921 1922
          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];
1923 1924 1925
        }


1926

1927 1928 1929 1930

        /* calculate the total processing time for each packet,
         * get the max, min, and number of packets that exceed t>2000us
         */
laurent's avatar
laurent committed
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
	double t_tx = inMicroS(eNB->phy_proc_tx.p_time);
        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);
	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);
        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
1947
          n_tx_dropped++;
laurent's avatar
laurent committed
1948 1949
	
        if (t_rx > 2000 )
1950
          n_rx_dropped++;
laurent's avatar
laurent committed
1951 1952 1953 1954 1955 1956 1957
	
	appendVarArray(table_tx, &t_tx);
        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 );
1958

1959
      }   //trials
1960

1961
      // round_trials[0]: number of code word : goodput the protocol
1962
      // sort table
laurent's avatar
laurent committed
1963 1964 1965 1966 1967 1968 1969 1970
      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);
1971

Navid Nikaein's avatar
Navid Nikaein committed
1972
      if (dump_table == 1 ) {
1973
        set_component_filelog(SIM);  // file located in /tmp/usim.txt
laurent's avatar
laurent committed
1974 1975
        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
1976
      }
1977

1978
      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]));
1979

1980
      printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n",
1981
             SNR,
1982
             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)));
1983

1984
      printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f, normalized delay %f (%f)\n",
1985 1986 1987 1988
             errs[0],
             errs2[0],
             round_trials[0],
             errs[1],
1989
             round_trials[1],
1990
             errs[2],
1991
             round_trials[2],
1992
             errs[3],
1993
             round_trials[3],
1994
             (double)errs[0]/(round_trials[0]),
1995 1996 1997
             (double)errs[1]/(round_trials[1]),
             (double)errs[2]/(round_trials[2]),
             (double)errs[3]/(round_trials[3]),
1998 1999 2000 2001
             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,
2002
             100*effective_rate,
2003
             //rate,
gabrielC's avatar
gabrielC committed
2004
             //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),
2005
             (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])/
2006
             (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2007 2008
             (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
2009
      double timeBase=1/(1000*cpu_freq_GHz);
2010
      if (print_perf==1) {
laurent's avatar
laurent committed
2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
        printf("\neNB TX function statistics (per 1ms subframe)\n");
	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_encoding_stats,"DLSCH encoding time");
	printStatIndent2(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time",eNB->dlsch_rate_matching_stats.trials);
	printStatIndent2(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time", eNB->dlsch_turbo_encoding_stats.trials);
	printStatIndent2(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time", eNB->dlsch_interleaving_stats.trials);
	printStatIndent(&eNB->dlsch_scrambling_stats,  "DLSCH scrambling time");
	printStatIndent(&eNB->dlsch_modulation_stats, "DLSCH modulation time");
	printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time");

        printf("\nUE RX function statistics (per 1ms subframe)\n");
	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", pdsch_procedures_tot.trials);
	printStatIndent2(&dlsch_procedures_tot,"dlsch processing", dlsch_procedures_tot.trials);
	printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing", UE->crnti_procedures_stats.trials);
	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");
        printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching");
	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,

               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);
        printStatIndent2(&UE->dlsch_tc_init_stats,"init", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_beta_stats,"beta", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_ext_stats,"ext", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver", UE->dlsch_tc_init_stats.trials);
        printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC", UE->dlsch_tc_init_stats.trials);
	
2052 2053
      }

2054
      if ((transmission_mode != 3) && (transmission_mode != 4)) {
2055 2056 2057
        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
                SNR,
                mcs1,
2058
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
2059 2060 2061 2062 2063 2064 2065 2066 2067
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
2068
                dci_errors[0]);
2069 2070 2071 2072
      } else {
        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
                SNR,
                mcs1,mcs2,
2073 2074
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
                eNB->dlsch[0][1]->harq_processes[0]->TBS,
2075 2076 2077 2078 2079 2080 2081 2082 2083
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
2084
                dci_errors[0]);
2085
      }
2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098


      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]);
        }
2099
      } //ABStraction
2100

2101
      if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
2102 2103 2104 2105 2106
        //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)) {
          fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
                  SNR,
                  mcs1,
2107
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
2108 2109 2110 2111 2112 2113 2114 2115 2116
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
2117
                  dci_errors[0]);
2118 2119 2120 2121 2122

          //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");
          fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
                  SNR,
                  mcs1,
2123
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
                  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]),
2140
                  dci_errors[0],
2141
                  round_trials[0],
2142
                  (double)dci_errors[0]/(round_trials[0]),
2143
                  (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])/
2144
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2145 2146 2147 2148 2149
                  (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 {
          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
                  SNR,
                  mcs1,mcs2,
2150 2151
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2152 2153 2154 2155 2156 2157 2158 2159 2160
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
2161
                  dci_errors[0]);
2162 2163 2164 2165 2166

          //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");
          fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;",
                  SNR,
                  mcs1,mcs2,
2167 2168
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184
                  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]),
2185
                  dci_errors[0],
2186
                  round_trials[0],
2187
                  (double)dci_errors[0]/(round_trials[0]),
2188
                  (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])/
2189
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2190 2191 2192 2193 2194
                  (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;",
2195 2196 2197 2198 2199
                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
2200
                phy_proc_rx_tot.trials,
2201 2202 2203 2204
                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
2205
                UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
2206 2207
               );
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
2208 2209 2210 2211 2212
                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
2213
                get_time_meas_us(&phy_proc_rx_tot),
2214 2215 2216 2217
                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
2218
                get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
2219 2220
               );
        //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
2221
        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);
2222
        //fprintf(time_meas_fd,"IFFT;\n");
laurent's avatar
laurent committed
2223 2224 2225
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
		squareRoot(&eNB->ofdm_mod_stats),
                median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft));
2226
        //fprintf(time_meas_fd,"MOD;\n");
laurent's avatar
laurent committed
2227 2228 2229
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
		squareRoot(&eNB->dlsch_modulation_stats),
                median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod));
2230
        //fprintf(time_meas_fd,"ENC;\n");
laurent's avatar
laurent committed
2231 2232 2233 2234 2235 2236 2237
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
		squareRoot(&eNB->dlsch_encoding_stats),
                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;",
		squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min,
                median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped);
2238
        //fprintf(time_meas_fd,"FFT;\n");
laurent's avatar
laurent committed
2239 2240 2241
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
		squareRoot(&UE->ofdm_demod_stats),
                median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft));
2242
        //fprintf(time_meas_fd,"DEMOD;\n");
laurent's avatar
laurent committed
2243 2244 2245
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
		squareRoot(&UE->dlsch_demodulation_stats),
                median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod));
2246
        //fprintf(time_meas_fd,"DEC;\n");
laurent's avatar
laurent committed
2247 2248 2249 2250
        fprintf(time_meas_fd,"%f;%f;%f;%f\n",
		squareRoot(&UE->dlsch_decoding_stats[subframe]),
                median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));

2251
        printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
2252
	test_passed = 1;
2253 2254 2255
        break;
      } else if (test_perf !=0 ) {
        printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
2256
	test_passed = 0;
2257 2258
      }

2259
      if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
2260 2261 2262 2263 2264 2265 2266
        break;
    }// SNR


  } //ch_realization


2267
  fclose(bler_fd);
2268

2269 2270
  if (test_perf !=0)
    fclose (time_meas_fd);
2271

2272 2273
  //fprintf(tikz_fd,"};\n");
  //fclose(tikz_fd);
2274 2275 2276

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

2278 2279
  if (input_file==1)
    fclose(input_fd);
2280 2281

  if(abstx) { // ABSTRACTION
2282 2283 2284
    fprintf(csv_fd,"];");
    fclose(csv_fd);
  }
2285

2286 2287
  if (uncoded_ber_bit)
    free(uncoded_ber_bit);
2288 2289 2290

  uncoded_ber_bit = NULL;

2291
  printf("Freeing dlsch structures\n");
2292 2293

  for (i=0; i<2; i++) {
2294
    printf("eNB %d\n",i);
2295
    free_eNB_dlsch(eNB->dlsch[0][i]);
2296
    printf("UE %d\n",i);
gabrielC's avatar
gabrielC committed
2297
    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
2298
  }
2299

2300 2301
  if (test_perf && !test_passed)
    return(-1);
Cedric Roux's avatar
Cedric Roux committed
2302
  else
2303
    return(0);
2304
}
2305

2306