dlsch_demodulation.c 185 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

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
unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
71
					     1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
72
unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
73
					     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 96 97 98
int rx_pdsch(PHY_VARS_UE *phy_vars_ue,
             PDSCH_t type,
             unsigned char eNB_id,
             unsigned char eNB_id_i, //if this == phy_vars_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 110 111 112
  LTE_UE_COMMON *lte_ue_common_vars  = &phy_vars_ue->lte_ue_common_vars;
  LTE_UE_PDSCH **lte_ue_pdsch_vars;
  LTE_DL_FRAME_PARMS *frame_parms    = &phy_vars_ue->lte_frame_parms;
  PHY_MEASUREMENTS *phy_measurements = &phy_vars_ue->PHY_measurements;
  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
  int32_t **rxdataF_comp_ptr;
  int32_t **dl_ch_mag_ptr;
123 124 125 126
  int32_t codeword_TB0;
  int32_t codeword_TB1;


127

128 129 130 131
  switch (type) {
  case SI_PDSCH:
    lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id];
    dlsch_ue          = &phy_vars_ue->dlsch_ue_SI[eNB_id];
132
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
133
    break;
134

135 136 137
  case RA_PDSCH:
    lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars_ra[eNB_id];
    dlsch_ue          = &phy_vars_ue->dlsch_ue_ra[eNB_id];
138
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
139
    break;
140

141 142 143
  case PDSCH:
    lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars[eNB_id];
    dlsch_ue          = phy_vars_ue->dlsch_ue[eNB_id];
144 145 146 147
    codeword_TB0      = dlsch_ue[0]->harq_processes[harq_pid]->codeword;
    codeword_TB1      = dlsch_ue[1]->harq_processes[harq_pid]->codeword;
    dlsch0_harq       = dlsch_ue[codeword_TB0]->harq_processes[harq_pid];
    dlsch1_harq       = dlsch_ue[codeword_TB1]->harq_processes[harq_pid];
148 149 150
    break;

  default:
151
    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",phy_vars_ue->frame_rx,subframe,type);
152 153 154
    return(-1);
    break;
  }
155

156 157
  DevAssert(dlsch0_harq);
  round = dlsch0_harq->round;
158

159
  if (eNB_id > 2) {
jiangx's avatar
jiangx committed
160
    LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
161 162
    return(-1);
  }
163

164
  if (!lte_ue_common_vars) {
jiangx's avatar
jiangx committed
165
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_ue_common_vars\n");
166 167 168 169
    return(-1);
  }

  if (!dlsch_ue[0]) {
jiangx's avatar
jiangx committed
170
    LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
171 172 173 174
    return(-1);
  }

  if (!lte_ue_pdsch_vars) {
jiangx's avatar
jiangx committed
175
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_ue_pdsch_vars pointer\n");
176 177
    return(-1);
  }
178

179
  if (!frame_parms) {
jiangx's avatar
jiangx committed
180
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_frame_parms\n");
181 182
    return(-1);
  }
183

184 185 186 187 188
  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;
189

Elena Lukashova's avatar
Elena Lukashova committed
190
  if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
191 192 193
    LOG_E(PHY,"This transmission mode is not yet supported!\n");
    return(-1);
  }
194 195 196



197 198 199 200 201 202 203 204 205 206
  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);

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

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

282
      else
283 284 285
        nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF,
                                         lte_ue_common_vars->dl_ch_estimates[eNB_id],
                                         lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext,
286
                                         lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
287 288
                                         dlsch0_harq->pmi_alloc,
                                         lte_ue_pdsch_vars[eNB_id_i]->pmi_ext,
289
                                         rballoc,
290 291 292 293
                                         symbol,
                                         subframe,
                                         phy_vars_ue->high_speed_flag,
                                         frame_parms);
294 295
    }
  } //else n_tx>1
296 297

  //  printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
298
  if (nb_rb==0) {
299
    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
300 301
    return(-1);
  }
302

Elena Lukashova's avatar
Elena Lukashova committed
303

304 305 306 307 308
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
    LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
#endif

Elena Lukashova's avatar
Elena Lukashova committed
309 310 311 312
  aatx = frame_parms->nb_antennas_tx_eNB;
  aarx = frame_parms->nb_antennas_rx;

  if (dlsch0_harq->mimo_mode<LARGE_CDD) {// SISO or ALAMOUTI
313

314
     dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
315 316 317 318
			  frame_parms,
			  dlsch_ue,
			  symbol,
			  nb_rb);
319

320 321
      if (first_symbol_flag==1) {
	dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
322 323 324 325
                        frame_parms,
                        avg,
                        symbol,
                        nb_rb);
326 327 328 329
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif

330
    avgs = 0;
331

332 333
    for (aatx=0;aatx<frame_parms->nb_antennas_tx_eNB;aatx++)
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
334
        avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
335
    //  avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
336

337
     lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs];
338
   // printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh);
339
      }
340 341


Elena Lukashova's avatar
Elena Lukashova committed
342
    	dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
343 344 345 346 347 348 349 350
                               lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                               lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
                               lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
                               lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                               (aatx>1) ? lte_ue_pdsch_vars[eNB_id]->rho : NULL,
                               frame_parms,
                               symbol,
                               first_symbol_flag,
Elena Lukashova's avatar
Elena Lukashova committed
351
                               dlsch0_harq->Qm,
352 353 354
                               nb_rb,
                               lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                               phy_measurements); // log2_maxh+I0_shift
355

356
 /*if (symbol == 5) {
357
     write_output("rxF_comp_d.m","rxF_c_d",&lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
358
 } */
359
    if ((rx_type==rx_IC_single_stream) &&
360
        (eNB_id_i<phy_vars_ue->n_connected_eNB)) {
361

Elena Lukashova's avatar
Elena Lukashova committed
362
	 dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext,
363 364 365 366 367 368 369 370 371 372 373 374
                                 lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                 lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                 lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                 lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                 (aatx>1) ? lte_ue_pdsch_vars[eNB_id_i]->rho : NULL,
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 i_mod,
                                 nb_rb,
                                 lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                                 phy_measurements); // log2_maxh+I0_shift
375
#ifdef DEBUG_PHY
376

377
      if (symbol == 5) {
378
        write_output("rxF_comp_d.m","rxF_c_d",&lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
379

380
        write_output("rxF_comp_i.m","rxF_c_i",&lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
381
      }
382
#endif
Elena Lukashova's avatar
Elena Lukashova committed
383
     // compute correlation between signal and interference channels
384
      dlsch_dual_stream_correlation(frame_parms,
385 386 387 388 389 390
                                    symbol,
                                    nb_rb,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh);
391
    }
392

393
  }
394 395
  else if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
           ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
396
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
397
    //   LOG_I(PHY,"Running PDSCH RX for TM3\n");
398

399
    if (frame_parms->nb_antennas_tx_eNB == 2) {
400 401


402
	 // scaling interfering channel (following for TM56)
Elena Lukashova's avatar
Elena Lukashova committed
403
	dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
404 405 406
			    frame_parms,
			    dlsch_ue,
			    symbol,
Elena Lukashova's avatar
Elena Lukashova committed
407
			    nb_rb);
408 409


410
      if (first_symbol_flag==1) {
411
        // effective channel of desired user is always stronger than interfering eff. channel
412
        dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
Elena Lukashova's avatar
Elena Lukashova committed
413 414
                                 frame_parms,
				 lte_ue_pdsch_vars[eNB_id]->pmi_ext,
415 416
                                 avg_0,
				 avg_1,
Elena Lukashova's avatar
Elena Lukashova committed
417 418
				 symbol,
				 nb_rb,
419
                                 dlsch0_harq->mimo_mode);
420 421


422 423

 //  write_output("dlsch0_r0_aver_chan_1.m","dl_aver_ch1_r0_0",&avg_1[0],1,1,2);
424 425


426
	if (rx_type>rx_standard) {
Elena Lukashova's avatar
Elena Lukashova committed
427 428
	// Shifts are needed to avoid tails in SNR/BLER curves.
	// LUT will be introduced with mcs-dependent shift
429 430
	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;
431 432
	lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
	lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
433

Elena Lukashova's avatar
Elena Lukashova committed
434 435
	//printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
	//printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
436

Elena Lukashova's avatar
Elena Lukashova committed
437
	 }
438
	else {
Elena Lukashova's avatar
Elena Lukashova committed
439 440
	// Shifts are needed to avoid tails in SNR/BLER curves.
	// LUT will be introduced with mcs-dependent shift
441 442
	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;
443 444
	lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
	lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
Elena Lukashova's avatar
Elena Lukashova committed
445 446 447
	//printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
	//printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
        }
448
      }
449

450
      dlsch_channel_compensation_TM34(frame_parms,
451
                                     lte_ue_pdsch_vars[eNB_id],
452 453 454 455
                                     phy_measurements,
                                     eNB_id,
                                     symbol,
                                     dlsch0_harq->Qm,
Elena Lukashova's avatar
Elena Lukashova committed
456
                                     dlsch1_harq->Qm,
457 458 459
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
460
                                     nb_rb,
461
                                     lte_ue_pdsch_vars[eNB_id]->log2_maxh0,
462 463
				     lte_ue_pdsch_vars[eNB_id]->log2_maxh1);

464
  /*   if (symbol == 5) {
465

466 467 468 469 470
     write_output("rxF_comp_d00.m","rxF_c_d00",&lte_ue_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",&lte_ue_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",&lte_ue_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",&lte_ue_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

471

472
	} */
Elena Lukashova's avatar
Elena Lukashova committed
473

474
      // compute correlation between signal and interference channels (rho12 and rho21)
475

476
	dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
477 478 479
                                    symbol,
                                    nb_rb,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
480
                                    &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
481
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext,
482
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
483

484
	//printf("rho stream1 =%d\n", &lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] );
485 486

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

488
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
489 490
                                    symbol,
                                    nb_rb,
491
				    &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
492
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
493
				    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
494
				    lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
495
    //  printf("rho stream2 =%d\n",&lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext );
496
      //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh);
497

498
  /*     if (symbol == 5) {
499

Elena Lukashova's avatar
Elena Lukashova committed
500 501 502 503 504
     write_output("rho0_0.m","rho0_0",&lte_ue_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",&lte_ue_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",&lte_ue_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",&lte_ue_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

505

506
	} */
507

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

      // Scale the channel estimates for interfering stream
519

Elena Lukashova's avatar
Elena Lukashova committed
520 521 522 523
       dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                          frame_parms,
                          dlsch_ue,
                          symbol,
524
                          nb_rb);
525

526
      dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
527 528 529
                          frame_parms,
                          dlsch_ue,
                          symbol,
530
                          nb_rb);
531 532 533

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

535
        // effective channel of desired user is always stronger than interfering eff. channel
Elena Lukashova's avatar
Elena Lukashova committed
536 537 538 539 540 541
       dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
				frame_parms,
				lte_ue_pdsch_vars[eNB_id]->pmi_ext,
				avg,
				symbol,
				nb_rb);
542

543 544
        //    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];
545

546 547
        lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
        //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh);
548
      }
549

550 551 552 553 554 555 556 557 558 559
      dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
                                      lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                                      lte_ue_pdsch_vars[eNB_id]->pmi_ext,
                                      frame_parms,
                                      phy_measurements,
                                      eNB_id,
                                      symbol,
560
                                      dlsch0_harq->Qm,
561 562
                                      nb_rb,
                                      lte_ue_pdsch_vars[eNB_id]->log2_maxh,
563
                                      dlsch0_harq->dl_power_off);
564 565 566 567

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

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

570 571 572 573
        switch(lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb]) {
        case 0:
          lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
          break;
Elena Lukashova's avatar
Elena Lukashova committed
574
       case 1:
575 576
          lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
          break;
Elena Lukashova's avatar
Elena Lukashova committed
577
       case 2:
578 579 580 581 582 583
          lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
          break;
        case 3:
          lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
          break;
        }
584

Elena Lukashova's avatar
Elena Lukashova committed
585
       //  if (rb==0)
586 587
        //    printf("pmi %d, pmi_i %d\n",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb],lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]);

588
      }
589 590


591 592 593 594 595 596 597 598 599 600 601 602 603
      dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext,
                                      lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                      lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                      lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                      lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                      lte_ue_pdsch_vars[eNB_id_i]->pmi_ext,
                                      frame_parms,
                                      phy_measurements,
                                      eNB_id_i,
                                      symbol,
                                      i_mod,
                                      nb_rb,
                                      lte_ue_pdsch_vars[eNB_id]->log2_maxh,
604
                                      dlsch0_harq->dl_power_off);
605

Elena Lukashova's avatar
Elena Lukashova committed
606

607
#ifdef DEBUG_PHY
608

609
      if (symbol==5) {
610
        write_output("rxF_comp_d.m","rxF_c_d",&lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
Elena Lukashova's avatar
Elena Lukashova committed
611
       write_output("rxF_comp_i.m","rxF_c_i",&lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
612
      }
613
#endif
614 615 616 617 618 619
      dlsch_dual_stream_correlation(frame_parms,
                                    symbol,
                                    nb_rb,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
620
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh);
621

622
    }
623
    else if (dlsch0_harq->dl_power_off==1)  {
624

Elena Lukashova's avatar
Elena Lukashova committed
625
        dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
626 627 628 629
			  frame_parms,
			  dlsch_ue,
			  symbol,
			  nb_rb);
630

631
      if (first_symbol_flag==1) {
632 633 634 635 636
	      dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                            frame_parms,
                            avg,
                            symbol,
                            nb_rb);
637 638 639
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif
640

641
    avgs = 0;
Elena Lukashova's avatar
Elena Lukashova committed
642 643 644 645

    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]);
646
    //  avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
Elena Lukashova's avatar
Elena Lukashova committed
647

648
   lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs];
649

650
      }
651 652 653



654
      dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
655 656 657 658 659 660 661 662 663
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
                                      lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
                                      lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                                      lte_ue_pdsch_vars[eNB_id]->pmi_ext,
                                      frame_parms,
                                      phy_measurements,
                                      eNB_id,
                                      symbol,
664
                                      dlsch0_harq->Qm,
665 666 667
                                      nb_rb,
                                      lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                                      1);
Elena Lukashova's avatar
Elena Lukashova committed
668

669 670 671 672
    }
  }

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

679
	dlsch_detection_mrc_TM34(frame_parms,
680 681 682 683 684 685
                                 lte_ue_pdsch_vars[eNB_id],
				 harq_pid,
                                 dlsch0_harq->round,
				 symbol,
				 nb_rb,
				 1);
686 687


688
    /*   if (symbol == 5) {
689

Elena Lukashova's avatar
Elena Lukashova committed
690 691
     write_output("rho0_mrc.m","rho0_0",&lte_ue_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",&lte_ue_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
692
    	} */
693 694


695
      }
696 697
    } else {

698
      dlsch_detection_mrc(frame_parms,
699 700 701 702 703 704 705 706 707 708
                          lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                          lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0,
                          lte_ue_pdsch_vars[eNB_id]->rho,
                          lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                          lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
                          lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
                          lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0,
                          lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0,
                          symbol,
                          nb_rb,
709
                          rx_type==rx_IC_single_stream);
710 711
    }
  }
712

713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
  //  printf("Combining");
  if ((dlsch0_harq->mimo_mode == SISO) ||
      ((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) &&
       (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0))) {

    /*
      dlsch_siso(frame_parms,
      lte_ue_pdsch_vars[eNB_id]->rxdataF_comp,
      lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp,
      symbol,
      nb_rb);
    */
  } else if (dlsch0_harq->mimo_mode == ALAMOUTI) {

    dlsch_alamouti(frame_parms,
728 729 730 731 732
                   lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                   lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,
                   lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0,
                   symbol,
                   nb_rb);
733 734 735

  }

736
  //    printf("LLR");
737 738
  if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
      ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
739 740
       (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))  {
    rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
741
    dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round];
742 743
  }
  else {
744 745 746
    rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0;
    dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0;
    //i_mod should have been passed as a parameter
747
  }
748

749
  switch (dlsch0_harq->Qm) {
750
  case 2 :
751 752 753 754 755
    if (rx_type==rx_standard) {
        dlsch_qpsk_llr(frame_parms,
                       lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                       lte_ue_pdsch_vars[eNB_id]->llr[0],
                       symbol,first_symbol_flag,nb_rb,
756
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
757 758
                       lte_ue_pdsch_vars[eNB_id]->llr128);
    }
Elena Lukashova's avatar
Elena Lukashova committed
759
      else if (rx_type >= rx_IC_single_stream) {
Elena Lukashova's avatar
Elena Lukashova committed
760
        if (dlsch1_harq->Qm == 2) {
761 762 763
          dlsch_qpsk_qpsk_llr(frame_parms,
                              lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
                              rxdataF_comp_ptr,
764
                              lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext,
765 766
                              lte_ue_pdsch_vars[eNB_id]->llr[0],
                              symbol,first_symbol_flag,nb_rb,
Elena Lukashova's avatar
Elena Lukashova committed
767
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
768 769 770 771 772
                              lte_ue_pdsch_vars[eNB_id]->llr128);
          if (rx_type==rx_IC_dual_stream) {
            dlsch_qpsk_qpsk_llr(frame_parms,
                                rxdataF_comp_ptr,
                                lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,
773
                                lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
774 775
                                lte_ue_pdsch_vars[eNB_id]->llr[1],
                                symbol,first_symbol_flag,nb_rb,
776
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
777 778 779
                                lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream);
          }
        }