dci.c 125 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * 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
 */
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

/*! \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
*/
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
40
#include "SIMULATION/TOOLS/defs.h" // for taus 
41
#include "PHY/sse_intrin.h"
42

43
#include "assertions.h" 
Bilel's avatar
Bilel committed
44
#include "T.h"
45
#include "UTIL/LOG/log.h"
46
47
48
49

//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
50

51
52
//#undef ALL_AGGREGATION

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

56
57
uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi)
{
58

gauthier's avatar
gauthier committed
59
60
61
62
  uint16_t i;
  uint16_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
  uint16_t mprime;
  uint16_t *pcfich_reg = frame_parms->pcfich_reg;
63
64
65
66
67
68
69
70

  if ((lprime>0) && (frame_parms->Ncp==0) )
    return(0);

  //  printf("check_phich_reg : mi %d\n",mi);

  // compute REG based on symbol
  if ((lprime == 0)||
Xiwen JIANG's avatar
Xiwen JIANG committed
71
      ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)))
72
73
74
75
76
    mprime = kprime/6;
  else
    mprime = kprime>>2;

  // check if PCFICH uses mprime
77
  if ((lprime==0) &&
78
79
80
81
82
      ((mprime == pcfich_reg[0]) ||
       (mprime == pcfich_reg[1]) ||
       (mprime == pcfich_reg[2]) ||
       (mprime == pcfich_reg[3]))) {
#ifdef DEBUG_DCI_ENCODING
83
    printf("[PHY] REG %d allocated to PCFICH\n",mprime);
84
85
86
87
88
89
90
91
92
93
#endif
    return(1);
  }

  // handle Special subframe case for TDD !!!

  //  printf("Checking phich_reg %d\n",mprime);
  if (mi > 0) {
    if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
      Ngroup_PHICH++;
94

95
96
97
    if (frame_parms->Ncp == 1) {
      Ngroup_PHICH<<=1;
    }
98
99
100
101
102
103
104



    for (i=0; i<Ngroup_PHICH; i++) {
      if ((mprime == frame_parms->phich_reg[i][0]) ||
          (mprime == frame_parms->phich_reg[i][1]) ||
          (mprime == frame_parms->phich_reg[i][2]))  {
105
#ifdef DEBUG_DCI_ENCODING
106
        printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
107
#endif
108
        return(1);
109
110
111
      }
    }
  }
112

113
114
115
  return(0);
}

116
117
uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
{
118

gauthier's avatar
gauthier committed
119
120
  uint16_t crc16;
  //  uint8_t i;
121
122

  /*
gauthier's avatar
gauthier committed
123
124
  uint8_t crc;
  crc = ((uint16_t *)dci)[DCI_LENGTH>>4];
125
126
127
  printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH);
  crc = (crc>>(DCI_LENGTH&0xf));
  // clear crc bits
gauthier's avatar
gauthier committed
128
129
130
  ((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf)));
  printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]);
  crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf));
131
  // clear crc bits
gauthier's avatar
gauthier committed
132
  (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0;
133
134
  printf("extract_crc: crc %x\n",crc);
  */
135
#ifdef DEBUG_DCI_DECODING
136
  LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)],
137
      dci_len&0x7);
138
#endif
139

140
  if ((dci_len&0x7) > 0) {
gauthier's avatar
gauthier committed
141
142
    ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7));
    ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7));
143
  } else {
gauthier's avatar
gauthier committed
144
145
    ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)];
    ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)];
146
147
  }

148
#ifdef DEBUG_DCI_DECODING
149
  LOG_I(PHY,"dci_crc =>%x\n",crc16);
150
151
152
153
154
#endif

  //  dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf));
  //  dci[(dci_len>>3)+1] = 0;
  //  dci[(dci_len>>3)+2] = 0;
gauthier's avatar
gauthier committed
155
  return((uint16_t)crc16);
156
  
157
158
159
160
}



gauthier's avatar
gauthier committed
161
162
static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
163

gauthier's avatar
gauthier committed
164
void dci_encoding(uint8_t *a,
165
166
167
168
169
                  uint8_t A,
                  uint16_t E,
                  uint8_t *e,
                  uint16_t rnti)
{
170
171


gauthier's avatar
gauthier committed
172
173
  uint8_t D = (A + 16);
  uint32_t RCC;
174
175

#ifdef DEBUG_DCI_ENCODING
gauthier's avatar
gauthier committed
176
  int32_t i;
177
#endif
178
  // encode dci
179
180

#ifdef DEBUG_DCI_ENCODING
181
  printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
182
183
184
185
186
187
188
#endif

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

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

#ifdef DEBUG_DCI_ENCODING
189
190

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

193
#endif
194

195
#ifdef DEBUG_DCI_ENCODING
196
  printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
197
198
199
200
#endif
  RCC = sub_block_interleaving_cc(D,d+96,w);

#ifdef DEBUG_DCI_ENCODING
201
  printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
202
203
204
205
206
207
208
#endif
  lte_rate_matching_cc(RCC,E,w,e);


}


gauthier's avatar
gauthier committed
209
uint8_t *generate_dci0(uint8_t *dci,
210
211
212
213
214
215
                       uint8_t *e,
                       uint8_t DCI_LENGTH,
                       uint8_t aggregation_level,
                       uint16_t rnti)
{

gauthier's avatar
gauthier committed
216
217
  uint16_t coded_bits;
  uint8_t dci_flip[8];
218

219
220
221
  AssertFatal((aggregation_level==1) || 
	      (aggregation_level==2) || 
	      (aggregation_level==4) || 
222
223
224
225
226
227
228
229
	      (aggregation_level==8) 
#ifdef Rel14 // Added for EPDCCH/MPDCCH
	      ||
	      (aggregation_level==16) ||
	      (aggregation_level==24) ||
	      (aggregation_level==32)
#endif
	      ,
230
231
	      "generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
  
232

233
  coded_bits = 72 * aggregation_level;
234

235
236
237
  /*

  #ifdef DEBUG_DCI_ENCODING
238
  for (i=0;i<1+((DCI_LENGTH+16)/8);i++)
239
    printf("i %d : %x\n",i,dci[i]);
240
  #endif
241
  */
242
  if (DCI_LENGTH<=32) {
243
244
245
    dci_flip[0] = dci[3];
    dci_flip[1] = dci[2];
    dci_flip[2] = dci[1];
246
247
    dci_flip[3] = dci[0];
  } else {
248
249
250
251
252
253
254
255
    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];
256
#ifdef DEBUG_DCI_ENCODING
257
    printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
258
259
        dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
        dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
260
#endif
261
  }
262

263
264
265
266
267
  dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);

  return(e+coded_bits);
}

gauthier's avatar
gauthier committed
268
uint32_t Y;
269
270
271
272
273
274
275
276

#define CCEBITS 72
#define CCEPERSYMBOL 33  // This is for 1200 RE
#define CCEPERSYMBOL0 22  // This is for 1200 RE
#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS)
#define Msymb (DCI_BITS_MAX/2)
//#define Mquad (Msymb/4)

gauthier's avatar
gauthier committed
277
static uint32_t bitrev_cc_dci[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30};
278
static int32_t wtemp[2][Msymb];
279

280
void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
281
{
282

283
  int32_t *wptr,*wptr2,*zptr;
gauthier's avatar
gauthier committed
284
285
286
287
  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;
288
#ifdef RM_DEBUG
gauthier's avatar
gauthier committed
289
  int32_t nulled=0;
290
#endif
291

292
  //  printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
293
294
  if ((Mquad&0x1f) > 0)
    RCC++;
295

296
297
298
299
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
300
301

  for (col=0; col<32; col++) {
302
303
    index = bitrev_cc_dci[col];

304
    for (row=0; row<RCC; row++) {
305
      //printf("col %d, index %d, row %d\n",col,index,row);
306
      if (index>=ND) {
Xiwen JIANG's avatar
Xiwen JIANG committed
307
        for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
308
          //printf("a %d k %d\n",a,k);
309
310
311

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

313
          //printf("wptr=%p, zptr=%p\n",wptr,zptr);
314

315
316
317
318
319
          wptr[0] = zptr[0];
          wptr[1] = zptr[1];
          wptr[2] = zptr[2];
          wptr[3] = zptr[3];
        }
320

321
        k++;
322
      }
323

324
325
326
327
328
      index+=32;
    }
  }

  // permutation
329
330
  for (i=0; i<Mquad; i++) {

Xiwen JIANG's avatar
Xiwen JIANG committed
331
    for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) {
332
333
334
335
336
337
338
339
340
341
342
343
344

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

345
346
void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi)
{
347

gauthier's avatar
gauthier committed
348
349
350
  uint32_t i, lprime;
  uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0;
  int16_t re_offset,re_offset0;
351
352
353
354
355
356
357
358
359

  // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5

  int Msymb2;

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

361
362
363
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
364

365
366
367
  case 50:
    Msymb2 = Msymb>>1;
    break;
368

369
370
371
  case 25:
    Msymb2 = Msymb>>2;
    break;
372

373
374
375
  case 15:
    Msymb2 = Msymb*15/100;
    break;
376

377
378
379
  case 6:
    Msymb2 = Msymb*6/100;
    break;
380

381
382
383
384
  default:
    Msymb2 = Msymb>>2;
    break;
  }
385

386
387
388
389
390
  mprime=0;


  re_offset = 0;
  re_offset0 = 0; // counter for symbol with pilots (extracted outside!)
391
392
393

  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
394

gauthier's avatar
gauthier committed
395
      symbol_offset = (uint32_t)frame_parms->N_RB_DL*12*lprime;
396

397
398
      tti_offset = symbol_offset + re_offset;
      tti_offset0 = symbol_offset + re_offset0;
399

400
401
      // if REG is allocated to PHICH, skip it
      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
402
403
404
	//        printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime);
	if ((lprime == 0)&&((kprime%6)==0))
	  re_offset0+=4;
405
      } else { // not allocated to PHICH/PCFICH
406
	//        printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
407
408
409
410
411
412
413
414
415
        if (lprime == 0) {
          // 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<4; i++) {
              wbar[mprime] = llr[tti_offset0+i];
416
#ifdef DEBUG_DCI_DECODING
Wilson's avatar
Wilson committed
417
              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
418
#endif
419
420
421
422
              mprime++;
              re_offset0++;
            }
          }
Xiwen JIANG's avatar
Xiwen JIANG committed
423
        } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) {
424
425
426
427
428
429
430
431
          // LATER!!!!
        } else { // no pilots in this symbol
          kprime_mod12 = kprime%12;

          if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) {
            // kprime represents REG
            for (i=0; i<4; i++) {
              wbar[mprime] = llr[tti_offset+i];
432
#ifdef DEBUG_DCI_DECODING
Wilson's avatar
Wilson committed
433
              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
434
#endif
435
436
437
438
              mprime++;
            }
          }  // is representative
        } // no pilots case
439
440
441
442
      } // not allocated to PHICH/PCFICH

      // Stop when all REGs are copied in
      if (mprime>=Msymb2)
443
        break;
444
    } //lprime loop
445

446
447
448
449
450
    re_offset++;

  } // kprime loop
}

gauthier's avatar
gauthier committed
451
static uint16_t wtemp_rx[Msymb];
452
453
void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi)
{
454

gauthier's avatar
gauthier committed
455
  uint16_t *wptr,*zptr,*wptr2;
456

gauthier's avatar
gauthier committed
457
458
459
460
  uint16_t Mquad=get_nquad(number_pdcch_symbols,frame_parms,mi);
  uint32_t RCC = (Mquad>>5), ND;
  uint32_t row,col,Kpi,index;
  int32_t i,k;
461
462
463
464


  //  printf("Mquad %d, RCC %d\n",Mquad,RCC);

465
  AssertFatal(z!=NULL,"dci.c: pdcch_deinterleaving: FATAL z is Null\n");
466

467
  // undo permutation
468
  for (i=0; i<Mquad; i++) {
469
470
471
472
473
474
475
    wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2];
    wptr2 = &wbar[i<<2];

    wptr[0] = wptr2[0];
    wptr[1] = wptr2[1];
    wptr[2] = wptr2[2];
    wptr[3] = wptr2[3];
476
477
478
479
480
481
482
483
484
485
    /*    
    printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad,
	   ((char*)wptr2)[0],
	   ((char*)wptr2)[1],
	   ((char*)wptr2)[2],
	   ((char*)wptr2)[3],
	   ((char*)wptr2)[4],
	   ((char*)wptr2)[5],
	   ((char*)wptr2)[6],
	   ((char*)wptr2)[7]);
486
    */
487
488
489
490
491

  }

  if ((Mquad&0x1f) > 0)
    RCC++;
492

493
494
495
496
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
497
498

  for (col=0; col<32; col++) {
499
500
    index = bitrev_cc_dci[col];

501
    for (row=0; row<RCC; row++) {
502
503
504
505
506
      //      printf("row %d, index %d, Nd %d\n",row,index,ND);
      if (index>=ND) {



507
508
509
510
511
512
513
514
        wptr = &wtemp_rx[k<<2];
        zptr = &z[(index-ND)<<2];

        zptr[0] = wptr[0];
        zptr[1] = wptr[1];
        zptr[2] = wptr[2];
        zptr[3] = wptr[3];

515
	/*        
516
517
518
519
520
521
522
523
524
        printf("deinterleaving ; k %d, index-Nd %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND),
               ((int8_t *)wptr)[0],
               ((int8_t *)wptr)[1],
               ((int8_t *)wptr)[2],
               ((int8_t *)wptr)[3],
               ((int8_t *)wptr)[4],
               ((int8_t *)wptr)[5],
               ((int8_t *)wptr)[6],
               ((int8_t *)wptr)[7]);
525
	*/
526
        k++;
527
      }
528

529
      index+=32;
530

531
532
533
    }
  }

534
  for (i=0; i<Mquad; i++) {
535
    zptr = &z[i<<2];
536
    /*    
537
    printf("deinterleaving ; quad %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
538
539
540
541
542
543
544
545
     ((int8_t *)zptr)[0],
     ((int8_t *)zptr)[1],
     ((int8_t *)zptr)[2],
     ((int8_t *)zptr)[3],
     ((int8_t *)zptr)[4],
     ((int8_t *)zptr)[5],
     ((int8_t *)zptr)[6],
     ((int8_t *)zptr)[7]);
546
    */  
547
  }
548

549
550
551
}


gauthier's avatar
gauthier committed
552
int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
553
554
555
556
557
558
559
                            int32_t **rxdataF_comp,
                            int32_t **rxdataF_comp_i,
                            int32_t **rho_i,
                            int16_t *pdcch_llr16,
                            int16_t *pdcch_llr8in,
                            uint8_t symbol)
{
560

561
562
563
564
  int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
  int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
  int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
  int16_t *llr128;
gauthier's avatar
gauthier committed
565
  int32_t i;
566
  char *pdcch_llr8;
gauthier's avatar
gauthier committed
567
  int16_t *pdcch_llr;
568
569
570
571
  pdcch_llr8 = (char *)&pdcch_llr8in[symbol*frame_parms->N_RB_DL*12];
  pdcch_llr = &pdcch_llr16[symbol*frame_parms->N_RB_DL*12];

  //  printf("dlsch_qpsk_qpsk: symbol %d\n",symbol);
572

573
  llr128 = (int16_t*)pdcch_llr;
574
575

  if (!llr128) {
576
    printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
577
578
579
    return -1;
  }

580
581
582
583
  qpsk_qpsk(rxF,
            rxF_i,
            llr128,
            rho,
584
            frame_parms->N_RB_DL*12);
585
586

  //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input.
587
  for (i=0; i<(frame_parms->N_RB_DL*24); i++) {
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    if (*pdcch_llr>7)
      *pdcch_llr8=7;
    else if (*pdcch_llr<-8)
      *pdcch_llr8=-8;
    else
      *pdcch_llr8 = (char)(*pdcch_llr);

    pdcch_llr++;
    pdcch_llr8++;
  }

  return(0);
}


gauthier's avatar
gauthier committed
603
int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
604
605
606
607
                  int32_t **rxdataF_comp,
                  char *pdcch_llr,
                  uint8_t symbol)
{
608

gauthier's avatar
gauthier committed
609
610
  int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
  int32_t i;
611
612
613
  char *pdcch_llr8;

  pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12];
614

615
  if (!pdcch_llr8) {
616
    printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
617
618
    return(-1);
  }
619

620
  //    printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);
621

622
  for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) {
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

    if (*rxF>31)
      *pdcch_llr8=31;
    else if (*rxF<-32)
      *pdcch_llr8=-32;
    else
      *pdcch_llr8 = (char)(*rxF);

    //    printf("%d %d => %d\n",i,*rxF,*pdcch_llr8);
    rxF++;
    pdcch_llr8++;
  }

  return(0);

}

640
//__m128i avg128P;
641
642

//compute average channel_level on each (TX,RX) antenna pair
gauthier's avatar
gauthier committed
643
void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
644
645
646
647
                         LTE_DL_FRAME_PARMS *frame_parms,
                         int32_t *avg,
                         uint8_t nb_rb)
{
648

gauthier's avatar
gauthier committed
649
650
  int16_t rb;
  uint8_t aatx,aarx;
651
#if defined(__x86_64__) || defined(__i386__)
652
  __m128i *dl_ch128;
653
654
655
656
657
  __m128i avg128P;
#elif defined(__arm__)
  int16x8_t *dl_ch128;
  int32x4_t *avg128P;
#endif
Xiwen JIANG's avatar
Xiwen JIANG committed
658
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
659
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
660
      //clear average level
661
#if defined(__x86_64__) || defined(__i386__)
662
      avg128P = _mm_setzero_si128();
663
      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
664
#elif defined(__arm__)
665

666
#endif
667
668
      for (rb=0; rb<nb_rb; rb++) {

669
#if defined(__x86_64__) || defined(__i386__)
670
671
672
        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
        avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
673
#elif defined(__arm__)
674

675
#endif
676
677
678
679
680
681
682
683
        dl_ch128+=3;
        /*
          if (rb==0) {
          print_shorts("dl_ch128",&dl_ch128[0]);
          print_shorts("dl_ch128",&dl_ch128[1]);
          print_shorts("dl_ch128",&dl_ch128[2]);
          }
        */
684
685
      }

686
      DevAssert( nb_rb );
687
688
689
690
      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] +
                             ((int32_t*)&avg128P)[1] +
                             ((int32_t*)&avg128P)[2] +
                             ((int32_t*)&avg128P)[3])/(nb_rb*12);
691

692
      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
693
    }
694

695
#if defined(__x86_64__) || defined(__i386__)
696
697
  _mm_empty();
  _m_empty();
698
#endif
699
700
701

}

702
#if defined(__x86_64) || defined(__i386__)
703
__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
704
#elif defined(__arm__)
705

706
#endif
707
void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
708
709
710
711
712
713
                                   uint8_t symbol,
                                   int32_t **dl_ch_estimates_ext,
                                   int32_t **dl_ch_estimates_ext_i,
                                   int32_t **dl_ch_rho_ext,
                                   uint8_t output_shift)
{
714

gauthier's avatar
gauthier committed
715
  uint16_t rb;
716
#if defined(__x86_64__) || defined(__i386__)
717
  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128;
718
719
720
#elif defined(__arm__)

#endif
gauthier's avatar
gauthier committed
721
  uint8_t aarx;
722
723
724
725

  //  printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);


726
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
727

728
#if defined(__x86_64__) || defined(__i386__)
729
730
731
732
    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch128i         = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12];
    dl_ch_rho128      = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12];

733
734
735
#elif defined(__arm__)

#endif
736

737
    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
738
      // multiply by conjugated channel
739
#if defined(__x86_64__) || defined(__i386__)
740
      mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
741
742
      //  print_ints("re",&mmtmpPD0);

743
744
745
746
      // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]);
747
      //  print_ints("im",&mmtmpPD1);
748
749
750
      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[0]);
      // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
751
      //  print_ints("re(shift)",&mmtmpPD0);
752
      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
753
      //  print_ints("im(shift)",&mmtmpPD1);
754
755
      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
756
757
      //        print_ints("c0",&mmtmpPD2);
      //  print_ints("c1",&mmtmpPD3);
758
      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
759

760
761
762
      //print_shorts("rx:",dl_ch128_2);
      //print_shorts("ch:",dl_ch128);
      //print_shorts("pack:",rho128);
763

764
765
766
767
768
769
770
771
772
773
774
775
      // multiply by conjugated channel
      mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]);
      // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[1]);
      // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
776
777


778
779
780
      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
      //print_shorts("rx:",dl_ch128_2+1);
      //print_shorts("ch:",dl_ch128+1);
781
      //print_shorts("pack:",rho128+1);
782
783
784
785
786
787
788
789
790
791
792
793
      // multiply by conjugated channel
      mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]);
      // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1));
      mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate);
      mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[2]);
      // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
794

795
796
797
798
      dl_ch_rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
      //print_shorts("rx:",dl_ch128_2+2);
      //print_shorts("ch:",dl_ch128+2);
      //print_shorts("pack:",rho128+2);
799

800
801
802
      dl_ch128+=3;
      dl_ch128i+=3;
      dl_ch_rho128+=3;
803
804


805
#elif defined(__arm__)
806

807
808
809
810
#endif
     }
  }
#if defined(__x86_64__) || defined(__i386__)
811
812
  _mm_empty();
  _m_empty();
813
#endif
814

815
816
817
818
}


void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms,
819
820
821
822
823
824
                           int32_t **rxdataF_comp,
                           int32_t **rxdataF_comp_i,
                           int32_t **rho,
                           int32_t **rho_i,
                           uint8_t symbol)
{
825

gauthier's avatar
gauthier committed
826
  uint8_t aatx;
827

828
#if defined(__x86_64__) || defined(__i386__)
829
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
830
831
832
#elif defined(__arm__)
  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
#endif
gauthier's avatar
gauthier committed
833
  int32_t i;
834
835

  if (frame_parms->nb_antennas_rx>1) {
Xiwen JIANG's avatar
Xiwen JIANG committed
836
    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
837
838
      //if (frame_parms->mode1_flag && (aatx>0)) break;

839
#if defined(__x86_64__) || defined(__i386__)
840
      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
841
      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
842
843
844
845
#elif defined(__arm__)
      rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
#endif
846
      // MRC on each re of rb on MF output
847
      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
848
#if defined(__x86_64__) || defined(__i386__)
849
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
850
851
852
#elif defined(__arm__)
        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
853
854
      }
    }
855

856
#if defined(__x86_64__) || defined(__i386__)
857
858
    rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
    rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
859
860
861
862
#elif defined(__arm__)
    rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12];
    rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12];
#endif
863
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
864
#if defined(__x86_64__) || defined(__i386__)
865
      rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
866
867
868
#elif defined(__arm__)
      rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
#endif
869
    }
870

871
#if defined(__x86_64__) || defined(__i386__)
872
873
    rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
    rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
874
    rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
875
    rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
876
877
878
879
880
#elif defined(__arm__)
    rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
    rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp128_i0   = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp128_i1   = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
881

882
#endif
883
884
    // MRC on each re of rb on MF and rho
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
885
#if defined(__x86_64__) || defined(__i386__)
886
887
      rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
      rho128_i0[i]          = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
888
889
890
891
892
#elif defined(__arm__)
      rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]);
      rho128_i0[i]          = vhaddq_s16(rho128_i0[i],rho128_i1[i]);

#endif
893
894
    }
  }
895

896
#if defined(__x86_64__) || defined(__i386__)
897
898
  _mm_empty();
  _m_empty();
899
#endif
900
901
902
}


gauthier's avatar
gauthier committed
903
void pdcch_extract_rbs_single(int32_t **rxdataF,
904
905
906
907
908
909
910
                              int32_t **dl_ch_estimates,
                              int32_t **rxdataF_ext,
                              int32_t **dl_ch_estimates_ext,
                              uint8_t symbol,
                              uint32_t high_speed_flag,
                              LTE_DL_FRAME_PARMS *frame_parms)
{
911
912


gauthier's avatar
gauthier committed
913
914
915
  uint16_t rb,nb_rb=0;
  uint8_t i,j,aarx;
  int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
916

917
918

  int nushiftmod3 = frame_parms->nushift%3;
gauthier's avatar
gauthier committed
919
  uint8_t symbol_mod;
920
921
922

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
923
  LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
924
#endif
925
926

  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
927
928
929
930
931

    if (high_speed_flag == 1)
      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
    else
      dl_ch0     = &dl_ch_estimates[aarx][5];
932

933
934
935
936
937
    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];

    rxF_ext   = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];

    rxF       = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
knopp's avatar
   
knopp committed
938

939
    if ((frame_parms->N_RB_DL&1) == 0)  { // even number of RBs
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
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

        // For second half of RBs skip DC carrier
        if (rb==(frame_parms->N_RB_DL>>1)) {
          rxF       = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))];

          //dl_ch0++;
        }

        if (symbol_mod>0) {
          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));

          for (i=0; i<12; i++) {

            rxF_ext[i]=rxF[i];

          }

          nb_rb++;
          dl_ch0_ext+=12;
          rxF_ext+=12;

          dl_ch0+=12;
          rxF+=12;
        } else {
          j=0;

          for (i=0; i<12; i++) {
            if ((i!=nushiftmod3) &&
                (i!=(nushiftmod3+3)) &&
                (i!=(nushiftmod3+6)) &&
                (i!=(nushiftmod3+9))) {
              rxF_ext[j]=rxF[i];
              //                        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
              dl_ch0_ext[j++]=dl_ch0[i];
              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
            }
          }

          nb_rb++;
          dl_ch0_ext+=8;
          rxF_ext+=8;

          dl_ch0+=12;
          rxF+=12;
        }
986
      }
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
    } else { // Odd number of RBs
      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {

        if (symbol_mod>0) {
          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));

          for (i=0; i<12; i++)
            rxF_ext[i]=rxF[i];

          nb_rb++;
          dl_ch0_ext+=12;
          rxF_ext+=12;

          dl_ch0+=12;
          rxF+=12;
        } else {
          j=0;

          for (i=0; i<12; i++) {
            if ((i!=nushiftmod3) &&
                (i!=(nushiftmod3+3)) &&
                (i!=(nushiftmod3+6)) &&
                (i!=(nushiftmod3+9))) {
              rxF_ext[j]=rxF[i];
              //                        printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]));
              dl_ch0_ext[j++]=dl_ch0[i];
              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
            }
          }

          nb_rb++;
          dl_ch0_ext+=8;
          rxF_ext+=8;

          dl_ch0+=12;
          rxF+=12;
        }
1024
      }
1025

1026
      // Do middle RB (around DC)
1027
      //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
1028
1029

      if (symbol_mod==0) {
1030
1031
1032
1033
1034
1035
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
        j=0;

        for (i=0; i<6; i++) {
          if ((i!=nushiftmod3) &&
              (i!=(nushiftmod3+3))) {
            dl_ch0_ext[j]=dl_ch0[i];
            rxF_ext[j++]=rxF[i];
            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
          }
        }

        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];

        for (; i<12; i++) {
          if ((i!=(nushiftmod3+6)) &&
              (i!=(nushiftmod3+9))) {
            dl_ch0_ext[j]=dl_ch0[i];
            rxF_ext[j++]=rxF[(1+i-6)];
            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
          }
        }


        nb_rb++;
        dl_ch0_ext+=8;
        rxF_ext+=8;
        dl_ch0+=12;
        rxF+=7;
        rb++;
      } else {
        for (i=0; i<6; i++) {
          dl_ch0_ext[i]=dl_ch0[i];
          rxF_ext[i]=rxF[i];
        }

        rxF       = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))];

        for (; i<12; i++) {
          dl_ch0_ext[i]=dl_ch0[i];
          rxF_ext[i]=rxF[(1+i-6)];
        }


        nb_rb++;
        dl_ch0_ext+=12;
        rxF_ext+=12;
        dl_ch0+=12;
        rxF+=7;
        rb++;
1079
1080
      }

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108