channel_sim.c 22.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * 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.0  (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
 */

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
63
#define DEBUG_SIM
64
65
66
67

int number_rb_ul;
int first_rbUL ;

gauthier's avatar
gauthier committed
68
extern Signal_buffers_t *signal_buffers_g;
69
70


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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];
int eNB_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_eNB_MAX];
pthread_mutex_t eNB_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_eNB_MAX];

void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs],
	       node_desc_t *enb_data[NUMBER_OF_eNB_MAX],
	       node_desc_t *ue_data[NUMBER_OF_UE_MAX],
	       uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
	       uint8_t UE_id,
	       int CC_id)
86
{
87

gauthier's avatar
gauthier committed
88
89
  int32_t att_eNB_id=-1;
  int32_t **txdata,**rxdata;
90

gauthier's avatar
gauthier committed
91
  uint8_t eNB_id=0;
92
93
  double tx_pwr;
  double rx_pwr;
gauthier's avatar
gauthier committed
94
95
  int32_t rx_pwr2;
  uint32_t i,aa;
96
  uint32_t sf_offset;
97
98

  double min_path_loss=-200;
gauthier's avatar
gauthier committed
99
  uint8_t hold_channel=0;
knopp's avatar
   
knopp committed
100
101
  uint8_t nb_antennas_rx = eNB2UE[0][0][CC_id]->nb_rx; // number of rx antennas at UE
  uint8_t nb_antennas_tx = eNB2UE[0][0][CC_id]->nb_tx; // number of tx antennas at eNB
102

knopp's avatar
knopp committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  double s_re0[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double s_re1[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *s_re[2];
  double s_im0[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double s_im1[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *s_im[2];
  double r_re00[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double r_re01[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *r_re0[2];
  double r_im00[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double r_im01[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  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;
knopp's avatar
knopp committed
125

126
  if (subframe==0)
127
128
129
130
131
132
133
    hold_channel = 0;
  else
    hold_channel = 1;

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

134
    if (!hold_channel) {
135
      // calculate the random channel from each eNB
136
137
      for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {

knopp's avatar
   
knopp committed
138
        random_channel(eNB2UE[eNB_id][UE_id][CC_id],abstraction_flag);
139
        /*
140
141
142
        for (i=0;i<eNB2UE[eNB_id][UE_id]->nb_taps;i++)
        printf("eNB2UE[%d][%d]->a[0][%d] = (%f,%f)\n",eNB_id,UE_id,i,eNB2UE[eNB_id][UE_id]->a[0][i].x,eNB2UE[eNB_id][UE_id]->a[0][i].y);
        */
knopp's avatar
   
knopp committed
143
        freq_channel(eNB2UE[eNB_id][UE_id][CC_id], frame_parms->N_RB_DL,frame_parms->N_RB_DL*12+1);
144
145
146
      }

      // find out which eNB the UE is attached to
147
      for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
Bilel's avatar
Bilel committed
148
        if (find_ue(PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti,PHY_vars_eNB_g[eNB_id][CC_id])>=0) {
149
150
          // UE with UE_id is connected to eNb with eNB_id
          att_eNB_id=eNB_id;
151
          LOG_D(OCM,"A: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
152
153
154
155
156
        }
      }

      // if UE is not attached yet, find assume its the eNB with the smallest pathloss
      if (att_eNB_id<0) {
157
        for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
knopp's avatar
   
knopp committed
158
159
          if (min_path_loss<eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB) {
            min_path_loss = eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB;
160
            att_eNB_id=eNB_id;
161
            LOG_D(OCM,"B: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id);
162
163
164
165
166
167
168
169
          }
        }
      }

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

171
#ifdef DEBUG_SIM
knopp's avatar
   
knopp committed
172
173
174
175
      rx_pwr = signal_energy_fp2(eNB2UE[att_eNB_id][UE_id][CC_id]->ch[0],
                                 eNB2UE[att_eNB_id][UE_id][CC_id]->channel_length)*eNB2UE[att_eNB_id][UE_id][CC_id]->channel_length;
      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,
knopp's avatar
   
knopp committed
176
            frame_parms->pdsch_config_common.referenceSignalPower,
knopp's avatar
   
knopp committed
177
            eNB2UE[att_eNB_id][UE_id][CC_id]->path_loss_dB);
178
#endif
179
180
181

      //dlsch_abstraction(PHY_vars_UE_g[UE_id]->sinr_dB, rb_alloc, 8);
      // fill in perfect channel estimates
knopp's avatar
   
knopp committed
182
      channel_desc_t *desc1 = eNB2UE[att_eNB_id][UE_id][CC_id];
183
      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];
184
      //      double scale = pow(10.0,(enb_data[att_eNB_id]->tx_power_dBm + eNB2UE[att_eNB_id][UE_id]->path_loss_dB + (double) PHY_vars_UE_g[UE_id]->rx_total_gain_dB)/20.0);
knopp's avatar
   
knopp committed
185
      double scale = pow(10.0,(frame_parms->pdsch_config_common.referenceSignalPower+eNB2UE[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);
186
187
188
189
190
      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;
191
192
193
194
195
196
197
198
199
200
201
202

      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) ;
            }
          }
        }
      }
203

204
      // calculate the SNR for the attached eNB (this assumes eNB always uses PMI stored in eNB_UE_stats; to be improved)
205
      init_snr(eNB2UE[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,
206
207
               PHY_vars_UE_g[UE_id][CC_id]->transmission_mode[att_eNB_id], PHY_vars_eNB_g[att_eNB_id][CC_id]->UE_stats[UE_id].DL_pmi_single,
	       PHY_vars_eNB_g[att_eNB_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off,PHY_vars_eNB_g[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
208
209
210
211

      // calculate sinr here
      for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) {
        if (att_eNB_id != eNB_id) {
212
          calculate_sinr(eNB2UE[eNB_id][UE_id][CC_id], enb_data[eNB_id], ue_data[UE_id], PHY_vars_UE_g[UE_id][CC_id]->sinr_dB,PHY_vars_eNB_g[att_eNB_id][CC_id]->frame_parms.N_RB_DL);
213
214
        }
      }
215
    } // hold channel
216
217
  }
  else { //abstraction_flag
218
219
220


    pthread_mutex_lock(&eNB_output_mutex[UE_id]);
knopp's avatar
knopp committed
221
 
222
    if (eNB_output_mask[UE_id] == 0) {  //  This is the first eNodeB for this UE, clear the buffer
knopp's avatar
knopp committed
223
      
224
225
226
227
      for (aa=0; aa<nb_antennas_rx; aa++) {
	memset((void*)r_re_DL[UE_id][aa],0,(frame_parms->samples_per_tti)*sizeof(double));
	memset((void*)r_im_DL[UE_id][aa],0,(frame_parms->samples_per_tti)*sizeof(double));
      }
228
    }
229
    pthread_mutex_unlock(&eNB_output_mutex[UE_id]);
knopp's avatar
   
knopp committed
230

231
    for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
232
      txdata = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.txdata[0];
233
      sf_offset = subframe*frame_parms->samples_per_tti;
234
235
236
      tx_pwr = dac_fixed_gain(s_re,
                              s_im,
                              txdata,
237
                              sf_offset,
238
                              nb_antennas_tx,
239
240
                              frame_parms->samples_per_tti,
                              sf_offset,
241
242
243
244
                              frame_parms->ofdm_symbol_size,
                              14,
                              frame_parms->pdsch_config_common.referenceSignalPower, // dBm/RE
                              frame_parms->N_RB_DL*12);
245
246

#ifdef DEBUG_SIM
247
      LOG_D(OCM,"[SIM][DL] eNB %d (CCid %d): tx_pwr %.1f dBm/RE (target %d dBm/RE), for subframe %d\n",
248
249
250
            eNB_id,CC_id,
            10*log10(tx_pwr),
            frame_parms->pdsch_config_common.referenceSignalPower,
251
252
            subframe);

253
254
255
#endif
      //eNB2UE[eNB_id][UE_id]->path_loss_dB = 0;
      multipath_channel(eNB2UE[eNB_id][UE_id][CC_id],s_re,s_im,r_re0,r_im0,
256
                        frame_parms->samples_per_tti,hold_channel);
257
258
259
260
#ifdef DEBUG_SIM
      rx_pwr = signal_energy_fp2(eNB2UE[eNB_id][UE_id][CC_id]->ch[0],
                                 eNB2UE[eNB_id][UE_id][CC_id]->channel_length)*eNB2UE[eNB_id][UE_id][CC_id]->channel_length;
      LOG_D(OCM,"[SIM][DL] Channel eNB %d => UE %d (CCid %d): Channel gain %f dB (%f)\n",eNB_id,UE_id,CC_id,10*log10(rx_pwr),rx_pwr);
261
#endif
262
263
264
265
266
267
268


#ifdef DEBUG_SIM

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

269
270
#endif

271
272
273
274
275
      LOG_D(OCM,"[SIM][DL] Channel eNB %d => UE %d (CCid %d): tx_power %.1f dBm/RE, path_loss %1.f dB\n",
            eNB_id,UE_id,CC_id,
            (double)frame_parms->pdsch_config_common.referenceSignalPower,
            //         enb_data[eNB_id]->tx_power_dBm,
            eNB2UE[eNB_id][UE_id][CC_id]->path_loss_dB);
276
277

#ifdef DEBUG_SIM
278
279
      rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx,
                                frame_parms->ofdm_symbol_size,
280
281
                                sf_offset)/(12.0*frame_parms->N_RB_DL);
      LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI)for subframe %d\n",UE_id,
282
            10*log10(rx_pwr),
283
            10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),subframe);
284
      LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for subframe %d\n",
285
            UE_id,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
286
287
            10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6)-174,
            10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6*12*frame_parms->N_RB_DL/(double)frame_parms->ofdm_symbol_size)-174,
288
            subframe);
289
290
#endif

291
292
293
294
295
      if (eNB2UE[eNB_id][UE_id][CC_id]->first_run == 1)
        eNB2UE[eNB_id][UE_id][CC_id]->first_run = 0;


      // RF model
296
#ifdef DEBUG_SIM
297
298
      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);
299
#endif
300
301
302
303

      rf_rx_simple(r_re0,
                   r_im0,
                   nb_antennas_rx,
304
                   frame_parms->samples_per_tti,
Florian Kaltenberger's avatar
Florian Kaltenberger committed
305
                   1e3/eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate,  // sampling time (ns)
306
307
308
309
310
311
                   (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,
                                frame_parms->ofdm_symbol_size,
312
313
                                sf_offset)/(12.0*frame_parms->N_RB_DL);
      LOG_D(OCM,"[SIM][DL] UE %d : ADC in (eNB %d) %f dBm/RE for subframe %d\n",
314
            UE_id,eNB_id,
315
            10*log10(rx_pwr),subframe);
316
#endif
317
318
319
      
      pthread_mutex_lock(&eNB_output_mutex[UE_id]);
      for (i=0; i<frame_parms->samples_per_tti; i++) {
320
        for (aa=0; aa<nb_antennas_rx; aa++) {
321
322
          r_re_DL[UE_id][aa][i]+=r_re0[aa][i];
          r_im_DL[UE_id][aa][i]+=r_im0[aa][i];
323
        }
324
      }
325
326
327
328
      eNB_output_mask[UE_id] |= (1<<eNB_id);
      if (eNB_output_mask[UE_id] == (1<<NB_eNB_INST)-1) {
	eNB_output_mask[UE_id]=0;
      
329

330
331
	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]};
332
333

#ifdef DEBUG_SIM
knopp's avatar
knopp committed
334
	rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->ofdm_symbol_size,sf_offset)/(12.0*frame_parms->N_RB_DL);
335
	LOG_D(OCM,"[SIM][DL] UE %d : ADC in %f dBm for subframe %d\n",UE_id,10*log10(rx_pwr),subframe);
336
#endif
337
338
339
	
	rxdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.rxdata;
	sf_offset = subframe*frame_parms->samples_per_tti;
knopp's avatar
knopp committed
340
341
342
343


	adc(r_re_p,
	    r_im_p,
344
345
346
347
348
349
350
	    0,
	    sf_offset,
	    rxdata,
	    nb_antennas_rx,
	    frame_parms->samples_per_tti,
	    12);
	
351
#ifdef DEBUG_SIM
352
353
	rx_pwr2 = signal_energy(rxdata[0]+sf_offset,frame_parms->ofdm_symbol_size)/(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\n",UE_id, 10*log10((double)rx_pwr2),rx_pwr2,subframe,rxdata);
354
#else
355
356
357
	UNUSED_VARIABLE(rx_pwr2);
	UNUSED_VARIABLE(tx_pwr);
	UNUSED_VARIABLE(rx_pwr);
358
#endif
359
360
361
362
363
		
      } // eNB_output_mask
      pthread_mutex_unlock(&eNB_output_mutex[UE_id]);      
    } // eNB_id

364
365
366
367
368
  }

}


369
370
371
372
void do_UL_sig(channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs],
               node_desc_t *enb_data[NUMBER_OF_eNB_MAX],node_desc_t *ue_data[NUMBER_OF_UE_MAX],
	       uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, 
	       uint32_t frame,int eNB_id,uint8_t CC_id)
373
{
374

gauthier's avatar
gauthier committed
375
  int32_t **txdata,**rxdata;
376
#ifdef PHY_ABSTRACTION_UL
gauthier's avatar
gauthier committed
377
  int32_t att_eNB_id=-1;
378
#endif
379
  uint8_t UE_id=0;
380

knopp's avatar
   
knopp committed
381
382
  uint8_t nb_antennas_rx = UE2eNB[0][0][CC_id]->nb_rx; // number of rx antennas at eNB
  uint8_t nb_antennas_tx = UE2eNB[0][0][CC_id]->nb_tx; // number of tx antennas at UE
383
384

  double tx_pwr, rx_pwr;
gauthier's avatar
gauthier committed
385
386
  int32_t rx_pwr2;
  uint32_t i,aa;
387
  uint32_t sf_offset;
388

gauthier's avatar
gauthier committed
389
  uint8_t hold_channel=0;
390
391
392

#ifdef PHY_ABSTRACTION_UL
  double min_path_loss=-200;
gauthier's avatar
gauthier committed
393
394
  uint16_t ul_nb_rb=0 ;
  uint16_t ul_fr_rb=0;
395
396
  int ulnbrb2 ;
  int ulfrrb2 ;
gauthier's avatar
gauthier committed
397
  uint8_t harq_pid;
398
#endif
knopp's avatar
knopp committed
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  double s_re0[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double s_re1[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *s_re[2];
  double s_im0[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double s_im1[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *s_im[2];
  double r_re00[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double r_re01[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double *r_re0[2];
  double r_im00[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  double r_im01[30720];//PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti];
  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;
421
422

  if (abstraction_flag!=0)  {
423
#ifdef PHY_ABSTRACTION_UL
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
      if (!hold_channel) {
	random_channel(UE2eNB[UE_id][eNB_id][CC_id],abstraction_flag);
	freq_channel(UE2eNB[UE_id][eNB_id][CC_id], frame_parms->N_RB_UL,frame_parms->N_RB_UL*12+1);
	
	// REceived power at the eNB
	rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0],
				   UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][att_eNB_id][CC_id]->channel_length; // calculate the rx power at the eNB
      }
      
      //  write_output("SINRch.m","SINRch",PHY_vars_eNB_g[att_eNB_id]->sinr_dB_eNB,frame_parms->N_RB_UL*12+1,1,1);
      if(subframe>1 && subframe <5) {
	harq_pid = subframe2harq_pid(frame_parms,frame,subframe);
	ul_nb_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->nb_rb;
	ul_fr_rb = PHY_vars_eNB_g[att_eNB_id][CC_id]->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->first_rb;
      }
      
      if(ul_nb_rb>1 && (ul_fr_rb < 25 && ul_fr_rb > -1)) {
	number_rb_ul = ul_nb_rb;
	first_rbUL = ul_fr_rb;
	init_snr_up(UE2eNB[UE_id][att_eNB_id][CC_id],enb_data[att_eNB_id], ue_data[UE_id],PHY_vars_eNB_g[att_eNB_id][CC_id]->sinr_dB,&PHY_vars_UE_g[att_eNB_id][CC_id]->N0,ul_nb_rb,ul_fr_rb);
	
      }
    } //UE_id
449

450
#else
451

452
#endif
453
  } else { //without abstraction
454

455
456
457
458
459
460
    pthread_mutex_lock(&UE_output_mutex[eNB_id]);
    // 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++) {
	r_re_UL[eNB_id][aa][i]=0.0;
	r_im_UL[eNB_id][aa][i]=0.0;
461
462
      }
    }
463
464
465
466
467
468
469
470
    pthread_mutex_unlock(&UE_output_mutex[eNB_id]);

    // Compute RX signal for eNB = eNB_id
    for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
      
      txdata = PHY_vars_UE_g[UE_id][CC_id]->common_vars.txdata;
      sf_offset = subframe*frame_parms->samples_per_tti;
      
471
      if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
472
473
	   UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB) <= -125.0) {
	// don't simulate a UE that is too weak
474
475
476
477
478
	LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d)\n",
	      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);	
479
480
481
482
483
484
485
486
487
488
      } 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,
489
490
				(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]),
				PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]);  // This make the previous argument the total power
491
492
493
	LOG_D(OCM,"[SIM][UL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d)\n",
	      UE_id,
	      10*log10(tx_pwr),
494
495
	      PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
	      PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
496
497
	      subframe,sf_offset);
       
knopp's avatar
knopp committed
498
499
		
	multipath_channel(UE2eNB[UE_id][eNB_id][CC_id],s_re,s_im,r_re0,r_im0,
500
501
502
503
504
505
506
507
508
509
			  frame_parms->samples_per_tti,hold_channel);
	

	rx_pwr = signal_energy_fp2(UE2eNB[UE_id][eNB_id][CC_id]->ch[0],
				   UE2eNB[UE_id][eNB_id][CC_id]->channel_length)*UE2eNB[UE_id][eNB_id][CC_id]->channel_length;

	LOG_D(OCM,"[SIM][UL] subframe %d Channel UE %d => eNB %d : %f dB (hold %d,length %d, PL %f)\n",subframe,UE_id,eNB_id,10*log10(rx_pwr),
	      hold_channel,UE2eNB[UE_id][eNB_id][CC_id]->channel_length,
	      UE2eNB[UE_id][eNB_id][CC_id]->path_loss_dB);

knopp's avatar
knopp committed
510
	rx_pwr = signal_energy_fp(r_re0,r_im0,nb_antennas_rx,frame_parms->samples_per_tti,0);
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
	LOG_D(OCM,"[SIM][UL] eNB %d : rx_pwr %f dBm (%f) for subframe %d, sptti %d\n",
	      eNB_id,10*log10(rx_pwr),rx_pwr,subframe,frame_parms->samples_per_tti);
	
	
	if (UE2eNB[UE_id][eNB_id][CC_id]->first_run == 1)
	  UE2eNB[UE_id][eNB_id][CC_id]->first_run = 0;
	
	
	pthread_mutex_lock(&UE_output_mutex[eNB_id]);
	for (aa=0; aa<nb_antennas_rx; aa++) {
	  for (i=0; i<frame_parms->samples_per_tti; i++) {
	    r_re_UL[eNB_id][aa][i]+=r_re0[aa][i];
	    r_im_UL[eNB_id][aa][i]+=r_im0[aa][i];
	  }
	}
	pthread_mutex_unlock(&UE_output_mutex[eNB_id]);
527
      }
528
529
    } //UE_id
    
knopp's avatar
knopp committed
530
531
532
533
534
    double *r_re_p[2] = {r_re_UL[eNB_id][0],r_re_UL[eNB_id][1]};
    double *r_im_p[2] = {r_im_UL[eNB_id][0],r_im_UL[eNB_id][1]};

    rf_rx_simple(r_re_p,
		 r_im_p,
535
536
537
538
539
		 nb_antennas_rx,
		 frame_parms->samples_per_tti,
		 1e3/UE2eNB[0][eNB_id][CC_id]->sampling_rate,  // sampling time (ns)
		 (double)PHY_vars_eNB_g[eNB_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)
    
540
#ifdef DEBUG_SIM
knopp's avatar
knopp committed
541
    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);
542
    LOG_D(OCM,"[SIM][UL] rx_pwr (ADC in) %f dB for subframe %d\n",10*log10(rx_pwr),subframe);
543
#endif
544
545
546
    
    rxdata = PHY_vars_eNB_g[eNB_id][CC_id]->common_vars.rxdata[0];
    sf_offset = subframe*frame_parms->samples_per_tti;
knopp's avatar
knopp committed
547

548
    
knopp's avatar
knopp committed
549
550
    adc(r_re_p,
	r_im_p,
551
552
553
554
555
556
557
	0,
	sf_offset,
	rxdata,
	nb_antennas_rx,
	frame_parms->samples_per_tti,
	12);
    
558
#ifdef DEBUG_SIM
559
    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);
560
    LOG_D(OCM,"[SIM][UL] eNB %d rx_pwr (ADC out) %f dB (%d) for subframe %d (offset %d)\n",eNB_id,10*log10((double)rx_pwr2),rx_pwr2,subframe,sf_offset);
561
#else
562
563
564
    UNUSED_VARIABLE(tx_pwr);
    UNUSED_VARIABLE(rx_pwr);
    UNUSED_VARIABLE(rx_pwr2);
565
#endif
566
    
567
568
569
570
571
  } // abstraction_flag==0

}


572
573
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)
{
574
575
576

  int i;

577
578
579
  memset(eNB_output_mask,0,sizeof(int)*NUMBER_OF_UE_MAX);
  for (i=0;i<NB_UE_INST;i++)
    pthread_mutex_init(&eNB_output_mutex[i],NULL);
580

581
582
583
584
585
  memset(UE_output_mask,0,sizeof(int)*NUMBER_OF_eNB_MAX);
  for (i=0;i<NB_eNB_INST;i++)
    pthread_mutex_init(&UE_output_mutex[i],NULL);

}
586