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 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
    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];
    }
     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;
    }
167 168 169
    break;

  default:
170
    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",phy_vars_ue->frame_rx,subframe,type);
171 172 173
    return(-1);
    break;
  }
174 175 176 177
#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
178

179 180
  DevAssert(dlsch0_harq);
  round = dlsch0_harq->round;
181

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

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

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

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

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

207 208 209 210 211
  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;
212

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



220 221 222 223 224 225 226 227 228 229
  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);

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

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

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

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

Elena Lukashova's avatar
Elena Lukashova committed
326

327 328 329 330 331
#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
332 333 334 335
  aatx = frame_parms->nb_antennas_tx_eNB;
  aarx = frame_parms->nb_antennas_rx;

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

337

338
     dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext,
339 340 341 342
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);
343

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

354
    avgs = 0;
355

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

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


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

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

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

401
      if (symbol == 5) {
402
        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);
403

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

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

423
    if (frame_parms->nb_antennas_tx_eNB == 2) {
424 425


426 427 428 429 430 431
         // 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);
432 433


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


446 447

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


450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
        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
471
        }
472
      }
473

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

488
  /*   if (symbol == 5) {
489

490 491 492 493 494
     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

495

496
        } */
Elena Lukashova's avatar
Elena Lukashova committed
497

498
      // compute correlation between signal and interference channels (rho12 and rho21)
499

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

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

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

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

522
  /*     if (symbol == 5) {
523

Elena Lukashova's avatar
Elena Lukashova committed
524 525 526 527 528
     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

529

530
        } */
531

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

      // Scale the channel estimates for interfering stream
543

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

550
      dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
551 552 553
                          frame_parms,
                          dlsch_ue,
                          symbol,
554
                          nb_rb);
555 556 557

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

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

567 568
        //    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];
569

570 571
        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);
572
      }
573

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

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

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

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

Elena Lukashova's avatar
Elena Lukashova committed
609
       //  if (rb==0)
610 611
        //    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]);

612
      }
613 614


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

Elena Lukashova's avatar
Elena Lukashova committed
630

631
#ifdef DEBUG_PHY
632

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

646
    }
647
    else if (dlsch0_harq->dl_power_off==1)  {
648

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

655
      if (first_symbol_flag==1) {
656 657

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

666
        avgs = 0;
Elena Lukashova's avatar
Elena Lukashova committed
667

668 669 670 671
        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
672

673 674
        lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
        lte_ue_pdsch_vars[eNB_id]->log2_maxh++;
675

676
      }
677 678


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

694 695 696 697
    }
  }

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

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


713
    /*   if (symbol == 5) {
714

Elena Lukashova's avatar
Elena Lukashova committed
715 716
     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
717
        } */
718 719


720
      }
721 722
    } else {

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

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

  }

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

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