dlsch_demodulation.c 248 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
#include "PHY/extern.h"
34
#include "SCHED/defs.h"
35 36
#include "defs.h"
#include "extern.h"
37
#include "PHY/sse_intrin.h"
38
#include "T.h"
39 40 41 42

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

46 47 48 49 50
/* dynamic shift for LLR computation for TM3/4
 * set as command line argument, see lte-softmodem.c
 * default value: 0
 */
int16_t dlsch_demod_shift = 0;
Cedric Roux's avatar
Cedric Roux committed
51
int16_t interf_unaw_shift = 13;
52

53 54
//#define DEBUG_HARQ

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

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

hbilel's avatar
hbilel committed
61

62 63

// [MCS][i_mod (0,1,2) = (2,4,6)]
64
unsigned char offset_mumimo_llr_drange_fix=0;
65
//inferference-free case
66
unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
67
                                             1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
68
unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
69
                                             0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
70

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


88
extern void print_shorts(char *s,int16_t *x);
89

90

91
int rx_pdsch(PHY_VARS_UE *ue,
92
             UE_rxtx_proc_t *proc,
93 94
             PDSCH_t type,
             unsigned char eNB_id,
95
             unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
96
             uint32_t frame,
97
             uint8_t subframe,
98 99
             unsigned char symbol,
             unsigned char first_symbol_flag,
100
             RX_type_t rx_type,
101
             unsigned char i_mod,
102 103 104
             unsigned char harq_pid)
{

105 106 107
  LTE_UE_COMMON *common_vars  = &ue->common_vars;
  LTE_UE_PDSCH **pdsch_vars;
  LTE_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
108
  PHY_MEASUREMENTS *measurements = &ue->measurements;
109
  LTE_UE_DLSCH_t   **dlsch;
110

hbilel's avatar
hbilel committed
111 112 113
  int avg[4];
  int avg_0[2];
  int avg_1[2];
lukashov's avatar
lukashov committed
114

fnabet's avatar
fnabet committed
115
#if UE_TIMING_TRACE
116
  uint8_t slot = 0;
fnabet's avatar
fnabet committed
117
#endif
118

119
  unsigned char aatx,aarx;
120

121
  unsigned short nb_rb = 0, round;
122
  int avgs = 0, rb;
123
  LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
lukashov's avatar
lukashov committed
124

125
  uint8_t beamforming_mode;
126
  uint32_t *rballoc;
127

128 129
  int32_t **rxdataF_comp_ptr;
  int32_t **dl_ch_mag_ptr;
Cedric Roux's avatar
Cedric Roux committed
130 131
  int32_t codeword_TB0 = -1;
  int32_t codeword_TB1 = -1;
132 133


134

135 136
  switch (type) {
  case SI_PDSCH:
137
    pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
138 139
    dlsch = &ue->dlsch_SI[eNB_id];
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
140
    beamforming_mode  = 0;
141
    break;
142

143
  case RA_PDSCH:
144
    pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
145 146
    dlsch = &ue->dlsch_ra[eNB_id];
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
147
    beamforming_mode  = 0;
148
    break;
149

150
  case PDSCH:
151 152
    pdsch_vars = ue->pdsch_vars[subframe%RX_NB_TH];
    dlsch = ue->dlsch[subframe%RX_NB_TH][eNB_id];
153
    //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
hbilel's avatar
hbilel committed
154 155 156 157 158
    LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d,  harq status %d.%d \n",
                   frame,subframe,symbol,harq_pid,
                   dlsch[0]->harq_processes[harq_pid]->status,
                   dlsch[1]->harq_processes[harq_pid]->status);

159 160 161 162 163 164
    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];
165 166 167
#ifdef DEBUG_HARQ
      printf("[DEMOD] I am assuming both TBs are active\n");
#endif
168
    }
169 170 171 172 173 174
     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;
175 176 177
#ifdef DEBUG_HARQ
      printf("[DEMOD] I am assuming only TB0 is active\n");
#endif
178
    }
179 180 181
     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;
hbilel's avatar
hbilel committed
182 183
      dlsch0_harq  = dlsch[1]->harq_processes[harq_pid];
      dlsch1_harq  = NULL;
184
      codeword_TB0 = -1;
185
#ifdef DEBUG_HARQ
186
      printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword);
187
#endif
188
    }
189 190 191 192
    else {
      LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe);
      return(-1);
    }
193
    beamforming_mode  = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
194 195 196
    break;

  default:
Cedric Roux's avatar
Cedric Roux committed
197
    LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,subframe,type);
198 199 200
    return(-1);
    break;
  }
201 202 203 204
#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
205

206 207
  DevAssert(dlsch0_harq);
  round = dlsch0_harq->round;
208
  //printf("round = %d\n", round);
209

210
  if (eNB_id > 2) {
jiangx's avatar
jiangx committed
211
    LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
212 213
    return(-1);
  }
214

215 216
  if (!common_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null common_vars\n");
217 218 219
    return(-1);
  }

220
  if (!dlsch[0]) {
jiangx's avatar
jiangx committed
221
    LOG_W(PHY,"dlsch_demodulation.c: Null dlsch_ue pointer\n");
222 223 224
    return(-1);
  }

225 226
  if (!pdsch_vars) {
    LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n");
227 228
    return(-1);
  }
229

230
  if (!frame_parms) {
231
    LOG_W(PHY,"dlsch_demodulation.c: Null frame_parms\n");
232 233
    return(-1);
  }
234

235 236 237 238 239
  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;
240

241

lukashov's avatar
lukashov committed
242
  if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) {
243 244 245
    LOG_E(PHY,"This transmission mode is not yet supported!\n");
    return(-1);
  }
246 247


248 249 250 251 252 253 254
  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);
    }
  }
255

fnabet's avatar
fnabet committed
256
#if UE_TIMING_TRACE
257 258 259 260
  if(symbol > ue->frame_parms.symbols_per_tti>>1)
  {
      slot = 1;
  }
fnabet's avatar
fnabet committed
261 262
#endif

263 264 265
#ifdef DEBUG_HARQ
  printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
#endif
266

Xiwen JIANG's avatar
Xiwen JIANG committed
267
  if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
268
#ifdef DEBUG_DLSCH_MOD
269
    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]);
270
#endif
271

272 273 274
#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
275 276
    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                   common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
277 278
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_ch_estimates_ext,
279
                                   dlsch0_harq->pmi_alloc,
280
                                   pdsch_vars[eNB_id]->pmi_ext,
281
                                   rballoc,
282 283
                                   symbol,
                                   subframe,
284
                                   ue->high_speed_flag,
lukashov's avatar
lukashov committed
285
                                   frame_parms,
286
                                   dlsch0_harq->mimo_mode);
gabrielC's avatar
gabrielC committed
287 288
#ifdef DEBUG_DLSCH_MOD
      printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc);
289
       for (rb=0;rb<nb_rb;rb++)
290
          printf("%d",pdsch_vars[eNB_id]->pmi_ext[rb]);
gabrielC's avatar
gabrielC committed
291 292
       printf("\n");
#endif
293

lukashov's avatar
lukashov committed
294
   if (rx_type >= rx_IC_single_stream) {
295
      if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
296 297
      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                       common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id_i],
298 299
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       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,
lukashov's avatar
lukashov committed
306
                                       frame_parms,
307
                                       dlsch0_harq->mimo_mode);
308
      else
309 310
        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                       common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
311 312
                                       pdsch_vars[eNB_id_i]->rxdataF_ext,
                                       pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
313
                                       dlsch0_harq->pmi_alloc,
314
                                       pdsch_vars[eNB_id_i]->pmi_ext,
315
                                       rballoc,
316 317
                                       symbol,
                                       subframe,
318
                                       ue->high_speed_flag,
lukashov's avatar
lukashov committed
319
                                       frame_parms,
320
                                       dlsch0_harq->mimo_mode);
321
    }
322
  } else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
323 324
    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                     common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
325 326
                                     pdsch_vars[eNB_id]->rxdataF_ext,
                                     pdsch_vars[eNB_id]->dl_ch_estimates_ext,
327
                                     dlsch0_harq->pmi_alloc,
328
                                     pdsch_vars[eNB_id]->pmi_ext,
329
                                     rballoc,
330 331
                                     symbol,
                                     subframe,
332
                                     ue->high_speed_flag,
333
                                     frame_parms);
334

lukashov's avatar
lukashov committed
335
   if (rx_type==rx_IC_single_stream) {
336
     if (eNB_id_i<ue->n_connected_eNB)
337 338
        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                         common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id_i],
339
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
340
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
341
                                         dlsch0_harq->pmi_alloc,
342
                                         pdsch_vars[eNB_id_i]->pmi_ext,
343
                                         rballoc,
344 345
                                         symbol,
                                         subframe,
346
                                         ue->high_speed_flag,
347
                                         frame_parms);
348
      else
349 350
        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
                                         common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id],
351
                                         pdsch_vars[eNB_id_i]->rxdataF_ext,
352
                                         pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
353
                                         dlsch0_harq->pmi_alloc,
354
                                         pdsch_vars[eNB_id_i]->pmi_ext,
355
                                         rballoc,
356 357
                                         symbol,
                                         subframe,
358
                                         ue->high_speed_flag,
359
                                         frame_parms);
360
    }
361
  } else if (beamforming_mode==7) { //else if beamforming_mode == 7
362
    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF,
363 364 365
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                  pdsch_vars[eNB_id]->rxdataF_ext,
                                  pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
366
                                  rballoc,
367 368
                                  symbol,
                                  subframe,
369
                                  ue->high_speed_flag,
370
                                  frame_parms);
371

372
  } else if(beamforming_mode>7) {
373
    LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
374
  }
375

hbilel's avatar
hbilel committed
376
  //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id);
377
  if (nb_rb==0) {
378
    LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n");
379 380
    return(-1);
  }
381

382 383 384 385 386 387 388 389 390
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,
            symbol,ue->high_speed_flag,type,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction  %5.2f \n",frame,subframe,slot,symbol,
            ue->high_speed_flag,type,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
391 392
#endif

393 394 395
#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
396
  aatx = frame_parms->nb_antenna_ports_eNB;
lukashov's avatar
lukashov committed
397 398
  aarx = frame_parms->nb_antennas_rx;

399
  dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
400 401 402 403
                      frame_parms,
                      dlsch,
                      symbol,
                      nb_rb);
404

405 406 407 408 409 410
  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
  {
411
    dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
412
                        frame_parms,
413
                        dlsch,
414 415
                        symbol,
                        nb_rb);
416
  }
417

418 419 420 421 422 423 424 425 426 427 428 429
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
#endif

#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
430
  if (first_symbol_flag==1) {
431 432 433
    if (beamforming_mode==0){
      if (dlsch0_harq->mimo_mode<LARGE_CDD) {
        dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
434 435 436 437
                           frame_parms,
                           avg,
                           symbol,
                           nb_rb);
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        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);

Cedric Roux's avatar
Cedric Roux committed
458
      LOG_D(PHY,"Channel Level TM34  avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0],
459
              avg_1[0], rx_type, rx_standard, dlsch_demod_shift);
460
        if (rx_type>rx_standard) {
461 462
          avg_0[0] = (log2_approx(avg_0[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
          avg_1[0] = (log2_approx(avg_1[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
463 464
          pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
          pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
465
         // printf("dlsch_demod_shift  %d\n", dlsch_demod_shift);
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
         }
          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);
        }
      }
      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);
484

485 486
        }
        else if (dlsch0_harq->dl_power_off==1) { //TM6
487

488 489 490 491 492
          dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                   frame_parms,
                                   avg,
                                   symbol,
                                   nb_rb);
493

494 495 496 497
          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]);
498

499 500
          pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
          pdsch_vars[eNB_id]->log2_maxh++;
501

502
        }
503
      }
504

505 506 507 508 509 510 511
    }
    else if (beamforming_mode==7)
       dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
                              frame_parms,
                              avg,
                              symbol,
                              nb_rb);
gabrielC's avatar
gabrielC committed
512
#ifdef UE_DEBUG_TRACE
gabrielC's avatar
gabrielC committed
513
    LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
gabrielC's avatar
gabrielC committed
514
            frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh,
hbilel's avatar
hbilel committed
515 516 517
                                                 pdsch_vars[eNB_id]->log2_maxh0,
                                                 pdsch_vars[eNB_id]->log2_maxh1,
                                                 avg[0],avgs);
gabrielC's avatar
gabrielC committed
518
    //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
519
#endif
520 521 522 523 524 525 526 527 528 529

    //wait until pdcch is decoded
    proc->channel_level = 1;
  }

  uint32_t wait = 0;
  while(proc->channel_level == 0)
  {
      usleep(1);
      wait++;
530
  }
531

532 533 534 535 536 537 538
#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
539

540 541 542 543 544 545 546 547 548 549 550 551 552
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
#endif


#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
553 554
// Now channel compensation
  if (dlsch0_harq->mimo_mode<LARGE_CDD) {
555 556 557 558 559 560
    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,
561 562 563
                               frame_parms,
                               symbol,
                               first_symbol_flag,
lukashov's avatar
lukashov committed
564
                               dlsch0_harq->Qm,
565
                               nb_rb,
566
                               pdsch_vars[eNB_id]->log2_maxh,
567
                               measurements); // log2_maxh+I0_shift
lukashov's avatar
lukashov committed
568
 /*if (symbol == 5) {
569
     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);
lukashov's avatar
lukashov committed
570
 } */
571
    if ((rx_type==rx_IC_single_stream) &&
572
        (eNB_id_i<ue->n_connected_eNB)) {
573
         dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext,
574 575 576 577 578
                                 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,
579 580 581 582 583
                                 frame_parms,
                                 symbol,
                                 first_symbol_flag,
                                 i_mod,
                                 nb_rb,
584
                                 pdsch_vars[eNB_id]->log2_maxh,
585
                                 measurements); // log2_maxh+I0_shift
586 587
#ifdef DEBUG_PHY
      if (symbol == 5) {
588
        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);
589
        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);
590
      }
591
#endif
592

593
      dlsch_dual_stream_correlation(frame_parms,
594 595
                                    symbol,
                                    nb_rb,
596 597
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
598
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
599
                                    pdsch_vars[eNB_id]->log2_maxh);
600
    }
601 602
  } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
            (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){
603
      dlsch_channel_compensation_TM34(frame_parms,
604
                                     pdsch_vars[eNB_id],
605
                                     measurements,
606 607 608
                                     eNB_id,
                                     symbol,
                                     dlsch0_harq->Qm,
lukashov's avatar
lukashov committed
609
                                     dlsch1_harq->Qm,
610 611 612
                                     harq_pid,
                                     dlsch0_harq->round,
                                     dlsch0_harq->mimo_mode,
613
                                     nb_rb,
614
                                     pdsch_vars[eNB_id]->log2_maxh0,
615
                                     pdsch_vars[eNB_id]->log2_maxh1);
616
  /*   if (symbol == 5) {
617 618 619 620
     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
621
        } */
622
      // compute correlation between signal and interference channels (rho12 and rho21)
623
        dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22
624 625
                                    symbol,
                                    nb_rb,
626 627
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
628 629 630
                                    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] );
631
      //to be optimized (just take complex conjugate)
632
      dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21
633 634
                                    symbol,
                                    nb_rb,
635
                                    &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]),
636
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
637 638
                                    pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                    pdsch_vars[eNB_id]->log2_maxh1);
639
    //  printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext );
640
      //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh);
641
  /*     if (symbol == 5) {
642 643 644 645
     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
646
        } */
647

648 649 650
    } 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,
651 652 653 654 655
                                      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,
656
                                      frame_parms,
657
                                      measurements,
658 659
                                      eNB_id,
                                      symbol,
660
                                      dlsch0_harq->Qm,
661
                                      nb_rb,
662
                                      pdsch_vars[eNB_id]->log2_maxh,
663
                                      dlsch0_harq->dl_power_off);
664

665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
        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;
          }
lukashov's avatar
lukashov committed
680
       //  if (rb==0)
681
        //    printf("pmi %d, pmi_i %d\n",pdsch_vars[eNB_id]->pmi_ext[rb],pdsch_vars[eNB_id_i]->pmi_ext[rb]);
682
      }
683 684 685 686 687 688
      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,
689
                                      frame_parms,
690
                                      measurements,
691 692 693 694
                                      eNB_id_i,
                                      symbol,
                                      i_mod,
                                      nb_rb,
695
                                      pdsch_vars[eNB_id]->log2_maxh,
696
                                      dlsch0_harq->dl_power_off);
697 698
#ifdef DEBUG_PHY
      if (symbol==5) {
699
        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);
700
       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);
701
      }
702
#endif
703 704 705
      dlsch_dual_stream_correlation(frame_parms,
                                    symbol,
                                    nb_rb,
706 707 708 709
                                    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);
710
    }  else if (dlsch0_harq->dl_power_off==1)  {
711 712 713 714 715 716
      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,
717
                                      frame_parms,
718
                                      measurements,
719 720
                                      eNB_id,
                                      symbol,
721
                                      dlsch0_harq->Qm,
722
                                      nb_rb,
723
                                      pdsch_vars[eNB_id]->log2_maxh,
724
                                      1);
lukashov's avatar
lukashov committed
725

726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
      }


    } 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
745 746
  }

747 748 749 750 751 752 753 754
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
#endif
755
// MRC
756 757 758
#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
759 760

   if (frame_parms->nb_antennas_rx > 1) {
761
    if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
762
        ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
763
         (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){  // TM3 or TM4
Xiwen JIANG's avatar
Xiwen JIANG committed
764
      if (frame_parms->nb_antenna_ports_eNB == 2) {
765
        dlsch_detection_mrc_TM34(frame_parms,
766
                                 pdsch_vars[eNB_id],
767
                                 harq_pid,
768
                                 dlsch0_harq->round,
769 770 771
                                 symbol,
                                 nb_rb,
                                 1);
772
    /*   if (symbol == 5) {
773 774
     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
775
        } */
776
      }
777
    } else {
778
      dlsch_detection_mrc(frame_parms,
779 780 781
                          pdsch_vars[eNB_id]->rxdataF_comp0,
                          pdsch_vars[eNB_id_i]->rxdataF_comp0,
                          pdsch_vars[eNB_id]->rho,
782
                          pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
783 784 785 786
                          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,
787 788
                          symbol,
                          nb_rb,
789
                          rx_type==rx_IC_single_stream);
790 791 792 793 794
    }
  }
  //  printf("Combining");
  if ((dlsch0_harq->mimo_mode == SISO) ||
      ((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) &&
795 796
       (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0)) ||
       (dlsch0_harq->mimo_mode == TM7)) {
797 798
    /*
      dlsch_siso(frame_parms,
799 800
      pdsch_vars[eNB_id]->rxdataF_comp,
      pdsch_vars[eNB_id_i]->rxdataF_comp,
801 802 803 804 805
      symbol,
      nb_rb);
    */
  } else if (dlsch0_harq->mimo_mode == ALAMOUTI) {
    dlsch_alamouti(frame_parms,
806 807 808
                   pdsch_vars[eNB_id]->rxdataF_comp0,
                   pdsch_vars[eNB_id]->dl_ch_mag0,
                   pdsch_vars[eNB_id]->dl_ch_magb0,
809 810
                   symbol,
                   nb_rb);
811 812
  }

813
  //    printf("LLR");
814 815
  if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
      ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
816
       (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING)))  {
817
    rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round];
818
    dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round];
819 820
  }
  else {
821 822
    rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0;
    dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0;
823
    //i_mod should have been passed as a parameter
824
  }
825

826 827 828 829 830 831 832 833 834 835 836 837
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
#endif

#if UE_TIMING_TRACE
    start_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#endif
gabrielC's avatar
gabrielC committed
838
  //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
  // compute LLRs
  // -> // compute @pointer where llrs should filled for this ofdm-symbol
  int8_t  *pllr_symbol_cw0;
  int8_t  *pllr_symbol_cw1;
  uint32_t llr_offset_symbol;
  llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol];
  pllr_symbol_cw0  = (int8_t*)pdsch_vars[eNB_id]->llr[0];
  pllr_symbol_cw1  = (int8_t*)pdsch_vars[eNB_id]->llr[1];
  pllr_symbol_cw0 += llr_offset_symbol;
  pllr_symbol_cw1 += llr_offset_symbol;

  /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
             proc->frame_rx, proc->subframe_rx,symbol,
             nb_rb,dlsch0_harq->Qm,
             pdsch_vars[eNB_id]->llr_length[symbol],
             pdsch_vars[eNB_id]->llr_offset[symbol],
             (int16_t*)pdsch_vars[eNB_id]->llr[0],
             pllr_symbol);*/
gabrielC's avatar
gabrielC committed
857

858
  switch (dlsch0_harq->Qm) {
859
  case 2 :
860
    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
861
        dlsch_qpsk_llr(frame_parms,
862
                       pdsch_vars[eNB_id]->rxdataF_comp0,
863
                       (int16_t*)pllr_symbol_cw0,
864 865 866
                       symbol,
                       first_symbol_flag,
                       nb_rb,
867
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
868
                       beamforming_mode);
869 870 871 872 873

    } else if (codeword_TB0 == -1){

        dlsch_qpsk_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
fnabet's avatar
fnabet committed
874
                       (int16_t*)pllr_symbol_cw1,
875 876 877 878 879
                       symbol,
                       first_symbol_flag,
                       nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
                       beamforming_mode);
880
    }
lukashov's avatar
lukashov committed
881
      else if (rx_type >= rx_IC_single_stream) {
lukashov's avatar
lukashov committed
882
        if (dlsch1_harq->Qm == 2) {
883
          dlsch_qpsk_qpsk_llr(frame_parms,
884
                              pdsch_vars[eNB_id]->rxdataF_comp0,
885
                              rxdataF_comp_ptr,
886 887
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                              pdsch_vars[eNB_id]->llr[0],
888
                              symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
889
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
890
                              pdsch_vars[eNB_id]->llr128);
891 892 893
          if (rx_type==rx_IC_dual_stream) {
            dlsch_qpsk_qpsk_llr(frame_parms,
                                rxdataF_comp_ptr,
894 895 896
                                pdsch_vars[eNB_id]->rxdataF_comp0,
                                pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                pdsch_vars[eNB_id]->llr[1],
897
                                symbol,first_symbol_flag,nb_rb,
898
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
899
                                pdsch_vars[eNB_id]->llr128_2ndstream);
900 901
          }
        }
902
        else if (dlsch1_harq->Qm == 4) {
903
          dlsch_qpsk_16qam_llr(frame_parms,
904
                               pdsch_vars[eNB_id]->rxdataF_comp0,
905 906
                               rxdataF_comp_ptr,//i
                               dl_ch_mag_ptr,//i
907 908
                               pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                               pdsch_vars[eNB_id]->llr[0],
909
                               symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
910
                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
911
                               pdsch_vars[eNB_id]->llr128);
912 913 914
          if (rx_type==rx_IC_dual_stream) {
            dlsch_16qam_qpsk_llr(frame_parms,
                                 rxdataF_comp_ptr,
915
                                 pdsch_vars[eNB_id]->rxdataF_comp0,//i
916
                                 dl_ch_mag_ptr,
917 918
                                 pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                 pdsch_vars[eNB_id]->llr[1],
919
                                 symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
920
                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
921
                                 pdsch_vars[eNB_id]->llr128_2ndstream);
922 923 924 925
          }
        }
        else {
          dlsch_qpsk_64qam_llr(frame_parms,
926
                               pdsch_vars[eNB_id]->rxdataF_comp0,
927 928
                               rxdataF_comp_ptr,//i
                               dl_ch_mag_ptr,//i
929 930
                               pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                               pdsch_vars[eNB_id]->llr[0],
931
                               symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
932
                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
933
                               pdsch_vars[eNB_id]->llr128);
934 935 936
          if (rx_type==rx_IC_dual_stream) {
            dlsch_64qam_qpsk_llr(frame_parms,
                                 rxdataF_comp_ptr,
937
                                 pdsch_vars[eNB_id]->rxdataF_comp0,//i
938
                                 dl_ch_mag_ptr,
939 940
                                 pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                 pdsch_vars[eNB_id]->llr[1],
941
                                 symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
942
                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
943
                                 pdsch_vars[eNB_id]->llr128_2ndstream);
944
          }
945
        }
946
      }
947 948
    break;
  case 4 :
949
    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
950
      dlsch_16qam_llr(frame_parms,
951 952 953
                      pdsch_vars[eNB_id]->rxdataF_comp0,
                      pdsch_vars[eNB_id]->llr[0],
                      pdsch_vars[eNB_id]->dl_ch_mag0,
954
                      symbol,first_symbol_flag,nb_rb,
955
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
956 957
                      pdsch_vars[eNB_id]->llr128,
                      beamforming_mode);
958 959 960 961 962 963 964 965 966
    } else if (codeword_TB0 == -1){
      dlsch_16qam_llr(frame_parms,
                      pdsch_vars[eNB_id]->rxdataF_comp0,
                      pdsch_vars[eNB_id]->llr[1],
                      pdsch_vars[eNB_id]->dl_ch_mag0,
                      symbol,first_symbol_flag,nb_rb,
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
                      pdsch_vars[eNB_id]->llr128_2ndstream,
                      beamforming_mode);
967
    }
968
    else if (rx_type >= rx_IC_single_stream) {
lukashov's avatar
lukashov committed
969
      if (dlsch1_harq->Qm == 2) {
970
        dlsch_16qam_qpsk_llr(frame_parms,
971
                             pdsch_vars[eNB_id]->rxdataF_comp0,
972
                             rxdataF_comp_ptr,//i
973 974 975
                             pdsch_vars[eNB_id]->dl_ch_mag0,
                             pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                             pdsch_vars[eNB_id]->llr[0],
976
                             symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
977
                             adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
978
                             pdsch_vars[eNB_id]->llr128);
979 980 981
        if (rx_type==rx_IC_dual_stream) {
          dlsch_qpsk_16qam_llr(frame_parms,
                               rxdataF_comp_ptr,
982 983 984 985
                               pdsch_vars[eNB_id]->rxdataF_comp0,//i
                               pdsch_vars[eNB_id]->dl_ch_mag0,//i
                               pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                               pdsch_vars[eNB_id]->llr[1],
986
                               symbol,first_symbol_flag,nb_rb,
lukashov's avatar
lukashov committed
987
                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
988
                               pdsch_vars[eNB_id]->llr128_2ndstream);
989
        }
990
      }
lukashov's avatar
lukashov committed
991
      else if (dlsch1_harq->Qm == 4) {
992
        dlsch_16qam_16qam_llr(frame_parms,
993
                              pdsch_vars[eNB_id]->rxdataF_comp0,
994
                              rxdataF_comp_ptr,//i
995
                              pdsch_vars[eNB_id]->dl_ch_mag0,
996
                              dl_ch_mag_ptr,//i
997 998
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                              pdsch_vars[eNB_id]->llr[0],
999 1000
                              symbol,first_symbol_flag,nb_rb,
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
1001
                              pdsch_vars[eNB_id]->llr128);
1002 1003 1004
        if (rx_type==rx_IC_dual_stream) {
          dlsch_16qam_16qam_llr(frame_parms,
                                rxdataF_comp_ptr,
1005
                                pdsch_vars[eNB_id]->rxdataF_comp0,//i
1006
                                dl_ch_mag_ptr,
1007 1008 1009
                                pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                pdsch_vars[eNB_id]->llr[1],
1010 1011
                                symbol,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
1012
                                pdsch_vars[eNB_id]->llr128_2ndstream);
1013
        }
1014 1015
      }
      else {
1016
        dlsch_16qam_64qam_llr(frame_parms,
1017
                              pdsch_vars[eNB_id]->rxdataF_comp0,
1018
                              rxdataF_comp_ptr,//i
1019
                              pdsch_vars[eNB_id]->dl_ch_mag0,
1020
                              dl_ch_mag_ptr,//i
1021 1022
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                              pdsch_vars[eNB_id]->llr[0],
1023 1024
                              symbol,first_symbol_flag,nb_rb,
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
1025
                              pdsch_vars[eNB_id]->llr128);
1026 1027 1028
        if (rx_type==rx_IC_dual_stream) {
          dlsch_64qam_16qam_llr(frame_parms,
                                rxdataF_comp_ptr,
1029
                                pdsch_vars[eNB_id]->rxdataF_comp0,
1030
                                dl_ch_mag_ptr,
1031 1032 1033
                                pdsch_vars[eNB_id]->dl_ch_mag0,
                                pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                pdsch_vars[eNB_id]->llr[1],
1034 1035
                                symbol,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
1036
                                pdsch_vars[eNB_id]->llr128_2ndstream);
1037
        }
1038 1039 1040 1041
      }
    }
    break;
  case 6 :
1042
    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
1043
      dlsch_64qam_llr(frame_parms,
1044
                      pdsch_vars[eNB_id]->rxdataF_comp0,
1045
                      (int16_t*)pllr_symbol_cw0,
1046 1047
                      pdsch_vars[eNB_id]->dl_ch_mag0,
                      pdsch_vars[eNB_id]->dl_ch_magb0,
1048
                      symbol,first_symbol_flag,nb_rb,
1049
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
1050
                      pdsch_vars[eNB_id]->llr_offset[symbol],
1051
                      beamforming_mode);
1052 1053 1054
    } else if (codeword_TB0 == -1){
      dlsch_64qam_llr(frame_parms,
                      pdsch_vars[eNB_id]->rxdataF_comp0,
fnabet's avatar
fnabet committed
1055
                      (int16_t*)pllr_symbol_cw1,
1056 1057 1058 1059
                      pdsch_vars[eNB_id]->dl_ch_mag0,
                      pdsch_vars[eNB_id]->dl_ch_magb0,
                      symbol,first_symbol_flag,nb_rb,
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
fnabet's avatar
fnabet committed
1060
                      pdsch_vars[eNB_id]->llr_offset[symbol],
1061
                      beamforming_mode);
1062
    }
1063
    else if (rx_type >= rx_IC_single_stream) {
1064
      if (dlsch1_harq->Qm == 2) {
1065
        dlsch_64qam_qpsk_llr(frame_parms,
1066
                             pdsch_vars[eNB_id]->rxdataF_comp0,
1067
                             rxdataF_comp_ptr,//i
1068 1069 1070
                             pdsch_vars[eNB_id]->dl_ch_mag0,
                             pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                             pdsch_vars[eNB_id]->llr[0],
1071 1072
                             symbol,first_symbol_flag,nb_rb,
                             adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
1073
                             pdsch_vars[eNB_id]->llr128);
1074 1075 1076
        if (rx_type==rx_IC_dual_stream) {
          dlsch_qpsk_64qam_llr(frame_parms,
                               rxdataF_comp_ptr,
1077 1078 1079 1080
                               pdsch_vars[eNB_id]->rxdataF_comp0,//i
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                               pdsch_vars[eNB_id]->llr[1],
1081 1082
                               symbol,first_symbol_flag,nb_rb,
                               adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
1083
                               pdsch_vars[eNB_id]->llr128_2ndstream);
1084
        }
1085
      }
lukashov's avatar
lukashov committed
1086
      else if (dlsch1_harq->Qm == 4) {
1087
        dlsch_64qam_16qam_llr(frame_parms,
1088
                              pdsch_vars[eNB_id]->rxdataF_comp0,
1089
                              rxdataF_comp_ptr,//i
1090
                              pdsch_vars[eNB_id]->dl_ch_mag0,
1091
                              dl_ch_mag_ptr,//i
1092 1093
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
                              pdsch_vars[eNB_id]->llr[0],
1094 1095
                              symbol,first_symbol_flag,nb_rb,
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
1096
                              pdsch_vars[eNB_id]->llr128);
1097 1098 1099
        if (rx_type==rx_IC_dual_stream) {
          dlsch_16qam_64qam_llr(frame_parms,
                                rxdataF_comp_ptr,
1100
                                pdsch_vars[eNB_id]->rxdataF_comp0,//i
1101
                                dl_ch_mag_ptr,
1102 1103 1104
                                pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
                                pdsch_vars[eNB_id]->llr[1],
1105 1106
                                symbol,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
1107
                                pdsch_vars[eNB_id]->llr128_2ndstream);
1108
        }
1109
      }
1110
      else {
1111
        dlsch_64qam_64qam_llr(frame_parms,
1112
                              pdsch_vars[eNB_id]->rxdataF_comp0,
1113
                              rxdataF_comp_ptr,//i
1114
                              pdsch_vars[eNB_id]->dl_ch_mag0,
1115
                              dl_ch_mag_ptr,//i
1116
                              pdsch_vars[eNB_id]->dl_ch_rho2_ext,
1117
                              (int16_t*)pllr_symbol_cw0,
1118 1119
                              symbol,first_symbol_flag,nb_rb,
                              adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
1120
                              pdsch_vars[eNB_id]->llr_offset[symbol]);
1121 1122 1123
        if (rx_type==rx_IC_dual_stream) {
          dlsch_64qam_64qam_llr(frame_parms,
                                rxdataF_comp_ptr,
1124
                                pdsch_vars[eNB_id]->rxdataF_comp0,//i
1125
                                dl_ch_mag_ptr,
1126 1127
                                pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
1128
                                (int16_t*)pllr_symbol_cw1,
1129 1130
                                symbol,first_symbol_flag,nb_rb,
                                adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
1131
                                pdsch_vars[eNB_id]->llr_offset[symbol]);
1132
        }
1133
      }
1134 1135
    }
    break;
1136 1137 1138 1139 1140
  default:
    LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
    return(-1);
    break;
  }
1141
  if (dlsch1_harq) {
1142
  switch (get_Qm(dlsch1_harq->mcs)) {
1143
  case 2 :
1144 1145
    if (rx_type==rx_standard) {
        dlsch_qpsk_llr(frame_parms,
1146
                       pdsch_vars[eNB_id]->rxdataF_comp0,
1147
                       (int16_t*)pllr_symbol_cw0,
1148
                       symbol,first_symbol_flag,nb_rb,
1149 1150
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
                       beamforming_mode);
1151
    }
1152 1153 1154 1155
    break;
  case 4:
    if (rx_type==rx_standard) {
      dlsch_16qam_llr(frame_parms,
1156 1157 1158
                      pdsch_vars[eNB_id]->rxdataF_comp0,
                      pdsch_vars[eNB_id]->llr[0],
                      pdsch_vars[eNB_id]->dl_ch_mag0,
1159
                      symbol,first_symbol_flag,nb_rb,
1160
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
1161
                      pdsch_vars[eNB_id]->llr128,
1162
                      beamforming_mode);
1163 1164 1165
    }
    break;
  case 6 :
1166
    if (rx_type==rx_standard) {
1167
      dlsch_64qam_llr(frame_parms,
1168
                      pdsch_vars[eNB_id]->rxdataF_comp0,
1169
                      (int16_t*)pllr_symbol_cw0,
1170 1171
                      pdsch_vars[eNB_id]->dl_ch_mag0,
                      pdsch_vars[eNB_id]->dl_ch_magb0,
1172
                      symbol,first_symbol_flag,nb_rb,
1173
                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
1174
                      pdsch_vars[eNB_id]->llr_offset[symbol],
1175
                      beamforming_mode);
lukashov's avatar
lukashov committed
1176
  }
1177 1178
    break;
  default:
jiangx's avatar
jiangx committed
1179
    LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
1180
    return(-1);
1181
    break;
1182
  }
1183 1184
  }

1185 1186 1187 1188 1189 1190 1191 1192
#if UE_TIMING_TRACE
    stop_meas(&ue->generic_stat_bis[subframe%RX_NB_TH][slot]);
#if DISABLE_LOG_X
    printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#else
    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[subframe%RX_NB_TH][slot].p_time/(cpuf*1000.0));
#endif
#endif
1193
// Please keep it: useful for debugging
hbilel's avatar
hbilel committed
1194
#if 0
gabrielC's avatar
gabrielC committed
1195
  if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/)
hbilel's avatar
hbilel committed
1196 1197
  {
      LOG_E(PHY,"Dump Phy Chan Est \n");
gabrielC's avatar
gabrielC committed
1198
      if(1)
hbilel's avatar
hbilel committed
1199 1200
      {
#if 1
1201 1202 1203 1204 1205 1206
      write_output("rxdataF0.m"    , "rxdataF0",             &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
      //write_output("rxdataF1.m"    , "rxdataF1",             &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
      write_output("dl_ch_estimates00.m", "dl_ch_estimates00",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
      //write_output("dl_ch_estimates01.m", "dl_ch_estimates01",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
      //write_output("dl_ch_estimates10.m", "dl_ch_estimates10",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
      //write_output("dl_ch_estimates11.m", "dl_ch_estimates11",   &common_vars->common_vars_rx_data_per_thread[subframe%RX_NB_TH].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
hbilel's avatar
hbilel committed
1207 1208 1209 1210 1211 1212 1213


      //write_output("rxdataF_ext00.m"    , "rxdataF_ext00",       &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("rxdataF_ext01.m"    , "rxdataF_ext01",       &pdsch_vars[eNB_id]->rxdataF_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("rxdataF_ext10.m"    , "rxdataF_ext10",       &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("rxdataF_ext11.m"    , "rxdataF_ext11",       &pdsch_vars[eNB_id]->rxdataF_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
      write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
gabrielC's avatar
gabrielC committed
1214 1215 1216
      //write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
hbilel's avatar
hbilel committed
1217
      write_output("rxdataF_comp00.m","rxdataF_comp00",              &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1);
gabrielC's avatar
gabrielC committed
1218 1219 1220
      //write_output("rxdataF_comp01.m","rxdataF_comp01",              &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("rxdataF_comp10.m","rxdataF_comp10",              &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1);
      //write_output("rxdataF_comp11.m","rxdataF_comp11",              &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1);
hbilel's avatar
hbilel committed
1221 1222
#endif
      write_output("llr0.m","llr0",  &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
gabrielC's avatar
gabrielC committed
1223
      //write_output("llr1.m","llr1",  &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
hbilel's avatar
hbilel committed
1224 1225 1226 1227 1228 1229 1230


      AssertFatal(0," ");
      }

  }
#endif
1231

1232 1233
#if T_TRACER
  T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
1234 1235
    T_INT(subframe), T_INT(nb_rb),
    T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti),
hbilel's avatar
hbilel committed
1236
    T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0],
1237
             2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
1238
#endif
1239
  return(0);
1240

1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
}

//==============================================================================================
// Pre-processing for LLR computation
//==============================================================================================

void dlsch_channel_compensation(int **rxdataF_ext,
                                int **dl_ch_estimates_ext,
                                int **dl_ch_mag,
                                int **dl_ch_magb,
                                int **rxdataF_comp,
                                int **rho,
                                LTE_DL_FRAME_PARMS *frame_parms,
                                unsigned char symbol,
1255
                                uint8_t first_symbol_flag,
1256 1257 1258
                                unsigned char mod_order,
                                unsigned short nb_rb,
                                unsigned char output_shift,
1259
                                PHY_MEASUREMENTS *measurements)
1260
{
1261

1262
#if defined(__i386) || defined(__x86_64)
1263 1264 1265 1266

  unsigned short rb;
  unsigned char aatx,aarx,symbol_mod,pilots=0;
  __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
1267
  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
1268 1269 1270 1271

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
1272 1273

    if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size
1274
      nb_rb=1+(5*nb_rb/6);
1275 1276
    else
      pilots=1;
1277 1278
  }

Xiwen JIANG's avatar
Xiwen JIANG committed
1279
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
1280 1281
    if (mod_order == 4) {
      QAM_amp128 = _mm_set1_epi16(QAM16_n1);  // 2/sqrt(10)
1282
      QAM_amp128b = _mm_setzero_si128();
1283 1284
    } else if (mod_order == 6) {
      QAM_amp128  = _mm_set1_epi16(QAM64_n1); //
1285 1286
      QAM_amp128b = _mm_set1_epi16(QAM64_n2);
    }
1287

1288 1289
    //    printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);

1290
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1291 1292 1293 1294 1295 1296 1297 1298

      dl_ch128          = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128      = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128b     = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];


1299
      for (rb=0; rb<nb_rb; rb++) {
1300
        if (mod_order>2) {
1301
          // get channel amplitude if not QPSK
1302

1303 1304
          mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]);
          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
1305

1306 1307
          mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]);
          mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
1308

1309
          mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
1310

1311
          // store channel magnitude here in a new field of dlsch
1312

1313 1314 1315 1316
          dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
          dl_ch_mag128b[0] = dl_ch_mag128[0];
          dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
          dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
1317 1318 1319
    //print_ints("Re(ch):",(int16_t*)&mmtmpD0);
    //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
    //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]);
1320 1321 1322 1323
          dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
          dl_ch_mag128b[1] = dl_ch_mag128[1];
          dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
          dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
1324

1325 1326 1327 1328
          if (pilots==0) {
            mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);
            mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
            mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
1329

1330 1331
            dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
            dl_ch_mag128b[2] = dl_ch_mag128[2];
1332

1333
            dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
1334
            dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
1335
          }
1336

1337 1338
          dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
          dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
1339 1340


1341 1342
          dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
          dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
1343

1344 1345
          if (pilots==0) {
            dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
1346
            dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
1347 1348
          }
        }
1349

1350 1351
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
1352
        //  print_ints("re",&mmtmpD0);
1353

1354 1355 1356 1357
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
1358
        //  print_ints("im",&mmtmpD1);
1359 1360 1361
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
1362
        //  print_ints("re(shift)",&mmtmpD0);
1363
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
1364
        //  print_ints("im(shift)",&mmtmpD1);
1365 1366
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1367 1368
        //        print_ints("c0",&mmtmpD2);
        //  print_ints("c1",&mmtmpD3);
1369
        rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
1370 1371 1372
        //  print_shorts("rx:",rxdataF128);
        //  print_shorts("ch:",dl_ch128);
        //  print_shorts("pack:",rxdataF_comp128);
1373

1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1386

1387
        rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
1388 1389 1390
        //  print_shorts("rx:",rxdataF128+1);
        //  print_shorts("ch:",dl_ch128+1);
        //  print_shorts("pack:",rxdataF_comp128+1);
1391

1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
        if (pilots==0) {
          // multiply by conjugated channel
          mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
          // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
          mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
          mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
          mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
          mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
          // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
          mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
          mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
          mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1405

1406
          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
1407 1408 1409
          //  print_shorts("rx:",rxdataF128+2);
          //  print_shorts("ch:",dl_ch128+2);
          //        print_shorts("pack:",rxdataF_comp128+2);
1410

1411 1412 1413 1414 1415
          dl_ch128+=3;
          dl_ch_mag128+=3;
          dl_ch_mag128b+=3;
          rxdataF128+=3;
          rxdataF_comp128+=3;
1416
        } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
1417 1418 1419 1420 1421 1422
          dl_ch128+=2;
          dl_ch_mag128+=2;
          dl_ch_mag128b+=2;
          rxdataF128+=2;
          rxdataF_comp128+=2;
        }
1423

1424 1425 1426
      }
    }
  }
1427

1428
  if (rho) {
1429 1430


1431
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1432 1433 1434
      rho128        = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
1435

1436
      for (rb=0; rb<nb_rb; rb++) {
1437 1438
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
1439
        //  print_ints("re",&mmtmpD0);
1440

1441 1442 1443 1444
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
1445
        //  print_ints("im",&mmtmpD1);
1446 1447 1448
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
1449
        //  print_ints("re(shift)",&mmtmpD0);
1450
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
1451
        //  print_ints("im(shift)",&mmtmpD1);
1452 1453
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1454 1455
        //        print_ints("c0",&mmtmpD2);
        //  print_ints("c1",&mmtmpD3);
1456
        rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
1457

1458 1459 1460
        //print_shorts("rx:",dl_ch128_2);
        //print_shorts("ch:",dl_ch128);
        //print_shorts("pack:",rho128);
1461

1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1474

1475

1476 1477 1478
        rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
        //print_shorts("rx:",dl_ch128_2+1);
        //print_shorts("ch:",dl_ch128+1);
1479
        //print_shorts("pack:",rho128+1);
1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
1492

1493 1494 1495 1496
        rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
        //print_shorts("rx:",dl_ch128_2+2);
        //print_shorts("ch:",dl_ch128+2);
        //print_shorts("pack:",rho128+2);
1497

1498 1499 1500
        dl_ch128+=3;
        dl_ch128_2+=3;
        rho128+=3;
1501 1502 1503

      }

1504
      if (first_symbol_flag==1) {
1505
        measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
1506 1507
      }
    }
1508 1509 1510 1511
  }

  _mm_empty();
  _m_empty();
1512

1513 1514 1515
#elif defined(__arm__)


1516 1517
  unsigned short rb;
  unsigned char aatx,aarx,symbol_mod,pilots=0;
1518

1519 1520 1521 1522 1523
  int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128;
  int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
  int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4;
  int16x8_t QAM_amp128,QAM_amp128b;
  int16x4x2_t *rxdataF_comp128,*rho128;
1524

1525
  int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
1526
  int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
1527

1528
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
1529

1530 1531 1532 1533 1534 1535
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
    if (frame_parms->mode1_flag==1) { // 10 out of 12 so don't reduce size
      nb_rb=1+(5*nb_rb/6);
    }
    else {
      pilots=1;
1536
    }
1537
  }
1538

Xiwen JIANG's avatar
Xiwen JIANG committed
1539
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
1540
    if (mod_order == 4) {
1541 1542
      QAM_amp128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
      QAM_amp128b = vmovq_n_s16(0);
1543
    } else if (mod_order == 6) {
1544 1545
      QAM_amp128  = vmovq_n_s16(QAM64_n1); //
      QAM_amp128b = vmovq_n_s16(QAM64_n2);
1546 1547
    }
    //    printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
1548

1549 1550 1551 1552 1553
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
      dl_ch128          = (int16x4_t*)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128      = (int16x8_t*)&dl_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128b     = (int16x8_t*)&dl_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      rxdataF128        = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
1554
      rxdataF_comp128   = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
1555

1556
      for (rb=0; rb<nb_rb; rb++) {
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578
  if (mod_order>2) {
    // get channel amplitude if not QPSK
    mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]);
    // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
    mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
    // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
    mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128[1]);
    mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
    mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
    // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
    mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128[2]);
    mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
    mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]);
    mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
    mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
    if (pilots==0) {
      mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]);
      mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
      mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]);
      mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
      mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
    }
1579

1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
    dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
    dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
    dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
    dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);

    if (pilots==0) {
      dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
      dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
    }
  }

  mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]);
  //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
  mmtmpD1 = vmull_s16(dl_ch128[1], rxdataF128[1]);
  //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
  //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]

  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
  //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
  //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
  //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]

  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
  rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
  mmtmpD0 = vmull_s16(dl_ch128[2], rxdataF128[2]);
  mmtmpD1 = vmull_s16(dl_ch128[3], rxdataF128[3]);
  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
  rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));

  if (pilots==0) {
    mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]);
    mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]);
    mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
         vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));

    mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
    mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
    mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
         vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));


    mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
    mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
    rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));


    dl_ch128+=6;
    dl_ch_mag128+=3;
    dl_ch_mag128b+=3;
    rxdataF128+=6;
    rxdataF_comp128+=3;

  } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
    dl_ch128+=4;
    dl_ch_mag128+=2;
    dl_ch_mag128b+=2;
    rxdataF128+=4;
    rxdataF_comp128+=2;
  }
1652
      }
1653
    }
1654
  }
1655

1656 1657
  if (rho) {
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1658
      rho128        = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
1659 1660 1661
      dl_ch128      = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch128_2    = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
      for (rb=0; rb<nb_rb; rb++) {
1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704
  mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]);
  mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]);
  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), dl_ch128_2[0]);
  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), dl_ch128_2[1]);
  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));

  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
  rho128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));

  mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128_2[2]);
  mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128_2[3]);
  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), dl_ch128_2[2]);
  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), dl_ch128_2[3]);
  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));

  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
  rho128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));

  mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]);
  mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]);
  mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
  mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), dl_ch128_2[4]);
  mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), dl_ch128_2[5]);
  mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));

  mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
  mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
  rho128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));


  dl_ch128+=6;
  dl_ch128_2+=6;
  rho128+=3;
1705
      }
1706

1707
      if (first_symbol_flag==1) {
1708
  measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12);
1709
      }
1710
    }
1711
  }
1712
#endif
1713 1714
}

1715 1716
#if defined(__x86_64__) || defined(__i386__)

1717 1718
void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1)
{
1719 1720 1721 1722 1723

  __m128i amp;
  amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);

  switch (pmi) {
1724

1725 1726 1727
  case 0 :   // +1 +1
    //    print_shorts("phase 0 :ch0",ch0);
    //    print_shorts("phase 0 :ch1",ch1);
1728
    ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
1729
    break;
1730

1731 1732 1733 1734 1735 1736
  case 1 :   // +1 -1
    //    print_shorts("phase 1 :ch0",ch0);
    //    print_shorts("phase 1 :ch1",ch1);
    ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
    //    print_shorts("phase 1 :ch0-ch1",ch0);
    break;
1737

1738 1739 1740 1741 1742
  case 2 :   // +1 +j
    ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
    ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
1743

1744
    break;   // +1 -j
1745

1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
  case 3 :
    ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
    ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
    break;
  }

  ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
  ch0[0] = _mm_slli_epi16(ch0[0],1);
1756

1757 1758 1759
  _mm_empty();
  _m_empty();
}
1760
#elif defined(__arm__)
1761
void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) {
1762

1763 1764 1765 1766 1767
  // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b,
  //so removed it

  //__m128i amp;
  //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
1768 1769

  switch (pmi) {
1770

1771 1772 1773
  case 0 :   // +1 +1
    //    print_shorts("phase 0 :ch0",ch0);
    //    print_shorts("phase 0 :ch1",ch1);
1774
    ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
    break;
  case 1 :   // +1 -1
    //    print_shorts("phase 1 :ch0",ch0);
    //    print_shorts("phase 1 :ch1",ch1);
    ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
    //    print_shorts("phase 1 :ch0-ch1",ch0);
    break;
  case 2 :   // +1 +j
    ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
    ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]);
1787

1788 1789 1790 1791 1792 1793 1794 1795 1796
    break;   // +1 -j
  case 3 :
    ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
    ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1));
    ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]);
    break;
  }

1797 1798
  //ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
  //ch0[0] = _mm_slli_epi16(ch0[0],1);
1799

1800 1801 1802
  _mm_empty();
  _m_empty();
}
1803
#endif
1804 1805 1806 1807 1808 1809 1810
// precoding is stream 0 .5(1,1)  .5(1,-1) .5(1,1)  .5(1,-1)
//              stream 1 .5(1,-1) .5(1,1)  .5(1,-1) .5(1,1)
// store "precoded" channel for stream 0 in ch0, stream 1 in ch1

short TM3_prec[8]__attribute__((aligned(16))) = {1,1,-1,-1,1,1,-1,-1} ;

void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) {
1811

1812
  __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
1813

1814
  __m128i tmp0,tmp1;
1815

1816
  //_mm_mulhi_epi16
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826
  //  print_shorts("prec2A_TM3 ch0 (before):",ch0);
  //  print_shorts("prec2A_TM3 ch1 (before):",ch1);

  tmp0 = ch0[0];
  tmp1  = _mm_sign_epi16(ch1[0],((__m128i*)&TM3_prec)[0]);
  //  print_shorts("prec2A_TM3 ch1*s (mid):",(__m128i*)TM3_prec);

  ch0[0] = _mm_adds_epi16(ch0[0],tmp1);
  ch1[0] = _mm_subs_epi16(tmp0,tmp1);

1827 1828 1829 1830 1831
  ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
  ch0[0] = _mm_slli_epi16(ch0[0],1);

  ch1[0] = _mm_mulhi_epi16(ch1[0],amp);
  ch1[0] = _mm_slli_epi16(ch1[0],1);
1832 1833 1834 1835

  //  print_shorts("prec2A_TM3 ch0 (mid):",&tmp0);
  //  print_shorts("prec2A_TM3 ch1 (mid):",ch1);

1836 1837 1838 1839
  //ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
  //ch0[0] = _mm_slli_epi16(ch0[0],1);
  //ch1[0] = _mm_mulhi_epi16(ch1[0],amp);
  //ch1[0] = _mm_slli_epi16(ch1[0],1);
1840

1841 1842
  //ch0[0] = _mm_srai_epi16(ch0[0],1);
  //ch1[0] = _mm_srai_epi16(ch1[0],1);
1843 1844 1845

  //  print_shorts("prec2A_TM3 ch0 (after):",ch0);
  //  print_shorts("prec2A_TM3 ch1 (after):",ch1);
1846

1847 1848 1849 1850 1851 1852 1853 1854
  _mm_empty();
  _m_empty();
}

// pmi = 0 => stream 0 (1,1), stream 1 (1,-1)
// pmi = 1 => stream 0 (1,j), stream 2 (1,-j)

void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) {
1855

1856 1857 1858
// sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b,
//so divide by 2 is replaced by divide by sqrt(2).

lukashov's avatar
lukashov committed
1859
 // printf ("demod pmi=%d\n", pmi);
1860 1861
 __m128i amp;
 amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15);
1862
  __m128i tmp0,tmp1;
1863

1864 1865
 // print_shorts("prec2A_TM4 ch0 (before):",ch0);
 // print_shorts("prec2A_TM4 ch1 (before):",ch1);
1866 1867 1868 1869 1870 1871

  if (pmi == 0) { //[1 1;1 -1]
    tmp0 = ch0[0];
    tmp1 = ch1[0];
    ch0[0] = _mm_adds_epi16(tmp0,tmp1);
    ch1[0] = _mm_subs_epi16(tmp0,tmp1);
1872
  }
lukashov's avatar
lukashov committed
1873
  else { //ch0+j*ch1 ch0-j*ch1
1874
    tmp0 = ch0[0];
1875 1876 1877 1878
    tmp1   = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]);
    tmp1   = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1));
    tmp1   = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1));
    ch0[0] = _mm_subs_epi16(tmp0,tmp1);
1879
    ch1[0] = _mm_add_epi16(tmp0,tmp1);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1880
  }
1881

1882 1883 1884
  //print_shorts("prec2A_TM4 ch0 (middle):",ch0);
  //print_shorts("prec2A_TM4 ch1 (middle):",ch1);

1885 1886 1887 1888
  ch0[0] = _mm_mulhi_epi16(ch0[0],amp);
  ch0[0] = _mm_slli_epi16(ch0[0],1);
  ch1[0] = _mm_mulhi_epi16(ch1[0],amp);
  ch1[0] = _mm_slli_epi16(ch1[0],1);
1889

1890

1891 1892
 // ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2
 // ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2
1893 1894
  //print_shorts("prec2A_TM4 ch0 (end):",ch0);
  //print_shorts("prec2A_TM4 ch1 (end):",ch1);
lukashov's avatar
lukashov committed
1895 1896
  _mm_empty();
  _m_empty();
1897 1898
 // print_shorts("prec2A_TM4 ch0 (end):",ch0);
  //print_shorts("prec2A_TM4 ch1 (end):",ch1);
1899 1900 1901
}

void dlsch_channel_compensation_TM56(int **rxdataF_ext,
1902 1903 1904 1905 1906 1907
                                     int **dl_ch_estimates_ext,
                                     int **dl_ch_mag,
                                     int **dl_ch_magb,
                                     int **rxdataF_comp,
                                     unsigned char *pmi_ext,
                                     LTE_DL_FRAME_PARMS *frame_parms,
1908
                                     PHY_MEASUREMENTS *measurements,
1909 1910 1911 1912 1913
                                     int eNB_id,
                                     unsigned char symbol,
                                     unsigned char mod_order,
                                     unsigned short nb_rb,
                                     unsigned char output_shift,
1914 1915 1916
                                     unsigned char dl_power_off)
{

1917 1918
#if defined(__x86_64__) || defined(__i386__)

1919
  unsigned short rb,Nre;
1920
  __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128;
1921
  unsigned char aarx=0,symbol_mod,pilots=0;
1922
  int precoded_signal_strength=0;
1923
  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
1924

1925
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
1926

1927 1928 1929
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
    pilots=1;

1930

1931 1932 1933 1934
  //printf("comp prec: symbol %d, pilots %d\n",symbol, pilots);

  if (mod_order == 4) {
    QAM_amp128 = _mm_set1_epi16(QAM16_n1);
1935
    QAM_amp128b = _mm_setzero_si128();
1936
  } else if (mod_order == 6) {
1937 1938 1939
    QAM_amp128  = _mm_set1_epi16(QAM64_n1);
    QAM_amp128b = _mm_set1_epi16(QAM64_n2);
  }
1940 1941 1942

  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {

1943 1944
    dl_ch0_128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128          = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
1945 1946


1947 1948 1949 1950 1951
    dl_ch_mag128      = (__m128i *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch_mag128b     = (__m128i *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
    rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp128   = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];

1952 1953

    for (rb=0; rb<nb_rb; rb++) {
1954 1955 1956
      // combine TX channels using precoder from pmi
#ifdef DEBUG_DLSCH_DEMOD
      printf("mode 6 prec: rb %d, pmi->%d\n",rb,pmi_ext[rb]);
1957
#endif
1958 1959
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]);
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]);
1960 1961

      if (pilots==0) {
lukashov's avatar
lukashov committed
1962

1963
        prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]);
1964 1965
      }

1966
      if (mod_order>2) {
1967
        // get channel amplitude if not QPSK
1968 1969

        mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]);
1970
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
1971

1972 1973
        mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
1974

1975
        mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
1976

1977 1978 1979 1980
        dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag128b[0] = dl_ch_mag128[0];
        dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128);
        dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1);
1981

1982

1983
        //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]);
lukashov's avatar
lukashov committed
1984

1985 1986
        //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]);

1987 1988 1989 1990
        dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag128b[1] = dl_ch_mag128[1];
        dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128);
        dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1);
1991

1992 1993 1994
        if (pilots==0) {
          mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]);
          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
1995

1996
          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
1997

1998 1999
          dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
          dl_ch_mag128b[2] = dl_ch_mag128[2];
2000

2001
          dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128);
2002
          dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1);
2003
        }
2004

2005 2006
        dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b);
        dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1);
2007

2008
        //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]);
2009

2010 2011
        dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
        dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
2012

2013 2014
        if (pilots==0) {
          dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b);
2015
          dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1);
lukashov's avatar
lukashov committed
2016

2017
        }
2018 2019 2020
      }

      // MF multiply by conjugated channel
2021
      mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]);
2022
      //        print_ints("re",&mmtmpD0);
2023

2024 2025 2026 2027
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
lukashov's avatar
lukashov committed
2028

2029
      //        print_ints("im",&mmtmpD1);
2030 2031 2032
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
2033
      //        print_ints("re(shift)",&mmtmpD0);
2034
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
2035
      //        print_ints("im(shift)",&mmtmpD1);
2036 2037
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2038 2039
      //        print_ints("c0",&mmtmpD2);
      //        print_ints("c1",&mmtmpD3);
2040
      rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2041 2042 2043
      //        print_shorts("rx:",rxdataF128);
      //        print_shorts("ch:",dl_ch128);
      //        print_shorts("pack:",rxdataF_comp128);
2044

2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]);
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2057

2058
      rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2059 2060 2061 2062
      //  print_shorts("rx:",rxdataF128+1);
      //  print_shorts("ch:",dl_ch128+1);
      //  print_shorts("pack:",rxdataF_comp128+1);

2063
      if (pilots==0) {
2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2076

2077
        rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2078 2079 2080 2081
        //  print_shorts("rx:",rxdataF128+2);
        //  print_shorts("ch:",dl_ch128+2);
        //        print_shorts("pack:",rxdataF_comp128+2);

2082 2083 2084 2085 2086 2087
        dl_ch0_128+=3;
        dl_ch1_128+=3;
        dl_ch_mag128+=3;
        dl_ch_mag128b+=3;
        rxdataF128+=3;
        rxdataF_comp128+=3;
2088
      } else {
2089 2090 2091 2092 2093 2094
        dl_ch0_128+=2;
        dl_ch1_128+=2;
        dl_ch_mag128+=2;
        dl_ch_mag128b+=2;
        rxdataF128+=2;
        rxdataF_comp128+=2;
2095 2096
      }
    }
2097

2098
    Nre = (pilots==0) ? 12 : 8;
2099

2100
    precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
2101
                                                     (nb_rb*Nre))) - (measurements->n0_power[aarx]));
2102
  } // rx_antennas
2103

2104
  measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot);
2105

2106
  //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
2107
  //   measurements->precoded_cqi_dB[eNB_id][0]);
2108

2109 2110
#elif defined(__arm__)

2111 2112
  uint32_t rb,Nre;
  uint32_t aarx,symbol_mod,pilots=0;
2113

2114 2115 2116 2117 2118
  int16x4_t *dl_ch0_128,*dl_ch1_128,*rxdataF128;
  int16x8_t *dl_ch0_128b,*dl_ch1_128b;
  int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
  int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp128;
  int16x8_t QAM_amp128,QAM_amp128b;
2119

2120
  int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
2121 2122
  int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
  int32_t precoded_signal_strength=0;
2123 2124

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
2125
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
2126 2127
    if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size
      { nb_rb=1+(5*nb_rb/6); }
2128

2129 2130
    else
      { pilots=1; }
2131
  }
2132 2133


2134
  if (mod_order == 4) {
2135 2136
    QAM_amp128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
    QAM_amp128b = vmovq_n_s16(0);
2137

2138
  } else if (mod_order == 6) {
2139
    QAM_amp128  = vmovq_n_s16(QAM64_n1); //
2140
    QAM_amp128b = vmovq_n_s16(QAM64_n2);
2141
  }
2142

2143
  //    printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
2144

2145
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
2146 2147 2148



2149 2150
    dl_ch0_128          = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128          = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
2151 2152 2153 2154
    dl_ch0_128b         = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128b         = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch_mag128        = (int16x8_t*)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch_mag128b       = (int16x8_t*)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
2155
    rxdataF128          = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
2156
    rxdataF_comp128     = (int16x8_t*)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
2157

2158
    for (rb=0; rb<nb_rb; rb++) {
2159 2160 2161 2162 2163
#ifdef DEBUG_DLSCH_DEMOD
      printf("mode 6 prec: rb %d, pmi->%d\n",rb,pmi_ext[rb]);
#endif
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[0],&dl_ch1_128b[0]);
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[1],&dl_ch1_128b[1]);
2164

2165
      if (pilots==0) {
2166
        prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]);
2167
      }
2168

2169
      if (mod_order>2) {
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
        // get channel amplitude if not QPSK
        mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
        // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
        mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
        // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
        mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
        if (pilots==0) {
          mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
          mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
          mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
          mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
          mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));


        }

        dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
        dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
        dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
        dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);


        if (pilots==0) {
          dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
          dl_ch_mag128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp128);
        }
2204
      }
2205
      mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]);
2206
      //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
2207
      mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]);
2208
      //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
2209
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2210
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2211 2212
      //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]

2213
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
2214
      //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
2215
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
2216
      //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
2217
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2218
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2219
      //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
2220

2221 2222
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
2223
      rxdataF_comp128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2224

2225 2226 2227
      mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]);
      mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]);
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2228
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2229

2230 2231 2232
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2233
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2234

2235 2236
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
2237
      rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2238

2239
      if (pilots==0) {
2240 2241 2242 2243
        mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
        mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
        mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
                               vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2244

2245 2246 2247 2248
        mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
        mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
        mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
                               vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2249 2250


2251 2252 2253
        mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
        mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
        rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2254 2255


2256 2257 2258 2259 2260 2261
        dl_ch0_128+=6;
        dl_ch1_128+=6;
        dl_ch_mag128+=3;
        dl_ch_mag128b+=3;
        rxdataF128+=6;
        rxdataF_comp128+=3;
2262

2263
      } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less
2264 2265 2266 2267 2268 2269
        dl_ch0_128+=4;
        dl_ch1_128+=4;
        dl_ch_mag128+=2;
        dl_ch_mag128b+=2;
        rxdataF128+=4;
        rxdataF_comp128+=2;
2270 2271
      }
    }
2272

2273
    Nre = (pilots==0) ? 12 : 8;
lukashov's avatar
lukashov committed
2274

2275

2276
    precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
2277 2278

                                                     (nb_rb*Nre))) - (measurements->n0_power[aarx]));
2279 2280
    // rx_antennas
  }
2281
  measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot);
2282

2283
  //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
2284
  //     measurements->precoded_cqi_dB[eNB_id][0]);
2285 2286

#endif
2287
  _mm_empty();
2288 2289
  _m_empty();
}
2290

2291
void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
2292 2293
                                    LTE_UE_PDSCH *pdsch_vars,
                                    PHY_MEASUREMENTS *measurements,
2294 2295 2296 2297 2298 2299 2300 2301
                                    int eNB_id,
                                    unsigned char symbol,
                                    unsigned char mod_order0,
                                    unsigned char mod_order1,
                                    int harq_pid,
                                    int round,
                                    MIMO_mode_t mimo_mode,
                                    unsigned short nb_rb,
2302
                                    unsigned char output_shift0,
2303
                                    unsigned char output_shift1) {
2304

2305 2306
#if defined(__x86_64__) || defined(__i386__)

2307 2308 2309
  unsigned short rb,Nre;
  __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128;
  unsigned char aarx=0,symbol_mod,pilots=0;
2310
  int precoded_signal_strength0=0,precoded_signal_strength1=0;
lukashov's avatar
lukashov committed
2311
  int rx_power_correction;
2312

2313 2314 2315
  int **rxdataF_ext           = pdsch_vars->rxdataF_ext;
  int **dl_ch_estimates_ext   = pdsch_vars->dl_ch_estimates_ext;
  int **dl_ch_mag0            = pdsch_vars->dl_ch_mag0;
2316
  int **dl_ch_mag1            = pdsch_vars->dl_ch_mag1[harq_pid][round];
2317
  int **dl_ch_magb0           = pdsch_vars->dl_ch_magb0;
2318
  int **dl_ch_magb1           = pdsch_vars->dl_ch_magb1[harq_pid][round];
2319
  int **rxdataF_comp0         = pdsch_vars->rxdataF_comp0;
2320
  int **rxdataF_comp1         = pdsch_vars->rxdataF_comp1[harq_pid][round];
2321
  unsigned char *pmi_ext      = pdsch_vars->pmi_ext;
2322 2323
  __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b;

2324
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
2325

2326 2327 2328 2329
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
    pilots=1;

  rx_power_correction = 1;
2330

2331
 // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots);
2332 2333 2334

  if (mod_order0 == 4) {
    QAM_amp0_128  = _mm_set1_epi16(QAM16_n1);
2335
    QAM_amp0_128b = _mm_setzero_si128();
2336
  } else if (mod_order0 == 6) {
2337 2338 2339
    QAM_amp0_128  = _mm_set1_epi16(QAM64_n1);
    QAM_amp0_128b = _mm_set1_epi16(QAM64_n2);
  }
2340

2341 2342
  if (mod_order1 == 4) {
    QAM_amp1_128  = _mm_set1_epi16(QAM16_n1);
2343
    QAM_amp1_128b = _mm_setzero_si128();
lukashov's avatar
lukashov committed
2344
  } else if (mod_order1 == 6) {
2345 2346 2347
    QAM_amp1_128  = _mm_set1_epi16(QAM64_n1);
    QAM_amp1_128b = _mm_set1_epi16(QAM64_n2);
  }
2348

2349
  for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
2350

2351
   /* if (aarx==0) {
2352
      output_shift=output_shift0;
2353 2354
    }
      else {
2355
        output_shift=output_shift1;
2356
      } */
2357 2358

     // printf("antenna %d\n", aarx);
2359 2360
   // printf("symbol %d, rx antenna %d\n", symbol, aarx);

2361 2362
    dl_ch0_128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11
    dl_ch1_128          = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12
2363 2364


2365 2366 2367 2368
    dl_ch_mag0_128      = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1
    dl_ch_mag0_128b     = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1
    dl_ch_mag1_128      = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12];   //responsible for x2. always coming from tx2
    dl_ch_mag1_128b     = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12];  //responsible for x2. always coming from tx2
2369
    rxdataF128          = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2
2370 2371
    rxdataF_comp0_128   = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x1 on antenna of interest
    rxdataF_comp1_128   = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest
2372

2373
    for (rb=0; rb<nb_rb; rb++) {
2374

2375
      // combine TX channels using precoder from pmi
2376 2377 2378
      if (mimo_mode==LARGE_CDD) {
        prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]);
2379 2380


2381
        if (pilots==0) {
2382
          prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]);
2383 2384 2385
        }
      }
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) {
2386 2387 2388
        prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]);

2389
        if (pilots==0) {
2390
          prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]);
2391 2392 2393 2394 2395
        }
      }
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) {
        prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]);
2396

2397
        if (pilots==0) {
2398
          prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]);
2399 2400
        }
      }
2401

2402
        else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) {
2403 2404
        prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]);
2405

lukashov's avatar
lukashov committed
2406
        if (pilots==0) {
2407
          prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]);
lukashov's avatar
lukashov committed
2408 2409
        }
      }
2410 2411


2412 2413 2414
      else {
        LOG_E(PHY,"Unknown MIMO mode\n");
        return;
2415 2416
      }

2417 2418

      if (mod_order0>2) {
2419
        // get channel amplitude if not QPSK
2420 2421

        mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]);
2422
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
2423

2424
        mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]);
2425
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
2426

2427
        mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
2428

2429 2430 2431 2432
        dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag0_128b[0] = dl_ch_mag0_128[0];
        dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128);
        dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1);
2433

2434
        //  print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]);
2435

2436

2437 2438 2439 2440
        dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag0_128b[1] = dl_ch_mag0_128[1];
        dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128);
        dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1);
2441

2442 2443
        if (pilots==0) {
          mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]);
2444
          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
2445

2446
          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
2447

2448 2449
          dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
          dl_ch_mag0_128b[2] = dl_ch_mag0_128[2];
2450

2451
          dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128);
2452
          dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1);
2453
        }
2454

2455 2456
        dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b);
        dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1);
2457

2458
       // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]);
2459

2460 2461
        dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b);
        dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1);
2462

2463 2464
        if (pilots==0) {
          dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b);
2465
          dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1);
2466
        }
2467 2468
      }

2469
      if (mod_order1>2) {
2470
        // get channel amplitude if not QPSK
2471 2472

        mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]);
2473
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
2474

2475
        mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]);
2476
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
2477

2478
        mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
2479

2480 2481 2482 2483
        dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag1_128b[0] = dl_ch_mag1_128[0];
        dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128);
        dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1);
2484

2485
       // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]);
2486

2487 2488 2489 2490
        dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
        dl_ch_mag1_128b[1] = dl_ch_mag1_128[1];
        dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128);
        dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1);
2491

2492 2493
        if (pilots==0) {
          mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]);
2494
          mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
2495

2496
          mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
2497

2498 2499
          dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
          dl_ch_mag1_128b[2] = dl_ch_mag1_128[2];
2500

2501
          dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128);
2502
          dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1);
2503
        }
2504

2505 2506
        dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b);
        dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1);
2507

2508
       // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]);
2509

2510 2511
        dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b);
        dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1);
2512

2513 2514
        if (pilots==0) {
          dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b);
2515
          dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1);
2516
        }
2517 2518
      }

2519
      // layer 0
2520 2521
      // MF multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]);
2522 2523
    //  print_ints("re",&mmtmpD0);

2524 2525 2526 2527 2528
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
2529
           // print_ints("im",&mmtmpD1);
2530
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2531
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
2532 2533
           // printf("Shift: %d\n",output_shift);
          // print_ints("re(shift)",&mmtmpD0);
2534
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
2535
           // print_ints("im(shift)",&mmtmpD1);
2536 2537
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2538 2539
          //  print_ints("c0",&mmtmpD2);
          // print_ints("c1",&mmtmpD3);
2540
      rxdataF_comp0_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2541

2542 2543 2544
           // print_shorts("rx:",rxdataF128);
           // print_shorts("ch:",dl_ch0_128);
        // print_shorts("pack:",rxdataF_comp0_128);
2545

2546 2547 2548 2549 2550 2551 2552 2553
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]);
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2554 2555
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
2556 2557
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2558

2559
      rxdataF_comp0_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2560 2561
           //  print_shorts("rx:",rxdataF128+1);
            //  print_shorts("ch:",dl_ch0_128+1);
2562 2563
            // print_shorts("pack:",rxdataF_comp0_128+1);

2564
      if (pilots==0) {
2565 2566 2567 2568 2569 2570 2571 2572
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2573 2574
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
2575 2576
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2577

2578 2579 2580 2581
        rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
           //   print_shorts("rx:",rxdataF128+2);
           //   print_shorts("ch:",dl_ch0_128+2);
            //  print_shorts("pack:",rxdataF_comp0_128+2);
2582

2583
      }
2584 2585


2586 2587 2588
      // layer 1
      // MF multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]);
2589
           //  print_ints("re",&mmtmpD0);
2590

lukashov's avatar
lukashov committed
2591
     // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
2592
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));
2593 2594
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
2595
            //  print_ints("im",&mmtmpD1);
2596 2597
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2598
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
2599
             // print_ints("re(shift)",&mmtmpD0);
2600
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
2601
             // print_ints("im(shift)",&mmtmpD1);
2602 2603
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2604 2605
             // print_ints("c0",&mmtmpD2);
             // print_ints("c1",&mmtmpD3);
2606
      rxdataF_comp1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2607 2608 2609
            // print_shorts("rx:",rxdataF128);
            //  print_shorts("ch:",dl_ch1_128);
            // print_shorts("pack:",rxdataF_comp1_128);
2610

lukashov's avatar
lukashov committed
2611
     // multiply by conjugated channel
2612
      mmtmpD0 = _mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]);
2613
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
2614
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1));
2615 2616 2617 2618
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2619 2620
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
2621 2622
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2623

2624
      rxdataF_comp1_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
2625 2626
            //  print_shorts("rx:",rxdataF128+1);
           // print_shorts("ch:",dl_ch1_128+1);
2627
            // print_shorts("pack:",rxdataF_comp1_128+1);
2628

2629
      if (pilots==0) {
2630 2631 2632 2633 2634 2635 2636 2637
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],rxdataF128[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
2638 2639
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1);
2640 2641
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
2642

2643 2644 2645 2646
        rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
          //   print_shorts("rx:",rxdataF128+2);
           //  print_shorts("ch:",dl_ch1_128+2);
             //         print_shorts("pack:",rxdataF_comp1_128+2);
2647

2648 2649 2650 2651 2652 2653 2654 2655 2656
        dl_ch0_128+=3;
        dl_ch1_128+=3;
        dl_ch_mag0_128+=3;
        dl_ch_mag1_128+=3;
        dl_ch_mag0_128b+=3;
        dl_ch_mag1_128b+=3;
        rxdataF128+=3;
        rxdataF_comp0_128+=3;
        rxdataF_comp1_128+=3;
2657 2658
      }
      else {
2659 2660 2661 2662 2663 2664 2665 2666 2667
        dl_ch0_128+=2;
        dl_ch1_128+=2;
        dl_ch_mag0_128+=2;
        dl_ch_mag1_128+=2;
        dl_ch_mag0_128b+=2;
        dl_ch_mag1_128b+=2;
        rxdataF128+=2;
        rxdataF_comp0_128+=2;
        rxdataF_comp1_128+=2;
2668
      }
2669

2670 2671
    } // rb loop
    Nre = (pilots==0) ? 12 : 8;
2672

2673
    precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
2674
                                                        (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
2675

2676
    precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre],
2677
                                                        (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
2678
  } // rx_antennas
2679

2680 2681
  measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot);
  measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot);
2682

2683
 // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol,
2684
     //  measurements->precoded_cqi_dB[eNB_id][0]);
2685

2686
  _mm_empty();
2687
  _m_empty();
2688

lukashov's avatar
lukashov committed
2689
  #elif defined(__arm__)
2690

2691 2692
  unsigned short rb,Nre;
  unsigned char aarx,symbol_mod,pilots=0;
2693
  int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction;
2694 2695 2696
  int16x4_t *dl_ch0_128,*rxdataF128;
  int16x4_t *dl_ch1_128;
  int16x8_t *dl_ch0_128b,*dl_ch1_128b;
2697

2698 2699 2700 2701
  int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b;
  int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128;
  int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b;
  int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
2702

2703 2704 2705
  int **rxdataF_ext           = pdsch_vars->rxdataF_ext;
  int **dl_ch_estimates_ext   = pdsch_vars->dl_ch_estimates_ext;
  int **dl_ch_mag0            = pdsch_vars->dl_ch_mag0;
2706
  int **dl_ch_mag1            = pdsch_vars->dl_ch_mag1[harq_pid][round];
2707
  int **dl_ch_magb0           = pdsch_vars->dl_ch_magb0;
2708
  int **dl_ch_magb1           = pdsch_vars->dl_ch_magb1[harq_pid][round];
2709
  int **rxdataF_comp0         = pdsch_vars->rxdataF_comp0;
2710
  int **rxdataF_comp1         = pdsch_vars->rxdataF_comp1[harq_pid][round];
2711

2712
  int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
2713

2714
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
2715

2716
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
2717 2718
    if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size
      { nb_rb=1+(5*nb_rb/6); }
2719

2720 2721
    else
      { pilots=1; }
2722
  }
2723

lukashov's avatar
lukashov committed
2724
  rx_power_correction=1;
2725

2726
  if (mod_order0 == 4) {
2727 2728
    QAM_amp0_128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
    QAM_amp0_128b = vmovq_n_s16(0);
2729

2730
  } else if (mod_order0 == 6) {
2731 2732
    QAM_amp0_128  = vmovq_n_s16(QAM64_n1); //
    QAM_amp0_128b = vmovq_n_s16(QAM64_n2);
2733
  }
2734

2735
  if (mod_order1 == 4) {
2736 2737
    QAM_amp1_128  = vmovq_n_s16(QAM16_n1);  // 2/sqrt(10)
    QAM_amp1_128b = vmovq_n_s16(0);
2738

2739
  } else if (mod_order1 == 6) {
2740 2741
    QAM_amp1_128  = vmovq_n_s16(QAM64_n1); //
    QAM_amp1_128b = vmovq_n_s16(QAM64_n2);
2742
  }
2743

2744
  //    printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
2745

2746
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
2747 2748 2749



2750 2751 2752 2753
    dl_ch0_128          = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128          = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch0_128b          = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128b          = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
2754
    dl_ch_mag0_128      = (int16x8_t*)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12];
2755
    dl_ch_mag0_128b     = (int16x8_t*)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];
2756
    dl_ch_mag1_128      = (int16x8_t*)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12];
2757
    dl_ch_mag1_128b     = (int16x8_t*)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12];
2758 2759 2760
    rxdataF128          = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp0_128   = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp1_128   = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12];
2761

2762
    for (rb=0; rb<nb_rb; rb++) {
lukashov's avatar
lukashov committed
2763 2764 2765 2766
      // combine TX channels using precoder from pmi
      if (mimo_mode==LARGE_CDD) {
        prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]);
2767 2768


lukashov's avatar
lukashov committed
2769
        if (pilots==0) {
2770
          prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]);
lukashov's avatar
lukashov committed
2771 2772 2773
        }
      }
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) {
2774 2775 2776
        prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]);

lukashov's avatar
lukashov committed
2777
        if (pilots==0) {
2778
          prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]);
lukashov's avatar
lukashov committed
2779 2780 2781 2782 2783
        }
      }
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) {
        prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]);
        prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]);
2784

lukashov's avatar
lukashov committed
2785
        if (pilots==0) {
2786
          prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]);
lukashov's avatar
lukashov committed
2787 2788 2789 2790 2791
        }
      }
      else {
        LOG_E(PHY,"Unknown MIMO mode\n");
        return;
2792 2793
      }

2794

2795
      if (mod_order0>2) {
2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830
        // get channel amplitude if not QPSK
        mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]);
        // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
        mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
        // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
        mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]);
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));

        if (pilots==0) {
          mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]);
          mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
          mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]);
          mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
          mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));


        }

        dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b);
        dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b);
        dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128);
        dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128);


        if (pilots==0) {
          dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b);
          dl_ch_mag0_128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp0_128);
        }
2831 2832 2833
      }

      if (mod_order1>2) {
2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868
        // get channel amplitude if not QPSK
        mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]);
        // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
        mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
        // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
        mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]);
        mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
        mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]);
        mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
        mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));

        if (pilots==0) {
          mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]);
          mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
          mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]);
          mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
          mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));


        }

        dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b);
        dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b);
        dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128);
        dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128);


        if (pilots==0) {
          dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b);
          dl_ch_mag1_128[2]  = vqdmulhq_s16(mmtmpD4,QAM_amp1_128);
        }
2869
      }
2870

2871
      mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]);
2872
      //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
2873
      mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]);
2874
      //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
2875
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2876
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2877 2878
      //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]

2879
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
2880
      //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
2881
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
2882
      //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
2883
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2884
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2885
      //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
2886

2887 2888 2889
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
      rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2890

2891 2892 2893
      mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]);
      mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]);
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2894
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2895

2896 2897 2898
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2899
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2900

2901 2902 2903
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
      rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2904

2905 2906 2907 2908
      // second stream
      mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]);
      mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]);
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2909
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2910
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]);
2911

2912 2913 2914
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]);
      //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2915
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2916
      //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
2917

2918 2919 2920
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
      rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2921

2922 2923 2924
      mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]);
      mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]);
      mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
2925
                             vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
2926

2927 2928 2929
      mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]);
      mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]);
      mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
2930
                             vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
2931

2932 2933 2934
      mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
      mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
      rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2935

2936
      if (pilots==0) {
2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964
        mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]);
        mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]);
        mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
                               vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));

        mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
        mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
        mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
                               vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));


        mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
        mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
        rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
        mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]);
        mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]);
        mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
                               vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));

        mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]);
        mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]);
        mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
                               vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));


        mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
        mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
        rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
2965 2966
      }
    }
2967 2968 2969



2970
    Nre = (pilots==0) ? 12 : 8;
2971

2972 2973
    // rx_antennas
  }
2974 2975


2976
  Nre = (pilots==0) ? 12 : 8;
2977

2978
  precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre],
2979
                                                        (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
2980
  precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre],
2981
                                                        (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx]));
2982

2983 2984
  measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot);
  measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot);
2985

2986
#endif
2987
}
2988

2989

2990 2991 2992 2993 2994 2995
void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
                                   unsigned char symbol,
                                   unsigned short nb_rb,
                                   int **dl_ch_estimates_ext,
                                   int **dl_ch_estimates_ext_i,
                                   int **dl_ch_rho_ext,
2996 2997 2998
                                   unsigned char output_shift)
{

2999 3000
#if defined(__x86_64__)||defined(__i386__)

3001
  unsigned short rb;
3002
  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
3003
  unsigned char aarx,symbol_mod,pilots=0;
3004

3005 3006 3007
  //    printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
3008

3009 3010 3011
  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
    pilots=1;
  }
3012

3013 3014
  //  printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i);

3015
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3016 3017 3018



3019
 //printf ("antenna %d", aarx);
3020
    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
3021

3022 3023 3024 3025
    if (dl_ch_estimates_ext_i == NULL) // TM3/4
      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
    else
      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12];
3026

3027
    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12];
3028 3029 3030


    for (rb=0; rb<nb_rb; rb++) {
3031 3032
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
3033
      //      print_ints("re",&mmtmpD0);
3034 3035 3036 3037 3038
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]);
3039
      //      print_ints("im",&mmtmpD1);
3040 3041
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
3042
      //      print_ints("re(shift)",&mmtmpD0);
3043
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
3044
      //      print_ints("im(shift)",&mmtmpD1);
3045 3046
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
3047 3048
      //      print_ints("c0",&mmtmpD2);
      //      print_ints("c1",&mmtmpD3);
3049
      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
3050
    // print_shorts("rho 0:",dl_ch_rho128);
3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);
3064

3065 3066

      if (pilots==0) {
lukashov's avatar
lukashov committed
3067

3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080
        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
        dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
3081

3082 3083 3084 3085 3086 3087 3088 3089 3090
       dl_ch128+=3;
        dl_ch128i+=3;
        dl_ch_rho128+=3;
      } else {

        dl_ch128+=2;
        dl_ch128i+=2;
        dl_ch_rho128+=2;
      }
3091
    }
3092

3093
  }
3094

3095 3096 3097 3098 3099 3100 3101 3102
  _mm_empty();
  _m_empty();

#elif defined(__arm__)

#endif
}

3103

3104
/*void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
3105 3106 3107 3108 3109 3110
                                   unsigned char symbol,
                                   unsigned short nb_rb,
                                   int **dl_ch_estimates_ext,
                                   int **dl_ch_estimates_ext_i,
                                   int **dl_ch_rho_ext,
                                   unsigned char output_shift0,
3111
                                   unsigned char output_shift1)
3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
{

#if defined(__x86_64__)||defined(__i386__)

  unsigned short rb;
  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
  unsigned char aarx,symbol_mod,pilots=0;
  int output_shift;

  //    printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
    pilots=1;
  }

  //  printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i);

  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3132

3133
       if (aarx==0) {
3134
      output_shift=output_shift0;
3135 3136
    }
      else {
3137
        output_shift=output_shift1;
3138
      }
3139

3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185
 //printf ("antenna %d", aarx);
    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];

    if (dl_ch_estimates_ext_i == NULL) // TM3/4
      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
    else
      dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12];

    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12];


    for (rb=0; rb<nb_rb; rb++) {
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
      //      print_ints("re",&mmtmpD0);
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]);
      //      print_ints("im",&mmtmpD1);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
      //      print_ints("re(shift)",&mmtmpD0);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
      //      print_ints("im(shift)",&mmtmpD1);
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
      //      print_ints("c0",&mmtmpD2);
      //      print_ints("c1",&mmtmpD3);
      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
    // print_shorts("rho 0:",dl_ch_rho128);
      // multiply by conjugated channel
      mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
      mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
      mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
      mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
      mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3);

3186 3187

      if (pilots==0) {
3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201

        // multiply by conjugated channel
        mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]);
        // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
        mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
        mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
        mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]);
        // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
        mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
        mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
        mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
        dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
3202

3203 3204 3205 3206 3207 3208 3209 3210 3211
       dl_ch128+=3;
        dl_ch128i+=3;
        dl_ch_rho128+=3;
      } else {

        dl_ch128+=2;
        dl_ch128i+=2;
        dl_ch_rho128+=2;
      }
3212
    }
3213 3214

  }
3215

3216 3217 3218 3219 3220 3221 3222
  _mm_empty();
  _m_empty();

#elif defined(__arm__)

#endif
}
3223
*/
3224

3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235
void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
                         int **rxdataF_comp,
                         int **rxdataF_comp_i,
                         int **rho,
                         int **rho_i,
                         int **dl_ch_mag,
                         int **dl_ch_magb,
                         int **dl_ch_mag_i,
                         int **dl_ch_magb_i,
                         unsigned char symbol,
                         unsigned short nb_rb,
3236 3237 3238
                         unsigned char dual_stream_UE)
{

3239 3240
#if defined(__x86_64__)||defined(__i386__)

3241 3242
  unsigned char aatx;
  int i;
3243
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,
3244
    *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b;
3245 3246 3247

  if (frame_parms->nb_antennas_rx>1) {

Xiwen JIANG's avatar
Xiwen JIANG committed
3248
    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
3249 3250 3251 3252 3253 3254 3255

      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0      = (__m128i *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1      = (__m128i *)&dl_ch_mag[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
3256 3257 3258

      // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
      for (i=0;i<nb_rb*3;i++) {
3259 3260 3261 3262
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
        dl_ch_mag128_0[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
        dl_ch_mag128_0b[i]   = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
          //       print_shorts("mrc comp0:",&rxdataF_comp128_0[i]);
3263 3264
        //       print_shorts("mrc mag0:",&dl_ch_mag128_0[i]);
        //       print_shorts("mrc mag0b:",&dl_ch_mag128_0b[i]);
3265
        //      print_shorts("mrc rho1:",&rho128_1[i]);
3266

3267 3268 3269 3270 3271 3272 3273
      }
    }

    if (rho) {
      rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
      rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
      for (i=0;i<nb_rb*3;i++) {
3274 3275 3276
        //      print_shorts("mrc rho0:",&rho128_0[i]);
        //      print_shorts("mrc rho1:",&rho128_1[i]);
        rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
3277 3278 3279 3280 3281 3282 3283
      }
    }


    if (dual_stream_UE == 1) {
      rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
      rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
3284 3285 3286 3287 3288
      rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i0      = (__m128i *)&dl_ch_mag_i[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i1      = (__m128i *)&dl_ch_mag_i[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i0b     = (__m128i *)&dl_ch_magb_i[0][symbol*frame_parms->N_RB_DL*12];
3289
      dl_ch_mag128_i1b     = (__m128i *)&dl_ch_magb_i[1][symbol*frame_parms->N_RB_DL*12];
3290 3291

      for (i=0; i<nb_rb*3; i++) {
3292 3293
        rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
        rho128_i0[i]           = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
3294

3295 3296
        dl_ch_mag128_i0[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1));
        dl_ch_mag128_i0b[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1));
3297 3298 3299
      }
    }
  }
3300

3301 3302
  _mm_empty();
  _m_empty();
3303 3304 3305

#elif defined(__arm__)

3306 3307 3308 3309 3310 3311
  unsigned char aatx;
  int i;
  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b;

  if (frame_parms->nb_antennas_rx>1) {

Xiwen JIANG's avatar
Xiwen JIANG committed
3312
    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361

      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0      = (int16x8_t *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1      = (int16x8_t *)&dl_ch_mag[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1b     = (int16x8_t *)&dl_ch_magb[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];

      // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
      for (i=0; i<nb_rb*3; i++) {
        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
        dl_ch_mag128_0[i]    = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
        dl_ch_mag128_0b[i]   = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
      }
    }

    if (rho) {
      rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12];
      rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12];

      for (i=0; i<nb_rb*3; i++) {
        //  print_shorts("mrc rho0:",&rho128_0[i]);
        //  print_shorts("mrc rho1:",&rho128_1[i]);
        rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
      }
    }


    if (dual_stream_UE == 1) {
      rho128_i0 = (int16x8_t *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
      rho128_i1 = (int16x8_t *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_i0   = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_i1   = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];

      dl_ch_mag128_i0      = (int16x8_t *)&dl_ch_mag_i[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i1      = (int16x8_t *)&dl_ch_mag_i[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i0b     = (int16x8_t *)&dl_ch_magb_i[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i1b     = (int16x8_t *)&dl_ch_magb_i[1][symbol*frame_parms->N_RB_DL*12];

      for (i=0; i<nb_rb*3; i++) {
        rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]);
        rho128_i0[i]          = vhaddq_s16(rho128_i0[i],rho128_i1[i]);

        dl_ch_mag128_i0[i]    = vhaddq_s16(dl_ch_mag128_i0[i],dl_ch_mag128_i1[i]);
        dl_ch_mag128_i0b[i]   = vhaddq_s16(dl_ch_mag128_i0b[i],dl_ch_mag128_i1b[i]);
      }
    }
  }

3362
#endif
3363 3364
}

3365 3366

void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms,
3367
                              LTE_UE_PDSCH *pdsch_vars,
3368 3369 3370 3371 3372
                              int harq_pid,
                              int round,
                              unsigned char symbol,
                              unsigned short nb_rb,
                              unsigned char dual_stream_UE) {
3373

3374 3375 3376
  int i;
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b;

3377 3378 3379 3380 3381 3382 3383 3384
  int **rxdataF_comp0           = pdsch_vars->rxdataF_comp0;
  int **rxdataF_comp1           = pdsch_vars->rxdataF_comp1[harq_pid][round];
  int **dl_ch_rho_ext           = pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream
  int **dl_ch_rho2_ext          = pdsch_vars->dl_ch_rho2_ext;
  int **dl_ch_mag0              = pdsch_vars->dl_ch_mag0;
  int **dl_ch_mag1              = pdsch_vars->dl_ch_mag1[harq_pid][round];
  int **dl_ch_magb0             = pdsch_vars->dl_ch_magb0;
  int **dl_ch_magb1             = pdsch_vars->dl_ch_magb1[harq_pid][round];
3385

3386
  if (frame_parms->nb_antennas_rx>1) {
3387 3388 3389 3390 3391 3392 3393

      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0      = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1      = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_0b     = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_1b     = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12];
3394 3395 3396 3397 3398 3399

      // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
      for (i=0;i<nb_rb*3;i++) {
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
        dl_ch_mag128_0[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
        dl_ch_mag128_0b[i]   = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
3400

3401 3402 3403
        // print_shorts("mrc compens0:",&rxdataF_comp128_0[i]);
        // print_shorts("mrc mag128_0:",&dl_ch_mag128_0[i]);
        // print_shorts("mrc mag128_0b:",&dl_ch_mag128_0b[i]);
3404
      }    }
3405 3406

   // if (rho) {
lukashov's avatar
lukashov committed
3407 3408
      rho128_0 = (__m128i *) &dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12];
      rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12];
3409 3410 3411 3412 3413 3414 3415 3416 3417
      for (i=0;i<nb_rb*3;i++) {
           //  print_shorts("mrc rho0:",&rho128_0[i]);
            //  print_shorts("mrc rho1:",&rho128_1[i]);
        rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
      }
   //}


    if (dual_stream_UE == 1) {
lukashov's avatar
lukashov committed
3418 3419
      rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12];
      rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12];
3420 3421 3422 3423 3424
      rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i0      = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i1      = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12];
      dl_ch_mag128_i0b     = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12];
3425 3426 3427 3428
      dl_ch_mag128_i1b     = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12];
      for (i=0;i<nb_rb*3;i++) {
        rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
        rho128_i0[i]           = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
3429

3430 3431
        dl_ch_mag128_i0[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1));
        dl_ch_mag128_i0b[i]    = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1));
3432

3433 3434 3435
        //print_shorts("mrc compens1:",&rxdataF_comp128_i0[i]);
        //print_shorts("mrc mag128_i0:",&dl_ch_mag128_i0[i]);
        //print_shorts("mrc mag128_i0b:",&dl_ch_mag128_i0b[i]);
3436 3437
      }
    }
3438

3439 3440 3441 3442 3443 3444 3445

  _mm_empty();
  _m_empty();
}



3446 3447 3448
void dlsch_scale_channel(int **dl_ch_estimates_ext,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         LTE_UE_DLSCH_t **dlsch_ue,
3449
                         uint8_t symbol,
3450 3451
                         unsigned short nb_rb)
{
3452

3453
#if defined(__x86_64__)||defined(__i386__)
3454 3455 3456

  short rb, ch_amp;
  unsigned char aatx,aarx,pilots=0,symbol_mod;
3457 3458
  __m128i *dl_ch128, ch_amp128;

3459 3460 3461
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
3462
    if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size
3463
      nb_rb=1+(5*nb_rb/6);
3464
    else
3465 3466 3467 3468
      pilots=1;
  }

  // Determine scaling amplitude based the symbol
3469

3470
ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
3471

gabrielC's avatar
gabrielC committed
3472
    LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol);
lukashov's avatar
lukashov committed
3473
   // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
3474 3475 3476

  ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13

Xiwen JIANG's avatar
Xiwen JIANG committed
3477
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
3478
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3479 3480

      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
3481

3482
      for (rb=0;rb<nb_rb;rb++) {
3483

3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495
        dl_ch128[0] = _mm_mulhi_epi16(dl_ch128[0],ch_amp128);
        dl_ch128[0] = _mm_slli_epi16(dl_ch128[0],3);

        dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128);
        dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3);

        if (pilots) {
          dl_ch128+=2;
        } else {
          dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128);
          dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3);
          dl_ch128+=3;
lukashov's avatar
lukashov committed
3496

3497 3498
        }
      }
3499 3500
    }
  }
3501

3502 3503 3504
#elif defined(__arm__)

#endif
3505 3506
}

3507

3508 3509
//compute average channel_level on each (TX,RX) antenna pair
void dlsch_channel_level(int **dl_ch_estimates_ext,
3510
                         LTE_DL_FRAME_PARMS *frame_parms,
gabrielC's avatar
gabrielC committed
3511
                         int32_t *avg,
3512
                         uint8_t symbol,
3513 3514
                         unsigned short nb_rb)
{
3515

3516
#if defined(__x86_64__)||defined(__i386__)
3517 3518 3519

  short rb;
  unsigned char aatx,aarx,nre=12,symbol_mod;
3520
  __m128i *dl_ch128, avg128D;
3521

3522 3523
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

3524 3525 3526 3527 3528 3529 3530
  if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
    nre=8;
  else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
    nre=10;
  else
    nre=12;

3531
  //nb_rb*nre = y * 2^x
3532
  int16_t x = factor2(nb_rb*nre);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
3533
  int16_t y = (nb_rb*nre)>>x;
3534
  //printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x);
gabrielC's avatar
gabrielC committed
3535

Xiwen JIANG's avatar
Xiwen JIANG committed
3536
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
3537
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3538
      //clear average level
3539
      avg128D = _mm_setzero_si128();
3540 3541 3542 3543 3544
      // 5 is always a symbol with no pilots for both normal and extended prefix

      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];

      for (rb=0;rb<nb_rb;rb++) {
3545 3546
        //      printf("rb %d : ",rb);
        //      print_shorts("ch",&dl_ch128[0]);
3547 3548 3549 3550 3551
	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));

        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
gabrielC's avatar
gabrielC committed
3552

3553
        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
3554
          dl_ch128+=2;
3555 3556
        }
        else {
3557 3558
	  avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
          //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15)));
3559
          dl_ch128+=3;
3560 3561 3562 3563 3564 3565 3566 3567
        }
        /*
          if (rb==0) {
          print_shorts("dl_ch128",&dl_ch128[0]);
          print_shorts("dl_ch128",&dl_ch128[1]);
          print_shorts("dl_ch128",&dl_ch128[2]);
          }
        */
3568 3569
      }

gabrielC's avatar
gabrielC committed
3570 3571 3572
      avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] +
                            ((int32_t*)&avg128D)[1] +
                            ((int32_t*)&avg128D)[2] +
3573
			      ((int32_t*)&avg128D)[3])/y;
lukashov's avatar
lukashov committed
3574
                //  printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
3575
    }
3576

3577 3578 3579
  _mm_empty();
  _m_empty();

3580
#elif defined(__arm__)
3581 3582

  short rb;
3583 3584 3585
  unsigned char aatx,aarx,nre=12,symbol_mod;
  int32x4_t avg128D;
  int16x4_t *dl_ch128;
3586 3587 3588

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

Xiwen JIANG's avatar
Xiwen JIANG committed
3589
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
3590 3591 3592 3593
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
      //clear average level
      avg128D = vdupq_n_s32(0);
      // 5 is always a symbol with no pilots for both normal and extended prefix
3594

3595
      dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
3596

3597 3598 3599 3600 3601 3602 3603
      for (rb=0; rb<nb_rb; rb++) {
        //  printf("rb %d : ",rb);
        //  print_shorts("ch",&dl_ch128[0]);
        avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0]));
        avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[1],dl_ch128[1]));
        avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[2],dl_ch128[2]));
        avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[3],dl_ch128[3]));
3604

3605 3606 3607 3608 3609 3610 3611
        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
          dl_ch128+=4;
        } else {
          avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[4],dl_ch128[4]));
          avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[5],dl_ch128[5]));
          dl_ch128+=6;
        }
3612

3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637
        /*
          if (rb==0) {
          print_shorts("dl_ch128",&dl_ch128[0]);
          print_shorts("dl_ch128",&dl_ch128[1]);
          print_shorts("dl_ch128",&dl_ch128[2]);
          }
        */
      }

      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
        nre=8;
      else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
        nre=10;
      else
        nre=12;

      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128D)[0] +
                             ((int32_t*)&avg128D)[1] +
                             ((int32_t*)&avg128D)[2] +
                             ((int32_t*)&avg128D)[3])/(nb_rb*nre);

      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
    }


3638
#endif
3639 3640
}

lukashov's avatar
lukashov committed
3641 3642
//compute average channel_level of effective (precoded) channel

3643
//compute average channel_level of effective (precoded) channel
lukashov's avatar
lukashov committed
3644 3645
void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
                              LTE_DL_FRAME_PARMS *frame_parms,
3646
                              unsigned char *pmi_ext,
3647
                              int *avg_0,
3648
                              int *avg_1,
lukashov's avatar
lukashov committed
3649 3650 3651 3652
                              uint8_t symbol,
                              unsigned short nb_rb,
                              MIMO_mode_t mimo_mode){

3653
#if defined(__x86_64__)||defined(__i386__)
3654

lukashov's avatar
lukashov committed
3655

3656 3657
  short rb;
  unsigned char aarx,nre=12,symbol_mod;
3658
  __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D;
3659 3660 3661 3662

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

  //clear average level
lukashov's avatar
lukashov committed
3663 3664
 // avg_0_128D = _mm_setzero_si128();
 // avg_1_128D = _mm_setzero_si128();
3665 3666 3667 3668
  avg_0[0] = 0;
  avg_0[1] = 0;
  avg_1[0] = 0;
  avg_1[1] = 0;
3669 3670 3671 3672 3673 3674 3675 3676 3677
  // 5 is always a symbol with no pilots for both normal and extended prefix

  if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
    nre=8;
  else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
    nre=10;
  else
    nre=12;

3678
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3679 3680
    dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
3681

3682 3683
    avg_0_128D = _mm_setzero_si128();
    avg_1_128D = _mm_setzero_si128();
3684
    for (rb=0; rb<nb_rb; rb++) {
3685 3686
              // printf("rb %d : \n",rb);
              // print_shorts("ch0\n",&dl_ch0_128[0]);
3687
               //print_shorts("ch1\n",&dl_ch1_128[0]);
3688 3689 3690
      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]);
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]);

3691
      if (mimo_mode==LARGE_CDD)
3692 3693 3694 3695 3696
        prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
        prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
        prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
lukashov's avatar
lukashov committed
3697
      else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING)
3698
        prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3699

3700
      //      mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
3701
      avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3702

3703
      avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp));
3704

3705
      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]);
3706
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]);
3707

3708
      if (mimo_mode==LARGE_CDD)
3709 3710 3711 3712 3713
        prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
        prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
        prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
lukashov's avatar
lukashov committed
3714
      else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING)
3715
        prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3716

3717
      //      mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
3718
      avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3719

3720
      avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp));
3721 3722

      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
3723
        dl_ch0_128+=2;
3724
        dl_ch1_128+=2;
3725 3726
      }
      else {
3727
        dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
3728
        dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
3729

3730
        if (mimo_mode==LARGE_CDD)
3731 3732 3733 3734 3735
          prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
        else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
          prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
        else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
          prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3736 3737
        else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING)
          prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3738
        //      mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
3739

3740 3741
        avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp));
        avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3742 3743

        dl_ch0_128+=3;
3744
        dl_ch1_128+=3;
3745
      }
3746
    }
3747 3748


3749

3750 3751 3752 3753 3754
    avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) +
      (((int*)&avg_0_128D)[1])/(nb_rb*nre) +
      (((int*)&avg_0_128D)[2])/(nb_rb*nre) +
      (((int*)&avg_0_128D)[3])/(nb_rb*nre);
    //  printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]);
3755

3756 3757 3758
    avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) +
      (((int*)&avg_1_128D)[1])/(nb_rb*nre) +
      (((int*)&avg_1_128D)[2])/(nb_rb*nre) +
3759
      (((int*)&avg_1_128D)[3])/(nb_rb*nre);
lukashov's avatar
lukashov committed
3760
  //    printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]);
3761
  }
lukashov's avatar
lukashov committed
3762 3763 3764 3765 3766
//avg_0[0] = max(avg_0[0],avg_0[1]);
//avg_1[0] = max(avg_1[0],avg_1[1]);
//avg_0[0]= max(avg_0[0], avg_1[0]);

  avg_0[0] = avg_0[0] + avg_0[1];
lukashov's avatar
lukashov committed
3767
 // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]);
lukashov's avatar
lukashov committed
3768
  avg_1[0] = avg_1[0] + avg_1[1];
lukashov's avatar
lukashov committed
3769 3770 3771 3772
 // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]);
 avg_0[0] = min (avg_0[0], avg_1[0]);
 avg_1[0] = avg_0[0];

3773 3774
  _mm_empty();
  _m_empty();
3775 3776 3777 3778

#elif defined(__arm__)

#endif
3779 3780
}

lukashov's avatar
lukashov committed
3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820


/*void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
                              LTE_DL_FRAME_PARMS *frame_parms,
                              int *avg,
                              uint8_t symbol,
                              unsigned short nb_rb,
                              MIMO_mode_t mimo_mode){

#if defined(__x86_64__)||defined(__i386__)


  short rb;
  unsigned char aarx,nre=12,symbol_mod;
  __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D;

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

  //clear average level
  avg128D = _mm_setzero_si128();
  avg[0] = 0;
  avg[1] = 0;
  // 5 is always a symbol with no pilots for both normal and extended prefix

  if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
    nre=8;
  else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
    nre=10;
  else
    nre=12;

  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
    dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];

    for (rb=0; rb<nb_rb; rb++) {

      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]);
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]);

3821
      if (mimo_mode==LARGE_CDD)
lukashov's avatar
lukashov committed
3822 3823 3824 3825 3826 3827
        prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
        prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
        prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);

3828
      //      mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
lukashov's avatar
lukashov committed
3829 3830 3831 3832 3833
      avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));

      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]);
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]);

3834
      if (mimo_mode==LARGE_CDD)
lukashov's avatar
lukashov committed
3835 3836 3837 3838 3839 3840
        prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
        prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
      else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
        prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);

3841
      //      mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
lukashov's avatar
lukashov committed
3842 3843 3844
      avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));

      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
3845
        dl_ch0_128+=2;
lukashov's avatar
lukashov committed
3846 3847 3848 3849
        dl_ch1_128+=2;
      }
      else {
        dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
3850
        dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
lukashov's avatar
lukashov committed
3851

3852
        if (mimo_mode==LARGE_CDD)
lukashov's avatar
lukashov committed
3853 3854 3855 3856 3857 3858 3859 3860 3861
          prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp);
        else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1)
          prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp);
        else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj)
          prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp);

        //      mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));

3862
        dl_ch0_128+=3;
lukashov's avatar
lukashov committed
3863
        dl_ch1_128+=3;
3864
      }
lukashov's avatar
lukashov committed
3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883
    }

    avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) +
      (((int*)&avg128D)[1])/(nb_rb*nre) +
      (((int*)&avg128D)[2])/(nb_rb*nre) +
      (((int*)&avg128D)[3])/(nb_rb*nre);
  }

  // choose maximum of the 2 effective channels
  avg[0] = cmax(avg[0],avg[1]);

  _mm_empty();
  _m_empty();

#elif defined(__arm__)

#endif
}*/

3884 3885
//compute average channel_level of effective (precoded) channel
void dlsch_channel_level_TM56(int **dl_ch_estimates_ext,
3886 3887 3888
                              LTE_DL_FRAME_PARMS *frame_parms,
                              unsigned char *pmi_ext,
                              int *avg,
3889
                              uint8_t symbol,
3890 3891
                              unsigned short nb_rb)
{
3892

3893
#if defined(__x86_64__)||defined(__i386__)
3894 3895 3896

  short rb;
  unsigned char aarx,nre=12,symbol_mod;
3897
  __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D;
3898 3899 3900

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

3901 3902
  //clear average level
  avg128D = _mm_setzero_si128();
3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913
  avg[0] = 0;
  avg[1] = 0;
  // 5 is always a symbol with no pilots for both normal and extended prefix

  if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0))
    nre=8;
  else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1))
    nre=10;
  else
    nre=12;

3914
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
3915 3916
    dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
3917

3918
    for (rb=0; rb<nb_rb; rb++) {
3919

3920 3921
      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]);
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]);
3922

3923
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3924
      //      mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
3925
      avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3926

3927
      dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]);
3928
      dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]);
3929

3930
      prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
3931
      //      mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
3932
      avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3933 3934

      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
3935
        dl_ch0_128+=2;
3936
        dl_ch1_128+=2;
3937 3938
      }
      else {
3939
        dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]);
3940
        dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]);
3941

3942 3943 3944
        prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp);
        //      mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp);
        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp));
3945

3946
        dl_ch0_128+=3;
3947
        dl_ch1_128+=3;
3948
      }
3949
    }
3950 3951

    avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) +
3952 3953
      (((int*)&avg128D)[1])/(nb_rb*nre) +
      (((int*)&avg128D)[2])/(nb_rb*nre) +
3954 3955
      (((int*)&avg128D)[3])/(nb_rb*nre);
  }
3956

3957 3958 3959 3960 3961
  // choose maximum of the 2 effective channels
  avg[0] = cmax(avg[0],avg[1]);

  _mm_empty();
  _m_empty();
3962 3963 3964 3965 3966

#elif defined(__arm__)


#endif
3967
}
3968

3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984
//compute average channel_level for TM7
void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         int *avg,
                         uint8_t symbol,
                         unsigned short nb_rb)
{

#if defined(__x86_64__)||defined(__i386__)

  short rb;
  unsigned char aatx,aarx,nre=12,symbol_mod;
  __m128i *dl_ch128,avg128D;

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;

Xiwen JIANG's avatar
Xiwen JIANG committed
3985
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
      //clear average level
      avg128D = _mm_setzero_si128();
      // 5 is always a symbol with no pilots for both normal and extended prefix

      dl_ch128=(__m128i *)&dl_bf_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];

      for (rb=0; rb<nb_rb; rb++) {
        //  printf("rb %d : ",rb);
        //  print_shorts("ch",&dl_ch128[0]);
        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));

        if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) {
          dl_ch128+=2;
        } else {
          avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
          dl_ch128+=3;
        }

        /*
          if (rb==0) {
          print_shorts("dl_ch128",&dl_ch128[0]);
          print_shorts("dl_ch128",&dl_ch128[1]);
          print_shorts("dl_ch128",&dl_ch128[2]);
          }
        */
      }

      if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1))))
        nre=10;
      else if ((frame_parms->Ncp==0) && (symbol==3 || symbol==6 || symbol==9 || symbol==12))
        nre=9;
      else if ((frame_parms->Ncp==1) && (symbol==4 || symbol==7 || symbol==9))
        nre=8;
      else
        nre=12;

      avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] +
                             ((int*)&avg128D)[1] +
                             ((int*)&avg128D)[2] +
                             ((int*)&avg128D)[3])/(nb_rb*nre);

      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
    }

  _mm_empty();
  _m_empty();

#elif defined(__arm__)

#endif
}
4039
//#define ONE_OVER_2_Q15 16384
4040 4041 4042 4043 4044
void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
                    int **rxdataF_comp,
                    int **dl_ch_mag,
                    int **dl_ch_magb,
                    unsigned char symbol,
4045 4046
                    unsigned short nb_rb)
{
4047

4048
#if defined(__x86_64__)||defined(__i386__)
4049 4050

  short *rxF0,*rxF1;
4051
  __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, *rxF0_128;
4052 4053
  unsigned char rb,re;
  int jj = (symbol*frame_parms->N_RB_DL*12);
4054 4055
  uint8_t symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
  uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
4056 4057
  rxF0_128 = (__m128i*) &rxdataF_comp[0][jj];

4058
  //amp = _mm_set1_epi16(ONE_OVER_2_Q15);
4059

4060

4061 4062 4063 4064 4065 4066 4067
  //    printf("Doing alamouti!\n");
  rxF0     = (short*)&rxdataF_comp[0][jj];  //tx antenna 0  h0*y
  rxF1     = (short*)&rxdataF_comp[2][jj];  //tx antenna 1  h1*y
  ch_mag0 = (__m128i *)&dl_ch_mag[0][jj];
  ch_mag1 = (__m128i *)&dl_ch_mag[2][jj];
  ch_mag0b = (__m128i *)&dl_ch_magb[0][jj];
  ch_mag1b = (__m128i *)&dl_ch_magb[2][jj];
4068

4069
  for (rb=0; rb<nb_rb; rb++) {
4070

4071
    for (re=0; re<((pilots==0)?12:8); re+=2) {
4072 4073

      // Alamouti RX combining
4074

4075
      //      printf("Alamouti: symbol %d, rb %d, re %d: rxF0 (%d,%d,%d,%d), rxF1 (%d,%d,%d,%d)\n",symbol,rb,re,rxF0[0],rxF0[1],rxF0[2],rxF0[3],rxF1[0],rxF1[1],rxF1[2],rxF1[3]);
4076
      rxF0[0] = rxF0[0] + rxF1[2];
4077
      rxF0[1] = rxF0[1] - rxF1[3];
4078 4079 4080

      rxF0[2] = rxF0[2] - rxF1[0];
      rxF0[3] = rxF0[3] + rxF1[1];
4081

4082
      //      printf("Alamouti: rxF0 after (%d,%d,%d,%d)\n",rxF0[0],rxF0[1],rxF0[2],rxF0[3]);
4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095
      rxF0+=4;
      rxF1+=4;

    }

    // compute levels for 16QAM or 64 QAM llr unit
    ch_mag0[0] = _mm_adds_epi16(ch_mag0[0],ch_mag1[0]);
    ch_mag0[1] = _mm_adds_epi16(ch_mag0[1],ch_mag1[1]);

    ch_mag0b[0] = _mm_adds_epi16(ch_mag0b[0],ch_mag1b[0]);
    ch_mag0b[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]);

    // account for 1/sqrt(2) scaling at transmission
4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109
    //ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1);
    //ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1);
    //ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1);
    //ch_mag0b[1] = _mm_srai_epi16(ch_mag0b[1],1);

    //rxF0_128[0] = _mm_mulhi_epi16(rxF0_128[0],amp);
    //rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1);
    //rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp);
    //rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1);

    //rxF0_128[0] = _mm_srai_epi16(rxF0_128[0],1);
    //rxF0_128[1] = _mm_srai_epi16(rxF0_128[1],1);


4110 4111 4112 4113 4114

    if (pilots==0) {
      ch_mag0[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]);
      ch_mag0b[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]);

4115 4116 4117 4118 4119 4120 4121
      //ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1);
      //ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1);

      //rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp);
      //rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1);

      //rxF0_128[2] = _mm_srai_epi16(rxF0_128[2],1);
4122 4123 4124 4125 4126 4127 4128


      ch_mag0+=3;
      ch_mag1+=3;
      ch_mag0b+=3;
      ch_mag1b+=3;
      rxF0_128+=3;
4129
    } else {
4130 4131 4132 4133 4134 4135 4136 4137 4138
      ch_mag0+=2;
      ch_mag1+=2;
      ch_mag0b+=2;
      ch_mag1b+=2;
      rxF0_128+=2;
    }
  }

  _mm_empty();
4139
  _m_empty();
4140

4141
#elif defined(__arm__)
4142

4143
#endif
4144 4145
}

4146

4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159
//==============================================================================================
// Extraction functions
//==============================================================================================

unsigned short dlsch_extract_rbs_single(int **rxdataF,
                                        int **dl_ch_estimates,
                                        int **rxdataF_ext,
                                        int **dl_ch_estimates_ext,
                                        unsigned short pmi,
                                        unsigned char *pmi_ext,
                                        unsigned int *rb_alloc,
                                        unsigned char symbol,
                                        unsigned char subframe,
4160
                                        uint32_t high_speed_flag,
4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176
                                        LTE_DL_FRAME_PARMS *frame_parms) {



  unsigned short rb,nb_rb=0;
  unsigned char rb_alloc_ind;
  unsigned char i,aarx,l,nsymb,skip_half=0,sss_symb,pss_symb=0;
  int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;



  unsigned char symbol_mod,pilots=0,j=0,poffset=0;

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
  pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
  l=symbol;
Raymond Knopp's avatar
 
Raymond Knopp committed
4177
  nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
4178

Raymond Knopp's avatar
 
Raymond Knopp committed
4179
  if (frame_parms->frame_type == TDD) {  // TDD
4180 4181
    sss_symb = nsymb-1;
    pss_symb = 2;
4182
  } else {
4183 4184 4185
    sss_symb = (nsymb>>1)-2;
    pss_symb = (nsymb>>1)-1;
  }
4186

4187 4188 4189
  if (symbol_mod==(4-frame_parms->Ncp))
    poffset=3;

4190
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
4191 4192 4193 4194 4195

    if (high_speed_flag == 1)
      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
    else
      dl_ch0     = &dl_ch_estimates[aarx][5];
4196

4197 4198 4199 4200
    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];

    rxF_ext   = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
    rxF       = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
4201

4202
    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
4203

4204
      for (rb=0;rb<frame_parms->N_RB_DL;rb++) {
4205

4206 4207 4208 4209 4210 4211 4212 4213 4214 4215
        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;
4216

4217
        if (rb_alloc_ind == 1)
4218 4219
          nb_rb++;

4220 4221 4222
        // For second half of RBs skip DC carrier
        if (rb==(frame_parms->N_RB_DL>>1)) {
          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
4223
          //dl_ch0++;
4224
        }
4225

4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250
        // PBCH
        if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }

        //SSS
        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }


        if (frame_parms->frame_type == FDD) {
          //PSS
          if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }

        if ((frame_parms->frame_type == TDD) &&
            (subframe==6)) { //TDD Subframe 6
          if ((rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }

4251 4252 4253
        if (rb_alloc_ind==1) {
          *pmi_ext = (pmi>>((rb>>2)<<1))&3;
          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
4254 4255

          /*
4256 4257 4258 4259
            printf("rb %d\n",rb);
            for (i=0;i<12;i++)
            printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
            printf("\n");
4260 4261
          */
          if (pilots==0) {
4262
            for (i=0; i<12; i++) {
4263
              rxF_ext[i]=rxF[i];
4264
              /*
4265 4266
                printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),
                ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/
4267
            }
4268

4269 4270
            dl_ch0_ext+=12;
            rxF_ext+=12;
4271
          } else {
4272
            j=0;
4273 4274

            for (i=0; i<12; i++) {
4275 4276 4277
              if ((i!=(frame_parms->nushift+poffset)) &&
                  (i!=((frame_parms->nushift+poffset+6)%12))) {
                rxF_ext[j]=rxF[i];
4278
                //            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4279
                dl_ch0_ext[j++]=dl_ch0[i];
4280

4281 4282
              }
            }
4283

4284 4285 4286
            dl_ch0_ext+=10;
            rxF_ext+=10;
          }
4287

4288

4289
        }
4290

4291 4292
        dl_ch0+=12;
        rxF+=12;
4293 4294 4295

      }
    else {  // Odd number of RBs
4296
      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
4297
#ifdef DEBUG_DLSCH_DEMOD
4298
        printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
4299
#endif
4300
        skip_half=0;
4301

4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312
        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;

4313 4314
        if (rb_alloc_ind == 1)
          nb_rb++;
4315

4316 4317 4318 4319 4320

        // PBCH
        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }
4321

4322 4323 4324 4325 4326
        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=1;
        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=2;
4327

4328 4329
        //SSS

4330 4331 4332
        if (((subframe==0)||(subframe==5)) &&
            (rb>((frame_parms->N_RB_DL>>1)-3)) &&
            (rb<((frame_parms->N_RB_DL>>1)+3)) &&
4333 4334 4335
            (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }
4336 4337 4338
        //SSS
        if (((subframe==0)||(subframe==5)) &&
            (rb==((frame_parms->N_RB_DL>>1)-3)) &&
4339 4340
            (l==sss_symb))
          skip_half=1;
4341 4342
        else if (((subframe==0)||(subframe==5)) &&
                 (rb==((frame_parms->N_RB_DL>>1)+3)) &&
4343 4344 4345 4346 4347
                 (l==sss_symb))
          skip_half=2;

        //PSS in subframe 0/5 if FDD
        if (frame_parms->frame_type == FDD) {  //FDD
lukashov's avatar
lukashov committed
4348

4349
          if (((subframe==0)||(subframe==5)) &&
4350 4351 4352
              (rb>((frame_parms->N_RB_DL>>1)-3)) &&
              (rb<((frame_parms->N_RB_DL>>1)+3)) &&
              (l==pss_symb) ) {
4353 4354
            rb_alloc_ind = 0;
          }
4355

4356 4357 4358 4359 4360
          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }
4361

4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375
        if ((frame_parms->frame_type == TDD) &&
            (subframe==6)){  //TDD Subframe 6
          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }


        if (rb_alloc_ind==1) {

4376
#ifdef DEBUG_DLSCH_DEMOD
4377
          printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
4378
#endif
4379
          if (pilots==0) {
4380
            //      printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
4381 4382
            if (skip_half==1) {
              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
4383

4384
              for (i=0; i<6; i++) {
4385
                rxF_ext[i]=rxF[i];
4386
#ifdef DEBUG_DLSCH_DEMOD
4387
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
4388
#endif
4389
              }
4390 4391
              dl_ch0_ext+=6;
              rxF_ext+=6;
4392
            } else if (skip_half==2) {
4393
              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));
4394

4395
              for (i=0; i<6; i++) {
4396
                rxF_ext[i]=rxF[(i+6)];
4397
#ifdef DEBUG_DLSCH_DEMOD
4398
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
4399
#endif
4400
              }
4401 4402
              dl_ch0_ext+=6;
              rxF_ext+=6;
4403
            } else {
4404
              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
4405

4406
              for (i=0; i<12; i++) {
4407
                rxF_ext[i]=rxF[i];
4408 4409 4410
#ifdef DEBUG_DLSCH_DEMOD
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
#endif
4411
              }
4412 4413 4414
              dl_ch0_ext+=12;
              rxF_ext+=12;
            }
4415
          } else {
4416
            //      printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
4417
            j=0;
4418

4419
            if (skip_half==1) {
4420
              for (i=0; i<6; i++) {
4421 4422
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[i];
4423 4424 4425
#ifdef DEBUG_DLSCH_DEMOD
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
4426 4427 4428
                  dl_ch0_ext[j++]=dl_ch0[i];
                }
              }
4429
              rxF_ext+=5;
4430
              dl_ch0_ext+=5;
4431 4432
            } else if (skip_half==2) {
              for (i=0; i<6; i++) {
4433 4434
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[(i+6)];
4435
#ifdef DEBUG_DLSCH_DEMOD
4436
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4437
#endif
4438 4439 4440
                  dl_ch0_ext[j++]=dl_ch0[i+6];
                }
              }
4441

4442 4443
              dl_ch0_ext+=5;
              rxF_ext+=5;
4444 4445
            } else {
              for (i=0; i<12; i++) {
4446 4447 4448
                if ((i!=(frame_parms->nushift+poffset)) &&
                    (i!=((frame_parms->nushift+poffset+6)%12))) {
                  rxF_ext[j]=rxF[i];
4449
#ifdef DEBUG_DLSCH_DEMOD
4450
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4451
#endif
4452
                  dl_ch0_ext[j++]=dl_ch0[i];
4453

4454 4455
                }
              }
4456

4457 4458 4459 4460
              dl_ch0_ext+=10;
              rxF_ext+=10;
            }
          }
4461
        }
4462 4463
        dl_ch0+=12;
        rxF+=12;
4464 4465 4466 4467 4468
      } // first half loop


      // Do middle RB (around DC)
      if (rb < 32)
4469
        rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
4470
      else if (rb < 64)
4471
        rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
4472
      else if (rb < 96)
4473
        rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
4474
      else if (rb < 100)
4475
        rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
4476
      else
4477
        rb_alloc_ind = 0;
4478

4479

4480
      if (rb_alloc_ind == 1)
4481
        nb_rb++;
4482 4483

      // PBCH
lukashov's avatar
lukashov committed
4484

4485
      if ((subframe==0) &&
4486 4487
          (l>=(nsymb>>1)) &&
          (l<((nsymb>>1) + 4))) {
4488
        rb_alloc_ind = 0;
4489
      }
4490

4491
      //SSS
Raymond Knopp's avatar
Raymond Knopp committed
4492
      if (((subframe==0)||(subframe==5)) && (l==sss_symb) ) {
4493
        rb_alloc_ind = 0;
4494
      }
4495

Raymond Knopp's avatar
 
Raymond Knopp committed
4496
      if (frame_parms->frame_type == FDD) {
4497
        //PSS
Raymond Knopp's avatar
Raymond Knopp committed
4498
        if (((subframe==0)||(subframe==5)) && (l==pss_symb) ) {
4499 4500
          rb_alloc_ind = 0;
        }
4501 4502
      }

Raymond Knopp's avatar
Raymond Knopp committed
4503
      //PSS
Raymond Knopp's avatar
 
Raymond Knopp committed
4504
      if ((frame_parms->frame_type == TDD) &&
Raymond Knopp's avatar
Raymond Knopp committed
4505
          (subframe==6) &&
4506 4507
          (l==pss_symb) ) {
        rb_alloc_ind = 0;
4508
      }
4509

4510 4511

      //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
4512 4513
      //      printf("DC rb %d (%p)\n",rb,rxF);
      if (rb_alloc_ind==1) {
4514
#ifdef DEBUG_DLSCH_DEMOD
4515
        printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
4516
#endif
4517
        if (pilots==0) {
4518
          for (i=0; i<6; i++) {
4519 4520 4521
            dl_ch0_ext[i]=dl_ch0[i];
            rxF_ext[i]=rxF[i];
          }
4522

4523
          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
4524 4525

          for (; i<12; i++) {
4526 4527 4528
            dl_ch0_ext[i]=dl_ch0[i];
            rxF_ext[i]=rxF[(1+i-6)];
          }
4529

4530 4531
          dl_ch0_ext+=12;
          rxF_ext+=12;
4532
        } else { // pilots==1
4533
          j=0;
4534 4535

          for (i=0; i<6; i++) {
4536 4537 4538
            if (i!=((frame_parms->nushift+poffset)%6)) {
              dl_ch0_ext[j]=dl_ch0[i];
              rxF_ext[j++]=rxF[i];
4539 4540 4541
#ifdef DEBUG_DLSCH_DEMOD
              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
#endif
4542 4543
            }
          }
4544

4545
          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
4546 4547

          for (; i<12; i++) {
4548 4549 4550
            if (i!=((frame_parms->nushift+6+poffset)%12)) {
              dl_ch0_ext[j]=dl_ch0[i];
              rxF_ext[j++]=rxF[(1+i-6)];
4551 4552
#ifdef DEBUG_DLSCH_DEMOD
              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
4553
#endif
4554 4555
            }
          }
4556

4557 4558 4559
          dl_ch0_ext+=10;
          rxF_ext+=10;
        } // symbol_mod==0
4560 4561
      } // rballoc==1
      else {
4562
        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
4563
      }
4564

4565 4566 4567
      dl_ch0+=12;
      rxF+=7;
      rb++;
4568

4569
      for (;rb<frame_parms->N_RB_DL;rb++) {
4570
        //      printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
4571 4572
        //      printf("rb %d (%p)\n",rb,rxF);
        skip_half=0;
4573

4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584
        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;

4585 4586
        if (rb_alloc_ind == 1)
          nb_rb++;
4587 4588 4589 4590 4591 4592 4593 4594 4595 4596

        // PBCH
        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }
        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=1;
        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=2;
4597

4598 4599 4600 4601
        //SSS
        if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }
4602
        //SSS
4603 4604 4605 4606 4607 4608 4609 4610 4611
        if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb))
          skip_half=1;
        else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb))
          skip_half=2;
        if (frame_parms->frame_type == FDD) {
          //PSS
          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
4612 4613

          //PSS
lukashov's avatar
lukashov committed
4614

4615 4616 4617 4618 4619 4620 4621
          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }

        if ((frame_parms->frame_type == TDD) &&
lukashov's avatar
lukashov committed
4622

4623
            (subframe==6)) { //TDD Subframe 6
4624 4625 4626
          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
4627

4628 4629 4630 4631 4632
          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }
4633

4634
        if (rb_alloc_ind==1) {
4635
#ifdef DEBUG_DLSCH_DEMOD
4636
          printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
4637
#endif
4638
          /*
4639
            printf("rb %d\n",rb);
4640 4641 4642 4643 4644
            for (i=0;i<12;i++)
            printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
            printf("\n");
          */
          if (pilots==0) {
4645
            //      printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
4646 4647
            if (skip_half==1) {
              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));
4648

4649
              for (i=0; i<6; i++) {
4650
                rxF_ext[i]=rxF[i];
4651
#ifdef DEBUG_DLSCH_DEMOD
4652
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
4653
#endif
4654
              }
4655 4656 4657
              dl_ch0_ext+=6;
              rxF_ext+=6;

4658
            } else if (skip_half==2) {
4659
              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));
4660

4661
              for (i=0; i<6; i++) {
4662
                rxF_ext[i]=rxF[(i+6)];
4663
#ifdef DEBUG_DLSCH_DEMOD
4664
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
4665
#endif
4666
              }
4667 4668 4669
              dl_ch0_ext+=6;
              rxF_ext+=6;

4670
            } else {
4671
              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
4672

4673
              for (i=0; i<12; i++) {
4674
                rxF_ext[i]=rxF[i];
4675
#ifdef DEBUG_DLSCH_DEMOD
4676
                printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
4677
#endif
4678
              }
4679 4680 4681
              dl_ch0_ext+=12;
              rxF_ext+=12;
            }
4682
          } else {
4683
            //      printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
4684
            j=0;
4685

4686
            if (skip_half==1) {
4687
              for (i=0; i<6; i++) {
4688 4689
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[i];
4690
#ifdef DEBUG_DLSCH_DEMOD
4691
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4692
#endif
4693 4694 4695
                  dl_ch0_ext[j++]=dl_ch0[i];
                }
              }
4696

4697 4698
              dl_ch0_ext+=5;
              rxF_ext+=5;
4699 4700
            } else if (skip_half==2) {
              for (i=0; i<6; i++) {
4701 4702
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[(i+6)];
4703
#ifdef DEBUG_DLSCH_DEMOD
4704
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4705
#endif
4706 4707 4708
                  dl_ch0_ext[j++]=dl_ch0[i+6];
                }
              }
4709

4710 4711
              dl_ch0_ext+=5;
              rxF_ext+=5;
4712 4713
            } else {
              for (i=0; i<12; i++) {
4714 4715 4716
                if ((i!=(frame_parms->nushift+poffset)) &&
                    (i!=((frame_parms->nushift+poffset+6)%12))) {
                  rxF_ext[j]=rxF[i];
4717
#ifdef DEBUG_DLSCH_DEMOD
4718
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4719
#endif
4720 4721 4722 4723 4724 4725 4726 4727
                  dl_ch0_ext[j++]=dl_ch0[i];
                }
              }
              dl_ch0_ext+=10;
              rxF_ext+=10;
            }
          } // pilots=0
        }
4728

4729 4730
        dl_ch0+=12;
        rxF+=12;
4731 4732 4733
      }
    }
  }
4734

4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747

  return(nb_rb/frame_parms->nb_antennas_rx);
}

unsigned short dlsch_extract_rbs_dual(int **rxdataF,
                                      int **dl_ch_estimates,
                                      int **rxdataF_ext,
                                      int **dl_ch_estimates_ext,
                                      unsigned short pmi,
                                      unsigned char *pmi_ext,
                                      unsigned int *rb_alloc,
                                      unsigned char symbol,
                                      unsigned char subframe,
4748
                                      uint32_t high_speed_flag,
lukashov's avatar
lukashov committed
4749
                                      LTE_DL_FRAME_PARMS *frame_parms,
4750
                                      MIMO_mode_t mimo_mode) {
4751

4752 4753 4754 4755 4756 4757
  int prb,nb_rb=0;
  int prb_off,prb_off2;
  int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l;
  int i,aarx;
  int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext;
  int symbol_mod,pilots=0,j=0;
4758
  unsigned char *pmi_loc;
4759

4760 4761 4762 4763 4764
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
  //  printf("extract_rbs: symbol_mod %d\n",symbol_mod);

  if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp)))
    pilots=1;
4765

Raymond Knopp's avatar
 
Raymond Knopp committed
4766
  nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
4767 4768
  l=symbol;

Raymond Knopp's avatar
 
Raymond Knopp committed
4769
  if (frame_parms->frame_type == TDD) {  // TDD
4770 4771
    sss_symb = nsymb-1;
    pss_symb = 2;
4772
  } else {
4773 4774 4775 4776
    sss_symb = (nsymb>>1)-2;
    pss_symb = (nsymb>>1)-1;
  }

4777
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
4778 4779 4780 4781

    if (high_speed_flag==1) {
      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
      dl_ch1     = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
4782
    } else {
4783 4784 4785
      dl_ch0     = &dl_ch_estimates[aarx][5];
      dl_ch1     = &dl_ch_estimates[2+aarx][5];
    }
4786

4787
    pmi_loc = pmi_ext;
4788

4789 4790
    // pointers to extracted RX signals and channel estimates
    rxF_ext    = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
4791 4792 4793
    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
    dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];

4794 4795
    for (prb=0; prb<frame_parms->N_RB_DL; prb++) {
      skip_half=0;
4796

4797
      if (prb < 32)
4798
        rb_alloc_ind = (rb_alloc[0]>>prb) & 1;
4799
      else if (prb < 64)
4800
        rb_alloc_ind = (rb_alloc[1]>>(prb-32)) & 1;
4801
      else if (prb < 96)
4802
        rb_alloc_ind = (rb_alloc[2]>>(prb-64)) & 1;
4803
      else if (prb < 100)
4804
        rb_alloc_ind = (rb_alloc[3]>>(prb-96)) & 1;
4805
      else
4806
        rb_alloc_ind = 0;
4807

4808 4809
      if (rb_alloc_ind == 1)
          nb_rb++;
4810

4811

Raymond Knopp's avatar
Raymond Knopp committed
4812
      if ((frame_parms->N_RB_DL&1) == 0) {  // even number of RBs
4813

4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875
        // PBCH
        if ((subframe==0) &&
            (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
            (prb<((frame_parms->N_RB_DL>>1)+3)) &&
            (l>=(nsymb>>1)) &&
            (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
          //    printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
        }

        //SSS

        if (((subframe==0)||(subframe==5)) &&
            (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
            (prb<((frame_parms->N_RB_DL>>1)+3)) &&
            (l==sss_symb) ) {
          rb_alloc_ind = 0;
          //    printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
        }



        //PSS in subframe 0/5 if FDD
        if (frame_parms->frame_type == FDD) {  //FDD
          if (((subframe==0)||(subframe==5)) &&
              (prb>=((frame_parms->N_RB_DL>>1)-3)) &&
              (prb<((frame_parms->N_RB_DL>>1)+3)) &&
              (l==pss_symb) ) {
            rb_alloc_ind = 0;
            //    printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
          }
        }

        if ((frame_parms->frame_type == TDD) &&
            (subframe==6)) { //TDD Subframe 6
          if ((prb>=((frame_parms->N_RB_DL>>1)-3)) &&
              (prb<((frame_parms->N_RB_DL>>1)+3)) &&
              (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }

        if (rb_alloc_ind==1) {              // PRB is allocated



          prb_off      = 12*prb;
          prb_off2     = 1+(12*(prb-(frame_parms->N_RB_DL>>1)));
          dl_ch0p    = dl_ch0+(12*prb);
          dl_ch1p    = dl_ch1+(12*prb);
          if (prb<(frame_parms->N_RB_DL>>1)){
            rxF      = &rxdataF[aarx][prb_off+
                                      frame_parms->first_carrier_offset +
                                      (symbol*(frame_parms->ofdm_symbol_size))];
          }
          else {
            rxF      = &rxdataF[aarx][prb_off2+
                                      (symbol*(frame_parms->ofdm_symbol_size))];
          }

         /*
         if (mimo_mode <= PUSCH_PRECODING1)
4876
          *pmi_loc = (pmi>>((prb>>2)<<1))&3;
4877 4878
         else
          *pmi_loc=(pmi>>prb)&1;*/
4879

4880
         *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
4881
          pmi_loc++;
4882 4883


4884
          if (pilots == 0) {
4885

4886 4887 4888
            memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int));
            memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int));
            memcpy(rxF_ext,rxF,12*sizeof(int));
4889 4890 4891
            dl_ch0_ext +=12;
            dl_ch1_ext +=12;
            rxF_ext    +=12;
4892
          } else { // pilots==1
4893
            j=0;
4894
            for (i=0; i<12; i++) {
4895 4896 4897 4898 4899
              if ((i!=frame_parms->nushift) &&
                  (i!=frame_parms->nushift+3) &&
                  (i!=frame_parms->nushift+6) &&
                  (i!=((frame_parms->nushift+9)%12))) {
                rxF_ext[j]=rxF[i];
4900
                //        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
4901 4902
                dl_ch0_ext[j]=dl_ch0p[i];
                dl_ch1_ext[j++]=dl_ch1p[i];
4903 4904
              }
            }
4905 4906 4907
            dl_ch0_ext+=8;
            dl_ch1_ext+=8;
            rxF_ext+=8;
4908
          } // pilots==1
4909

4910
        }
Raymond Knopp's avatar
Raymond Knopp committed
4911
      } else {  // Odd number of RBs
4912

4913 4914

      // PBCH
4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013
        if ((subframe==0) &&
            (prb>((frame_parms->N_RB_DL>>1)-3)) &&
            (prb<((frame_parms->N_RB_DL>>1)+3)) &&
            (l>=(nsymb>>1)) &&
            (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
          //    printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb);
        }

        //SSS

        if (((subframe==0)||(subframe==5)) &&
            (prb>((frame_parms->N_RB_DL>>1)-3)) &&
            (prb<((frame_parms->N_RB_DL>>1)+3)) &&
            (l==sss_symb) ) {
          rb_alloc_ind = 0;
          //    printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb);
        }



        //PSS in subframe 0/5 if FDD
        if (frame_parms->frame_type == FDD) {  //FDD
          if (((subframe==0)||(subframe==5)) &&
              (prb>((frame_parms->N_RB_DL>>1)-3)) &&
              (prb<((frame_parms->N_RB_DL>>1)+3)) &&
              (l==pss_symb) ) {
            rb_alloc_ind = 0;
            //    printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb);
          }
        }

        if ((frame_parms->frame_type == TDD) &&
            ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6
          if ((prb>((frame_parms->N_RB_DL>>1)-3)) &&
              (prb<((frame_parms->N_RB_DL>>1)+3)) &&
              (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }

        if (rb_alloc_ind == 1) {
          skip_half=0;

          //Check if we have to drop half a PRB due to PSS/SSS/PBCH
          // skip_half == 0 means full PRB
          // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH)
          // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH)
          //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
          if ((subframe==0) &&
              (prb==((frame_parms->N_RB_DL>>1)-3)) &&
              (l>=(nsymb>>1)) &&
              (l<((nsymb>>1) + 4)))
            skip_half=1;
          else if ((subframe==0) &&
                   (prb==((frame_parms->N_RB_DL>>1)+3)) &&
                   (l>=(nsymb>>1)) &&
                   (l<((nsymb>>1) + 4)))
            skip_half=2;

          //SSS
          if (((subframe==0)||(subframe==5)) &&
              (prb==((frame_parms->N_RB_DL>>1)-3)) &&
              (l==sss_symb))
            skip_half=1;
          else if (((subframe==0)||(subframe==5)) &&
                   (prb==((frame_parms->N_RB_DL>>1)+3)) &&
                   (l==sss_symb))
            skip_half=2;

          //PSS Subframe 0,5
          if (((frame_parms->frame_type == FDD) &&
               (((subframe==0)||(subframe==5)))) ||  //FDD Subframes 0,5
              ((frame_parms->frame_type == TDD) &&
               (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6

            if ((prb==((frame_parms->N_RB_DL>>1)-3)) &&
                (l==pss_symb))
              skip_half=1;
            else if ((prb==((frame_parms->N_RB_DL>>1)+3)) &&
                     (l==pss_symb))
              skip_half=2;
          }


          prb_off      = 12*prb;
          prb_off2     = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1));
          dl_ch0p      = dl_ch0+(12*prb);
          dl_ch1p      = dl_ch1+(12*prb);

          if (prb<=(frame_parms->N_RB_DL>>1)){
            rxF      = &rxdataF[aarx][prb_off+
                                      frame_parms->first_carrier_offset +
                                      (symbol*(frame_parms->ofdm_symbol_size))];
          }
          else {
            rxF      = &rxdataF[aarx][prb_off2+
                                      (symbol*(frame_parms->ofdm_symbol_size))];
          }
Raymond Knopp's avatar
Raymond Knopp committed
5014
#ifdef DEBUG_DLSCH_DEMOD
5015
          printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2);
Raymond Knopp's avatar
Raymond Knopp committed
5016
#endif
5017
         /* if (mimo_mode <= PUSCH_PRECODING1)
lukashov's avatar
lukashov committed
5018
           *pmi_loc = (pmi>>((prb>>2)<<1))&3;
5019 5020
          else
           *pmi_loc=(pmi>>prb)&1;
5021
         // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext);
5022
*/
5023
         *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb);
5024 5025
          pmi_loc++;

5026 5027 5028 5029 5030 5031
          if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC
            if (pilots==0) {
              if (skip_half==1) {
                memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
                memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
                memcpy(rxF_ext,rxF,6*sizeof(int32_t));
Raymond Knopp's avatar
Raymond Knopp committed
5032
#ifdef DEBUG_DLSCH_DEMOD
5033 5034
                for (i=0;i<6;i++)
                  printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
Raymond Knopp's avatar
Raymond Knopp committed
5035
#endif
5036 5037 5038 5039 5040 5041 5042
                dl_ch0_ext+=6;
                dl_ch1_ext+=6;
                rxF_ext+=6;
              } else if (skip_half==2) {
                memcpy(dl_ch0_ext,dl_ch0p+6,6*sizeof(int32_t));
                memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t));
                memcpy(rxF_ext,rxF+6,6*sizeof(int32_t));
Raymond Knopp's avatar
Raymond Knopp committed
5043
#ifdef DEBUG_DLSCH_DEMOD
5044 5045
                for (i=0;i<6;i++)
                  printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
Raymond Knopp's avatar
Raymond Knopp committed
5046
#endif
5047 5048 5049 5050 5051 5052 5053
                dl_ch0_ext+=6;
                dl_ch1_ext+=6;
                rxF_ext+=6;
              } else {  // skip_half==0
                memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int32_t));
                memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t));
                memcpy(rxF_ext,rxF,12*sizeof(int32_t));
Raymond Knopp's avatar
Raymond Knopp committed
5054
#ifdef DEBUG_DLSCH_DEMOD
5055 5056
                for (i=0;i<12;i++)
                  printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
Raymond Knopp's avatar
Raymond Knopp committed
5057
#endif
5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069
                dl_ch0_ext+=12;
                dl_ch1_ext+=12;
                rxF_ext+=12;
              }
            } else { // pilots=1
              j=0;

              if (skip_half==1) {
                for (i=0; i<6; i++) {
                  if ((i!=frame_parms->nushift) &&
                      (i!=((frame_parms->nushift+3)%6))) {
                    rxF_ext[j]=rxF[i];
Raymond Knopp's avatar
Raymond Knopp committed
5070
#ifdef DEBUG_DLSCH_DEMOD
5071
                    printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
Raymond Knopp's avatar
Raymond Knopp committed
5072
#endif
5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084
                    dl_ch0_ext[j]=dl_ch0p[i];
                    dl_ch1_ext[j++]=dl_ch1p[i];
                  }
                }
                dl_ch0_ext+=4;
                dl_ch1_ext+=4;
                rxF_ext+=4;
              } else if (skip_half==2) {
                for (i=0; i<6; i++) {
                  if ((i!=frame_parms->nushift) &&
                      (i!=((frame_parms->nushift+3)%6))) {
                    rxF_ext[j]=rxF[(i+6)];
Raymond Knopp's avatar
Raymond Knopp committed
5085
#ifdef DEBUG_DLSCH_DEMOD
5086
                    printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
Raymond Knopp's avatar
Raymond Knopp committed
5087
#endif
5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102
                    dl_ch0_ext[j]=dl_ch0p[i+6];
                    dl_ch1_ext[j++]=dl_ch1p[i+6];
                  }
                }
                dl_ch0_ext+=4;
                dl_ch1_ext+=4;
                rxF_ext+=4;

              } else { //skip_half==0
                for (i=0; i<12; i++) {
                  if ((i!=frame_parms->nushift) &&
                      (i!=frame_parms->nushift+3) &&
                      (i!=frame_parms->nushift+6) &&
                      (i!=((frame_parms->nushift+9)%12))) {
                    rxF_ext[j]=rxF[i];
Raymond Knopp's avatar
Raymond Knopp committed
5103
#ifdef DEBUG_DLSCH_DEMOD
5104
                    printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
Raymond Knopp's avatar
Raymond Knopp committed
5105
#endif
5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120
                    dl_ch0_ext[j]  =dl_ch0p[i];
                    dl_ch1_ext[j++]=dl_ch1p[i];
                  }
                }
                dl_ch0_ext+=8;
                dl_ch1_ext+=8;
                rxF_ext+=8;
              } //skip_half==0
            } //pilots==1
          } else {       // Do middle RB (around DC)

            if (pilots==0) {
              memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
              memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
              memcpy(rxF_ext,rxF,6*sizeof(int32_t));
Raymond Knopp's avatar
Raymond Knopp committed
5121
#ifdef DEBUG_DLSCH_DEMOD
5122 5123 5124
              for (i=0; i<6; i++) {
                printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
              }
Raymond Knopp's avatar
Raymond Knopp committed
5125
#endif
5126 5127 5128 5129 5130
              rxF_ext+=6;
              dl_ch0_ext+=6;
              dl_ch1_ext+=6;
              dl_ch0p+=6;
              dl_ch1p+=6;
5131

5132
              rxF       = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))];
5133

5134 5135 5136
              memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t));
              memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t));
              memcpy(rxF_ext,rxF,6*sizeof(int32_t));
Raymond Knopp's avatar
Raymond Knopp committed
5137
#ifdef DEBUG_DLSCH_DEMOD
5138 5139 5140
              for (i=0; i<6; i++) {
                printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
              }
Raymond Knopp's avatar
Raymond Knopp committed
5141
#endif
5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153
              rxF_ext+=6;
              dl_ch0_ext+=6;
              dl_ch1_ext+=6;
            } else { // pilots==1
              j=0;

              for (i=0; i<6; i++) {
                if ((i!=frame_parms->nushift) &&
                    (i!=((frame_parms->nushift+3)%6))) {
                  dl_ch0_ext[j]=dl_ch0p[i];
                  dl_ch1_ext[j]=dl_ch1p[i];
                  rxF_ext[j++]=rxF[i];
Raymond Knopp's avatar
Raymond Knopp committed
5154
#ifdef DEBUG_DLSCH_DEMOD
5155
                  printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
Raymond Knopp's avatar
Raymond Knopp committed
5156
#endif
5157 5158 5159 5160 5161 5162 5163 5164 5165 5166
                }
              }
              rxF       = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)];

              for (; i<12; i++) {
                if ((i!=((frame_parms->nushift+6)%12)) &&
                    (i!=((frame_parms->nushift+9)%12))) {
                  dl_ch0_ext[j]=dl_ch0p[i];
                  dl_ch1_ext[j]=dl_ch1p[i];
                  rxF_ext[j++]=rxF[i-6];
Raymond Knopp's avatar
Raymond Knopp committed
5167
#ifdef DEBUG_DLSCH_DEMOD
5168
                  printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6]));
Raymond Knopp's avatar
Raymond Knopp committed
5169
#endif
5170 5171 5172 5173 5174 5175 5176 5177 5178
                }
              }

              dl_ch0_ext+=8;
              dl_ch1_ext+=8;
              rxF_ext+=8;
            } //pilots==1
          }  // if Middle PRB
        } // if odd PRB
5179
      } // if rballoc==1
5180
    } // for prb
5181
  } // for aarx
5182 5183 5184
  return(nb_rb/frame_parms->nb_antennas_rx);
}

5185 5186 5187 5188 5189 5190 5191 5192 5193 5194
unsigned short dlsch_extract_rbs_TM7(int **rxdataF,
                                     int **dl_bf_ch_estimates,
                                     int **rxdataF_ext,
                                     int **dl_bf_ch_estimates_ext,
                                     unsigned int *rb_alloc,
                                     unsigned char symbol,
                                     unsigned char subframe,
                                     uint32_t high_speed_flag,
                                     LTE_DL_FRAME_PARMS *frame_parms)
{
5195

5196 5197 5198 5199
  unsigned short rb,nb_rb=0;
  unsigned char rb_alloc_ind;
  unsigned char i,aarx,l,nsymb,skip_half=0,sss_symb,pss_symb=0;
  int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
5200

5201 5202
  unsigned char symbol_mod,pilots=0,uespec_pilots=0,j=0,poffset=0,uespec_poffset=0;
  int8_t uespec_nushift = frame_parms->Nid_cell%3;
5203

5204 5205 5206 5207
  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
  pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0;
  l=symbol;
  nsymb = (frame_parms->Ncp==NORMAL) ? 14:12;
5208

5209 5210 5211 5212 5213 5214 5215
  if (frame_parms->Ncp==0){
    if (symbol==3 || symbol==6 || symbol==9 || symbol==12)
      uespec_pilots = 1;
  } else{
    if (symbol==4 || symbol==7 || symbol==10)
      uespec_pilots = 1;
  }
5216

5217 5218 5219 5220 5221 5222
  if (frame_parms->frame_type == TDD) {// TDD
    sss_symb = nsymb-1;
    pss_symb = 2;
  } else {
    sss_symb = (nsymb>>1)-2;
    pss_symb = (nsymb>>1)-1;
5223
  }
5224

5225 5226
  if (symbol_mod==(4-frame_parms->Ncp))
    poffset=3;
5227

5228 5229
  if ((frame_parms->Ncp==0 && (symbol==6 ||symbol ==12)) || (frame_parms->Ncp==1 && symbol==7))
    uespec_poffset=2;
5230

5231
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
5232

5233 5234 5235 5236 5237 5238 5239 5240 5241
    if (high_speed_flag == 1)
      dl_ch0     = &dl_bf_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)];
    else
      dl_ch0     = &dl_bf_ch_estimates[aarx][0];

    dl_ch0_ext = &dl_bf_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];

    rxF_ext    = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
    rxF        = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
5242 5243

    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;

5257
  if (rb_alloc_ind == 1)
5258 5259
          nb_rb++;

5260 5261 5262 5263 5264
        // For second half of RBs skip DC carrier
        if (rb==(frame_parms->N_RB_DL>>1)) {
          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];
          //dl_ch0++;
        }
5265

5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289
        // PBCH
        if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }

        //SSS
        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }


        if (frame_parms->frame_type == FDD) {
          //PSS
          if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }

        if ((frame_parms->frame_type == TDD) &&
            (subframe==6)) { //TDD Subframe 6
          if ((rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }
        }
5290

5291
        if (rb_alloc_ind==1) {
5292

5293 5294 5295 5296 5297 5298 5299 5300
          /*
              printf("rb %d\n",rb);
              for (i=0;i<12;i++)
              printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
              printf("\n");
          */
          if (pilots==0 && uespec_pilots==0) {
            memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
5301

5302 5303 5304
            for (i=0; i<12; i++) {
              rxF_ext[i]=rxF[i];
            }
5305

5306 5307 5308 5309
            dl_ch0_ext+=12;
            rxF_ext+=12;
          } else if(pilots==1 && uespec_pilots==0) {
            j=0;
5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323

            for (i=0; i<12; i++) {
              if ((i!=(frame_parms->nushift+poffset)) &&
                  (i!=((frame_parms->nushift+poffset+6)%12))) {
                rxF_ext[j]=rxF[i];
                dl_ch0_ext[j++]=dl_ch0[i];
              }
            }

            dl_ch0_ext+=10;
            rxF_ext+=10;

          } else if (pilots==0 && uespec_pilots==1) {
            j=0;
Xiwen JIANG's avatar
Xiwen JIANG committed
5324

5325

5326
      for (i=0; i<12; i++){
5327
              if (frame_parms->Ncp==0){
5328 5329 5330
                if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
      rxF_ext[j] = rxF[i];
                  dl_ch0_ext[j++]=dl_ch0[i];
5331 5332
                }
              } else{
5333 5334
                if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
      rxF_ext[j] = rxF[i];
5335
                  dl_ch0_ext[j++]=dl_ch0[i];
5336
                }
5337
              }
5338 5339 5340

      }

5341
            dl_ch0_ext+=9-frame_parms->Ncp;
5342
            rxF_ext+=9-frame_parms->Ncp;
5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369

          } else {
            msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
            exit(-1);
          }

        }

        dl_ch0+=12;
        rxF+=12;

      }
    else {  // Odd number of RBs
      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
        skip_half=0;

        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;

5370 5371
        if (rb_alloc_ind == 1)
          nb_rb++;
5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414

        // PBCH
        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }

        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=1;
        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=2;

        //SSS

        if (((subframe==0)||(subframe==5)) &&
            (rb>((frame_parms->N_RB_DL>>1)-3)) &&
            (rb<((frame_parms->N_RB_DL>>1)+3)) &&
            (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }

        //SSS
        if (((subframe==0)||(subframe==5)) &&
            (rb==((frame_parms->N_RB_DL>>1)-3)) &&
            (l==sss_symb))
          skip_half=1;
        else if (((subframe==0)||(subframe==5)) &&
                 (rb==((frame_parms->N_RB_DL>>1)+3)) &&
                 (l==sss_symb))
          skip_half=2;

        //PSS in subframe 0/5 if FDD
        if (frame_parms->frame_type == FDD) {  //FDD
          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }

          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }

5415
        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427
          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }

          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }


        if (rb_alloc_ind==1) {
5428 5429 5430
#ifdef DEBUG_DLSCH_DEMOD
          printf("rb %d/symbol %d pilots %d, uespec_pilots %d, (skip_half %d)\n",rb,l,pilots,uespec_pilots,skip_half);
#endif
5431 5432

          if (pilots==0 && uespec_pilots==0) {
5433
            //printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
5434 5435 5436 5437

            if (skip_half==1) {
              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));

5438
              for (i=0; i<6; i++) {
5439
                rxF_ext[i]=rxF[i];
5440
#ifdef DEBUG_DLSCH_DEMOD
5441
    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5442 5443
#endif
              }
5444 5445 5446 5447 5448 5449

              dl_ch0_ext+=6;
              rxF_ext+=6;
            } else if (skip_half==2) {
              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));

5450
              for (i=0; i<6; i++) {
5451
                rxF_ext[i]=rxF[(i+6)];
5452
#ifdef DEBUG_DLSCH_DEMOD
5453
    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5454 5455
#endif
              }
5456 5457 5458 5459 5460 5461

              dl_ch0_ext+=6;
              rxF_ext+=6;
            } else {
              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));

5462
              for (i=0; i<12; i++){
5463
                rxF_ext[i]=rxF[i];
5464 5465 5466
#ifdef DEBUG_DLSCH_DEMOD
                printf("extract rb %d, re %d => (%d,%d)\n",symbol,rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i]));
#endif
5467
              }
5468 5469 5470
              dl_ch0_ext+=12;
              rxF_ext+=12;
            }
5471
          } else if (pilots==1 && uespec_pilots==0) {
5472 5473 5474 5475 5476 5477 5478 5479
            // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
            j=0;

            if (skip_half==1) {
              for (i=0; i<6; i++) {
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[i];
                  dl_ch0_ext[j++]=dl_ch0[i];
5480
#ifdef DEBUG_DLSCH_DEMOD
5481
    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5482
#endif
5483 5484 5485 5486 5487 5488 5489 5490 5491 5492
                }
              }

              dl_ch0_ext+=5;
              rxF_ext+=5;
            } else if (skip_half==2) {
              for (i=0; i<6; i++) {
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[(i+6)];
                  dl_ch0_ext[j++]=dl_ch0[i+6];
5493
#ifdef DEBUG_DLSCH_DEMOD
5494
    printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5495
#endif
5496 5497 5498 5499 5500 5501 5502 5503 5504 5505
                }
              }

              dl_ch0_ext+=5;
              rxF_ext+=5;
            } else {
              for (i=0; i<12; i++) {
                if ((i!=(frame_parms->nushift+poffset)) &&
                    (i!=((frame_parms->nushift+poffset+6)%12))) {
                  rxF_ext[j]=rxF[i];
5506 5507 5508
#ifdef DEBUG_DLSCH_DEMOD
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526
                  dl_ch0_ext[j++]=dl_ch0[i];

                }
              }

              dl_ch0_ext+=10;
              rxF_ext+=10;
            }
          } else if(pilots==0 && uespec_pilots==1){
            //printf("Extracting with uespec pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
            j=0;

            if (skip_half==1) {
              if (frame_parms->Ncp==0){
                for (i=0; i<6; i++) {
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
                    rxF_ext[j]=rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5527
#ifdef DEBUG_DLSCH_DEMOD
5528
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5529
#endif
5530 5531 5532 5533 5534 5535 5536
                  }
                }
                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
                rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);

              } else{
                for (i=0; i<6; i++) {
5537
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5538 5539
                    rxF_ext[j]=rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5540
#ifdef DEBUG_DLSCH_DEMOD
5541
        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5542
#endif
5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554
                  }
                }
                dl_ch0_ext+=4;
                rxF_ext+=4;
              }

            } else if (skip_half==2) {
              if(frame_parms->Ncp==0){
                for (i=0; i<6; i++) {
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
                    rxF_ext[j]=rxF[(i+6)];
                    dl_ch0_ext[j++]=dl_ch0[i+6];
5555
#ifdef DEBUG_DLSCH_DEMOD
5556
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5557
#endif
5558 5559 5560 5561 5562 5563 5564
                  }
                }
                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
                rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);

              } else {
                for (i=0; i<6; i++) {
5565
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5566 5567
                    rxF_ext[j]=rxF[(i+6)];
                    dl_ch0_ext[j++]=dl_ch0[i+6];
5568
#ifdef DEBUG_DLSCH_DEMOD
5569
        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5570
#endif
5571 5572 5573 5574 5575 5576 5577 5578
                  }
                }
                dl_ch0_ext+=4;
                rxF_ext+=4;
              }

            } else {

5579
        for (i=0; i<12; i++){
5580 5581
                if (frame_parms->Ncp==0){
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
5582 5583
              rxF_ext[j] = rxF[i];
                    dl_ch0_ext[j++] = dl_ch0[i];
5584 5585 5586
#ifdef DEBUG_DLSCH_DEMOD
                    printf("extract rb %d, re %d, j %d => (%d,%d)\n",symbol,rb,i,j-1,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i]));
#endif
5587 5588
                  }
                } else{
5589 5590 5591
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
              rxF_ext[j] = rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5592
#ifdef DEBUG_DLSCH_DEMOD
5593
        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5594
#endif
5595
                  }
5596
                }
5597 5598 5599

        }

5600
              dl_ch0_ext+=9-frame_parms->Ncp;
5601 5602 5603
              rxF_ext+=9-frame_parms->Ncp;
      }

5604 5605 5606
          } else {
            msg("dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n");
            exit(-1);
5607

5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627
          }
        }

        dl_ch0+=12;
        rxF+=12;
      } // first half loop


      // Do middle RB (around DC)
      if (rb < 32)
        rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
      else if (rb < 64)
        rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
      else if (rb < 96)
        rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
      else if (rb < 100)
        rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
      else
        rb_alloc_ind = 0;

5628 5629
      if (rb_alloc_ind == 1)
        nb_rb++;
5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647

      // PBCH
      if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) {
        rb_alloc_ind = 0;
      }

      //SSS
      if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
        rb_alloc_ind = 0;
      }

      if (frame_parms->frame_type == FDD) {
        //PSS
        if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
          rb_alloc_ind = 0;
        }
      }

5648
      if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) {
5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662
        //PSS
        if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
          rb_alloc_ind = 0;
        }
      }

      //printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
      //printf("DC rb %d (%p)\n",rb,rxF);
      if (rb_alloc_ind==1) {
        //printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
        if (pilots==0 && uespec_pilots==0) {
          for (i=0; i<6; i++) {
            dl_ch0_ext[i]=dl_ch0[i];
            rxF_ext[i]=rxF[i];
5663
#ifdef DEBUG_DLSCH_DEMOD
5664
      printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5665
#endif
5666 5667 5668 5669 5670 5671 5672
          }

          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];

          for (; i<12; i++) {
            dl_ch0_ext[i]=dl_ch0[i];
            rxF_ext[i]=rxF[(1+i-6)];
5673
#ifdef DEBUG_DLSCH_DEMOD
5674
      printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5675
#endif
5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686
          }

          dl_ch0_ext+=12;
          rxF_ext+=12;
        } else if(pilots==1 && uespec_pilots==0){ // pilots==1
          j=0;

          for (i=0; i<6; i++) {
            if (i!=((frame_parms->nushift+poffset)%6)) {
              dl_ch0_ext[j]=dl_ch0[i];
              rxF_ext[j++]=rxF[i];
5687
#ifdef DEBUG_DLSCH_DEMOD
5688
        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5689
#endif
5690 5691 5692 5693 5694 5695 5696 5697 5698
            }
          }

          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];

          for (; i<12; i++) {
            if (i!=((frame_parms->nushift+6+poffset)%12)) {
              dl_ch0_ext[j]=dl_ch0[i];
              rxF_ext[j++]=rxF[(1+i-6)];
5699
#ifdef DEBUG_DLSCH_DEMOD
5700
        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5701
#endif
5702 5703 5704 5705 5706 5707 5708 5709
            }
          }

          dl_ch0_ext+=10;
          rxF_ext+=10;
        } else if(pilots==0 && uespec_pilots==1) {
          j=0;

5710
    for (i=0; i<6; i++) {
5711
            if (frame_parms->Ncp==0){
5712 5713 5714
              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
                dl_ch0_ext[j]=dl_ch0[i];
          rxF_ext[j++] = rxF[i];
5715
#ifdef DEBUG_DLSCH_DEMOD
5716
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5717
#endif
5718 5719 5720
              }
            } else {
              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5721 5722
                dl_ch0_ext[j]=dl_ch0[i];
          rxF_ext[j++] = rxF[i];
5723
#ifdef DEBUG_DLSCH_DEMOD
5724
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5725
#endif
5726 5727
              }
            }
5728 5729
    }

5730 5731 5732 5733
          rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];

          for (; i<12; i++) {
            if (frame_parms->Ncp==0){
5734
              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
5735 5736
                dl_ch0_ext[j]=dl_ch0[i];
                rxF_ext[j++]=rxF[(1+i-6)];
5737
#ifdef DEBUG_DLSCH_DEMOD
5738
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5739
#endif
5740 5741 5742
              }
            } else {
              if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5743 5744
                dl_ch0_ext[j]=dl_ch0[i];
          rxF_ext[j++] = rxF[(1+i-6)];
5745
#ifdef DEBUG_DLSCH_DEMOD
5746
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5747
#endif
5748 5749 5750
              }
            }
          }
5751

5752
          dl_ch0_ext+=9-frame_parms->Ncp;
5753 5754 5755
          rxF_ext+=9-frame_parms->Ncp;

  }// symbol_mod==0
5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781

      } // rballoc==1
      else {
        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];
      }

      dl_ch0+=12;
      rxF+=7;
      rb++;

      for (; rb<frame_parms->N_RB_DL; rb++) {
        //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
        //  printf("rb %d (%p)\n",rb,rxF);
        skip_half=0;

        if (rb < 32)
          rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
        else if (rb < 64)
          rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
        else if (rb < 96)
          rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
        else if (rb < 100)
          rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
        else
          rb_alloc_ind = 0;

5782 5783
        if (rb_alloc_ind==1)
          nb_rb++;
5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806

        // PBCH
        if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) {
          rb_alloc_ind = 0;
        }

        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
        if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=1;
        else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=2;

        //SSS
        if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) {
          rb_alloc_ind = 0;
        }

        //SSS
        if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb))
          skip_half=1;
        else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb))
          skip_half=2;

5807
        //PSS
5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818
        if (frame_parms->frame_type == FDD) {
          if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }

          if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }

5819
        if ((frame_parms->frame_type == TDD) && ((subframe==1)||(subframe==6))) { //TDD Subframe 1 and 6
5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830
          if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) {
            rb_alloc_ind = 0;
          }

          if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb))
            skip_half=1;
          else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb))
            skip_half=2;
        }

        if (rb_alloc_ind==1) {
5831 5832 5833
#ifdef DEBUG_DLSCH_DEMOD
           printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half);
#endif
5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844
          /*
              printf("rb %d\n",rb);
            for (i=0;i<12;i++)
            printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
            printf("\n");
          */
          if (pilots==0 && uespec_pilots==0) {
            //printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
            if (skip_half==1) {
              memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int));

5845
              for (i=0; i<6; i++) {
5846
                rxF_ext[i]=rxF[i];
5847
#ifdef DEBUG_DLSCH_DEMOD
5848
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5849 5850
#endif
              }
5851 5852 5853 5854 5855 5856 5857

              dl_ch0_ext+=6;
              rxF_ext+=6;

            } else if (skip_half==2) {
              memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int));

5858
              for (i=0; i<6; i++) {
5859
                rxF_ext[i]=rxF[i+6];
5860
#ifdef DEBUG_DLSCH_DEMOD
5861
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5862 5863
#endif
              }
5864 5865 5866 5867 5868 5869

              dl_ch0_ext+=6;
              rxF_ext+=6;

            } else {
              memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
5870
              //printf("symbol %d, extract rb %d, => (%d,%d)\n",symbol,rb,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i]));
5871

5872
              for (i=0; i<12; i++) {
5873
                rxF_ext[i]=rxF[i];
5874
#ifdef DEBUG_DLSCH_DEMOD
5875
          printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5876 5877
#endif
              }
5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890

              dl_ch0_ext+=12;
              rxF_ext+=12;
            }
          } else if (pilots==1 && uespec_pilots==0){
            //printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half);
            j=0;

            if (skip_half==1) {
              for (i=0; i<6; i++) {
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[i];
                  dl_ch0_ext[j++]=dl_ch0[i];
5891
#ifdef DEBUG_DLSCH_DEMOD
5892
            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5893
#endif
5894 5895 5896 5897 5898 5899 5900 5901 5902 5903
                }
              }

              dl_ch0_ext+=5;
              rxF_ext+=5;
            } else if (skip_half==2) {
              for (i=0; i<6; i++) {
                if (i!=((frame_parms->nushift+poffset)%6)) {
                  rxF_ext[j]=rxF[(i+6)];
                  dl_ch0_ext[j++]=dl_ch0[i+6];
5904
#ifdef DEBUG_DLSCH_DEMOD
5905
            printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5906
#endif
5907 5908 5909 5910 5911 5912 5913 5914 5915 5916
                }
              }

              dl_ch0_ext+=5;
              rxF_ext+=5;
            } else {
              for (i=0; i<12; i++) {
                if ((i!=(frame_parms->nushift+poffset)) &&
                    (i!=((frame_parms->nushift+poffset+6)%12))) {
                  rxF_ext[j]=rxF[i];
5917 5918 5919
#ifdef DEBUG_DLSCH_DEMOD
                  printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
#endif
5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935
                  dl_ch0_ext[j++]=dl_ch0[i];
                }
              }

              dl_ch0_ext+=10;
              rxF_ext+=10;
            }
          } else if(pilots==0 && uespec_pilots==1) {
            j=0;

            if (skip_half==1) {
              if (frame_parms->Ncp==0){
                for (i=0; i<6; i++) {
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
                    rxF_ext[j]=rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5936
#ifdef DEBUG_DLSCH_DEMOD
5937
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5938
#endif
5939 5940 5941 5942 5943 5944 5945
                  }
                }
                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);
                rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6);

              } else{
                for (i=0; i<6; i++) {
5946
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5947 5948
                    rxF_ext[j]=rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5949
#ifdef DEBUG_DLSCH_DEMOD
5950
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5951
#endif
5952 5953 5954 5955 5956 5957 5958 5959 5960 5961
                  }
                }
                dl_ch0_ext+=4;
                rxF_ext+=4;
              }

            } else if (skip_half==2) {
              if(frame_parms->Ncp==0){
                for (i=0; i<6; i++) {
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
5962
                    rxF_ext[j]=rxF[i+6];
5963
                    dl_ch0_ext[j++]=dl_ch0[i+6];
5964
#ifdef DEBUG_DLSCH_DEMOD
5965
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5966
#endif
5967 5968 5969 5970 5971 5972 5973
                  }
                }
                dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);
                rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6);

              } else {
                for (i=0; i<6; i++) {
5974
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
5975 5976
                    rxF_ext[j]=rxF[(i+6)];
                    dl_ch0_ext[j++]=dl_ch0[i+6];
5977
#ifdef DEBUG_DLSCH_DEMOD
5978
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5979
#endif
5980 5981 5982 5983 5984 5985 5986
                  }
                }
                dl_ch0_ext+=4;
                rxF_ext+=4;
              }

            } else {
5987
        for (i=0; i<12; i++){
5988 5989
                if (frame_parms->Ncp==0){
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){
5990 5991
              rxF_ext[j] = rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
5992
#ifdef DEBUG_DLSCH_DEMOD
5993
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
5994
#endif
5995 5996
                  }
                } else{
5997 5998 5999
                  if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){
              rxF_ext[j] = rxF[i];
                    dl_ch0_ext[j++]=dl_ch0[i];
6000
#ifdef DEBUG_DLSCH_DEMOD
6001
              printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i]));
6002
#endif
6003 6004
                  }
                }
6005 6006
        }

6007
              dl_ch0_ext+=9-frame_parms->Ncp;
6008
              rxF_ext+=9-frame_parms->Ncp;
6009 6010

            }
6011

6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031
          }// pilots=0
        }

        dl_ch0+=12;
        rxF+=12;
      }
    }
  }

  _mm_empty();
  _m_empty();

  return(nb_rb/frame_parms->nb_antennas_rx);
}

//==============================================================================================

#ifdef USER_MODE


Cedric Roux's avatar
Cedric Roux committed
6032
void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *coded_bits_per_codeword,int round,  unsigned char harq_pid)
6033
{
6034
  unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
6035
  char fname[32],vname[32];
6036
  int N_RB_DL=ue->frame_parms.N_RB_DL;
6037 6038 6039

  sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
  sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
6040
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
6041

6042
  if (ue->frame_parms.nb_antennas_rx >1) {
6043 6044
    sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
    sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
6045
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
6046 6047 6048 6049
  }

  sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
  sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
6050
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
6051

6052
  if (ue->transmission_mode[eNB_id]==7){
6053 6054
    sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
    sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
6055
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
6056 6057 6058 6059
    //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);

    sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
    sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
6060
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
6061 6062
  }

6063
  if (ue->frame_parms.nb_antennas_rx == 2) {
6064 6065
    sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
    sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
6066
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
6067 6068
  }

6069
  if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
6070 6071
    sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
    sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
6072
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
6073

6074
    if (ue->frame_parms.nb_antennas_rx == 2) {
6075 6076
      sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
      sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
6077
      write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
6078 6079 6080 6081 6082
    }
  }

  sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
  sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
6083
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
6084

6085
  /*
6086 6087 6088
    write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
    write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
    write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
6089
  */
Raymond Knopp's avatar
Raymond Knopp committed
6090 6091
  sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
  sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
6092

6093
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
6094

lukashov's avatar
lukashov committed
6095 6096
  sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
  sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
6097

6098
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
6099

Raymond Knopp's avatar
Raymond Knopp committed
6100 6101
  sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
  sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
6102
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
6103
  if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
Raymond Knopp's avatar
Raymond Knopp committed
6104 6105
    sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
    sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
6106
    write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
6107 6108
  }

Raymond Knopp's avatar
Raymond Knopp committed
6109 6110
  sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
  sprintf(vname,"dl%d_r%d_llr",eNB_id,round);
6111
  write_output(fname,vname, ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
Raymond Knopp's avatar
Raymond Knopp committed
6112 6113
  sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round);
  sprintf(vname,"dl%d_r%d_mag1",eNB_id,round);
6114
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
Raymond Knopp's avatar
Raymond Knopp committed
6115 6116
  sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round);
  sprintf(vname,"dl%d_r%d_mag2",eNB_id,round);
6117
  write_output(fname,vname,ue->pdsch_vars[subframe%RX_NB_TH][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
6118

6119
  //  printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh);
6120 6121 6122 6123
}
#endif

#ifdef DEBUG_DLSCH_DEMOD
6124
/*
6125 6126
void print_bytes(char *s,__m128i *x)
{
6127 6128 6129 6130 6131 6132

  char *tempb = (char *)x;

  printf("%s  : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s,
         tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7],
         tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15]
6133
         );
6134 6135 6136

}

6137 6138
void print_shorts(char *s,__m128i *x)
{
6139 6140 6141 6142 6143 6144 6145

  short *tempb = (short *)x;
  printf("%s  : %d,%d,%d,%d,%d,%d,%d,%d\n",s,
         tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7]);

}

6146 6147
void print_shorts2(char *s,__m64 *x)
{
6148 6149 6150 6151 6152 6153 6154

  short *tempb = (short *)x;
  printf("%s  : %d,%d,%d,%d\n",s,
         tempb[0],tempb[1],tempb[2],tempb[3]);

}

6155 6156
void print_ints(char *s,__m128i *x)
{
6157 6158 6159 6160 6161

  int *tempb = (int *)x;
  printf("%s  : %d,%d,%d,%d\n",s,
         tempb[0],tempb[1],tempb[2],tempb[3]);

6162
}*/
6163
#endif