dlsch_demodulation.c 191 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
int rx_pdsch(PHY_VARS_UE *ue,
97 98
             PDSCH_t type,
             unsigned char eNB_id,
99
             unsigned char eNB_id_i, //if this == 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
  LTE_UE_COMMON *common_vars  = &ue->common_vars;
  LTE_UE_PDSCH **pdsch_vars;
  LTE_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
111
  PHY_MEASUREMENTS *measurements = &ue->measurements;
112 113
  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
  switch (type) {
  case SI_PDSCH:
131
    pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
132
    dlsch_ue          = &ue->dlsch_SI[eNB_id];
133
    dlsch0_harq       = dlsch_ue[0]->harq_processes[harq_pid];
134
    break;
135

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

142
  case PDSCH:
143
    pdsch_vars = &ue->pdsch_vars[eNB_id];
144
    dlsch_ue          = ue->dlsch[eNB_id];
145 146 147 148 149 150
    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];
151 152 153
#ifdef DEBUG_HARQ
      printf("I am assuming both CW active\n");
#endif
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    }
     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;
    }
169 170 171
    break;

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

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

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

189 190
  if (!common_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null common_vars\n");
191 192 193 194
    return(-1);
  }

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

199 200
  if (!pdsch_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n");
201 202
    return(-1);
  }
203

204
  if (!frame_parms) {
205
    LOG_W(PHY,"dlsch_demodulation.c: Null frame_parms\n");
206 207
    return(-1);
  }
208

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

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



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

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

Elena Lukashova's avatar
Elena Lukashova committed
252
   if (rx_type >= rx_IC_single_stream) {
253 254
      if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
255 256 257
                                       common_vars->dl_ch_estimates[eNB_id_i],
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
258
                                       dlsch0_harq->pmi_alloc,
259
                                       pdsch_vars[eNB_id_i]->pmi_ext,
260
                                       rballoc,
261 262
                                       symbol,
                                       subframe,
263
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
264
                                       frame_parms,
265
                                       dlsch0_harq->mimo_mode);
266
     else
267
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
268 269 270
                                       common_vars->dl_ch_estimates[eNB_id],
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
271
                                       dlsch0_harq->pmi_alloc,
272
                                       pdsch_vars[eNB_id_i]->pmi_ext,
273
                                       rballoc,
274 275
                                       symbol,
                                       subframe,
276
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
277
                                       frame_parms,
278
                                       dlsch0_harq->mimo_mode);
279 280
    }
  } // if n_tx>1
281
  else {
282 283 284 285
    nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                     common_vars->dl_ch_estimates[eNB_id],
                                     pdsch_vars[eNB_id]->rxdataF_ext,
                                     pdsch_vars[eNB_id]->dl_ch_estimates_ext,
286
                                     dlsch0_harq->pmi_alloc,
287
                                     pdsch_vars[eNB_id]->pmi_ext,
288
                                     rballoc,
289 290
                                     symbol,
                                     subframe,
291
                                     ue->high_speed_flag,
292
                                     frame_parms);
Elena Lukashova's avatar
Elena Lukashova committed
293
   if (rx_type==rx_IC_single_stream) {
294
     if (eNB_id_i<ue->n_connected_eNB)
295 296 297
        nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                         common_vars->dl_ch_estimates[eNB_id_i],
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
298
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
299
                                         dlsch0_harq->pmi_alloc,
300
                                         pdsch_vars[eNB_id_i]->pmi_ext,
301
                                         rballoc,
302 303
                                         symbol,
                                         subframe,
304
                                         ue->high_speed_flag,
305
                                         frame_parms);
306
      else
307 308 309
        nb_rb = dlsch_extract_rbs_single(common_vars->rxdataF,
                                         common_vars->dl_ch_estimates[eNB_id],
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
310
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
311
                                         dlsch0_harq->pmi_alloc,
312
                                         pdsch_vars[eNB_id_i]->pmi_ext,
313
                                         rballoc,
314 315
                                         symbol,
                                         subframe,
316
                                         ue->high_speed_flag,
317
                                         frame_parms);
318 319
    }
  } //else n_tx>1
320 321

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

Elena Lukashova's avatar
Elena Lukashova committed
327

328
#ifdef DEBUG_PHY
329
    LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
330 331 332
    LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
#endif

Elena Lukashova's avatar
Elena Lukashova committed
333 334 335 336
  aatx = frame_parms->nb_antennas_tx_eNB;
  aarx = frame_parms->nb_antennas_rx;

  if (dlsch0_harq->mimo_mode<LARGE_CDD) {// SISO or ALAMOUTI
337
     dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
338 339 340 341
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);
342

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

353
    avgs = 0;
354

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

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

364
        dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
365 366 367 368 369
                               pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               pdsch_vars[eNB_id]->dl_ch_magb0,
                               pdsch_vars[eNB_id]->rxdataF_comp0,
                               (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
370 371 372
                               frame_parms,
                               symbol,
                               first_symbol_flag,
Elena Lukashova's avatar
Elena Lukashova committed
373
                               dlsch0_harq->Qm,
374
                               nb_rb,
375
                               pdsch_vars[eNB_id]->log2_maxh,
376
                               measurements); // log2_maxh+I0_shift
377
 /*if (symbol == 5) {
378
     write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
379
 } */
380

381
    if ((rx_type==rx_IC_single_stream) &&
382
        (eNB_id_i<ue->n_connected_eNB)) {
383 384

         dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
385 386 387 388 389
                                 pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                 pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                 pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                 pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                 (aatx>1) ? pdsch_vars[eNB_id_i]->rho : NULL,
390 391 392 393 394
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 i_mod,
                                 nb_rb,
395
                                 pdsch_vars[eNB_id]->log2_maxh,
396
                                 measurements); // log2_maxh+I0_shift
397
#ifdef DEBUG_PHY
398

399
      if (symbol == 5) {
400
        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
401
        write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
402
      }
403
#endif
Elena Lukashova's avatar
Elena Lukashova committed
404
     // compute correlation between signal and interference channels
405
      dlsch_dual_stream_correlation(frame_parms,
406 407
                                    symbol,
                                    nb_rb,
408 409
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
410
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
411
                                    pdsch_vars[eNB_id]->log2_maxh);
412
    }
413

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

420
    if (frame_parms->nb_antennas_tx_eNB == 2) {
421
         // scaling interfering channel (following for TM56)
422
        dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
423 424 425 426
                            frame_parms,
                            dlsch_ue,
                            symbol,
                            nb_rb);
427 428


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


441 442

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

444 445 446 447 448
        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;
449 450
        pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
        pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
451

452 453
        //printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
        //printf("TM4 I-A log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
454 455 456 457 458 459 460

         }
        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;
461 462 463 464
        pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
        pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
        //printf("TM4 I-UA log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
        //printf("TM4 I-UA log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
Elena Lukashova's avatar
Elena Lukashova committed
465
        }
466
      }
467

468
      dlsch_channel_compensation_TM34(frame_parms,
469
                                     pdsch_vars[eNB_id],
470
                                     measurements,
471 472 473
                                     eNB_id,
                                     symbol,
                                     dlsch0_harq->Qm,
Elena Lukashova's avatar
Elena Lukashova committed
474
                                     dlsch1_harq->Qm,
475 476 477
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
478
                                     nb_rb,
479
                                     pdsch_vars[eNB_id]->log2_maxh0,
480
                                     pdsch_vars[eNB_id]->log2_maxh1);
481

482
  /*   if (symbol == 5) {
483

484 485 486 487
     write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
488

489
        } */
Elena Lukashova's avatar
Elena Lukashova committed
490

491
      // compute correlation between signal and interference channels (rho12 and rho21)
492

493
        dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
494 495
                                    symbol,
                                    nb_rb,
496 497
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
498 499
                                    pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                                    pdsch_vars[eNB_id]->log2_maxh0);
500

501
        //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] );
502 503

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

505
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
506 507
                                    symbol,
                                    nb_rb,
508
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
509
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
510 511
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    pdsch_vars[eNB_id]->log2_maxh1);
512
    //  printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext );
513
      //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh);
514

515
  /*     if (symbol == 5) {
516

517 518 519 520
     write_output("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
     write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM
521
        } */
522

Elena Lukashova's avatar
Elena Lukashova committed
523
   }
524
      else {
Elena Lukashova's avatar
Elena Lukashova committed
525
     LOG_E(PHY, "only 2 tx antennas supported for TM3\n");
526
      return(-1);
527 528
    }
  }
529
  else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
Elena Lukashova's avatar
Elena Lukashova committed
530
   //    printf("Channel compensation for precoding\n");
531
    if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {  // TM5 two-user
532 533

      // Scale the channel estimates for interfering stream
534
       dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
Elena Lukashova's avatar
Elena Lukashova committed
535 536 537
                          frame_parms,
                          dlsch_ue,
                          symbol,
538
                          nb_rb);
539

540
      dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
541 542 543
                          frame_parms,
                          dlsch_ue,
                          symbol,
544
                          nb_rb);
545 546 547

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

549
        // effective channel of desired user is always stronger than interfering eff. channel
550
       dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
551
                                frame_parms,
552
                                pdsch_vars[eNB_id]->pmi_ext,
553 554 555
                                avg,
                                symbol,
                                nb_rb);
556

557 558
        //    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];
559

560 561
        pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
        //printf("log1_maxh =%d\n",pdsch_vars[eNB_id]->log2_maxh);
562
      }
563

564 565 566 567 568 569
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id]->dl_ch_mag0,
                                      pdsch_vars[eNB_id]->dl_ch_magb0,
                                      pdsch_vars[eNB_id]->rxdataF_comp0,
                                      pdsch_vars[eNB_id]->pmi_ext,
570
                                      frame_parms,
571
                                      measurements,
572 573
                                      eNB_id,
                                      symbol,
574
                                      dlsch0_harq->Qm,
575
                                      nb_rb,
576
                                      pdsch_vars[eNB_id]->log2_maxh,
577
                                      dlsch0_harq->dl_power_off);
578 579 580 581

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

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

584
        switch(pdsch_vars[eNB_id]->pmi_ext[rb]) {
585
        case 0:
586
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
587
          break;
Elena Lukashova's avatar
Elena Lukashova committed
588
       case 1:
589
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
590
          break;
Elena Lukashova's avatar
Elena Lukashova committed
591
       case 2:
592
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
593 594
          break;
        case 3:
595
          pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
596 597
          break;
        }
598

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

602
      }
603

604 605 606 607 608 609
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id_i]->rxdataF_ext,
                                      pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id_i]->dl_ch_mag0,
                                      pdsch_vars[eNB_id_i]->dl_ch_magb0,
                                      pdsch_vars[eNB_id_i]->rxdataF_comp0,
                                      pdsch_vars[eNB_id_i]->pmi_ext,
610
                                      frame_parms,
611
                                      measurements,
612 613 614 615
                                      eNB_id_i,
                                      symbol,
                                      i_mod,
                                      nb_rb,
616
                                      pdsch_vars[eNB_id]->log2_maxh,
617
                                      dlsch0_harq->dl_power_off);
618

Elena Lukashova's avatar
Elena Lukashova committed
619

620
#ifdef DEBUG_PHY
621

622
      if (symbol==5) {
623
        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
624
       write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
625
      }
626
#endif
627

628 629 630
      dlsch_dual_stream_correlation(frame_parms,
                                    symbol,
                                    nb_rb,
631 632 633 634
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    pdsch_vars[eNB_id]->log2_maxh);
635
    }
636
    else if (dlsch0_harq->dl_power_off==1)  {
637

638
        dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
639 640 641 642
                          frame_parms,
                          dlsch_ue,
                          symbol,
                          nb_rb);
643

644
      if (first_symbol_flag==1) {
645
              dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
646 647 648 649
                            frame_parms,
                            avg,
                            symbol,
                            nb_rb);
650 651 652
#ifdef DEBUG_PHY
    LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]);
#endif
653

654
        avgs = 0;
Elena Lukashova's avatar
Elena Lukashova committed
655

656 657 658 659
        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
660

661 662
        pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
        pdsch_vars[eNB_id]->log2_maxh++;
663
      }
664 665 666 667 668 669
      dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      pdsch_vars[eNB_id]->dl_ch_mag0,
                                      pdsch_vars[eNB_id]->dl_ch_magb0,
                                      pdsch_vars[eNB_id]->rxdataF_comp0,
                                      pdsch_vars[eNB_id]->pmi_ext,
670
                                      frame_parms,
671
                                      measurements,
672 673
                                      eNB_id,
                                      symbol,
674
                                      dlsch0_harq->Qm,
675
                                      nb_rb,
676
                                      pdsch_vars[eNB_id]->log2_maxh,
677
                                      1);
Elena Lukashova's avatar
Elena Lukashova committed
678

679 680 681 682
    }
  }

  //  printf("MRC\n");
683
  if (frame_parms->nb_antennas_rx > 1) {
684
    if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
685
        ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
686
         (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
687
      if (frame_parms->nb_antennas_tx_eNB == 2) {
688
        dlsch_detection_mrc_TM34(frame_parms,
689
                                 pdsch_vars[eNB_id],
690
                                 harq_pid,
691
                                 dlsch0_harq->round,
692 693 694
                                 symbol,
                                 nb_rb,
                                 1);
695 696


697
    /*   if (symbol == 5) {
698

699 700
     write_output("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM
     write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0