dlsch_modulation.c 102 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * 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

/*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c
23
 * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03, V14.1 2017 (FeMBMS)
24
 * \author R. Knopp, F. Kaltenberger, J. Morgade
25 26 27
 * \date 2011
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, javier.morgade@ieee.irg
29 30 31
 * \note
 * \warning
 */
32 33 34 35
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/coding_extern.h"
36
#include "PHY/CODING/lte_interleaver_inline.h"
37
#include "PHY/LTE_TRANSPORT/transport_eNB.h"
38
#include "common/utils/LOG/vcd_signal_dumper.h"
39
#include "PHY/LTE_TRANSPORT/transport_proto.h"
Wang Tsu-Han's avatar
Wang Tsu-Han committed
40
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
41
//#define DEBUG_DLSCH_MODULATION
Wang Tsu-Han's avatar
Wang Tsu-Han committed
42
//#define NEW_ALLOC_RE
43 44 45

//#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0)

46 47
uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots)
{
48 49 50

  uint8_t offset = (pilots==2)?3:0;
  int nushiftmod3 = nushift%3;
51

52 53 54 55 56 57
  if (pilots==0)
    return(1);

  if (use2ndpilots==1) {  // This is for SISO (mode 1)
    if ((re!=nushift+offset) && (re!=((nushift+6+offset)%12)))
      return(1);
58
  } else { // 2 antenna pilots
59 60 61
    if ((re!=nushiftmod3) && (re!=nushiftmod3+6) && (re!=nushiftmod3+3) && (re!=nushiftmod3+9))
      return(1);
  }
62

63 64 65
  return(0);
}

Xiwen JIANG's avatar
Xiwen JIANG committed
66 67 68 69
/*uint8_t is_not_UEspecRS(int first_layer,int re)
{
  return(1);
}*/
70
uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
71
{
72 73
  uint8_t offset = (lprime==1||lprime==3)?2:0;
  if (lprime==-1)
74 75
    return(1);

76
  switch (beamforming_mode) {
77 78
    case 7:
      if (Ncp == NORMAL){
79
        if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) &&  (re!=((nushift+8+offset)%12)))
80 81
          return(1);
        /*else{
82
          LOG_I(PHY,"(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset);
83
        }*/
84
      } else {
85 86 87 88 89 90
        if ((re!=nushift+offset) && (re!=((nushift+3+offset)%12)) && (re!=((nushift+6+offset)%12)) && (re!=((nushift+9+offset)%12)))
          return(1);
      }
      break;

    default:
91
      LOG_E(PHY,"is_not_UEspecRS() [dlsch_modulation.c] : ERROR, unknown beamforming_mode %d\n",beamforming_mode);
92 93
      return(-1);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
94

95
  return(0);
Raymond Knopp's avatar
 
Raymond Knopp committed
96 97
}

98

Eurecom's avatar
Eurecom committed
99

100 101 102



103 104
void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t precoding_index)
{
105 106 107

  switch (precoding_index) {

108 109 110
    case 0: // 1 1
      *antenna1_sample=*antenna0_sample;
      break;
111

112 113 114 115
    case 1: // 1 -1
      ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[0];
      ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[1];
      break;
116

117 118 119 120
    case 2: // 1 j
      ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[1];
      ((int16_t *)antenna1_sample)[1] = ((int16_t *)antenna0_sample)[0];
      break;
121

122 123 124 125
    case 3: // 1 -j
      ((int16_t *)antenna1_sample)[0] = ((int16_t *)antenna0_sample)[1];
      ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[0];
      break;
126 127 128
  }

  // normalize
129
  /*  ((int16_t *)antenna0_sample)[0] = (int16_t)((((int16_t *)antenna0_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
130 131
      ((int16_t *)antenna0_sample)[1] = (int16_t)((((int16_t *)antenna0_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  ((int16_t *)antenna1_sample)[0] = (int16_t)((((int16_t *)antenna1_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
      ((int16_t *)antenna1_sample)[1] = (int16_t)((((int16_t *)antenna1_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  */
132
}
133

134 135 136
uint32_t FOUR[2]={0,4};
uint32_t TWO[2]={0,2};

Eurecom's avatar
Eurecom committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
                                           int **txdataF,
                                           uint32_t *jj,
                                           uint32_t *jj2,
                                           uint16_t re_offset,
                                           uint32_t symbol_offset,
                                           LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                           LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                           uint8_t pilots,
                                           int16_t amp,
                                           uint8_t precoder_index,
                                           int16_t *qam_table_s0,
                                           int16_t *qam_table_s1,
                                           uint32_t *re_allocated,
                                           uint8_t skip_dc,
                                           uint8_t skip_half,
                                           uint8_t lprime,
                                           uint8_t mprime,
                                           uint8_t Ns,
                                           int *P1_SHIFT,
                                           int *P2_SHIFT)
{

  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
161
  uint8_t *x0             = dlsch0_harq->eDL;
Eurecom's avatar
Eurecom committed
162 163 164 165 166 167
  uint32_t qpsk_table_offset_re = 0;
  uint32_t qpsk_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
168 169 170 171 172 173 174 175 176
  uint8_t first_re,last_re;

  last_re=12;
  first_re=0;
  if (skip_half==1)
    last_re=6;
  else if (skip_half==2)
    first_re=6;
  re=first_re;
Eurecom's avatar
Eurecom committed
177 178

  if (skip_dc == 0) {
179 180
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
         re<last_re;
Eurecom's avatar
Eurecom committed
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
         re++,x0p+=2,tti_offset++) {

      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
    }
  }
  else {
    // 1st half of PRB
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
         re<6;
         re++,x0p+=2,tti_offset++) {

      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
    }
    // 2nd half of PRB
    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
         re<12;
         re++,x0p+=2,tti_offset++) {

      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
    }
  }
211 212 213 214 215 216 217 218 219 220
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 6;
    *jj=*jj + 12;
  }
  else
  {
    *re_allocated = *re_allocated + 12;
    *jj=*jj + 24;
  }
Eurecom's avatar
Eurecom committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250

    return(0);
}

int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB,
                                        int **txdataF,
                                        uint32_t *jj,
                                        uint32_t *jj2,
                                        uint16_t re_offset,
                                        uint32_t symbol_offset,
                                        LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                        LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                        uint8_t pilots,
                                        int16_t amp,
                                        uint8_t precoder_index,
                                        int16_t *qam_table_s0,
                                        int16_t *qam_table_s1,
                                        uint32_t *re_allocated,
                                        uint8_t skip_dc,
                                        uint8_t skip_half,
                                        uint8_t lprime,
                                        uint8_t mprime,
                                        uint8_t Ns,
                                        int *P1_SHIFT,
                                        int *P2_SHIFT)
{


  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;

251
  uint8_t *x0             = dlsch0_harq->eDL;
Eurecom's avatar
Eurecom committed
252 253 254 255 256 257
  uint32_t qpsk_table_offset_re = 0;
  uint32_t qpsk_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
258
  uint8_t first_re,last_re;
Eurecom's avatar
Eurecom committed
259

260 261 262 263 264 265 266
  last_re=12;
  first_re=0;
  if (skip_half==1)
    last_re=6;
  else if (skip_half==2)
    first_re=6;
  re=first_re+P1_SHIFT[0];
Eurecom's avatar
Eurecom committed
267 268 269

  if (skip_dc == 0) {
    //    printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]);
270 271
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
         re<last_re;
Eurecom's avatar
Eurecom committed
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
         x0p+=2) {

      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
      //      printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]);
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
  else {
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
         re<6;
         x0p+=2) {

288 289
      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
Eurecom's avatar
Eurecom committed
290 291 292 293 294 295 296 297 298 299
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }

    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
         re<12;
         x0p+=2) {

300 301
      qpsk_table_offset_re=x0p[0];
      qpsk_table_offset_im=x0p[1];
Eurecom's avatar
Eurecom committed
302 303 304 305 306 307
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
308 309 310 311 312 313 314 315 316 317
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 5;
    *jj=*jj + 10;
  }
  else
  {
    *re_allocated = *re_allocated + 10;
    *jj=*jj + 20;
  }
Eurecom's avatar
Eurecom committed
318 319 320 321

  return(0);
}

322
int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
                                            int **txdataF,
                                            uint32_t *jj,
                                            uint32_t *jj2,
                                            uint16_t re_offset,
                                            uint32_t symbol_offset,
                                            LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                            LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                            uint8_t pilots,
                                            int16_t amp,
                                            uint8_t precoder_index,
                                            int16_t *qam_table_s0,
                                            int16_t *qam_table_s1,
                                            uint32_t *re_allocated,
                                            uint8_t skip_dc,
                                            uint8_t skip_half,
                                            uint8_t lprime,
                                            uint8_t mprime,
                                            uint8_t Ns,
                                            int *P1_SHIFT,
                                            int *P2_SHIFT)
343 344
{

345
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
346
  uint8_t *x0             = dlsch0_harq->eDL;
347 348 349 350 351 352
  uint32_t qam16_table_offset_re = 0;
  uint32_t qam16_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
353 354 355 356 357 358 359 360 361
  uint8_t first_re,last_re;

  last_re=12;
  first_re=0;
  if (skip_half==1)
    last_re=6;
  else if (skip_half==2)
    first_re=6;
  re=first_re;
362 363

  if (skip_dc == 0) {
364 365
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
         re<last_re;
366
         re++,x0p+=4,tti_offset++) {
367

368 369 370 371 372 373 374 375 376
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
    }
  }
  else {
377 378
    // 1st half of PRB
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
379 380
         re<6;
         re++,x0p+=4,tti_offset++) {
381

382 383 384 385 386 387 388
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
    }
389 390
    // 2nd half of PRB
    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
391 392
         re<12;
         re++,x0p+=4,tti_offset++) {
393

394 395 396 397 398 399 400 401
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
    }
  }
402 403 404 405 406 407 408 409 410 411
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 6;
    *jj=*jj + 24;
  }
  else
  {
    *re_allocated = *re_allocated + 12;
    *jj=*jj + 48;
  }
412

413 414 415
    return(0);
}

416
int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
                                         int **txdataF,
                                         uint32_t *jj,
                                         uint32_t *jj2,
                                         uint16_t re_offset,
                                         uint32_t symbol_offset,
                                         LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                         LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                         uint8_t pilots,
                                         int16_t amp,
                                         uint8_t precoder_index,
                                         int16_t *qam_table_s0,
                                         int16_t *qam_table_s1,
                                         uint32_t *re_allocated,
                                         uint8_t skip_dc,
                                         uint8_t skip_half,
                                         uint8_t lprime,
                                         uint8_t mprime,
                                         uint8_t Ns,
                                         int *P1_SHIFT,
                                         int *P2_SHIFT)
437
{
438

439

440
  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
441

442
  uint8_t *x0             = dlsch0_harq->eDL;
443 444 445 446 447 448
  uint32_t qam16_table_offset_re = 0;
  uint32_t qam16_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
449 450 451 452 453 454 455 456 457
  uint8_t first_re,last_re;

  last_re=12;
  first_re=0;
  if (skip_half==1)
    last_re=6;
  else if (skip_half==2)
    first_re=6;
  re=first_re+P1_SHIFT[0];
458 459 460


  if (skip_dc == 0) {
461
    //    LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]);
462 463
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
         re<last_re;
464
         x0p+=4) {
465

466 467 468 469 470 471
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
472
      //      LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]);
473 474 475 476 477
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
  else {
478
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
479 480
         re<6;
         x0p+=4) {
481

482 483 484 485 486 487 488 489 490 491
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }

492
    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
493 494
         re<12;
         x0p+=4) {
495

496 497 498 499 500 501 502 503 504 505
      qam16_table_offset_re=TWO[x0p[0]];
      qam16_table_offset_im=TWO[x0p[1]];
      qam16_table_offset_re+=x0p[2];
      qam16_table_offset_im+=x0p[3];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
506 507 508 509 510 511 512 513 514 515
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 5;
    *jj=*jj + 20;
  }
  else
  {
    *re_allocated = *re_allocated + 10;
    *jj=*jj + 40;
  }
516 517 518 519

  return(0);
}

520
int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
                                            int **txdataF,
                                            uint32_t *jj,
                                            uint32_t *jj2,
                                            uint16_t re_offset,
                                            uint32_t symbol_offset,
                                            LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                            LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                            uint8_t pilots,
                                            int16_t amp,
                                            uint8_t precoder_index,
                                            int16_t *qam_table_s0,
                                            int16_t *qam_table_s1,
                                            uint32_t *re_allocated,
                                            uint8_t skip_dc,
                                            uint8_t skip_half,
                                            uint8_t lprime,
                                            uint8_t mprime,
                                            uint8_t Ns,
                                            int *P1_SHIFT,
                                            int *P2_SHIFT)
541 542
{

543
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
544

545
  uint8_t *x0             = dlsch0_harq->eDL;
546 547 548 549 550 551
  uint32_t qam64_table_offset_re = 0;
  uint32_t qam64_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
WANG Tsu-Han's avatar
WANG Tsu-Han committed
552
  uint8_t first_re;
553 554

  first_re=0;
WANG Tsu-Han's avatar
WANG Tsu-Han committed
555
  if (skip_half==2)
556 557
    first_re=6;
  re=first_re;
558 559 560

  if (skip_dc == 0) {

561
    x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
562

563
    /*    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
564 565
         re<12;
         re+=4,x0p+=24,tti_offset+=4) {*/
566

567 568
      qam64_table_offset_re=(x0p[0]<<2)|(x0p[2]<<1)|x0p[4];
      qam64_table_offset_im=(x0p[1]<<2)|(x0p[3]<<1)|x0p[5];
569 570
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
571

572 573
      qam64_table_offset_re=(x0p[6]<<2)|(x0p[8]<<1)|x0p[10];
      qam64_table_offset_im=(x0p[7]<<2)|(x0p[9]<<1)|x0p[11];
574 575 576
      ((int16_t *)&txdataF[0][tti_offset])[2]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[3]=qam_table_s0[qam64_table_offset_im];

577 578
      qam64_table_offset_re=(x0p[12]<<2)|(x0p[14]<<1)|x0p[16];
      qam64_table_offset_im=(x0p[13]<<2)|(x0p[15]<<1)|x0p[17];
579 580 581
      ((int16_t *)&txdataF[0][tti_offset])[4]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[5]=qam_table_s0[qam64_table_offset_im];

582 583
      qam64_table_offset_re=(x0p[18]<<2)|(x0p[20]<<1)|x0p[22];
      qam64_table_offset_im=(x0p[19]<<2)|(x0p[21]<<1)|x0p[23];
584 585
      ((int16_t *)&txdataF[0][tti_offset])[6]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[7]=qam_table_s0[qam64_table_offset_im];
586 587 588 589 590 591 592 593 594 595 596

      qam64_table_offset_re=(x0p[24]<<2)|(x0p[26]<<1)|x0p[28];
      qam64_table_offset_im=(x0p[25]<<2)|(x0p[27]<<1)|x0p[29];
      ((int16_t *)&txdataF[0][tti_offset])[8]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[9]=qam_table_s0[qam64_table_offset_im];

      qam64_table_offset_re=(x0p[30]<<2)|(x0p[32]<<1)|x0p[34];
      qam64_table_offset_im=(x0p[31]<<2)|(x0p[33]<<1)|x0p[35];
      ((int16_t *)&txdataF[0][tti_offset])[10]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[11]=qam_table_s0[qam64_table_offset_im];

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
      if(skip_half==0)
      {
        qam64_table_offset_re=(x0p[36]<<2)|(x0p[38]<<1)|x0p[40];
        qam64_table_offset_im=(x0p[37]<<2)|(x0p[39]<<1)|x0p[41];
        ((int16_t *)&txdataF[0][tti_offset])[12]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[13]=qam_table_s0[qam64_table_offset_im];

        qam64_table_offset_re=(x0p[42]<<2)|(x0p[44]<<1)|x0p[46];
        qam64_table_offset_im=(x0p[43]<<2)|(x0p[45]<<1)|x0p[47];
        ((int16_t *)&txdataF[0][tti_offset])[14]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[15]=qam_table_s0[qam64_table_offset_im];

        qam64_table_offset_re=(x0p[48]<<2)|(x0p[50]<<1)|x0p[52];
        qam64_table_offset_im=(x0p[49]<<2)|(x0p[51]<<1)|x0p[53];
        ((int16_t *)&txdataF[0][tti_offset])[16]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[17]=qam_table_s0[qam64_table_offset_im];

WANG Tsu-Han's avatar
WANG Tsu-Han committed
614
        qam64_table_offset_re=(x0p[54]<<2)|(x0p[56]<<1)|x0p[58];
615 616 617 618 619 620 621 622 623 624 625 626 627 628
        qam64_table_offset_im=(x0p[55]<<2)|(x0p[57]<<1)|x0p[59];
        ((int16_t *)&txdataF[0][tti_offset])[18]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[19]=qam_table_s0[qam64_table_offset_im];

        qam64_table_offset_re=(x0p[60]<<2)|(x0p[62]<<1)|x0p[64];
        qam64_table_offset_im=(x0p[61]<<2)|(x0p[63]<<1)|x0p[65];
        ((int16_t *)&txdataF[0][tti_offset])[20]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[21]=qam_table_s0[qam64_table_offset_im];

        qam64_table_offset_re=(x0p[66]<<2)|(x0p[68]<<1)|x0p[70];
        qam64_table_offset_im=(x0p[67]<<2)|(x0p[69]<<1)|x0p[71];
        ((int16_t *)&txdataF[0][tti_offset])[22]=qam_table_s0[qam64_table_offset_re];
        ((int16_t *)&txdataF[0][tti_offset])[23]=qam_table_s0[qam64_table_offset_im];
      }
629 630

      //    }
631 632
  }
  else {
633
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0;
634 635
         re<6;
         re++,x0p+=6,tti_offset++) {
636

637 638 639 640 641 642 643 644 645 646
      qam64_table_offset_re=FOUR[x0p[0]];
      qam64_table_offset_im=FOUR[x0p[1]];
      qam64_table_offset_re+=TWO[x0p[2]];
      qam64_table_offset_im+=TWO[x0p[3]];
      qam64_table_offset_re+=x0p[4];
      qam64_table_offset_im+=x0p[5];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
    }

647
    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7;
648 649
         re<12;
         re++,x0p+=6,tti_offset++) {
650

651 652 653 654 655 656 657 658 659 660 661
      qam64_table_offset_re=FOUR[x0p[0]];
      qam64_table_offset_im=FOUR[x0p[1]];
      qam64_table_offset_re+=TWO[x0p[2]];
      qam64_table_offset_im+=TWO[x0p[3]];
      qam64_table_offset_re+=x0p[4];
      qam64_table_offset_im+=x0p[5];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
    }
  }

662 663 664 665 666 667 668 669 670 671
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 6;
    *jj=*jj + 36;
  }
  else
  {
    *re_allocated = *re_allocated + 12;
    *jj=*jj + 72;
  }
672

673 674 675
  return(0);
}

676
int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB,
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
                                         int **txdataF,
                                         uint32_t *jj,
                                         uint32_t *jj2,
                                         uint16_t re_offset,
                                         uint32_t symbol_offset,
                                         LTE_DL_eNB_HARQ_t *dlsch0_harq,
                                         LTE_DL_eNB_HARQ_t *dlsch1_harq,
                                         uint8_t pilots,
                                         int16_t amp,
                                         uint8_t precoder_index,
                                         int16_t *qam_table_s0,
                                         int16_t *qam_table_s1,
                                         uint32_t *re_allocated,
                                         uint8_t skip_dc,
                                         uint8_t skip_half,
                                         uint8_t lprime,
                                         uint8_t mprime,
                                         uint8_t Ns,
                                         int *P1_SHIFT,
                                         int *P2_SHIFT)
697
{
698

699

700
  LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms;
701

702
  uint8_t *x0             = dlsch0_harq->eDL;
703 704 705 706 707 708
  uint32_t qam64_table_offset_re = 0;
  uint32_t qam64_table_offset_im = 0;

  uint32_t tti_offset;
  uint8_t re;
  uint8_t *x0p;
709 710 711 712 713 714 715 716 717
  uint8_t first_re,last_re;

  last_re=12;
  first_re=0;
  if (skip_half==1)
    last_re=6;
  else if (skip_half==2)
    first_re=6;
  re=first_re+P1_SHIFT[0];
718 719 720


  if (skip_dc == 0) {
721
    //    LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]);
722 723
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re;
         re<last_re;
724
         x0p+=6) {
725

726 727 728 729 730 731 732 733
      qam64_table_offset_re=FOUR[x0p[0]];
      qam64_table_offset_im=FOUR[x0p[1]];
      qam64_table_offset_re+=TWO[x0p[2]];
      qam64_table_offset_im+=TWO[x0p[3]];
      qam64_table_offset_re+=x0p[4];
      qam64_table_offset_im+=x0p[5];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
734
      //      LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]);
735 736 737 738 739
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
  else {
740
    for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0];
741 742
         re<6;
         x0p+=6) {
743

744 745 746 747 748 749 750 751 752 753 754 755
      qam64_table_offset_re=FOUR[x0p[0]];
      qam64_table_offset_im=FOUR[x0p[1]];
      qam64_table_offset_re+=TWO[x0p[2]];
      qam64_table_offset_im+=TWO[x0p[3]];
      qam64_table_offset_re+=x0p[4];
      qam64_table_offset_im+=x0p[5];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }

756
    for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6];
757 758
         re<12;
         x0p+=6) {
759

760 761 762 763 764 765 766 767 768 769 770 771
      qam64_table_offset_re=FOUR[x0p[0]];
      qam64_table_offset_im=FOUR[x0p[1]];
      qam64_table_offset_re+=TWO[x0p[2]];
      qam64_table_offset_im+=TWO[x0p[3]];
      qam64_table_offset_re+=x0p[4];
      qam64_table_offset_im+=x0p[5];
      ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re];
      ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im];
      tti_offset+=P1_SHIFT[re+1];
      re+=P1_SHIFT[re+1];
    }
  }
772 773 774 775 776 777 778 779 780 781
  if(skip_half!=0)
  {
    *re_allocated = *re_allocated + 5;
    *jj=*jj + 30;
  }
  else
  {
    *re_allocated = *re_allocated + 10;
    *jj=*jj + 60;
  }
782 783 784 785

  return(0);
}

786
int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
787
                       int32_t **txdataF,
788 789 790 791 792 793 794 795 796 797 798 799 800
                       uint32_t *jj,
                       uint32_t *jj2,
                       uint16_t re_offset,
                       uint32_t symbol_offset,
                       LTE_DL_eNB_HARQ_t *dlsch0_harq,
                       LTE_DL_eNB_HARQ_t *dlsch1_harq,
                       uint8_t pilots,
                       int16_t amp,
                       uint8_t precoder_index,
                       int16_t *qam_table_s0,
                       int16_t *qam_table_s1,
                       uint32_t *re_allocated,
                       uint8_t skip_dc,
801
                       uint8_t skip_half,
802 803 804 805 806
                       uint8_t lprime,
                       uint8_t mprime,
                       uint8_t Ns,
                       int *P1_SHIFT,
                       int *P2_SHIFT)
807
{
808

Wang Tsu-Han's avatar
Wang Tsu-Han committed
809

810
  uint8_t *x0 = NULL;
Cedric Roux's avatar
Cedric Roux committed
811
  MIMO_mode_t mimo_mode = -1;
Xiwen JIANG's avatar
Xiwen JIANG committed
812

813 814
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;

815

816
  int first_layer0 = -1; //= dlsch0_harq->first_layer;
Cedric Roux's avatar
Cedric Roux committed
817
  int Nlayers0 = -1; //  = dlsch0_harq->Nlayers;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
818 819
  uint8_t mod_order0=0;
  uint8_t mod_order1=0;
820
  uint8_t precoder_index0,precoder_index1;
821

Raymond Knopp's avatar
 
Raymond Knopp committed
822 823 824 825
  uint8_t *x1=NULL;
  // Fill these in later for TM8-10
  //  int Nlayers1;
  //  int first_layer1;
Xiwen JIANG's avatar
Xiwen JIANG committed
826

827
  int use2ndpilots = (frame_parms->nb_antenna_ports_eNB==1)?1:0;
828

829
  uint32_t tti_offset; //,aa;
830 831 832 833 834
  uint8_t re;
  uint8_t qam64_table_offset_re = 0;
  uint8_t qam64_table_offset_im = 0;
  uint8_t qam16_table_offset_re = 0;
  uint8_t qam16_table_offset_im = 0;
835 836 837 838 839 840 841 842 843 844 845
  uint8_t qam64_table_offset_re0 = 0;
  uint8_t qam64_table_offset_im0 = 0;
  uint8_t qam16_table_offset_re0 = 0;
  uint8_t qam16_table_offset_im0 = 0;
  uint8_t qam64_table_offset_re1 = 0;
  uint8_t qam64_table_offset_im1 = 0;
  uint8_t qam16_table_offset_re1 = 0;
  uint8_t qam16_table_offset_im1 = 0;
  int16_t xx0_re,xx1_re;
  int16_t xx0_im,xx1_im;

846 847
  int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2;
  int16_t re_off=re_offset;
848

849 850 851
  uint8_t first_re,last_re;
  int32_t tmp_sample1,tmp_sample2;
  int16_t tmp_amp=amp;
852
  int s=1;
853
  int mprime2 = mprime,ind,ind_dword,ind_qpsk_symb;
854 855 856

  gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);

857 858 859 860 861 862 863 864 865 866
  int32_t qpsk[4];
  ((int16_t *)&qpsk[0])[0] = gain_lin_QPSK;
  ((int16_t *)&qpsk[0])[1] = gain_lin_QPSK;
  ((int16_t *)&qpsk[1])[0] = -gain_lin_QPSK;
  ((int16_t *)&qpsk[1])[1] = gain_lin_QPSK;;
  ((int16_t *)&qpsk[2])[0] = gain_lin_QPSK;;
  ((int16_t *)&qpsk[2])[1] = -gain_lin_QPSK;;
  ((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;;
  ((int16_t *)&qpsk[3])[1] = -gain_lin_QPSK;

867 868
  if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4

869
    x0 = dlsch0_harq->eDL;
870 871 872
    mimo_mode = dlsch0_harq->mimo_mode;
    first_layer0 = dlsch0_harq->first_layer;
    Nlayers0 = dlsch0_harq->Nlayers;
873
    mod_order0 = dlsch0_harq->Qm;
874
    x1             = dlsch1_harq->eDL;
Raymond Knopp's avatar
 
Raymond Knopp committed
875
    // Fill these in later for TM8-10
876
    //    Nlayers1       = dlsch1_harq->Nlayers;
Raymond Knopp's avatar
 
Raymond Knopp committed
877
    //    first_layer1   = dlsch1_harq->first_layer;
878
    mod_order1     = dlsch1_harq->Qm;
879

880 881
  } else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc

882
    x0 = dlsch0_harq->eDL;
883 884 885
    mimo_mode = dlsch0_harq->mimo_mode;
    first_layer0 = dlsch0_harq->first_layer;
    Nlayers0 = dlsch0_harq->Nlayers;
886
    mod_order0 = dlsch0_harq->Qm;
887 888 889

  } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission

890
    x0 = dlsch1_harq->eDL;
891 892 893
    mimo_mode = dlsch1_harq->mimo_mode;
    first_layer0 = dlsch1_harq->first_layer;
    Nlayers0 = dlsch1_harq->Nlayers;
894
    mod_order0 = dlsch1_harq->Qm;
895

896
  }
897

898 899
  if (dlsch0_harq != NULL){
    #ifdef DEBUG_DLSCH_MODULATION
900
      LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]);
901 902 903
    #endif
  } else{
    #ifdef DEBUG_DLSCH_MODULATION
904
      LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]);
905 906
    #endif
  }
907 908 909 910

  first_re=0;
  last_re=12;

911
  if (skip_half==1)
912 913 914
    last_re=6;
  else if (skip_half==2)
    first_re=6;
915

916

Xiwen JIANG's avatar
Xiwen JIANG committed
917
  for (re=first_re; re<last_re; re++) {
918
  // LOG_I(PHY,"element %d precoder_index for allocation %d\n",re, precoder_index );
919

920 921
    if ((skip_dc == 1) && (re==6))
      re_off=re_off - frame_parms->ofdm_symbol_size+1;
922

923
    tti_offset = symbol_offset + re_off + re;
924

lukashov's avatar
lukashov committed
925
      //check that RE is not from Cell-specific RS
Raymond Knopp's avatar
 
Raymond Knopp committed
926

927
    if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) {
928
      //LOG_I(PHY,"re %d (jj %d)\n",re,*jj);
Raymond Knopp's avatar
 
Raymond Knopp committed
929

930

931
      if (mimo_mode == SISO) {  //SISO mapping
932 933 934 935 936
        *re_allocated = *re_allocated + 1;

        switch (mod_order0) {
        case 2:  //QPSK

937

938
          //LOG_I(PHY,"re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
939
          ((int16_t*)&txdataF[0][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
940 941 942

          *jj = *jj + 1;

943
          ((int16_t*)&txdataF[0][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974

          *jj = *jj + 1;

          break;

        case 4:  //16QAM

          qam16_table_offset_re = 0;
          qam16_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam16_table_offset_re+=2;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam16_table_offset_im+=2;

          *jj=*jj+1;


          if (x0[*jj] == 1)
            qam16_table_offset_re+=1;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam16_table_offset_im+=1;

          *jj=*jj+1;

975 976
          ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
          ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015

          break;

        case 6:  //64QAM


          qam64_table_offset_re = 0;
          qam64_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam64_table_offset_re+=4;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam64_table_offset_im+=4;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam64_table_offset_re+=2;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam64_table_offset_im+=2;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam64_table_offset_re+=1;

          *jj=*jj+1;

          if (x0[*jj] == 1)
            qam64_table_offset_im+=1;

          *jj=*jj+1;

1016 1017
          ((int16_t *)&txdataF[0][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];
          ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];
1018 1019 1020 1021

          break;

        }
1022
      }
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046

      else if (mimo_mode == ALAMOUTI) {
        *re_allocated = *re_allocated + 1;

        amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);


        switch (mod_order0) {
        case 2:  //QPSK

          // first antenna position n -> x0

          ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj=*jj+1;
          ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj=*jj+1;

          // second antenna position n -> -x1*

          ((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
          *jj=*jj+1;
          ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj=*jj+1;

1047
	  //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
1048
          // normalization for 2 tx antennas
1049 1050 1051 1052
          ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]));
          ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]));
          ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]));
          ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]));
1053

lukashov's avatar
lukashov committed
1054
        break;
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076

        case 4:  //16QAM

          // Antenna 0 position n
          qam16_table_offset_re = 0;
          qam16_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam16_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=2;
          *jj=*jj+1;


          if (x0[*jj] == 1)
            qam16_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=1;
          *jj=*jj+1;

1077 1078
          //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
          //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
1079 1080 1081
	  //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
	  ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]);
	  ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102

          // Antenna 1 position n Real part -> -x1*

          qam16_table_offset_re = 0;
          qam16_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam16_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=2;
          *jj=*jj+1;


          if (x0[*jj] == 1)
            qam16_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=1;
          *jj=*jj+1;

1103 1104
          //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
          //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
1105 1106 1107
	  //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
	  ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam16_table_offset_re]);
	  ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]);
1108

1109 1110
         //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re];
         //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138

          break;

        case 6:   // 64-QAM

          // Antenna 0
          qam64_table_offset_re = 0;
          qam64_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam64_table_offset_re+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=1;
          *jj=*jj+1;

1139 1140
          //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
          //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
1141 1142 1143
	  //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
	  ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]);
	  ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]);
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167


          // Antenna 1 => -x1*
          qam64_table_offset_re = 0;
          qam64_table_offset_im = 0;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=1;
          *jj=*jj+1;

1168 1169
          //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
          //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
1170 1171 1172
	  //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore
	  ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam64_table_offset_re]);
	  ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]);
1173 1174 1175 1176


          break;
        }
1177
  // fill in the rest of the ALAMOUTI precoding
1178 1179 1180 1181 1182
        if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) {
          ((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
          ((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
          ((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0];  //x0*
          ((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
lukashov's avatar
lukashov committed
1183 1184
        }
        else {
1185 1186 1187 1188 1189
          ((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
          ((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
          ((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0];  //x0*
          ((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
        }
1190
      }
1191
      else if (mimo_mode == LARGE_CDD) {
1192 1193 1194

        *re_allocated = *re_allocated + 1;

1195
        if (frame_parms->nb_antenna_ports_eNB == 2) {
1196
          switch (mod_order0) {
lukashov's avatar
lukashov committed
1197

1198 1199 1200 1201 1202 1203
          default:
            LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
            xx0_re=xx0_im=0;
            break;

          case 2:  //QPSK
1204
            //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1205 1206 1207 1208
            xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj = *jj + 1;
            xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj = *jj + 1;
1209
            //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
            break;

          case 4:  //16QAM

            qam16_table_offset_re0 = 0;
            qam16_table_offset_im0 = 0;
            if (x0[*jj] == 1)
              qam16_table_offset_re0+=2;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam16_table_offset_im0+=2;
            *jj=*jj+1;

            if (x0[*jj] == 1)
              qam16_table_offset_re0+=1;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam16_table_offset_im0+=1;
            *jj=*jj+1;

            xx0_re = qam_table_s0[qam16_table_offset_re0];
            xx0_im = qam_table_s0[qam16_table_offset_im0];

            break;

          case 6:  //64QAM


            qam64_table_offset_re0 = 0;
            qam64_table_offset_im0 = 0;

            if (x0[*jj] == 1)
              qam64_table_offset_re0+=4;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam64_table_offset_im0+=4;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam64_table_offset_re0+=2;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam64_table_offset_im0+=2;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam64_table_offset_re0+=1;
            *jj=*jj+1;
            if (x0[*jj] == 1)
              qam64_table_offset_im0+=1;
            *jj=*jj+1;

            xx0_re = qam_table_s0[qam64_table_offset_re0];
            xx0_im = qam_table_s0[qam64_table_offset_im0];

            break;

          }

          switch (mod_order1) {
lukashov's avatar
lukashov committed
1268

1269 1270 1271 1272 1273 1274
          default:
            LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1);
            xx1_re=xx1_im=0;
            break;

          case 2:  //QPSK
1275
            //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1276 1277 1278 1279
            xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj2 = *jj2 + 1;
            xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj2 = *jj2 + 1;
1280
            //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
            break;

          case 4:  //16QAM

            qam16_table_offset_re1 = 0;
            qam16_table_offset_im1 = 0;
            if (x1[*jj2] == 1)
              qam16_table_offset_re1+=2;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam16_table_offset_im1+=2;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam16_table_offset_re1+=1;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam16_table_offset_im1+=1;
            *jj2 = *jj2 + 1;

            xx1_re = qam_table_s1[qam16_table_offset_re1];
            xx1_im = qam_table_s1[qam16_table_offset_im1];

            break;

          case 6:  //64QAM

            qam64_table_offset_re1 = 0;
            qam64_table_offset_im1 = 0;

            if (x1[*jj2] == 1)
              qam64_table_offset_re1+=4;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im1+=4;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam64_table_offset_re1+=2;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im1+=2;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam64_table_offset_re1+=1;
            *jj2 = *jj2 + 1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im1+=1;
            *jj2 = *jj2 + 1;

            xx1_re = qam_table_s1[qam64_table_offset_re1];
            xx1_im = qam_table_s1[qam64_table_offset_im1];

            break;

          }

          // This implements the Large CDD precoding for 2 TX antennas
          // -  -        -    -  -         -  -     -  -  -       -              -
          //| y0 |      | 1  0 || 1    0    || 1   1 || x0 |     |        x0 + x1 |
          //| y1 | = .5 | 0  1 || 0  (-1)^i || 1  -1 || x1 | = .5| (-1)^i(x0 - x1)|
          // -  -        -    -  -         -  -     -  -  -       -
          // Note: Factor .5 is accounted for in amplitude when calling this function
          ((int16_t *)&txdataF[0][tti_offset])[0]+=((xx0_re+xx1_re)>>1);
          ((int16_t *)&txdataF[1][tti_offset])[0]+=(s*((xx0_re-xx1_re)>>1));
          ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1);
          ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1));
          /*
1347
          LOG_I(PHY,"CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n",
1348 1349 1350 1351 1352 1353
           xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1],
           ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]);
          */
          // s alternates +1/-1 for each RE
          s = -s;
        }
1354
      }
1355
      else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) {
lukashov's avatar
lukashov committed
1356
  // this is for transmission modes 5-6 (1 layer)
1357 1358 1359 1360
        *re_allocated = *re_allocated + 1;
        amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);

        switch (mod_order0) {
lukashov's avatar
lukashov committed
1361
        case 2:
1362 1363 1364 1365 1366 1367

          ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj = *jj + 1;
          ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj = *jj + 1;

lukashov's avatar
lukashov committed
1368
          //normalization for 2 tx antennas
1369
          /*((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
1370 1371
          ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);

1372
          if (frame_parms->nb_antenna_ports_eNB == 2) {
1373 1374 1375
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
            ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386
          }*/

          // We remove ONE_OVER_SQRT2_Q15 that was coming from precoder, as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function

          ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
          ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];

          if (frame_parms->nb_antenna_ports_eNB == 2) {
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
            ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
            ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
1387 1388 1389 1390
          }

          break;

lukashov's avatar
lukashov committed
1391
        case 4:
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411

          qam16_table_offset_re = 0;
          qam16_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam16_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=2;
          *jj=*jj+1;


          if (x0[*jj] == 1)
            qam16_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=1;
          *jj=*jj+1;


lukashov's avatar
lukashov committed
1412 1413
           ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));
           ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));
1414

1415 1416
           ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
           ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];
1417

lukashov's avatar
lukashov committed
1418
          if (frame_parms->nb_antennas_tx == 2) {
1419 1420 1421 1422 1423 1424 1425
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
            ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
            ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
          }

          break;

lukashov's avatar
lukashov committed
1426
        case 6:
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448

          qam64_table_offset_re = 0;
          qam64_table_offset_im = 0;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=1;
          *jj=*jj+1;

lukashov's avatar
lukashov committed
1449 1450
          ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));
          ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));
1451 1452 1453 1454

          ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0];
          ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1];

1455
          if (frame_parms->nb_antenna_ports_eNB == 2) {
1456 1457 1458 1459 1460 1461
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
            ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0];
            ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1];
          }

          break;
lukashov's avatar
lukashov committed
1462
        }
1463
      }
1464
      else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) {
lukashov's avatar
lukashov committed
1465
  // this is for transmission mode 4 (1 layer)
1466
        *re_allocated = *re_allocated + 1;
1467

lukashov's avatar
lukashov committed
1468 1469 1470 1471 1472 1473 1474 1475 1476
        if (precoder_index==0) {
          precoder_index0 = 0; //[1 1]
          precoder_index1 = 1; //[1 -1]
        }
        else if (precoder_index==1) {
          precoder_index0 = 2; //[1 j]
          precoder_index1 = 3; //[1 -j]
        }
        else {
1477
         LOG_I(PHY,"problem with precoder in TM4\n");
lukashov's avatar
lukashov committed
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
          return(-1);
        }

        switch (mod_order0) {
        case 2:

          ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj = *jj + 1;
          ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
          *jj = *jj + 1;

          //normalization for 2 tx antennas
1490 1491 1492 1493 1494
          // We remove ONE_OVER_2_Q15 that was coming from precoder,
          //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function
          //ONE_OVER_SQRT2_Q15 remains from it
          ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
          ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1495

1496
          //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1497

1498
          if (frame_parms->nb_antenna_ports_eNB == 2) {
lukashov's avatar
lukashov committed
1499
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
1500 1501
            ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1502 1503 1504
          }

        break;
1505

lukashov's avatar
lukashov committed
1506
        case 4:
1507

lukashov's avatar
lukashov committed
1508 1509 1510 1511 1512 1513 1514 1515 1516
          qam16_table_offset_re = 0;
          qam16_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam16_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=2;
          *jj=*jj+1;
1517

lukashov's avatar
lukashov committed
1518 1519 1520 1521 1522 1523
          if (x0[*jj] == 1)
            qam16_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam16_table_offset_im+=1;
          *jj=*jj+1;
1524

lukashov's avatar
lukashov committed
1525 1526
           ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));
           ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));
1527 1528 1529 1530 1531 1532

           // We remove ONE_OVER_2_Q15 that was coming from precoder,
           //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function
           //ONE_OVER_SQRT2_Q15 remains from it
           ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
           ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
1533

1534
          if (frame_parms->nb_antenna_ports_eNB == 2) {
lukashov's avatar
lukashov committed
1535
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
1536 1537
            ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1538 1539 1540
          }

          break;
1541

lukashov's avatar
lukashov committed
1542
        case 6:
1543

lukashov's avatar
lukashov committed
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564
          qam64_table_offset_re = 0;
          qam64_table_offset_im = 0;

          if (x0[*jj] == 1)
            qam64_table_offset_re+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=4;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=2;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_re+=1;
          *jj=*jj+1;
          if (x0[*jj] == 1)
            qam64_table_offset_im+=1;
          *jj=*jj+1;
1565

lukashov's avatar
lukashov committed
1566 1567
          ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));
          ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));
1568 1569
          ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
          ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
1570

1571 1572 1573 1574
          if (frame_parms->nb_antennas_tx == 2) {
            layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
            ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1575
          }
1576

lukashov's avatar
lukashov committed
1577 1578
          break;
        }
1579

lukashov's avatar
lukashov committed
1580 1581
        if (dlsch1_harq) {
          switch (mod_order1) {
1582

lukashov's avatar
lukashov committed
1583 1584 1585 1586 1587 1588 1589 1590
          case 2:

            ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj2 = *jj2 + 1;
            ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
            *jj2 = *jj2 + 1;

            //normalization for 2 tx antennas
1591 1592
            ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1593

1594
            if (frame_parms->nb_antenna_ports_eNB== 2) {
lukashov's avatar
lukashov committed
1595
              layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
1596 1597
              ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
              ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1598 1599 1600
            }

            break;
1601

lukashov's avatar
lukashov committed
1602
          case 4:
1603

lukashov's avatar
lukashov committed
1604 1605 1606 1607 1608 1609 1610 1611 1612
            qam16_table_offset_re = 0;
            qam16_table_offset_im = 0;

            if (x1[*jj2] == 1)
              qam16_table_offset_re+=2;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam16_table_offset_im+=2;
            *jj2=*jj2+1;
1613 1614


lukashov's avatar
lukashov committed
1615 1616 1617 1618 1619 1620
            if (x1[*jj2] == 1)
              qam16_table_offset_re+=1;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam16_table_offset_im+=1;
            *jj2=*jj2+1;
1621

lukashov's avatar
lukashov committed
1622 1623
             ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));
             ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));
1624 1625
             ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
             ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
1626

1627
            if (frame_parms->nb_antenna_ports_eNB == 2) {
lukashov's avatar
lukashov committed
1628
              layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
1629 1630
              ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
              ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1631 1632 1633
            }

            break;
1634

lukashov's avatar
lukashov committed
1635
          case 6:
1636

lukashov's avatar
lukashov committed
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656
            qam64_table_offset_re = 0;
            qam64_table_offset_im = 0;
            if (x1[*jj2] == 1)
              qam64_table_offset_re+=4;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im+=4;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam64_table_offset_re+=2;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im+=2;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam64_table_offset_re+=1;
            *jj2=*jj2+1;
            if (x1[*jj2] == 1)
              qam64_table_offset_im+=1;
            *jj2=*jj2+1;
1657

lukashov's avatar
lukashov committed
1658 1659
            ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));
            ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));
1660 1661
            ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
            ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
1662

1663
            if (frame_parms->nb_antenna_ports_eNB == 2) {
lukashov's avatar
lukashov committed
1664
              layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
1665 1666
              ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
              ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
lukashov's avatar
lukashov committed
1667
            }
1668

lukashov's avatar
lukashov committed
1669
            break;
1670

lukashov's avatar
lukashov committed
1671 1672
          }
        }
Xiwen JIANG's avatar
Xiwen JIANG committed
1673 1674
      }

1675

Xiwen JIANG's avatar
Xiwen JIANG committed
1676 1677 1678 1679 1680 1681 1682 1683 1684
      if (mimo_mode == ALAMOUTI) {
        re++;  // adjacent carriers are taken care of by precoding
        *re_allocated = *re_allocated + 1;

        if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==0) {
          re++;
          *re_allocated = *re_allocated + 1;
        }
      }
1685

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
      if (mimo_mode == TM7) {
        *re_allocated = *re_allocated + 1;

        if (is_not_UEspecRS(lprime,re,frame_parms->Nid_cell%3,frame_parms->Ncp,7)) {

          switch (mod_order0){
            case 2:  //QPSK

              ((int16_t*)&txdataF[5][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
              *jj = *jj + 1;
              ((int16_t*)&txdataF[5][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
              *jj = *jj + 1;

1699
              //LOG_I(PHY,"%d(%d) : %d,%d =>
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777
              //",tti_offset,*jj,((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[1]);
              break;

            case 4:  //16QAM

              qam16_table_offset_re = 0;
              qam16_table_offset_im = 0;

              if (x0[*jj] == 1)
                qam16_table_offset_re+=2;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam16_table_offset_im+=2;

              *jj=*jj+1;


              if (x0[*jj] == 1)
                qam16_table_offset_re+=1;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam16_table_offset_im+=1;

              *jj=*jj+1;

              ((int16_t*)&txdataF[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
              ((int16_t*)&txdataF[5][tti_offset])[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);

              break;

            case 6:  //64QAM


              qam64_table_offset_re = 0;
              qam64_table_offset_im = 0;

              if (x0[*jj] == 1)
                qam64_table_offset_re+=4;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam64_table_offset_im+=4;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam64_table_offset_re+=2;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam64_table_offset_im+=2;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam64_table_offset_re+=1;

              *jj=*jj+1;

              if (x0[*jj] == 1)
                qam64_table_offset_im+=1;

              *jj=*jj+1;

              ((int16_t*)&txdataF[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
              ((int16_t*)&txdataF[5][tti_offset])[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);

              break;

          }
        } else {
          //precoding UE spec RS
1778
          //LOG_I(PHY,"precoding UE spec RS\n");
1779 1780 1781 1782 1783 1784 1785 1786 1787

          ind = 3*lprime*dlsch0_harq->nb_rb+mprime2;
          ind_dword = ind>>4;
          ind_qpsk_symb = ind&0xf;

          txdataF[5][tti_offset] = qpsk[(phy_vars_eNB->lte_gold_uespec_port5_table[0][Ns][ind_dword]>>(2*ind_qpsk_symb))&3];
          mprime2++;

        }
Xiwen JIANG's avatar
Xiwen JIANG committed
1788

1789
      } else if (mimo_mode >= TM8) { //TM8,TM9,TM10
1790
        //uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode)
1791

1792
        if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
Xiwen JIANG's avatar
Xiwen JIANG committed
1793 1794 1795
          switch (mod_order0) {
          case 2:  //QPSK

1796
            //    LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
Xiwen JIANG's avatar
Xiwen JIANG committed
1797 1798 1799 1800 1801 1802 1803 1804 1805 1806
            for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
              ((int16_t*)&txdataF[layer][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
              *jj = *jj + 1;
              ((int16_t*)&txdataF[layer][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
              *jj = *jj + 1;
            }

            break;

          case 4:  //16QAM
1807
            if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) {
Xiwen JIANG's avatar
Xiwen JIANG committed
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881
              qam16_table_offset_re = 0;
              qam16_table_offset_im = 0;

              if (x0[*jj] == 1)
                qam16_table_offset_re+=2;

              *jj = *jj + 1;

              if (x0[*jj] == 1)
                qam16_table_offset_im+=2;

              *jj = *jj + 1;

              if (x0[*jj] == 1)
                qam16_table_offset_re+=1;

              *jj = *jj + 1;

              if (x0[*jj] == 1)
                qam16_table_offset_im+=1;

              *jj = *jj + 1;

              for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
                ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam16_table_offset_re];
                ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam16_table_offset_im];
              }
            }

            break;

          case 6:  //64QAM

            qam64_table_offset_re = 0;
            qam64_table_offset_im = 0;

            if (x0[*jj] == 1)
              qam64_table_offset_re+=4;

            *jj = *jj + 1;

            if (x0[*jj] == 1)
              qam64_table_offset_im+=4;

            *jj = *jj + 1;

            if (x0[*jj] == 1)
              qam64_table_offset_re+=2;

            *jj = *jj + 1;

            if (x0[*jj] == 1)
              qam64_table_offset_im+=2;

            *jj = *jj + 1;

            if (x0[*jj] == 1)
              qam64_table_offset_re+=1;

            *jj = *jj + 1;

            if (x0[*jj] == 1)
              qam64_table_offset_im+=1;

            *jj = *jj + 1;

            for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
              ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam64_table_offset_re];
              ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam64_table_offset_im];
            }

            break;

          }
1882
        }
Xiwen JIANG's avatar
Xiwen JIANG committed
1883
      } else if (mimo_mode>=TM9_10) {
1884
        LOG_I(PHY,"allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode);
Xiwen JIANG's avatar
Xiwen JIANG committed
1885
        return(-1);
1886
      }
1887 1888 1889 1890 1891
    }
  }
  return(0);
}

1892

1893
int allocate_REs_in_RB_MCH(int32_t **txdataF,
1894
                           uint32_t *jj,
1895 1896 1897 1898 1899 1900 1901 1902 1903 1904
                            uint16_t re_offset,
                            uint32_t symbol_offset,
                            uint8_t *x0,
                            uint8_t l,
                            uint8_t mod_order,
                            int16_t amp,
                            int16_t *qam_table_s,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
                            LTE_DL_FRAME_PARMS *frame_parms)
1905
{
1906

Xiwen JIANG's avatar
Xiwen JIANG committed
1907
  uint32_t tti_offset;
1908 1909 1910 1911 1912 1913 1914
  uint8_t re;
  uint8_t qam64_table_offset_re = 0;
  uint8_t qam64_table_offset_im = 0;
  uint8_t qam16_table_offset_re = 0;
  uint8_t qam16_table_offset_im = 0;
  int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2;
  int16_t re_off=re_offset;
1915
  gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
1916 1917 1918
  uint8_t first_re,last_re;
  int inc;
#ifdef DEBUG_DLSCH_MODULATION
1919
  LOG_I(PHY,"allocate_re_MCH (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]);
1920 1921 1922 1923 1924
#endif

  last_re=12;
  first_re=0;
  inc=1;
1925

1926 1927 1928
  if ((l==2)||(l==10)) {
    inc=2;
    first_re=1;
1929
  } else if (l==6) {
1930 1931
    inc=2;
  }
1932 1933 1934

  for (re=first_re; re<last_re; re+=inc) {

1935 1936
    if ((skip_dc == 1) && (re==(6+first_re)))
      re_off=re_off - frame_parms->ofdm_symbol_size+1;
1937

1938
    tti_offset = symbol_offset + re_off + re;
1939

1940
    //LOG_I(PHY,"re %d (jj %d)\n",re,*jj);
1941
    *re_allocated = *re_allocated + 1;
1942 1943


1944
    switch (mod_order) {
1945

1946
      case 2:  //QPSK
1947

1948
      //            LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1949
      ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
1950

Xiwen JIANG's avatar
Xiwen JIANG committed
1951
      *jj = *jj + 1;
1952

1953
      ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
1954

Xiwen JIANG's avatar
Xiwen JIANG committed
1955
      *jj = *jj + 1;
1956

1957
      //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1958 1959 1960
      break;


1961
      case 4:  //16QAM
1962

frtabu's avatar
frtabu committed
1963 1964 1965 1966
    if (qam_table_s == NULL) {
      LOG_E(PHY,"qam table pointer is NULL\n");
      return -1;
    }
1967 1968
    qam16_table_offset_re = 0;
    qam16_table_offset_im = 0;
1969

1970 1971
    if (x0[*jj] == 1)
      qam16_table_offset_re+=2;
1972

1973
    *jj=*jj+1;
1974

1975 1976
    if (x0[*jj] == 1)
      qam16_table_offset_im+=2;
1977

1978
    *jj=*jj+1;
1979 1980


1981 1982
    if (x0[*jj] == 1)
      qam16_table_offset_re+=1;
1983

1984
    *jj=*jj+1;
1985

1986 1987
    if (x0[*jj] == 1)
      qam16_table_offset_im+=1;
1988

1989
    *jj=*jj+1;
1990 1991


1992 1993
    ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
    ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
1994

1995
    break;
1996

1997
      case 6:  //64QAM
1998

1999 2000
    qam64_table_offset_re = 0;
    qam64_table_offset_im = 0;
2001

2002 2003
    if (x0[*jj] == 1)
      qam64_table_offset_re+=4;
2004

2005
    *jj=*jj+1;
2006

2007 2008
    if (x0[*jj] == 1)
      qam64_table_offset_im+=4;
2009

2010
    *jj=*jj+1;
2011

2012 2013
    if (x0[*jj] == 1)
      qam64_table_offset_re+=2;
2014

2015
    *jj=*jj+1;
2016

2017 2018
    if (x0[*jj] == 1)
      qam64_table_offset_im+=2;
2019

2020
    *jj=*jj+1;
2021

2022 2023
    if (x0[*jj] == 1)
      qam64_table_offset_re+=1;
2024

2025
    *jj=*jj+1;
2026

2027 2028
    if (x0[*jj] == 1)
      qam64_table_offset_im+=1;
2029

2030
    *jj=*jj+1;
2031

2032 2033
    ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
    ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
2034

2035
    break;
frtabu's avatar
frtabu committed
2036
    default:
2037
        LOG_E(PHY,"Invalid modulation order %i_n",mod_order);
frtabu's avatar
frtabu committed
2038
    break;
2039
    }
2040 2041
  }

2042 2043 2044 2045
  return(0);
}


Raymond Knopp's avatar
 
Raymond Knopp committed
2046

2047 2048 2049 2050 2051 2052 2053
inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline));
inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) {


  if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
    // PBCH
    if ((subframe_offset==0) &&
2054 2055 2056 2057
        (rb>((frame_parms->N_RB_DL>>1)-3)) &&
        (rb<((frame_parms->N_RB_DL>>1)+3)) &&
        (l>=(nsymb>>1)) &&
        (l<((nsymb>>1) + 4))) {
2058 2059 2060 2061 2062
      return(1);
    }
    if (frame_parms->frame_type == TDD) { // TDD
            //SSS TDD
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)) ) {
2063
        return(1);
2064
      }
2065 2066
      //PSS TDD
      if (((subframe_offset==1) || (subframe_offset==6)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==2) ) {
2067
        return(1);
2068 2069 2070 2071
      }
    } else {
      //PSS FDD
      if (((subframe_offset==0)||(subframe_offset==5)) &&
2072 2073 2074 2075
          (rb>((frame_parms->N_RB_DL>>1)-3)) &&
          (rb<((frame_parms->N_RB_DL>>1)+3)) &&
          (l==((nsymb>>1)-1)) ) {
        return(1);
2076 2077 2078
      }
      //SSS FDD
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) {
2079
        return(1);
2080 2081 2082 2083 2084 2085
      }
    }
  }
  else { // even N_RB_DL
    //PBCH
    if ((subframe_offset==0) &&
2086 2087 2088
        (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
        (rb<((frame_parms->N_RB_DL>>1)+3)) &&
        (l>=nsymb>>1) && (l<((nsymb>>1) + 4)))
2089 2090 2091 2092 2093
      return(1);

    if (frame_parms->frame_type == TDD) { // TDD
      //SSS
      if (((subframe_offset==0)||
2094 2095 2096 2097 2098
           (subframe_offset==5)) &&
          (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
          (rb<((frame_parms->N_RB_DL>>1)+3)) &&
          (l==nsymb-1) ) {
         return(1);
2099
      }
2100

2101 2102
      //PSS
      if (((subframe_offset==1)||
2103 2104 2105 2106 2107
           (subframe_offset==6)) &&
          (rb>=((frame_parms->N_RB_DL>>1)-3)) &&
          (rb<((frame_parms->N_RB_DL>>1)+3)) &&
          (l==2) ) {
         return(1);
2108 2109 2110 2111
      }
    } else { // FDD
      //SSS
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) {
2112
         return(1);
2113
      }
2114

2115 2116
      //PSS
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-1)) ) {
2117
         return(1);
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127
      }
    }
  }

  return(0);
}

inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline));
inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) {

2128
  //  LOG_I(PHY,"check_skiphalf : rb %d, subframe_offset %d,l %d, nsymb %d\n",rb,subframe_offset,l,nsymb);
2129 2130 2131 2132 2133

  if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL

    // PBCH
    if ((subframe_offset==0) &&
2134 2135 2136
        (rb==((frame_parms->N_RB_DL>>1)-3)) &&
        (l>=(nsymb>>1)) &&
        (l<((nsymb>>1) + 4)))
2137 2138 2139 2140 2141 2142 2143
      return(1);
    else if ((subframe_offset==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
      return(2);

    if (frame_parms->frame_type == TDD) { // TDD
      //SSS TDD
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==(nsymb-1)))
2144
        return(1);
2145
      else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)))
2146
        return(2);
2147 2148
      //PSS TDD
      if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==2))
2149
        return(1);
2150
      else if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==2))
2151
        return(2);
2152 2153 2154 2155
    }
    else { // FDD
      //PSS FDD
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==((nsymb>>1)-1)))
2156
        return(1);
2157
      else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(((nsymb>>1)-1))))
2158
        return(2);
2159 2160
      //SSS FDD
      if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && ((l==((nsymb>>1)-2))))
2161
        return(1);
2162
      else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && ((l==(nsymb>>1)-2)))
2163
        return(2);
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182
    }
  }
  else { // EVEN N_RB_DL
    return(0);
  }

  return(0);
}

inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) __attribute__((always_inline));
inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) {

  if (((frame_parms->N_RB_DL&1) == 1) &&  // odd N_RB_DL, rb==N_RB_DL/2 PRB contains DC element
      (rb==(frame_parms->N_RB_DL>>1)))
    return(1);
  else
    return(0);
}

Raymond Knopp's avatar
Raymond Knopp committed
2183

2184
int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
2185
                     int32_t **txdataF,
2186
                     int16_t amp,
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2187
                     int frame,
2188 2189 2190
                     uint32_t subframe_offset,
                     uint8_t num_pdcch_symbols,
                     LTE_eNB_DLSCH_t *dlsch0,
Xiwen JIANG's avatar
Xiwen JIANG committed
2191
                     LTE_eNB_DLSCH_t *dlsch1)
2192
{
2193
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
2194 2195

  uint8_t nsymb;
Cedric Roux's avatar
Cedric Roux committed
2196
  uint8_t harq_pid = -1; //= dlsch0->current_harq_pid;
Cedric Roux's avatar
Cedric Roux committed
2197
  LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL;
Cedric Roux's avatar
Cedric Roux committed
2198
  LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; //= dlsch1->harq_processes[harq_pid];
2199
  uint32_t i,i2,jj,jj2,re_allocated,symbol_offset;
2200 2201
  uint16_t l,rb,re_offset;
  uint32_t rb_alloc_ind;
Cedric Roux's avatar
Cedric Roux committed
2202
  uint32_t *rb_alloc = NULL; //=dlsch0_harq->rb_alloc;
2203

Xiwen JIANG's avatar
Xiwen JIANG committed
2204
  uint8_t pilots=0;
2205
  uint8_t skip_dc,skip_half;
2206
  uint8_t mod_order0 = 0;
2207
  uint8_t mod_order1 = 0;
2208
  int16_t amp_rho_a, amp_rho_b;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2209 2210
  int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8],qpsk_table_a0[2],qpsk_table_b0[2];
  int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8],qpsk_table_a1[2],qpsk_table_b1[2];
2211

2212
  int16_t *qam_table_s0=NULL,*qam_table_s1=NULL;
2213
  int (*allocate_REs)(PHY_VARS_eNB*,
2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
                      int **,
                      uint32_t*,
                      uint32_t*,
                      uint16_t,
                      uint32_t,
                      LTE_DL_eNB_HARQ_t *,
                      LTE_DL_eNB_HARQ_t *,
                      uint8_t,
                      int16_t,
                      uint8_t,
                      int16_t *,
                      int16_t *,
                      uint32_t *,
                      uint8_t,
                      uint8_t,
                      uint8_t,
                      uint8_t,
                      uint8_t,
                      int *,
                      int *);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2234

2235 2236


2237 2238
  int P1_SHIFT[13],P2_SHIFT[13];
  int offset,nushiftmod3;
2239

2240
  uint8_t get_pmi_temp;
2241

Cedric Roux's avatar
Cedric Roux committed
2242
  MIMO_mode_t mimo_mode = -1;
2243 2244
  uint8_t mprime=0,Ns;
  int8_t  lprime=-1;
2245

2246

Raymond Knopp's avatar
 
Raymond Knopp committed
2247
#ifdef DEBUG_DLSCH_MODULATION
2248
  uint8_t Nl0;  //= dlsch0_harq->Nl;
2249
  uint8_t Nl1;
Raymond Knopp's avatar
 
Raymond Knopp committed
2250
#endif
2251

2252

2253
  if ((dlsch0 != NULL) && (dlsch1 != NULL)){
2254

Wang Tsu-Han's avatar
Wang Tsu-Han committed
2255
    harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
2256 2257
    if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
      LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2258 2259
      return(-1);
    }
2260
    dlsch0_harq = dlsch0->harq_processes[harq_pid];
2261
    mimo_mode = dlsch0_harq->mimo_mode;
2262
    mod_order0 = dlsch0_harq->Qm;
2263 2264 2265 2266 2267
    rb_alloc = dlsch0_harq->rb_alloc;
#ifdef DEBUG_DLSCH_MODULATION
    Nl0 = dlsch0_harq->Nl;
#endif

2268
    dlsch1_harq = dlsch1->harq_processes[harq_pid];
2269
    mod_order1 = dlsch1_harq->Qm;
2270 2271 2272
#ifdef DEBUG_DLSCH_MODULATION
    Nl1 = dlsch1_harq->Nl;
#endif
2273 2274 2275

  }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){

Wang Tsu-Han's avatar
Wang Tsu-Han committed
2276
    harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
2277 2278
    if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
      LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2279 2280
      return(-1);
    }
2281
    dlsch0_harq = dlsch0->harq_processes[harq_pid];
2282
    mimo_mode = dlsch0_harq->mimo_mode;
2283
    mod_order0 = dlsch0_harq->Qm;
2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296
    rb_alloc = dlsch0_harq->rb_alloc;
#ifdef DEBUG_DLSCH_MODULATION
    Nl0 = dlsch0_harq->Nl;
#endif

    dlsch1_harq = NULL;
    mod_order1 = 0;
#ifdef DEBUG_DLSCH_MODULATION
    Nl1 = 0;
#endif

  }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){

Wang Tsu-Han's avatar
Wang Tsu-Han committed
2297
    harq_pid = dlsch1->harq_ids[frame%2][subframe_offset];
2298 2299
    if((harq_pid < 0) || (harq_pid >= dlsch1->Mdlharq)) {
      LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2300 2301
      return(-1);
    }
2302
    dlsch1_harq = dlsch1->harq_processes[harq_pid];
2303
    mimo_mode = dlsch1_harq->mimo_mode;
2304
    mod_order0 = dlsch1_harq->Qm;
2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315
    rb_alloc = dlsch1_harq->rb_alloc;
#ifdef DEBUG_DLSCH_MODULATION
    Nl0 = dlsch1_harq->Nl;
#endif

    dlsch0_harq = NULL;
    mod_order1 = 0;
#ifdef DEBUG_DLSCH_MODULATION
    Nl1 = NULL;
#endif

2316
  }
2317

2318
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN);
2319

2320
  nsymb = (frame_parms->Ncp==0) ? 14:12;
2321

2322
  if (dlsch0 != NULL){
2323
  amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); //amp=512 in  full scale; dlsch0->sqrt_rho_a=8192in Q2.13, 1 in full scale
2324
  amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13);
2325 2326 2327 2328
  } else{
  amp_rho_a = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_a)>>13);
  amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13);
  }
2329

Wang Tsu-Han's avatar
Wang Tsu-Han committed
2330
  if(mod_order0 == 2)
Eurecom's avatar
Eurecom committed
2331 2332 2333 2334 2335 2336 2337
  {
    for(i=0;i<2;i++)
    {
      qpsk_table_a0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15);
      qpsk_table_b0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15);
    }
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2338
  else if (mod_order0 == 4)
2339
    for (i=0;i<4; i++) {
2340 2341
      qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15);
      qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15);
2342
    }
2343
  else if (mod_order0 == 6)
2344
    for (i=0; i<8; i++) {
2345 2346
      qam64_table_a0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_a)>>15);
      qam64_table_b0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15);
2347
    }
2348

Wang Tsu-Han's avatar
Wang Tsu-Han committed
2349
  if (mod_order1 == 2)
Eurecom's avatar
Eurecom committed
2350 2351 2352 2353 2354 2355
  {
    for (i=0; i<2; i++) {
      qpsk_table_a1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15);
      qpsk_table_b1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15);
    }
  }
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2356
  else if (mod_order1 == 4)
2357
    for (i=0; i<4; i++) {
2358 2359 2360
      qam16_table_a1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15);
      qam16_table_b1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15);
    }
Raymond Knopp's avatar
Raymond Knopp committed
2361
  else if (mod_order1 == 6)
2362
    for (i=0; i<8; i++) {
2363 2364
      qam64_table_a1[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_a)>>15);
      qam64_table_b1[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15);
2365 2366
    }

2367
  //Modulation mapping (difference w.r.t. LTE specs)
2368 2369 2370

  jj=0;
  jj2=0;
2371
  re_allocated=0;
2372

2373

2374
  //  LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
2375 2376
  for (l=num_pdcch_symbols; l<nsymb; l++) {

2377
  if (dlsch0 != NULL ) {
2378
#ifdef DEBUG_DLSCH_MODULATION
2379
    LOG_I(PHY,"Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d)\n",
lukashov's avatar
lukashov committed
2380 2381 2382 2383 2384
            harq_pid,
            dlsch0_harq->mimo_mode,
            pmi2hex_2Ar2(dlsch0_harq->pmi_alloc),
            mod_order0,
            mod_order1,
2385 2386
            rb_alloc[0]
            );
2387
#endif
2388
  }
2389 2390 2391

    if (frame_parms->Ncp==0) { // normal prefix
      if ((l==4)||(l==11))
2392
        pilots=2;   // pilots in nushift+3, nushift+9
2393
      else if (l==7)
2394
        pilots=1;   // pilots in nushift, nushift+6
2395
      else
2396 2397
        pilots=0;
    } else {
2398
      if ((l==3)||(l==9))
2399
        pilots=2;
2400
      else if (l==6)
2401
        pilots=1;
2402
      else
2403
        pilots=0;
2404 2405
    }

2406 2407 2408
    if(mimo_mode==TM7){ //36.211 V8.6.0 2009-03
      mprime = 0;
      if (frame_parms->Ncp==0) { // normal prefix
2409 2410 2411 2412 2413 2414 2415 2416
        if (l==12)
          lprime=3;   // pilots in nushift+3, nushift+9
        else if (l==9)
          lprime=2;   // pilots in nushift, nushift+6
        else if (l==6)
          lprime=1;   // pilots in nushift+3, nushift+9
        else if (l==3)
          lprime=0;   // pilots in nushift, nushift+6
2417
        else
2418
          lprime=-1;
2419
      } else {
2420
        if (l==10)
2421
          lprime=2;
2422
        else if (l==7)
2423
          lprime=1;
2424
        else if (l==4)
2425
          lprime=0;
2426 2427
        else
          lprime=-1;
2428
      }
Xiwen JIANG's avatar
Xiwen JIANG committed
2429

2430
      // mapping ue specific beamforming weights from UE specified DLSCH structure to RU beam weights for the eNB
2431
      /*
2432
      for (int ru_id=0;ru_id<RC.nb_RU;ru_id++) {
Laurent's avatar
Laurent committed
2433
        RU_t *ru;
2434
	ru = RC.ru[ru_id];
2435
	for (int eNB_id=0;eNB_id<ru->num_eNB;eNB_id++){
2436
	  if (phy_vars_eNB == ru->eNB_list[eNB_id]) {
2437
	    for (int aa=0;aa<ru->nb_tx;aa++){
2438
              LOG_I(PHY,"ru_id:%d eNB_id:%d aa:%d memcpy(ru->beam_weights, dlsch0->ue_spec_bf_weights[ru_id][0],)\n", ru_id, eNB_id, aa);
2439 2440 2441
	      memcpy(ru->beam_weights[eNB_id][5][aa],
		     dlsch0->ue_spec_bf_weights[ru_id][0],
		     frame_parms->ofdm_symbol_size*sizeof(int32_t));
2442 2443 2444
	    }
	  }
	}
Xiwen JIANG's avatar
Xiwen JIANG committed
2445
      }
2446
      */
2447

2448
    }
2449

2450
    Ns = 2*subframe_offset+(l>=(nsymb>>1));
2451

2452 2453 2454 2455
    offset = (pilots==2)?3:0;
    nushiftmod3 = frame_parms->nushift%3;

    if (pilots>0) {  // compute pilot arrays, could be done statically if performance suffers
2456
      if (frame_parms->nb_antenna_ports_eNB == 1) {
2457
	//	LOG_I(PHY,"l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset);
2458 2459 2460 2461 2462 2463 2464 2465 2466
	for (i=0,i2=0;i<12;i++) {
	  if ((i!=(frame_parms->nushift+offset)) && (i!=((frame_parms->nushift+6+offset)%12)))
	    P1_SHIFT[i2++]=1;
	  else
	    P1_SHIFT[i2++]=2;
	}
	P1_SHIFT[0]--;
      }
      else {
2467 2468 2469 2470 2471 2472 2473
        for (i=0,i2=0;i<12;i++) {
          if ((i!=nushiftmod3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+3) && (i!=nushiftmod3+9))
            P2_SHIFT[i2++]=1;
          else
            P2_SHIFT[i2++]=2;
        }
        P2_SHIFT[0]--;
2474 2475 2476 2477
      }
    }
    P1_SHIFT[12]=1;P2_SHIFT[12]=1;

2478 2479
    re_offset = frame_parms->first_carrier_offset;
    symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));
2480
    allocate_REs = allocate_REs_in_RB;
2481

2482 2483
    switch (mod_order0) {
    case 2:
2484
      qam_table_s0 = NULL;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2485
      if (pilots) {
Eurecom's avatar
Eurecom committed
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495
        qam_table_s0 = qpsk_table_b0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_pilots_QPSK_siso :
          allocate_REs_in_RB;
      }
      else {
        qam_table_s0 = qpsk_table_a0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_no_pilots_QPSK_siso :
          allocate_REs_in_RB;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2496
      }
2497 2498 2499
      break;
    case 4:
      if (pilots) {
2500 2501 2502 2503
        qam_table_s0 = qam16_table_b0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_pilots_16QAM_siso :
          allocate_REs_in_RB;
2504 2505
      }
      else {
2506 2507 2508 2509
        qam_table_s0 = qam16_table_a0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_no_pilots_16QAM_siso :
          allocate_REs_in_RB;
2510

2511 2512
      }
      break;
2513

2514 2515
    case 6:
      if (pilots) {
2516 2517 2518 2519
        qam_table_s0 = qam64_table_b0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_pilots_64QAM_siso :
          allocate_REs_in_RB;
2520 2521
      }
      else {
2522 2523 2524 2525
        qam_table_s0 = qam64_table_a0;
        allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ?
          allocate_REs_in_RB_no_pilots_64QAM_siso :
          allocate_REs_in_RB;
2526
      }
2527 2528 2529 2530
      /* TODO: this is a quick hack to be removed. There is a problem
       * with above code that needs to be analyzed and fixed. In the
       * meantime, let's use the generic function.
       */
2531
      //allocate_REs = allocate_REs_in_RB;
2532
      break;
2533

2534
    }
2535

2536 2537 2538 2539
    /* TODO: hack, to be removed. The power is too different from
     * previous version. Some more work/validation is needed before
     * we switch to the new version.
     */
2540 2541
    //if (frame_parms->N_RB_DL==25)
      //allocate_REs = allocate_REs_in_RB;
2542

2543 2544
    switch (mod_order1) {
    case 2:
2545 2546
      qam_table_s1 = NULL;
      allocate_REs = allocate_REs_in_RB;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2547
      if (pilots) {
2548 2549 2550 2551
        qam_table_s1 = qpsk_table_b1;
      }
      else {
        qam_table_s1 = qpsk_table_a1;
Wang Tsu-Han's avatar
Wang Tsu-Han committed
2552
      }
2553 2554 2555
      break;
    case 4:
      if (pilots) {
2556
        qam_table_s1 = qam16_table_b1;
2557 2558
      }
      else {
2559
        qam_table_s1 = qam16_table_a1;
2560 2561 2562 2563
      }
      break;
    case 6:
      if (pilots) {
2564
        qam_table_s1 = qam64_table_b1;
2565 2566
      }
      else {
2567
        qam_table_s1 = qam64_table_a1;
2568 2569
      }
      break;
2570

2571 2572
    }

2573
    //for (aa=0;aa<frame_parms->nb_antennas_tx;aa++)
lukashov's avatar
lukashov committed
2574
    //memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2);
2575
    //LOG_I(PHY,"symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots);
2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588
    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;

2589
      if (check_skip(rb,subframe_offset,frame_parms,l,nsymb)==1)
2590
        rb_alloc_ind = 0;
2591

2592 2593
      skip_half = check_skiphalf(rb,subframe_offset,frame_parms,l,nsymb);
      skip_dc   = check_skip_dc(rb,frame_parms);
2594

2595 2596
     if (dlsch0) {
        if (dlsch0_harq->Nlayers>1) {
2597
          LOG_E(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
2598 2599
          return(-1);
        }
2600
      }
2601 2602 2603

      if (dlsch1) {
        if (dlsch1_harq->Nlayers>1) {
2604
          LOG_I(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
2605 2606 2607 2608 2609 2610 2611
          return(-1);
        }
      }



      if (rb_alloc_ind > 0) {
2612
        //    LOG_I(PHY,"Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj);
2613

2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624
      if (dlsch0 != NULL) {
        get_pmi_temp = get_pmi(frame_parms->N_RB_DL,
                               dlsch0->harq_processes[harq_pid]->mimo_mode,
                               dlsch0->harq_processes[harq_pid]->pmi_alloc,
                               rb);
      } else
        get_pmi_temp = get_pmi(frame_parms->N_RB_DL,
                               dlsch1->harq_processes[harq_pid]->mimo_mode,
                               dlsch1->harq_processes[harq_pid]->pmi_alloc,
                               rb);

2625

2626
      allocate_REs(phy_vars_eNB,
lukashov's avatar
lukashov committed
2627 2628 2629 2630 2631
                         txdataF,
                         &jj,
                         &jj2,
                         re_offset,
                         symbol_offset,
2632 2633
                         (dlsch0 == NULL) ? NULL : dlsch0->harq_processes[harq_pid],
                         (dlsch1 == NULL) ? NULL : dlsch1->harq_processes[harq_pid],
lukashov's avatar
lukashov committed
2634 2635
                         pilots,
                         ((pilots) ? amp_rho_b : amp_rho_a),
2636
                         get_pmi_temp,
lukashov's avatar
lukashov committed
2637 2638 2639 2640
                         qam_table_s0,
                         qam_table_s1,
                         &re_allocated,
                         skip_dc,
2641
                         skip_half,
2642 2643 2644 2645 2646
                         lprime,
                         mprime,
                         Ns,
                         P1_SHIFT,
                         P2_SHIFT);
2647

Xiwen JIANG's avatar
Xiwen JIANG committed
2648 2649
          if ((mimo_mode == TM7) && (lprime>=0))
            mprime +=3+frame_parms->Ncp;
2650
      }
2651
      else {
2652
        //      LOG_I(PHY,"Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj);
2653
      }
2654 2655
      re_offset+=12; // go to next RB

2656
      // check if we crossed the symbol boundary and skip DCs
2657

2658
      if (re_offset >= frame_parms->ofdm_symbol_size) {
Xiwen JIANG's avatar
Xiwen JIANG committed
2659 2660 2661 2662
        if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
          re_offset=1;
        else
          re_offset=7;  // odd number of RBs
2663
      }
Xiwen JIANG's avatar
Xiwen JIANG committed
2664
    }
2665
  }
Xiwen JIANG's avatar
Xiwen JIANG committed
2666

2667
#ifdef DEBUG_DLSCH_MODULATION
2668
  if (dlsch0 != NULL){
2669
    LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1));
2670
  }else{
2671
    LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset,1));
Xiwen JIANG's avatar
Xiwen JIANG committed
2672
  }
2673
#endif
2674

2675
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
2676

2677 2678 2679
  return (re_allocated);
}

lukashov's avatar
lukashov committed
2680

lukashov's avatar
lukashov committed
2681 2682 2683 2684 2685
int dlsch_modulation_SIC(int32_t **sic_buffer,
                         uint32_t subframe_offset,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         uint8_t num_pdcch_symbols,
                         LTE_eNB_DLSCH_t *dlsch0,
lukashov's avatar
lukashov committed
2686
                         int G)
lukashov's avatar
lukashov committed
2687 2688
{

2689
  AssertFatal(1==0,"This function needs to be reintegrated ...\n");
2690
  uint8_t harq_pid = -1;//dlsch0->current_harq_pid;
lukashov's avatar
lukashov committed
2691
  LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
2692
  uint32_t i,jj,re_allocated=0;
2693
  uint8_t mod_order0 = dlsch0_harq->Qm;
2694
  uint8_t *x0  = dlsch0_harq->eDL;
lukashov's avatar
lukashov committed
2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705
  uint8_t qam64_table_offset_re = 0;
  uint8_t qam64_table_offset_im = 0;
  uint8_t qam16_table_offset_re = 0;
  uint8_t qam16_table_offset_im = 0;
  int16_t gain_lin_QPSK;
 #ifdef DEBUG_DLSCH_MODULATION
  uint8_t Nl0 = dlsch0_harq->Nl;
  uint8_t Nl1;
#endif

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN);
2706

2707
  gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15));
2708

lukashov's avatar
lukashov committed
2709 2710 2711
  jj = 0;
  i = 0;
  while (jj <= G-1) {
2712

lukashov's avatar
lukashov committed
2713
    re_allocated = re_allocated + 1;
lukashov's avatar
lukashov committed
2714

lukashov's avatar
lukashov committed
2715 2716
    switch (mod_order0) {
    case 2:  //QPSK
2717

lukashov's avatar
lukashov committed
2718
      ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
2719

lukashov's avatar
lukashov committed
2720
      jj = jj + 1;
2721

lukashov's avatar
lukashov committed
2722
      ((int16_t*)&sic_buffer[0][i])[1] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
2723

lukashov's avatar
lukashov committed
2724
      jj = jj + 1;
2725

2726
      //LOG_I(PHY,"recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]);
lukashov's avatar
lukashov committed
2727
      i++;
2728

lukashov's avatar
lukashov committed
2729
      break;
lukashov's avatar
lukashov committed
2730

lukashov's avatar
lukashov committed
2731
    case 4:  //16QAM
lukashov's avatar
lukashov committed
2732

lukashov's avatar
lukashov committed
2733 2734
      qam16_table_offset_re = 0;
      qam16_table_offset_im = 0;
lukashov's avatar
lukashov committed
2735

lukashov's avatar
lukashov committed
2736 2737
      if (x0[jj] == 1)
        qam16_table_offset_re+=2;
lukashov's avatar
lukashov committed
2738

lukashov's avatar
lukashov committed
2739
      jj=jj+1;
lukashov's avatar
lukashov committed
2740

lukashov's avatar
lukashov committed
2741 2742
      if (x0[jj] == 1)
        qam16_table_offset_im+=2;
lukashov's avatar
lukashov committed
2743

lukashov's avatar
lukashov committed
2744
      jj=jj+1;
lukashov's avatar
lukashov committed
2745 2746


lukashov's avatar
lukashov committed
2747 2748
      if (x0[jj] == 1)
        qam16_table_offset_re+=1;
lukashov's avatar
lukashov committed
2749

lukashov's avatar
lukashov committed
2750
      jj=jj+1;
lukashov's avatar
lukashov committed
2751

lukashov's avatar
lukashov committed
2752 2753
      if (x0[jj] == 1)
        qam16_table_offset_im+=1;
lukashov's avatar
lukashov committed
2754

lukashov's avatar
lukashov committed
2755
      jj=jj+1;
lukashov's avatar
lukashov committed
2756 2757


lukashov's avatar
lukashov committed
2758 2759
      ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re];
      ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im];
2760 2761

      i++;
lukashov's avatar
lukashov committed
2762

lukashov's avatar
lukashov committed
2763
      break;
lukashov's avatar
lukashov committed
2764

lukashov's avatar
lukashov committed
2765
    case 6:
lukashov's avatar
lukashov committed
2766

lukashov's avatar
lukashov committed
2767 2768
      qam64_table_offset_re = 0;
      qam64_table_offset_im = 0;
lukashov's avatar
lukashov committed
2769

lukashov's avatar
lukashov committed
2770 2771
      if (x0[jj] == 1)
      qam64_table_offset_re+=4;
lukashov's avatar
lukashov committed
2772

lukashov's avatar
lukashov committed
2773
      jj=jj+1;
lukashov's avatar
lukashov committed
2774

lukashov's avatar
lukashov committed
2775 2776
      if (x0[jj] == 1)
        qam64_table_offset_im+=4;
lukashov's avatar
lukashov committed
2777

lukashov's avatar
lukashov committed
2778
      jj=jj+1;
lukashov's avatar
lukashov committed
2779

lukashov's avatar
lukashov committed
2780 2781
      if (x0[jj] == 1)
        qam64_table_offset_re+=2;
lukashov's avatar
lukashov committed
2782

lukashov's avatar
lukashov committed
2783
      jj=jj+1;
lukashov's avatar
lukashov committed
2784

lukashov's avatar
lukashov committed
2785 2786
      if (x0[jj] == 1)
        qam64_table_offset_im+=2;
lukashov's avatar
lukashov committed
2787

lukashov's avatar
lukashov committed
2788
      jj=jj+1;
lukashov's avatar
lukashov committed
2789

lukashov's avatar
lukashov committed
2790 2791
      if (x0[jj] == 1)
        qam64_table_offset_re+=1;
lukashov's avatar
lukashov committed
2792

lukashov's avatar
lukashov committed
2793
      jj=jj+1;
lukashov's avatar
lukashov committed
2794

lukashov's avatar
lukashov committed
2795 2796
      if (x0[jj] == 1)
        qam64_table_offset_im+=1;
lukashov's avatar
lukashov committed
2797

lukashov's avatar
lukashov committed
2798
      jj=jj+1;
lukashov's avatar
lukashov committed
2799 2800


lukashov's avatar
lukashov committed
2801 2802
      ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
      ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
2803

lukashov's avatar
lukashov committed
2804
      i++;
2805

lukashov's avatar
lukashov committed
2806
      break;
lukashov's avatar
lukashov committed
2807
      }
2808

lukashov's avatar
lukashov committed
2809
    }
2810 2811 2812


#ifdef DEBUG_DLSCH_MODULATION
2813
  LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1/*transmission mode*/));
2814
#endif
2815

2816
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
2817

2818 2819 2820
  return (re_allocated);
}

lukashov's avatar
lukashov committed
2821

2822
int mch_modulation(int32_t **txdataF,
2823 2824 2825 2826 2827
                   int16_t amp,
                   uint32_t subframe_offset,
                   LTE_DL_FRAME_PARMS *frame_parms,
                   LTE_eNB_DLSCH_t *dlsch)
{
2828 2829 2830 2831
  uint8_t nsymb,nsymb_pmch;
  uint32_t i,jj,re_allocated,symbol_offset;
  uint16_t l,rb,re_offset;
  uint8_t skip_dc=0;
2832
  uint8_t mod_order = dlsch->harq_processes[0]->Qm;
2833 2834 2835 2836 2837
  int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8];
  int16_t *qam_table_s;

  nsymb_pmch = 12;
  nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12;
2838

2839
  if (mod_order == 4)
2840
    for (i=0; i<4; i++) {
2841 2842 2843
      qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15);
    }
  else if (mod_order == 6)
2844
    for (i=0; i<8; i++) {
2845
      qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15);
2846 2847 2848
    }

  jj=0;
2849
  re_allocated=0;
2850

2851
  //  LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
2852 2853
  for (l=2; l<nsymb_pmch; l++) {

2854
#ifdef DEBUG_DLSCH_MODULATION
2855
    LOG_I(PHY,"Generating MCH (mod %d) in subframe %d for symbol %d\n",mod_order, subframe_offset,l);
2856
#endif
2857 2858 2859 2860

    re_offset = frame_parms->first_carrier_offset;
    symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));

2861 2862
    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

2863 2864

      if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
2865

lukashov's avatar
lukashov committed
2866
    if (rb==(frame_parms->N_RB_DL>>1))
2867 2868 2869
          skip_dc = 1;
        else
          skip_dc = 0;
2870 2871 2872 2873

      }

      if (mod_order == 4)
2874
        qam_table_s = qam16_table_a;
2875
      else if (mod_order == 6)
2876
        qam_table_s = qam64_table_a;
2877
      else
2878
        qam_table_s = NULL;
2879

2880
      //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
2881
      allocate_REs_in_RB_MCH(txdataF,
2882 2883 2884
                             &jj,
                             re_offset,
                             symbol_offset,
2885
                             dlsch->harq_processes[0]->eDL,
2886 2887 2888 2889 2890 2891 2892 2893
                             l,
                             mod_order,
                             amp,
                             qam_table_s,
                             &re_allocated,
                             skip_dc,
                             frame_parms);

2894
      re_offset+=12; // go to next RB
2895

2896 2897
      // check if we crossed the symbol boundary and skip DC
      if (re_offset >= frame_parms->ofdm_symbol_size) {
2898 2899 2900 2901
        if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
          re_offset=1;
        else
          re_offset=7;  // odd number of RBs
2902 2903 2904 2905 2906
      }
    }
  }

#ifdef DEBUG_DLSCH_MODULATION
2907
  LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/));
2908
#endif
2909 2910

  return (re_allocated);
2911
}
2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 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 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 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

int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF,
                           uint32_t *jj,
                            uint16_t re_offset,
                            uint32_t symbol_offset,
                            uint8_t *x0,
                            uint8_t subframe,
                            uint8_t mod_order,
                            int16_t amp,
                            int16_t *qam_table_s,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
                            LTE_DL_FRAME_PARMS *frame_parms)
{
 uint32_t tti_offset;
  uint8_t re,offset;
  uint8_t qam64_table_offset_re = 0;
  uint8_t qam64_table_offset_im = 0;
  uint8_t qam16_table_offset_re = 0;
  uint8_t qam16_table_offset_im = 0;
  int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2;
  int16_t re_off=re_offset;
  gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
  uint8_t first_re,last_re;
  int inc;
#ifdef DEBUG_DLSCH_MODULATION
  LOG_I(PHY,"allocate_re_MCH khz_1dot25 (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]);
#endif

  /*last_re=12;
  first_re=0;
  inc=1;

  if ((l==2)||(l==10)) {
    inc=2;
    first_re=1;
  } else if (l==6) {
    inc=2;
  }*/
  last_re=144; //12*12
  if ((subframe&0x1)==0){ // n_sf mod 2 == 0: even
        first_re=1;
        offset=0;
  }else{
        first_re=0;
        offset=3;
  }
  inc=1;

  for (re=first_re; re<last_re; re+=inc) {
    if( ((re-offset)%6) == 0  )
                continue; //pilot
    //if ((subframe&0x1)==0) // n_sf mod 2 == 0: even
        //k = 6*m;
    //else
        //k = 6*m + 3;
    //if ((skip_dc == 1) && (re==(6+first_re)))
    if ((skip_dc == 1) && (re==(72+first_re))){
      re_off=re_off - frame_parms->ofdm_symbol_size_khz_1dot25+1;
    }

        tti_offset = symbol_offset + re_off + re;

    //LOG_I(PHY,"re %d (jj %d)\n",re,*jj);
    *re_allocated = *re_allocated + 1;


    switch (mod_order) {

      case 2:  //QPSK

                  LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
      ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i

      *jj = *jj + 1;

      ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}

      *jj = *jj + 1;

      LOG_D(PHY,"subframe%d alloc[%d][%d][%d](%d,%d)\n",subframe,tti_offset,symbol_offset,tti_offset-symbol_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
      break;


      case 4:  //16QAM

    qam16_table_offset_re = 0;
    qam16_table_offset_im = 0;

    if (x0[*jj] == 1)
      qam16_table_offset_re+=2;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam16_table_offset_im+=2;

    *jj=*jj+1;


    if (x0[*jj] == 1)
      qam16_table_offset_re+=1;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam16_table_offset_im+=1;

    *jj=*jj+1;


    ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
    ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);

    break;

      case 6:  //64QAM

        qam64_table_offset_re = 0;
    qam64_table_offset_im = 0;

    if (x0[*jj] == 1)
      qam64_table_offset_re+=4;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam64_table_offset_im+=4;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam64_table_offset_re+=2;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam64_table_offset_im+=2;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam64_table_offset_re+=1;

    *jj=*jj+1;

    if (x0[*jj] == 1)
      qam64_table_offset_im+=1;

    *jj=*jj+1;

    ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
    ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);

    break;

    }
  }
  return(0);
}

int mch_modulation_khz_1dot25(int32_t **txdataF,
                   int16_t amp,
                   uint32_t subframe_offset,
                   LTE_DL_FRAME_PARMS *frame_parms,
                   LTE_eNB_DLSCH_t *dlsch)
{
  uint8_t nsymb,nsymb_pmch;
  uint32_t i,jj,re_allocated,symbol_offset;
  uint16_t l,rb,re_offset;
  uint8_t skip_dc=0;
  uint8_t mod_order = dlsch->harq_processes[0]->Qm;
  int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8];
  int16_t *qam_table_s;

  nsymb_pmch = 1;
  nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12;

  if (mod_order == 4)
    for (i=0; i<4; i++) {
      qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15);
    }
  else if (mod_order == 6)
    for (i=0; i<8; i++) {
      qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15);
    }

  jj=0;
  re_allocated=0;





  //  LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
  for (l=0; l<nsymb_pmch; l++) {

#ifdef DEBUG_DLSCH_MODULATION
    LOG_I(PHY,"Generating khz_1dot25 MCH (mod %d) in subframe %d for symbol %d\n",mod_order, subframe_offset,l);
#endif

    re_offset = frame_parms->first_carrier_offset_khz_1dot25;
    symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb));

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


      if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL

        if (rb==(frame_parms->N_RB_DL>>1))
          skip_dc = 1;
        else
          skip_dc = 0;

      }

      if (mod_order == 4)
        qam_table_s = qam16_table_a;
      else if (mod_order == 6)
        qam_table_s = qam64_table_a;
      else
        qam_table_s = NULL;

      //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
      allocate_REs_in_RB_MCH_khz_1dot25(txdataF,
                             &jj,
                             re_offset,
                             symbol_offset,
                             dlsch->harq_processes[0]->eDL,
                             subframe_offset,
                             mod_order,
                             amp,
                             qam_table_s,
                             &re_allocated,
                             skip_dc,
                             frame_parms);

      re_offset+=144; // go to next RB 12*12

      // check if we crossed the symbol boundary and skip DC
      if (re_offset >= frame_parms->ofdm_symbol_size_khz_1dot25) {
        if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
          re_offset=1;
        else
          re_offset=73;  // odd number of RBs
      }
    }
  }

#ifdef DEBUG_DLSCH_MODULATION
  LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/));
  LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d\n",jj,re_allocated);
#endif

  return (re_allocated);
}