dlsch_demodulation.c 184 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


ghaddab's avatar
ghaddab committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19
   see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
ghaddab's avatar
ghaddab committed
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

28
*******************************************************************************/
29 30 31 32 33

/*! \file PHY/LTE_TRANSPORT/dlsch_demodulation.c
 * \brief Top-level routines for demodulating the PDSCH physical channel from 36-211, V8.6 2009-03
 * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert
 * \date 2011
34
 * \version 0.1
35 36 37 38 39 40 41 42 43 44
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr,sebastien.aubert@eurecom.fr
 * \note
 * \warning
 */

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "defs.h"
#include "extern.h"
45
#include "PHY/sse_intrin.h"
46 47 48 49 50


#ifndef USER_MODE
#define NOCYGWIN_STATIC static
#else
51
#define NOCYGWIN_STATIC
52 53
#endif

Elena Lukashova's avatar
Elena Lukashova committed
54 55 56
//#undef LOG_D
//#define LOG_D LOG_I

57
//#define DEBUG_PHY 1
58
//#define DEBUG_DLSCH_DEMOD 1
59

knopp's avatar
knopp committed
60
int avg[4]; 
61 62
int avg_0[2];
int avg_1[2];
63 64

// [MCS][i_mod (0,1,2) = (2,4,6)]
65
unsigned char offset_mumimo_llr_drange_fix=0;
Elena Lukashova's avatar
Elena Lukashova committed
66 67 68
uint8_t interf_unaw_shift0=0;
uint8_t interf_unaw_shift1=0;
uint8_t interf_unaw_shift=0;
69
//inferference-free case
70 71
unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 
					     1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
72 73
unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, 
					     0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
74

75 76 77
/*
//original values from sebastion + same hand tuning
unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK
78 79
{5,5,4},{5,5,5},{5,5,5},{3,3,3},{2,2,2},{2,2,2},{2,2,2}, // 16-QAM
{2,2,1},{3,3,3},{3,3,3},{3,3,1},{2,2,2},{2,2,2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; //64-QAM
80
*/
81 82 83 84 85 86 87 88
 /*
 //first optimization try
 unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6, 6, 6},{5, 6, 6},{5, 5, 6},{5, 5, 6},{4, 5, 4},{4, 3, 4},{3, 2, 2},{6, 5, 5},{5, 4, 4},{5, 5, 4},{3, 3, 2},{2, 2, 1},{2, 1, 1},{2, 2, 2},{3, 3, 3},{3, 3, 2},{3, 3, 2},{3, 2, 1},{2, 2, 2},{2, 2, 2},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
 */
 //second optimization try
 /*
   unsigned char offset_mumimo_llr_drange[29][3]={{5, 8, 7},{4, 6, 8},{3, 6, 7},{7, 7, 6},{4, 7, 8},{4, 7, 4},{6, 6, 6},{3, 6, 6},{3, 6, 6},{1, 3, 4},{1, 1, 0},{3, 3, 2},{3, 4, 1},{4, 0, 1},{4, 2, 2},{3, 1, 2},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};  w
 */
89
unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
90 91


92
extern void print_shorts(char *s,int16_t *x);
93

94

95
int rx_pdsch(PHY_VARS_UE *ue,
96 97
             PDSCH_t type,
             unsigned char eNB_id,
98
             unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
gauthier's avatar
gauthier committed
99
             uint8_t subframe,
100 101
             unsigned char symbol,
             unsigned char first_symbol_flag,
102
             RX_type_t rx_type,
103
             unsigned char i_mod,
104 105 106
             unsigned char harq_pid)
{

107 108 109
  LTE_UE_COMMON *common_vars  = &ue->common_vars;
  LTE_UE_PDSCH **pdsch_vars;
  LTE_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
110
  PHY_MEASUREMENTS *measurements = &ue->measurements;
111 112
  LTE_UE_DLSCH_t   **dlsch_ue;

Elena Lukashova's avatar
Elena Lukashova committed
113

114
  unsigned char aatx,aarx;    
115
  unsigned short nb_rb, round;
116
  int avgs, rb;  
Elena Lukashova's avatar
Elena Lukashova committed
117 118

 LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
119
  uint32_t *rballoc;
120

121 122 123
  int32_t **rxdataF_comp_ptr;
  int32_t **dl_ch_mag_ptr;

Elena Lukashova's avatar
Elena Lukashova committed
124 125
  
  
126 127
  switch (type) {
  case SI_PDSCH:
128
    pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
129
    dlsch_ue          = &ue->dlsch_SI[eNB_id];
130
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
131
    break;
132

133
  case RA_PDSCH:
134
    pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
135
    dlsch_ue          = &ue->dlsch_ra[eNB_id];
136
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
137
    break;
138

139
  case PDSCH:
140
    pdsch_vars = &ue->pdsch_vars[eNB_id];
141
    dlsch_ue          = ue->dlsch[eNB_id];
142 143
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
    dlsch1_harq       = dlsch_ue[1]->harq_processes[harq_pid];
144 145 146
    break;

  default:
147
    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,subframe,type);
148 149 150
    return(-1);
    break;
  }
151

152 153
  DevAssert(dlsch0_harq);
  round = dlsch0_harq->round;
154

155
  if (eNB_id > 2) {
jiangx's avatar
jiangx committed
156
    LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
157 158
    return(-1);
  }
159

160 161
  if (!common_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null common_vars\n");
162 163 164 165
    return(-1);
  }

  if (!dlsch_ue[0]) {
jiangx's avatar
jiangx committed
166
    LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
167 168 169
    return(-1);
  }

170 171
  if (!pdsch_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n");
172 173
    return(-1);
  }
174

175
  if (!frame_parms) {
176
    LOG_W(PHY,"dlsch_demodulation.c: Null frame_parms\n");
177 178
    return(-1);
  }
179 180 181 182 183 184
  
  if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) ||
      ((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
    rballoc = dlsch0_harq->rb_alloc_odd;
  else
    rballoc = dlsch0_harq->rb_alloc_even;
185

Elena Lukashova's avatar
Elena Lukashova committed
186
  if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
187 188 189
    LOG_E(PHY,"This transmission mode is not yet supported!\n");
    return(-1);
  }
Elena Lukashova's avatar
Elena Lukashova committed
190 191 192
  
  
  
193 194 195 196 197 198 199 200 201 202
  if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING)))  {
    DevAssert(dlsch1_harq);
    if (eNB_id!=eNB_id_i) {
      LOG_E(PHY,"TM3/TM4 requires to set eNB_id==eNB_id_i!\n");
      return(-1);
    }
  }

  //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round);

203
  if (frame_parms->nb_antennas_tx_eNB>1) {
204 205 206 207
    nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
                                   common_vars->dl_ch_estimates[eNB_id],
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_ch_estimates_ext,
208
                                   dlsch0_harq->pmi_alloc,
209
                                   pdsch_vars[eNB_id]->pmi_ext,
210
                                   rballoc,
211 212
                                   symbol,
                                   subframe,
213
                                   ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
214
                                   frame_parms,
215
				                           dlsch0_harq->mimo_mode);
216
//#ifdef DEBUG_DLSCH_MOD
217 218
    /*   printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc);
       for (rb=0;rb<nb_rb;rb++)
219
	  printf("%d",pdsch_vars[eNB_id]->pmi_ext[rb]);
220
       printf("\n");*/
221
//#endif
222

Elena Lukashova's avatar
Elena Lukashova committed
223
   if (rx_type >= rx_IC_single_stream) {
224 225
      if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
226 227 228
                                       common_vars->dl_ch_estimates[eNB_id_i],
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
229
                                       dlsch0_harq->pmi_alloc,
230
                                       pdsch_vars[eNB_id_i]->pmi_ext,
231
                                       rballoc,
232 233
                                       symbol,
                                       subframe,
234
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
235 236
                                       frame_parms,
				       dlsch0_harq->mimo_mode);
Elena Lukashova's avatar
Elena Lukashova committed
237
     else 
238
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
239 240 241
                                       common_vars->dl_ch_estimates[eNB_id],
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
242
                                       dlsch0_harq->pmi_alloc,
243
                                       pdsch_vars[eNB_id_i]->pmi_ext,
244
                                       rballoc,
245 246
                                       symbol,
                                       subframe,
247
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
248 249
                                       frame_parms,
				       dlsch0_harq->mimo_mode);
250 251
    }
  } // if n_tx>1
252
  else {
253 254 255 256
    nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                     common_vars->dl_ch_estimates[eNB_id],
                                     pdsch_vars[eNB_id]->rxdataF_ext,
                                     pdsch_vars[eNB_id]->dl_ch_estimates_ext,
257
                                     dlsch0_harq->pmi_alloc,
258
                                     pdsch_vars[eNB_id]->pmi_ext,
259
                                     rballoc,
260 261
                                     symbol,
                                     subframe,
262
                                     ue->high_speed_flag,
263
                                     frame_parms);
Elena Lukashova's avatar
Elena Lukashova committed
264
   if (rx_type==rx_IC_single_stream) {
265
     if (eNB_id_i<ue->n_connected_eNB)
266 267 268
        nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                         common_vars->dl_ch_estimates[eNB_id_i],
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
269
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,    
270
                                         dlsch0_harq->pmi_alloc,
271
                                         pdsch_vars[eNB_id_i]->pmi_ext,
272
                                         rballoc,
273 274
                                         symbol,
                                         subframe,
275
                                         ue->high_speed_flag,
276
                                         frame_parms);
Elena Lukashova's avatar
Elena Lukashova committed
277

278
      else 
279 280 281
        nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                         common_vars->dl_ch_estimates[eNB_id],
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
282
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,    
283
                                         dlsch0_harq->pmi_alloc,
284
                                         pdsch_vars[eNB_id_i]->pmi_ext,
285
                                         rballoc,
286 287
                                         symbol,
                                         subframe,
288
                                         ue->high_speed_flag,
289
                                         frame_parms);
290 291
    }
  } //else n_tx>1
292 293

  //  printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
294
  if (nb_rb==0) {
295
    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
296 297
    return(-1);
  }
298

Elena Lukashova's avatar
Elena Lukashova committed
299

300
#ifdef DEBUG_PHY
301
    LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
302 303 304
    LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
#endif

Elena Lukashova's avatar
Elena Lukashova committed
305 306 307 308
  aatx = frame_parms->nb_antennas_tx_eNB;
  aarx = frame_parms->nb_antennas_rx;

  if (dlsch0_harq->mimo_mode<LARGE_CDD) {// SISO or ALAMOUTI
309
    
310
     dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
311 312 313 314
			  frame_parms,
			  dlsch_ue,
			  symbol,
			  nb_rb);
315
  
316
      if (first_symbol_flag==1) {
317
	dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
318 319 320 321
                        frame_parms,
                        avg,
                        symbol,
                        nb_rb);
322 323 324 325
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif

326
    avgs = 0;
327

328 329
    for (aatx=0;aatx<frame_parms->nb_antennas_tx_eNB;aatx++)
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
330
        avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
331
    //  avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
332

333 334
     pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs];
   // printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh);
335 336
      }
    
337
    
338
    	dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
339 340 341 342 343
                               pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               pdsch_vars[eNB_id]->dl_ch_magb0,
                               pdsch_vars[eNB_id]->rxdataF_comp0,
                               (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
344 345 346
                               frame_parms,
                               symbol,
                               first_symbol_flag,
Elena Lukashova's avatar
Elena Lukashova committed
347
                               dlsch0_harq->Qm,
348
                               nb_rb,
349
                               pdsch_vars[eNB_id]->log2_maxh,
350
                               measurements); // log2_maxh+I0_shift
Elena Lukashova's avatar
Elena Lukashova committed
351
 
352
 /*if (symbol == 5) {
353
     write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
354
 } */
355
    if ((rx_type==rx_IC_single_stream) && 
356
        (eNB_id_i<ue->n_connected_eNB)) {
Elena Lukashova's avatar
Elena Lukashova committed
357
         
358
	 dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
359 360 361 362 363
                                 pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                 pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                 pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                 pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                 (aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL,
364 365 366 367 368
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 i_mod,
                                 nb_rb,
369
                                 pdsch_vars[eNB_id]->log2_maxh,
370
                                 measurements); // log2_maxh+I0_shift
371
#ifdef DEBUG_PHY
372

373
      if (symbol == 5) {
374
        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
375

376
        write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);     
377 378
      }
#endif 
Elena Lukashova's avatar
Elena Lukashova committed
379
     // compute correlation between signal and interference channels
380
      dlsch_dual_stream_correlation(frame_parms,
381 382
                                    symbol,
                                    nb_rb,
383 384
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
385
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
386
                                    pdsch_vars[eNB_id]->log2_maxh);
387
    }
388
    
389
  }
390 391 392
  else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || 
           ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && 
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
393
    //   LOG_I(PHY,"Running PDSCH RX for TM3\n");
394
	      
395
    if (frame_parms->nb_antennas_tx_eNB == 2) {
396 397 398
       
	 
	 // scaling interfering channel (following for TM56)
399
	dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
400 401 402
			    frame_parms,
			    dlsch_ue,
			    symbol,
Elena Lukashova's avatar
Elena Lukashova committed
403
			    nb_rb);
404 405
	
	        
406
      if (first_symbol_flag==1) {
407
        // effective channel of desired user is always stronger than interfering eff. channel
408
        dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, 
Elena Lukashova's avatar
Elena Lukashova committed
409
                                 frame_parms,
410
				 pdsch_vars[eNB_id]->pmi_ext,
411 412
                                 avg_0,
				 avg_1,
Elena Lukashova's avatar
Elena Lukashova committed
413 414
				 symbol,
				 nb_rb,
415
                                 dlsch0_harq->mimo_mode);
416 417 418 419
	
	  

 //  write_output("dlsch0_r0_aver_chan_1.m","dl_aver_ch1_r0_0",&avg_1[0],1,1,2);
420
	    
Elena Lukashova's avatar
Elena Lukashova committed
421
	
422
	if (rx_type>rx_standard) {
Elena Lukashova's avatar
Elena Lukashova committed
423 424
	// Shifts are needed to avoid tails in SNR/BLER curves.
	// LUT will be introduced with mcs-dependent shift
425 426
	avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift;
	avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift;
427 428
	pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
	pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
429
	
430 431
	//printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
	//printf("TM4 I-A log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
432
	  
Elena Lukashova's avatar
Elena Lukashova committed
433
	 }
434
	else {
Elena Lukashova's avatar
Elena Lukashova committed
435 436
	// Shifts are needed to avoid tails in SNR/BLER curves.
	// LUT will be introduced with mcs-dependent shift
437 438
	avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift;
	avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift;
439 440 441 442
	pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
	pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
	//printf("TM4 I-UA log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
	//printf("TM4 I-UA log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
Elena Lukashova's avatar
Elena Lukashova committed
443
        }
444
      }
445

446
      dlsch_channel_compensation_TM34(frame_parms, 
447
                                     pdsch_vars[eNB_id],
448
                                     measurements, 
449 450
                                     eNB_id, 
                                     symbol, 
Elena Lukashova's avatar
Elena Lukashova committed
451 452
                                     dlsch0_harq->Qm, 
                                     dlsch1_harq->Qm,
453 454 455 456
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
                                     nb_rb, 
457 458
                                     pdsch_vars[eNB_id]->log2_maxh0,
				     pdsch_vars[eNB_id]->log2_maxh1); 
Elena Lukashova's avatar
Elena Lukashova committed
459
   	   
460
  /*   if (symbol == 5) {
461
   
462 463 464 465
     write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
466 467

   
468
	} */
Elena Lukashova's avatar
Elena Lukashova committed
469

470
      // compute correlation between signal and interference channels (rho12 and rho21)
Elena Lukashova's avatar
Elena Lukashova committed
471
      
472
	dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
473 474
                                    symbol,
                                    nb_rb,
475 476
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
477 478
                                    pdsch_vars[eNB_id]->dl_ch_rho2_ext, 
			   	    pdsch_vars[eNB_id]->log2_maxh0);
479
	
480
	//printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] );
481 482

      //to be optimized (just take complex conjugate)
Elena Lukashova's avatar
Elena Lukashova committed
483

484
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
485 486
                                    symbol,
                                    nb_rb,
487
				    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
488
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
489 490 491
				    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
				    pdsch_vars[eNB_id]->log2_maxh1);
    //  printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext );
492
      //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh);
Elena Lukashova's avatar
Elena Lukashova committed
493
      
494
  /*     if (symbol == 5) {
Elena Lukashova's avatar
Elena Lukashova committed
495
   
496 497 498 499
     write_output("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
Elena Lukashova's avatar
Elena Lukashova committed
500 501

   
502
	} */
503

Elena Lukashova's avatar
Elena Lukashova committed
504
   }
505
      else {
Elena Lukashova's avatar
Elena Lukashova committed
506
     LOG_E(PHY, "only 2 tx antennas supported for TM3\n");
507
      return(-1);
508 509
    }
  }
510
  else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
Elena Lukashova's avatar
Elena Lukashova committed
511
   //    printf("Channel compensation for precoding\n");
512
    if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {  // TM5 two-user
513 514

      // Scale the channel estimates for interfering stream
Elena Lukashova's avatar
Elena Lukashova committed
515
      
516
       dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
Elena Lukashova's avatar
Elena Lukashova committed
517 518 519 520
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb); 
521

522
      dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
523 524 525 526
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);     
527 528 529

      /* compute new log2_maxh for effective channel */
      if (first_symbol_flag==1) {
Elena Lukashova's avatar
Elena Lukashova committed
530

531
        // effective channel of desired user is always stronger than interfering eff. channel
532
       dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
Elena Lukashova's avatar
Elena Lukashova committed
533
				frame_parms,
534
				pdsch_vars[eNB_id]->pmi_ext,
Elena Lukashova's avatar
Elena Lukashova committed
535 536 537
				avg,
				symbol,
				nb_rb);
538

539 540
        //    LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]);
        avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1];
541

542 543
        pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
        //printf("log1_maxh =%d\n",pdsch_vars[eNB_id]->log2_maxh);
544
      }
545
   
546 547 548 549 550 551
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id]->dl_ch_mag0,
                                      pdsch_vars[eNB_id]->dl_ch_magb0,
                                      pdsch_vars[eNB_id]->rxdataF_comp0,
                                      pdsch_vars[eNB_id]->pmi_ext,
552
                                      frame_parms,
553
                                      measurements,
554 555
                                      eNB_id,
                                      symbol,
556
                                      dlsch0_harq->Qm,
557
                                      nb_rb,
558
                                      pdsch_vars[eNB_id]->log2_maxh,
559
                                      dlsch0_harq->dl_power_off);
560 561 562 563

      // if interference source is MU interference, assume opposite precoder was used at eNB

      // calculate opposite PMI
564
      for (rb=0; rb<nb_rb; rb++) {
Elena Lukashova's avatar
Elena Lukashova committed
565

566
        switch(pdsch_vars[eNB_id]->pmi_ext[rb]) {
567
        case 0:
568
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
569
          break;
Elena Lukashova's avatar
Elena Lukashova committed
570
       case 1:
571
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
572
          break;
Elena Lukashova's avatar
Elena Lukashova committed
573
       case 2:
574
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
575 576
          break;
        case 3:
577
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
578 579
          break;
        }
580

Elena Lukashova's avatar
Elena Lukashova committed
581
       //  if (rb==0)
582
        //    printf("pmi %d, pmi_i %d\n",pdsch_vars[eNB_id]->pmi_ext[rb],pdsch_vars[eNB_id_i]->pmi_ext[rb]);
583

584
      }
585 586
    
  
587 588 589 590 591 592
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id_i]->rxdataF_ext,
                                      pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                      pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                      pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                      pdsch_vars[eNB_id_i]->pmi_ext,
593
                                      frame_parms,
594
                                      measurements,
595 596 597 598
                                      eNB_id_i,
                                      symbol,
                                      i_mod,
                                      nb_rb,
599
                                      pdsch_vars[eNB_id]->log2_maxh,
600
                                      dlsch0_harq->dl_power_off);
601

Elena Lukashova's avatar
Elena Lukashova committed
602

603
#ifdef DEBUG_PHY
604

605
      if (symbol==5) {
606
        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
607
       write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
608
      }
609
#endif
610
      dlsch_dual_stream_correlation(frame_parms, 
611 612
                                    symbol, 
                                    nb_rb, 
613 614 615 616
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext, 
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, 
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], 
                                    pdsch_vars[eNB_id]->log2_maxh);
617

618 619
    } 
    else if (dlsch0_harq->dl_power_off==1)  {
Elena Lukashova's avatar
Elena Lukashova committed
620
      
621
        dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
622 623 624 625 626
			  frame_parms,
			  dlsch_ue,
			  symbol,
			  nb_rb);
  
627
      if (first_symbol_flag==1) {
628
	      dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
629 630 631 632
                            frame_parms,
                            avg,
                            symbol,
                            nb_rb);
633 634 635
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif
636

637
    avgs = 0;
Elena Lukashova's avatar
Elena Lukashova committed
638 639 640 641

    for (aatx=0;aatx<frame_parms->nb_antennas_tx_eNB;aatx++)
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
        avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
642
    //  avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
Elena Lukashova's avatar
Elena Lukashova committed
643

644
   pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs];
645
    
646 647 648
      }
      
      
Elena Lukashova's avatar
Elena Lukashova committed
649
      
650 651 652 653 654 655
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id]->dl_ch_mag0,
                                      pdsch_vars[eNB_id]->dl_ch_magb0,
                                      pdsch_vars[eNB_id]->rxdataF_comp0,
                                      pdsch_vars[eNB_id]->pmi_ext,
656
                                      frame_parms,
657
                                      measurements,
658 659
                                      eNB_id,
                                      symbol,
660
                                      dlsch0_harq->Qm,
661
                                      nb_rb,
662
                                      pdsch_vars[eNB_id]->log2_maxh,
663
                                      1);
Elena Lukashova's avatar
Elena Lukashova committed
664

665 666 667 668
    }
  }

  //  printf("MRC\n");
669
  if (frame_parms->nb_antennas_rx > 1) {
670 671 672
    if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
        ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && 
         (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
673
      if (frame_parms->nb_antennas_tx_eNB == 2) {
Elena Lukashova's avatar
Elena Lukashova committed
674

675
	dlsch_detection_mrc_TM34(frame_parms, 
676
                                 pdsch_vars[eNB_id],
677 678 679 680 681
				 harq_pid,
                                 dlsch0_harq->round,
				 symbol,
				 nb_rb,
				 1);
Elena Lukashova's avatar
Elena Lukashova committed
682 683
	
	 
684
    /*   if (symbol == 5) {
Elena Lukashova's avatar
Elena Lukashova committed
685
   
686 687
     write_output("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
688
    	} */
Elena Lukashova's avatar
Elena Lukashova committed
689 690
	
	
691
      }
692 693
    } else {

694
      dlsch_detection_mrc(frame_parms,
695 696 697
                          pdsch_vars[eNB_id]->rxdataF_comp0,
                          pdsch_vars[eNB_id_i]->rxdataF_comp0,
                          pdsch_vars[eNB_id]->rho,
698
                          pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
699 700 701 702
                          pdsch_vars[eNB_id]->dl_ch_mag0,
                          pdsch_vars[eNB_id]->dl_ch_magb0,
                          pdsch_vars[eNB_id_i]->dl_ch_mag0,
                          pdsch_vars[eNB_id_i]->dl_ch_magb0,
703 704 705
                          symbol,
                          nb_rb,
                          rx_type==rx_IC_single_stream); 
706 707
    }
  }
708

709 710 711