dci.c 126 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" 
44
45
46
47

//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
48

49
50
//#undef ALL_AGGREGATION

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

54
55
uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi)
{
56

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

  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)||
      ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4)))
    mprime = kprime/6;
  else
    mprime = kprime>>2;

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

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



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

111
112
113
  return(0);
}

114
115
uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
{
116

gauthier's avatar
gauthier committed
117
118
  uint16_t crc16;
  //  uint8_t i;
119
120

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

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

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



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

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


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

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

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

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

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

#ifdef DEBUG_DCI_ENCODING
187
188

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

191
#endif
192

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

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


}


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

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

  if (aggregation_level>3) {
218
    printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
219
220
221
222
223
    return NULL;
  }

  coded_bits = 72 * (1<<aggregation_level);

224
225
226
  /*

  #ifdef DEBUG_DCI_ENCODING
227
  for (i=0;i<1+((DCI_LENGTH+16)/8);i++)
228
    printf("i %d : %x\n",i,dci[i]);
229
  #endif
230
  */
231
  if (DCI_LENGTH<=32) {
232
233
234
    dci_flip[0] = dci[3];
    dci_flip[1] = dci[2];
    dci_flip[2] = dci[1];
235
236
    dci_flip[3] = dci[0];
  } else {
237
238
239
240
241
242
243
244
    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];
245
#ifdef DEBUG_DCI_ENCODING
246
    printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
247
248
        dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
        dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
249
#endif
250
  }
251

252
253
254
255
256
  dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);

  return(e+coded_bits);
}

gauthier's avatar
gauthier committed
257
uint32_t Y;
258
259
260
261
262
263
264
265

#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
266
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};
267
static int32_t wtemp[2][Msymb];
268

269
void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
270
{
271

272
  int32_t *wptr,*wptr2,*zptr;
gauthier's avatar
gauthier committed
273
274
275
276
  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;
277
#ifdef RM_DEBUG
gauthier's avatar
gauthier committed
278
  int32_t nulled=0;
279
#endif
280

281
  //  printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
282
283
  if ((Mquad&0x1f) > 0)
    RCC++;
284

285
286
287
288
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
289
290

  for (col=0; col<32; col++) {
291
292
    index = bitrev_cc_dci[col];

293
    for (row=0; row<RCC; row++) {
294
      //printf("col %d, index %d, row %d\n",col,index,row);
295
      if (index>=ND) {
296
        for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
297
          //printf("a %d k %d\n",a,k);
298
299
300

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

302
          //printf("wptr=%p, zptr=%p\n",wptr,zptr);
303

304
305
306
307
308
          wptr[0] = zptr[0];
          wptr[1] = zptr[1];
          wptr[2] = zptr[2];
          wptr[3] = zptr[3];
        }
309

310
        k++;
311
      }
312

313
314
315
316
317
      index+=32;
    }
  }

  // permutation
318
319
320
  for (i=0; i<Mquad; i++) {

    for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
321
322
323
324
325
326
327
328
329
330
331
332
333

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

334
335
void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi)
{
336

gauthier's avatar
gauthier committed
337
338
339
  uint32_t i, lprime;
  uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0;
  int16_t re_offset,re_offset0;
340
341
342
343
344
345
346
347
348

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

350
351
352
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
353

354
355
356
  case 50:
    Msymb2 = Msymb>>1;
    break;
357

358
359
360
  case 25:
    Msymb2 = Msymb>>2;
    break;
361

362
363
364
  case 15:
    Msymb2 = Msymb*15/100;
    break;
365

366
367
368
  case 6:
    Msymb2 = Msymb*6/100;
    break;
369

370
371
372
373
  default:
    Msymb2 = Msymb>>2;
    break;
  }
374

375
376
377
378
379
  mprime=0;


  re_offset = 0;
  re_offset0 = 0; // counter for symbol with pilots (extracted outside!)
380
381
382

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

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

386
387
      tti_offset = symbol_offset + re_offset;
      tti_offset0 = symbol_offset + re_offset0;
388

389
390
      // if REG is allocated to PHICH, skip it
      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
391
392
393
	//        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;
394
      } else { // not allocated to PHICH/PCFICH
395
	//        printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
396
397
398
399
400
401
402
403
404
        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];
405
#ifdef DEBUG_DCI_DECODING
406
              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]));
407
#endif
408
409
410
411
412
413
414
415
416
417
418
419
420
              mprime++;
              re_offset0++;
            }
          }
        } else if ((lprime==1)&&(frame_parms->nb_antennas_tx_eNB == 4)) {
          // 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];
421
#ifdef DEBUG_DCI_DECODING
422
              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]));
423
#endif
424
425
426
427
              mprime++;
            }
          }  // is representative
        } // no pilots case
428
429
430
431
      } // not allocated to PHICH/PCFICH

      // Stop when all REGs are copied in
      if (mprime>=Msymb2)
432
        break;
433
    } //lprime loop
434

435
436
437
438
439
    re_offset++;

  } // kprime loop
}

gauthier's avatar
gauthier committed
440
static uint16_t wtemp_rx[Msymb];
441
442
void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi)
{
443

gauthier's avatar
gauthier committed
444
  uint16_t *wptr,*zptr,*wptr2;
445

gauthier's avatar
gauthier committed
446
447
448
449
  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;
450
451
452
453
454


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

  if (!z) {
455
    printf("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
456
457
    return;
  }
458

459
  // undo permutation
460
  for (i=0; i<Mquad; i++) {
461
462
463
464
465
466
467
    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];
468
469
470
471
472
473
474
475
476
477
    /*    
    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]);
478
    */
479
480
481
482
483

  }

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

485
486
487
488
  Kpi = (RCC<<5);
  ND = Kpi - Mquad;

  k=0;
489
490

  for (col=0; col<32; col++) {
491
492
    index = bitrev_cc_dci[col];

493
    for (row=0; row<RCC; row++) {
494
495
496
497
498
      //      printf("row %d, index %d, Nd %d\n",row,index,ND);
      if (index>=ND) {



499
500
501
502
503
504
505
506
        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];

507
	/*        
508
509
510
511
512
513
514
515
516
        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]);
517
	*/
518
        k++;
519
      }
520

521
      index+=32;
522

523
524
525
    }
  }

526
  for (i=0; i<Mquad; i++) {
527
    zptr = &z[i<<2];
528
    /*    
529
    printf("deinterleaving ; quad %d  => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
530
531
532
533
534
535
536
537
     ((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]);
538
    */  
539
  }
540

541
542
543
}


gauthier's avatar
gauthier committed
544
int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
545
546
547
548
549
550
551
                            int32_t **rxdataF_comp,
                            int32_t **rxdataF_comp_i,
                            int32_t **rho_i,
                            int16_t *pdcch_llr16,
                            int16_t *pdcch_llr8in,
                            uint8_t symbol)
{
552

553
554
555
556
  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
557
  int32_t i;
558
  char *pdcch_llr8;
gauthier's avatar
gauthier committed
559
  int16_t *pdcch_llr;
560
561
562
563
  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);
564

565
  llr128 = (int16_t*)pdcch_llr;
566
567

  if (!llr128) {
568
    printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
569
570
571
    return -1;
  }

572
573
574
575
  qpsk_qpsk(rxF,
            rxF_i,
            llr128,
            rho,
576
            frame_parms->N_RB_DL*12);
577
578

  //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input.
579
  for (i=0; i<(frame_parms->N_RB_DL*24); i++) {
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
    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
595
int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
596
597
598
599
                  int32_t **rxdataF_comp,
                  char *pdcch_llr,
                  uint8_t symbol)
{
600

gauthier's avatar
gauthier committed
601
602
  int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
  int32_t i;
603
604
605
  char *pdcch_llr8;

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

607
  if (!pdcch_llr8) {
608
    printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
609
610
    return(-1);
  }
611

612
  //    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);
613

614
  for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) {
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

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

}

632
//__m128i avg128P;
633
634

//compute average channel_level on each (TX,RX) antenna pair
gauthier's avatar
gauthier committed
635
void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
636
637
638
639
                         LTE_DL_FRAME_PARMS *frame_parms,
                         int32_t *avg,
                         uint8_t nb_rb)
{
640

gauthier's avatar
gauthier committed
641
642
  int16_t rb;
  uint8_t aatx,aarx;
643
#if defined(__x86_64__) || defined(__i386__)
644
  __m128i *dl_ch128;
645
646
647
648
649
  __m128i avg128P;
#elif defined(__arm__)
  int16x8_t *dl_ch128;
  int32x4_t *avg128P;
#endif
650
651
  for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
652
      //clear average level
653
#if defined(__x86_64__) || defined(__i386__)
654
      avg128P = _mm_setzero_si128();
655
      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
656
#elif defined(__arm__)
657

658
#endif
659
660
      for (rb=0; rb<nb_rb; rb++) {

661
#if defined(__x86_64__) || defined(__i386__)
662
663
664
        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]));
665
#elif defined(__arm__)
666

667
#endif
668
669
670
671
672
673
674
675
        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]);
          }
        */
676
677
      }

678
      DevAssert( nb_rb );
679
680
681
682
      avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] +
                             ((int32_t*)&avg128P)[1] +
                             ((int32_t*)&avg128P)[2] +
                             ((int32_t*)&avg128P)[3])/(nb_rb*12);
683

684
      //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
685
    }
686

687
#if defined(__x86_64__) || defined(__i386__)
688
689
  _mm_empty();
  _m_empty();
690
#endif
691
692
693

}

694
#if defined(__x86_64) || defined(__i386__)
695
__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
696
#elif defined(__arm__)
697

698
#endif
699
void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
700
701
702
703
704
705
                                   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)
{
706

gauthier's avatar
gauthier committed
707
  uint16_t rb;
708
#if defined(__x86_64__) || defined(__i386__)
709
  __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128;
710
711
712
#elif defined(__arm__)

#endif
gauthier's avatar
gauthier committed
713
  uint8_t aarx;
714
715
716
717

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


718
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
719

720
#if defined(__x86_64__) || defined(__i386__)
721
722
723
724
    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];

725
726
727
#elif defined(__arm__)

#endif
728

729
    for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
730
      // multiply by conjugated channel
731
#if defined(__x86_64__) || defined(__i386__)
732
      mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
733
734
      //  print_ints("re",&mmtmpPD0);

735
736
737
738
      // 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]);
739
      //  print_ints("im",&mmtmpPD1);
740
741
742
      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);
743
      //  print_ints("re(shift)",&mmtmpPD0);
744
      mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
745
      //  print_ints("im(shift)",&mmtmpPD1);
746
747
      mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
      mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
748
749
      //        print_ints("c0",&mmtmpPD2);
      //  print_ints("c1",&mmtmpPD3);
750
      dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
751

752
753
754
      //print_shorts("rx:",dl_ch128_2);
      //print_shorts("ch:",dl_ch128);
      //print_shorts("pack:",rho128);
755

756
757
758
759
760
761
762
763
764
765
766
767
      // 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);
768
769


770
771
772
      dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
      //print_shorts("rx:",dl_ch128_2+1);
      //print_shorts("ch:",dl_ch128+1);
773
      //print_shorts("pack:",rho128+1);
774
775
776
777
778
779
780
781
782
783
784
785
      // 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);
786

787
788
789
790
      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);
791

792
793
794
      dl_ch128+=3;
      dl_ch128i+=3;
      dl_ch_rho128+=3;
795
796


797
#elif defined(__arm__)
798

799
800
801
802
#endif
     }
  }
#if defined(__x86_64__) || defined(__i386__)
803
804
  _mm_empty();
  _m_empty();
805
#endif
806

807
808
809
810
}


void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms,
811
812
813
814
815
816
                           int32_t **rxdataF_comp,
                           int32_t **rxdataF_comp_i,
                           int32_t **rho,
                           int32_t **rho_i,
                           uint8_t symbol)
{
817

gauthier's avatar
gauthier committed
818
  uint8_t aatx;
819

820
#if defined(__x86_64__) || defined(__i386__)
821
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
822
823
824
#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
825
  int32_t i;
826
827

  if (frame_parms->nb_antennas_rx>1) {
828
    for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
829
830
      //if (frame_parms->mode1_flag && (aatx>0)) break;

831
#if defined(__x86_64__) || defined(__i386__)
832
      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
833
      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
834
835
836
837
#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
838
      // MRC on each re of rb on MF output
839
      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
840
#if defined(__x86_64__) || defined(__i386__)
841
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
842
843
844
#elif defined(__arm__)
        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
845
846
      }
    }
847

848
#if defined(__x86_64__) || defined(__i386__)
849
850
    rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
    rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
851
852
853
854
#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
855
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
856
#if defined(__x86_64__) || defined(__i386__)
857
      rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
858
859
860
#elif defined(__arm__)
      rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
#endif
861
    }
862

863
#if defined(__x86_64__) || defined(__i386__)
864
865
    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];
866
    rxdataF_comp128_i0   = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
867
    rxdataF_comp128_i1   = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
868
869
870
871
872
#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];
873

874
#endif
875
876
    // MRC on each re of rb on MF and rho
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
877
#if defined(__x86_64__) || defined(__i386__)
878
879
      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));
880
881
882
883
884
#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
885
886
    }
  }
887

888
#if defined(__x86_64__) || defined(__i386__)
889
890
  _mm_empty();
  _m_empty();
891
#endif
892
893
894
}


gauthier's avatar
gauthier committed
895
void pdcch_extract_rbs_single(int32_t **rxdataF,
896
897
898
899
900
901
902
                              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)
{
903
904


gauthier's avatar
gauthier committed
905
906
907
  uint16_t rb,nb_rb=0;
  uint8_t i,j,aarx;
  int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
908

909
910

  int nushiftmod3 = frame_parms->nushift%3;
gauthier's avatar
gauthier committed
911
  uint8_t symbol_mod;
912
913
914

  symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
915
  LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
916
#endif
917
918

  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
919
920
921
922
923

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

925
926
927
928
929
    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
930

931
    if ((frame_parms->N_RB_DL&1) == 0)  { // even number of RBs
932
933
934
935
936
937
938
939
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
      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;
        }
978
      }
979
980
981
982
983
984
985
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
    } 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;
        }
1016
      }
1017

1018
      // Do middle RB (around DC)
1019
      //  printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
1020
1021

      if (symbol_mod==0) {
1022
1023
1024
1025
1026
1027
1028
1029
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
        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++;
1071
1072
      }

1073
1074
1075
1076
1077
1078
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
      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;
        }
1107
1108
1109
1110
1111
      }
    }
  }
}

gauthier's avatar
gauthier committed
1112
void pdcch_extract_rbs_dual(int32_t **rxdataF,
1113
1114
1115
1116
1117
1118
1119
1120
                            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)
{

1121