ulsch_modulation.c 24.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*! \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"
38
#include "UTIL/LOG/vcd_signal_dumper.h"
39

40

41
42
43
44

//#define DEBUG_ULSCH_MODULATION

#ifndef OFDMA_ULSCH
45
void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
46
{
47

48
49
50
51
52
#if defined(__x86_64__) || defined(__i386__)
  __m128i dft_in128[4][1200],dft_out128[4][1200];
#elif defined(__arm__)
  int16x8_t dft_in128[4][1200],dft_out128[4][1200];
#endif
53
54
55
56
57
58
59
60
61
  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;
62
#if defined(__x86_64__) || defined(__i386__)
63
  __m128i norm128;
64
65
66
#elif defined(__arm__)
  int16x8_t norm128;
#endif
67
  //  printf("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);
68
69
70
71
72
73

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

82
  //  printf("symbol 0 (d0 %p, d %p)\n",d0,d);
83
  for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
84
85
86
87
88
89
90
91
92
93
94
95
    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];
96
    //    printf("dft%d %d: %d,%d,%d,%d\n",Msc_PUSCH,ip,d0[i],d1[i],d2[i],d3[i]);
97
98
99
100
101

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

102
  //  printf("\n");
103
104
105
106
107
108
109
110
111

  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],
112
    &((__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]);
113
114

    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],
115
    &((__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]);
116
117

    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],
118
    &((__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]);
119
    */
120
#if defined(__x86_64__) || defined(__i386__)
121
    norm128 = _mm_set1_epi16(9459);
122
123
124
#elif defined(__arm__)
    norm128 = vdupq_n_s16(9459);
#endif
125
    for (i=0; i<12; i++) {
126
#if defined(__x86_64__) || defined(__i386__)
127
128
129
      ((__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);
130
131
132
133
134
#elif defined(__arm__)
      ((int16x8_t*)dft_out0)[i] = vqdmulhq_s16(((int16x8_t*)dft_out0)[i],norm128);
      ((int16x8_t*)dft_out1)[i] = vqdmulhq_s16(((int16x8_t*)dft_out1)[i],norm128);
      ((int16x8_t*)dft_out2)[i] = vqdmulhq_s16(((int16x8_t*)dft_out2)[i],norm128);
#endif
135
136
137
    }

    break;
138

139
140
141
142
  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);
143
144
145
    break;

  case 36:
146
147
148
    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);
149
150
151
    break;

  case 48:
152
153
154
    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);
155
156
157
    break;

  case 60:
158
159
160
    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);
161
162
163
    break;

  case 72:
164
165
166
    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);
167
168
169
    break;

  case 96:
170
171
172
173
    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;
174

175
176
177
178
  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);
179
180
    break;

181
182
183
184
  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);
185
186
    break;

187
188
189
190
  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);
191
192
    break;

193
194
195
196
  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);
197
198
    break;

199
200
201
202
  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);
203
204
    break;

205
206
207
208
  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);
209
210
    break;

211
212
213
214
215
  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;
216

217
218
219
220
221
  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;
222

223
224
225
226
227
  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;
228

229
230
231
232
233
  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;
234

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

241
242
243
244
245
  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;
246

247
248
249
250
251
  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;
252

253
254
255
256
257
  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;
258

259
260
261
262
263
  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;
264

265
266
267
268
269
  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;
270

271
272
273
274
275
  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;
276

277
278
279
280
281
  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;
282

283
284
285
286
287
  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;
288

289
290
291
292
293
  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;
294

295
296
297
298
299
  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;
300

301
302
303
304
305
  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;
306

307
308
309
310
311
  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;
312

313
314
315
316
317
  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;
318

319
320
321
322
323
  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;
324

325
326
327
328
329
330
331
332
333
334
335
336
  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;
337
  z5 = z4+Msc_PUSCH;
338
339
340
341
342
343
  z6 = z5+Msc_PUSCH;
  z7 = z6+Msc_PUSCH;
  z8 = z7+Msc_PUSCH;
  z9 = z8+Msc_PUSCH;
  z10 = z9+Msc_PUSCH;
  z11 = z10+Msc_PUSCH;
344

345
  //  printf("symbol0 (dft)\n");
346
347
  for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
    z0[i]     = dft_out0[ip];
348
    //    printf("%d,%d,",((short*)&z0[i])[0],((short*)&z0[i])[1]);
349
350
351
352
353
354
355
356
357
358
359
    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];
360
    //    printf("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]);
361
362

  }
363

364
  //  printf("\n");
365
366
367
}

#endif
368
void ulsch_modulation(int32_t **txdataF,
369
370
371
372
373
374
                      short amp,
                      uint32_t frame,
                      uint32_t subframe,
                      LTE_DL_FRAME_PARMS *frame_parms,
                      LTE_UE_ULSCH_t *ulsch)
{
375
376
377
378
379
380
381

  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;

382
383
  DevAssert(frame_parms);

384
385
  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
386
  uint8_t harq_pid = subframe2harq_pid(frame_parms,frame,subframe);
387
  uint8_t Q_m;
388
  int32_t *txptr;
389
390
391
392
  uint32_t symbol_offset;
  uint16_t first_rb;
  uint16_t nb_rb;
  int G;
393

394
395
396
397
  uint32_t x1, x2, s=0;
  uint8_t c;

  if (!ulsch) {
398
    printf("ulsch_modulation.c: Null ulsch\n");
399
400
401
    return;
  }

402
403
404
  // 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

405
  if (harq_pid > 7) {
406
    printf("ulsch_modulation.c: Illegal harq_pid %d\n",harq_pid);
407
408
409
410
411
412
413
    return;
  }

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

  if (nb_rb == 0) {
414
    printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal nb_rb %d\n",frame,subframe,nb_rb);
415
416
417
418
    return;
  }

  if (first_rb >25 ) {
419
    printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal first_rb %d\n",frame,subframe,first_rb);
420
421
422
    return;
  }

gauthier's avatar
gauthier committed
423
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_IN);
424

425
426
  Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);

Gabriel's avatar
Gabriel committed
427
  G = (int)ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
Gabriel's avatar
Gabriel committed
428

429
430
431
432
433
434

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

#ifdef DEBUG_ULSCH_MODULATION
Gabriel's avatar
Gabriel committed
435
436
  LOG_D(PHY,"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);
437
438
439
#endif

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

444
  //printf("G %d\n",G);
445
446
  for (i=0; i<(1+(G>>5)); i++) {
    for (j=0; j<32; j++,k++) {
447
448
449
      c = (uint8_t)((s>>j)&1);

      if (ulsch->h[k] == PUSCH_x) {
450
        //  printf("i %d: PUSCH_x\n",i);
451
452
        ulsch->b_tilde[k] = 1;
      } else if (ulsch->h[k] == PUSCH_y) {
453
        //  printf("i %d: PUSCH_y\n",i);
454
455
456
        ulsch->b_tilde[k] = ulsch->b_tilde[k-1];
      } else {
        ulsch->b_tilde[k] = (ulsch->h[k]+c)&1;
457
        //  printf("i %d : %d (h %d c %d)\n", (i<<5)+j,ulsch->b_tilde[k],ulsch->h[k],c);
458
      }
459

460
    }
461

462
463
    s = lte_gold_generic(&x1, &x2, 0);
  }
464

465
  //printf("\n");
466
467
468
469
470
471
472
473


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


  // Modulation

  Msymb = G/Q_m;
474

475
476
  if(ulsch->cooperation_flag == 2)
    // For Distributed Alamouti Scheme in Collabrative Communication
477
478
479
480
481
482
483
484
485
486
487
488
  {
    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)
489
        //  printf("input %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

        // 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;
517
518


519
520
        ((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);
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
        //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)
622
        //    printf("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]);
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

        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);
646
        //      printf("input(16qam) %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
        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;
678
679

      }
680
681
    }
  }// normal symbols
682
683
684
685
686


  // Transform Precoding

#ifdef OFDMA_ULSCH
687
688
689

  for (i=0; i<Msymb; i++) {
    ulsch->z[i] = ulsch->d[i];
690
  }
691
692

#else
693
694
695
  dft_lte(ulsch->z,ulsch->d,Msc_PUSCH,ulsch->Nsymb_pusch);
#endif

696
  DevAssert(txdataF);
697

698
699
#ifdef OFDMA_ULSCH
  re_offset0 = frame_parms->first_carrier_offset + (ulsch->harq_processes[harq_pid]->first_rb*12);
700

701
702
703
704
  if (re_offset0>frame_parms->ofdm_symbol_size) {
    re_offset0 -= frame_parms->ofdm_symbol_size;
    //    re_offset0++;
  }
705

706
  //  printf("re_offset0 %d\n",re_offset0);
707
708


709
  for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
710
711
712
    re_offset = re_offset0;
    symbol_offset = (int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
713
    printf("symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
714
715
#endif
    txptr = &txdataF[0][symbol_offset];
716

717
    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
718
        ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
719
720
721
722
    }
    // Skip reference symbols
    else {

723
      //      printf("copying %d REs\n",Msc_PUSCH);
724
      for (i=0; i<Msc_PUSCH; i++,j++) {
725
#ifdef DEBUG_ULSCH_MODULATION
726
        printf("re_offset %d (%p): %d,%d\n", re_offset,&ulsch->z[j],((int16_t*)&ulsch->z[j])[0],((int16_t*)&ulsch->z[j])[1]);
727
#endif
728
729
730
731
        txptr[re_offset++] = ulsch->z[j];

        if (re_offset==frame_parms->ofdm_symbol_size)
          re_offset = 0;
732
733
734
735
736
737
      }
    }
  }

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

739
740
741
742
  if (re_offset0>frame_parms->ofdm_symbol_size) {
    re_offset0 -= frame_parms->ofdm_symbol_size;
    //    re_offset0++;
  }
743

744
  //    printf("re_offset0 %d\n",re_offset0);
745
  //  printf("txdataF %p\n",&txdataF[0][0]);
746
  for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
747
748
749
    re_offset = re_offset0;
    symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
knopp's avatar
knopp committed
750
    printf("ulsch_mod (SC-FDMA) symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
751
752
#endif
    txptr = &txdataF[0][symbol_offset];
753

754
    if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
755
        ((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
756
757
758
    }
    // Skip reference symbols
    else {
759
      //      printf("copying %d REs\n",Msc_PUSCH);
760
      for (i=0; i<Msc_PUSCH; i++,j++) {
761
762

#ifdef DEBUG_ULSCH_MODULATION
763
        printf("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]);
764
#endif //DEBUG_ULSCH_MODULATION
765
        txptr[re_offset++] = ulsch->z[j];
766

767
768
        if (re_offset==frame_parms->ofdm_symbol_size)
          re_offset = 0;
769
770
771
      }
    }
  }
772

773
#endif
gauthier's avatar
gauthier committed
774
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_OUT);
775
776
777

}