dlsim.c 92.8 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 75
double cpuf;

76
int otg_enabled=0;
77 78 79 80 81 82 83
/*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 */
84

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
static THREAD_STRUCT thread_struct;
void set_parallel_conf(int parallel_conf)
{
   thread_struct.parallel_conf = (PARALLEL_CONF_t)parallel_conf;
} 
void set_parallel_worker_conf(int worker_conf)
{
  thread_struct.worker_conf = (WORKER_CONF_t)worker_conf;
} 
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;
} 
102

Raymond Knopp's avatar
Raymond Knopp committed
103 104
int emulate_rf = 0;

105 106
void handler(int sig)
{
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  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;
127
#define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2)
128 129
//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13
//#define DLSCH_RB_ALLOC 0x0001
130
void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
131
{
132 133 134 135 136 137 138 139 140 141 142

  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
143
                   &txdata[aa][slot_offset],         // output
144
                   frame_parms->ofdm_symbol_size,
145 146 147
                   6,                 // number of symbols
                   frame_parms->nb_prefix_samples,               // number of prefix samples
                   CYCLIC_PREFIX);
148 149
    else {
      normal_prefix_mod(&txdataF[aa][slot_offset_F],
150 151 152
                        &txdata[aa][slot_offset],
                        7,
                        frame_parms);
153
    }
154

155 156

  }
157

158 159
}

160
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],
161
		double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) {
162

163 164 165 166
  int i,u;
  int aa,aarx,aatx;
  double channelx,channely;
  double sigma2_dB,sigma2;
167 168
  double iqim=0.0;

169 170
  //    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++) {
171
    for (aa=0; aa<ru->frame_parms.nb_antennas_tx; aa++) {
172
      if (awgn_flag == 0) {
173 174
	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]);
175 176 177
      } else {
	for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
	  if (aa==0) {
178 179
	    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]);
180
	  } else {
181 182
	    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]);
183
	  }
184

185 186 187 188
	}
      }
    }
  }
189

190 191 192 193
  // 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);
194

195 196 197 198 199 200 201
    //      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);
      }
202

203 204 205 206
    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
207 208
	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);
209 210 211
      */
    }
  }
212 213


214 215 216
  if(abstx) {
    if (trials==0 && round==0) {
      // calculate freq domain representation to compute SINR
217
      freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
218 219
      // snr=pow(10.0,.1*SNR);
      fprintf(csv_fd,"%f,",SNR);
220

221
      for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) {
222 223 224 225 226 227 228
	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);
	  }
	}
229 230
      }

231
      if(num_rounds>1) {
232
	freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1);
233

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

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

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

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

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

271
  //AWGN
272 273
  // tx_lev is the average energy over the whole subframe
  // but SNR should be better defined wrt the energy in the reference symbols
274
  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;
275 276 277
  sigma2 = pow(10,sigma2_dB/10);

  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
278
    for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) {
279 280 281 282 283 284 285 286
      //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));
    }
  }
}
287

288 289
uint16_t
fill_tx_req(nfapi_tx_request_body_t *tx_req_body,
Cedric Roux's avatar
Cedric Roux committed
290
	    uint16_t                absSF,
291
	    uint16_t                pdu_length,
Cedric Roux's avatar
Cedric Roux committed
292
	    uint16_t                pdu_index,
293 294 295 296 297 298 299 300 301 302 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
	    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++;
}
367

368
void fill_DCI(PHY_VARS_eNB *eNB,
369
	      int frame,
370
	      int subframe,
371 372
	      Sched_Rsp_t *sched_resp,
	      uint8_t input_buffer[NUMBER_OF_UE_MAX][20000],
373 374 375
	      int n_rnti,
	      int n_users,
	      int transmission_mode,
376
	      int retrans,
377
	      int common_flag,
378
	      int NB_RB,
379 380 381 382 383 384
	      int DLSCH_RB_ALLOC,
	      int TPC,
	      int mcs1,
	      int mcs2,
	      int ndi,
	      int rv,
385
	      int pa,
386 387 388 389 390 391
	      int *num_common_dci,
	      int *num_ue_spec_dci,
	      int *num_dci) {

  int k;

392 393 394 395 396 397 398 399
  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;

400 401 402
  for(k=0; k<n_users; k++) {
    switch(transmission_mode) {
    case 1:
403

404
    case 2:
Xiwen JIANG's avatar
Xiwen JIANG committed
405 406

    case 7:
407
      if (common_flag == 0) {
408

409 410 411 412 413 414 415 416 417 418 419
	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
420

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
	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
439 440
	fill_dlsch_config(dl_req,
			  get_TBS_DL(mcs1,NB_RB),
441
			  (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */
Cedric Roux's avatar
Cedric Roux committed
442
			  n_rnti,
443 444
			  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
445 446
			  DLSCH_RB_ALLOC,	// resource_block_coding,
			  get_Qm(mcs1),
447 448 449 450 451 452 453 454
			  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
455
			  pa,    // pa
456 457 458 459 460 461 462 463 464
			  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
465
		    get_TBS_DL(mcs1,NB_RB),
466 467 468 469
		    0,
		    input_buffer[k]);
      }
      else {
470

471
      }
472

473
      break;
474

475 476
    case 3:
      if (common_flag == 0) {
Cedric Roux's avatar
Cedric Roux committed
477

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

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

482 483
	  }
	  else {
Cedric Roux's avatar
Cedric Roux committed
484

485 486 487 488
	  }
	}
      }
      break;
Cedric Roux's avatar
Cedric Roux committed
489

490 491
    case 4:
      if (common_flag == 0) {
Cedric Roux's avatar
Cedric Roux committed
492

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

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

497

498
	  }
499

500
	  else {
501

502 503
	  }
	} else if (eNB->frame_parms.nb_antennas_tx == 4) {
504

505
	}
506

507 508
      }
      else {
509

510
        }
511

512
        break;
513

514 515
      case 5:
      case 6:
516

517
        break;
518

519 520 521 522
    default:
      printf("Unsupported Transmission Mode %d!!!\n",transmission_mode);
      exit(-1);
      break;
523
    }
524 525 526 527
  }
  *num_dci         = dl_req->number_dci;
  *num_ue_spec_dci = dl_req->number_dci;
  *num_common_dci  = 0;
528
}
529

530 531 532 533
int n_users = 1;
sub_frame_t subframe=7;
int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
uint16_t n_rnti=0x1234;
534
  int nfapi_mode=0;
535

536 537
int main(int argc, char **argv)
{
538

539
  int c;
540
  int k,i,j,aa;
Xiwen JIANG's avatar
Xiwen JIANG committed
541
  int re;
542
  int loglvl=OAILOG_DEBUG;
543

544
  int s,Kr,Kr_bytes;
545

546
  double SNR,snr0=-2.0,snr1,rate = 0;
547
  double snr_step=1,input_snr_step=1, snr_int=30;
548

549
  LTE_DL_FRAME_PARMS *frame_parms;
550 551 552 553 554 555
  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};
556
  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
557

558

Xiwen JIANG's avatar
Xiwen JIANG committed
559
  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2;
560
  uint16_t Nid_cell=0;
561

562 563 564 565 566
  int eNB_id = 0;
  unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round;
  unsigned char i_mod = 2;
  unsigned short NB_RB;
  uint16_t tdd_config=3;
567

568

569 570
  SCM_t channel_model=Rayleigh1;
  //  unsigned char *input_data,*decoded_output;
571

572 573
  DCI_ALLOC_t da;
  DCI_ALLOC_t *dci_alloc = &da;
574

575
  unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0;
576

577 578 579 580 581 582 583
  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));

584
  //int re_allocated;
585 586 587 588 589 590 591
  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];
592

593 594 595 596
  FILE *input_trch_fd=NULL;
  unsigned char input_trch_file=0;
  FILE *input_fd=NULL;
  unsigned char input_file=0;
597

598 599 600
  int n_frames;
  int n_ch_rlz = 1;
  channel_desc_t *eNB2UE[4];
601
  //uint8_t num_pdcch_symbols_2=0;
602 603 604 605
  uint8_t rx_sample_offset = 0;
  //char stats_buffer[4096];
  //int len;
  uint8_t num_rounds = 4;//,fix_rounds=0;
606

607
  //int u;
608 609
  int n=0;
  int abstx=0;
610
  //int iii;
611

612
  int ch_realization;
613
  //int pmi_feedback=0;
614
  int hold_channel=0;
615

616 617 618
  // void *data;
  // int ii;
  //  int bler;
619
  double blerr[4];
620 621 622 623 624 625
  short *uncoded_ber_bit=NULL;
  uint8_t N_RB_DL=25,osf=1;
  frame_t frame_type = FDD;
  int xforms=0;
  FD_lte_phy_scope_ue *form_ue = NULL;
  char title[255];
626

627
  int numCCE=0;
628
  //int dci_length_bytes=0,dci_length=0;
629 630
  //double channel_bandwidth = 5.0, sampling_rate=7.68;
  int common_flag=0,TPC=0;
631

632 633 634 635 636 637
  double cpu_freq_GHz;
  //  time_stats_t ts;//,sts,usts;
  int avg_iter,iter_trials;
  int rballocset=0;
  int print_perf=0;
  int test_perf=0;
638
  int test_passed=0;
639
  int dump_table=0;
640

641 642
  double effective_rate=0.0;
  char channel_model_input[10]="I";
643

644 645
  int TB0_active = 1;
  uint32_t perfect_ce = 0;
646

647 648 649 650 651
  //  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;
652
  int sf;
653

654 655


656
  int CCE_table[800];
657

658
  int threequarter_fs=0;
659

660

661
  opp_enabled=1; // to enable the time meas
662

663 664
  FILE *csv_fd=NULL;
  char csv_fname[32];
665
  int dci_flag=0;
666
  int two_thread_flag=0;
667
  int DLSCH_RB_ALLOC = 0;
668

669
  int dci_received;
670 671 672 673 674 675
  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
676
  nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU];
677 678 679 680
  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;
681

682 683 684
#if defined(__arm__)
  FILE    *proc_fd = NULL;
  char buf[64];
685

686 687 688 689 690 691
  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);
692
  }
693 694 695 696 697 698
  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);
699 700 701 702 703 704 705 706 707 708 709 710
  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;
711

712 713
  cpuf = cpu_freq_GHz;

714 715
  //signal(SIGSEGV, handler);
  //signal(SIGABRT, handler);
716

717 718 719 720 721
  // default parameters
  n_frames = 1000;
  snr0 = 0;
  //  num_layers = 1;
  perfect_ce = 0;
722

723
  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXYL:")) != -1) {
724 725 726 727 728
    switch (c) {
    case 'a':
      awgn_flag = 1;
      channel_model = AWGN;
      break;
729

730 731 732
    case 'A':
      abstx = 1;
      break;
733

734 735 736
    case 'b':
      tdd_config=atoi(optarg);
      break;
737

738 739 740
    case 'B':
      N_RB_DL=atoi(optarg);
      break;
741

742 743 744
    case 'c':
      num_pdcch_symbols=atoi(optarg);
      break;
745

746 747 748
    case 'C':
      Nid_cell = atoi(optarg);
      break;
749

750 751 752
    case 'd':
      dci_flag = 1;
      break;
753

754 755 756
    case 'D':
      frame_type=TDD;
      break;
757

758 759 760 761 762
    case 'e':
      num_rounds=1;
      common_flag = 1;
      TPC = atoi(optarg);
      break;
763

764 765 766
    case 'E':
      threequarter_fs=1;
      break;
767

768 769 770
    case 'f':
      input_snr_step= atof(optarg);
      break;
771

772 773 774
    case 'F':
      forgetting_factor = atof(optarg);
      break;
775

776 777 778
    case 'i':
      input_fd = fopen(optarg,"r");
      input_file=1;
779
      dci_flag = 1;
780
      break;
781

782 783 784 785
    case 'I':
      input_trch_fd = fopen(optarg,"r");
      input_trch_file=1;
      break;
786

787 788 789
    case 'W':
      two_thread_flag = 1;
      break;
790 791 792
    case 'l':
      offset_mumimo_llr_drange_fix=atoi(optarg);
      break;
793

794 795 796
    case 'm':
      mcs1 = atoi(optarg);
      break;
797

798 799 800
    case 'M':
      mcs2 = atoi(optarg);
      break;
801

802 803 804 805
    case 'O':
      test_perf=atoi(optarg);
      //print_perf =1;
      break;
806

807 808 809 810
    case 't':
      mcs_i = atoi(optarg);
      i_mod = get_Qm(mcs_i);
      break;
811

812 813 814
    case 'n':
      n_frames = atoi(optarg);
      break;
815 816


817 818 819
    case 'o':
      rx_sample_offset = atoi(optarg);
      break;
820

821 822 823 824
    case 'r':
      DLSCH_RB_ALLOC = atoi(optarg);
      rballocset = 1;
      break;
825

826 827 828
    case 's':
      snr0 = atof(optarg);
      break;
829

830 831 832
    case 'w':
      snr_int = atof(optarg);
      break;
833 834


835 836 837
    case 'N':
      n_ch_rlz= atof(optarg);
      break;
838

839 840 841
    case 'p':
      extended_prefix_flag=1;
      break;
842

843 844
    case 'g':
      memcpy(channel_model_input,optarg,10);
845

846 847 848
      switch((char)*optarg) {
      case 'A':
        channel_model=SCM_A;
849 850
        break;

851 852 853
      case 'B':
        channel_model=SCM_B;
        break;
854

855 856 857
      case 'C':
        channel_model=SCM_C;
        break;
858

859 860 861
      case 'D':
        channel_model=SCM_D;
        break;
862

863 864 865
      case 'E':
        channel_model=EPA;
        break;
866

867 868 869
      case 'F':
        channel_model=EVA;
        break;
870

871 872 873
      case 'G':
        channel_model=ETU;
        break;
874

875 876 877
      case 'H':
        channel_model=Rayleigh8;
        break;
878

879 880 881
      case 'I':
        channel_model=Rayleigh1;
        break;
882

883 884 885
      case 'J':
        channel_model=Rayleigh1_corr;
        break;
886

887 888 889
      case 'K':
        channel_model=Rayleigh1_anticorr;
        break;
890

891 892 893
      case 'L':
        channel_model=Rice8;
        break;
894

895 896 897
      case 'M':
        channel_model=Rice1;
        break;
898

899 900 901 902
      case 'N':
        channel_model=AWGN;
        break;
      default:
903
        printf("Unsupported channel model!\n");
904 905
        exit(-1);
      }
906

907 908 909 910
      break;
    case 'R':
      num_rounds=atoi(optarg);
      break;
911

912 913 914
    case 'S':
      subframe=atoi(optarg);
      break;
915

916 917 918
    case 'T':
      n_rnti=atoi(optarg);
      break;
919

920 921 922
    case 'u':
      dual_stream_UE=1;
      UE->use_ia_receiver = 1;
923

Xiwen JIANG's avatar
Xiwen JIANG committed
924
      if ((n_tx_port!=2) || (transmission_mode!=5)) {
925
        printf("IA receiver only supported for TM5!");
926 927
        exit(-1);
      }
928

929
      break;
930

931 932
    case 'v':
      i_mod = atoi(optarg);
933

934
      if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
935
        printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
936 937
        exit(-1);
      }
938

939
      break;
940

941 942 943
    case 'P':
      print_perf=1;
      break;
944

Xiwen JIANG's avatar
Xiwen JIANG committed
945 946 947 948
    case 'q':
      n_tx_port=atoi(optarg);

      if ((n_tx_port==0) || ((n_tx_port>2))) {
949
        printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port);
Xiwen JIANG's avatar
Xiwen JIANG committed
950 951 952 953 954 955
        exit(-1);
      }

      break;


956 957
    case 'x':
      transmission_mode=atoi(optarg);
958

959 960 961 962 963
      if ((transmission_mode!=1) &&
          (transmission_mode!=2) &&
          (transmission_mode!=3) &&
          (transmission_mode!=4) &&
          (transmission_mode!=5) &&
Xiwen JIANG's avatar
Xiwen JIANG committed
964 965
          (transmission_mode!=6) &&
          (transmission_mode!=7)) {
966
        printf("Unsupported transmission mode %d\n",transmission_mode);
967 968
        exit(-1);
      }
969

Xiwen JIANG's avatar
Xiwen JIANG committed
970 971
      if (transmission_mode>1 && transmission_mode<7) {
        n_tx_port = 2;
972
      }
973

974
      break;
975

976
    case 'y':
Xiwen JIANG's avatar
Xiwen JIANG committed
977
      n_tx_phy=atoi(optarg);
978

Xiwen JIANG's avatar
Xiwen JIANG committed
979
      if (n_tx_phy < n_tx_port) {
980
        printf("n_tx_phy mush not be smaller than n_tx_port");
981 982
        exit(-1);
      }
983

Xiwen JIANG's avatar
Xiwen JIANG committed
984
      if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) {
985
        printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode);
Xiwen JIANG's avatar
Xiwen JIANG committed
986 987
        exit(-1);
      }
988

Xiwen JIANG's avatar
Xiwen JIANG committed
989
      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)) {
990
        printf("Physical number of antennas not supported for TM7.\n");
991 992
        exit(-1);
      }
993

994 995
      break;
      break;
996

997 998 999
    case 'X':
      xforms=1;
      break;
1000

1001 1002 1003
    case 'Y':
      perfect_ce=1;
      break;
1004

1005 1006
    case 'z':
      n_rx=atoi(optarg);
1007

1008
      if ((n_rx==0) || (n_rx>2)) {
1009
        printf("Unsupported number of rx antennas %d\n",n_rx);
1010 1011
        exit(-1);
      }
1012

1013
      break;
1014

1015 1016 1017
    case 'Z':
      dump_table=1;
      break;
1018

1019
    case 'L':
1020
      loglvl = atoi(optarg);
1021
      break;
1022

1023 1024
    case 'h':
    default:
Xiwen JIANG's avatar
Xiwen JIANG committed
1025
      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]);
1026 1027 1028 1029 1030
      printf("-h This message\n");
      printf("-a Use AWGN channel and not multipath\n");
      printf("-c Number of PDCCH symbols\n");
      printf("-m MCS1 for TB 1\n");
      printf("-M MCS2 for TB 2\n");
1031
      printf("-d Transmit the DCI and compute its error statistics\n");
1032 1033 1034 1035 1036
      printf("-p Use extended prefix mode\n");
      printf("-n Number of frames to simulate\n");
      printf("-o Sample offset for receiver\n");
      printf("-s 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\n", snr_int, snr_step);
      printf("-f step size of SNR, default value is 1.\n");
1037 1038 1039 1040 1041
      printf("-C cell id\n");
      printf("-S subframe\n");
      printf("-D use TDD mode\n");
      printf("-b TDD config\n");
      printf("-B bandwidth configuration (in number of ressource blocks): 6, 25, 50, 100\n");
1042 1043 1044
      printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
      printf("-g [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')\n");
      printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
Xiwen JIANG's avatar
Xiwen JIANG committed
1045 1046
      printf("-x Transmission mode (1,2,6,7 for the moment)\n");
      printf("-q Number of TX antennas ports used in eNB\n");
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
      printf("-y Number of TX antennas used in eNB\n");
      printf("-z Number of RX antennas used in UE\n");
      printf("-t MCS of interfering UE\n");
      printf("-R Number of HARQ rounds (fixed)\n");
      printf("-A Turns on calibration mode for abstraction.\n");
      printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
      printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
      printf("-I Input filename for TrCH data (binary)\n");
      printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n");
      exit(1);
      break;
    }
  }
1060

1061 1062 1063 1064 1065
  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");
1066 1067
  logInit();
  // enable these lines if you need debug info
1068
  set_glog(loglvl);
1069 1070 1071 1072 1073 1074
  // 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);


1075 1076 1077 1078 1079 1080
  if (common_flag == 0) {
    switch (N_RB_DL) {
    case 6:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
      num_pdcch_symbols = 3;
      break;
1081

1082 1083 1084
    case 25:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
      break;
1085

1086 1087 1088
    case 50:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
      break;
1089

1090 1091 1092 1093
    case 100:
      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
      break;
    }
1094

1095 1096 1097
    NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
  } else
    NB_RB = 4;
1098

1099 1100 1101 1102 1103
  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);
1104

1105 1106 1107 1108 1109 1110 1111
    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);
    }
  }
1112

1113 1114 1115 1116
  if (transmission_mode==5) {
    n_users = 2;
    printf("dual_stream_UE=%d\n", dual_stream_UE);
  }
1117 1118
  RC.nb_L1_inst = 1;
  RC.nb_RU = 1;
1119

1120 1121
  lte_param_init(&eNB,&UE,&ru,
		 n_tx_port,
Xiwen JIANG's avatar
Xiwen JIANG committed
1122
		 n_tx_phy,
1123 1124
		 1,
                 n_rx,
1125 1126 1127 1128 1129 1130
		 transmission_mode,
		 extended_prefix_flag,
		 frame_type,
		 Nid_cell,
		 tdd_config,
		 N_RB_DL,
1131
		 pa,
1132 1133 1134
		 threequarter_fs,
		 osf,
		 perfect_ce);
1135 1136 1137 1138 1139 1140
  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");
1141
  if ((transmission_mode==1) || (transmission_mode==7)) {
1142 1143 1144
    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;
1145 1146
  }

1147
  if (transmission_mode<7)
1148
     ru->do_precoding=0;
1149
  else
1150
     ru->do_precoding=1;
1151

1152
  eNB->mac_enabled=1;
1153 1154 1155 1156 1157
  if (two_thread_flag == 0) {
    eNB->te = dlsch_encoding;
  }
  else {
    eNB->te = dlsch_encoding_2threads;
1158 1159 1160 1161
    extern void init_td_thread(PHY_VARS_eNB *);
    extern void init_te_thread(PHY_VARS_eNB *);
    init_td_thread(eNB);
    init_te_thread(eNB);
1162 1163
  }

1164 1165
  // callback functions required for phy_procedures_tx

1166
  //  eNB_id_i = UE->n_connected_eNB;
1167

1168 1169 1170 1171
  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
1172
  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
1173

1174 1175
  snr1 = snr0+snr_int;
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
1176

1177
  uint8_t input_buffer[NUMBER_OF_UE_MAX][20000];
1178

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

1182
  frame_parms = &eNB->frame_parms;
1183

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

1186 1187 1188
  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);
1189

1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
  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
1210
            N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
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 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 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 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326
    //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;
    }
  */

1327

gabrielC's avatar
gabrielC committed
1328
  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
1329
  UE->n_connected_eNB = 1;
1330

1331
  printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx);
1332 1333 1334 1335 1336 1337 1338 1339 1340
  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);

1341 1342
  reset_meas(&eNB2UE[0]->random_channel);
  reset_meas(&eNB2UE[0]->interp_time);
1343
  if(num_rounds>1) {
1344
    for(n=1; n<4; n++) {
1345 1346 1347 1348 1349 1350 1351 1352
      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);
1353 1354 1355
      reset_meas(&eNB2UE[n]->random_channel);
      reset_meas(&eNB2UE[n]->interp_time);
    }
1356
  }
1357
  
1358
  if (eNB2UE[0]==NULL) {
1359
    printf("Problem generating channel model. Exiting.\n");
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384
    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;
  }

1385
  for (k=0; k<NUMBER_OF_UE_MAX; k++) {
1386 1387
    // Create transport channel structures for 2 transport blocks (MIMO)
    for (i=0; i<2; i++) {
1388
      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1389 1390 1391

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

1395 1396 1397 1398
      eNB->dlsch[k][i]->rnti = n_rnti+k;
    }
  }

1399 1400 1401 1402 1403 1404 1405 1406
  /* 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);
1407

1408 1409 1410 1411
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
      }
1412

1413 1414
      UE->dlsch[sf][0][i]->rnti   = n_rnti;
    }
1415 1416
  }

1417 1418
    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);
1419
    UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
1420

1421
  // structure for SIC at UE
1422
  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms);
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435

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

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

1439
  if (input_fd==NULL) {
1440

1441
    DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols;
1442 1443
    DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
    TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe;
1444 1445
    // UE specific DCI
    fill_DCI(eNB,
1446 1447 1448
	     proc_eNB->frame_tx,subframe,
	     &sched_resp,
	     input_buffer,
1449 1450 1451
	     n_rnti,
	     n_users,
	     transmission_mode,
1452
	     0,
1453
	     common_flag,
1454
	     NB_RB,
1455 1456 1457 1458
	     DLSCH_RB_ALLOC,
	     TPC,
	     mcs1,
	     mcs2,
1459
	     1,
1460
	     0,
1461
	     pa,
1462 1463 1464
	     &num_common_dci,
	     &num_ue_spec_dci,
	     &num_dci);
1465

1466
    numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
1467

1468
    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);
1469

1470

1471

1472
  }
1473

1474
  snr_step = input_snr_step;
1475 1476
  UE->high_speed_flag = 1;
  UE->ch_est_alpha=0;
1477

1478 1479
  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
    if(abstx) {
1480 1481 1482
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
    }

1483
    for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
tct-labo4's avatar
tct-labo4 committed
1484
      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
1485 1486 1487 1488
      errs[0]=0;
      errs[1]=0;
      errs[2]=0;
      errs[3]=0;
1489 1490 1491 1492
      errs2[0]=0;
      errs2[1]=0;
      errs2[2]=0;
      errs2[3]=0;
1493 1494 1495 1496 1497
      round_trials[0] = 0;
      round_trials[1] = 0;
      round_trials[2] = 0;
      round_trials[3] = 0;

1498 1499 1500 1501
      dci_errors[0]=0;
      dci_errors[1]=0;
      dci_errors[2]=0;
      dci_errors[3]=0;
1502
      //      avg_ber = 0;
1503 1504

      round=0;
1505 1506
      avg_iter = 0;
      iter_trials=0;
1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
      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);

gabrielC's avatar
gabrielC committed
1517
      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
1518 1519 1520 1521
      reset_meas(&UE->ofdm_demod_stats);
      reset_meas(&UE->dlsch_channel_estimation_stats);
      reset_meas(&UE->dlsch_freq_offset_estimation_stats);
      reset_meas(&UE->rx_dft_stats);
1522 1523
      reset_meas(&UE->dlsch_decoding_stats[0]);
      reset_meas(&UE->dlsch_decoding_stats[1]);
1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
      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);
1534 1535 1536
      // initialization
      struct list time_vector_tx;
      initialize(&time_vector_tx);
1537 1538 1539 1540 1541 1542 1543
      struct list time_vector_tx_ifft;
      initialize(&time_vector_tx_ifft);
      struct list time_vector_tx_mod;
      initialize(&time_vector_tx_mod);
      struct list time_vector_tx_enc;
      initialize(&time_vector_tx_enc);

1544 1545
      struct list time_vector_rx;
      initialize(&time_vector_rx);
1546 1547 1548 1549 1550 1551
      struct list time_vector_rx_fft;
      initialize(&time_vector_rx_fft);
      struct list time_vector_rx_demod;
      initialize(&time_vector_rx_demod);
      struct list time_vector_rx_dec;
      initialize(&time_vector_rx_dec);
1552

1553

1554

1555
      for (trials = 0; trials<n_frames; trials++) {
1556
	//printf("Trial %d\n",trials);
1557 1558 1559 1560 1561
        fflush(stdout);
        round=0;

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

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

1569 1570 1571 1572
          //if(transmission_mode>=5)
          //  pmi_feedback=1;
          //else
          //  pmi_feedback=0;
1573 1574 1575 1576 1577 1578 1579 1580 1581

          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;

1582
	  //PMI_FEEDBACK:
1583 1584

          //  printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
1585
          for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1586
            memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t));
1587 1588 1589 1590 1591 1592
          }

          if (input_fd==NULL) {


            // Simulate HARQ procedures!!!
1593
	    memset(CCE_table,0,800*sizeof(int));
1594 1595
            if (common_flag == 0) {

1596 1597 1598 1599
	      num_dci=0;
	      num_common_dci=0;
	      num_ue_spec_dci=0;

1600 1601 1602
              if (round == 0) {   // First round
                TB0_active = 1;

1603
                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
1604 1605 1606 1607
		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);
1608 1609
	      }
	      else {
1610 1611 1612 1613
		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);
1614
	      }
1615
	    }
Cedric Roux's avatar
Cedric Roux committed
1616

1617
	    proc_eNB->subframe_tx = subframe;
1618 1619
	    sched_resp.subframe=subframe;
	    sched_resp.frame=proc_eNB->frame_tx;
1620

1621 1622
	    eNB->abstraction_flag=0;
	    schedule_response(&sched_resp);
1623
	    phy_procedures_eNB_TX(eNB,proc_eNB,1);
1624 1625 1626 1627 1628

	    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,
1629
		     eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0],
1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
		     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
1641

1642 1643 1644
	      uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword);
	      printf("uncoded_ber_bit=%p\n",uncoded_ber_bit);
	    }
1645

1646
	    start_meas(&eNB->ofdm_mod_stats);
1647

1648 1649 1650 1651
	    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);
1652

1653
	    stop_meas(&eNB->ofdm_mod_stats);
1654 1655 1656



1657
	    // generate next subframe for channel estimation
1658

1659 1660 1661
	    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;
1662
	    proc_eNB->subframe_tx = subframe+1;
1663 1664
	    sched_resp.subframe=subframe+1;
	    schedule_response(&sched_resp);
1665
	    phy_procedures_eNB_TX(eNB,proc_eNB,0);
1666 1667


1668 1669 1670
	    ru->proc.subframe_tx=(subframe+1)%10;
	    feptx_prec(ru);
	    feptx_ofdm(ru);
1671

1672

1673
	    proc_eNB->frame_tx++;
1674

1675
            tx_lev = 0;
1676

1677
            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
1678
              tx_lev += signal_energy(&ru->common.txdata[aa]
1679 1680
                                      [subframe*eNB->frame_parms.samples_per_tti],
                                      eNB->frame_parms.samples_per_tti);
1681 1682
            }

1683
            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
1684

1685

1686

1687 1688
            if (n_frames==1) {
              printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
1689

bruno mongazon's avatar
bruno mongazon committed
1690
              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
1691 1692

              if (transmission_mode<7) {
bruno mongazon's avatar
bruno mongazon committed
1693
	        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
1694
              } else if (transmission_mode == 7) {
bruno mongazon's avatar
bruno mongazon committed
1695 1696
                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
1697
              }
1698
            }
1699
	  }
1700

1701
	  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);
1702

1703

tct-labo4's avatar
tct-labo4 committed
1704
	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
1705 1706
	  proc->subframe_rx = subframe;
	  UE->UE_mode[0] = PUSCH;
1707

1708 1709 1710 1711 1712 1713 1714
	  // first symbol has to be done separately in one-shot mode
	  slot_fep(UE,
		   0,
		   (proc->subframe_rx<<1),
		   UE->rx_offset,
		   0,
		   0);
1715

1716
	  if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
1717 1718

	  if (dci_flag==0) {
1719 1720
	    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;
1721 1722 1723 1724 1725 1726 1727
	    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
1728 1729
						   UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
						   UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
1730
						   UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
1731 1732 1733 1734 1735 1736 1737 1738 1739 1740
						   &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
1741 1742
		//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;
1743

gabrielC's avatar
gabrielC committed
1744
		UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
1745 1746 1747 1748 1749 1750 1751

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

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

1754
	  phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx);
1755

gabrielC's avatar
gabrielC committed
1756
	  dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
1757 1758

	  if (dci_flag && (dci_received == 0)) {
1759
	    printf("DCI not received\n");
1760 1761
	    dci_errors[round]++;

bruno mongazon's avatar
bruno mongazon committed
1762 1763
	    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);
1764

bruno mongazon's avatar
bruno mongazon committed
1765 1766
	    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
1767

bruno mongazon's avatar
bruno mongazon committed
1768 1769
	    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);
1770

Cedric Roux's avatar
Cedric Roux committed
1771

1772
	    exit(-1);
Cedric Roux's avatar
Cedric Roux committed
1773

1774
	  }
1775

1776
	  int bit_errors=0;
1777
	  if ((test_perf ==0 ) && (n_frames==1)) {
1778

1779 1780 1781 1782 1783 1784 1785
	    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
1786
	    for (i=0;i<coded_bits_per_codeword;i++)
1787
	      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
1788
		  (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) {
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
		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
1801

bruno mongazon's avatar
bruno mongazon committed
1802 1803
	    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
1804

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

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

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

1813
	    if (UE->frame_parms.nb_antennas_rx>1) {
bruno mongazon's avatar
bruno mongazon committed
1814 1815
	      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);
1816
	    }
1817

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

1822
	    if (UE->frame_parms.nb_antennas_rx>1)
bruno mongazon's avatar
bruno mongazon committed
1823
	      LOG_M("dlsch01_r0.m","dl01_r0",
gabrielC's avatar
gabrielC committed
1824
			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
1825
			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1826

1827
	    if (eNB->frame_parms.nb_antennas_tx>1)
bruno mongazon's avatar
bruno mongazon committed
1828
	      LOG_M("dlsch10_r0.m","dl10_r0",
gabrielC's avatar
gabrielC committed
1829
			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
1830
			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
1831

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

1837
	    //pdsch_vars
1838
	    printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword);
1839

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

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

1844
	    //pdcch_vars
bruno mongazon's avatar
bruno mongazon committed
1845 1846
	    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);
1847

bruno mongazon's avatar
bruno mongazon committed
1848 1849
	    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);
1850

1851
	  }
1852 1853


1854 1855


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

gabrielC's avatar
gabrielC committed
1858
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
1859 1860 1861
            iter_trials++;

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

gabrielC's avatar
gabrielC committed
1864
            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;
1865 1866
            TB0_active = 0;

1867

1868 1869
	  } // DLSCH received ok
	  else {
1870 1871
            errs[round]++;

gabrielC's avatar
gabrielC committed
1872
            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
1873 1874 1875
            iter_trials++;

            if (n_frames==1) {
1876 1877


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

gabrielC's avatar
gabrielC committed
1881 1882 1883
              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;
1884
                else
gabrielC's avatar
gabrielC committed
1885
                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
1886 1887 1888 1889 1890 1891

                Kr_bytes = Kr>>3;

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

                for (i=0; i<Kr_bytes; i++)
gabrielC's avatar
gabrielC committed
1892
                  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]);
1893 1894 1895
              }

              sprintf(fname,"rxsig0_r%d.m",round);
1896
              sprintf(vname,"rxs0_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1897
              LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
1898
              sprintf(fname,"rxsigF0_r%d.m",round);
1899
              sprintf(vname,"rxs0F_r%d",round);
1900

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

1903
              if (UE->frame_parms.nb_antennas_rx>1) {
1904 1905
                sprintf(fname,"rxsig1_r%d.m",round);
                sprintf(vname,"rxs1_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1906
                LOG_M(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
1907
                sprintf(fname,"rxsigF1_r%d.m",round);
1908
                sprintf(vname,"rxs1F_r%d.m",round);
bruno mongazon's avatar
bruno mongazon committed
1909
                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);
1910 1911 1912
              }

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

1918
              if (UE->frame_parms.nb_antennas_rx>1) {
1919
                sprintf(fname,"dlsch01_r%d.m",round);
1920
                sprintf(vname,"dl01_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1921
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1922
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
1923
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1924 1925
              }

1926
              if (eNB->frame_parms.nb_antennas_tx>1) {
1927
                sprintf(fname,"dlsch10_r%d.m",round);
1928
                sprintf(vname,"dl10_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1929
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1930
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
1931
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1932 1933
              }

1934
              if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) {
1935
                sprintf(fname,"dlsch11_r%d.m",round);
1936
                sprintf(vname,"dl11_r%d",round);
bruno mongazon's avatar
bruno mongazon committed
1937
                LOG_M(fname,vname,
gabrielC's avatar
gabrielC committed
1938
                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
1939
                             UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
1940 1941 1942
              }

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

1945

bruno mongazon's avatar
bruno mongazon committed
1946 1947 1948 1949
              //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);
1950
	      //pdcch_vars
bruno mongazon's avatar
bruno mongazon committed
1951 1952
	      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);
1953

bruno mongazon's avatar
bruno mongazon committed
1954 1955
	      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);
1956

1957 1958 1959 1960 1961 1962
              if (round == 3) exit(-1);
            }

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

            round++;
gabrielC's avatar
gabrielC committed
1963
            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
1964 1965
          }

1966 1967
	  if (xforms==1) {
	    phy_scope_UE(form_ue,
1968
			 UE,
1969 1970 1971 1972
			 eNB_id,
			 0,// UE_id
			 subframe);
	  }
1973

tct-labo4's avatar
tct-labo4 committed
1974
	  UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
1975
	}  //round
1976 1977 1978 1979 1980 1981 1982 1983 1984

        //      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
1985
        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx % 10 == 0) {
1986 1987 1988 1989
          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];
1990 1991 1992
        }


1993

1994 1995 1996 1997

        /* calculate the total processing time for each packet,
         * get the max, min, and number of packets that exceed t>2000us
         */
1998 1999 2000 2001
        double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0;
        double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0;
        double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0;
        double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
2002 2003


gabrielC's avatar
gabrielC committed
2004
        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
2005 2006
        double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
        double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
tct-labo4's avatar
tct-labo4 committed
2007
        double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
2008

2009
        if (t_tx > t_tx_max)
2010 2011
          t_tx_max = t_tx;

2012
        if (t_tx < t_tx_min)
2013 2014
          t_tx_min = t_tx;

2015
        if (t_rx > t_rx_max)
2016 2017
          t_rx_max = t_rx;

2018
        if (t_rx < t_rx_min)
2019 2020
          t_rx_min = t_rx;

2021
        if (t_tx > 2000)
2022 2023
          n_tx_dropped++;

2024
        if (t_rx > 2000)
2025 2026
          n_rx_dropped++;

2027
        push_front(&time_vector_tx, t_tx);
2028 2029 2030 2031
        push_front(&time_vector_tx_ifft, t_tx_ifft);
        push_front(&time_vector_tx_mod, t_tx_mod);
        push_front(&time_vector_tx_enc, t_tx_enc);

2032
        push_front(&time_vector_rx, t_rx);
2033 2034 2035
        push_front(&time_vector_rx_fft, t_rx_fft);
        push_front(&time_vector_rx_demod, t_rx_demod);
        push_front(&time_vector_rx_dec, t_rx_dec);
2036 2037


2038
      }   //trials
2039

2040
      // round_trials[0]: number of code word : goodput the protocol
2041 2042
      double table_tx[time_vector_tx.size];
      totable(table_tx, &time_vector_tx);
2043 2044 2045 2046 2047 2048
      double table_tx_ifft[time_vector_tx_ifft.size];
      totable(table_tx_ifft, &time_vector_tx_ifft);
      double table_tx_mod[time_vector_tx_mod.size];
      totable(table_tx_mod, &time_vector_tx_mod);
      double table_tx_enc[time_vector_tx_enc.size];
      totable(table_tx_enc, &time_vector_tx_enc);
2049

2050 2051
      double table_rx[time_vector_rx.size];
      totable(table_rx, &time_vector_rx);
2052 2053 2054 2055 2056
      double table_rx_fft[time_vector_rx_fft.size];
      totable(table_rx_fft, &time_vector_rx_fft);
      double table_rx_demod[time_vector_rx_demod.size];
      totable(table_rx_demod, &time_vector_rx_demod);
      double table_rx_dec[time_vector_rx_dec.size];
2057 2058 2059
      totable(table_rx_dec, &time_vector_rx_dec);


2060 2061 2062
      // sort table
      qsort (table_tx, time_vector_tx.size, sizeof(double), &compare);
      qsort (table_rx, time_vector_rx.size, sizeof(double), &compare);
2063

Navid Nikaein's avatar
Navid Nikaein committed
2064
      if (dump_table == 1 ) {
2065 2066 2067
        set_component_filelog(SIM);  // file located in /tmp/usim.txt
        LOG_UDUMPMSG(SIM,table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n");
        LOG_UDUMPMSG(SIM,table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n");
Navid Nikaein's avatar
Navid Nikaein committed
2068
      }
2069

2070 2071 2072
      double tx_median = table_tx[time_vector_tx.size/2];
      double tx_q1 = table_tx[time_vector_tx.size/4];
      double tx_q3 = table_tx[3*time_vector_tx.size/4];
2073

2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085
      double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2];
      double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4];
      double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4];

      double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2];
      double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4];
      double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4];

      double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2];
      double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4];
      double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4];

2086 2087
      double rx_median = table_rx[time_vector_rx.size/2];
      double rx_q1 = table_rx[time_vector_rx.size/4];
2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101
      double rx_q3 = table_rx[3*time_vector_rx.size/4];

      double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2];
      double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4];
      double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4];

      double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2];
      double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4];
      double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4];

      double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2];
      double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4];
      double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4];

2102
      double std_phy_proc_tx=0;
2103 2104 2105 2106
      double std_phy_proc_tx_ifft=0;
      double std_phy_proc_tx_mod=0;
      double std_phy_proc_tx_enc=0;

2107
      double std_phy_proc_rx=0;
2108 2109 2110
      double std_phy_proc_rx_fft=0;
      double std_phy_proc_rx_demod=0;
      double std_phy_proc_rx_dec=0;
2111

2112
      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]));
2113

2114
      printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n",
2115
             SNR,
2116
             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)));
2117

2118
      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",
2119 2120 2121 2122
             errs[0],
             errs2[0],
             round_trials[0],
             errs[1],
2123
             round_trials[1],
2124
             errs[2],
2125
             round_trials[2],
2126
             errs[3],
2127
             round_trials[3],
2128
             (double)errs[0]/(round_trials[0]),
2129 2130 2131
             (double)errs[1]/(round_trials[1]),
             (double)errs[2]/(round_trials[2]),
             (double)errs[3]/(round_trials[3]),
2132 2133 2134 2135
             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,
2136
             100*effective_rate,
2137
             //rate,
gabrielC's avatar
gabrielC committed
2138
             //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),
2139
             (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])/
2140
             (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2141 2142
             (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]));

2143
      if (print_perf==1) {
2144
        printf("eNB TX function statistics (per 1ms subframe)\n\n");
2145 2146 2147 2148 2149
        std_phy_proc_tx = sqrt((double)eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                               2)/eNB->phy_proc_tx.trials - pow((double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2));
        std_phy_proc_tx_ifft = sqrt((double)eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                    2)/eNB->ofdm_mod_stats.trials - pow((double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2));
        printf("OFDM_mod time                     :%f us (%d trials)\n",(double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,eNB->ofdm_mod_stats.trials);
2150
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);
2151 2152 2153 2154
        printf("Total PHY proc tx                 :%f us (%d trials)\n",(double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_tx.trials);
        printf("|__ Statistcs                           std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3,
               n_tx_dropped);

2155 2156 2157 2158
        std_phy_proc_tx_mod = sqrt((double)eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                   2)/eNB->dlsch_modulation_stats.trials - pow((double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2));
        printf("DLSCH modulation time             :%f us (%d trials)\n",(double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0,
               eNB->dlsch_modulation_stats.trials);
2159
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);
2160 2161 2162 2163 2164 2165
        printf("DLSCH scrambling time             :%f us (%d trials)\n",(double)eNB->dlsch_scrambling_stats.diff/eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0,
               eNB->dlsch_scrambling_stats.trials);
        std_phy_proc_tx_enc = sqrt((double)eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                   2)/eNB->dlsch_encoding_stats.trials - pow((double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2));
        printf("DLSCH encoding time               :%f us (%d trials)\n",(double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0,
               eNB->dlsch_modulation_stats.trials);
2166 2167
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);
        printf("|__ DLSCH turbo encoding time         :%f us (%d trials)\n",
2168 2169
               ((double)eNB->dlsch_turbo_encoding_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
               eNB->dlsch_turbo_encoding_stats.diff/eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_turbo_encoding_stats.trials);
2170
        printf("|__ DLSCH rate-matching time          :%f us (%d trials)\n",
2171 2172
               ((double)eNB->dlsch_rate_matching_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
               eNB->dlsch_rate_matching_stats.diff/eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_rate_matching_stats.trials);
2173
        printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n",
2174 2175
               ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double)
               eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
2176 2177

        printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
gabrielC's avatar
gabrielC committed
2178 2179 2180 2181
        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
2182 2183
        printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
               rx_q1, rx_q3, n_rx_dropped);
2184 2185 2186 2187
        std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                   2)/UE->ofdm_demod_stats.trials - pow((double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2));
        printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0,
               UE->ofdm_demod_stats.trials*2/3);
2188 2189
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3);
        printf("|__ DLSCH rx dft                                        :%f us (%d trials)\n",
2190
               (nsymb*UE->frame_parms.nb_antennas_rx)*(double)UE->rx_dft_stats.diff/UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,UE->rx_dft_stats.trials*2/3);
2191
        printf("|__ DLSCH channel estimation time                       :%f us (%d trials)\n",
2192
               (4.0)*(double)UE->dlsch_channel_estimation_stats.diff/UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_channel_estimation_stats.trials*2/3);
2193
        printf("|__ DLSCH frequency offset estimation time              :%f us (%d trials)\n",
2194 2195 2196 2197 2198 2199
               (4.0)*(double)UE->dlsch_freq_offset_estimation_stats.diff/UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0,
               UE->dlsch_freq_offset_estimation_stats.trials*2/3);
        printf("DLSCH rx pdcch                                       :%f us (%d trials)\n",(double)UE->dlsch_rx_pdcch_stats.diff/UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0,
               UE->dlsch_rx_pdcch_stats.trials);
        std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                     2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2));
2200
        printf("DLSCH Channel Compensation and LLR generation time  :%f us (%d trials)\n",(14-num_pdcch_symbols)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0,
2201
               UE->dlsch_llr_stats.trials/3);
2202
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
2203 2204
        printf("DLSCH unscrambling time                             :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
               UE->dlsch_unscrambling_stats.trials);
tct-labo4's avatar
tct-labo4 committed
2205 2206
        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                   2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
2207
        printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
2208
               eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials,
tct-labo4's avatar
tct-labo4 committed
2209 2210
               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials,
               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0);
2211 2212
        printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
        printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
2213
               (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
2214
        printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
gabrielC's avatar
gabrielC committed
2215
               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,
2216
               (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
2217
        printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
2218 2219 2220
               (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/((double)avg_iter/iter_trials),
               UE->dlsch_tc_init_stats.trials);
2221
        printf("    |__ alpha                                           %f us (cycles/iter %f, %d trials)\n",
2222 2223 2224
               (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials*2,
               UE->dlsch_tc_alpha_stats.trials);
2225
        printf("    |__ beta                                            %f us (cycles/iter %f,%d trials)\n",
2226 2227 2228
               (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials*2,
               UE->dlsch_tc_beta_stats.trials);
2229
        printf("    |__ gamma                                           %f us (cycles/iter %f,%d trials)\n",
2230 2231 2232
               (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials*2,
               UE->dlsch_tc_gamma_stats.trials);
2233
        printf("    |__ ext                                             %f us (cycles/iter %f,%d trials)\n",
2234 2235 2236
               (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials*2,
               UE->dlsch_tc_ext_stats.trials);
2237
        printf("    |__ intl1                                           %f us (cycles/iter %f,%d trials)\n",
2238 2239 2240
               (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials,
               UE->dlsch_tc_intl1_stats.trials);
2241
        printf("    |__ intl2+HD+CRC                                    %f us (cycles/iter %f,%d trials)\n",
2242 2243 2244
               (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0,
               (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials,
               UE->dlsch_tc_intl2_stats.trials);
2245 2246
      }

2247
      if ((transmission_mode != 3) && (transmission_mode != 4)) {
2248 2249 2250
        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
                SNR,
                mcs1,
2251
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
2252 2253 2254 2255 2256 2257 2258 2259 2260
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
2261
                dci_errors[0]);
2262 2263 2264 2265
      } else {
        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
                SNR,
                mcs1,mcs2,
2266 2267
                eNB->dlsch[0][0]->harq_processes[0]->TBS,
                eNB->dlsch[0][1]->harq_processes[0]->TBS,
2268 2269 2270 2271 2272 2273 2274 2275 2276
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3],
2277
                dci_errors[0]);
2278
      }
2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291


      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]);
        }
2292
      } //ABStraction
2293

2294
      if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
2295 2296 2297 2298 2299
        //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,
2300
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
2301 2302 2303 2304 2305 2306 2307 2308 2309
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
2310
                  dci_errors[0]);
2311 2312 2313 2314 2315

          //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,
2316
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
                  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]),
2333
                  dci_errors[0],
2334
                  round_trials[0],
2335
                  (double)dci_errors[0]/(round_trials[0]),
2336
                  (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])/
2337
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2338 2339 2340 2341 2342
                  (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,
2343 2344
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2345 2346 2347 2348 2349 2350 2351 2352 2353
                  rate,
                  errs[0],
                  round_trials[0],
                  errs[1],
                  round_trials[1],
                  errs[2],
                  round_trials[2],
                  errs[3],
                  round_trials[3],
2354
                  dci_errors[0]);
2355 2356 2357 2358 2359

          //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,
2360 2361
                  eNB->dlsch[0][0]->harq_processes[0]->TBS,
                  eNB->dlsch[0][1]->harq_processes[0]->TBS,
2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
                  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]),
2378
                  dci_errors[0],
2379
                  round_trials[0],
2380
                  (double)dci_errors[0]/(round_trials[0]),
2381
                  (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])/
2382
                  (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
2383 2384 2385 2386 2387
                  (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;",
2388 2389 2390 2391 2392
                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,
gabrielC's avatar
gabrielC committed
2393
                UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
2394 2395 2396 2397
                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
2398
                UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
2399 2400
               );
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
2401 2402 2403 2404 2405
                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),
gabrielC's avatar
gabrielC committed
2406
                get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
2407 2408 2409 2410
                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
2411
                get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440
               );
        //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");
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);

        //fprintf(time_meas_fd,"IFFT;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3);

        //fprintf(time_meas_fd,"MOD;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3);

        //fprintf(time_meas_fd,"ENC;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3);


        //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped);

        //fprintf(time_meas_fd,"FFT;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3);

        //fprintf(time_meas_fd,"DEMOD;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3);

        //fprintf(time_meas_fd,"DEC;\n");
        fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);


        /*
        fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;",
2441 2442 2443 2444 2445
        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,
gabrielC's avatar
gabrielC committed
2446
        UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
2447 2448 2449 2450
        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
2451
        UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials);
2452 2453
        */
        printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
2454
	test_passed = 1;
2455 2456 2457
        break;
      } else if (test_perf !=0 ) {
        printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
2458
	test_passed = 0;
2459 2460
      }

2461
      if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
2462 2463 2464 2465 2466 2467 2468
        break;
    }// SNR


  } //ch_realization


2469
  fclose(bler_fd);
2470

2471 2472
  if (test_perf !=0)
    fclose (time_meas_fd);
2473

2474 2475
  //fprintf(tikz_fd,"};\n");
  //fclose(tikz_fd);
2476 2477 2478

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

2480 2481
  if (input_file==1)
    fclose(input_fd);
2482 2483

  if(abstx) { // ABSTRACTION
2484 2485 2486
    fprintf(csv_fd,"];");
    fclose(csv_fd);
  }
2487

2488 2489
  if (uncoded_ber_bit)
    free(uncoded_ber_bit);
2490 2491 2492

  uncoded_ber_bit = NULL;

2493
  printf("Freeing dlsch structures\n");
2494 2495

  for (i=0; i<2; i++) {
2496
    printf("eNB %d\n",i);
2497
    free_eNB_dlsch(eNB->dlsch[0][i]);
2498
    printf("UE %d\n",i);
gabrielC's avatar
gabrielC committed
2499
    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
2500
  }
2501

2502 2503
  if (test_perf && !test_passed)
    return(-1);
Cedric Roux's avatar
Cedric Roux committed
2504
  else
2505
    return(0);
2506
}
2507

2508