ulsim.c 68.9 KB
Newer Older
1
/*
laurent's avatar
laurent committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22

/*! \file ulsim.c
laurent's avatar
laurent committed
23 24 25 26 27 28 29 30
  \brief Top-level UL simulator
  \author R. Knopp
  \date 2011 - 2014
  \version 0.1
  \company Eurecom
  \email: knopp@eurecom.fr
  \note
  \warning
31 32
*/

33 34 35
#include <string.h>
#include <math.h>
#include <unistd.h>
Robert Schmidt's avatar
Robert Schmidt committed
36
#include "common/utils/var_array.h"
37
#include "PHY/types.h"
38 39 40 41
#include "PHY/defs_common.h"
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/phy_vars.h"
42 43 44
#include "PHY/INIT/phy_init.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
45 46
#include "SCHED/sched_eNB.h"
#include "SCHED_UE/sched_UE.h"
47
#include "SIMULATION/TOOLS/sim.h"
48
#include "unitary_defs.h"
49
#include "dummy_functions.c"
frtabu's avatar
frtabu committed
50
#include "nfapi/oai_integration/vendor_ext.h"
51
#include "common/config/config_load_configmodule.h"
52
#include "executables/thread-common.h"
53
#include "executables/lte-softmodem.h"
Raymond Knopp's avatar
Raymond Knopp committed
54 55
#include "common/ran_context.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
laurent's avatar
laurent committed
56
#include "openair1/PHY/LTE_TRANSPORT/dlsch_tbs_full.h"
laurent's avatar
laurent committed
57 58
#include "PHY/phy_extern.h"

Robert Schmidt's avatar
Robert Schmidt committed
59 60 61 62 63 64
const char *__asan_default_options()
{
  /* don't do leak checking in ulsim, not finished yet */
  return "detect_leaks=0";
}

65
double cpuf;
66
#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
laurent's avatar
laurent committed
67
//#define MCS_COUNT 23//added for PHY abstraction
laurent's avatar
laurent committed
68
#include <openair1/SIMULATION/LTE_PHY/common_sim.h>
69 70
channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX];
71
node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
72 73
node_desc_t *ue_data[NUMBER_OF_UE_MAX];

74 75 76
THREAD_STRUCT thread_struct;
nfapi_ue_release_request_body_t release_rntis;

77 78
char title[255];

79 80 81 82 83 84 85
/*the following parameters are used to control the processing times*/
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 tx */
int n_tx_dropped = 0; /*!< \brief initial max process time for tx */
int n_rx_dropped = 0; /*!< \brief initial max process time for rx */
Laurent's avatar
Laurent committed
86 87 88
static int cmpdouble(const void *p1, const void *p2) {
  return *(double *)p1 > *(double *)p2;
}
frtabu's avatar
frtabu committed
89

90
RAN_CONTEXT_t RC;
91 92 93 94
extern void fep_full(RU_t *ru, int subframe);
extern void ru_fep_full_2thread(RU_t *ru, int subframe);
//extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
//extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc);
95 96 97 98

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
99
nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU];
100 101 102 103
nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU];
nfapi_tx_request_t TX_req;
Sched_Rsp_t sched_resp;

104

105
void
Cedric Roux's avatar
Cedric Roux committed
106
fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu,
laurent's avatar
laurent committed
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
                                uint8_t                        cqi_req,
                                uint8_t                        p_eNB,
                                uint8_t                        cqi_ReportModeAperiodic,
                                uint8_t                        betaOffset_CQI_Index,
                                uint8_t                        betaOffset_RI_Index,
                                uint8_t                        dl_cqi_pmi_size,
                                uint8_t                        tmode,
                                uint32_t                       handle,
                                uint16_t                       rnti,
                                uint8_t                        resource_block_start,
                                uint8_t                        number_of_resource_blocks,
                                uint8_t                        modulation_type,
                                uint8_t                        cyclic_shift_2_for_drms,
                                uint8_t                        frequency_hopping_enabled_flag,
                                uint8_t                        frequency_hopping_bits,
                                uint8_t                        new_data_indication,
                                uint8_t                        redundancy_version,
                                uint8_t                        harq_process_number,
                                uint8_t                        ul_tx_mode,
                                uint8_t                        current_tx_nb,
                                uint8_t                        n_srs,
                                uint16_t                       size) {
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
  memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
  ul_config_pdu->pdu_type                                                    = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
  ul_config_pdu->pdu_size                                                    = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu));
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                             = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                             = handle;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                               = rnti;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start               = resource_block_start;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks          = number_of_resource_blocks;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                    = modulation_type;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms            = cyclic_shift_2_for_drms;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag     = frequency_hopping_enabled_flag;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits             = frequency_hopping_bits;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                = new_data_indication;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                 = redundancy_version;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                = harq_process_number;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                         = ul_tx_mode;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                      = current_tx_nb;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                              = n_srs;
  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                               = size;

Raymond Knopp's avatar
Raymond Knopp committed
149 150
  //printf("Filling ul_config_pdu : Q %d, TBS %d, rv %d, ndi %d\n", modulation_type,size,redundancy_version,new_data_indication);

151 152 153 154 155 156 157 158 159 160
  if (cqi_req == 1) {
    // Add CQI portion
    ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE;
    ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu));
    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG;
    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1;
    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1;
    LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type);

    if (p_eNB <= 2
laurent's avatar
laurent committed
161
        && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10))
162 163 164 165
      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1;
    else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0;
    else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2;

Cedric Roux's avatar
Cedric Roux committed
166
    for (int ri = 0;
laurent's avatar
laurent committed
167 168 169
         ri <  (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size);
         ri++)
      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] =  dl_cqi_pmi_size;
Cedric Roux's avatar
Cedric Roux committed
170

171 172 173 174
    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index;
    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri  = betaOffset_RI_Index;
  }
}
175

176
void fill_ulsch_dci(PHY_VARS_eNB *eNB,
laurent's avatar
laurent committed
177 178 179 180 181 182 183 184 185 186
                    int frame,
                    int subframe,
                    Sched_Rsp_t *sched_resp,
                    uint16_t rnti,
                    void *UL_dci,
                    int first_rb,
                    int nb_rb,
                    int mcs,
                    int modulation_type,
                    int ndi,
Raymond Knopp's avatar
Raymond Knopp committed
187
                    int TBS,
laurent's avatar
laurent committed
188 189 190 191
                    int cqi_flag,
                    uint8_t beta_CQI,
                    uint8_t beta_RI,
                    uint8_t cqi_size) {
192 193 194
  nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body;
  int harq_pid = ((frame*10)+subframe)&7;

Raymond Knopp's avatar
Raymond Knopp committed
195
  //printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi);
196 197

  switch (eNB->frame_parms.N_RB_UL) {
laurent's avatar
laurent committed
198 199
    case 6:
      break;
200

laurent's avatar
laurent committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
    case 25:
      if (eNB->frame_parms.frame_type == TDD) {
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->type    = 0;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->mcs     = mcs;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->ndi     = ndi;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->TPC     = 0;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->cshift  = 0;
        ((DCI0_5MHz_TDD_1_6_t *)UL_dci)->dai     = 1;
      } else {
        ((DCI0_5MHz_FDD_t *)UL_dci)->type    = 0;
        ((DCI0_5MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //      printf("nb_rb %d/%d, rballoc %d (dci %x) (dcip %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_5MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,UL_dci);
        ((DCI0_5MHz_FDD_t *)UL_dci)->mcs     = mcs;
        ((DCI0_5MHz_FDD_t *)UL_dci)->ndi     = ndi;
        ((DCI0_5MHz_FDD_t *)UL_dci)->TPC     = 0;
        ((DCI0_5MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_5MHz_FDD_t *)UL_dci)->cshift  = 0;
      }
222

laurent's avatar
laurent committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
      break;

    case 50:
      if (eNB->frame_parms.frame_type == TDD) {
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->type    = 0;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->mcs     = mcs;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->ndi     = ndi;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->TPC     = 0;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->cshift  = 0;
        ((DCI0_10MHz_TDD_1_6_t *)UL_dci)->dai     = 1;
      } else {
        ((DCI0_10MHz_FDD_t *)UL_dci)->type    = 0;
        ((DCI0_10MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_10MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
        ((DCI0_10MHz_FDD_t *)UL_dci)->mcs     = mcs;
        ((DCI0_10MHz_FDD_t *)UL_dci)->ndi     = ndi;
        ((DCI0_10MHz_FDD_t *)UL_dci)->TPC     = 0;
        ((DCI0_10MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_10MHz_FDD_t *)UL_dci)->cshift  = 0;
      }

      break;

    case 100:
      if (eNB->frame_parms.frame_type == TDD) {
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->type    = 0;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //      printf("nb_rb %d/%d, rballoc %d (dci %x)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_TDD_1_6_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci);
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->mcs     = mcs;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->ndi     = ndi;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->TPC     = 0;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->cshift  = 0;
        ((DCI0_20MHz_TDD_1_6_t *)UL_dci)->dai     = 1;
      } else {
        ((DCI0_20MHz_FDD_t *)UL_dci)->type    = 0;
        ((DCI0_20MHz_FDD_t *)UL_dci)->rballoc = computeRIV(eNB->frame_parms.N_RB_UL,first_rb,nb_rb); // 12 RBs from position 8
        //   printf("nb_rb %d/%d, rballoc %d (dci %x) (UL_dci %p)\n",nb_rb,eNB->frame_parms.N_RB_UL,((DCI0_20MHz_FDD_t*)UL_dci)->rballoc,*(uint32_t *)UL_dci,(void*)UL_dci);
        ((DCI0_20MHz_FDD_t *)UL_dci)->mcs     = mcs;
        ((DCI0_20MHz_FDD_t *)UL_dci)->ndi     = ndi;
        ((DCI0_20MHz_FDD_t *)UL_dci)->TPC     = 0;
        ((DCI0_20MHz_FDD_t *)UL_dci)->cqi_req = cqi_flag&1;
        ((DCI0_20MHz_FDD_t *)UL_dci)->cshift  = 0;
      }
270

laurent's avatar
laurent committed
271
      break;
272

laurent's avatar
laurent committed
273 274
    default:
      break;
275 276
  }

Cedric Roux's avatar
Cedric Roux committed
277
  fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0],
laurent's avatar
laurent committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
                                  cqi_flag&1,
                                  1,  // p_eNB
                                  0,  // reportmode Aperiodic
                                  beta_CQI,
                                  beta_RI,
                                  cqi_size,
                                  //cc,
                                  //UE_template->physicalConfigDedicated,
                                  1,
                                  0,
                                  14,     // rnti
                                  first_rb, // resource_block_start
                                  nb_rb,  // number_of_resource_blocks
                                  modulation_type,
                                  0,  // cyclic_shift_2_for_drms
                                  0,  // frequency_hopping_enabled_flag
                                  0,  // frequency_hopping_bits
                                  ndi,  // new_data_indication
                                  mcs>28?(mcs-28):0,  // redundancy_version
                                  harq_pid, // harq_process_number
                                  0,  // ul_tx_mode
                                  0,  // current_tx_nb
                                  0,  // n_srs
                                  TBS);
302 303 304
  sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
  ul_req->number_of_pdus=1;
  ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
laurent's avatar
laurent committed
305
}
Cedric Roux's avatar
Cedric Roux committed
306

laurent's avatar
laurent committed
307
enum eTypes { eBool, eInt, eFloat, eText };
laurent's avatar
laurent committed
308
static int verbose,help,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1;
309

laurent's avatar
laurent committed
310
int main(int argc, char **argv) {
311
  int i,j,aa,u;
312 313 314
  PHY_VARS_eNB *eNB;
  PHY_VARS_UE *UE;
  RU_t *ru;
315 316
  int aarx,aatx;
  double channelx,channely;
laurent's avatar
laurent committed
317 318
  static double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
  static double input_snr_step=.2,snr_int=30;
319
  double blerr;
laurent's avatar
laurent committed
320
  int rvidx[8]= {0,2,3,1,0,2,3,1};
321 322
  int **txdata;
  LTE_DL_FRAME_PARMS *frame_parms;
323 324
  double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720];
  double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720];
325 326
  double r_re2[30720],r_im2[30720];
  double r_re3[30720],r_im3[30720];
Laurent THOMAS's avatar
Laurent THOMAS committed
327 328 329 330
  double *s_re[NB_ANTENNAS_TX]= {s_re0,s_re1, NULL, NULL};
  double *s_im[NB_ANTENNAS_TX]= {s_im0,s_im1, NULL, NULL};
  double *r_re[NB_ANTENNAS_RX]= {r_re0,r_re1,r_re2,r_re3};
  double *r_im[NB_ANTENNAS_RX]= {r_im0,r_im1,r_im2,r_im3};
331 332
  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
  double iqim=0.0;
laurent's avatar
laurent committed
333
  int cqi_error,cqi_errors,ack_errors,cqi_crc_falsepositives,cqi_crc_falsenegatives;
334 335 336 337
  int ch_realization;
  int eNB_id = 0;
  int chMod = 0 ;
  int UE_id = 0;
laurent's avatar
laurent committed
338
  static int nb_rb=25,first_rb=0,mcs=0,round=0;
339
  //unsigned char l;
340
  SCM_t channel_model=Rice1;
laurent's avatar
laurent committed
341
  unsigned char *input_buffer=0,harq_pid;
342 343 344
  unsigned short input_buffer_length;
  unsigned int ret;
  unsigned int coded_bits_per_codeword,nsymb;
laurent's avatar
laurent committed
345
  unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0};
346
  FILE *bler_fd=NULL;
347
  char bler_fname[512];
348 349
  FILE *time_meas_fd=NULL;
  char time_meas_fname[256];
350 351 352 353
  FILE *input_fdUL=NULL,*trch_out_fdUL=NULL;
  //  unsigned char input_file=0;
  char input_val_str[50],input_val_str2[50];
  //  FILE *rx_frame_file;
354
  FILE *csv_fdUL=NULL;
355
  char csv_fname[512];
laurent's avatar
laurent committed
356 357 358
  static int n_frames=5000;
  static int n_ch_rlz = 1;
  static int abstx = 0;
359
  int hold_channel=0;
360
  channel_desc_t *UE2eNB;
361
  //uint8_t control_only_flag = 0;
laurent's avatar
laurent committed
362 363 364 365
  static int delay = 0;
  static double maxDoppler = 0.0;
  static int srs_flag = 0;
  static int N_RB_DL=25,osf=1;
366
  //uint8_t cyclic_shift = 0;
laurent's avatar
laurent committed
367 368 369 370
  static uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11;
  static uint8_t tdd_config=3,frame_type=FDD;
  static int N0=30;
  static double tx_gain=1.0;
371
  double cpu_freq_GHz;
laurent's avatar
laurent committed
372
  int iter_trials;
373 374
  uint32_t UL_alloc_pdu;
  int dump_perf=0;
laurent's avatar
laurent committed
375
  static int dump_table =0;
376
  double effective_rate=0.0;
laurent's avatar
laurent committed
377 378
  char channel_model_input[10]= {0};
  static int max_turbo_iterations=4;
379
  int nb_rb_set = 0;
380
  int sf;
laurent's avatar
laurent committed
381
  static int threequarter_fs=0;
382
  int ndi;
Raymond Knopp's avatar
 
Raymond Knopp committed
383
  opp_enabled=1; // to enable the time meas
384 385 386 387
  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;
laurent's avatar
laurent committed
388 389 390 391
  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));
392 393
  UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list;
  TX_req.tx_request_body.tx_pdu_list = tx_pdu_list;
394
  cpu_freq_GHz = (double)get_cpu_freq_GHz();
395
  cpuf = cpu_freq_GHz;
laurent's avatar
laurent committed
396
  set_parallel_conf("PARALLEL_SINGLE_THREAD");
397
  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
yilmazt's avatar
yilmazt committed
398
  AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) != NULL, "Cannot load configuration module, exiting\n");
399
  logInit();
400
  set_glog(OAILOG_INFO);
401
  T_stdout = 1;
Calisson's avatar
Calisson committed
402 403 404
  // enable these lines if you need debug info
  // however itti will catch all signals, so ctrl-c won't work anymore
  // alternatively you can disable ITTI completely in CMakeLists.txt
Raymond Knopp's avatar
Raymond Knopp committed
405 406
  //  set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
  //  set_glog(LOG_DEBUG,LOG_HIGH);
laurent's avatar
laurent committed
407 408
  //hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF
  static paramdef_t options[] = {
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
    { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, .strptr=NULL, .defintval=0, TYPE_INT, 0, NULL, NULL },
    { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, .iptr=&N_RB_DL,  .defintval=25, TYPE_INT, 0 },
    { "mcs", "The MCS to use", 0, .iptr=&mcs,  .defintval=10, TYPE_INT, 0 },
    { "nb_frame", "number of frame in a test",0, .iptr=&n_frames,  .defintval=1, TYPE_INT, 0 },
    { "snr", "starting snr", 0, .dblptr=&snr0,  .defdblval=-2.9, TYPE_DOUBLE, 0 },
    { "wsnrInterrupt", "snr int ?", 0, .dblptr=&snr_int,  .defdblval=30, TYPE_DOUBLE, 0 },
    { "e_snr_step", "step increasing snr",0, .dblptr=&input_snr_step,  .defdblval=0.2, TYPE_DOUBLE, 0 },
    { "rb_dynamic", "number of rb in dynamic allocation",0, .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "first_rb", "first rb used in dynamic allocation",0, .iptr=&first_rb,  .defintval=0, TYPE_INT, 0 },
    { "osrs", "enable srs generation",PARAMFLAG_BOOL, .iptr=&srs_flag,  .defintval=0, TYPE_INT, 0 },
    { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'),  Rice8('L'), Rice1('M')",0, .strptr=NULL,  .defstrval=NULL, TYPE_STRING, 0 },
    { "delay_chan", "Channel delay",0, .iptr=&delay,  .defintval=0, TYPE_INT, 0 },
    { "Doppler", "Maximum doppler shift",0, .dblptr=&maxDoppler,  .defdblval=0.0, TYPE_DOUBLE, 0 },
    { "Zdump", "dump table",PARAMFLAG_BOOL,  .iptr=&dump_table, .defintval=0, TYPE_INT, 0 },
    { "Lparallel", "Enable parallel execution",0, .strptr=NULL,  .defstrval=NULL, TYPE_STRING,  0 },
    { "Iterations", "Number of iterations of turbo decoder", 0, .iptr=&max_turbo_iterations,  .defintval=4, TYPE_INT, 0 },
    { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL,  .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "Q_cqi", "Enable CQI", PARAMFLAG_BOOL, .iptr=&cqi_flag,  .defintval=0, TYPE_INT, 0 },
    { "prefix_extended","Extended prefix", PARAMFLAG_BOOL, .iptr=&extended_prefix_flag,  .defintval=0, TYPE_INT, 0 },
    { "RI_beta", "TBD", 0, .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "CQI_beta", "TBD",0, .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "ACK_beta", "TBD",0, .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "input_file", "input IQ data file",0, .iptr=NULL,  .defintval=0, TYPE_INT, 0 },
    { "N0", "N0",0, .iptr=&N0,  .defintval=30, TYPE_INT, 0 },
    { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, .iptr=&threequarter_fs, .defintval=0, TYPE_INT, 0 },
    { "TDD", "Enable TDD and set the tdd configuration mode",0, .iptr=NULL,  .defintval=25, TYPE_INT, 0 },
    { "Subframe", "subframe to use",0, .iptr=&subframe,  .defintval=3, TYPE_INT, 0 },
    { "xTransmission","transmission mode (1 or 2 are supported)",0, .iptr=NULL,  .defintval=25, TYPE_INT, 0 },
    { "yN_rx", "TBD: n_rx",0, .iptr=&n_rx,  .defintval=1, TYPE_INT, 0 },
    { "bundling_disable", "bundling disable",PARAMFLAG_BOOL,  .iptr=&disable_bundling, .defintval=0, TYPE_INT, 0 },
    { "Y",  "n_ch_rlz",0, .iptr=&n_ch_rlz,  .defintval=1, TYPE_INT, 0 },
    { "X",  "abstx", PARAMFLAG_BOOL,  .iptr=&abstx, .defintval=0, TYPE_INT, 0 },
    { "Operf", "Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, .iptr=&test_perf,  .defintval=0, TYPE_INT, 0 },
    { "verbose", "display debug text", PARAMFLAG_BOOL,  .iptr=&verbose, .defintval=0, TYPE_INT, 0 },
    { "help", "display help and exit", PARAMFLAG_BOOL,  .iptr=&help, .defintval=0, TYPE_INT, 0 },
    { "", "",0,  .iptr=NULL, .defintval=0, TYPE_INT, 0 },
laurent's avatar
laurent committed
445
  };
frtabu's avatar
frtabu committed
446
  struct option *long_options = parse_oai_options(options);
laurent's avatar
laurent committed
447 448
  int option_index;
  int res;
449

laurent's avatar
laurent committed
450 451 452 453 454
  while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) {
    if (options[option_index].voidptr != NULL ) {
      if (long_options[option_index].has_arg==no_argument)
        *(bool *)options[option_index].iptr=1;
      else switch (options[option_index].type) {
frtabu's avatar
frtabu committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
          case TYPE_INT:
            *(int *)options[option_index].iptr=atoi(optarg);
            break;

          case TYPE_DOUBLE:
            *(double *)options[option_index].dblptr=atof(optarg);
            break;

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

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

          default:
            printf("not decoded type.\n");
            exit(1);
laurent's avatar
laurent committed
474
        }
475

laurent's avatar
laurent committed
476 477
      continue;
    }
478

laurent's avatar
laurent committed
479
    switch (long_options[option_index].name[0]) {
frtabu's avatar
frtabu committed
480 481 482 483
      case 'T':
        tdd_config=atoi(optarg);
        frame_type=TDD;
        break;
laurent's avatar
laurent committed
484

frtabu's avatar
frtabu committed
485 486 487 488
      case 'a':
        channel_model = AWGN;
        chMod = 1;
        break;
laurent's avatar
laurent committed
489

frtabu's avatar
frtabu committed
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
      case 'g':
        strncpy(channel_model_input,optarg,9);
        struct tmp {
          char opt;
          int m;
          int M;
        }
        tmp[]= {
          {'A',SCM_A,2},
          {'B',SCM_B,3},
          {'C',SCM_C,4},
          {'D',SCM_D,5},
          {'E',EPA,6},
          {'G',ETU,8},
          {'H',Rayleigh8,9},
          {'I',Rayleigh1,10},
          {'J',Rayleigh1_corr,11},
          {'K',Rayleigh1_anticorr,12},
          {'L',Rice8,13},
          {'M',Rice1,14},
          {'N',AWGN,1},
          {0,0,0}
        };
        struct tmp *ptr;

        for (ptr=tmp; ptr->opt!=0; ptr++)
          if ( ptr->opt == optarg[0] ) {
            channel_model=ptr->m;
            chMod=ptr->M;
            break;
          }
laurent's avatar
laurent committed
521

frtabu's avatar
frtabu committed
522 523
        AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg );
        break;
laurent's avatar
laurent committed
524

frtabu's avatar
frtabu committed
525 526 527 528 529 530 531 532 533 534
      case 'x':
        transmission_m=atoi(optarg);
        AssertFatal(transmission_m==1 || transmission_m==2,
                    "Unsupported transmission mode %d\n",transmission_m);
        break;

      case 'r':
        nb_rb = atoi(optarg);
        nb_rb_set = 1;
        break;
535

laurent's avatar
laurent committed
536 537 538
      //case 'c':
      //  cyclic_shift = atoi(optarg);
      //  break;
539

frtabu's avatar
frtabu committed
540 541 542 543 544
      case 'i':
        input_fdUL = fopen(optarg,"r");
        printf("Reading in %s (%p)\n",optarg,input_fdUL);
        AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg);
        break;
laurent's avatar
laurent committed
545

frtabu's avatar
frtabu committed
546 547 548 549
      case 'A':
        beta_ACK = atoi(optarg);
        AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n");
        break;
laurent's avatar
laurent committed
550

frtabu's avatar
frtabu committed
551 552 553 554
      case 'C':
        beta_CQI = atoi(optarg);
        AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n");
        break;
laurent's avatar
laurent committed
555

frtabu's avatar
frtabu committed
556 557 558 559
      case 'R':
        beta_RI = atoi(optarg);
        AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n");
        break;
laurent's avatar
laurent committed
560

frtabu's avatar
frtabu committed
561 562 563 564
      case 'P':
        dump_perf=1;
        opp_enabled=1;
        break;
laurent's avatar
laurent committed
565

frtabu's avatar
frtabu committed
566 567 568 569 570 571 572 573
      case 'L':
        set_parallel_conf(optarg);
        break;

      default:
        printf("Wrong option: %s\n",long_options[option_index].name);
        exit(1);
        break;
laurent's avatar
laurent committed
574 575
    }
  }
576

laurent's avatar
laurent committed
577 578 579 580
  if ( res != -1 ) {
    printf("A wrong option has been found\n");
    exit(1);
  }
581

laurent's avatar
laurent committed
582
  if (help || verbose )
frtabu's avatar
frtabu committed
583 584
    display_options_values(options, true);

laurent's avatar
laurent committed
585 586
  if (help)
    exit(0);
frtabu's avatar
frtabu committed
587

laurent's avatar
laurent committed
588 589
  if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD)
    set_worker_conf("WORKER_ENABLE");
frtabu's avatar
frtabu committed
590

591 592 593
  RC.nb_L1_inst = 1;
  RC.nb_RU = 1;
  lte_param_init(&eNB,&UE,&ru,
594
                 1,
laurent's avatar
laurent committed
595 596 597 598 599 600 601 602 603 604 605 606 607
                 1,
                 n_rx,
                 1,
                 1,
                 extended_prefix_flag,
                 frame_type,
                 0,
                 tdd_config,
                 N_RB_DL,
                 4,
                 threequarter_fs,
                 osf,
                 0);
frtabu's avatar
frtabu committed
608
  RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **));
609 610 611 612 613
  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;

laurent's avatar
laurent committed
614
  for (int k=0; k<eNB->RU_list[0]->nb_rx; k++) eNB->common_vars.rxdataF[k]     =  eNB->RU_list[0]->common.rxdataF[k];
Cedric Roux's avatar
Cedric Roux committed
615

laurent's avatar
laurent committed
616
  memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO));
617 618 619 620 621
  printf("Setting indication lists\n");
  eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list   = eNB->rx_pdu_list;
  eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
  eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list;
  eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
622 623
  eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list;
  eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
624
  printf("lte_param_init done\n");
Calisson's avatar
Calisson committed
625
  // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE
frtabu's avatar
frtabu committed
626
  PHY_vars_UE_g = (PHY_VARS_UE ** *)malloc(sizeof(PHY_VARS_UE **));
laurent's avatar
laurent committed
627
  PHY_vars_UE_g[0] = (PHY_VARS_UE **) malloc(sizeof(PHY_VARS_UE *));
Calisson's avatar
Calisson committed
628 629
  PHY_vars_UE_g[0][0] = UE;

630
  if (nb_rb_set == 0)
631
    nb_rb = eNB->frame_parms.N_RB_UL;
632

633
  printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]);
634
  printf("Setting mcs = %d\n",mcs);
635
  printf("n_frames = %d\n", n_frames);
Raymond Knopp's avatar
 
Raymond Knopp committed
636
  snr1 = snr0+snr_int;
637
  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
638 639 640
  frame_parms = &eNB->frame_parms;
  txdata = UE->common_vars.txdata;
  nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12;
641
  sprintf(bler_fname,"ULbler_mcs%d_nrb%d_ChannelModel%d_nsim%d.csv",mcs,nb_rb,chMod,n_frames);
642
  bler_fd = fopen(bler_fname,"w");
laurent's avatar
laurent committed
643

644 645 646 647
  if (bler_fd==NULL) {
    fprintf(stderr,"Problem creating file %s\n",bler_fname);
    exit(-1);
  }
648

649
  fprintf(bler_fd,"#SNR;mcs;nb_rb;TBS;rate;errors[0];trials[0];errors[1];trials[1];errors[2];trials[2];errors[3];trials[3]\n");
650 651

  if (test_perf != 0) {
652 653 654 655
    char hostname[1024];
    hostname[1023] = '\0';
    gethostname(hostname, 1023);
    printf("Hostname: %s\n", hostname);
656
    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_antrx%d_channel%s_tx%d.csv",
laurent's avatar
laurent committed
657
            N_RB_DL,mcs,n_rx,channel_model_input,transmission_m);
658
    time_meas_fd = fopen(time_meas_fname,"w");
laurent's avatar
laurent committed
659

660 661 662 663
    if (time_meas_fd==NULL) {
      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
      exit(-1);
    }
664
  }
665 666 667

  if(abstx) {
    // CSV file
laurent's avatar
laurent committed
668
    sprintf(csv_fname,"EULdataout_tx%d_mcs%d_nbrb%d_chan%d_nsimus%d_eren.m",transmission_m,mcs,nb_rb,chMod,n_frames);
669
    csv_fdUL = fopen(csv_fname,"w");
laurent's avatar
laurent committed
670

671 672 673 674
    if (csv_fdUL == NULL) {
      fprintf(stderr,"Problem opening file %s\n",csv_fname);
      exit(-1);
    }
laurent's avatar
laurent committed
675

676 677
    fprintf(csv_fdUL,"data_all%d=[",mcs);
  }
678

hbilel's avatar
hbilel committed
679
  UE->pdcch_vars[0][0]->crnti = 14;
680
  UE->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag;
681
  UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
682 683 684 685
  UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3;
  UE->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = srs_flag;
  UE->soundingrs_ul_config_dedicated[eNB_id].duration = 1;
  UE->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = 2;
686 687 688
  UE->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = 0;
  UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0;
  UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0;
689
  UE->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = 0;
690
  eNB->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag;
691
  eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2;
692 693 694 695
  eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3;
  eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup = srs_flag;
  eNB->soundingrs_ul_config_dedicated[UE_id].duration = 1;
  eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex = 2;
696 697 698
  eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth = 0;
  eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0;
  eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0;
699
  eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0;
700 701 702 703 704 705 706
  eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK;
  eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index  = beta_RI;
  eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index = beta_CQI;
  UE->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = beta_ACK;
  UE->pusch_config_dedicated[eNB_id].betaOffset_RI_Index  = beta_RI;
  UE->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = beta_CQI;
  UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1;
707 708 709
  // disable periodic cqi/ri reporting
  UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1;
  UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1;
710
  printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8);
711 712
  UE2eNB = new_channel_desc_scm(1,
                                n_rx,
713
                                channel_model,
laurent's avatar
laurent committed
714
                                N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
715
                                0,
laurent's avatar
laurent committed
716
                                N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
717
                                30e-9,
718
                                maxDoppler,
719
                                CORR_LEVEL_LOW,
720 721
                                forgetting_factor,
                                delay,
722 723
                                0,
                                0);
724 725

  // NN: N_RB_UL has to be defined in ulsim
726
  for (int k=0; k<NUMBER_OF_ULSCH_MAX; k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0);
laurent's avatar
laurent committed
727

728
  UE->ulsch[0]   = new_ue_ulsch(N_RB_DL,0);
729
  printf("ULSCH %p\n",UE->ulsch[0]);
730

laurent's avatar
laurent committed
731
  if(get_thread_worker_conf() == WORKER_ENABLE) {
732
    extern void init_fep_thread(RU_t *, pthread_attr_t *);
laurent's avatar
laurent committed
733
    init_fep_thread(ru, NULL);
734
  }
laurent's avatar
laurent committed
735

736
  // Create transport channel structures for 2 transport blocks (MIMO)
737
  for (i=0; i<2; i++) {
738
    eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms);
laurent's avatar
laurent committed
739

740
    if (!eNB->dlsch[0][i]) {
741 742 743
      printf("Can't get eNB dlsch structures\n");
      exit(-1);
    }
laurent's avatar
laurent committed
744

745
    eNB->dlsch[0][i]->rnti = 14;
746
  }
laurent's avatar
laurent committed
747

748
  /* allocate memory for both subframes (only one is really used
laurent's avatar
laurent committed
749 750 751 752
     but there is now "copy_harq_proc_struct" which needs both
     to be valid)
     TODO: refine this somehow (necessary?)
  */
753 754 755
  for (sf = 0; sf < 2; sf++) {
    for (i=0; i<2; i++) {
      UE->dlsch[sf][0][i]  = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
laurent's avatar
laurent committed
756

757 758 759 760
      if (!UE->dlsch[sf][0][i]) {
        printf("Can't get ue dlsch structures\n");
        exit(-1);
      }
laurent's avatar
laurent committed
761

762 763 764
      UE->dlsch[sf][0][i]->rnti   = 14;
    }
  }
765

766 767
  UE->dlsch_SI[0]  = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
  UE->dlsch_ra[0]  = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0);
768 769
  UE->measurements.rank[0] = 0;
  UE->transmission_mode[0] = 2;
laurent's avatar
laurent committed
770
  UE->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing;
771
  eNB->transmission_mode[0] = 2;
laurent's avatar
laurent committed
772
  eNB->pucch_config_dedicated[0].tdd_AckNackFeedbackMode = disable_bundling == 0 ? bundling : multiplexing;
773 774 775 776 777 778
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
  UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
  eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;
779
  UE->mac_enabled=0;
780
  L1_rxtx_proc_t *proc_rxtx         = &eNB->proc.L1_proc;
781
  UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1];
782 783 784 785
  proc_rxtx->frame_rx=1;
  proc_rxtx->subframe_rx=subframe;
  proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe);
  proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe);
786
  proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx;
787
  proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
788
  proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
789
  proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
790
  proc_rxtx->threadPool = (tpool_t *)malloc(sizeof(tpool_t));
laurent's avatar
laurent committed
791
  proc_rxtx->respDecode=(notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
792
  initTpool("n", proc_rxtx->threadPool, true);
laurent's avatar
laurent committed
793
  initNotifiedFIFO(proc_rxtx->respDecode);
794

795
  printf("Init UL hopping UE\n");
796
  init_ul_hopping(&UE->frame_parms);
797
  printf("Init UL hopping eNB\n");
798
  init_ul_hopping(&eNB->frame_parms);
799
  UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1;
800 801
  UE->ulsch_Msg3_active[eNB_id] = 0;
  UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1;
802 803
  coded_bits_per_codeword = nb_rb * (12 * get_Qm_ul(mcs)) * nsymb;

804
  if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O;
805

laurent's avatar
laurent committed
806
  rate = (double)TBStable[get_I_TBS(mcs)][nb_rb - 1] / (coded_bits_per_codeword);
807
  printf("Rate = %f (mod %d), coded bits %u\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword);
808

809
  for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) {
810 811 812 813 814 815
    /*
      if(abstx){
      int ulchestim_f[300*12];
      int ulchestim_t[2*(frame_parms->ofdm_symbol_size)];
      }
    */
816
    if(abstx) {
817 818 819
      printf("**********************Channel Realization Index = %d **************************\n", ch_realization);
      saving_bler=1;
    }
820

Raymond Knopp's avatar
 
Raymond Knopp committed
821
    //    if ((subframe>5) || (subframe < 4))
822
    //      UE->frame++;
823 824

    for (SNR=snr0; SNR<snr1; SNR+=input_snr_step) {
825 826 827 828 829 830 831 832 833 834 835 836 837 838
      errs[0]=0;
      errs[1]=0;
      errs[2]=0;
      errs[3]=0;
      round_trials[0] = 0;
      round_trials[1] = 0;
      round_trials[2] = 0;
      round_trials[3] = 0;
      cqi_errors=0;
      ack_errors=0;
      cqi_crc_falsepositives=0;
      cqi_crc_falsenegatives=0;
      round=0;
      //randominit(0);
839
      harq_pid = subframe2harq_pid(&UE->frame_parms,proc_rxtx_ue->frame_tx,subframe);
840
      input_buffer_length = UE->ulsch[0]->harq_processes[harq_pid]->TBS/8;
laurent's avatar
laurent committed
841 842 843 844

      if ( input_buffer != NULL )
        free(input_buffer);

845
      input_buffer = (unsigned char *)memalign(32,input_buffer_length+64);
laurent's avatar
laurent committed
846

847
      //      printf("UL frame %d/subframe %d, harq_pid %d\n",UE->frame,subframe,harq_pid);
848
      if (input_fdUL == NULL) {
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
        if (n_frames == 1) {
          trch_out_fdUL= fopen("ulsch_trchUL.txt","w");

          for (i=0; i<input_buffer_length; i++) {
            input_buffer[i] = taus()&0xff;

            for (j=0; j<8; j++)
              fprintf(trch_out_fdUL,"%d\n",(input_buffer[i]>>(7-j))&1);
          }

          fclose(trch_out_fdUL);
        } else {
          for (i=0; i<input_buffer_length; i++)
            input_buffer[i] = taus()&0xff;
        }
      } else {
        n_frames=1;
        i=0;

        while (!feof(input_fdUL)) {
869
          ret=fscanf(input_fdUL,"%49s %49s",input_val_str,input_val_str2);//&input_val1,&input_val2);
laurent's avatar
laurent committed
870

871
          if (ret != 2) printf("ERROR: error reading file\n");
872 873

          if ((i%4)==0) {
laurent's avatar
laurent committed
874 875
            ((short *)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL));
            ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL));
876 877

            if ((i/4)<100)
laurent's avatar
laurent committed
878
              printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short *)txdata[0])[i/4],((short *)txdata[0])[(i/4)+1]); //1,input_val2,);
879 880 881 882 883 884 885 886 887
          }

          i++;

          if (i>(FRAME_LENGTH_SAMPLES))
            break;
        }

        printf("Read in %d samples\n",i/4);
bruno mongazon's avatar
bruno mongazon committed
888 889
        //      LOG_M("txsig0UL.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1);
        //    LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
890 891 892
        tx_lev = signal_energy(&txdata[0][0],
                               OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
        tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
893 894
      }

895
      iter_trials=0;
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
      reset_meas(&UE->phy_proc_tx);
      reset_meas(&UE->ofdm_mod_stats);
      reset_meas(&UE->ulsch_modulation_stats);
      reset_meas(&UE->ulsch_encoding_stats);
      reset_meas(&UE->ulsch_interleaving_stats);
      reset_meas(&UE->ulsch_rate_matching_stats);
      reset_meas(&UE->ulsch_turbo_encoding_stats);
      reset_meas(&UE->ulsch_segmentation_stats);
      reset_meas(&UE->ulsch_multiplexing_stats);
      reset_meas(&eNB->phy_proc_rx);
      reset_meas(&eNB->ulsch_channel_estimation_stats);
      reset_meas(&eNB->ulsch_freq_offset_estimation_stats);
      reset_meas(&eNB->rx_dft_stats);
      reset_meas(&eNB->ulsch_decoding_stats);
      reset_meas(&eNB->ulsch_turbo_decoding_stats);
      reset_meas(&eNB->ulsch_deinterleaving_stats);
      reset_meas(&eNB->ulsch_demultiplexing_stats);
      reset_meas(&eNB->ulsch_rate_unmatching_stats);
laurent's avatar
laurent committed
914
      reset_meas(&eNB->ulsch_demodulation_stats);
915 916 917 918 919 920 921
      reset_meas(&eNB->ulsch_tc_init_stats);
      reset_meas(&eNB->ulsch_tc_alpha_stats);
      reset_meas(&eNB->ulsch_tc_beta_stats);
      reset_meas(&eNB->ulsch_tc_gamma_stats);
      reset_meas(&eNB->ulsch_tc_ext_stats);
      reset_meas(&eNB->ulsch_tc_intl1_stats);
      reset_meas(&eNB->ulsch_tc_intl2_stats);
Cedric Roux's avatar
Cedric Roux committed
922
      // initialization
laurent's avatar
laurent committed
923 924 925 926 927 928 929 930
      varArray_t *table_tx=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_mod=initVarArray(1000,sizeof(double));
      varArray_t *table_tx_enc=initVarArray(1000,sizeof(double));
      varArray_t *table_rx=initVarArray(1000,sizeof(double));
      varArray_t *table_rx_fft=initVarArray(1000,sizeof(double));
      varArray_t *table_rx_demod=initVarArray(1000,sizeof(double));
      varArray_t *table_rx_dec=initVarArray(1000,sizeof(double));
931
      ndi=0;
932
      phy_reset_ue(0,0,0);
933
      UE->UE_mode[eNB_id]=PUSCH;
laurent's avatar
laurent committed
934
      SET_LOG_DEBUG(UE_TIMING);
935

936 937
      for (trials = 0; trials<n_frames; trials++) {
        //      printf("*");
938 939
        //        UE->frame++;
        //        eNB->frame++;
laurent's avatar
laurent committed
940
        ndi = (1-ndi);
941 942 943 944
        fflush(stdout);
        round=0;

        while (round < 4) {
laurent's avatar
laurent committed
945 946 947 948 949 950 951 952
          proc_rxtx->frame_rx=1;
          proc_rxtx->subframe_rx=subframe;
          proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe);
          proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe);
          proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx;
          proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx);
          proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
          proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10;
953 954
          eNB->ulsch[0]->harq_processes[harq_pid]->round=round;
          UE->ulsch[0]->harq_processes[harq_pid]->round=round;
955

956
          if (n_frames==1) printf("filling ulsch: Trial %u : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx);
957

laurent's avatar
laurent committed
958 959
          round_trials[round]++;
          UL_req.sfn_sf = (1<<4)+subframe;
Cedric Roux's avatar
Cedric Roux committed
960

laurent's avatar
laurent committed
961
          if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe);
962

laurent's avatar
laurent committed
963
          int modulation_type;
964

laurent's avatar
laurent committed
965 966 967 968 969 970 971
          if (mcs < 11)      modulation_type = 2;
          else if (mcs < 21) modulation_type = 4;
          else if (mcs < 29) modulation_type = 6;
          else {
            LOG_E(SIM,"mcs %i is not valid\n",mcs);
            exit(-1);
          }
972

laurent's avatar
laurent committed
973 974 975 976 977 978
          fill_ulsch_dci(eNB, proc_rxtx->frame_rx, subframe, &sched_resp, 14,
                         (void *)&UL_alloc_pdu, first_rb,nb_rb, (round==0)?mcs:(28+rvidx[round]),
                         modulation_type, ndi, get_TBS_UL(mcs,nb_rb), cqi_flag, beta_CQI,
                         beta_RI, cqi_size);
          UE->ulsch_Msg3_active[eNB_id] = 0;
          UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1;
979

laurent's avatar
laurent committed
980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
          if (n_frames==1)
            printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx);

          generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu,
                                            14,
                                            (subframe+6)%10,
                                            format0,
                                            UE,
                                            proc_rxtx_ue,
                                            SI_RNTI,
                                            0,
                                            P_RNTI,
                                            CBA_RNTI,
                                            0,
                                            srs_flag);
          sched_resp.subframe=(subframe+6)%10;
          sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023;
997
          schedule_response(&sched_resp, proc_rxtx);
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012

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

          ///////////////////////////////////////

          if (input_fdUL == NULL) {
laurent's avatar
laurent committed
1013 1014 1015
            eNB->proc.frame_rx = 1;
            eNB->proc.subframe_rx = subframe;
            ru->proc.frame_rx = 1;
1016
            ru->proc.tti_rx = subframe;
laurent's avatar
laurent committed
1017 1018 1019 1020 1021 1022 1023
            proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx;
            proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx;
            proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx;
            proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx;
            phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx);
            tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe],
                                   eNB->frame_parms.samples_per_tti);
Cedric Roux's avatar
Cedric Roux committed
1024

1025
            if (n_frames==1) {
bruno mongazon's avatar
bruno mongazon committed
1026
              LOG_M("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1,
laurent's avatar
laurent committed
1027
                    1);
bruno mongazon's avatar
bruno mongazon committed
1028
              //LOG_M("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1);
1029
            }
laurent's avatar
laurent committed
1030
          }  // input_fd == NULL
Cedric Roux's avatar
Cedric Roux committed
1031

1032 1033 1034
          tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev);

          if (n_frames==1) {
bruno mongazon's avatar
bruno mongazon committed
1035 1036
            LOG_M("txsig0UL.m","txs0", &txdata[0][eNB->frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
            //        LOG_M("txsig1UL.m","txs1", &txdata[1][eNB->frame_parms.samples_per_tti*subframe],2*frame_parms->samples_per_tti,1,1);
1037 1038 1039 1040
          }

          //AWGN
          //Set target wideband RX noise level to N0
1041
          sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev)  +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR;
1042 1043
          sigma2 = pow(10,sigma2_dB/10);
          // compute tx_gain to achieve target SNR (per resource element!)
frtabu's avatar
frtabu committed
1044
          tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);// *(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev);
1045

laurent's avatar
laurent committed
1046
          if (n_frames==1)
1047
            printf("tx_lev = %u (%u.%u dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain));
1048 1049 1050

          // fill measurement symbol (19) with noise
          for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) {
1051
            for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
laurent's avatar
laurent committed
1052 1053
              ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
              ((short *) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
1054 1055 1056 1057 1058
            }
          }

          // multipath channel

1059
          for (i=0; i<eNB->frame_parms.samples_per_tti; i++) {
1060
            for (aa=0; aa<1; aa++) {
1061 1062
              s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][eNB->frame_parms.samples_per_tti*subframe]))[(i<<1)]);
              s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][eNB->frame_parms.samples_per_tti*subframe]))[(i<<1)+1]);
1063 1064 1065
            }
          }

1066 1067 1068 1069 1070 1071
          if (UE2eNB->max_Doppler == 0) {
            multipath_channel(UE2eNB,s_re,s_im,r_re,r_im,
                              eNB->frame_parms.samples_per_tti,hold_channel,0);
          } else {
            multipath_tv_channel(UE2eNB,s_re,s_im,r_re,r_im,
                                 2*eNB->frame_parms.samples_per_tti,hold_channel);
1072 1073 1074 1075 1076 1077
          }

          if(abstx) {
            if(saving_bler==0)
              if (trials==0 && round==0) {
                // calculate freq domain representation to compute SINR
rmagueta's avatar
rmagueta committed
1078
                freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1, 15);
1079
                // snr=pow(10.0,.1*SNR);
1080
                fprintf(csv_fdUL,"%f,%u,%u,%f,%f,%f,",SNR,tx_lev,tx_lev_dB,sigma2_dB,tx_gain,SNR2);
1081 1082 1083 1084 1085 1086

                //fprintf(csv_fdUL,"%f,",SNR);
                for (u=0; u<12*nb_rb; u++) {
                  for (aarx=0; aarx<UE2eNB->nb_rx; aarx++) {
                    for (aatx=0; aatx<UE2eNB->nb_tx; aatx++) {
                      // abs_channel = (eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].x + eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y*eNB2UE->chF[aarx+(aatx*eNB2UE->nb_rx)][u].y);
1087 1088
                      channelx = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].r;
                      channely = UE2eNB->chF[aarx+(aatx*UE2eNB->nb_rx)][u].i;
laurent's avatar
laurent committed
1089
                      // if(transmission_m==5){
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
                      fprintf(csv_fdUL,"%e+i*(%e),",channelx,channely);
                      // }
                      // else{
                      //  pilot_sinr = 10*log10(snr*abs_channel);
                      //  fprintf(csv_fd,"%e,",pilot_sinr);
                      // }
                    }
                  }
                }
              }
          }

          if (n_frames==1)
            printf("Sigma2 %f (sigma2_dB %f), tx_gain %f (%f dB)\n",sigma2,sigma2_dB,tx_gain,20*log10(tx_gain));

1105 1106
          for (i=0; i<eNB->frame_parms.samples_per_tti; i++) {
            for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
laurent's avatar
laurent committed
1107 1108 1109 1110 1111
              ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] =
                (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
              ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] =
                (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) +
                         sqrt(sigma2/2)*gaussdouble(0.0,1.0));
1112 1113
            }
          }
1114 1115 1116 1117 1118 1119 1120 1121 1122
          if (n_frames==1)
            for (i=0; i<eNB->frame_parms.samples_per_tti; i++) {
              for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
                ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*(subframe+1)%10])[2*i] =
                  (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
                ((short *) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*(subframe+1)%10])[2*i+1] =
                  (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
              }
            }
1123

1124
          if (n_frames<=10) {
laurent's avatar
laurent committed
1125 1126 1127 1128 1129 1130
            printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int *)
                   &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -
                                         eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
            printf("rx_level data symbol %f\n",
                   10*log10(signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)],
                                          OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
1131 1132
          }

laurent's avatar
laurent committed
1133 1134
          SNRmeas = 10*log10(((double)signal_energy((int *)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)],
                              OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int *)
1135
                                  &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],
1136
                                  OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb);
1137

1138
          if (n_frames<=10) {
1139
            printf("SNRmeas %f\n",SNRmeas);
laurent's avatar
laurent committed
1140
            LOG_M("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1);
1141

laurent's avatar
laurent committed
1142
            if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1);
1143 1144
          }

frtabu's avatar
frtabu committed
1145
          start_meas(&eNB->phy_proc_rx);
laurent's avatar
laurent committed
1146
          ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread        : fep_full;
1147
          ru->feprx(ru,subframe);
1148 1149
          if (n_frames==1) lte_eNB_I0_measurements(eNB,(subframe+1)%10,0,1);

laurent's avatar
laurent committed
1150
          phy_procedures_eNB_uespec_RX(eNB,proc_rxtx);
frtabu's avatar
frtabu committed
1151
          stop_meas(&eNB->phy_proc_rx);
1152 1153 1154
          if (cqi_flag > 0) {
            cqi_error = 0;

1155
            if (eNB->ulsch[0]->harq_processes[harq_pid]->Or1 < 32) {
1156
              for (i=2; i<4; i++) {
1157 1158
                //                printf("cqi %d : %d (%d)\n",i,eNB->ulsch[0]->o[i],UE->ulsch[0]->o[i]);
                if (eNB->ulsch[0]->harq_processes[harq_pid]->o[i] != UE->ulsch[0]->o[i])
1159 1160 1161 1162 1163 1164 1165 1166
                  cqi_error = 1;
              }
            } else {
            }

            if (cqi_error == 1) {
              cqi_errors++;

1167
              if (eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status == 1)
1168 1169
                cqi_crc_falsepositives++;
            } else {
1170
              if (eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status == 0)
1171 1172 1173 1174
                cqi_crc_falsenegatives++;
            }
          }

1175
          if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] != UE->ulsch[0]->o_ACK[0])
1176 1177
            ack_errors++;

1178
          //    printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]);
laurent's avatar
laurent committed
1179 1180
          //          if (ret <= eNB->ulsch[0]->max_turbo_iterations) {
          iter_trials++;
1181

laurent's avatar
laurent committed
1182
          if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) {
1183
            if (n_frames==1) {
1184
              printf("No ULSCH errors found, o_ACK[0]= %d, cqi_crc_status=%d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0],eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status);
1185

1186 1187 1188
              if (eNB->ulsch[0]->harq_processes[harq_pid]->cqi_crc_status==1)
                print_CQI(eNB->ulsch[0]->harq_processes[harq_pid]->o,
                          eNB->ulsch[0]->harq_processes[harq_pid]->uci_format,0,eNB->frame_parms.N_RB_DL);
1189

1190
              dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
1191 1192 1193
              dump_I0_stats(stdout,eNB);
              dump_ulsch_stats(stdout,eNB,0);

1194 1195 1196 1197 1198 1199 1200 1201
              exit(-1);
            }

            round=5;
          } else {
            errs[round]++;

            if (n_frames==1) {
1202
              printf("ULSCH errors found o_ACK[0]= %d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0]);
laurent's avatar
laurent committed
1203 1204
#ifdef DUMP_EACH_VALUE
              int Kr_bytes;
1205 1206
              for (s=0; s<eNB->ulsch[0]->harq_processes[harq_pid]->C; s++) {
                if (s<eNB->ulsch[0]->harq_processes[harq_pid]->Cminus)
laurent's avatar
laurent committed
1207
                  Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus;
1208
                else
laurent's avatar
laurent committed
1209 1210
                  Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus;
                Kr_bytes = Kr_bytes >> 3;
1211 1212 1213
                printf("Decoded_output (Segment %d):\n",s);

                for (i=0; i<Kr_bytes; i++)
1214 1215
                  printf("%d : %x (%x)\n",i,eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i],
                         eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]);
1216
              }
laurent's avatar
laurent committed
1217
#endif
1218

1219
              dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
frtabu's avatar
frtabu committed
1220
              round=5;
1221 1222
            }

1223
            if (n_frames==1) printf("round %d errors %u/%u\n",round,errs[round],trials);
laurent's avatar
laurent committed
1224

1225 1226 1227 1228 1229
            round++;

            if (n_frames==1) {
              printf("ULSCH in error in round %d\n",round);
            }
Cedric Roux's avatar
Cedric Roux committed
1230
          }  // ulsch error
1231 1232 1233 1234 1235 1236
        } // round

        //      printf("\n");
        if ((errs[0]>=100) && (trials>(n_frames/2)))
          break;

laurent's avatar
laurent committed
1237 1238 1239 1240 1241 1242 1243 1244
        double t_tx = inMicroS(UE->phy_proc_tx.p_time);
        double t_tx_ifft = inMicroS(UE->ofdm_mod_stats.p_time);
        double t_tx_mod = inMicroS(UE->ulsch_modulation_stats.p_time);
        double t_tx_enc = inMicroS(UE->ulsch_encoding_stats.p_time);
        double t_rx = inMicroS(eNB->phy_proc_rx.p_time);
        double t_rx_fft = inMicroS(ru->ofdm_demod_stats.p_time);
        double t_rx_demod = inMicroS(eNB->ulsch_demodulation_stats.p_time);
        double t_rx_dec = inMicroS(eNB->ulsch_decoding_stats.p_time);
1245

laurent's avatar
laurent committed
1246
        if (t_tx > 2000 )// 2ms is too much time for a subframe
1247 1248
          n_tx_dropped++;

laurent's avatar
laurent committed
1249
        if (t_rx > 2000 )
1250 1251
          n_rx_dropped++;

1252
        if (trials < 1000) {
1253 1254 1255 1256 1257 1258 1259 1260
         appendVarArray(&table_tx, &t_tx);
         appendVarArray(&table_tx_ifft, &t_tx_ifft);
         appendVarArray(&table_tx_mod, &t_tx_mod );
         appendVarArray(&table_tx_enc, &t_tx_enc );
         appendVarArray(&table_rx, &t_rx );
         appendVarArray(&table_rx_fft, &t_rx_fft );
         appendVarArray(&table_rx_demod, &t_rx_demod );
         appendVarArray(&table_rx_dec, &t_rx_dec );
1261
       }
1262
      }   //trials
1263

1264
      // sort table
laurent's avatar
laurent committed
1265 1266 1267 1268 1269 1270 1271 1272
      qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble);
      qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble);
      qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble);
      qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble);
1273

Navid Nikaein's avatar
Navid Nikaein committed
1274
      if (dump_table == 1 ) {
1275
        set_component_filelog(SIM); // file located in /tmp/usim.txt
laurent's avatar
laurent committed
1276 1277
        LOG_UDUMPMSG(SIM,dataArray(table_tx),table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n");
        LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n");
1278 1279
      }

1280
      dump_ulsch_stats(stdout,eNB,0);
laurent's avatar
laurent committed
1281
      printf("\n**********rb: %d ***mcs : %d  *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %u dB, delta_IF %d [ (%d,%d) dB / (%u,%u) dB ]**************************\n",
1282 1283 1284 1285
             nb_rb,mcs,SNR,SNR2,
             tx_lev_dB,
             20*log10(tx_gain),
             (double)N0,
1286
             eNB->measurements.n0_power_tot_dB,
laurent's avatar
laurent committed
1287
             get_hundred_times_delta_IF(UE,eNB_id,harq_pid),
1288 1289
             dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]),
             dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]),
1290 1291
             eNB->measurements.n0_power_dB[0],
             eNB->measurements.n0_power_dB[1]);
1292
      effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]));
1293
      printf("Errors (%u/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e) => effective rate %f (%3.1f%%,%f,%f), normalized delay %f (%f)\n",
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
             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]),
             rate*effective_rate,
             100*effective_rate,
             rate,
1309
             rate*get_Qm_ul(mcs),
1310
             (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])/
1311
             (double)eNB->ulsch[0]->harq_processes[harq_pid]->TBS,
1312 1313
             (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]));

1314
      if (cqi_flag >0) {
1315
        printf("CQI errors %d/%u,false positives %d/%u, CQI false negatives %d/%u\n",
1316 1317 1318
               cqi_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
               cqi_crc_falsepositives,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
               cqi_crc_falsenegatives,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]);
1319
      }
1320

1321
      if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] > 0)
1322
        printf("ACK/NAK errors %d/%u\n",ack_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]);
1323

1324
      fprintf(bler_fd,"%f;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u\n",
1325 1326 1327
              SNR,
              mcs,
              nb_rb,
1328
              eNB->ulsch[0]->harq_processes[harq_pid]->TBS,
1329 1330 1331 1332 1333 1334 1335 1336 1337
              rate,
              errs[0],
              round_trials[0],
              errs[1],
              round_trials[1],
              errs[2],
              round_trials[2],
              errs[3],
              round_trials[3]);
laurent's avatar
laurent committed
1338
      double timeBase=1/(1000*cpu_freq_GHz);
1339 1340

      if (dump_perf==1) {
1341
        printf("UE TX function statistics (per 1ms subframe)\n\n");
laurent's avatar
laurent committed
1342 1343 1344 1345 1346 1347 1348 1349 1350
        printDistribution(&UE->phy_proc_tx,table_tx,"Total PHY proc tx");
        printDistribution(&UE->ofdm_mod_stats, table_tx_ifft, "OFDM_mod time");
        printDistribution(&UE->ulsch_modulation_stats,table_tx_mod, "ULSCH modulation time");
        printDistribution(&UE->ulsch_encoding_stats,table_tx_enc, "ULSCH encoding time");
        printStatIndent(&UE->ulsch_segmentation_stats,"ULSCH segmentation time");
        printStatIndent(&UE->ulsch_turbo_encoding_stats,"ULSCH turbo encoding time");
        printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time");
        printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving");
        printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time");
frtabu's avatar
frtabu committed
1351
        printf("\n");
laurent's avatar
laurent committed
1352 1353 1354
        printDistribution(&eNB->phy_proc_rx,table_rx,"Total PHY proc rx subframe");
        printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"|__ OFDM_demod time");
        printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"|__ ULSCH demodulation time");
frtabu's avatar
frtabu committed
1355
        printDistribution(&eNB->ulsch_decoding_stats,table_rx_dec,"|__ ULSCH Decoding time");
laurent's avatar
laurent committed
1356 1357
        printf("     (%.2f Mbit/s, avg iter %.2f, max %.2f)\n",
               UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,
frtabu's avatar
frtabu committed
1358 1359
               (double)iter_trials,
               (double)eNB->ulsch_decoding_stats.max*timeBase);
laurent's avatar
laurent committed
1360 1361 1362
        printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" );
        printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" );
        printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" );
laurent's avatar
laurent committed
1363 1364 1365 1366 1367 1368
        printf("    |__ harqID: %d turbo_decoder(%d bits), avg iterations: %.1f       %.2f us (%d cycles, %d trials)\n",
               harq_pid,
               eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : eNB->ulsch[0]->harq_processes[harq_pid]->Kplus,
               eNB->ulsch_tc_intl1_stats.trials / (double)eNB->ulsch_tc_init_stats.trials,
               (double)eNB->ulsch_turbo_decoding_stats.diff / eNB->ulsch_turbo_decoding_stats.trials * timeBase,
               (int)((double)eNB->ulsch_turbo_decoding_stats.diff / eNB->ulsch_turbo_decoding_stats.trials),
laurent's avatar
laurent committed
1369
               eNB->ulsch_turbo_decoding_stats.trials);
laurent's avatar
laurent committed
1370 1371 1372 1373 1374 1375 1376
        printStatIndent3(&eNB->ulsch_tc_init_stats,"init");
        printStatIndent3(&eNB->ulsch_tc_alpha_stats,"alpha");
        printStatIndent3(&eNB->ulsch_tc_beta_stats,"beta");
        printStatIndent3(&eNB->ulsch_tc_gamma_stats,"gamma");
        printStatIndent3(&eNB->ulsch_tc_ext_stats,"ext");
        printStatIndent3(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver");
        printStatIndent3(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC");
1377 1378
      }

1379 1380 1381 1382 1383 1384 1385 1386 1387
      if(abstx) { //ABSTRACTION
        blerr= (double)errs[1]/(round_trials[1]);
        //printf("hata yok XX,");
        blerr = (double)errs[0]/(round_trials[0]);

        if(saving_bler==0)
          fprintf(csv_fdUL,"%e;\n",blerr);

        //    printf("hata yok XX,");
1388

1389 1390 1391
        if(blerr<1)
          saving_bler = 0;
        else saving_bler =1;
1392
      } //ABStraction
1393

1394
      if ( (test_perf != 0) && (100 * effective_rate > test_perf )) {
1395
        //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3\n");
1396
        fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;",
1397 1398
                SNR,
                mcs,
1399
                eNB->ulsch[0]->harq_processes[harq_pid]->TBS,
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409
                rate,
                errs[0],
                round_trials[0],
                errs[1],
                round_trials[1],
                errs[2],
                round_trials[2],
                errs[3],
                round_trials[3]);
        //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3;ND;\n");
1410
        fprintf(time_meas_fd,"%f;%d;%d;%f;%2.1f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%f;%f;",
1411 1412
                SNR,
                mcs,
1413
                eNB->ulsch[0]->harq_processes[harq_pid]->TBS,
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
                rate*effective_rate,
                100*effective_rate,
                rate,
                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]),
                (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])/
1430
                (double)eNB->ulsch[0]->harq_processes[harq_pid]->TBS,
1431 1432 1433
                (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,"UE_PROC_TX(%d); OFDM_MOD(%d); UL_MOD(%d); UL_ENC(%d); eNB_PROC_RX(%d); OFDM_DEMOD(%d); UL_DEMOD(%d); UL_DECOD(%d);\n",
        fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d;",
1434 1435 1436 1437 1438
                UE->phy_proc_tx.trials,
                UE->ofdm_mod_stats.trials,
                UE->ulsch_modulation_stats.trials,
                UE->ulsch_encoding_stats.trials,
                eNB->phy_proc_rx.trials,
1439
                ru->ofdm_demod_stats.trials,
1440 1441
                eNB->ulsch_demodulation_stats.trials,
                eNB->ulsch_decoding_stats.trials
1442 1443
               );
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;",
1444 1445 1446 1447 1448
                get_time_meas_us(&UE->phy_proc_tx),
                get_time_meas_us(&UE->ofdm_mod_stats),
                get_time_meas_us(&UE->ulsch_modulation_stats),
                get_time_meas_us(&UE->ulsch_encoding_stats),
                get_time_meas_us(&eNB->phy_proc_rx),
1449
                get_time_meas_us(&ru->ofdm_demod_stats),
1450 1451
                get_time_meas_us(&eNB->ulsch_demodulation_stats),
                get_time_meas_us(&eNB->ulsch_decoding_stats)
1452 1453
               );
        //fprintf(time_meas_fd,"UE_PROC_TX_STD;UE_PROC_TX_MAX;UE_PROC_TX_MIN;UE_PROC_TX_MED;UE_PROC_TX_Q1;UE_PROC_TX_Q3;UE_PROC_TX_DROPPED;\n");
laurent's avatar
laurent committed
1454
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",
frtabu's avatar
frtabu committed
1455
                squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped);
1456
        //fprintf(time_meas_fd,"IFFT;\n");
laurent's avatar
laurent committed
1457
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
frtabu's avatar
frtabu committed
1458
                squareRoot(&UE->ofdm_mod_stats),
laurent's avatar
laurent committed
1459
                median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft));
1460
        //fprintf(time_meas_fd,"MOD;\n");
laurent's avatar
laurent committed
1461
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
frtabu's avatar
frtabu committed
1462
                squareRoot(&UE->ulsch_modulation_stats),
laurent's avatar
laurent committed
1463
                median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod));
1464
        //fprintf(time_meas_fd,"ENC;\n");
laurent's avatar
laurent committed
1465
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
frtabu's avatar
frtabu committed
1466
                squareRoot(&UE->ulsch_encoding_stats),
laurent's avatar
laurent committed
1467
                median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc));
1468
        //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n");
laurent's avatar
laurent committed
1469
        fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",
frtabu's avatar
frtabu committed
1470
                squareRoot(&eNB->phy_proc_rx), t_rx_max, t_rx_min,
laurent's avatar
laurent committed
1471
                median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped);
1472
        //fprintf(time_meas_fd,"FFT;\n");
laurent's avatar
laurent committed
1473
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
frtabu's avatar
frtabu committed
1474
                squareRoot(&ru->ofdm_demod_stats),
laurent's avatar
laurent committed
1475
                median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft));
1476
        //fprintf(time_meas_fd,"DEMOD;\n");
laurent's avatar
laurent committed
1477
        fprintf(time_meas_fd,"%f;%f;%f;%f;",
frtabu's avatar
frtabu committed
1478
                squareRoot(&eNB->ulsch_demodulation_stats),
laurent's avatar
laurent committed
1479
                median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod));
1480
        //fprintf(time_meas_fd,"DEC;\n");
laurent's avatar
laurent committed
1481
        fprintf(time_meas_fd,"%f;%f;%f;%f\n",
frtabu's avatar
frtabu committed
1482
                squareRoot(&eNB->ulsch_decoding_stats),
laurent's avatar
laurent committed
1483
                median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec));
1484 1485 1486 1487
        printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
        break;
      } else if (test_perf !=0 ) {
        printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
1488 1489
      }

1490 1491
      if (((double)errs[0]/(round_trials[0]))<1e-2)
        break;
laurent's avatar
laurent committed
1492
    } // SNR
1493 1494

    //
bruno mongazon's avatar
bruno mongazon committed
1495 1496
    //LOG_M("chestim_f.m","chestf",eNB->pusch_vars[0]->drs_ch_estimates[0][0],300*12,2,1);
    // LOG_M("chestim_t.m","chestt",eNB->pusch_vars[0]->drs_ch_estimates_time[0][0], (frame_parms->ofdm_symbol_size)*2,2,1);
1497 1498
  }//ch realization

1499
  oai_exit=1;
Robert Schmidt's avatar
Robert Schmidt committed
1500
  pthread_cond_signal(&ru->proc.cond_fep[0]);
1501

1502
  if (abstx) { // ABSTRACTION
1503 1504 1505
    fprintf(csv_fdUL,"];");
    fclose(csv_fdUL);
  }
1506

1507
  fclose(bler_fd);
1508

1509 1510
  if (test_perf !=0)
    fclose (time_meas_fd);
1511

1512 1513
  return(0);
}
1514

1515 1516 1517 1518
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
uint64_t get_softmodem_optmask(void) {
  return 0;
}