dlsch_demodulation.c 194 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
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr,sebastien.aubert@eurecom.fr
 * \note
 * \warning
 */
40
//#include "PHY/defs.h"
41 42 43
#include "PHY/extern.h"
#include "defs.h"
#include "extern.h"
44
#include "PHY/sse_intrin.h"
45 46 47 48 49


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

53 54
//#define DEBUG_HARQ

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

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

61
int avg[4];
62 63
int avg_0[2];
int avg_1[2];
64 65

// [MCS][i_mod (0,1,2) = (2,4,6)]
66
unsigned char offset_mumimo_llr_drange_fix=0;
Elena Lukashova's avatar
Elena Lukashova committed
67 68 69
uint8_t interf_unaw_shift0=0;
uint8_t interf_unaw_shift1=0;
uint8_t interf_unaw_shift=0;
70
//inferference-free case
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,
72
                                             1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
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,
74
                                             0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
75

76 77 78
/*
//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
79 80
{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
81
*/
82 83 84 85 86 87 88 89
 /*
 //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
 */
90
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}};
91 92


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

95

96 97 98 99
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
100
             uint8_t subframe,
101 102
             unsigned char symbol,
             unsigned char first_symbol_flag,
103
             RX_type_t rx_type,
104
             unsigned char i_mod,
105 106 107
             unsigned char harq_pid)
{

108 109 110 111 112 113
  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
114

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

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

122 123
  int32_t **rxdataF_comp_ptr;
  int32_t **dl_ch_mag_ptr;
124 125 126 127
  int32_t codeword_TB0;
  int32_t codeword_TB1;


128

129 130 131 132
  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];
133
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
134
    break;
135

136 137 138
  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];
139
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
140
    break;
141

142
  case PDSCH:
143

144 145
    lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars[eNB_id];
    dlsch_ue          = phy_vars_ue->dlsch_ue[eNB_id];
146 147 148 149 150 151
    if ((dlsch_ue[0]->harq_processes[harq_pid]->status == ACTIVE) &&
        (dlsch_ue[1]->harq_processes[harq_pid]->status == ACTIVE)){
      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];
152 153 154
#ifdef DEBUG_HARQ
      printf("I am assuming both CW active\n");
#endif
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    }
     else if ((dlsch_ue[0]->harq_processes[harq_pid]->status == ACTIVE) &&
              (dlsch_ue[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
      codeword_TB0      = dlsch_ue[0]->harq_processes[harq_pid]->codeword;
      dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
      dlsch1_harq       = NULL;
      codeword_TB1      = -1;
    }
     else if ((dlsch_ue[0]->harq_processes[harq_pid]->status != ACTIVE) &&
              (dlsch_ue[1]->harq_processes[harq_pid]->status == ACTIVE) ){
      codeword_TB1      = dlsch_ue[1]->harq_processes[harq_pid]->codeword;
      dlsch0_harq       = dlsch_ue[1]->harq_processes[harq_pid];
      dlsch1_harq       = NULL;
      codeword_TB0      = -1;
    }
170 171 172
    break;

  default:
173
    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",phy_vars_ue->frame_rx,subframe,type);
174 175 176
    return(-1);
    break;
  }
177 178 179 180
#ifdef DEBUG_HARQ
  printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
  printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
#endif
181

182 183
  DevAssert(dlsch0_harq);
  round = dlsch0_harq->round;
184

185
  if (eNB_id > 2) {
jiangx's avatar
jiangx committed
186
    LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
187 188
    return(-1);
  }
189

190
  if (!lte_ue_common_vars) {
jiangx's avatar
jiangx committed
191
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_ue_common_vars\n");
192 193 194 195
    return(-1);
  }

  if (!dlsch_ue[0]) {
jiangx's avatar
jiangx committed
196
    LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
197 198 199 200
    return(-1);
  }

  if (!lte_ue_pdsch_vars) {
jiangx's avatar
jiangx committed
201
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_ue_pdsch_vars pointer\n");
202 203
    return(-1);
  }
204

205
  if (!frame_parms) {
jiangx's avatar
jiangx committed
206
    LOG_W(PHY,"dlsch_demodulation.c: Null lte_frame_parms\n");
207 208
    return(-1);
  }
209

210 211 212 213 214
  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;
215

Elena Lukashova's avatar
Elena Lukashova committed
216
  if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
217 218 219
    LOG_E(PHY,"This transmission mode is not yet supported!\n");
    return(-1);
  }
220 221 222



223 224 225 226 227 228 229 230 231 232
  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);

233 234
  if (frame_parms->nb_antennas_tx_eNB>1) {
    nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF,
235 236 237 238 239
                                   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,
240
                                   rballoc,
241 242 243
                                   symbol,
                                   subframe,
                                   phy_vars_ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
244
                                   frame_parms,
245
                                                           dlsch0_harq->mimo_mode);
246
//#ifdef DEBUG_DLSCH_MOD
247 248
    /*   printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc);
       for (rb=0;rb<nb_rb;rb++)
249
          printf("%d",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb]);
250
       printf("\n");*/
251
//#endif
252

Elena Lukashova's avatar
Elena Lukashova committed
253
   if (rx_type >= rx_IC_single_stream) {
254
      if (eNB_id_i<phy_vars_ue->n_connected_eNB) // we are in TM5
Elena Lukashova's avatar
Elena Lukashova committed
255
       nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF,
256 257 258 259 260
                                       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,
261
                                       rballoc,
262 263 264
                                       symbol,
                                       subframe,
                                       phy_vars_ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
265
                                       frame_parms,
266
                                                               dlsch0_harq->mimo_mode);
267
     else
Elena Lukashova's avatar
Elena Lukashova committed
268
       nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF,
269
                                       lte_ue_common_vars->dl_ch_estimates[eNB_id],
270 271
                                       lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
272
                                       dlsch0_harq->pmi_alloc,
273
                                       lte_ue_pdsch_vars[eNB_id_i]->pmi_ext,
274
                                       rballoc,
275 276 277
                                       symbol,
                                       subframe,
                                       phy_vars_ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
278
                                       frame_parms,
279
                                                               dlsch0_harq->mimo_mode);
280 281
    }
  } // if n_tx>1
282
  else {
283
    nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF,
284 285 286 287 288
                                     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,
289
                                     rballoc,
290 291 292 293
                                     symbol,
                                     subframe,
                                     phy_vars_ue->high_speed_flag,
                                     frame_parms);
Elena Lukashova's avatar
Elena Lukashova committed
294 295
   if (rx_type==rx_IC_single_stream) {
     if (eNB_id_i<phy_vars_ue->n_connected_eNB)
296 297 298
        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,
299
                                         lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
300 301
                                         dlsch0_harq->pmi_alloc,
                                         lte_ue_pdsch_vars[eNB_id_i]->pmi_ext,
302
                                         rballoc,
303 304 305 306
                                         symbol,
                                         subframe,
                                         phy_vars_ue->high_speed_flag,
                                         frame_parms);
Elena Lukashova's avatar
Elena Lukashova committed
307

308
      else
309 310 311
        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,
312
                                         lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
313 314
                                         dlsch0_harq->pmi_alloc,
                                         lte_ue_pdsch_vars[eNB_id_i]->pmi_ext,
315
                                         rballoc,
316 317 318 319
                                         symbol,
                                         subframe,
                                         phy_vars_ue->high_speed_flag,
                                         frame_parms);
320 321
    }
  } //else n_tx>1
322 323

  //  printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
324
  if (nb_rb==0) {
325
    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
326 327
    return(-1);
  }
328

Elena Lukashova's avatar
Elena Lukashova committed
329

330 331 332 333 334
#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
335 336 337 338
  aatx = frame_parms->nb_antennas_tx_eNB;
  aarx = frame_parms->nb_antennas_rx;

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

340

341
     dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
342 343 344 345
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);
346

347
      if (first_symbol_flag==1) {
348
        dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
349 350 351 352
                        frame_parms,
                        avg,
                        symbol,
                        nb_rb);
353 354 355 356
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif

357
    avgs = 0;
358

359 360
    for (aatx=0;aatx<frame_parms->nb_antennas_tx_eNB;aatx++)
      for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
361
        avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
362
    //  avgs = cmax(avgs,avg[(aarx<<1)+aatx]);
363

364
     lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs];
365
   // printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh);
366
      }
367 368


369
        dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
370 371 372 373 374 375 376 377
                               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
378
                               dlsch0_harq->Qm,
379 380 381
                               nb_rb,
                               lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                               phy_measurements); // log2_maxh+I0_shift
382

383
 /*if (symbol == 5) {
384
     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);
385
 } */
386
    if ((rx_type==rx_IC_single_stream) &&
387
        (eNB_id_i<phy_vars_ue->n_connected_eNB)) {
388

389
         dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext,
390 391 392 393 394 395 396 397 398 399 400 401
                                 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
402
#ifdef DEBUG_PHY
403

404
      if (symbol == 5) {
405
        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);
406

407
        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);
408
      }
409
#endif
Elena Lukashova's avatar
Elena Lukashova committed
410
     // compute correlation between signal and interference channels
411
      dlsch_dual_stream_correlation(frame_parms,
412 413 414 415 416 417
                                    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);
418
    }
419

420
  }
421 422
  else if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
           ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
423
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
424
    //   LOG_I(PHY,"Running PDSCH RX for TM3\n");
425

426
    if (frame_parms->nb_antennas_tx_eNB == 2) {
427 428


429 430 431 432 433 434
         // scaling interfering channel (following for TM56)
        dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                            frame_parms,
                            dlsch_ue,
                            symbol,
                            nb_rb);
435 436


437
      if (first_symbol_flag==1) {
438
        // effective channel of desired user is always stronger than interfering eff. channel
439
        dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
Elena Lukashova's avatar
Elena Lukashova committed
440
                                 frame_parms,
441
                                 lte_ue_pdsch_vars[eNB_id]->pmi_ext,
442
                                 avg_0,
443 444 445
                                 avg_1,
                                 symbol,
                                 nb_rb,
446
                                 dlsch0_harq->mimo_mode);
447 448


449 450

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


453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
        if (rx_type>rx_standard) {
        // Shifts are needed to avoid tails in SNR/BLER curves.
        // LUT will be introduced with mcs-dependent shift
        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;
        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);

        //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);

         }
        else {
        // Shifts are needed to avoid tails in SNR/BLER curves.
        // LUT will be introduced with mcs-dependent shift
        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;
        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);
        //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);
Elena Lukashova's avatar
Elena Lukashova committed
474
        }
475
      }
476

477
      dlsch_channel_compensation_TM34(frame_parms,
478
                                     lte_ue_pdsch_vars[eNB_id],
479 480 481 482
                                     phy_measurements,
                                     eNB_id,
                                     symbol,
                                     dlsch0_harq->Qm,
Elena Lukashova's avatar
Elena Lukashova committed
483
                                     dlsch1_harq->Qm,
484 485 486
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
487
                                     nb_rb,
488
                                     lte_ue_pdsch_vars[eNB_id]->log2_maxh0,
489
                                     lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
490

491
  /*   if (symbol == 5) {
492

493 494 495 496 497
     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

498

499
        } */
Elena Lukashova's avatar
Elena Lukashova committed
500

501
      // compute correlation between signal and interference channels (rho12 and rho21)
502

503
        dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
504 505 506
                                    symbol,
                                    nb_rb,
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
507
                                    &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
508
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext,
509
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
510

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

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

515
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
516 517
                                    symbol,
                                    nb_rb,
518
                                    &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
519
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
520 521
                                    lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
522
    //  printf("rho stream2 =%d\n",&lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext );
523
      //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh);
524

525
  /*     if (symbol == 5) {
526

Elena Lukashova's avatar
Elena Lukashova committed
527 528 529 530 531
     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

532

533
        } */
534

Elena Lukashova's avatar
Elena Lukashova committed
535
   }
536
      else {
Elena Lukashova's avatar
Elena Lukashova committed
537
     LOG_E(PHY, "only 2 tx antennas supported for TM3\n");
538
      return(-1);
539 540
    }
  }
541
  else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
Elena Lukashova's avatar
Elena Lukashova committed
542
   //    printf("Channel compensation for precoding\n");
543
    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
544 545

      // Scale the channel estimates for interfering stream
546

Elena Lukashova's avatar
Elena Lukashova committed
547 548 549 550
       dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                          frame_parms,
                          dlsch_ue,
                          symbol,
551
                          nb_rb);
552

553
      dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
554 555 556
                          frame_parms,
                          dlsch_ue,
                          symbol,
557
                          nb_rb);
558 559 560

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

562
        // effective channel of desired user is always stronger than interfering eff. channel
Elena Lukashova's avatar
Elena Lukashova committed
563
       dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
564 565 566 567 568
                                frame_parms,
                                lte_ue_pdsch_vars[eNB_id]->pmi_ext,
                                avg,
                                symbol,
                                nb_rb);
569

570 571
        //    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];
572

573 574
        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);
575
      }
576

577 578 579 580 581 582 583 584 585 586
      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,
587
                                      dlsch0_harq->Qm,
588 589
                                      nb_rb,
                                      lte_ue_pdsch_vars[eNB_id]->log2_maxh,
590
                                      dlsch0_harq->dl_power_off);
591 592 593 594

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

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

597 598 599 600
        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
601
       case 1:
602 603
          lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
          break;
Elena Lukashova's avatar
Elena Lukashova committed
604
       case 2:
605 606 607 608 609 610
          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;
        }
611

Elena Lukashova's avatar
Elena Lukashova committed
612
       //  if (rb==0)
613 614
        //    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]);

615
      }
616 617


618 619 620 621 622 623 624 625 626 627 628 629 630
      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,
631
                                      dlsch0_harq->dl_power_off);
632

Elena Lukashova's avatar
Elena Lukashova committed
633

634
#ifdef DEBUG_PHY
635

636
      if (symbol==5) {
637
        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
638
       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);
639
      }
640
#endif
641 642 643 644 645 646
      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],
647
                                    lte_ue_pdsch_vars[eNB_id]->log2_maxh);
648

649
    }
650
    else if (dlsch0_harq->dl_power_off==1)  {
651

Elena Lukashova's avatar
Elena Lukashova committed
652
        dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
653 654 655 656
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);
657

658
      if (first_symbol_flag==1) {
659 660

        dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
661 662 663 664
                            frame_parms,
                            avg,
                            symbol,
                            nb_rb);
665 666 667
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif
668

669
        avgs = 0;
Elena Lukashova's avatar
Elena Lukashova committed
670

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

676 677
        lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
        lte_ue_pdsch_vars[eNB_id]->log2_maxh++;
678

679
      }
680 681


682
      dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext,
683 684 685 686 687 688 689 690 691
                                      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,
692
                                      dlsch0_harq->Qm,
693 694 695
                                      nb_rb,
                                      lte_ue_pdsch_vars[eNB_id]->log2_maxh,
                                      1);
Elena Lukashova's avatar
Elena Lukashova committed
696

697 698 699 700
    }
  }

  //  printf("MRC\n");
701
  if (frame_parms->nb_antennas_rx > 1) {
702
    if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
703
        ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
704
         (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
705
      if (frame_parms->nb_antennas_tx_eNB == 2) {
Elena Lukashova's avatar
Elena Lukashova committed
706

707
        dlsch_detection_mrc_TM34(frame_parms,
708
                                 lte_ue_pdsch_vars[eNB_id],
709
                                 harq_pid,
710
                                 dlsch0_harq->round,
711 712 713
                                 symbol,
                                 nb_rb,
                                 1);
714 715


716
    /*   if (symbol == 5) {
717

Elena Lukashova's avatar
Elena Lukashova committed
718 719
     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
720
        } */
721 722


723
      }
724 725
    } else {

726
      dlsch_detection_mrc(frame_parms,
727 728 729 730 731 732 733 734 735 736
                          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,
737
                          rx_type==rx_IC_single_stream);
738 739
    }
  }
740

741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
  //  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,
756 757 758 759 760
                   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);
761 762 763

  }

764
  //    printf("LLR");
765 766
  if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
      ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
767 768
       (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))  {
    rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
769
    dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round];
770 771
  }
  else {
772 773 774
    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
775
  }
776

777
  switch (dlsch0_harq->Qm) {
778
  case 2 :
779
    if ((rx_type==rx_standard) || (codeword_TB0 = 1)) {
780 781 782 783
        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,
784
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
785 786
                       lte_ue_pdsch_vars[eNB_id]->llr128);
    }
Elena Lukashova's avatar
Elena Lukashova committed
787
      else if (rx_type >= rx_IC_single_stream) {
Elena Lukashova's avatar
Elena Lukashova committed
788
        if (dlsch1_harq->Qm == 2) {
Florian Kaltenberger's avatar