dci.c 141 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
#include "UTIL/LOG/vcd_signal_dumper.h"
47
48
49
50

//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
51

52
53
//#undef ALL_AGGREGATION

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

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

gauthier's avatar
gauthier committed
60
61
62
63
  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;
64
65
66
67
68
69
70
71

  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
72
      ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)))
73
74
75
76
77
    mprime = kprime/6;
  else
    mprime = kprime>>2;

  // check if PCFICH uses mprime
78
  if ((lprime==0) &&
79
80
81
82
83
      ((mprime == pcfich_reg[0]) ||
       (mprime == pcfich_reg[1]) ||
       (mprime == pcfich_reg[2]) ||
       (mprime == pcfich_reg[3]))) {
#ifdef DEBUG_DCI_ENCODING
84
    printf("[PHY] REG %d allocated to PCFICH\n",mprime);
85
86
87
88
89
90
91
92
93
94
#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++;
95

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



    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]))  {
106
#ifdef DEBUG_DCI_ENCODING
107
        printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
108
#endif
109
        return(1);
110
111
112
      }
    }
  }
113

114
115
116
  return(0);
}

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

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

  /*
gauthier's avatar
gauthier committed
124
125
  uint8_t crc;
  crc = ((uint16_t *)dci)[DCI_LENGTH>>4];
126
127
128
  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
129
130
131
  ((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));
132
  // clear crc bits
gauthier's avatar
gauthier committed
133
  (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0;
134
135
  printf("extract_crc: crc %x\n",crc);
  */
136
#ifdef DEBUG_DCI_DECODING
137
  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)],
138
      dci_len&0x7);
139
#endif
140

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

149
#ifdef DEBUG_DCI_DECODING
150
  LOG_I(PHY,"dci_crc =>%x\n",crc16);
151
152
153
154
155
#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
156
  return((uint16_t)crc16);
157
  
158
159
160
161
}



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

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


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

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

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

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

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

#ifdef DEBUG_DCI_ENCODING
190
191

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

194
#endif
195

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

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


}


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

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

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

234
  coded_bits = 72 * aggregation_level;
235

236
237
238
  /*

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

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

  return(e+coded_bits);
}

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

#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
278
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};
279
static int32_t wtemp[2][Msymb];
280

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

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

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

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

  k=0;
301
302

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

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

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

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

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

322
        k++;
323
      }
324

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

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

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

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

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

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

  // 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;
361

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

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

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

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

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

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

387
388
389
390
391
  mprime=0;


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

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

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

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

401
402
      // if REG is allocated to PHICH, skip it
      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
403
404
405
	//        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;
406
      } else { // not allocated to PHICH/PCFICH
407
	//        printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
408
409
410
411
412
413
414
415
416
        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];
417
#ifdef DEBUG_DCI_DECODING
418
//              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]));
419
#endif
420
421
422
423
              mprime++;
              re_offset0++;
            }
          }
Xiwen JIANG's avatar
Xiwen JIANG committed
424
        } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) {
425
426
427
428
429
430
431
432
          // 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];
433
#ifdef DEBUG_DCI_DECODING
434
//              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]));
435
#endif
436
437
438
439
              mprime++;
            }
          }  // is representative
        } // no pilots case
440
441
442
443
      } // not allocated to PHICH/PCFICH

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

447
448
449
450
451
    re_offset++;

  } // kprime loop
}

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

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

gauthier's avatar
gauthier committed
458
459
460
461
  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;
462
463
464
465


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

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

468
  // undo permutation
469
  for (i=0; i<Mquad; i++) {
470
471
472
473
474
475
476
    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];
477
478
479
480
481
482
483
484
485
486
    /*    
    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]);
487
    */
488
489
490
491
492

  }

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

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

  k=0;
498
499

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

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



508
509
510
511
512
513
514
515
        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];

516
	/*        
517
518
519
520
521
522
523
524
525
        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]);
526
	*/
527
        k++;
528
      }
529

530
      index+=32;
531

532
533
534
    }
  }

535
  for (i=0; i<Mquad; i++) {
536
    zptr = &z[i<<2];
537
    /*    
538
    printf("deinterleaving ; quad %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
539
540
541
542
543
544
545
546
     ((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]);
547
    */  
548
  }
549

550
551
552
}


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

562
563
564
565
  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
566
  int32_t i;
567
  char *pdcch_llr8;
gauthier's avatar
gauthier committed
568
  int16_t *pdcch_llr;
569
570
571
572
  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);
573

574
  llr128 = (int16_t*)pdcch_llr;
575
576

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

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

  //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input.
588
  for (i=0; i<(frame_parms->N_RB_DL*24); i++) {
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    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
604
int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
605
606
607
608
                  int32_t **rxdataF_comp,
                  char *pdcch_llr,
                  uint8_t symbol)
{
609

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

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

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

621
  //    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);
622

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

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

}

641
//__m128i avg128P;
642
643

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

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

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

670
#if defined(__x86_64__) || defined(__i386__)
671
672
673
        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]));
674
#elif defined(__arm__)
675

676
#endif
677
678
679
680
681
682
683
684
        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]);
          }
        */
685
686
      }

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

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

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

}

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

707
#endif
708
void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
709
710
711
712
713
714
                                   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)
{
715

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

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

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


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

729
#if defined(__x86_64__) || defined(__i386__)
730
731
732
733
    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];

734
735
736
#elif defined(__arm__)

#endif
737

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

744
745
746
747
      // 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]);
748
      //  print_ints("im",&mmtmpPD1);
749
750
751
      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);
752
      //  print_ints("re(shift)",&mmtmpPD0);
753
      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
754
      //  print_ints("im(shift)",&mmtmpPD1);
755
756
      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
757
758
      //        print_ints("c0",&mmtmpPD2);
      //  print_ints("c1",&mmtmpPD3);
759
      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
760

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

765
766
767
768
769
770
771
772
773
774
775
776
      // 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);
777
778


779
780
781
      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
      //print_shorts("rx:",dl_ch128_2+1);
      //print_shorts("ch:",dl_ch128+1);
782
      //print_shorts("pack:",rho128+1);
783
784
785
786
787
788
789
790
791
792
793
794
      // 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);
795

796
797
798
799
      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);
800

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


806
#elif defined(__arm__)
807

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

816
817
818
819
}


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

gauthier's avatar
gauthier committed
827
  uint8_t aatx;
828

829
#if defined(__x86_64__) || defined(__i386__)
830
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
831
832
833
#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
834
  int32_t i;
835
836

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

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

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

872
#if defined(__x86_64__) || defined(__i386__)
873
874
    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];
875
    rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
876
    rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
877
878
879
880
881
#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];
882

883
#endif
884
885
    // MRC on each re of rb on MF and rho
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
886
#if defined(__x86_64__) || defined(__i386__)
887
888
      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));
889
890
891
892
893
#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
894
895
    }
  }
896

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


gauthier's avatar
gauthier committed
904
void pdcch_extract_rbs_single(int32_t **rxdataF,
905
906
907
908
909
910
911
                              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)
{
912
913


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

918
919

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

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

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

    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];
933

934
935
936
937
938
    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
939

940
    if ((frame_parms->N_RB_DL&1) == 0)  { // even number of RBs
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
986
      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;
        }
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
1024
    } 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;
        }
1025
      }
1026

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

      if (symbol_mod==0) {
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
1079
        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++;
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
1109
1110
1111
1112
1113
1114
1115
      for (; rb<frame_parms->N_RB_DL; 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];
            }
          }

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

          dl_ch0+=12;
          rxF+=12;
        }
1116
1117
1118
1119
1120
      }
    }
  }
}

gauthier's avatar
gauthier committed
1121
void pdcch_extract_rbs_dual(int32_t **rxdataF,
1122
1123
1124
1125
1126
1127
1128
1129
                            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)
{

1130

gauthier's avatar
gauthier committed
1131
1132
1133
1134
  uint16_t rb,nb_rb=0;
  uint8_t i,aarx,j;
  int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext;
  uint8_t symbol_mod;
1135
1136
1137
  int nushiftmod3 = frame_parms->nushift%3;

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;