dlsch_demodulation.c 235 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[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 236 237
    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,
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 255
      if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
256 257 258
                                       common_vars->dl_ch_estimates[eNB_id_i],
                                       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
       nb_rb = dlsch_extract_rbs_dual(common_vars->rxdataF,
269 270 271
                                       common_vars->dl_ch_estimates[eNB_id],
                                       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 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 if (beamforming_mode==7) { //else if beamforming_mode == 7
320 321 322 323
    nb_rb = dlsch_extract_rbs_TM7(common_vars->rxdataF,
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                  pdsch_vars[eNB_id]->rxdataF_ext,
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
324
                                  rballoc,
325 326
                                  symbol,
                                  subframe,
327
                                  ue->high_speed_flag,
328
                                  frame_parms);
329

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

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

Elena Lukashova's avatar
Elena Lukashova committed
340

341
#ifdef DEBUG_PHY
342 343
  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);
344 345
#endif

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

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

355 356
  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,
357
                        frame_parms,
358
                        dlsch,
359 360
                        symbol,
                        nb_rb);
361

362
  if (first_symbol_flag==1) {
363 364 365
    if (beamforming_mode==0){
      if (dlsch0_harq->mimo_mode<LARGE_CDD) {
        dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
366 367 368 369
                           frame_parms,
                           avg,
                           symbol,
                           nb_rb);
370 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
        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);
417

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

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

427 428 429 430
          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]);
431

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

435
        }
436
      }
437

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

451 452 453 454 455 456 457
#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
458

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

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

554 555 556
    } 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,
557 558 559 560 561
                                      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,
562
                                      frame_parms,
563
                                      measurements,
564 565
                                      eNB_id,
                                      symbol,
566
                                      dlsch0_harq->Qm,
567
                                      nb_rb,
568
                                      pdsch_vars[eNB_id]->log2_maxh,
569
                                      dlsch0_harq->dl_power_off);
570

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

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


    } 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
651 652
  }

653 654 655 656
// MRC


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

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

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