channel_sim.c 22.3 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 21
 * 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
 */

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>

#include "SIMULATION/TOOLS/defs.h"
#include "SIMULATION/RF/defs.h"
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/extern.h"

#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log_if.h"
#include "UTIL/LOG/log_extern.h"
#include "RRC/LITE/extern.h"
#include "PHY_INTERFACE/extern.h"
#include "UTIL/OCG/OCG.h"
#include "UTIL/OPT/opt.h" // to test OPT
#endif

#include "UTIL/FIFO/types.h"

#ifdef IFFT_FPGA
#include "PHY/LTE_REFSIG/mod_table.h"
#endif

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#ifdef XFORMS
#include "forms.h"
#include "phy_procedures_sim_form.h"
#endif

#include "oaisim.h"

#define RF
Raymond Knopp's avatar
Raymond Knopp committed
63 64 65 66 67
#define DEBUG_SIM
/*
#undef LOG_D
#define LOG_D(A,B,C...) printf(B,C)
*/
68 69 70 71

int number_rb_ul;
int first_rbUL ;

72
extern Signal_buffers_t *signal_buffers_g;
73 74


75 76 77 78
double r_re_DL[NUMBER_OF_UE_MAX][2][30720];
double r_im_DL[NUMBER_OF_UE_MAX][2][30720];
double r_re_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_im_UL[NUMBER_OF_eNB_MAX][2][30720];
79 80 81 82
int RU_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_RU_MAX];
pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX];
83

84 85
double ru_amp[NUMBER_OF_RU_MAX];

86 87
void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs],
	       node_desc_t *enb_data[NUMBER_OF_RU_MAX],
88
	       node_desc_t *ue_data[NUMBER_OF_UE_MAX],
89
	       uint16_t subframe,
90 91
	       uint32_t offset,
	       uint32_t length,
92
	       uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *ue_frame_parms,
93 94
	       uint8_t UE_id,
	       int CC_id)
95
{
96

97 98
  int32_t att_eNB_id=-1;
  int32_t **txdata,**rxdata;
99

100
  uint32_t eNB_id,ru_id=0;
101 102
  double tx_pwr;
  double rx_pwr;
103 104
  int32_t rx_pwr2;
  uint32_t i,aa;
105
  uint32_t sf_offset;
106 107

  double min_path_loss=-200;
108
  uint8_t hold_channel=0;
109 110
  uint8_t nb_antennas_rx = RU2UE[0][0][CC_id]->nb_rx; // number of rx antennas at UE
  uint8_t nb_antennas_tx = RU2UE[0][0][CC_id]->nb_tx; // number of tx antennas at eNB
111

112 113
  double s_re0[30720];
  double s_re1[30720];
114
  double *s_re[2];
115 116
  double s_im0[30720];
  double s_im1[30720];
117
  double *s_im[2];
118 119
  double r_re00[30720];
  double r_re01[30720];
120
  double *r_re0[2];
121 122
  double r_im00[30720];
  double r_im01[30720];
123
  double *r_im0[2];
124
  LTE_DL_FRAME_PARMS *frame_parms;
125 126 127 128 129 130 131 132 133 134

  s_re[0] = s_re0;
  s_im[0] = s_im0;
  s_re[1] = s_re1;
  s_im[1] = s_im1;

  r_re0[0] = r_re00;
  r_im0[0] = r_im00;
  r_re0[1] = r_re01;
  r_im0[1] = r_im01;
135

136
  if (subframe==0)
137 138 139 140 141 142 143
    hold_channel = 0;
  else
    hold_channel = 1;

  if (abstraction_flag != 0) {
    //for (UE_id=0;UE_id<NB_UE_INST;UE_id++) {

144
    if (!hold_channel) {
145 146
      // calculate the random channel from each RU
      for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
Cedric Roux's avatar
Cedric Roux committed
147
        frame_parms = &RC.ru[ru_id]->frame_parms;
148

149
        random_channel(RU2UE[ru_id][UE_id][CC_id],abstraction_flag);
150
        /*
151 152
        for (i=0;i<RU2UE[eNB_id][UE_id]->nb_taps;i++)
        printf("RU2UE[%d][%d]->a[0][%d] = (%f,%f)\n",eNB_id,UE_id,i,RU2UE[eNB_id][UE_id]->a[0][i].x,RU2UE[eNB_id][UE_id]->a[0][i].y);
153
        */
154
        freq_channel(RU2UE[ru_id][UE_id][CC_id], frame_parms->N_RB_DL,frame_parms->N_RB_DL*12+1);
155 156 157
      }

      // find out which eNB the UE is attached to
158
      /*
159
      for (eNB_id=0; eNB_id<RC.nb_inst; eNB_id++) {
160
        if (find_ue(PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti,RC.eNB[eNB_id][CC_id])>=0) {
161 162
          // UE with UE_id is connected to eNb with eNB_id
          att_eNB_id=eNB_id;
163
          LOG_D(OCM,"A: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
164 165
        }
      }
166
      */
167 168
      // if UE is not attached yet, find assume its the eNB with the smallest pathloss
      if (att_eNB_id<0) {
169
        for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
170 171 172 173 174 175 176 177
	  for (int ru=0;ru<RC.nb_RU;ru++) {
	    ru_id = RC.eNB[eNB_id][CC_id]->RU_list[ru]->idx;
	    if (min_path_loss<RU2UE[ru_id][UE_id][CC_id]->path_loss_dB) {
	      min_path_loss = RU2UE[ru_id][UE_id][CC_id]->path_loss_dB;
	      att_eNB_id=eNB_id;
	      LOG_D(OCM,"B: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
	    }
	  }
178 179 180 181 182 183 184
        }
      }

      if (att_eNB_id<0) {
        LOG_E(OCM,"Cannot find eNB for UE %d, return\n",UE_id);
        return; //exit(-1);
      }
185

186
#ifdef DEBUG_SIM
187 188
      rx_pwr = signal_energy_fp2(RU2UE[att_eNB_id][UE_id][CC_id]->ch[0],
                                 RU2UE[att_eNB_id][UE_id][CC_id]->channel_length)*RU2UE[att_eNB_id][UE_id][CC_id]->channel_length;
Raymond Knopp's avatar
 
Raymond Knopp committed
189 190
      LOG_D(OCM,"Channel (CCid %d) eNB %d => UE %d : tx_power %d dBm, path_loss %f dB\n",
            CC_id,att_eNB_id,UE_id,
Raymond Knopp's avatar
 
Raymond Knopp committed
191
            frame_parms->pdsch_config_common.referenceSignalPower,
192
            RU2UE[att_eNB_id][UE_id][CC_id]->path_loss_dB);
193
#endif
194 195 196

      //dlsch_abstraction(PHY_vars_UE_g[UE_id]->sinr_dB, rb_alloc, 8);
      // fill in perfect channel estimates
197
      channel_desc_t *desc1 = RU2UE[att_eNB_id][UE_id][CC_id];
198
      int32_t **dl_channel_est = PHY_vars_UE_g[UE_id][CC_id]->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0];
199 200
      //      double scale = pow(10.0,(enb_data[att_eNB_id]->tx_power_dBm + RU2UE[att_eNB_id][UE_id]->path_loss_dB + (double) PHY_vars_UE_g[UE_id]->rx_total_gain_dB)/20.0);
      double scale = pow(10.0,(frame_parms->pdsch_config_common.referenceSignalPower+RU2UE[att_eNB_id][UE_id][CC_id]->path_loss_dB + (double) PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB)/20.0);
201 202 203 204 205
      LOG_D(OCM,"scale =%lf (%d dB)\n",scale,(int) (20*log10(scale)));
      // freq_channel(desc1,frame_parms->N_RB_DL,nb_samples);
      //write_output("channel.m","ch",desc1->ch[0],desc1->channel_length,1,8);
      //write_output("channelF.m","chF",desc1->chF[0],nb_samples,1,8);
      int count,count1,a_rx,a_tx;
206 207 208 209 210 211 212 213 214 215 216 217

      for(a_tx=0; a_tx<nb_antennas_tx; a_tx++) {
        for (a_rx=0; a_rx<nb_antennas_rx; a_rx++) {
          //for (count=0;count<frame_parms->symbols_per_tti/2;count++)
          for (count=0; count<1; count++) {
            for (count1=0; count1<frame_parms->N_RB_DL*12; count1++) {
              ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count1+(count*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(desc1->chF[a_rx+(a_tx*nb_antennas_rx)][count1].x*scale);
              ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count1+1+(count*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(desc1->chF[a_rx+(a_tx*nb_antennas_rx)][count1].y*scale) ;
            }
          }
        }
      }
218

219
      // calculate the SNR for the attached eNB (this assumes eNB always uses PMI stored in eNB_UE_stats; to be improved)
220 221 222
      init_snr(RU2UE[att_eNB_id][UE_id][CC_id], enb_data[att_eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB, &PHY_vars_UE_g[UE_id][CC_id]->N0,
               PHY_vars_UE_g[UE_id][CC_id]->transmission_mode[att_eNB_id], RC.eNB[att_eNB_id][CC_id]->UE_stats[UE_id].DL_pmi_single,
	       RC.eNB[att_eNB_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off,RC.eNB[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
223 224 225 226

      // calculate sinr here
      for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
        if (att_eNB_id != eNB_id) {
227 228
          calculate_sinr(RU2UE[eNB_id][UE_id][CC_id], enb_data[eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB,
			 RC.eNB[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
229 230
        }
      }
231
    } // hold channel
232 233
  }
  else { //abstraction_flag
234 235


236
    pthread_mutex_lock(&RU_output_mutex[UE_id]);
237
 
238
    if (RU_output_mask[UE_id] == 0) {  //  This is the first eNodeB for this UE, clear the buffer
239
      for (aa=0; aa<nb_antennas_rx; aa++) {
240 241
	memset((void*)r_re_DL[UE_id][aa],0,(RC.ru[0]->frame_parms.samples_per_tti)*sizeof(double));
	memset((void*)r_im_DL[UE_id][aa],0,(RC.ru[0]->frame_parms.samples_per_tti)*sizeof(double));
242
      }
243
    }
244 245 246 247 248
    pthread_mutex_unlock(&RU_output_mutex[UE_id]);

    for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
      txdata = RC.ru[ru_id]->common.txdata;
      frame_parms = &RC.ru[ru_id]->frame_parms;
Raymond Knopp's avatar
 
Raymond Knopp committed
249

250
      sf_offset = (subframe*frame_parms->samples_per_tti) + offset;
251
      LOG_D(EMU,">>>>>>>>>>>>>>>>>TXPATH: RU %d : DL_sig reading TX for subframe %d (sf_offset %d, length %d) from %p\n",ru_id,subframe,sf_offset,length,txdata[0]+sf_offset); 
252
      int length_meas = frame_parms->ofdm_symbol_size;
253
      if (sf_offset+length <= frame_parms->samples_per_tti*10) {
254

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
	tx_pwr = dac_fixed_gain(s_re,
				s_im,
				txdata,
				sf_offset,
				nb_antennas_tx,
				length,
				sf_offset,
				length_meas,
				14,
				frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE
				0,
				&ru_amp[ru_id],
				frame_parms->N_RB_DL*12);

      }
      else {
	tx_pwr = dac_fixed_gain(s_re,
				s_im,
				txdata,
				sf_offset,
				nb_antennas_tx,
				(frame_parms->samples_per_tti*10)-sf_offset,
				sf_offset,
				length_meas,
				14,
				frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE
				0,
				&ru_amp[ru_id],
				frame_parms->N_RB_DL*12);

	tx_pwr = dac_fixed_gain(s_re,
				s_im,
				txdata,
				sf_offset,
				nb_antennas_tx,
				length+sf_offset-(frame_parms->samples_per_tti*10),
				sf_offset,
				length_meas,
				14,
				frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE
				0,
				&ru_amp[ru_id],
				frame_parms->N_RB_DL*12);
      }
299
#ifdef DEBUG_SIM
300
      LOG_D(PHY,"[SIM][DL] subframe %d: txp (time) %d dB\n",
301
	    subframe,dB_fixed(signal_energy(&txdata[0][sf_offset],length_meas)));
302
	    
303
      LOG_D(OCM,"[SIM][DL] RU %d (CCid %d): tx_pwr %.1f dBm/RE (target %d dBm/RE), for subframe %d\n",
304
            ru_id,CC_id,
305 306
            10*log10(tx_pwr),
            frame_parms->pdsch_config_common.referenceSignalPower,
307 308
            subframe);

309
#endif
310 311 312 313
      tx_pwr = signal_energy_fp(s_re,s_im,nb_antennas_tx,
				length<length_meas?length:length_meas,
                                0)/(12.0*frame_parms->N_RB_DL);
 
314 315
      //RU2UE[eNB_id][UE_id]->path_loss_dB = 0;
      multipath_channel(RU2UE[ru_id][UE_id][CC_id],s_re,s_im,r_re0,r_im0,
316
                        length,hold_channel);
317
#ifdef DEBUG_SIM
318 319 320
      rx_pwr = signal_energy_fp2(RU2UE[ru_id][UE_id][CC_id]->ch[0],
                                 RU2UE[ru_id][UE_id][CC_id]->channel_length)*RU2UE[ru_id][UE_id][CC_id]->channel_length;
      LOG_D(OCM,"[SIM][DL] Channel RU %d => UE %d (CCid %d): Channel gain %f dB (%f)\n",ru_id,UE_id,CC_id,10*log10(rx_pwr),rx_pwr);
321
#endif
322 323 324 325


#ifdef DEBUG_SIM

326 327
      for (i=0; i<RU2UE[ru_id][UE_id][CC_id]->channel_length; i++)
        LOG_D(OCM,"channel(%d,%d)[%d] : (%f,%f)\n",ru_id,UE_id,i,RU2UE[ru_id][UE_id][CC_id]->ch[0][i].x,RU2UE[ru_id][UE_id][CC_id]->ch[0][i].y);
328

329 330
#endif

331
      LOG_D(OCM,"[SIM][DL] Channel RU %d => UE %d (CCid %d): tx_power %.1f dBm/RE, path_loss %1.f dB\n",
332
            ru_id,UE_id,CC_id,
333 334
            (double)frame_parms->pdsch_config_common.referenceSignalPower,
            //         enb_data[eNB_id]->tx_power_dBm,
335
            RU2UE[ru_id][UE_id][CC_id]->path_loss_dB);
336 337

#ifdef DEBUG_SIM
338
      rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx,
339
                                length<length_meas?length:length_meas,
340
                                0)/(12.0*frame_parms->N_RB_DL);
341 342 343 344 345 346 347
     LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI,tx %f dB)for subframe %d (length %d)\n",UE_id,
	   10*log10(rx_pwr),
	   10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),
	   10*log10(tx_pwr),subframe,
	   length<length_meas?length:length_meas);

      
348
      LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for subframe %d\n",
349
            UE_id,
350 351
            10*log10(RU2UE[ru_id][UE_id][CC_id]->sampling_rate*1e6)-174,
            10*log10(RU2UE[ru_id][UE_id][CC_id]->sampling_rate*1e6*12*frame_parms->N_RB_DL/(double)frame_parms->ofdm_symbol_size)-174,
352
            subframe);
353 354
#endif

355 356
      if (RU2UE[ru_id][UE_id][CC_id]->first_run == 1)
        RU2UE[ru_id][UE_id][CC_id]->first_run = 0;
357 358 359


      // RF model
360
#ifdef DEBUG_SIM
361 362
      LOG_D(OCM,"[SIM][DL] UE %d (CCid %d): rx_gain %d dB (-ADC %f) for subframe %d\n",UE_id,CC_id,PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB,
            PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB-66.227,subframe);
363
#endif
364 365 366 367

      rf_rx_simple(r_re0,
                   r_im0,
                   nb_antennas_rx,
368
                   length,
369
                   1e3/RU2UE[ru_id][UE_id][CC_id]->sampling_rate,  // sampling time (ns)
370 371 372 373 374
                   (double)PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB - 66.227);   // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later)

#ifdef DEBUG_SIM
      rx_pwr = signal_energy_fp(r_re0,r_im0,
                                nb_antennas_rx,
375
                                length<length_meas?length:length_meas,
376
                                0)/(12.0*frame_parms->N_RB_DL);
377
      LOG_D(OCM,"[SIM][DL] UE %d : ADC in (RU %d) %f dBm/RE for subframe %d\n",
378
            UE_id,ru_id,
379
            10*log10(rx_pwr),subframe);
380
#endif
Raymond Knopp's avatar
Raymond Knopp committed
381 382


383
      pthread_mutex_lock(&RU_output_mutex[UE_id]);
384
      for (i=0; i<frame_parms->samples_per_tti; i++) {
385
        for (aa=0; aa<nb_antennas_rx; aa++) {
386 387
          r_re_DL[UE_id][aa][i]+=r_re0[aa][i];
          r_im_DL[UE_id][aa][i]+=r_im0[aa][i];
388
        }
389
      }
390
      RU_output_mask[UE_id] |= (1<<ru_id);
391
      if (RU_output_mask[UE_id] == (1<<RC.nb_RU)-1) {
392
	RU_output_mask[UE_id]=0;
393
      
394

395

Raymond Knopp's avatar
Raymond Knopp committed
396 397
	double *r_re_p[2] = {r_re_DL[UE_id][0],r_re_DL[UE_id][1]};
	double *r_im_p[2] = {r_im_DL[UE_id][0],r_im_DL[UE_id][1]};
398 399

#ifdef DEBUG_SIM
400 401
	rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,length<length_meas?length:length_meas,0)/(12.0*frame_parms->N_RB_DL);
	LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm/RE for subframe %d\n",UE_id,10*log10(rx_pwr),subframe);
402
#endif
Raymond Knopp's avatar
Raymond Knopp committed
403

404
	rxdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.rxdata;
405
	sf_offset = (subframe*frame_parms->samples_per_tti)+offset;
406 407 408 409


	adc(r_re_p,
	    r_im_p,
410 411 412 413
	    0,
	    sf_offset,
	    rxdata,
	    nb_antennas_rx,
414
	    length,
415 416
	    12);
	
417
#ifdef DEBUG_SIM
418 419 420
	rx_pwr2 = signal_energy(rxdata[0]+sf_offset,length<length_meas?length:length_meas)/(12.0*frame_parms->N_RB_DL);
	LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (ADC out) %f dB/RE (%d) for subframe %d, writing to %p, length %d\n",UE_id, 10*log10((double)rx_pwr2),rx_pwr2,subframe,rxdata,length<length_meas?length:length_meas);
	LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (ADC out) %f dB for subframe %d\n",UE_id,10*log10((double)rx_pwr2*12*frame_parms->N_RB_DL) ,subframe);
421
#else
422 423 424
	UNUSED_VARIABLE(rx_pwr2);
	UNUSED_VARIABLE(tx_pwr);
	UNUSED_VARIABLE(rx_pwr);
425
#endif
426
		
427 428 429
      } // RU_output_mask
      pthread_mutex_unlock(&RU_output_mutex[UE_id]);      
    } // ru_id
430

431 432 433 434 435
  }

}


436 437
void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs],
               node_desc_t *enb_data[NUMBER_OF_RU_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],
438
	       uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, 
439
	       uint32_t frame,int ru_id,uint8_t CC_id)
440
{
441

442
  int32_t **txdata,**rxdata;
443
  uint8_t UE_id=0;
444

445 446
  uint8_t nb_antennas_rx = UE2RU[0][0][CC_id]->nb_rx; // number of rx antennas at eNB
  uint8_t nb_antennas_tx = UE2RU[0][0][CC_id]->nb_tx; // number of tx antennas at UE
447 448

  double tx_pwr, rx_pwr;
449 450
  int32_t rx_pwr2;
  uint32_t i,aa;
451
  uint32_t sf_offset;
452

453
  uint8_t hold_channel=0;
454

455 456
  double s_re0[30720];
  double s_re1[30720];
457
  double *s_re[2];
458 459
  double s_im0[30720];
  double s_im1[30720];
460
  double *s_im[2];
461 462
  double r_re00[30720];
  double r_re01[30720];
463
  double *r_re0[2];
464 465
  double r_im00[30720];
  double r_im01[30720];
466 467 468 469 470 471 472 473 474 475 476
  double *r_im0[2];

  s_re[0] = s_re0;
  s_im[0] = s_im0;
  s_re[1] = s_re1;
  s_im[1] = s_im1;

  r_re0[0] = r_re00;
  r_im0[0] = r_im00;
  r_re0[1] = r_re01;
  r_im0[1] = r_im01;
477
  
478
  if (abstraction_flag!=0)  {
479
  } else { //without abstraction
480

481
    pthread_mutex_lock(&UE_output_mutex[ru_id]);
482 483 484
    // Clear RX signal for eNB = eNB_id
    for (i=0; i<frame_parms->samples_per_tti; i++) {
      for (aa=0; aa<nb_antennas_rx; aa++) {
485 486
	r_re_UL[ru_id][aa][i]=0.0;
	r_im_UL[ru_id][aa][i]=0.0;
487 488
      }
    }
489
    pthread_mutex_unlock(&UE_output_mutex[ru_id]);
490 491 492 493

    // Compute RX signal for eNB = eNB_id
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
      
494
      txdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdata;
495
      AssertFatal(txdata != NULL,"txdata is null\n");
496
      sf_offset = subframe*frame_parms->samples_per_tti;
497
      if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
498
	   UE2RU[UE_id][ru_id][CC_id]->path_loss_dB) <= -125.0) {
499
	// don't simulate a UE that is too weak
500
	LOG_D(OCM,"[SIM][UL] ULPOWERS UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n",
501 502 503 504
	      UE_id,
	      PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
	      PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
	      subframe,sf_offset);	
505 506 507 508 509 510 511 512 513 514
      } else {
	tx_pwr = dac_fixed_gain((double**)s_re,
				(double**)s_im,
				txdata,
				sf_offset,
				nb_antennas_tx,
				frame_parms->samples_per_tti,
				sf_offset,
				frame_parms->ofdm_symbol_size,
				14,
515
				(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe]-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
516 517
				1,
				NULL,
518
				PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]);  // This make the previous argument the total power
519
	LOG_D(OCM,"[SIM][UL] ULPOWERS UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n",
520
	      UE_id,
521
	      10*log10(tx_pwr*PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
522 523
	      PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
	      PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
524 525
	      subframe,sf_offset);
       
526
		
527
	multipath_channel(UE2RU[UE_id][ru_id][CC_id],s_re,s_im,r_re0,r_im0,
528 529 530
			  frame_parms->samples_per_tti,hold_channel);
	

531 532
	rx_pwr = signal_energy_fp2(UE2RU[UE_id][ru_id][CC_id]->ch[0],
				   UE2RU[UE_id][ru_id][CC_id]->channel_length)*UE2RU[UE_id][ru_id][CC_id]->channel_length;
533

534 535 536
	LOG_D(OCM,"[SIM][UL] subframe %d Channel UE %d => RU %d : %f dB (hold %d,length %d, PL %f)\n",subframe,UE_id,ru_id,10*log10(rx_pwr),
	      hold_channel,UE2RU[UE_id][ru_id][CC_id]->channel_length,
	      UE2RU[UE_id][ru_id][CC_id]->path_loss_dB);
537

538
	rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx,frame_parms->samples_per_tti,0);
539 540 541 542 543 544 545 546 547 548 549
	LOG_D(OCM,"[SIM][UL] RU %d (%d/%d rx antennas) : rx_pwr %f dBm (tx_pwr - PL %f) for subframe %d, sptti %d\n",
	      ru_id,nb_antennas_rx,UE2RU[UE_id][ru_id][CC_id]->nb_rx,10*log10(rx_pwr),10*log10(tx_pwr*PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe])+UE2RU[UE_id][ru_id][CC_id]->path_loss_dB,subframe,frame_parms->samples_per_tti);
	/*	
	if (abs(10*log10(rx_pwr)-10*log10(tx_pwr*PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe])-UE2RU[UE_id][ru_id][CC_id]->path_loss_dB)>3) {
	  write_output("txsig_re.m","s_re",s_re[0],frame_parms->samples_per_tti,1,7);
	  write_output("txsig_im.m","s_im",s_im[0],frame_parms->samples_per_tti,1,7);
	  write_output("rxsig_re.m","r_re",r_re0[0],frame_parms->samples_per_tti,1,7);
	  write_output("rxsig_im.m","r_im",r_im0[0],frame_parms->samples_per_tti,1,7);
	  exit(-1);
	  }*/

550 551
	if (UE2RU[UE_id][ru_id][CC_id]->first_run == 1)
	  UE2RU[UE_id][ru_id][CC_id]->first_run = 0;
552 553
	
	
554
	pthread_mutex_lock(&UE_output_mutex[ru_id]);
555 556
	for (aa=0; aa<nb_antennas_rx; aa++) {
	  for (i=0; i<frame_parms->samples_per_tti; i++) {
557 558
	    r_re_UL[ru_id][aa][i]+=r_re0[aa][i];
	    r_im_UL[ru_id][aa][i]+=r_im0[aa][i];
559 560
	  }
	}
561
	pthread_mutex_unlock(&UE_output_mutex[ru_id]);
562
      }
563 564
    } //UE_id
    
565 566
    double *r_re_p[2] = {r_re_UL[ru_id][0],r_re_UL[ru_id][1]};
    double *r_im_p[2] = {r_im_UL[ru_id][0],r_im_UL[ru_id][1]};
567

568 569 570 571
    rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->samples_per_tti,0);
    LOG_D(OCM,"[SIM][UL] RU %d (%d/%d rx antennas) : rx_pwr %f dBm (before RF) for subframe %d, gain %f\n",
	  ru_id,nb_antennas_rx,nb_antennas_rx,10*log10(rx_pwr),subframe,
	  (double)RC.ru[ru_id]->max_rxgain-(double)RC.ru[ru_id]->att_rx - 66.227);
572 573
    rf_rx_simple(r_re_p,
		 r_im_p,
574 575
		 nb_antennas_rx,
		 frame_parms->samples_per_tti,
576 577
		 1e3/UE2RU[0][ru_id][CC_id]->sampling_rate,  // sampling time (ns)
		 (double)RC.ru[ru_id]->max_rxgain-(double)RC.ru[ru_id]->att_rx - 66.227);   // rx_gain (dB) (66.227 = 20*log10(pow2(11)) = gain from the adc that will be applied later)
578
    
579
    //#ifdef DEBUG_SIM
580 581 582
    rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->samples_per_tti,0);//*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL;
    LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d (rx_gain %f)\n",10*log10(rx_pwr),subframe,
	  (double)RC.ru[ru_id]->max_rxgain-(double)RC.ru[ru_id]->att_rx);
583
    //#endif
584
    
585
    rxdata = RC.ru[ru_id]->common.rxdata;
586
    sf_offset = subframe*frame_parms->samples_per_tti;
587

588
    
589 590
    adc(r_re_p,
	r_im_p,
591 592 593 594 595 596 597
	0,
	sf_offset,
	rxdata,
	nb_antennas_rx,
	frame_parms->samples_per_tti,
	12);
    
598
#ifdef DEBUG_SIM
599
    rx_pwr2 = signal_energy(rxdata[0]+sf_offset,frame_parms->samples_per_tti)*(double)frame_parms->ofdm_symbol_size/(12.0*frame_parms->N_RB_DL);
600
    LOG_D(OCM,"[SIM][UL] RU %d rx_pwr (ADC out) %f dB (%d) for subframe %d (offset %d) = %p\n",ru_id,10*log10((double)rx_pwr2),rx_pwr2,subframe,sf_offset,rxdata[0]+sf_offset);
601
#else
602 603 604
    UNUSED_VARIABLE(tx_pwr);
    UNUSED_VARIABLE(rx_pwr);
    UNUSED_VARIABLE(rx_pwr2);
605
#endif
606
    
607 608 609 610 611
  } // abstraction_flag==0

}


612 613
void init_channel_vars(LTE_DL_FRAME_PARMS *frame_parms, double ***s_re,double ***s_im,double ***r_re,double ***r_im,double ***r_re0,double ***r_im0)
{
614 615 616

  int i;

617
  memset(RU_output_mask,0,sizeof(int)*NUMBER_OF_UE_MAX);
618
  for (i=0;i<NB_UE_INST;i++)
619
    pthread_mutex_init(&RU_output_mutex[i],NULL);
620

621
  memset(UE_output_mask,0,sizeof(int)*NUMBER_OF_RU_MAX);
622 623 624 625
  for (i=0;i<NB_eNB_INST;i++)
    pthread_mutex_init(&UE_output_mutex[i],NULL);

}
626