dlsch_modulation.c 55.5 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


ghaddab's avatar
ghaddab committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17 18
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
19
   see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
ghaddab's avatar
ghaddab committed
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

/*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c
* \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs.h"
#include "defs.h"
47
#include "UTIL/LOG/vcd_signal_dumper.h"
48

49
//#define DEBUG_DLSCH_MODULATION
50 51 52

//#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)

53 54
uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots)
{
55 56 57

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

59 60 61 62 63 64
  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);
65
  } else { // 2 antenna pilots
66 67 68
    if ((re!=nushiftmod3) && (re!=nushiftmod3+6) && (re!=nushiftmod3+3) && (re!=nushiftmod3+9))
      return(1);
  }
69

70 71 72
  return(0);
}

73 74
uint8_t is_not_UEspecRS(int first_layer,int re)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
75 76 77 78

  return(1);
}

79 80
void generate_64qam_table(void)
{
81 82 83 84

  int a,b,c,index;


85 86 87 88 89 90
  for (a=-1; a<=1; a+=2)
    for (b=-1; b<=1; b+=2)
      for (c=-1; c<=1; c+=2) {
        index = (1+a)*2 + (1+b) + (1+c)/2;
        qam64_table[index] = -a*(QAM64_n1 + b*(QAM64_n2 + (c*QAM64_n3))); // 0 1 2
      }
91 92
}

93 94
void generate_16qam_table(void)
{
95 96 97

  int a,b,index;

98 99 100 101 102
  for (a=-1; a<=1; a+=2)
    for (b=-1; b<=1; b+=2) {
      index = (1+a) + (1+b)/2;
      qam16_table[index] = -a*(QAM16_n1 + (b*QAM16_n2));
    }
103 104 105 106 107
}




108 109
void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t precoding_index)
{
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

  switch (precoding_index) {

  case 0: // 1 1
    *antenna1_sample=*antenna0_sample;
    break;

  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;

  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;

  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;
  }

  // normalize
134 135
  /*  ((int16_t *)antenna0_sample)[0] = (int16_t)((((int16_t *)antenna0_sample)[0]*ONE_OVER_SQRT2_Q15)>>15);
  ((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);
136
  ((int16_t *)antenna1_sample)[1] = (int16_t)((((int16_t *)antenna1_sample)[1]*ONE_OVER_SQRT2_Q15)>>15);  */
137
}
138

139
int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms,
140
                       int32_t **txdataF,
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
                       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)
{
156 157 158 159 160 161


  uint8_t *x0             = dlsch0_harq->e;
  MIMO_mode_t mimo_mode   = dlsch0_harq->mimo_mode;

  int first_layer0        = dlsch0_harq->first_layer;
162
  int Nlayers0            = dlsch0_harq->Nlayers;
163
  uint8_t mod_order0      = get_Qm(dlsch0_harq->mcs);
164 165
  uint8_t mod_order1=2;
  uint8_t precoder_index0,precoder_index1;
166

Raymond Knopp's avatar
 
Raymond Knopp committed
167 168 169 170
  uint8_t *x1=NULL;
  // Fill these in later for TM8-10
  //  int Nlayers1;
  //  int first_layer1;
171 172

  int use2ndpilots = (frame_parms->mode1_flag==1)?1:0;
173 174 175 176 177 178 179

  uint32_t tti_offset,aa;
  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;
180 181 182 183 184 185 186 187 188 189 190
  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;

191 192
  int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2;
  int16_t re_off=re_offset;
193

194 195 196
  uint8_t first_re,last_re;
  int32_t tmp_sample1,tmp_sample2;
  int16_t tmp_amp=amp;
197 198 199 200 201 202 203
  int s=1;

  gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
  //  if (mimo_mode == LARGE_CDD) gain_lin_QPSK>>=1;

  if (dlsch1_harq) {
    x1             = dlsch1_harq->e;
Raymond Knopp's avatar
 
Raymond Knopp committed
204
    // Fill these in later for TM8-10
205
    //    Nlayers1       = dlsch1_harq->Nlayers;
Raymond Knopp's avatar
 
Raymond Knopp committed
206
    //    first_layer1   = dlsch1_harq->first_layer;
207 208 209
    mod_order1     = get_Qm(dlsch1_harq->mcs);

  }
210

211 212 213 214
  /*
  switch (mod_order) {
  case 2:
    // QPSK single stream
215

216 217 218 219 220
    break;
  case 4:
    //16QAM Single stream
    gain_lin_16QAM1 = (int16_t)(((int32_t)amp*QAM16_n1)>>15);
    gain_lin_16QAM2 = (int16_t)(((int32_t)amp*QAM16_n2)>>15);
221

222
    break;
223

224 225 226 227 228 229
  case 6:
    //64QAM Single stream
    break;
  default:
    break;
  }
230
  */
231 232

#ifdef DEBUG_DLSCH_MODULATION
233
  printf("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]);
234 235 236 237 238
#endif

  first_re=0;
  last_re=12;

239
  if (skip_half==1)
240 241 242
    last_re=6;
  else if (skip_half==2)
    first_re=6;
243 244

  for (re=first_re; re<last_re; re++) {
245 246
    
  // printf("element %d precoder_index for allocation %d\n",re, precoder_index );
247 248


249 250
    if ((skip_dc == 1) && (re==6))
      re_off=re_off - frame_parms->ofdm_symbol_size+1;
251

252
    tti_offset = symbol_offset + re_off + re;
253

Raymond Knopp's avatar
 
Raymond Knopp committed
254 255
    // check that RE is not from Cell-specific RS

256
    if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) {
257
      //     printf("re %d (jj %d)\n",re,*jj);
Raymond Knopp's avatar
 
Raymond Knopp committed
258

259

260
      if (mimo_mode == SISO) {  //SISO mapping
261 262 263 264 265
        *re_allocated = *re_allocated + 1;

        switch (mod_order0) {
        case 2:  //QPSK

266
//          printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
267 268 269 270 271 272 273 274 275 276 277 278
          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
            ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
          }

          *jj = *jj + 1;

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

          *jj = *jj + 1;

279
 //         printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
          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;

          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
            ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re];
            ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im];
            //      ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
            //      ((int16_t *)&txdataF[aa][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;

          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
            ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s0[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
            ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
          }

          break;

        }
361 362
      }

363 364
      else if (mimo_mode == ALAMOUTI) {
        *re_allocated = *re_allocated + 1;
lukashov's avatar
lukashov committed
365
      
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
        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;

385
      // normalization for 2 tx antennas
386
	  ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
387
	  ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
388 389 390
	  ((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);
	  
391 392 393 394 395 396 397 398
	  break;
	  
	case 4:  //16QAM
	  
	  // Antenna 0 position n 
	  
	  qam16_table_offset_re = 0;
	  qam16_table_offset_im = 0;
lukashov's avatar
lukashov committed
399
	 
400
	  if (x0[*jj] == 1)
401 402
	    qam16_table_offset_re+=2;
	  *jj=*jj+1;
403
	  if (x0[*jj] == 1)
404 405 406 407
	    qam16_table_offset_im+=2;
	  *jj=*jj+1;
	  
	  
408
	  if (x0[*jj] == 1)
409 410
	    qam16_table_offset_re+=1;
	  *jj=*jj+1;
411
	  if (x0[*jj] == 1)
412 413 414 415 416 417 418 419 420 421
	    qam16_table_offset_im+=1;
	  *jj=*jj+1;
	  
	  ((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);
	  
	  // Antenna 1 position n Real part -> -x1*
	  
	  qam16_table_offset_re = 0;
	  qam16_table_offset_im = 0;
422
	  if (x0[*jj] == 1)
423 424
	    qam16_table_offset_re+=2;
	  *jj=*jj+1;
425
	  if (x0[*jj] == 1)
426 427 428 429
	    qam16_table_offset_im+=2;
	  *jj=*jj+1;
	  
	  
430
	  if (x0[*jj] == 1)
431 432
	    qam16_table_offset_re+=1;
	  *jj=*jj+1;
433
	  if (x0[*jj] == 1)
434 435 436 437 438 439 440 441 442 443 444 445 446 447
	    qam16_table_offset_im+=1;
	  *jj=*jj+1;
	  
	  ((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);
	  
	  
	  break;
	case 6:   // 64-QAM
	  
	  // Antenna 0
	  qam64_table_offset_re = 0;
	  qam64_table_offset_im = 0;

448
	  if (x0[*jj] == 1)
449 450
	    qam64_table_offset_re+=4;
	  *jj=*jj+1;
451
	  if (x0[*jj] == 1)
452 453
	    qam64_table_offset_im+=4;
	  *jj=*jj+1;
454
	  if (x0[*jj] == 1)
455 456
	    qam64_table_offset_re+=2;
	  *jj=*jj+1;
457
	  if (x0[*jj] == 1)
458 459
	    qam64_table_offset_im+=2;
	  *jj=*jj+1;
460
	  if (x0[*jj] == 1)
461 462
	    qam64_table_offset_re+=1;
	  *jj=*jj+1;
463
	  if (x0[*jj] == 1)
464 465 466 467 468 469 470 471 472 473
	    qam64_table_offset_im+=1;
	  *jj=*jj+1;
	  
	  ((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);
	  
	  
	  // Antenna 1 => -x1*
	  qam64_table_offset_re = 0;
	  qam64_table_offset_im = 0;
474
	  if (x0[*jj] == 1)
475 476
	    qam64_table_offset_re+=4;
	  *jj=*jj+1;
477
	  if (x0[*jj] == 1)
478 479
	    qam64_table_offset_im+=4;
	  *jj=*jj+1;
480
	  if (x0[*jj] == 1)
481 482
	    qam64_table_offset_re+=2;
	  *jj=*jj+1;
483
	  if (x0[*jj] == 1)
484 485
	    qam64_table_offset_im+=2;
	  *jj=*jj+1;
486
	  if (x0[*jj] == 1)
487 488
	    qam64_table_offset_re+=1;
	  *jj=*jj+1;
489
	  if (x0[*jj] == 1)
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
	    qam64_table_offset_im+=1;
	  *jj=*jj+1;
	  
	  ((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);
	  
	  break;
	}
	// fill in the rest of the ALAMOUTI precoding
	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];
	}
	else {
	  ((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];
	}
      }
512
      else if (mimo_mode == LARGE_CDD) {
513

514
	*re_allocated = *re_allocated + 1;
515

516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
	if (frame_parms->nb_antennas_tx == 2) {
	  switch (mod_order0) {
	  default:
	    LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0);
	    xx0_re=xx0_im=0;
	    break;
	  case 2:  //QPSK
	    //	  printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
	    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;
	    


	    // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
	    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;

Raymond Knopp's avatar
Raymond Knopp committed
582 583
	    xx0_re = qam_table_s0[qam64_table_offset_re0];
	    xx0_im = qam_table_s0[qam64_table_offset_im0];
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630


	    break;
	    
	  }
	  switch (mod_order1) {
	  default:
	    LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1);
	    xx1_re=xx1_im=0;
	    break;
	  case 2:  //QPSK
	    //	  printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
	    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;
	    // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
	    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)
Raymond Knopp's avatar
Raymond Knopp committed
631
	      qam64_table_offset_re1+=4;
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
	    *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;

Raymond Knopp's avatar
Raymond Knopp committed
649 650
	    xx1_re = qam_table_s1[qam64_table_offset_re1];
	    xx1_im = qam_table_s1[qam64_table_offset_im1];
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673


	    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));
	  /*
	  printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n",
		 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;
674 675 676
	}
      }
      else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) {
677
	// this is for transmission modes 5-6 (1 layer)
Raymond Knopp's avatar
 
Raymond Knopp committed
678 679
	*re_allocated = *re_allocated + 1;	         
	amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15);
680

681
	switch (mod_order0) {
682 683
	case 2:  //QPSK

684
	  ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
685
	  *jj = *jj + 1;
686
	  ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
687 688 689 690 691 692 693 694
	  *jj = *jj + 1;

      // normalization for 2 tx antennas
	  ((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);

	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
695 696
	    ((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);
697 698 699 700 701 702 703 704 705
	  }

	  break;
	  
	case 4:  //16QAM
	  
	  qam16_table_offset_re = 0;
	  qam16_table_offset_im = 0;

706
	  if (x0[*jj] == 1)
707 708
	    qam16_table_offset_re+=2;
	  *jj=*jj+1;
709
	  if (x0[*jj] == 1)
710 711 712 713
	    qam16_table_offset_im+=2;
	  *jj=*jj+1;
	  
	  
714
	  if (x0[*jj] == 1)
715 716
	    qam16_table_offset_re+=1;
	  *jj=*jj+1;
717
	  if (x0[*jj] == 1)
718 719 720
	    qam16_table_offset_im+=1;
	  *jj=*jj+1;
	  
721 722 723
		  
	   ((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]));
724

725 726
	   ((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);
727 728 729
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
730 731
	    ((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);
732 733 734 735 736 737 738 739 740
	  }

	  break;
	  
	case 6:  //64QAM
	  
	  
	  qam64_table_offset_re = 0;
	  qam64_table_offset_im = 0;
741
	  if (x0[*jj] == 1)
742 743
	    qam64_table_offset_re+=4;
	  *jj=*jj+1;
744
	  if (x0[*jj] == 1)
745 746
	    qam64_table_offset_im+=4;
	  *jj=*jj+1;
747
	  if (x0[*jj] == 1)
748 749
	    qam64_table_offset_re+=2;
	  *jj=*jj+1;
750
	  if (x0[*jj] == 1)
751 752
	    qam64_table_offset_im+=2;
	  *jj=*jj+1;
753
	  if (x0[*jj] == 1)
754 755
	    qam64_table_offset_re+=1;
	  *jj=*jj+1;
756
	  if (x0[*jj] == 1)
757 758 759
	    qam64_table_offset_im+=1;
	  *jj=*jj+1;
	  
760 761
	  ((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]));
762

763 764
	  ((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);
765 766 767
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index);
768 769
	    ((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);
770 771 772 773 774 775
	  }
	  
	  break;
	  
	}
      }
776 777 778
      else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) {
	// this is for transmission mode 4 (1 layer)
	*re_allocated = *re_allocated + 1;	         
lukashov's avatar
lukashov committed
779

780 781 782 783 784 785 786 787 788 789

	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 {
lukashov's avatar
lukashov committed
790
	 printf("problem with precoder in TM4\n");
791 792 793 794 795 796 797 798 799 800 801 802
	  return(-1);
	}

	switch (mod_order0) {
	case 2:  //QPSK

	  ((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
803 804
	  ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	  ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
805

lukashov's avatar
lukashov committed
806 807 808
	//   printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
	 
	   if (frame_parms->nb_antennas_tx == 2) {
809
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
810 811
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
	  }

	  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;
	  
836 837 838 839
	   ((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]));
	   ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	   ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
840 841 842
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
843 844
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
	  }

	  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;
	  
873 874 875 876
	  ((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]));
	  ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	  ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
877 878 879
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0);
880 881
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
882 883 884 885 886
	  }
	  
	  break;
	  
	}
887 888
	
	if   (dlsch1_harq) {
889 890 891 892 893 894 895 896 897
	switch (mod_order1) {
	case 2:  //QPSK

	  ((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
898 899
	  ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	  ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
900 901 902

	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
903 904
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
	  }

	  break;
	  
	case 4:  //16QAM
	  
	  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;
	  
	  
	  if (x1[*jj2] == 1)
	    qam16_table_offset_re+=1;
	  *jj2=*jj2+1;
	  if (x1[*jj2] == 1)
	    qam16_table_offset_im+=1;
	  *jj2=*jj2+1;
	  
929 930 931 932
	   ((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]));
	   ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	   ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
933 934 935
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
936 937
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965
	  }

	  break;
	  
	case 6:  //64QAM
	  
	  
	  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;
	  
966 967 968 969
	  ((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]));
	  ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15);
	  ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15);
970 971 972
	  
	  if (frame_parms->nb_antennas_tx == 2) {
	    layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1);
973 974
	    ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15);
	    ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15);
975 976 977 978 979 980
	  }
	  
	  break;
	  
	}
      }
981
      }
982

983

984
      if (mimo_mode == ALAMOUTI) {
985 986 987 988 989 990 991
        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;
        }
992
      }
993

Raymond Knopp's avatar
 
Raymond Knopp committed
994 995
      if (mimo_mode >= TM8) { //TM8,TM9,TM10

996 997 998
        if (is_not_UEspecRS(first_layer0,re)) {
          switch (mod_order0) {
          case 2:  //QPSK
Raymond Knopp's avatar
 
Raymond Knopp committed
999

1000
            //    printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1001
            for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
1002 1003 1004 1005 1006
              ((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;
            }
Raymond Knopp's avatar
 
Raymond Knopp committed
1007

1008
            break;
1009

1010
          case 4:  //16QAM
1011
            if (is_not_UEspecRS(0/*layer (FIXME uninitialized!)*/,re)) {
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
              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;

1035
              for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
                ((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;

1079
            for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) {
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
              ((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;

          }
        }
      } else if (mimo_mode>=TM9_10) {
        msg("allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode);
        return(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1091
      }
1092
    }
1093 1094


1095
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1096

1097 1098 1099
  return(0);
}

lukashov's avatar
lukashov committed
1100

1101
int allocate_REs_in_RB_MCH(int32_t **txdataF,
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
                           uint32_t *jj,
                           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)
{
1114 1115 1116 1117 1118 1119 1120 1121 1122

  uint32_t tti_offset,aa;
  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;
1123
  gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
1124 1125 1126
  uint8_t first_re,last_re;
  int inc;
#ifdef DEBUG_DLSCH_MODULATION
1127
  printf("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]);
1128 1129 1130 1131 1132
#endif

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

1134 1135 1136
  if ((l==2)||(l==10)) {
    inc=2;
    first_re=1;
1137
  } else if (l==6) {
1138 1139
    inc=2;
  }
1140 1141 1142

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

1143 1144
    if ((skip_dc == 1) && (re==(6+first_re)))
      re_off=re_off - frame_parms->ofdm_symbol_size+1;
1145

1146
    tti_offset = symbol_offset + re_off + re;
1147

1148 1149
    //    printf("re %d (jj %d)\n",re,*jj);
    *re_allocated = *re_allocated + 1;
1150 1151


1152 1153
    switch (mod_order) {
    case 2:  //QPSK
1154

1155
      //            printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1156
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
1157 1158 1159 1160 1161 1162 1163 1164 1165
        ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i

      *jj = *jj + 1;

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

      *jj = *jj + 1;

1166
      //      printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
1167 1168
      break;

1169
    case 4:  //16QAM
1170

1171 1172
      qam16_table_offset_re = 0;
      qam16_table_offset_im = 0;
1173

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

1177
      *jj=*jj+1;
1178

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

1182
      *jj=*jj+1;
1183 1184


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

1188
      *jj=*jj+1;
1189

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

1193
      *jj=*jj+1;
1194

1195
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
1196 1197 1198 1199
        ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s[qam16_table_offset_re];
        ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s[qam16_table_offset_im];
        //      ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
        //      ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
1200
      }
1201

1202
      break;
1203

1204
    case 6:  //64QAM
1205 1206


1207 1208
      qam64_table_offset_re = 0;
      qam64_table_offset_im = 0;
1209

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

1213
      *jj=*jj+1;
1214

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

1218
      *jj=*jj+1;
1219

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

1223
      *jj=*jj+1;
1224

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

1228
      *jj=*jj+1;
1229

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

1233
      *jj=*jj+1;
1234

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

1238
      *jj=*jj+1;
1239

1240
      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
1241 1242
        ((int16_t *)&txdataF[aa][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[aa][tti_offset])[1]+=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
1243
      }
1244

1245
      break;
1246

1247
    }
1248 1249
  }

1250 1251 1252
  return(0);
}

Florian Kaltenberger's avatar
Florian Kaltenberger committed
1253
uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb)
1254
{
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1255
  /*
1256 1257
  MIMO_mode_t mode   = dlsch_harq->mimo_mode;
  uint32_t pmi_alloc = dlsch_harq->pmi_alloc;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1258
  */
1259

Raymond Knopp's avatar
 
Raymond Knopp committed
1260 1261
  switch (N_RB_DL) {
  case 6:   // 1 PRB per subband
1262
    if (mode <= PUSCH_PRECODING1) //single layer
Raymond Knopp's avatar
 
Raymond Knopp committed
1263
      return((pmi_alloc>>(rb<<1))&3);
1264
    else //two layer
1265 1266
      return((pmi_alloc>>rb)&1);

Raymond Knopp's avatar
 
Raymond Knopp committed
1267
    break;
1268

1269
  default:
Raymond Knopp's avatar
 
Raymond Knopp committed
1270 1271 1272
  case 25:  // 4 PRBs per subband
    if (mode <= PUSCH_PRECODING1)
      return((pmi_alloc>>((rb>>2)<<1))&3);
1273
    else {
lukashov's avatar
lukashov committed
1274
    // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1));
Raymond Knopp's avatar
 
Raymond Knopp committed
1275
      return((pmi_alloc>>(rb>>2))&1);
1276
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1277
    break;
1278

Raymond Knopp's avatar
 
Raymond Knopp committed
1279 1280 1281 1282 1283
  case 50: // 6 PRBs per subband
    if (mode <= PUSCH_PRECODING1)
      return((pmi_alloc>>((rb/6)<<1))&3);
    else
      return((pmi_alloc>>(rb/6))&1);
1284

Raymond Knopp's avatar
 
Raymond Knopp committed
1285
    break;
1286

Raymond Knopp's avatar
 
Raymond Knopp committed
1287 1288 1289 1290
  case 100: // 8 PRBs per subband
    if (mode <= PUSCH_PRECODING1)
      return((pmi_alloc>>((rb>>3)<<1))&3);
    else
1291 1292
      return((pmi_alloc>>(rb>>3))&1);

Raymond Knopp's avatar
 
Raymond Knopp committed
1293 1294
    break;
  }
1295 1296
}

Raymond Knopp's avatar
 
Raymond Knopp committed
1297

1298

1299
int dlsch_modulation(int32_t **txdataF,
1300 1301 1302 1303 1304 1305 1306
                     int16_t amp,
                     uint32_t subframe_offset,
                     LTE_DL_FRAME_PARMS *frame_parms,
                     uint8_t num_pdcch_symbols,
                     LTE_eNB_DLSCH_t *dlsch0,
                     LTE_eNB_DLSCH_t *dlsch1)
{
1307 1308

  uint8_t nsymb;
1309 1310 1311 1312
  uint8_t harq_pid = dlsch0->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
  LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid];
  uint32_t i,jj,jj2,re_allocated,symbol_offset;
1313 1314
  uint16_t l,rb,re_offset;
  uint32_t rb_alloc_ind;
1315
  uint32_t *rb_alloc = dlsch0_harq->rb_alloc;
1316 1317
  uint8_t pilots=0;
  uint8_t skip_dc,skip_half;
1318
  uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
1319
  uint8_t mod_order1 = 0;
1320
  int16_t amp_rho_a, amp_rho_b;
1321 1322 1323
  int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8];
  int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8];
  int16_t *qam_table_s0,*qam_table_s1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1324
#ifdef DEBUG_DLSCH_MODULATION
1325 1326
  uint8_t Nl0 = dlsch0_harq->Nl;
  uint8_t Nl1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1327
#endif
1328 1329 1330 1331 1332 1333 1334 1335

  if (dlsch1) {
    dlsch1_harq = dlsch1->harq_processes[harq_pid];
    mod_order1 = get_Qm(dlsch1_harq->mcs);
#ifdef DEBUG_DLSCH_MODULATION
    Nl1 = dlsch1_harq->Nl;
#endif
  }
1336

1337
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN);
1338

1339
  nsymb = (frame_parms->Ncp==0) ? 14:12;
1340

1341
  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
1342
  amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13);
1343

1344
  if (mod_order0 == 4)
1345
    for (i=0; i<4; i++) {
1346 1347
      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);
1348
    }
1349
  else if (mod_order0 == 6)
1350
    for (i=0; i<8; i++) {
1351 1352
      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);
1353
    }
1354 1355

  if (mod_order1 == 4)
1356
    for (i=0; i<4; i++) {
1357 1358 1359
      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
1360
  else if (mod_order1 == 6)
1361
    for (i=0; i<8; i++) {
1362 1363
      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);
1364 1365
    }

1366
  //Modulation mapping (difference w.r.t. LTE specs)
1367 1368 1369

  jj=0;
  jj2=0;
1370
  re_allocated=0;
1371

1372
  //  printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
1373 1374
  for (l=num_pdcch_symbols; l<nsymb; l++) {

1375
#ifdef DEBUG_DLSCH_MODULATION
1376
    printf("Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d) in %d\n",
1377 1378
        harq_pid,
        dlsch0_harq->mimo_mode,
lukashov's avatar
lukashov committed
1379
        pmi2hex_2Ar2(dlsch0_harq->pmi_alloc),
1380 1381 1382
        mod_order0,
        mod_order1,
        rb_alloc[0],
lukashov's avatar
lukashov committed
1383
        len);
1384
#endif
1385 1386 1387

    if (frame_parms->Ncp==0) { // normal prefix
      if ((l==4)||(l==11))
1388
        pilots=2;   // pilots in nushift+3, nushift+9
1389
      else if (l==7)
1390
        pilots=1;   // pilots in nushift, nushift+6
1391
      else
1392 1393
        pilots=0;
    } else {
1394
      if ((l==3)||(l==9))
1395
        pilots=2;
1396
      else if (l==6)
1397
        pilots=1;
1398
      else
1399
        pilots=0;
1400 1401 1402 1403 1404 1405
    }

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

    //for (aa=0;aa<frame_parms->nb_antennas_tx;aa++)
1406
    //  memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2);
1407
    //printf("symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots);
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
    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;
1420

1421 1422 1423 1424
      // check for PBCH
      skip_half=0;

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

1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
        if (rb==(frame_parms->N_RB_DL>>1))
          skip_dc = 1;
        else
          skip_dc = 0;

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

        //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3
        if ((subframe_offset==0) &&
            (rb==((frame_parms->N_RB_DL>>1)-3)) &&
            (l>=(nsymb>>1)) &&
            (l<((nsymb>>1) + 4)))
          skip_half=1;
        else if ((subframe_offset==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4)))
          skip_half=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)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)) ) {
            rb_alloc_ind = 0;
          }

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

          //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) ) {
            rb_alloc_ind = 0;
          }

          //PSS TDD
          if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==2))
            skip_half=1;
          else if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==2))
            skip_half=2;
        } else {
          //PSS 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)-1)) ) {
            rb_alloc_ind = 0;
          }

          //PSS FDD
          if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==((nsymb>>1)-1)))
            skip_half=1;
          else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(((nsymb>>1)-1))))
            skip_half=2;

          //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)) ) {
            rb_alloc_ind = 0;
          }

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

        }

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

        skip_dc=0;
        skip_half=0;

        if (frame_parms->frame_type == TDD) { // TDD
          //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) ) {
            rb_alloc_ind = 0;
          }

          //PSS
          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) ) {
            rb_alloc_ind = 0;
          }
        } 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)) ) {
            rb_alloc_ind = 0;
          }

          //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)) ) {
            rb_alloc_ind = 0;
          }
        }
1539
      }
1540

1541 1542 1543
      if (dlsch0_harq->Nlayers>1) {
        msg("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
        return(-1);
1544
      }
1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568

      if (dlsch1) {
        if (dlsch1_harq->Nlayers>1) {
          msg("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset);
          return(-1);
        }
      }

      if (mod_order0 == 4)
        qam_table_s0 = ((pilots) ? qam16_table_b0 : qam16_table_a0);
      else if (mod_order0 == 6)
        qam_table_s0 = ((pilots) ? qam64_table_b0 : qam64_table_a0);
      else
        qam_table_s0 = NULL;

      if (mod_order1 == 4)
        qam_table_s1 = ((pilots) ? qam16_table_b1 : qam16_table_a1);
      else if (mod_order1 == 6)
        qam_table_s1 = ((pilots) ? qam64_table_b1 : qam64_table_a1);
      else
        qam_table_s1 = NULL;

      if (rb_alloc_ind > 0) {
        //    printf("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);
lukashov's avatar
lukashov committed
1569 1570
 
	  	allocate_REs_in_RB(frame_parms,
1571 1572 1573 1574 1575 1576 1577 1578 1579
                           txdataF,
                           &jj,
                           &jj2,
                           re_offset,
                           symbol_offset,
                           dlsch0->harq_processes[harq_pid],
                           (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid],
                           pilots,
                           ((pilots) ? amp_rho_b : amp_rho_a),
1580 1581
                           get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb),
                           qam_table_s0,
1582 1583 1584 1585 1586
                           qam_table_s1,
                           &re_allocated,
                           skip_dc,
                           skip_half);

1587
      }
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600

      re_offset+=12; // go to next RB


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

1601
  }
1602

1603 1604 1605


#ifdef DEBUG_DLSCH_MODULATION
1606
  msg("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));
1607
#endif
1608

1609
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
1610

1611 1612 1613
  return (re_allocated);
}

1614
<<<<<<< HEAD
lukashov's avatar
lukashov committed
1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629

int dlsch_modulation_SIC(mod_sym_t **sic_buffer,
                     int16_t amp,
                     uint32_t subframe_offset,
                     LTE_DL_FRAME_PARMS *frame_parms,
                     uint8_t num_pdcch_symbols,
                     LTE_eNB_DLSCH_t *dlsch0,
                     LTE_eNB_DLSCH_t *dlsch1,
		     int G)
{

  uint8_t nsymb;
  uint8_t harq_pid = dlsch0->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
  LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid];
1630
  uint32_t i,jj,re_allocated=0;
lukashov's avatar
lukashov committed
1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647
  uint16_t l,rb,re_offset;
  uint32_t *rb_alloc = dlsch0_harq->rb_alloc;
  uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs);
  uint8_t *x0  = dlsch0_harq->e;
  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);

  amp=1; //we do full scale here for SIC
1648
  gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15));
lukashov's avatar
lukashov committed
1649
 // printf("gain=%d\n", gain_lin_QPSK);
1650
 
lukashov's avatar
lukashov committed
1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669
  jj = 0;
  i = 0;
  while (jj <= G-1) {
       
	re_allocated = re_allocated + 1;

        switch (mod_order0) {
        case 2:  //QPSK
       /* TODO: handle more than 1 antenna */
     //   printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
        
          ((int16_t*)&sic_buffer[0][i])[0] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
          
          jj = jj + 1;
          
	  ((int16_t*)&sic_buffer[0][i])[1] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
          
          jj = jj + 1;
          
lukashov's avatar
lukashov committed
1670
	//  printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]);
lukashov's avatar
lukashov committed
1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 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
	  
	  i++;
          
	  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 *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re];
            ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_im];
	    
           i++; 

          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 *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
            ((int16_t *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
	   
	   i++;
          
	   break;
      }
      
      }


#ifdef DEBUG_DLSCH_MODULATION
  msg("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));
#endif

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);

  return (re_allocated);
}


1768
int mch_modulation(int32_t **txdataF,
1769 1770 1771 1772 1773
                   int16_t amp,
                   uint32_t subframe_offset,
                   LTE_DL_FRAME_PARMS *frame_parms,
                   LTE_eNB_DLSCH_t *dlsch)
{
1774 1775 1776 1777 1778 1779 1780 1781 1782 1783
  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 = get_Qm(dlsch->harq_processes[0]->mcs);
  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;
1784

1785
  if (mod_order == 4)
1786
    for (i=0; i<4; i++) {
1787 1788 1789
      qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15);
    }
  else if (mod_order == 6)
1790
    for (i=0; i<8; i++) {
1791
      qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15);
1792 1793 1794
    }

  jj=0;
1795
  re_allocated=0;
1796

1797
  //  printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb);
1798 1799
  for (l=2; l<nsymb_pmch; l++) {

1800
#ifdef DEBUG_DLSCH_MODULATION
1801
    printf("Generating MCH (mod %d) in subframe %d for symbol %d\n",mod_order, subframe_offset,l);
1802
#endif
1803 1804 1805 1806

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

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

1809 1810

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

lukashov's avatar
lukashov committed
1812
	  if (rb==(frame_parms->N_RB_DL>>1))
1813 1814 1815
          skip_dc = 1;
        else
          skip_dc = 0;
1816 1817 1818

      }

1819

1820
      if (mod_order == 4)
1821
        qam_table_s = qam16_table_a;
1822
      else if (mod_order == 6)
1823
        qam_table_s = qam64_table_a;
1824
      else
1825
        qam_table_s = NULL;
1826

1827
      //      printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
1828
      allocate_REs_in_RB_MCH(txdataF,
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
                             &jj,
                             re_offset,
                             symbol_offset,
                             dlsch->harq_processes[0]->e,
                             l,
                             mod_order,
                             amp,
                             qam_table_s,
                             &re_allocated,
                             skip_dc,
                             frame_parms);

1841
      re_offset+=12; // go to next RB
1842 1843


1844 1845
      // check if we crossed the symbol boundary and skip DC
      if (re_offset >= frame_parms->ofdm_symbol_size) {
1846 1847 1848 1849
        if (skip_dc == 0)  //even number of RBs (doesn't straddle DC)
          re_offset=1;
        else
          re_offset=7;  // odd number of RBs
1850 1851 1852 1853
      }
    }
  }

1854 1855


1856 1857 1858


#ifdef DEBUG_DLSCH_MODULATION
1859
  msg("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));
1860
#endif
1861 1862

  return (re_allocated);
1863
}