ulsch_modulation.c 23.8 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 24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@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

/*! \file PHY/LTE_TRANSPORT/ulsch_modulation.c
* \brief Top-level routines for generating PUSCH physical channel from 36.211 V8.6 2009-03
* \author R. Knopp, F. Kaltenberger, A. Bhamri
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/LTE_TRANSPORT/defs.h"
#include "defs.h"
46
#include "UTIL/LOG/vcd_signal_dumper.h"
47 48 49 50 51 52 53 54

//#define OFDMA_ULSCH

//#define DEBUG_ULSCH_MODULATION

__m128i dft_in128[4][1200],dft_in128[4][1200],dft_out128[4][1200],dft_out128[4][1200];

#ifndef OFDMA_ULSCH
55 56
void dft_lte(mod_sym_t *z,mod_sym_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
{
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

  uint32_t *dft_in0=(uint32_t*)dft_in128[0],*dft_out0=(uint32_t*)dft_out128[0];
  uint32_t *dft_in1=(uint32_t*)dft_in128[1],*dft_out1=(uint32_t*)dft_out128[1];
  uint32_t *dft_in2=(uint32_t*)dft_in128[2],*dft_out2=(uint32_t*)dft_out128[2];
  //  uint32_t *dft_in3=(uint32_t*)dft_in128[3],*dft_out3=(uint32_t*)dft_out128[3];

  uint32_t *d0,*d1,*d2,*d3,*d4,*d5,*d6,*d7,*d8,*d9,*d10,*d11;

  uint32_t *z0,*z1,*z2,*z3,*z4,*z5,*z6,*z7,*z8,*z9,*z10,*z11;
  uint32_t i,ip;
  __m128i norm128;

  //  msg("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);

  d0 = (uint32_t *)d;
  d1 = d0+Msc_PUSCH;
  d2 = d1+Msc_PUSCH;
  d3 = d2+Msc_PUSCH;
  d4 = d3+Msc_PUSCH;
76
  d5 = d4+Msc_PUSCH;
77 78 79 80 81 82 83 84
  d6 = d5+Msc_PUSCH;
  d7 = d6+Msc_PUSCH;
  d8 = d7+Msc_PUSCH;
  d9 = d8+Msc_PUSCH;
  d10 = d9+Msc_PUSCH;
  d11 = d10+Msc_PUSCH;

  //  msg("symbol 0 (d0 %p, d %p)\n",d0,d);
85
  for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    dft_in0[ip]   =  d0[i];
    dft_in0[ip+1] =  d1[i];
    dft_in0[ip+2] =  d2[i];
    dft_in0[ip+3] =  d3[i];
    dft_in1[ip]   =  d4[i];
    dft_in1[ip+1] =  d5[i];
    dft_in1[ip+2] =  d6[i];
    dft_in1[ip+3] =  d7[i];
    dft_in2[ip]   =  d8[i];
    dft_in2[ip+1] =  d9[i];
    dft_in2[ip+2] =  d10[i];
    dft_in2[ip+3] =  d11[i];
    //    msg("dft%d %d: %d,%d,%d,%d\n",Msc_PUSCH,ip,d0[i],d1[i],d2[i],d3[i]);

    //    dft_in_re2[ip+1] =  d9[i];
    //    dft_in_re2[ip+2] =  d10[i];
  }

  //  msg("\n");

  switch (Msc_PUSCH) {
  case 12:
    dft12((int16_t *)dft_in0,(int16_t *)dft_out0);
    dft12((int16_t *)dft_in1,(int16_t *)dft_out1);
    dft12((int16_t *)dft_in2,(int16_t *)dft_out2);

    /*
    dft12f(&((__m128i *)dft_in0)[0],&((__m128i *)dft_in0)[1],&((__m128i *)dft_in0)[2],&((__m128i *)dft_in0)[3],&((__m128i *)dft_in0)[4],&((__m128i *)dft_in0)[5],&((__m128i *)dft_in0)[6],&((__m128i *)dft_in0)[7],&((__m128i *)dft_in0)[8],&((__m128i *)dft_in0)[9],&((__m128i *)dft_in0)[10],&((__m128i *)dft_in0)[11],
114
    &((__m128i *)dft_out0)[0],&((__m128i *)dft_out0)[1],&((__m128i *)dft_out0)[2],&((__m128i *)dft_out0)[3],&((__m128i *)dft_out0)[4],&((__m128i *)dft_out0)[5],&((__m128i *)dft_out0)[6],&((__m128i *)dft_out0)[7],&((__m128i *)dft_out0)[8],&((__m128i *)dft_out0)[9],&((__m128i *)dft_out0)[10],&((__m128i *)dft_out0)[11]);
115 116

    dft12f(&((__m128i *)dft_in1)[0],&((__m128i *)dft_in1)[1],&((__m128i *)dft_in1)[2],&((__m128i *)dft_in1)[3],&((__m128i *)dft_in1)[4],&((__m128i *)dft_in1)[5],&((__m128i *)dft_in1)[6],&((__m128i *)dft_in1)[7],&((__m128i *)dft_in1)[8],&((__m128i *)dft_in1)[9],&((__m128i *)dft_in1)[10],&((__m128i *)dft_in1)[11],
117
    &((__m128i *)dft_out1)[0],&((__m128i *)dft_out1)[1],&((__m128i *)dft_out1)[2],&((__m128i *)dft_out1)[3],&((__m128i *)dft_out1)[4],&((__m128i *)dft_out1)[5],&((__m128i *)dft_out1)[6],&((__m128i *)dft_out1)[7],&((__m128i *)dft_out1)[8],&((__m128i *)dft_out1)[9],&((__m128i *)dft_out1)[10],&((__m128i *)dft_out1)[11]);
118 119

    dft12f(&((__m128i *)dft_in2)[0],&((__m128i *)dft_in2)[1],&((__m128i *)dft_in2)[2],&((__m128i *)dft_in2)[3],&((__m128i *)dft_in2)[4],&((__m128i *)dft_in2)[5],&((__m128i *)dft_in2)[6],&((__m128i *)dft_in2)[7],&((__m128i *)dft_in2)[8],&((__m128i *)dft_in2)[9],&((__m128i *)dft_in2)[10],&((__m128i *)dft_in2)[11],
120
    &((__m128i *)dft_out2)[0],&((__m128i *)dft_out2)[1],&((__m128i *)dft_out2)[2],&((__m128i *)dft_out2)[3],&((__m128i *)dft_out2)[4],&((__m128i *)dft_out2)[5],&((__m128i *)dft_out2)[6],&((__m128i *)dft_out2)[7],&((__m128i *)dft_out2)[8],&((__m128i *)dft_out2)[9],&((__m128i *)dft_out2)[10],&((__m128i *)dft_out2)[11]);
121 122
    */
    norm128 = _mm_set1_epi16(9459);
123 124

    for (i=0; i<12; i++) {
125 126 127 128 129 130
      ((__m128i*)dft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out0)[i],norm128),1);
      ((__m128i*)dft_out1)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out1)[i],norm128),1);
      ((__m128i*)dft_out2)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out2)[i],norm128),1);
    }

    break;
131

132 133 134 135
  case 24:
    dft24((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft24((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft24((int16_t*)dft_in2,(int16_t*)dft_out2,1);
136 137 138
    break;

  case 36:
139 140 141
    dft36((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft36((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft36((int16_t*)dft_in2,(int16_t*)dft_out2,1);
142 143 144
    break;

  case 48:
145 146 147
    dft48((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft48((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft48((int16_t*)dft_in2,(int16_t*)dft_out2,1);
148 149 150
    break;

  case 60:
151 152 153
    dft60((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft60((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft60((int16_t*)dft_in2,(int16_t*)dft_out2,1);
154 155 156
    break;

  case 72:
157 158 159
    dft72((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft72((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft72((int16_t*)dft_in2,(int16_t*)dft_out2,1);
160 161 162
    break;

  case 96:
163 164 165 166
    dft96((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft96((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft96((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
167

168 169 170 171
  case 108:
    dft108((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft108((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft108((int16_t*)dft_in2,(int16_t*)dft_out2,1);
172 173
    break;

174 175 176 177
  case 120:
    dft120((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft120((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft120((int16_t*)dft_in2,(int16_t*)dft_out2,1);
178 179
    break;

180 181 182 183
  case 144:
    dft144((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft144((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft144((int16_t*)dft_in2,(int16_t*)dft_out2,1);
184 185
    break;

186 187 188 189
  case 180:
    dft180((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft180((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft180((int16_t*)dft_in2,(int16_t*)dft_out2,1);
190 191
    break;

192 193 194 195
  case 192:
    dft192((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft192((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft192((int16_t*)dft_in2,(int16_t*)dft_out2,1);
196 197
    break;

198 199 200 201
  case 216:
    dft216((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft216((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft216((int16_t*)dft_in2,(int16_t*)dft_out2,1);
202 203
    break;

204 205 206 207 208
  case 240:
    dft240((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft240((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft240((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
209

210 211 212 213 214
  case 288:
    dft288((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft288((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft288((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
215

216 217 218 219 220
  case 300:
    dft300((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft300((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft300((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
221

222 223 224 225 226
  case 324:
    dft324((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft324((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft324((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
227

228 229 230 231 232
  case 360:
    dft360((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft360((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft360((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
233

234 235 236 237 238
  case 384:
    dft384((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft384((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft384((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
239

240 241 242 243 244
  case 432:
    dft432((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft432((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft432((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
245

246 247 248 249 250
  case 480:
    dft480((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft480((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft480((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
251

252 253 254 255 256
  case 540:
    dft540((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft540((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft540((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
257

258 259 260 261 262
  case 576:
    dft576((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft576((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft576((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
263

264 265 266 267 268
  case 600:
    dft600((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft600((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft600((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
269

270 271 272 273 274
  case 648:
    dft648((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft648((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft648((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
275

276 277 278 279 280
  case 720:
    dft720((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft720((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft720((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
281

282 283 284 285 286
  case 864:
    dft864((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft864((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft864((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
287

288 289 290 291 292
  case 900:
    dft900((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft900((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft900((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
293

294 295 296 297 298
  case 960:
    dft960((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft960((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft960((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
299

300 301 302 303 304
  case 972:
    dft972((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft972((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft972((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
305

306 307 308 309 310
  case 1080:
    dft1080((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft1080((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft1080((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
311

312 313 314 315 316
  case 1152:
    dft1152((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft1152((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft1152((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
317

318 319 320 321 322 323 324 325 326 327 328 329
  case 1200:
    dft1200((int16_t*)dft_in0,(int16_t*)dft_out0,1);
    dft1200((int16_t*)dft_in1,(int16_t*)dft_out1,1);
    dft1200((int16_t*)dft_in2,(int16_t*)dft_out2,1);
    break;
  }

  z0 = (uint32_t *)z;
  z1 = z0+Msc_PUSCH;
  z2 = z1+Msc_PUSCH;
  z3 = z2+Msc_PUSCH;
  z4 = z3+Msc_PUSCH;
330
  z5 = z4+Msc_PUSCH;
331 332 333 334 335 336
  z6 = z5+Msc_PUSCH;
  z7 = z6+Msc_PUSCH;
  z8 = z7+Msc_PUSCH;
  z9 = z8+Msc_PUSCH;
  z10 = z9+Msc_PUSCH;
  z11 = z10+Msc_PUSCH;
337

338
  //  msg("symbol0 (dft)\n");
339 340
  for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
    z0[i]     = dft_out0[ip];
341
    //    msg("%d,%d,",((short*)&z0[i])[0],((short*)&z0[i])[1]);
342 343 344 345 346 347 348 349 350 351 352
    z1[i]     = dft_out0[ip+1];
    z2[i]     = dft_out0[ip+2];
    z3[i]     = dft_out0[ip+3];
    z4[i]     = dft_out1[ip+0];
    z5[i]     = dft_out1[ip+1];
    z6[i]     = dft_out1[ip+2];
    z7[i]     = dft_out1[ip+3];
    z8[i]     = dft_out2[ip];
    z9[i]     = dft_out2[ip+1];
    z10[i]    = dft_out2[ip+2];
    z11[i]    = dft_out2[ip+3];
353 354 355
    //    msg("out dft%d %d: %d,%d,%d,%d,%d,%d,%d,%d\n",Msc_PUSCH,ip,z0[i],z1[i],z2[i],z3[i],z4[i],z5[i],z6[i],z7[i]);

  }
356

357 358 359 360 361
  //  msg("\n");
}

#endif
void ulsch_modulation(mod_sym_t **txdataF,
362 363 364 365 366 367
                      short amp,
                      uint32_t frame,
                      uint32_t subframe,
                      LTE_DL_FRAME_PARMS *frame_parms,
                      LTE_UE_ULSCH_t *ulsch)
{
368 369 370 371 372 373 374

  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;
  short gain_lin_QPSK;

375 376
  DevAssert(frame_parms);

377 378
  int re_offset,re_offset0,i,Msymb,j,k,nsymb,Msc_PUSCH,l;
  //  uint8_t harq_pid = (rag_flag == 1) ? 0 : subframe2harq_pid_tdd(frame_parms->tdd_config,subframe);
knopp's avatar
 
knopp committed
379
  uint8_t harq_pid = subframe2harq_pid(frame_parms,frame,subframe);
380 381 382 383 384 385
  uint8_t Q_m;
  mod_sym_t *txptr;
  uint32_t symbol_offset;
  uint16_t first_rb;
  uint16_t nb_rb;
  int G;
386

387 388 389 390 391 392 393 394
  uint32_t x1, x2, s=0;
  uint8_t c;

  if (!ulsch) {
    msg("ulsch_modulation.c: Null ulsch\n");
    return;
  }

395 396 397
  // x1 is set in lte_gold_generic
  x2 = (ulsch->rnti<<14) + (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1

398 399 400 401 402 403 404 405 406
  if (harq_pid > 7) {
    msg("ulsch_modulation.c: Illegal harq_pid %d\n",harq_pid);
    return;
  }

  first_rb = ulsch->harq_processes[harq_pid]->first_rb;
  nb_rb = ulsch->harq_processes[harq_pid]->nb_rb;

  if (nb_rb == 0) {
knopp's avatar
 
knopp committed
407
    msg("ulsch_modulation.c: Frame %d, Subframe %d Illegal nb_rb %d\n",frame,subframe,nb_rb);
408 409 410 411
    return;
  }

  if (first_rb >25 ) {
knopp's avatar
 
knopp committed
412
    msg("ulsch_modulation.c: Frame %d, Subframe %d Illegal first_rb %d\n",frame,subframe,first_rb);
413 414 415
    return;
  }

gauthier's avatar
gauthier committed
416
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_IN);
417

418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
  Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);

  G = (int)ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);

  // Mapping
  nsymb = (frame_parms->Ncp==0) ? 14:12;
  Msc_PUSCH = ulsch->harq_processes[harq_pid]->nb_rb*12;

#ifdef DEBUG_ULSCH_MODULATION
  msg("ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
      ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
#endif

  // scrambling (Note the placeholding bits are handled in ulsch_coding.c directly!)
  //msg("ulsch bits: ");
  s = lte_gold_generic(&x1, &x2, 1);
  k=0;
435

436
  //printf("G %d\n",G);
437 438
  for (i=0; i<(1+(G>>5)); i++) {
    for (j=0; j<32; j++,k++) {
439 440 441
      c = (uint8_t)((s>>j)&1);

      if (ulsch->h[k] == PUSCH_x) {
442 443 444 445 446 447 448 449
        //  msg("i %d: PUSCH_x\n",i);
        ulsch->b_tilde[k] = 1;
      } else if (ulsch->h[k] == PUSCH_y) {
        //  msg("i %d: PUSCH_y\n",i);
        ulsch->b_tilde[k] = ulsch->b_tilde[k-1];
      } else {
        ulsch->b_tilde[k] = (ulsch->h[k]+c)&1;
        //  msg("i %d : %d (h %d c %d)\n", (i<<5)+j,ulsch->b_tilde[k],ulsch->h[k],c);
450
      }
451

452
    }
453

454 455
    s = lte_gold_generic(&x1, &x2, 0);
  }
456

457 458 459 460 461 462 463 464 465
  //msg("\n");


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


  // Modulation

  Msymb = G/Q_m;
466

467 468
  if(ulsch->cooperation_flag == 2)
    // For Distributed Alamouti Scheme in Collabrative Communication
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
  {
    for (i=0,j=Q_m; i<Msymb; i+=2,j+=2*Q_m) {

      switch (Q_m) {

      case 2:


        //UE1, -x1*
        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (gain_lin_QPSK) : -gain_lin_QPSK;
        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
        //      if (i<Msc_PUSCH)
        //  msg("input %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);

        // UE1, x0*
        ((int16_t*)&ulsch->d[i+1])[0] = (ulsch->b_tilde[j-2] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
        ((int16_t*)&ulsch->d[i+1])[1] = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;

        break;

      case 4:


        //UE1,-x1*
        qam16_table_offset_re = 0;
        qam16_table_offset_im = 0;

        if (ulsch->b_tilde[j] == 1)
          qam16_table_offset_re+=2;

        if (ulsch->b_tilde[j+1] == 1)
          qam16_table_offset_im+=2;



        if (ulsch->b_tilde[j+2] == 1)
          qam16_table_offset_re+=1;

        if (ulsch->b_tilde[j+3] == 1)
          qam16_table_offset_im+=1;
509 510


511 512
        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
513

514 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 582 583 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 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
        //UE1,x0*
        qam16_table_offset_re = 0;
        qam16_table_offset_im = 0;

        if (ulsch->b_tilde[j-4] == 1)
          qam16_table_offset_re+=2;

        if (ulsch->b_tilde[j-3] == 1)
          qam16_table_offset_im+=2;


        if (ulsch->b_tilde[j-2] == 1)
          qam16_table_offset_re+=1;

        if (ulsch->b_tilde[j-1] == 1)
          qam16_table_offset_im+=1;


        //    ((int16_t*)&ulsch->d[i+1])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
        //    ((int16_t*)&ulsch->d[i+1])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);


        break;

      case 6:



        //UE1,-x1*FPGA_UE
        qam64_table_offset_re = 0;
        qam64_table_offset_im = 0;

        if (ulsch->b_tilde[j] == 1)
          qam64_table_offset_re+=4;

        if (ulsch->b_tilde[j+1] == 1)
          qam64_table_offset_im+=4;

        if (ulsch->b_tilde[j+2] == 1)
          qam64_table_offset_re+=2;


        if (ulsch->b_tilde[j+3] == 1)
          qam64_table_offset_im+=2;

        if (ulsch->b_tilde[j+4] == 1)
          qam64_table_offset_re+=1;

        if (ulsch->b_tilde[j+5] == 1)
          qam64_table_offset_im+=1;


        ((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);

        //UE1,x0*
        qam64_table_offset_re = 0;
        qam64_table_offset_im = 0;

        if (ulsch->b_tilde[j-6] == 1)
          qam64_table_offset_re+=4;

        if (ulsch->b_tilde[j-5] == 1)
          qam64_table_offset_im+=4;

        if (ulsch->b_tilde[j-4] == 1)
          qam64_table_offset_re+=2;


        if (ulsch->b_tilde[j-3] == 1)
          qam64_table_offset_im+=2;

        if (ulsch->b_tilde[j-2] == 1)
          qam64_table_offset_re+=1;

        if (ulsch->b_tilde[j-1] == 1)
          qam64_table_offset_im+=1;


        ((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);

        break;

      }//switch
    }//for
  }//cooperation_flag == 2
  else {
    for (i=0,j=0; i<Msymb; i++,j+=Q_m) {

      switch (Q_m) {

      case 2:
        // TODO: this has to be updated!!!

        ((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1)  ? (-gain_lin_QPSK) : gain_lin_QPSK;
        ((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
        //        if (i<Msc_PUSCH)
        //    msg("input %d/%d Msc_PUSCH %d (%p): %d,%d\n", i,Msymb,Msc_PUSCH,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);

        break;

      case 4:

        qam16_table_offset_re = 0;
        qam16_table_offset_im = 0;

        if (ulsch->b_tilde[j] == 1)
          qam16_table_offset_re+=2;

        if (ulsch->b_tilde[j+1] == 1)
          qam16_table_offset_im+=2;

        if (ulsch->b_tilde[j+2] == 1)
          qam16_table_offset_re+=1;

        if (ulsch->b_tilde[j+3] == 1)
          qam16_table_offset_im+=1;


        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
        //      msg("input(16qam) %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
        break;

      case 6:


        qam64_table_offset_re = 0;
        qam64_table_offset_im = 0;

        if (ulsch->b_tilde[j] == 1)
          qam64_table_offset_re+=4;

        if (ulsch->b_tilde[j+1] == 1)
          qam64_table_offset_im+=4;

        if (ulsch->b_tilde[j+2] == 1)
          qam64_table_offset_re+=2;

        if (ulsch->b_tilde[j+3] == 1)
          qam64_table_offset_im+=2;

        if (ulsch->b_tilde[j+4] == 1)
          qam64_table_offset_re+=1;

        if (ulsch->b_tilde[j+5] == 1)
          qam64_table_offset_im+=1;


        ((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
        ((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);

        break;
670 671

      }
672 673
    }
  }// normal symbols
674 675 676 677 678


  // Transform Precoding

#ifdef OFDMA_ULSCH
679 680 681

  for (i=0; i<Msymb; i++) {
    ulsch->z[i] = ulsch->d[i];
682
  }
683 684

#else
685 686 687
  dft_lte(ulsch->z,ulsch->d,Msc_PUSCH,ulsch->Nsymb_pusch);
#endif

688
  DevAssert(txdataF);
689

690 691
#ifdef OFDMA_ULSCH
  re_offset0 = frame_parms->first_carrier_offset + (ulsch->harq_processes[harq_pid]->first_rb*12);
692

693 694 695 696
  if (re_offset0>frame_parms->ofdm_symbol_size) {
    re_offset0 -= frame_parms->ofdm_symbol_size;
    //    re_offset0++;
  }
697

698 699 700
  //  msg("re_offset0 %d\n",re_offset0);


701
  for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
702 703 704
    re_offset = re_offset0;
    symbol_offset = (int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
705
    msg("symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
706 707
#endif
    txptr = &txdataF[0][symbol_offset];
708

709
    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
710
        ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
711 712 713 714 715
    }
    // Skip reference symbols
    else {

      //      msg("copying %d REs\n",Msc_PUSCH);
716
      for (i=0; i<Msc_PUSCH; i++,j++) {
717
#ifdef DEBUG_ULSCH_MODULATION
718
        msg("re_offset %d (%p): %d,%d\n", re_offset,&ulsch->z[j],((int16_t*)&ulsch->z[j])[0],((int16_t*)&ulsch->z[j])[1]);
719
#endif
720 721 722 723
        txptr[re_offset++] = ulsch->z[j];

        if (re_offset==frame_parms->ofdm_symbol_size)
          re_offset = 0;
724 725 726 727 728 729
      }
    }
  }

# else  // OFDMA_ULSCH = 0
  re_offset0 = frame_parms->first_carrier_offset + (ulsch->harq_processes[harq_pid]->first_rb*12);
730

731 732 733 734
  if (re_offset0>frame_parms->ofdm_symbol_size) {
    re_offset0 -= frame_parms->ofdm_symbol_size;
    //    re_offset0++;
  }
735

736 737
  //    msg("re_offset0 %d\n",re_offset0);
  //  printf("txdataF %p\n",&txdataF[0][0]);
738
  for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
739 740 741 742 743 744
    re_offset = re_offset0;
    symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
    msg("ulsch_mod (OFDMA) symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
#endif
    txptr = &txdataF[0][symbol_offset];
745

746
    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
747
        ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
748 749 750 751
    }
    // Skip reference symbols
    else {
      //      msg("copying %d REs\n",Msc_PUSCH);
752
      for (i=0; i<Msc_PUSCH; i++,j++) {
753 754

#ifdef DEBUG_ULSCH_MODULATION
755
        msg("re_offset %d (%p): %d,%d => %p\n", re_offset,&ulsch->z[j],((int16_t*)&ulsch->z[j])[0],((int16_t*)&ulsch->z[j])[1],&txptr[re_offset]);
756
#endif //DEBUG_ULSCH_MODULATION
757
        txptr[re_offset++] = ulsch->z[j];
758

759 760
        if (re_offset==frame_parms->ofdm_symbol_size)
          re_offset = 0;
761 762 763
      }
    }
  }
764

765
#endif
gauthier's avatar
gauthier committed
766
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_OUT);
767 768 769

}