dlsch_demodulation.c 236 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22 23

/*! \file PHY/LTE_TRANSPORT/dlsch_demodulation.c
 * \brief Top-level routines for demodulating the PDSCH physical channel from 36-211, V8.6 2009-03
24
 * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert, X. Xiang
25
 * \date 2011
26
 * \version 0.1
27 28 29 30 31
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr,sebastien.aubert@eurecom.fr
 * \note
 * \warning
 */
32
//#include "PHY/defs.h"
33 34 35
#include "PHY/extern.h"
#include "defs.h"
#include "extern.h"
36
#include "PHY/sse_intrin.h"
Bilel's avatar
Bilel committed
37
#include "T.h"
38 39 40 41

#ifndef USER_MODE
#define NOCYGWIN_STATIC static
#else
42
#define NOCYGWIN_STATIC
43 44
#endif

45 46
//#define DEBUG_HARQ

Elena Lukashova's avatar
Elena Lukashova committed
47 48 49
//#undef LOG_D
//#define LOG_D LOG_I

50
//#define DEBUG_PHY 1
51
//#define DEBUG_DLSCH_DEMOD 1
52

53
int avg[4];
54 55
int avg_0[2];
int avg_1[2];
56 57

// [MCS][i_mod (0,1,2) = (2,4,6)]
58
unsigned char offset_mumimo_llr_drange_fix=0;
Elena Lukashova's avatar
Elena Lukashova committed
59 60 61
uint8_t interf_unaw_shift0=0;
uint8_t interf_unaw_shift1=0;
uint8_t interf_unaw_shift=0;
62
//inferference-free case
63
unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
64
                                             1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
65
unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
66
                                             0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
67

68 69 70
/*
//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
71 72
{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
73
*/
74 75 76 77 78 79 80 81
 /*
 //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
 */
82
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}};
83 84


85
extern void print_shorts(char *s,int16_t *x);
86

87

88
int rx_pdsch(PHY_VARS_UE *ue,
89 90
             PDSCH_t type,
             unsigned char eNB_id,
91
             unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
Bilel's avatar
Bilel committed
92
             uint32_t frame,
gauthier's avatar
gauthier committed
93
             uint8_t subframe,
94 95
             unsigned char symbol,
             unsigned char first_symbol_flag,
96
             RX_type_t rx_type,
97
             unsigned char i_mod,
98 99 100
             unsigned char harq_pid)
{

101 102 103
  LTE_UE_COMMON *common_vars  = &ue->common_vars;
  LTE_UE_PDSCH **pdsch_vars;
  LTE_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
104
  PHY_MEASUREMENTS *measurements = &ue->measurements;
105
  LTE_UE_DLSCH_t   **dlsch;
106

Elena Lukashova's avatar
Elena Lukashova committed
107

108
  unsigned char aatx,aarx;
109

110
  unsigned short nb_rb, round;
111
  int avgs, rb;
112
  LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
Elena Lukashova's avatar
Elena Lukashova committed
113

114
  uint8_t beamforming_mode;
115
  uint32_t *rballoc;
116

117 118
  int32_t **rxdataF_comp_ptr;
  int32_t **dl_ch_mag_ptr;
119 120 121 122
  int32_t codeword_TB0;
  int32_t codeword_TB1;


123

124 125
  switch (type) {
  case SI_PDSCH:
126
    pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
127 128
    dlsch = &ue->dlsch_SI[eNB_id];
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
129
    beamforming_mode  = 0;
130
    break;
131

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

139
  case PDSCH:
140
    pdsch_vars = &ue->pdsch_vars[subframe&0x1][eNB_id];
141 142 143 144 145 146 147
    dlsch = ue->dlsch[eNB_id];
    if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
        (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){
      codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
      codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
      dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
      dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
148 149 150
#ifdef DEBUG_HARQ
      printf("I am assuming both CW active\n");
#endif
151
    }
152 153 154 155 156 157
     else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
              (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
      codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      dlsch1_harq = NULL;
      codeword_TB1 = -1;
158
    }
159 160 161 162 163 164
     else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
              (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
      codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
      dlsch0_harq = dlsch[1]->harq_processes[harq_pid];
      dlsch1_harq = NULL;
      codeword_TB0 = -1;
165
    }
166
    beamforming_mode  = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
167 168 169
    break;

  default:
Cedric Roux's avatar
Cedric Roux committed
170
    LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].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 188
  if (!common_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null common_vars\n");
189 190 191
    return(-1);
  }

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

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

202
  if (!frame_parms) {
203
    LOG_W(PHY,"dlsch_demodulation.c: Null 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

213

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



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

Xiwen JIANG's avatar
Xiwen JIANG committed
229
  if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
230
#ifdef DEBUG_DLSCH_MOD
231
    LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]);
232
#endif
233

234 235
    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
                                   common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
236 237
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_ch_estimates_ext,
238
                                   dlsch0_harq->pmi_alloc,
239
                                   pdsch_vars[eNB_id]->pmi_ext,
240
                                   rballoc,
241 242
                                   symbol,
                                   subframe,
243
                                   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",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<ue->n_connected_eNB) // we are in TM5
255
      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
256
                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
257 258
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
259
                                       dlsch0_harq->pmi_alloc,
260
                                       pdsch_vars[eNB_id_i]->pmi_ext,
261
                                       rballoc,
262 263
                                       symbol,
                                       subframe,
264
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
265
                                       frame_parms,
266
                                       dlsch0_harq->mimo_mode);
267
      else
268 269
        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
270 271
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
272
                                       dlsch0_harq->pmi_alloc,
273
                                       pdsch_vars[eNB_id_i]->pmi_ext,
274
                                       rballoc,
275 276
                                       symbol,
                                       subframe,
277
                                       ue->high_speed_flag,
Elena Lukashova's avatar
Elena Lukashova committed
278
                                       frame_parms,
279
                                       dlsch0_harq->mimo_mode);
280
    }
281
  } else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
282 283
    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
                                     common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
284 285
                                     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);
293

Elena Lukashova's avatar
Elena Lukashova committed
294
   if (rx_type==rx_IC_single_stream) {
295
     if (eNB_id_i<ue->n_connected_eNB)
296 297
        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
298
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
299
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
300
                                         dlsch0_harq->pmi_alloc,
301
                                         pdsch_vars[eNB_id_i]->pmi_ext,
302
                                         rballoc,
303 304
                                         symbol,
                                         subframe,
305
                                         ue->high_speed_flag,
306
                                         frame_parms);
307
      else
308 309
        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
310
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
311
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
312
                                         dlsch0_harq->pmi_alloc,
313
                                         pdsch_vars[eNB_id_i]->pmi_ext,
314
                                         rballoc,
315 316
                                         symbol,
                                         subframe,
317
                                         ue->high_speed_flag,
318
                                         frame_parms);
319
    }
320
  } else if (beamforming_mode==7) { //else if beamforming_mode == 7
321
    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
322 323 324
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                  pdsch_vars[eNB_id]->rxdataF_ext,
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
325
                                  rballoc,
326 327
                                  symbol,
                                  subframe,
328
                                  ue->high_speed_flag,
329
                                  frame_parms);
330

331
  } else if(beamforming_mode>7) {
332
    LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
333
  }
334 335

  //  printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
336
  if (nb_rb==0) {
337
    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
338 339
    return(-1);
  }
340

Elena Lukashova's avatar
Elena Lukashova committed
341

342
#ifdef DEBUG_PHY
343 344
  LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
  LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
345 346
#endif

347
  aatx = frame_parms->nb_antenna_ports_eNB;
Elena Lukashova's avatar
Elena Lukashova committed
348 349
  aarx = frame_parms->nb_antennas_rx;

350
  dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
351 352 353 354
                      frame_parms,
                      dlsch,
                      symbol,
                      nb_rb);
355

356 357
  if ((dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) && (rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0))  // TM5 two-user
    dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
358
                        frame_parms,
359
                        dlsch,
360 361
                        symbol,
                        nb_rb);
362

363
  if (first_symbol_flag==1) {
364 365 366
    if (beamforming_mode==0){
      if (dlsch0_harq->mimo_mode<LARGE_CDD) {
        dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
367 368 369 370
                           frame_parms,
                           avg,
                           symbol,
                           nb_rb);
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
        avgs = 0;
        for (aatx=0;aatx<frame_parms->nb_antenna_ports_eNB;aatx++)
          for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
            avgs = cmax(avgs,avg[(aatx<<1)+aarx]);

        pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1;
     }
     else if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
           ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))
     {
      dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                 frame_parms,
                                 pdsch_vars[eNB_id]->pmi_ext,
                                 avg_0,
                                 avg_1,
                                 symbol,
                                 nb_rb,
                                 dlsch0_harq->mimo_mode);

        if (rx_type>rx_standard) {
          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;
          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-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 {
          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;
          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", lte_ue_pdsch_vars[eNB_id]->log2_maxh0);
          //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1);
        }
      }
      else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
        if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {
            dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                frame_parms,
                                pdsch_vars[eNB_id]->pmi_ext,
                                avg,
                                symbol,
                                nb_rb);
            avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1];
            pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0);
418

419 420
        }
        else if (dlsch0_harq->dl_power_off==1) { //TM6
421

422 423 424 425 426
          dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                   frame_parms,
                                   avg,
                                   symbol,
                                   nb_rb);
427

428 429 430 431
          avgs = 0;
          for (aatx=0;aatx<frame_parms->nb_antenna_ports_eNB;aatx++)
            for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
              avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
432

433 434
          pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
          pdsch_vars[eNB_id]->log2_maxh++;
435

436
        }
437
      }
438

439 440 441 442 443 444 445
    }
    else if (beamforming_mode==7)
       dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
                              frame_parms,
                              avg,
                              symbol,
                              nb_rb);
446
#ifdef DEBUG_PHY
447
    LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
jiangx's avatar
jiangx committed
448
    LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
449 450
#endif
  }
451

452 453 454 455 456 457 458
#if T_TRACER
    if (type == PDSCH)
    {
      T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id),  T_INT(0), T_INT(frame%1024), T_INT(subframe),
                               T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
    }
#endif
459

460 461
// Now channel compensation
  if (dlsch0_harq->mimo_mode<LARGE_CDD) {
462 463 464 465 466 467
    dlsch_channel_compensation(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,
                               (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
468 469 470
                               frame_parms,
                               symbol,
                               first_symbol_flag,
Elena Lukashova's avatar
Elena Lukashova committed
471
                               dlsch0_harq->Qm,
472
                               nb_rb,
473
                               pdsch_vars[eNB_id]->log2_maxh,
474
                               measurements); // log2_maxh+I0_shift
475
 /*if (symbol == 5) {
476
     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);
477
 } */
478
    if ((rx_type==rx_IC_single_stream) &&
479
        (eNB_id_i<ue->n_connected_eNB)) {
480
         dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
481 482 483 484 485
                                 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,
486 487 488 489 490
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 i_mod,
                                 nb_rb,
491
                                 pdsch_vars[eNB_id]->log2_maxh,
492
                                 measurements); // log2_maxh+I0_shift
493 494
#ifdef DEBUG_PHY
      if (symbol == 5) {
495
        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);
496
        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);
497
      }
498
#endif
499

500
      dlsch_dual_stream_correlation(frame_parms,
501 502
                                    symbol,
                                    nb_rb,
503 504
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
505
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
506
                                    pdsch_vars[eNB_id]->log2_maxh);
507
    }
508 509
  } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){
510
      dlsch_channel_compensation_TM34(frame_parms,
511
                                     pdsch_vars[eNB_id],
512
                                     measurements,
513 514 515
                                     eNB_id,
                                     symbol,
                                     dlsch0_harq->Qm,
Elena Lukashova's avatar
Elena Lukashova committed
516
                                     dlsch1_harq->Qm,
517 518 519
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
520
                                     nb_rb,
521
                                     pdsch_vars[eNB_id]->log2_maxh0,
522
                                     pdsch_vars[eNB_id]->log2_maxh1);
523
  /*   if (symbol == 5) {
524 525 526 527
     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
528
        } */
529
      // compute correlation between signal and interference channels (rho12 and rho21)
530
        dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
531 532
                                    symbol,
                                    nb_rb,
533 534
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
535 536 537
                                    pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                                    pdsch_vars[eNB_id]->log2_maxh0);
        //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] );
538
      //to be optimized (just take complex conjugate)
539
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
540 541
                                    symbol,
                                    nb_rb,
542
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
543
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
544 545
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    pdsch_vars[eNB_id]->log2_maxh1);
546
    //  printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext );
547
      //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh);
548
  /*     if (symbol == 5) {
549 550 551 552
     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
553
        } */
554

555 556 557
    } else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
        if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) {
          dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext,
558 559 560 561 562
                                      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,
563
                                      frame_parms,
564
                                      measurements,
565 566
                                      eNB_id,
                                      symbol,
567
                                      dlsch0_harq->Qm,
568
                                      nb_rb,
569
                                      pdsch_vars[eNB_id]->log2_maxh,
570
                                      dlsch0_harq->dl_power_off);
571

572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
        for (rb=0; rb<nb_rb; rb++) {
          switch(pdsch_vars[eNB_id]->pmi_ext[rb]) {
          case 0:
            pdsch_vars[eNB_id_i]->pmi_ext[rb]=1;
            break;
         case 1:
            pdsch_vars[eNB_id_i]->pmi_ext[rb]=0;
            break;
         case 2:
            pdsch_vars[eNB_id_i]->pmi_ext[rb]=3;
            break;
          case 3:
            pdsch_vars[eNB_id_i]->pmi_ext[rb]=2;
            break;
          }
Elena Lukashova's avatar
Elena Lukashova committed
587
       //  if (rb==0)
588
        //    printf("pmi %d, pmi_i %d\n",pdsch_vars[eNB_id]->pmi_ext[rb],pdsch_vars[eNB_id_i]->pmi_ext[rb]);
589
      }
590 591 592 593 594 595
      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,
596
                                      frame_parms,
597
                                      measurements,
598 599 600 601
                                      eNB_id_i,
                                      symbol,
                                      i_mod,
                                      nb_rb,
602
                                      pdsch_vars[eNB_id]->log2_maxh,
603
                                      dlsch0_harq->dl_power_off);
604 605
#ifdef DEBUG_PHY
      if (symbol==5) {
606
        write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
607
       write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
608
      }
609
#endif
610 611 612
      dlsch_dual_stream_correlation(frame_parms,
                                    symbol,
                                    nb_rb,
613 614 615 616
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    pdsch_vars[eNB_id]->log2_maxh);
617
    }  else if (dlsch0_harq->dl_power_off==1)  {
618 619 620 621 622 623
      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,
624
                                      frame_parms,
625
                                      measurements,
626 627
                                      eNB_id,
                                      symbol,
628
                                      dlsch0_harq->Qm,
629
                                      nb_rb,
630
                                      pdsch_vars[eNB_id]->log2_maxh,
631
                                      1);
Elena Lukashova's avatar
Elena Lukashova committed
632

633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
      }


    } else if (dlsch0_harq->mimo_mode==TM7) { //TM7

      dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
                                 pdsch_vars[eNB_id]->dl_bf_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,
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 get_Qm(dlsch0_harq->mcs),
                                 nb_rb,
                                 //9,
                                 pdsch_vars[eNB_id]->log2_maxh,
                                 measurements); // log2_maxh+I0_shift
652 653
  }

654 655 656 657
// MRC


   if (frame_parms->nb_antennas_rx > 1) {
658
    if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
659
        ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
660
         (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
Xiwen JIANG's avatar
Xiwen JIANG committed
661
      if (frame_parms->nb_antenna_ports_eNB == 2) {
662
        dlsch_detection_mrc_TM34(frame_parms,
663
                                 pdsch_vars[eNB_id],
664
                                 harq_pid,
665
                                 dlsch0_harq->round,
666 667 668
                                 symbol,
                                 nb_rb,
                                 1);
669
    /*   if (symbol == 5) {
670 671
     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
672
        } */
673
      }
674
    } else {
675
      dlsch_detection_mrc(frame_parms,
676 677 678
                          pdsch_vars[eNB_id]->rxdataF_comp0,
                          pdsch_vars[eNB_id_i]->rxdataF_comp0,
                          pdsch_vars[eNB_id]->rho,
679
                          pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
680 681 682 683
                          pdsch_vars[eNB_id]->dl_ch_mag0,
                          pdsch_vars[eNB_id]->dl_ch_magb0,
                          pdsch_vars[eNB_id_i]->dl_ch_mag0,
                          pdsch_vars[eNB_id_i]->dl_ch_magb0,
684 685
                          symbol,
                          nb_rb,
686
                          rx_type==rx_IC_single_stream);
687 688 689 690 691
    }
  }
  //  printf("Combining");
  if ((dlsch0_harq->mimo_mode == SISO) ||
      ((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) &&
692 693
       (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0)) ||
       (dlsch0_harq->mimo_mode == TM7)) {
694 695
    /*
      dlsch_siso(frame_parms,
696 697
      pdsch_vars[eNB_id]->rxdataF_comp,
      pdsch_vars[eNB_id_i]->rxdataF_comp,
698 699 700 701 702
      symbol,
      nb_rb);
    */
  } else if (dlsch0_harq->mimo_mode == ALAMOUTI) {
    dlsch_alamouti(frame_parms,
703 704 705
                   pdsch_vars[eNB_id]->rxdataF_comp0,
                   pdsch_vars[eNB_id]->dl_ch_mag0,
                   pdsch_vars[eNB_id]->dl_ch_magb0,
706 707
                   symbol,
                   nb_rb);
708 709
  }

710
  //    printf("LLR");
711 712
  if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
      ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
713
       (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))  {
714
    rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
715
    dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round];
716 717
  }
  else {
718 719
    rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0;
    dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0;
720
    //i_mod should have been passed as a parameter
721
  }
722

723
  switch (dlsch0_harq->Qm) {
724
  case 2 :
725
    if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
726
        dlsch_qpsk_llr(frame_parms,
727 728
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       pdsch_vars[eNB_id]->llr[0],
729 730 731
                       symbol,
                       first_symbol_flag,
                       nb_rb,
732
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
733
                       pdsch_vars[eNB_id]->llr128,
734
                       beamforming_mode);
735
    }
Elena Lukashova's avatar
Elena Lukashova committed
736
      else if (rx_type >= rx_IC_single_stream) {
Elena Lukashova's avatar
Elena Lukashova committed
737
        if (dlsch1_harq->Qm == 2) {
738
          dlsch_qpsk_qpsk_llr(frame_parms,
739
                              pdsch_vars[eNB_id]->rxdataF_comp0,
740
                              rxdataF_comp_ptr,
741 742
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                              pdsch_vars[eNB_id]->llr[0],
743
                              symbol,first_symbol_flag,nb_rb,
Elena Lukashova's avatar
Elena Lukashova committed
744
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
745
                              pdsch_vars[eNB_id]->llr128);
746