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

/*! \file PHY/LTE_TRANSPORT/dci.c
* \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03.
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
35
36
37
38
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
#include "SCHED/sched_eNB.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
39
#include "PHY/sse_intrin.h"
40
41
#include "transport_proto.h"
#include "transport_common_proto.h"
Cedric Roux's avatar
Cedric Roux committed
42
#include "assertions.h"
Bilel's avatar
Bilel committed
43
#include "T.h"
44
45
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
46
#include "PHY/LTE_TRANSPORT/transport_extern.h"
knopp's avatar
knopp committed
47
#include "PHY/LTE_REFSIG/lte_refsig.h"
48
49
50
51

//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
52

53
54
//#undef ALL_AGGREGATION

gauthier's avatar
gauthier committed
55
56
//extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3];
//extern uint16_t pcfich_reg[4];
57

58

59

60
61
//static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
//static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
62

gauthier's avatar
gauthier committed
63
void dci_encoding(uint8_t *a,
64
65
66
67
68
                  uint8_t A,
                  uint16_t E,
                  uint8_t *e,
                  uint16_t rnti)
{
69
70


gauthier's avatar
gauthier committed
71
72
  uint8_t D = (A + 16);
  uint32_t RCC;
73
74
  uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
  uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
75
76

#ifdef DEBUG_DCI_ENCODING
gauthier's avatar
gauthier committed
77
  int32_t i;
78
#endif
79
  // encode dci
80
81

#ifdef DEBUG_DCI_ENCODING
knopp's avatar
knopp committed
82
  printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E);
83
84
85
86
87
88
89
#endif

  memset((void *)d,LTE_NULL,96);

  ccodelte_encode(A,2,a,d+96,rnti);

#ifdef DEBUG_DCI_ENCODING
90
91

  for (i=0; i<16+A; i++)
92
    printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
93

94
#endif
95

96
#ifdef DEBUG_DCI_ENCODING
97
  printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
98
99
100
101
#endif
  RCC = sub_block_interleaving_cc(D,d+96,w);

#ifdef DEBUG_DCI_ENCODING
102
  printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
103
104
105
106
107
108
109
#endif
  lte_rate_matching_cc(RCC,E,w,e);


}


gauthier's avatar
gauthier committed
110
uint8_t *generate_dci0(uint8_t *dci,
111
112
113
114
115
116
                       uint8_t *e,
                       uint8_t DCI_LENGTH,
                       uint8_t aggregation_level,
                       uint16_t rnti)
{

gauthier's avatar
gauthier committed
117
118
  uint16_t coded_bits;
  uint8_t dci_flip[8];
119

Cedric Roux's avatar
Cedric Roux committed
120
121
122
123
  AssertFatal((aggregation_level==1) ||
	      (aggregation_level==2) ||
	      (aggregation_level==4) ||
	      (aggregation_level==8)
124
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Added for EPDCCH/MPDCCH
125
126
127
128
129
130
	      ||
	      (aggregation_level==16) ||
	      (aggregation_level==24) ||
	      (aggregation_level==32)
#endif
	      ,
131
	      "generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
Cedric Roux's avatar
Cedric Roux committed
132

133

134
  coded_bits = 72 * aggregation_level;
135

Cedric Roux's avatar
Cedric Roux committed
136

137
138

  #ifdef DEBUG_DCI_ENCODING
knopp's avatar
knopp committed
139
  for (int i=0;i<1+((DCI_LENGTH+16)/8);i++)
140
    printf("i %d : %x\n",i,dci[i]);
141
  #endif
Cedric Roux's avatar
Cedric Roux committed
142

143
  if (DCI_LENGTH<=32) {
144
145
146
    dci_flip[0] = dci[3];
    dci_flip[1] = dci[2];
    dci_flip[2] = dci[1];
147
    dci_flip[3] = dci[0];
knopp's avatar
knopp committed
148
149
150
151
152
#ifdef DEBUG_DCI_ENCODING
    printf("DCI => %x,%x,%x,%x\n",
	   dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]);

#endif
153
  } else {
154
155
156
157
158
159
160
161
    dci_flip[0] = dci[7];
    dci_flip[1] = dci[6];
    dci_flip[2] = dci[5];
    dci_flip[3] = dci[4];
    dci_flip[4] = dci[3];
    dci_flip[5] = dci[2];
    dci_flip[6] = dci[1];
    dci_flip[7] = dci[0];
162
#ifdef DEBUG_DCI_ENCODING
163
    printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
164
165
        dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
        dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
166
#endif
167
  }
168

169
170
171
172
173
  dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);

  return(e+coded_bits);
}

174
//uint32_t Y;
175
176


177
178
179



180

181
void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
182
{
183

184
  int32_t *wptr,*wptr2,*zptr;
gauthier's avatar
gauthier committed
185
186
187
188
  uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi);
  uint32_t RCC = (Mquad>>5), ND;
  uint32_t row,col,Kpi,index;
  int32_t i,k,a;
189
#ifdef RM_DEBUG
gauthier's avatar
gauthier committed
190
  int32_t nulled=0;
191
#endif
192
193
  uint32_t Msymb=(DCI_BITS_MAX/2);
  int32_t wtemp[2][Msymb];
194

195
  //  printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
196
197
  if ((Mquad&0x1f) > 0)
    RCC++;
198

199
200
201
202
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
203
204

  for (col=0; col<32; col++) {
205
206
    index = bitrev_cc_dci[col];

207
    for (row=0; row<RCC; row++) {
208
      //printf("col %d, index %d, row %d\n",col,index,row);
209
      if (index>=ND) {
Xiwen JIANG's avatar
Xiwen JIANG committed
210
        for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
211
          //printf("a %d k %d\n",a,k);
212
213
214

          wptr = &wtemp[a][k<<2];
          zptr = &z[a][(index-ND)<<2];
215

216
          //printf("wptr=%p, zptr=%p\n",wptr,zptr);
217

218
219
220
221
222
          wptr[0] = zptr[0];
          wptr[1] = zptr[1];
          wptr[2] = zptr[2];
          wptr[3] = zptr[3];
        }
223

224
        k++;
225
      }
226

227
228
229
230
231
      index+=32;
    }
  }

  // permutation
232
233
  for (i=0; i<Mquad; i++) {

Xiwen JIANG's avatar
Xiwen JIANG committed
234
    for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
235
236
237
238
239
240
241
242
243
244
245
246
247
248

      //wptr  = &wtemp[a][i<<2];
      //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
      wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
      wptr2 = &wbar[a][i<<2];
      wptr2[0] = wptr[0];
      wptr2[1] = wptr[1];
      wptr2[2] = wptr[2];
      wptr2[3] = wptr[3];
    }
  }
}

void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
249
250
251
252
                      uint8_t subframe,
                      uint8_t *e,
                      uint32_t length)
{
253
  int i;
gauthier's avatar
gauthier committed
254
255
  uint8_t reset;
  uint32_t x1, x2, s=0;
knopp's avatar
knopp committed
256
257

  //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length);
258
259

  reset = 1;
knopp's avatar
knopp committed
260
  // x1 is set in lte_gold_generic
261
262
263
264

  x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2

  for (i=0; i<length; i++) {
265
    if ((i&0x1f)==0) {
266
      s = lte_gold_generic(&x1, &x2, reset);
knopp's avatar
knopp committed
267
      //printf("lte_gold[%d]=%x\n",i,s);
268
269
      reset = 0;
    }
270

knopp's avatar
knopp committed
271
272
273
    //    printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1));
    if (e[i] != 2) // <NIL> element is 2
      e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1);
274
275
  }
}
276

277
278
uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
			 uint8_t num_dci,
279
280
281
282
                         DCI_ALLOC_t *dci_alloc,
                         uint32_t n_rnti,
                         int16_t amp,
                         LTE_DL_FRAME_PARMS *frame_parms,
283
                         int32_t **txdataF,
284
285
                         uint32_t subframe)
{
gauthier's avatar
gauthier committed
286

287

288
  uint8_t *e_ptr;
gauthier's avatar
gauthier committed
289
290
291
292
293
  int8_t L;
  uint32_t i, lprime;
  uint32_t gain_lin_QPSK,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset;
  int16_t re_offset;
  uint8_t mi = get_mi(frame_parms,subframe);
294
295
296
  uint8_t e[DCI_BITS_MAX];
  uint32_t Msymb=(DCI_BITS_MAX/2);
  int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb];
297

298
299
  int32_t *y[2];
  int32_t *wbar[2];
300

301
302
303
304
305
306
307
308
309
  int nushiftmod3 = frame_parms->nushift%3;

  int Msymb2;
  int split_flag=0;

  switch (frame_parms->N_RB_DL) {
  case 100:
    Msymb2 = Msymb;
    break;
310

311
312
313
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
314

315
316
317
  case 50:
    Msymb2 = Msymb>>1;
    break;
318

319
320
321
  case 25:
    Msymb2 = Msymb>>2;
    break;
322

323
324
325
  case 15:
    Msymb2 = Msymb*15/100;
    break;
326

327
328
329
  case 6:
    Msymb2 = Msymb*6/100;
    break;
330

331
332
333
334
335
  default:
    Msymb2 = Msymb>>2;
    break;
  }

336

337
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,1);
338
  generate_pcfich(num_pdcch_symbols,
339
340
341
342
                  amp,
                  frame_parms,
                  txdataF,
                  subframe);
343
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,0);
344
345
346
347
348
  wbar[0] = &wbar0[0];
  wbar[1] = &wbar1[0];
  y[0] = &yseq0[0];
  y[1] = &yseq1[0];

349
350
351
352
353
354
355
#if BASIC_SIMULATOR
  /* this should be the normal case
   * but it has to be validated for all the various cases
   * so let's just do it for the basic simulator
   */
  memset(e, 2, DCI_BITS_MAX);
#else
356
#if 1
357
  // reset all bits to <NIL>, here we set <NIL> elements as 2
358
359
360
361
  // memset(e, 2, DCI_BITS_MAX);
  // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
  for (i=0; i<DCI_BITS_MAX; i++)
    e[i]=taus()&1;
362
363
364
365
366
#endif

  /* clear all bits, the above code may generate too much false detections
   * (not sure about this, to be checked somehow)
   */
367
  //memset(e, 0, DCI_BITS_MAX);
368
#endif /* BASIC_SIMULATOR */
369

370
371
  e_ptr = e;

372
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,1);
373

374
375
  // generate DCIs in order of decreasing aggregation level, then common/ue spec
  // MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization
376
  for (L=8; L>=1; L>>=1) {
377
    for (i=0; i<num_dci; i++) {
378

gauthier's avatar
gauthier committed
379
      if (dci_alloc[i].L == (uint8_t)L) {
380

381
        LOG_D(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",
knopp's avatar
knopp committed
382
              i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L,
383
384
		*(unsigned int*)dci_alloc[i].dci_pdu,
		dci_alloc[i].rnti);
385

386
        if (dci_alloc[i].firstCCE>=0) {
387
          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
388
                                e+(72*dci_alloc[i].firstCCE),
389
390
391
392
                                dci_alloc[i].dci_length,
                                dci_alloc[i].L,
                                dci_alloc[i].rnti);
        }
393
394
395
      }
    }
  }
396
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0);
397
398

  // Scrambling
399
400
401
402
403
404
#ifdef DEBUG_DCI_ENCODING
  printf("pdcch scrambling\n");
#endif
  //LOG_D(PHY, "num_pdcch_symbols:%d mi:%d nquad:%d\n", num_pdcch_symbols, mi, get_nquad(num_pdcch_symbols, frame_parms, mi));

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,1);
405
  pdcch_scrambling(frame_parms,
406
407
                   subframe,
                   e,
408
                   8*get_nquad(num_pdcch_symbols, frame_parms, mi));
409
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,0);
410
411
  //72*get_nCCE(num_pdcch_symbols,frame_parms,mi));

412

413

414

415
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,1);
416
  // Now do modulation
417
  if (frame_parms->nb_antenna_ports_eNB==1)
418
    gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
419
  else
420
    gain_lin_QPSK = amp/2;
421
422

  e_ptr = e;
423

424
425
426
427
#ifdef DEBUG_DCI_ENCODING
  printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK);
#endif

428
  //LOG_D(PHY,"%s() Msymb2:%d\n", __FUNCTION__, Msymb2);
429

430
  if (frame_parms->nb_antenna_ports_eNB==1) { //SISO
431

432

433
    for (i=0; i<Msymb2; i++) {
Cedric Roux's avatar
Cedric Roux committed
434

gauthier's avatar
gauthier committed
435
436
437
438
      //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
439
      e_ptr++;
gauthier's avatar
gauthier committed
440
441
442
443
      //((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      //((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
444
445
446

      e_ptr++;
    }
447
  } else { //ALAMOUTI
448

449

450
    for (i=0; i<Msymb2; i+=2) {
451
452

#ifdef DEBUG_DCI_ENCODING
453
      printf(" PDCCH Modulation (TX diversity): REG %d\n",i>>2);
454
#endif
455
      // first antenna position n -> x0
456
      ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
457
      e_ptr++;
458
      ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
459
      e_ptr++;
460

461
      // second antenna position n -> -x1*
462
      ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
463
      e_ptr++;
464
      ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
465
466
467
468
469
470
471
472
473
      e_ptr++;

      // fill in the rest of the ALAMOUTI precoding
      ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0];
      ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1];
      ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0];
      ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1];

    }
474
  }
475
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0);
476
477
478


#ifdef DEBUG_DCI_ENCODING
479
  printf(" PDCCH Interleaving\n");
480
481
#endif

482
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,1);
483
  //  printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
484
485
  // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5
  pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi);
486
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,0);
487

488
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,1);
489
490
491
492
493
  mprime=0;
  nsymb = (frame_parms->Ncp==0) ? 14:12;
  re_offset = frame_parms->first_carrier_offset;

  // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5
494
  //  printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]);
495
496
497
498
499
500
501
502
503
504
505
506
#ifdef DEBUG_DCI_ENCODING
  printf("kprime loop - N_RB_DL:%d lprime:num_pdcch_symbols:%d Ncp:%d pcfich:%02x,%02x,%02x,%02x ofdm_symbol_size:%d first_carrier_offset:%d nb_antenna_ports_eNB:%d\n",
  frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp,
  frame_parms->pcfich_reg[0],
  frame_parms->pcfich_reg[1],
  frame_parms->pcfich_reg[2],
  frame_parms->pcfich_reg[3],
  frame_parms->ofdm_symbol_size,
  frame_parms->first_carrier_offset,
  frame_parms->nb_antenna_ports_eNB
  );
#endif
507
508
  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
509

gauthier's avatar
gauthier committed
510
      symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(lprime+(subframe*nsymb));
511
512


513

514
515
516
517
518
519
520
521
      tti_offset = symbol_offset + re_offset;

      (re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0);

      //            printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset);
      // if REG is allocated to PHICH, skip it
      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
#ifdef DEBUG_DCI_ENCODING
522
        printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
523
#endif
524
525
526
527
      } else {
        // Copy REG to TX buffer

        if ((lprime == 0)||
Xiwen JIANG's avatar
Xiwen JIANG committed
528
            ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) {
529
530
531
532
533
534
535
536
537
538
539
          // first symbol, or second symbol+4 TX antennas skip pilots

          kprime_mod12 = kprime%12;

          if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) {
            // kprime represents REG

            for (i=0; i<6; i++) {
              if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) {
                txdataF[0][tti_offset+i] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
540
                if (frame_parms->nb_antenna_ports_eNB > 1)
541
542
                  txdataF[1][tti_offset+i] = wbar[1][mprime];

543
#ifdef DEBUG_DCI_ENCODING
544
                printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
545
#endif
546

547
548
549
550
551
552
553
554
555
556
557
558
559
                mprime++;
              }
            }
          }
        } else { // no pilots in this symbol
          kprime_mod12 = kprime%12;

          if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) {
            // kprime represents REG
            if (split_flag==0) {
              for (i=0; i<4; i++) {
                txdataF[0][tti_offset+i] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
560
                if (frame_parms->nb_antenna_ports_eNB > 1)
561
562
                  txdataF[1][tti_offset+i] = wbar[1][mprime];

563
#ifdef DEBUG_DCI_ENCODING
564
                LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
565
#endif
566
567
568
569
570
                mprime++;
              }
            } else {
              txdataF[0][tti_offset+0] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
571
              if (frame_parms->nb_antenna_ports_eNB > 1)
572
573
                txdataF[1][tti_offset+0] = wbar[1][mprime];

574
#ifdef DEBUG_DCI_ENCODING
575
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
576
#endif
577
578
579
              mprime++;
              txdataF[0][tti_offset+1] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
580
              if (frame_parms->nb_antenna_ports_eNB > 1)
581
582
                txdataF[1][tti_offset+1] = wbar[1][mprime];

583
#ifdef DEBUG_DCI_ENCODING
584
              printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
585
#endif
586
587
588
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
589
              if (frame_parms->nb_antenna_ports_eNB > 1)
590
591
                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];

592
#ifdef DEBUG_DCI_ENCODING
593
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
594
                    *(1+(short*)&wbar[0][mprime]));
595
#endif
596
597
598
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
599
              if (frame_parms->nb_antenna_ports_eNB > 1)
600
601
                txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];

602
#ifdef DEBUG_DCI_ENCODING
603
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
604
                    *(1+(short*)&wbar[0][mprime]));
605
#endif
606
607
608
609
610
              mprime++;

            }
          }
        }
611

612
613
        if (mprime>=Msymb2)
          return(num_pdcch_symbols);
614
      } // check_phich_reg
615

616
    } //lprime loop
617

618
    re_offset++;
619

620
621
622
    if (re_offset == (frame_parms->ofdm_symbol_size))
      re_offset = 1;
  } // kprime loop
623
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0);
624

625
626
627
628
  return(num_pdcch_symbols);
}