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

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

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

119 120
  uint16_t crc16;
  //  uint8_t i;
121 122

  /*
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
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
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) {
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 {
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;
155
  return((uint16_t)crc16);
156
  
157 158 159 160
}



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

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


172 173
  uint8_t D = (A + 16);
  uint32_t RCC;
174 175

#ifdef DEBUG_DCI_ENCODING
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);


}


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

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

Raymond Knopp's avatar
Raymond Knopp committed
234
  coded_bits = bitsperCCE * 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);
}

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)

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

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

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
}

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

456
  uint16_t *wptr,*zptr,*wptr2;
457

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
}


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;
566
  int32_t i;
567
  char *pdcch_llr8;
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);
}


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

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

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

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

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
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
}


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


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;
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)))];
Raymond Knopp's avatar
 
Raymond 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
      }
    }
  }
}

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

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;
1138 1139 1140
#ifdef DEBUG_DCI_DECODING
  LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod);
#endif
1141

1142
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1143 1144 1145 1146

    if (high_speed_flag==1) {
      dl_ch0     = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
      dl_ch1     = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))];
1147
    } else {
1148 1149 1150
      dl_ch0     = &dl_ch_estimates[aarx][5];
      dl_ch1     = &dl_ch_estimates[2+aarx][5];
    }
1151

1152 1153 1154
    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
    dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];

1155
    //    printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
1156 1157 1158
    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)))];
Raymond Knopp's avatar
 
Raymond Knopp committed
1159

1160
    if ((frame_parms->N_RB_DL&1) == 0)  // even number of RBs
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
      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++;
          //dl_ch1++;
        }

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

          /*
1175
            printf("rb %d\n",rb);
1176
            for (i=0;i<12;i++)
1177 1178
            printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
            printf("\n");
1179 1180 1181
          */
          for (i=0; i<12; i++) {
            rxF_ext[i]=rxF[i];
1182
            //      printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
            //  ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]);
          }

          nb_rb++;
          dl_ch0_ext+=12;
          dl_ch1_ext+=12;
          rxF_ext+=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];
              dl_ch1_ext[j++]=dl_ch1[i];
            }
          }

          nb_rb++;
          dl_ch0_ext+=8;
          dl_ch1_ext+=8;
          rxF_ext+=8;
        }

        dl_ch0+=12;
        dl_ch1+=12;
        rxF+=12;
1214
      }
1215

1216
    else {  // Odd number of RBs
1217 1218
      for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {

1219
        //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

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

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

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

          dl_ch0+=12;
          dl_ch1+=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];
              dl_ch1_ext[j++]=dl_ch1[i];
              //                printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i]));
            }
          }

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


          dl_ch0+=12;
          dl_ch1+=12;
          rxF+=12;
        }
      }

      // Do middle RB (around DC)
1266 1267

      if (symbol_mod > 0) {
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
        for (i=0; i<6; i++) {
          dl_ch0_ext[i]=dl_ch0[i];
          dl_ch1_ext[i]=dl_ch1[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];
          dl_ch1_ext[i]=dl_ch1[i];
          rxF_ext[i]=rxF[(1+i)];
        }

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

        dl_ch0+=12;
        dl_ch1+=12;
        rxF+=7;
        rb++;
      } else {
        j=0;

        for (i=0; i<6; i++) {
          if ((i!=nushiftmod3) &&
              (i!=nushiftmod3+3)) {
            dl_ch0_ext[j]=dl_ch0[i];
            dl_ch1_ext[j]=dl_ch1[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];
            dl_ch1_ext[j]=dl_ch1[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;
        dl_ch1_ext+=8;
        rxF_ext+=8;
        dl_ch0+=12;
        dl_ch1+=12;
        rxF+=7;
        rb++;
1325 1326
      }

1327 1328 1329
      for (; rb<frame_parms->N_RB_DL; rb++) {

        if (symbol_mod>0) {
1330
          //  printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
          memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
          memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));

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

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

          dl_ch0+=12;
          dl_ch1+=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];
              dl_ch1_ext[j++]=dl_ch1[i];
            }
          }

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

          dl_ch0+=12;
          dl_ch1+=12;
          rxF+=12;
        }
1369 1370 1371 1372 1373 1374
      }
    }
  }
}


1375
void pdcch_channel_compensation(int32_t **rxdataF_ext,
1376 1377 1378 1379 1380 1381 1382
                                int32_t **dl_ch_estimates_ext,
                                int32_t **rxdataF_comp,
                                int32_t **rho,
                                LTE_DL_FRAME_PARMS *frame_parms,
                                uint8_t symbol,
                                uint8_t output_shift)
{
1383

1384
  uint16_t rb;
1385
#if defined(__x86_64__) || defined(__i386__)
1386 1387
  __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
  __m128i *dl_ch128_2, *rho128;
1388 1389 1390
#elif defined(__arm__)

#endif
1391
  uint8_t aatx,aarx,pilots=0;
1392 1393 1394 1395 1396




#ifdef DEBUG_DCI_DECODING
1397
  LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol);
1398 1399 1400 1401 1402
#endif

  if (symbol==0)
    pilots=1;

Xiwen JIANG's avatar
Xiwen JIANG committed
1403 1404
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
    //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB
1405

1406
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1407

1408
#if defined(__x86_64__) || defined(__i386__)
1409 1410 1411 1412
      dl_ch128          = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
      rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128   = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];

1413 1414 1415
#elif defined(__arm__)

#endif
1416

1417 1418
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

1419
#if defined(__x86_64__) || defined(__i386__)
1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
        // multiply by conjugated channel
        mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
        //  print_ints("re",&mmtmpPD0);

        // mmtmpPD0 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]);
        //  print_ints("im",&mmtmpPD1);
        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[0]);
        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
        //  print_ints("re(shift)",&mmtmpPD0);
        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
        //  print_ints("im(shift)",&mmtmpPD1);
        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
        //        print_ints("c0",&mmtmpPD2);
        //  print_ints("c1",&mmtmpPD3);
        rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
        //  print_shorts("rx:",rxdataF128);
        //  print_shorts("ch:",dl_ch128);
        //  print_shorts("pack:",rxdataF_comp128);

        // multiply by conjugated channel
        mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[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,rxdataF128[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);

        rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);

        //  print_shorts("rx:",rxdataF128+1);
        //  print_shorts("ch:",dl_ch128+1);
        //  print_shorts("pack:",rxdataF_comp128+1);
        // multiply by conjugated channel
        if (pilots == 0) {
          mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[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,rxdataF128[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);

          rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);
        }

        //  print_shorts("rx:",rxdataF128+2);
        //  print_shorts("ch:",dl_ch128+2);
        //        print_shorts("pack:",rxdataF_comp128+2);

        if (pilots==0) {
          dl_ch128+=3;
          rxdataF128+=3;
          rxdataF_comp128+=3;
        } else {
          dl_ch128+=2;
          rxdataF128+=2;
          rxdataF_comp128+=2;
        }
1492 1493 1494
#elif defined(__arm__)

#endif
1495 1496 1497
      }
    }
  }
1498

1499 1500 1501

  if (rho) {

1502
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
1503 1504

#if defined(__x86_64__) || defined(__i386__)
1505 1506 1507 1508
      rho128        = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch128      = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
      dl_ch128_2    = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];

1509 1510 1511
#elif defined(__arm__)
      
#endif
1512
      for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
1513 1514
#if defined(__x86_64__) || defined(__i386__)

1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
        // multiply by conjugated channel
        mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
        //  print_ints("re",&mmtmpD0);

        // 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]);
        //  print_ints("im",&mmtmpPD1);
        mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]);
        // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit)
        mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift);
        //  print_ints("re(shift)",&mmtmpD0);
        mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift);
        //  print_ints("im(shift)",&mmtmpD1);
        mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1);
        mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1);
        //        print_ints("c0",&mmtmpPD2);
        //  print_ints("c1",&mmtmpPD3);
        rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3);

        //print_shorts("rx:",dl_ch128_2);
        //print_shorts("ch:",dl_ch128);
        //print_shorts("pack:",rho128);

        // multiply by conjugated channel
        mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]);
        // mmtmpD0 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_ch128_2[1]);
        // mmtmpD1 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);


        rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3);
        //print_shorts("rx:",dl_ch128_2+1);
        //print_shorts("ch:",dl_ch128+1);
        //print_shorts("pack:",rho128+1);
        // multiply by conjugated channel
        mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[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_ch128_2[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);

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

        dl_ch128+=3;
        dl_ch128_2+=3;
        rho128+=3;

1580 1581 1582 1583
#elif defined(__arm_)


#endif
1584
      }
1585 1586 1587 1588
    }

  }

1589
#if defined(__x86_64__) || defined(__i386__)
1590 1591
  _mm_empty();
  _m_empty();
1592
#endif
1593
}
1594 1595

void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
1596 1597 1598
                         int32_t **rxdataF_comp,
                         uint8_t symbol)
{
1599

1600
  uint8_t aatx;
1601

1602
#if defined(__x86_64__) || defined(__i386__)
1603
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
1604 1605 1606
#elif defined(__arm__)
 int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
#endif
1607
  int32_t i;
1608 1609

  if (frame_parms->nb_antennas_rx>1) {
Xiwen JIANG's avatar
Xiwen JIANG committed
1610
    for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
1611
#if defined(__x86_64__) || defined(__i386__)
1612 1613
      rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
      rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
1614 1615 1616 1617
#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
1618
      // MRC on each re of rb
1619
      for (i=0; i<frame_parms->N_RB_DL*3; i++) {
1620
#if defined(__x86_64__) || defined(__i386__)
1621
        rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
1622 1623 1624
#elif defined(__arm__)
        rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
1625 1626 1627
      }
    }
  }
1628

1629
#if defined(__x86_64__) || defined(__i386__)
1630 1631
  _mm_empty();
  _m_empty();
1632
#endif
1633 1634 1635 1636

}

void pdcch_siso(LTE_DL_FRAME_PARMS *frame_parms,
1637 1638 1639
                int32_t **rxdataF_comp,
                uint8_t l)
{
1640 1641


1642
  uint8_t rb,re,jj,ii;
1643 1644 1645 1646

  jj=0;
  ii=0;

1647 1648 1649 1650
  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {

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

1651 1652 1653 1654 1655 1656 1657 1658
      rxdataF_comp[0][jj++] = rxdataF_comp[0][ii];
      ii++;
    }
  }
}


void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
1659 1660 1661
                    int32_t **rxdataF_comp,
                    uint8_t symbol)
{
1662 1663


1664 1665 1666
  int16_t *rxF0,*rxF1;
  uint8_t rb,re;
  int32_t jj=(symbol*frame_parms->N_RB_DL*12);
1667

1668 1669
  rxF0     = (int16_t*)&rxdataF_comp[0][jj];  //tx antenna 0  h0*y
  rxF1     = (int16_t*)&rxdataF_comp[2][jj];  //tx antenna 1  h1*y
1670

1671
  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
1672

1673
    for (re=0; re<12; re+=2) {
1674 1675

      // Alamouti RX combining
1676

1677 1678 1679 1680 1681
      rxF0[0] = rxF0[0] + rxF1[2];
      rxF0[1] = rxF0[1] - rxF1[3];

      rxF0[2] = rxF0[2] - rxF1[0];
      rxF0[3] = rxF0[3] + rxF1[1];
1682

1683 1684 1685 1686 1687
      rxF0+=4;
      rxF1+=4;
    }
  }

1688

1689 1690
}

1691
int32_t avgP[4];
1692

hbilel's avatar
hbilel committed
1693
int32_t rx_pdcch(PHY_VARS_UE *ue,
1694
                 uint32_t frame,
1695 1696 1697 1698 1699 1700
                 uint8_t subframe,
                 uint8_t eNB_id,
                 MIMO_mode_t mimo_mode,
                 uint32_t high_speed_flag,
                 uint8_t is_secondary_ue)
{
1701

hbilel's avatar
hbilel committed
1702 1703
  LTE_UE_COMMON *common_vars      = &ue->common_vars;
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
1704
  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[ue->current_thread_id[subframe]];
hbilel's avatar
hbilel committed
1705

1706
  uint8_t log2_maxh,aatx,aarx;
1707
#ifdef MU_RECEIVER
1708
  uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1
1709
#endif
1710 1711
  int32_t avgs;
  uint8_t n_pdcch_symbols;
1712
  uint8_t mi = get_mi(frame_parms,subframe);
1713

hbilel's avatar
hbilel committed
1714
  //printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars);
1715
  // procress ofdm symbol 0
1716
    if (is_secondary_ue == 1) {
1717 1718
      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
1719 1720
                               pdcch_vars[eNB_id]->rxdataF_ext,
                               pdcch_vars[eNB_id]->dl_ch_estimates_ext,
1721
                               0,
1722 1723
                               high_speed_flag,
                               frame_parms);
1724
#ifdef MU_RECEIVER
1725 1726
      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
1727 1728
                               pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
                               pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
1729
                               0,
1730 1731
                               high_speed_flag,
                               frame_parms);
1732
#endif //MU_RECEIVER
Xiwen JIANG's avatar
Xiwen JIANG committed
1733
    } else if (frame_parms->nb_antenna_ports_eNB>1) {
1734 1735
      pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                             common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
1736 1737
                             pdcch_vars[eNB_id]->rxdataF_ext,
                             pdcch_vars[eNB_id]->dl_ch_estimates_ext,
1738
                             0,
1739 1740 1741
                             high_speed_flag,
                             frame_parms);
    } else {
1742 1743
      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
1744 1745
                               pdcch_vars[eNB_id]->rxdataF_ext,
                               pdcch_vars[eNB_id]->dl_ch_estimates_ext,
1746
                               0,
1747 1748 1749 1750
                               high_speed_flag,
                               frame_parms);
    }

1751 1752

  // compute channel level based on ofdm symbol 0
1753
  pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext,
1754 1755 1756
                      frame_parms,
                      avgP,
                      frame_parms->N_RB_DL);
1757 1758

  avgs = 0;
1759

Xiwen JIANG's avatar
Xiwen JIANG committed
1760
  for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
1761
    for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
1762
      avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
1763

1764
  log2_maxh = (log2_approx(avgs)/2) + 5;  //+frame_parms->nb_antennas_rx;
gabrielC's avatar
gabrielC committed
1765
#ifdef UE_DEBUG_TRACE
gabrielC's avatar
gabrielC committed
1766
  LOG_D(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs);
1767
#endif
1768

Cedric Roux's avatar
Cedric Roux committed
1769 1770
  T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id),  T_INT(frame%1024), T_INT(subframe),
                           T_INT(avgP[0]), T_INT(avgP[1]),    T_INT(avgP[2]),  T_INT(avgP[3]));
1771 1772 1773 1774 1775 1776 1777 1778 1779

  // compute LLRs for ofdm symbol 0 only
  pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
          pdcch_vars[eNB_id]->dl_ch_estimates_ext,
          pdcch_vars[eNB_id]->rxdataF_comp,
          (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
                  frame_parms,
                  0,
                  log2_maxh); // log2_maxh+I0_shift
1780 1781 1782


#ifdef DEBUG_PHY
1783

1784
  if (subframe==5)
1785
      write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1786

1787 1788 1789
#endif

#ifdef MU_RECEIVER
1790

1791
  if (is_secondary_ue) {
1792
      //get MF output for interfering stream
1793
      pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
1794 1795 1796 1797 1798 1799
              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
              pdcch_vars[eNB_id_i]->rxdataF_comp,
              (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
                      frame_parms,
                      0,
                      log2_maxh); // log2_maxh+I0_shift
1800
#ifdef DEBUG_PHY
1801
      write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1802 1803
#endif
      pdcch_dual_stream_correlation(frame_parms,
1804 1805 1806 1807 1808 1809
              0,
              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
              pdcch_vars[eNB_id]->dl_ch_rho_ext,
              log2_maxh);
  }
1810

1811
#endif //MU_RECEIVER
1812

1813

1814
  if (frame_parms->nb_antennas_rx > 1) {
1815
#ifdef MU_RECEIVER
1816

1817
      if (is_secondary_ue) {
1818 1819 1820 1821 1822 1823
          pdcch_detection_mrc_i(frame_parms,
                  pdcch_vars[eNB_id]->rxdataF_comp,
                  pdcch_vars[eNB_id_i]->rxdataF_comp,
                  pdcch_vars[eNB_id]->rho,
                  pdcch_vars[eNB_id]->dl_ch_rho_ext,
                  0);
1824
#ifdef DEBUG_PHY
1825 1826
          write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
          write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
1827
#endif
1828
      } else
1829
#endif //MU_RECEIVER
1830 1831 1832 1833
          pdcch_detection_mrc(frame_parms,
                  pdcch_vars[eNB_id]->rxdataF_comp,
                  0);
  }
1834

1835 1836 1837 1838
  if (mimo_mode == SISO)
      pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
  else
      pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
1839

1840

1841
#ifdef MU_RECEIVER
1842

1843
  if (is_secondary_ue) {
1844
      pdcch_qpsk_qpsk_llr(frame_parms,
1845 1846 1847 1848 1849 1850
              pdcch_vars[eNB_id]->rxdataF_comp,
              pdcch_vars[eNB_id_i]->rxdataF_comp,
              pdcch_vars[eNB_id]->dl_ch_rho_ext,
              pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
              pdcch_vars[eNB_id]->llr,
              0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1851
      /*
1852
      #ifdef DEBUG_PHY
Raymond Knopp's avatar
 
Raymond Knopp committed
1853
      if (subframe==5) {
1854 1855
      write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
      write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
Raymond Knopp's avatar
 
Raymond Knopp committed
1856
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1857
      #endif*/
1858
  } else {
1859 1860
#endif //MU_RECEIVER
      pdcch_llr(frame_parms,
1861 1862 1863
              pdcch_vars[eNB_id]->rxdataF_comp,
              (char *)pdcch_vars[eNB_id]->llr,
              0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1864
      /*#ifdef DEBUG_PHY
1865
      write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
Raymond Knopp's avatar
 
Raymond Knopp committed
1866
      #endif*/
1867

1868
#ifdef MU_RECEIVER
1869
  }
1870

1871 1872 1873
#endif //MU_RECEIVER


1874 1875 1876 1877 1878
#if T_TRACER
  T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
    T_INT(n_pdcch_symbols),
    T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
#endif
1879

1880
  // decode pcfich here and find out pdcch ofdm symbol number
1881
  n_pdcch_symbols = rx_pcfich(frame_parms,
1882
                              subframe,
1883
                              pdcch_vars[eNB_id],
1884 1885
                              mimo_mode);

hbilel's avatar
hbilel committed
1886

1887 1888 1889
  if (n_pdcch_symbols>3)
    n_pdcch_symbols=1;

1890

1891 1892
#ifdef DEBUG_DCI_DECODING

1893
  LOG_I(PHY,"demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
1894 1895
#endif

1896 1897 1898
  // process pdcch ofdm symbol 1 and 2 if necessary
  for (int s=1; s<n_pdcch_symbols; s++){
      if (is_secondary_ue == 1) {
1899 1900
          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
1901 1902 1903 1904 1905 1906
                  pdcch_vars[eNB_id]->rxdataF_ext,
                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                  s,
                  high_speed_flag,
                  frame_parms);
#ifdef MU_RECEIVER
1907 1908
pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
        common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
1909 1910 1911 1912 1913 1914 1915
        pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
        s,
        high_speed_flag,
        frame_parms);
#endif //MU_RECEIVER
      } else if (frame_parms->nb_antenna_ports_eNB>1) {
1916 1917
          pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
1918 1919 1920 1921 1922 1923
                  pdcch_vars[eNB_id]->rxdataF_ext,
                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                  s,
                  high_speed_flag,
                  frame_parms);
      } else {
1924 1925
          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036
                  pdcch_vars[eNB_id]->rxdataF_ext,
                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                  s,
                  high_speed_flag,
                  frame_parms);
      }


      pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
              pdcch_vars[eNB_id]->rxdataF_comp,
              (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
                      frame_parms,
                      s,
                      log2_maxh); // log2_maxh+I0_shift


#ifdef DEBUG_PHY

if (subframe==5)
    write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);

#endif

#ifdef MU_RECEIVER

if (is_secondary_ue) {
    //get MF output for interfering stream
    pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
            pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
            pdcch_vars[eNB_id_i]->rxdataF_comp,
            (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
                    frame_parms,
                    s,
                    log2_maxh); // log2_maxh+I0_shift
#ifdef DEBUG_PHY
write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
#endif
pdcch_dual_stream_correlation(frame_parms,
        s,
        pdcch_vars[eNB_id]->dl_ch_estimates_ext,
        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
        pdcch_vars[eNB_id]->dl_ch_rho_ext,
        log2_maxh);
}

#endif //MU_RECEIVER


if (frame_parms->nb_antennas_rx > 1) {
#ifdef MU_RECEIVER

    if (is_secondary_ue) {
        pdcch_detection_mrc_i(frame_parms,
                pdcch_vars[eNB_id]->rxdataF_comp,
                pdcch_vars[eNB_id_i]->rxdataF_comp,
                pdcch_vars[eNB_id]->rho,
                pdcch_vars[eNB_id]->dl_ch_rho_ext,
                s);
#ifdef DEBUG_PHY
write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
#endif
    } else
#endif //MU_RECEIVER
        pdcch_detection_mrc(frame_parms,
                pdcch_vars[eNB_id]->rxdataF_comp,
                s);

}

if (mimo_mode == SISO)
    pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
else
    pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);


#ifdef MU_RECEIVER

if (is_secondary_ue) {
    pdcch_qpsk_qpsk_llr(frame_parms,
            pdcch_vars[eNB_id]->rxdataF_comp,
            pdcch_vars[eNB_id_i]->rxdataF_comp,
            pdcch_vars[eNB_id]->dl_ch_rho_ext,
            pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
            pdcch_vars[eNB_id]->llr,
            s);
    /*
        #ifdef DEBUG_PHY
        if (subframe==5) {
        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
        write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
        }
        #endif*/
} else {
#endif //MU_RECEIVER
    pdcch_llr(frame_parms,
            pdcch_vars[eNB_id]->rxdataF_comp,
            (char *)pdcch_vars[eNB_id]->llr,
            s);
    /*#ifdef DEBUG_PHY
        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
        #endif*/

#ifdef MU_RECEIVER
}

#endif //MU_RECEIVER

  }

2037 2038
  pdcch_demapping(pdcch_vars[eNB_id]->llr,
                  pdcch_vars[eNB_id]->wbar,
2039 2040 2041
                  frame_parms,
                  n_pdcch_symbols,
                  get_mi(frame_parms,subframe));
2042 2043

  pdcch_deinterleaving(frame_parms,
2044 2045
                       (uint16_t*)pdcch_vars[eNB_id]->e_rx,
                       pdcch_vars[eNB_id]->wbar,
2046 2047 2048
                       n_pdcch_symbols,
                       mi);

2049
  pdcch_unscrambling(frame_parms,
2050
                     subframe,
2051
                     pdcch_vars[eNB_id]->e_rx,
2052 2053
                     get_nCCE(n_pdcch_symbols,frame_parms,mi)*72);

2054
  pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols;
2055 2056 2057 2058 2059 2060

  return(0);
}


void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
2061 2062 2063 2064
                      uint8_t subframe,
                      uint8_t *e,
                      uint32_t length)
{
2065
  int i;
2066 2067
  uint8_t reset;
  uint32_t x1, x2, s=0;
2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079

  reset = 1;
  // x1 is set in lte_gold_generic

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

  for (i=0; i<length; i++) {
    if ((i&0x1f)==0) {
      s = lte_gold_generic(&x1, &x2, reset);
      //printf("lte_gold[%d]=%x\n",i,s);
      reset = 0;
    }
2080

2081 2082 2083 2084 2085 2086 2087
    //    printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1));
    if (e[i] != 2) // <NIL> element is 2
      e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1);
  }
}

void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
2088 2089 2090 2091
                        uint8_t subframe,
                        int8_t* llr,
                        uint32_t length)
{
2092 2093

  int i;
2094 2095
  uint8_t reset;
  uint32_t x1, x2, s=0;
2096 2097 2098 2099 2100 2101 2102

  reset = 1;
  // x1 is set in first call to lte_gold_generic

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

  for (i=0; i<length; i++) {
2103
    if ((i&0x1f)==0) {
2104
      s = lte_gold_generic(&x1, &x2, reset);
2105
      //      printf("lte_gold[%d]=%x\n",i,s);
2106 2107
      reset = 0;
    }
2108

2109 2110
    
    //    printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1));
2111 2112
    if (((s>>(i%32))&1)==0)
      llr[i] = -llr[i];
2113
    //    printf("%d\n",llr[i]);
2114 2115 2116

  }
}
2117

2118
/*
2119
uint8_t get_num_pdcch_symbols(uint8_t num_dci,
2120 2121 2122 2123
                              DCI_ALLOC_t *dci_alloc,
                              LTE_DL_FRAME_PARMS *frame_parms,
                              uint8_t subframe)
{
2124

2125 2126 2127
  uint16_t numCCE = 0;
  uint8_t i;
  uint8_t nCCEmin = 0;
2128 2129 2130
  uint16_t CCE_max_used_index = 0;
  uint16_t firstCCE_max = dci_alloc[0].firstCCE;
  uint8_t  L = dci_alloc[0].L;
2131 2132 2133

  // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211)
  if (frame_parms->Ncp==1) { // extended prefix
2134 2135 2136
    if ((frame_parms->frame_type == TDD) &&
        ((frame_parms->tdd_config<3)||(frame_parms->tdd_config==6)) &&
        ((subframe==1) || (subframe==6))) // subframes 1 and 6 (S-subframes) for 5ms switching periodicity are 2 symbols
2137 2138 2139 2140 2141 2142 2143
      nCCEmin = 2;
    else {   // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols
      nCCEmin = 3;
    }
  }

  // compute numCCE
2144
  for (i=0; i<num_dci; i++) {
2145
    //     printf("dci %d => %d\n",i,dci_alloc[i].L);
2146
    numCCE += (1<<(dci_alloc[i].L));
2147 2148

    if(firstCCE_max < dci_alloc[i].firstCCE) {
2149 2150
      firstCCE_max = dci_alloc[i].firstCCE;
      L            = dci_alloc[i].L;
2151
    }
2152
  }
2153
  CCE_max_used_index = firstCCE_max + (1<<L) - 1;
2154 2155

  //if ((9*numCCE) <= (frame_parms->N_RB_DL*2))
2156
  if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)))
2157
    return(cmax(1,nCCEmin));
Xiwen JIANG's avatar
Xiwen JIANG committed
2158
  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5)))
2159
  else if (CCE_max_used_index < get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)))
2160
    return(cmax(2,nCCEmin));
Xiwen JIANG's avatar
Xiwen JIANG committed
2161
  //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8)))
2162
  else if (CCE_max_used_index < get_nCCE(3, frame_parms, get_mi(frame_parms, subframe)))
2163
    return(cmax(3,nCCEmin));
2164
  else if (frame_parms->N_RB_DL<=10) {
2165
    if (frame_parms->Ncp == 0) { // normal CP
Raymond Knopp's avatar
 
Raymond Knopp committed
2166
      printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL,
2167 2168 2169 2170
             get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)),
             get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)),
             get_nCCE(3, frame_parms, get_mi(frame_parms, subframe)));

Xiwen JIANG's avatar
Xiwen JIANG committed
2171
      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11)))
2172 2173
        return(4);
    } else { // extended CP
Xiwen JIANG's avatar
Xiwen JIANG committed
2174
      if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10)))
2175
        return(4);
2176 2177 2178
    }
  }

2179

2180

2181
  //  LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
2182 2183
  //for (i=0;i<num_dci;i++) {
  //  printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
2184
  //}
2185
  //exit(-1);
Cedric Roux's avatar
Cedric Roux committed
2186
exit(1);
2187 2188
  return(0);
}
2189
*/
2190

2191

2192 2193
uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
			 uint8_t num_dci,
2194 2195 2196 2197
                         DCI_ALLOC_t *dci_alloc,
                         uint32_t n_rnti,
                         int16_t amp,
                         LTE_DL_FRAME_PARMS *frame_parms,
2198
                         int32_t **txdataF,
2199 2200
                         uint32_t subframe)
{
2201

2202

2203
  uint8_t *e_ptr;
2204 2205 2206 2207 2208
  int8_t L;
  uint32_t i, lprime;
  uint32_t gain_lin_QPSK,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset;
  int16_t re_offset;
  uint8_t mi = get_mi(frame_parms,subframe);
2209
  static uint8_t e[DCI_BITS_MAX];
2210
  static int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb];
2211

2212 2213
  int32_t *y[2];
  int32_t *wbar[2];
2214

2215 2216 2217 2218 2219 2220 2221 2222 2223
  int nushiftmod3 = frame_parms->nushift%3;

  int Msymb2;
  int split_flag=0;

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

2225 2226 2227
  case 75:
    Msymb2 = 3*Msymb/4;
    break;
2228

2229 2230 2231
  case 50:
    Msymb2 = Msymb>>1;
    break;
2232

2233 2234 2235
  case 25:
    Msymb2 = Msymb>>2;
    break;
2236

2237 2238 2239
  case 15:
    Msymb2 = Msymb*15/100;
    break;
2240

2241 2242 2243
  case 6:
    Msymb2 = Msymb*6/100;
    break;
2244

2245 2246 2247 2248 2249
  default:
    Msymb2 = Msymb>>2;
    break;
  }

2250

2251
  generate_pcfich(num_pdcch_symbols,
2252 2253 2254 2255
                  amp,
                  frame_parms,
                  txdataF,
                  subframe);
2256 2257 2258 2259 2260
  wbar[0] = &wbar0[0];
  wbar[1] = &wbar1[0];
  y[0] = &yseq0[0];
  y[1] = &yseq1[0];

2261
#if 0
2262
  // reset all bits to <NIL>, here we set <NIL> elements as 2
2263 2264 2265 2266
  // memset(e, 2, DCI_BITS_MAX);
  // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
  for (i=0; i<DCI_BITS_MAX; i++)
    e[i]=taus()&1;
2267 2268 2269 2270 2271 2272
#endif

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

2274 2275
  e_ptr = e;

2276

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

2282
      if (dci_alloc[i].L == (uint8_t)L) {
2283

2284
	#ifdef DEBUG_DCI_ENCODING
2285 2286
	if (dci_alloc[i].rnti==0x02)
	  LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L,
2287 2288
		*(unsigned int*)dci_alloc[i].dci_pdu,
		dci_alloc[i].rnti);
2289 2290
       //dump_dci(frame_parms,&dci_alloc[i]);
	#endif
2291

2292
        if (dci_alloc[i].firstCCE>=0) {
2293
          e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
2294
                                e+(72*dci_alloc[i].firstCCE),
2295 2296
                                dci_alloc[i].dci_length,
                                dci_alloc[i].L,
Raymond Knopp's avatar
Raymond Knopp committed
2297
				72,
2298 2299
                                dci_alloc[i].rnti);
        }
2300 2301 2302 2303 2304 2305 2306
      }
    }
  }

  // Scrambling
  //  printf("pdcch scrambling\n");
  pdcch_scrambling(frame_parms,
2307 2308
                   subframe,
                   e,
2309
                   8*get_nquad(num_pdcch_symbols, frame_parms, mi));
2310 2311
  //72*get_nCCE(num_pdcch_symbols,frame_parms,mi));

2312

2313

2314

2315
  // Now do modulation
2316
  if (frame_parms->nb_antenna_ports_eNB==1)
2317
    gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
2318
  else
2319
    gain_lin_QPSK = amp/2;
2320 2321

  e_ptr = e;
2322

2323 2324 2325 2326 2327
#ifdef DEBUG_DCI_ENCODING
  printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK);
#endif


2328
  if (frame_parms->nb_antenna_ports_eNB==1) { //SISO
2329

2330

2331
    for (i=0; i<Msymb2; i++) {
2332
      
2333 2334 2335 2336
      //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
2337
      e_ptr++;
2338 2339 2340 2341
      //((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      //((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
      ((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
2342 2343 2344

      e_ptr++;
    }
2345
  } else { //ALAMOUTI
2346

2347

2348
    for (i=0; i<Msymb2; i+=2) {
2349 2350

#ifdef DEBUG_DCI_ENCODING
2351
      printf(" PDCCH Modulation (TX diversity): REG %d\n",i>>2);
2352
#endif
2353
      // first antenna position n -> x0
2354
      ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
2355
      e_ptr++;
2356
      ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
2357
      e_ptr++;
2358

2359
      // second antenna position n -> -x1*
2360
      ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
2361
      e_ptr++;
2362
      ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
2363 2364 2365 2366 2367 2368 2369 2370 2371
      e_ptr++;

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

    }
2372 2373 2374 2375
  }


#ifdef DEBUG_DCI_ENCODING
2376
  printf(" PDCCH Interleaving\n");
2377 2378
#endif

2379
  //  printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
2380 2381 2382 2383 2384 2385 2386 2387
  // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5
  pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi);

  mprime=0;
  nsymb = (frame_parms->Ncp==0) ? 14:12;
  re_offset = frame_parms->first_carrier_offset;

  // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5
2388
  //  printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]);
2389 2390
  for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) {
    for (lprime=0; lprime<num_pdcch_symbols; lprime++) {
2391

2392
      symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(lprime+(subframe*nsymb));
2393 2394


2395

2396 2397 2398 2399 2400 2401 2402 2403
      tti_offset = symbol_offset + re_offset;

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

      //            printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset);
      // if REG is allocated to PHICH, skip it
      if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
#ifdef DEBUG_DCI_ENCODING
2404
        printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
2405
#endif
2406 2407 2408 2409
      } else {
        // Copy REG to TX buffer

        if ((lprime == 0)||
Xiwen JIANG's avatar
Xiwen JIANG committed
2410
            ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) {
2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421
          // first symbol, or second symbol+4 TX antennas skip pilots

          kprime_mod12 = kprime%12;

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

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

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

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

2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441
                mprime++;
              }
            }
          }
        } else { // no pilots in this symbol
          kprime_mod12 = kprime%12;

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

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

2445
#ifdef DEBUG_DCI_ENCODING
2446
                LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
2447
#endif
2448 2449 2450 2451 2452
                mprime++;
              }
            } else {
              txdataF[0][tti_offset+0] = wbar[0][mprime];

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

2456
#ifdef DEBUG_DCI_ENCODING
2457
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
2458
#endif
2459 2460 2461
              mprime++;
              txdataF[0][tti_offset+1] = wbar[0][mprime];

Xiwen JIANG's avatar
Xiwen JIANG committed
2462
              if (frame_parms->nb_antenna_ports_eNB > 1)
2463 2464
                txdataF[1][tti_offset+1] = wbar[1][mprime];

2465
#ifdef DEBUG_DCI_ENCODING
2466
              printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
2467
#endif
2468 2469 2470
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];

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

2474
#ifdef DEBUG_DCI_ENCODING
2475
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
2476
                    *(1+(short*)&wbar[0][mprime]));
2477
#endif
2478 2479 2480
              mprime++;
              txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];

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

2484
#ifdef DEBUG_DCI_ENCODING
2485
              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
2486
                    *(1+(short*)&wbar[0][mprime]));
2487
#endif
2488 2489 2490 2491 2492
              mprime++;

            }
          }
        }
2493

2494 2495
        if (mprime>=Msymb2)
          return(num_pdcch_symbols);
2496
      } // check_phich_reg
2497

2498
    } //lprime loop
2499

2500
    re_offset++;
2501

2502 2503 2504
    if (re_offset == (frame_parms->ofdm_symbol_size))
      re_offset = 1;
  } // kprime loop
2505

2506 2507 2508 2509 2510
  return(num_pdcch_symbols);
}



2511
void dci_decoding(uint8_t DCI_LENGTH,
2512 2513 2514 2515
                  uint8_t aggregation_level,
                  int8_t *e,
                  uint8_t *decoded_output)
{
2516 2517 2518 2519

  uint8_t dummy_w_rx[3*(MAX_DCI_SIZE_BITS+16+64)];
  int8_t w_rx[3*(MAX_DCI_SIZE_BITS+16+32)],d_rx[96+(3*(MAX_DCI_SIZE_BITS+16))];

2520
  uint16_t RCC;
2521

2522 2523
  uint16_t D=(DCI_LENGTH+16+64);
  uint16_t coded_bits;
2524
#ifdef DEBUG_DCI_DECODING
2525
  int32_t i;
2526
#endif
2527

2528 2529
  AssertFatal(aggregation_level<4,
	      "dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level);
2530 2531 2532 2533

  coded_bits = 72 * (1<<aggregation_level);

#ifdef DEBUG_DCI_DECODING
2534
  LOG_I(PHY," Doing DCI decoding for %d bits, DCI_LENGTH %d,coded_bits %d, e %p\n",3*(DCI_LENGTH+16),DCI_LENGTH,coded_bits,e);
2535
#endif
2536

2537 2538 2539
  // now do decoding
  memset((void*)dummy_w_rx,0,3*D);
  RCC = generate_dummy_w_cc(DCI_LENGTH+16,
2540 2541
                            dummy_w_rx);

2542 2543 2544


#ifdef DEBUG_DCI_DECODING
2545
  LOG_I(PHY," Doing DCI Rate Matching RCC %d, w %p\n",RCC,w);
2546 2547 2548
#endif

  lte_rate_matching_cc_rx(RCC,coded_bits,w_rx,dummy_w_rx,e);
2549 2550 2551 2552 2553

  sub_block_deinterleaving_cc((uint32_t)(DCI_LENGTH+16),
                              &d_rx[96],
                              &w_rx[0]);

2554
#ifdef DEBUG_DCI_DECODING
2555 2556

  for (i=0; i<16+DCI_LENGTH; i++)
2557
    LOG_I(PHY," DCI %d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
2558 2559

#endif
2560
  memset(decoded_output,0,2+((16+DCI_LENGTH)>>3));
2561

2562
#ifdef DEBUG_DCI_DECODING
2563
  printf("Before Viterbi\n");
2564

2565
  for (i=0; i<16+DCI_LENGTH; i++)
2566
    printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
2567 2568

#endif
2569
  //debug_printf("Doing DCI Viterbi \n");
2570
  phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH);
2571
  //debug_printf("Done DCI Viterbi \n");
2572 2573 2574
}


2575
static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
2576

2577 2578
uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
2579 2580 2581
  return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9);
}

2582 2583
uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
{
2584

2585
  uint16_t Nreg=0;
2586
  uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
2587 2588 2589 2590 2591 2592 2593

  if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
    Ngroup_PHICH++;

  if (frame_parms->Ncp == 1) {
    Ngroup_PHICH<<=1;
  }
2594

2595 2596 2597 2598 2599 2600 2601
  Ngroup_PHICH*=mi;

  if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4))
    switch (frame_parms->N_RB_DL) {
    case 6:
      Nreg=12+(num_pdcch_symbols-1)*18;
      break;
2602

2603 2604 2605
    case 25:
      Nreg=50+(num_pdcch_symbols-1)*75;
      break;
2606

2607 2608 2609
    case 50:
      Nreg=100+(num_pdcch_symbols-1)*150;
      break;
2610

2611 2612 2613
    case 100:
      Nreg=200+(num_pdcch_symbols-1)*300;
      break;
2614

2615 2616 2617
    default:
      return(0);
    }
2618

2619 2620 2621 2622
  //   printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH));
  return(Nreg - 4 - (3*Ngroup_PHICH));
}

2623
uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe)
2624
{
2625 2626

  // check for eNB only !
2627
  return(get_nCCE(num_pdcch_symbols,
2628 2629
		  &RC.eNB[Mod_id][CC_id]->frame_parms,
		  get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); 
2630 2631
}

2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713

int get_nCCE_offset_l1(int *CCE_table,
		       const unsigned char L, 
		       const int nCCE, 
		       const int common_dci, 
		       const unsigned short rnti, 
		       const unsigned char subframe)
{

  int search_space_free,m,nb_candidates = 0,l,i;
  unsigned int Yk;
   /*
    printf("CCE Allocation: ");
    for (i=0;i<nCCE;i++)
    printf("%d.",CCE_table[i]);
    printf("\n");
  */
  if (common_dci == 1) {
    // check CCE(0 ... L-1)
    nb_candidates = (L==4) ? 4 : 2;
    nb_candidates = min(nb_candidates,nCCE/L);

    //    printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L);

    for (m = nb_candidates-1 ; m >=0 ; m--) {

      search_space_free = 1;
      for (l=0; l<L; l++) {

	//	printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
        if (CCE_table[(m*L) + l] == 1) {
          search_space_free = 0;
          break;
        }
      }
     
      if (search_space_free == 1) {

	//	printf("returning %d\n",m*L);

        for (l=0; l<L; l++)
          CCE_table[(m*L)+l]=1;
        return(m*L);
      }
    }

    return(-1);

  } else { // Find first available in ue specific search space
    // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
    // compute Yk
    Yk = (unsigned int)rnti;

    for (i=0; i<=subframe; i++)
      Yk = (Yk*39827)%65537;

    Yk = Yk % (nCCE/L);


    switch (L) {
    case 1:
    case 2:
      nb_candidates = 6;
      break;

    case 4:
    case 8:
      nb_candidates = 2;
      break;

    default:
      DevParam(L, nCCE, rnti);
      break;
    }


    LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);

    for (m = 0 ; m < nb_candidates ; m++) {
      search_space_free = 1;

      for (l=0; l<L; l++) {
Cedric Roux's avatar
Cedric Roux committed
2714 2715
        int cce = (((Yk+m)%(nCCE/L))*L) + l;
        if (cce >= nCCE || CCE_table[cce] == 1) {
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733
          search_space_free = 0;
          break;
        }
      }

      if (search_space_free == 1) {
        for (l=0; l<L; l++)
          CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1;

        return(((Yk+m)%(nCCE/L))*L);
      }
    }

    return(-1);
  }
}


2734
void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
2735
			     int do_common,
2736
			     dci_detect_mode_t mode,
2737
			     uint8_t subframe,
2738 2739
                             DCI_ALLOC_t *dci_alloc,
                             int16_t eNB_id,
2740
                             uint8_t current_thread_id,
2741 2742 2743 2744
                             LTE_DL_FRAME_PARMS *frame_parms,
                             uint8_t mi,
                             uint16_t si_rnti,
                             uint16_t ra_rnti,
2745
                             uint16_t p_rnti,
2746 2747
                             uint8_t L,
                             uint8_t format_si,
2748
                             uint8_t format_p,
2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760
                             uint8_t format_ra,
                             uint8_t format_c,
                             uint8_t sizeof_bits,
                             uint8_t sizeof_bytes,
                             uint8_t *dci_cnt,
                             uint8_t *format0_found,
                             uint8_t *format_c_found,
                             uint32_t *CCEmap0,
                             uint32_t *CCEmap1,
                             uint32_t *CCEmap2)
{

2761 2762
  uint16_t crc,CCEind,nCCE;
  uint32_t *CCEmap=NULL,CCEmap_mask=0;
2763
  int L2=(1<<L);
2764
  unsigned int Yk,nb_candidates = 0,i,m;
2765 2766
  unsigned int CCEmap_cand;

2767
  nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi);
2768

2769 2770
  if (nCCE > get_nCCE(3,frame_parms,1)) {
    LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1));
2771
    return;
2772
  }
2773

2774 2775
  if (nCCE<L2) {
    LOG_D(PHY,"skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2);
2776
    return;
2777
  }
2778

2779 2780 2781 2782 2783
  if (mode == NO_DCI) {
    LOG_D(PHY, "skip DCI decoding: expect no DCIs at subframe %d\n", subframe);
    return;
  }

2784 2785 2786
  if (do_common == 1) {
    nb_candidates = (L2==4) ? 4 : 2;
    Yk=0;
2787
  } else {
2788 2789 2790
    // Find first available in ue specific search space
    // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
    // compute Yk
2791
    Yk = (unsigned int)pdcch_vars[eNB_id]->crnti;
2792

2793
    for (i=0; i<=subframe; i++)
2794 2795 2796 2797 2798 2799 2800 2801 2802
      Yk = (Yk*39827)%65537;

    Yk = Yk % (nCCE/L2);

    switch (L2) {
    case 1:
    case 2:
      nb_candidates = 6;
      break;
2803

2804 2805 2806 2807
    case 4:
    case 8:
      nb_candidates = 2;
      break;
2808

2809 2810 2811
    default:
      DevParam(L2, do_common, eNB_id);
      break;
2812
    }
2813
  }
2814

2815 2816 2817 2818 2819 2820 2821
  /*  for (CCEind=0;
       CCEind<nCCE2;
       CCEind+=(1<<L)) {*/

  if (nb_candidates*L2 > nCCE)
    nb_candidates = nCCE/L2;

2822
  for (m=0; m<nb_candidates; m++) {
2823 2824 2825 2826 2827 2828 2829 2830 2831 2832

    CCEind = (((Yk+m)%(nCCE/L2))*L2);

    if (CCEind<32)
      CCEmap = CCEmap0;
    else if (CCEind<64)
      CCEmap = CCEmap1;
    else if (CCEind<96)
      CCEmap = CCEmap2;
    else {
2833 2834
      AssertFatal(1==0,
		  "Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2);
2835
    }
2836

2837 2838 2839 2840
    switch (L2) {
    case 1:
      CCEmap_mask = (1<<(CCEind&0x1f));
      break;
2841

2842 2843 2844
    case 2:
      CCEmap_mask = (3<<(CCEind&0x1f));
      break;
2845

2846 2847 2848
    case 4:
      CCEmap_mask = (0xf<<(CCEind&0x1f));
      break;
2849

2850 2851 2852
    case 8:
      CCEmap_mask = (0xff<<(CCEind&0x1f));
      break;
2853 2854

    default:
2855 2856
      AssertFatal(1==0,
		  "Illegal L2 value %d\n", L2 );
2857 2858
    }

2859
    CCEmap_cand = (*CCEmap)&CCEmap_mask;
2860 2861

    // CCE is not allocated yet
2862 2863

    if (CCEmap_cand == 0) {
2864 2865

      if (do_common == 1)
2866
        LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
hbilel's avatar
hbilel committed
2867
                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
2868
      else
2869
        LOG_D(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
2870
                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
2871

2872
       dci_decoding(sizeof_bits,
2873
                   L,
2874
                   &pdcch_vars[eNB_id]->e_rx[CCEind*72],
2875
                   &dci_decoded_output[current_thread_id][0]);
2876 2877 2878 2879
      /*
        for (i=0;i<3+(sizeof_bits>>3);i++)
        printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
      */
2880

2881
      crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits);
2882
#ifdef DEBUG_DCI_DECODING
2883
      printf("crc =>%x\n",crc);
2884
#endif
2885 2886

      if (((L>1) && ((crc == si_rnti)||
2887
		     (crc == p_rnti)||
2888
                     (crc == ra_rnti)))||
2889
          (crc == pdcch_vars[eNB_id]->crnti))   {
2890 2891 2892
        dci_alloc[*dci_cnt].dci_length = sizeof_bits;
        dci_alloc[*dci_cnt].rnti       = crc;
        dci_alloc[*dci_cnt].L          = L;
2893
        dci_alloc[*dci_cnt].firstCCE   = CCEind;
2894

hbilel's avatar
hbilel committed
2895
        //printf("DCI FOUND !!! crc =>%x,  sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
2896
        if (sizeof_bytes<=4) {
2897 2898 2899 2900
          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
2901
#ifdef DEBUG_DCI_DECODING
2902 2903 2904 2905
          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
                  dci_decoded_output[current_thread_id][1],
                  dci_decoded_output[current_thread_id][2],
                  dci_decoded_output[current_thread_id][3]);
2906
#endif
2907
        } else {
2908 2909 2910 2911 2912 2913 2914 2915
          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6];
          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7];
2916
#ifdef DEBUG_DCI_DECODING
2917
          printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
2918 2919
              dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
              dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
2920
#endif
2921 2922 2923 2924 2925
        }

        if (crc==si_rnti) {
          dci_alloc[*dci_cnt].format     = format_si;
          *dci_cnt = *dci_cnt+1;
2926 2927 2928
        } else if (crc==p_rnti) {
          dci_alloc[*dci_cnt].format     = format_p;
          *dci_cnt = *dci_cnt+1;
2929 2930 2931
        } else if (crc==ra_rnti) {
          dci_alloc[*dci_cnt].format     = format_ra;
          // store first nCCE of group for PUCCH transmission of ACK/NAK
2932
          pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
2933
          *dci_cnt = *dci_cnt+1;
2934
        } else if (crc==pdcch_vars[eNB_id]->crnti) {
2935

2936
          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A
2937 2938 2939 2940
            if (*format0_found == 0) {
              dci_alloc[*dci_cnt].format     = format0;
              *format0_found = 1;
              *dci_cnt = *dci_cnt+1;
2941
              pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
2942 2943 2944 2945
            }
          } else if (format_c == format0) { // this is a format 1A DCI
            dci_alloc[*dci_cnt].format     = format1A;
            *dci_cnt = *dci_cnt+1;
2946
            pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
2947 2948 2949 2950 2951 2952
          } else {
            // store first nCCE of group for PUCCH transmission of ACK/NAK
            if (*format_c_found == 0) {
              dci_alloc[*dci_cnt].format     = format_c;
              *dci_cnt = *dci_cnt+1;
              *format_c_found = 1;
2953
              pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
2954 2955 2956 2957
            }
          }
        }

2958
        //LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
2959 2960 2961 2962 2963 2964 2965 2966 2967 2968
        //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);



        switch (1<<L) {
        case 1:
          *CCEmap|=(1<<(CCEind&0x1f));
          break;

        case 2:
hbilel's avatar
hbilel committed
2969
          *CCEmap|=(1<<(CCEind&0x1f));
2970 2971 2972
          break;

        case 4:
hbilel's avatar
hbilel committed
2973
          *CCEmap|=(1<<(CCEind&0x1f));
2974 2975 2976
          break;

        case 8:
hbilel's avatar
hbilel committed
2977
          *CCEmap|=(1<<(CCEind&0x1f));
2978 2979 2980
          break;
        }

2981
#ifdef DEBUG_DCI_DECODING
2982 2983
        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n",
              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates );
2984 2985
        dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);

2986
#endif
2987
         return;
2988 2989
      } // rnti match
    }  // CCEmap_cand == 0
2990 2991
/*    
	if ( agregationLevel != 0xFF &&
2992 2993 2994 2995 2996
        (format_c == format0 && m==0 && si_rnti != SI_RNTI))
    {
      //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
      return;
    }
2997
*/
2998 2999 3000
  } // candidate loop
}

3001 3002 3003 3004 3005 3006 3007 3008 3009 3010
uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
                                DCI_ALLOC_t *dci_alloc,
                                uint8_t DCIFormat,
                                uint8_t agregationLevel,
                                int16_t eNB_id,
                                uint8_t subframe)
{

  uint8_t  dci_cnt=0,old_dci_cnt=0;
  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
3011
  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094
  LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
  uint8_t mi = get_mi(&ue->frame_parms,subframe);
  uint16_t ra_rnti=99;
  uint8_t format0_found=0,format_c_found=0;
  uint8_t tmode = ue->transmission_mode[eNB_id];
  uint8_t frame_type = frame_parms->frame_type;
  uint8_t format0_size_bits=0,format0_size_bytes=0;
  uint8_t format1_size_bits=0,format1_size_bytes=0;
  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe);

  switch (frame_parms->N_RB_DL) {
  case 6:
    if (frame_type == TDD) {
      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);

    } else {
      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
    }

    break;

  case 25:
  default:
    if (frame_type == TDD) {
      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
    } else {
      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
    }

    break;

  case 50:
    if (frame_type == TDD) {
      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);

    } else {
      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
    }

    break;

  case 100:
    if (frame_type == TDD) {
      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
    } else {
      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
    }

    break;
  }

  if (ue->prach_resources[eNB_id])
    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;

  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
  dci_decoding_procedure0(pdcch_vars,0,mode,
                          subframe,
                          dci_alloc,
                          eNB_id,
3095
                          ue->current_thread_id[subframe],
3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131
                          frame_parms,
                          mi,
                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                          ra_rnti,
              P_RNTI,
              agregationLevel,
                          format1A,
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);

  if (DCIFormat == 1)
  {
      if ((tmode < 3) || (tmode == 7)) {
          //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);

          // Now check UE_SPEC format 1 search spaces at aggregation 1

           //printf("[DCI search] Format 1/1A aggregation 1\n");

          old_dci_cnt=dci_cnt;
          dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                                  dci_alloc,
                                  eNB_id,
3132
                                  ue->current_thread_id[subframe],
3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175
                                  frame_parms,
                                  mi,
                                  ((ue->decode_SIB == 1) ? SI_RNTI : 0),
                                  ra_rnti,
                                  P_RNTI,
                                  0,
                                  format1A,
                                  format1A,
                                  format1A,
                                  format1,
                                  format1_size_bits,
                                  format1_size_bytes,
                                  &dci_cnt,
                                  &format0_found,
                                  &format_c_found,
                                  &CCEmap0,
                                  &CCEmap1,
                                  &CCEmap2);

          if ((CCEmap0==0xffff) ||
              (format_c_found==1))
            return(dci_cnt);

          if (dci_cnt>old_dci_cnt)
            return(dci_cnt);

          //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);

      }
      else
      {
          AssertFatal(0,"Other Transmission mode not yet coded\n");
      }
  }
  else
  {
     AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat);
  }

  return(dci_cnt);

}

3176
uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
3177 3178 3179 3180 3181 3182
                                DCI_ALLOC_t *dci_alloc,
                                int do_common,
                                int16_t eNB_id,
                                uint8_t subframe)
{

3183 3184
  uint8_t  dci_cnt=0,old_dci_cnt=0;
  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
3185
  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
3186 3187
  LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
  uint8_t mi = get_mi(&ue->frame_parms,subframe);
3188 3189
  uint16_t ra_rnti=99;
  uint8_t format0_found=0,format_c_found=0;
3190
  uint8_t tmode = ue->transmission_mode[eNB_id];
3191
  uint8_t frame_type = frame_parms->frame_type;
3192
  uint8_t format1A_size_bits=0,format1A_size_bytes=0;
3193
  uint8_t format1C_size_bits=0,format1C_size_bytes=0;
3194 3195 3196 3197
  uint8_t format0_size_bits=0,format0_size_bytes=0;
  uint8_t format1_size_bits=0,format1_size_bytes=0;
  uint8_t format2_size_bits=0,format2_size_bytes=0;
  uint8_t format2A_size_bits=0,format2A_size_bytes=0;
3198
  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe);
3199 3200 3201 3202 3203 3204

  switch (frame_parms->N_RB_DL) {
  case 6:
    if (frame_type == TDD) {
      format1A_size_bits  = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
      format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
3205 3206
      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
3207 3208 3209 3210
      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
3211

Xiwen JIANG's avatar
Xiwen JIANG committed
3212
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3213 3214 3215 3216
        format2_size_bits  = sizeof_DCI2_1_5MHz_2A_TDD_t;
        format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3217
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3218 3219 3220 3221
        format2_size_bits  = sizeof_DCI2_1_5MHz_4A_TDD_t;
        format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_TDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3222
      }
3223
    } else {
3224 3225
      format1A_size_bits  = sizeof_DCI1A_1_5MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
3226 3227
      format1C_size_bits  = sizeof_DCI1C_1_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
3228 3229 3230 3231
      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
3232

Xiwen JIANG's avatar
Xiwen JIANG committed
3233
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3234 3235 3236 3237
        format2_size_bits  = sizeof_DCI2_1_5MHz_2A_FDD_t;
        format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_1_5MHz_2A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3238
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3239 3240 3241 3242
        format2_size_bits  = sizeof_DCI2_1_5MHz_4A_FDD_t;
        format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_1_5MHz_4A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_FDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3243
      }
3244
    }
3245

3246
    break;
3247

3248
  case 25:
Raymond Knopp's avatar
 
Raymond Knopp committed
3249
  default:
3250 3251 3252
    if (frame_type == TDD) {
      format1A_size_bits  = sizeof_DCI1A_5MHz_TDD_1_6_t;
      format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
3253 3254
      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
3255 3256 3257 3258
      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
3259

Xiwen JIANG's avatar
Xiwen JIANG committed
3260
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3261 3262 3263 3264
        format2_size_bits  = sizeof_DCI2_5MHz_2A_TDD_t;
        format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_5MHz_2A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3265
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3266 3267 3268 3269
        format2_size_bits  = sizeof_DCI2_5MHz_4A_TDD_t;
        format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_5MHz_4A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_5MHz_4A_TDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3270
      }
3271
    } else {
3272 3273
      format1A_size_bits  = sizeof_DCI1A_5MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t);
3274 3275
      format1C_size_bits  = sizeof_DCI1C_5MHz_t;
      format1C_size_bytes = sizeof(DCI1C_5MHz_t);
3276 3277 3278 3279
      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
3280

Xiwen JIANG's avatar
Xiwen JIANG committed
3281
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3282 3283 3284 3285
        format2_size_bits  = sizeof_DCI2_5MHz_2A_FDD_t;
        format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_5MHz_2A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3286
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3287 3288 3289 3290
        format2_size_bits  = sizeof_DCI2_5MHz_4A_FDD_t;
        format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_5MHz_4A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_5MHz_4A_FDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3291
      }
3292
    }
3293

3294
    break;
3295

3296 3297 3298 3299
  case 50:
    if (frame_type == TDD) {
      format1A_size_bits  = sizeof_DCI1A_10MHz_TDD_1_6_t;
      format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
roux's avatar
roux committed
3300 3301
      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
3302 3303 3304 3305
      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
3306

Xiwen JIANG's avatar
Xiwen JIANG committed
3307
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3308 3309 3310 3311
        format2_size_bits  = sizeof_DCI2_10MHz_2A_TDD_t;
        format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_10MHz_2A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3312
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3313 3314 3315 3316
        format2_size_bits  = sizeof_DCI2_10MHz_4A_TDD_t;
        format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_10MHz_4A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_10MHz_4A_TDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3317
      }
3318
    } else {
3319 3320
      format1A_size_bits  = sizeof_DCI1A_10MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t);
3321 3322
      format1C_size_bits  = sizeof_DCI1C_10MHz_t;
      format1C_size_bytes = sizeof(DCI1C_10MHz_t);
3323 3324 3325 3326
      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
3327

Xiwen JIANG's avatar
Xiwen JIANG committed
3328
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3329 3330 3331 3332
        format2_size_bits  = sizeof_DCI2_10MHz_2A_FDD_t;
        format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_10MHz_2A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3333
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3334 3335 3336 3337
        format2_size_bits  = sizeof_DCI2_10MHz_4A_FDD_t;
        format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_10MHz_4A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_10MHz_4A_FDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3338
      }
3339
    }
3340

3341 3342 3343 3344 3345 3346
    break;

  case 100:
    if (frame_type == TDD) {
      format1A_size_bits  = sizeof_DCI1A_20MHz_TDD_1_6_t;
      format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
3347 3348
      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
3349 3350 3351 3352
      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
3353

Xiwen JIANG's avatar
Xiwen JIANG committed
3354
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3355 3356 3357 3358
        format2_size_bits  = sizeof_DCI2_20MHz_2A_TDD_t;
        format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_20MHz_2A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3359
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3360 3361 3362 3363
        format2_size_bits  = sizeof_DCI2_20MHz_4A_TDD_t;
        format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t);
        format2A_size_bits  = sizeof_DCI2A_20MHz_4A_TDD_t;
        format2A_size_bytes = sizeof(DCI2A_20MHz_4A_TDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3364
      }
3365
    } else {
3366 3367
      format1A_size_bits  = sizeof_DCI1A_20MHz_FDD_t;
      format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t);
3368 3369
      format1C_size_bits  = sizeof_DCI1C_20MHz_t;
      format1C_size_bytes = sizeof(DCI1C_20MHz_t);
3370 3371 3372 3373
      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
3374

Xiwen JIANG's avatar
Xiwen JIANG committed
3375
      if (frame_parms->nb_antenna_ports_eNB == 2) {
3376 3377 3378 3379
        format2_size_bits  = sizeof_DCI2_20MHz_2A_FDD_t;
        format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_20MHz_2A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
Xiwen JIANG's avatar
Xiwen JIANG committed
3380
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
3381 3382 3383 3384
        format2_size_bits  = sizeof_DCI2_20MHz_4A_FDD_t;
        format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t);
        format2A_size_bits  = sizeof_DCI2A_20MHz_4A_FDD_t;
        format2A_size_bytes = sizeof(DCI2A_20MHz_4A_FDD_t);
Raymond Knopp's avatar
 
Raymond Knopp committed
3385
      }
3386
    }
3387

3388 3389 3390
    break;
  }

3391
  if (do_common == 1) {
3392 3393 3394
#ifdef DEBUG_DCI_DECODING
    printf("[DCI search] doing common search/format0 aggregation 4\n");
#endif
3395

3396 3397
    if (ue->prach_resources[eNB_id])
      ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
3398

3399
    // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A),
3400
    // and UE_SPEC format0 (PUSCH) too while we're at it
3401
    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
3402 3403
                            dci_alloc,
                            eNB_id,
3404
                            ue->current_thread_id[subframe],
3405 3406
                            frame_parms,
                            mi,
3407
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0) ,
3408
                            ra_rnti,
3409
			    P_RNTI,
3410 3411 3412
                            2,
                            format1A,
                            format1A,
3413
                            format1A,
3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425
                            format0,
                            format1A_size_bits,
                            format1A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff) ||
        ((format0_found==1)&&(format_c_found==1)))
3426
      return(dci_cnt);
3427

3428
    // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C),
3429
    // and UE_SPEC format0 (PUSCH) too while we're at it
3430
    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
3431 3432
                            dci_alloc,
                            eNB_id,
3433
                            ue->current_thread_id[subframe],
3434 3435
                            frame_parms,
                            mi,
3436
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3437
                            ra_rnti,
3438
			    P_RNTI,
3439 3440 3441 3442
                            2,
                            format1C,
                            format1C,
                            format1C,
3443
                            format1C,
3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456
                            format1C_size_bits,
                            format1C_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff) ||
        ((format0_found==1)&&(format_c_found==1)))
      return(dci_cnt);

3457
    // Now check common search spaces at aggregation 8 (SI_RNTI,P_RNTI and RA_RNTI format 1A),
3458 3459 3460 3461 3462
    // and UE_SPEC format0 (PUSCH) too while we're at it
    //  printf("[DCI search] doing common search/format0 aggregation 3\n");
#ifdef DEBUG_DCI_DECODING
    printf("[DCI search] doing common search/format0 aggregation 8\n");
#endif
3463
    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
3464 3465
                            dci_alloc,
                            eNB_id,
3466
                            ue->current_thread_id[subframe],
3467 3468
                            frame_parms,
                            mi,
3469
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3470
			    P_RNTI,
3471 3472 3473 3474
                            ra_rnti,
                            3,
                            format1A,
                            format1A,
3475
                            format1A,
3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487
                            format0,
                            format1A_size_bits,
                            format1A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3488
      return(dci_cnt);
3489

3490 3491
    // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
    // and UE_SPEC format0 (PUSCH) too while we're at it
3492
    dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
3493 3494
                            dci_alloc,
                            eNB_id,
3495
                            ue->current_thread_id[subframe],
3496 3497
                            frame_parms,
                            mi,
3498
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3499
                            ra_rnti,
3500 3501 3502
			    P_RNTI,
			    3,
                            format1C,
3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513
                            format1C,
                            format1C,
                            format1C,
                            format1C_size_bits,
                            format1C_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3514 3515 3516 3517
    //#endif

  }

3518
  if (ue->UE_mode[eNB_id] <= PRACH)
3519 3520
    return(dci_cnt);

3521 3522
  if (ue->prach_resources[eNB_id])
    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
3523

3524
  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
3525
  //  printf("[DCI search] Format 0/1A aggregation 8\n");
3526
  dci_decoding_procedure0(pdcch_vars,0,mode,
3527 3528 3529
                          subframe,
                          dci_alloc,
                          eNB_id,
3530
                          ue->current_thread_id[subframe],
3531 3532
                          frame_parms,
                          mi,
3533
                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3534
                          ra_rnti,
3535
			  P_RNTI,
3536
			  0,
3537
                          format1A,
3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3551 3552
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);
3553

3554 3555 3556 3557
  //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt);

  if (dci_cnt == 0)
  {
3558
  // Now check UE_SPEC format 0 search spaces at aggregation 4
3559
  dci_decoding_procedure0(pdcch_vars,0,mode,
3560 3561 3562
                          subframe,
                          dci_alloc,
                          eNB_id,
3563
                          ue->current_thread_id[subframe],
3564 3565
                          frame_parms,
                          mi,
3566
                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3567
                          ra_rnti,
3568
			  P_RNTI,
3569
			  1,
3570
                          format1A,
3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583
                          format1A,
                          format1A,
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3584 3585 3586
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);

3587

3588 3589 3590 3591 3592
  //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt);
  }

  if (dci_cnt == 0)
  {
3593
  // Now check UE_SPEC format 0 search spaces at aggregation 2
3594
  dci_decoding_procedure0(pdcch_vars,0,mode,
3595 3596 3597
                          subframe,
                          dci_alloc,
                          eNB_id,
3598
                          ue->current_thread_id[subframe],
3599 3600
                          frame_parms,
                          mi,
3601
                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3602
                          ra_rnti,
3603
			  P_RNTI,
3604
                          2,
3605 3606
                          format1A,
                          format1A,
3607
                          format1A,
3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3619 3620 3621
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);

3622 3623 3624 3625 3626
  //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt);
  }

  if (dci_cnt == 0)
  {
3627
  // Now check UE_SPEC format 0 search spaces at aggregation 1
3628
  dci_decoding_procedure0(pdcch_vars,0,mode,
3629 3630 3631
                          subframe,
                          dci_alloc,
                          eNB_id,
3632
                          ue->current_thread_id[subframe],
3633 3634
                          frame_parms,
                          mi,
3635
                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3636
                          ra_rnti,
3637
			  P_RNTI,
3638
                          3,
3639 3640
                          format1A,
                          format1A,
3641
                          format1A,
3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652
                          format0,
                          format0_size_bits,
                          format0_size_bytes,
                          &dci_cnt,
                          &format0_found,
                          &format_c_found,
                          &CCEmap0,
                          &CCEmap1,
                          &CCEmap2);

  if ((CCEmap0==0xffff)||
3653 3654 3655
      ((format0_found==1)&&(format_c_found==1)))
    return(dci_cnt);

3656
  //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt);
3657

3658
  }
3659
  // These are for CRNTI based on transmission mode
Xiwen JIANG's avatar
Xiwen JIANG committed
3660
  if ((tmode < 3) || (tmode == 7)) {
3661
    // Now check UE_SPEC format 1 search spaces at aggregation 1
3662
    old_dci_cnt=dci_cnt;
3663
    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
3664 3665
                            dci_alloc,
                            eNB_id,
3666
                            ue->current_thread_id[subframe],
3667 3668
                            frame_parms,
                            mi,
3669
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3670
                            ra_rnti,
3671
			    P_RNTI,
3672 3673 3674
                            0,
                            format1A,
                            format1A,
3675
                            format1A,
3676 3677 3678 3679 3680 3681 3682 3683 3684
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3685
    //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt);
3686 3687 3688

    if ((CCEmap0==0xffff) ||
        (format_c_found==1))
3689
      return(dci_cnt);
3690

3691 3692
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3693 3694

    // Now check UE_SPEC format 1 search spaces at aggregation 2
3695
    old_dci_cnt=dci_cnt;
3696
    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
3697 3698
                            dci_alloc,
                            eNB_id,
3699
                            ue->current_thread_id[subframe],
3700 3701
                            frame_parms,
                            mi,
3702
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3703
                            ra_rnti,
3704
			    P_RNTI,
3705 3706 3707
                            1,
                            format1A,
                            format1A,
3708
                            format1A,
3709 3710 3711 3712 3713 3714 3715 3716 3717
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3718
    //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt);
3719 3720 3721

    if ((CCEmap0==0xffff)||
        (format_c_found==1))
3722
      return(dci_cnt);
3723

3724
    if (dci_cnt>old_dci_cnt)
3725
      return(dci_cnt);
3726

3727
    // Now check UE_SPEC format 1 search spaces at aggregation 4
3728
    old_dci_cnt=dci_cnt;
3729
    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
3730 3731
                            dci_alloc,
                            eNB_id,
3732
                            ue->current_thread_id[subframe],
3733 3734
                            frame_parms,
                            mi,
3735
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3736
                            ra_rnti,
3737 3738 3739
			    P_RNTI,
			    2,
                            format1A,
3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750
                            format1A,
                            format1A,
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3751
    //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt);
3752 3753 3754

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3755
      return(dci_cnt);
3756

3757 3758 3759 3760 3761 3762
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#ifdef ALL_AGGREGATION
    // Now check UE_SPEC format 1 search spaces at aggregation 8
    old_dci_cnt=dci_cnt;
3763
    dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
3764 3765
                            dci_alloc,
                            eNB_id,
3766
                            ue->current_thread_id[subframe],
3767 3768
                            frame_parms,
                            mi,
3769
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3770
                            ra_rnti,
3771
			    P_RNTI,
3772 3773 3774
                            3,
                            format1A,
                            format1A,
3775
                            format1A,
3776 3777 3778 3779 3780 3781 3782 3783 3784
                            format1,
                            format1_size_bits,
                            format1_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3785
    //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt);
3786 3787 3788

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3789
      return(dci_cnt);
3790

3791 3792
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3793 3794 3795

    //#endif //ALL_AGGREGATION
  } else if (tmode == 3) {
3796 3797


hbilel's avatar
hbilel committed
3798
    LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
3799
    // Now check UE_SPEC format 2A_2A search spaces at aggregation 1
hbilel's avatar
hbilel committed
3800
    old_dci_cnt=dci_cnt;
3801
    dci_decoding_procedure0(pdcch_vars,0,mode,
3802 3803 3804
                            subframe,
                            dci_alloc,
                            eNB_id,
3805
                            ue->current_thread_id[subframe],
3806 3807
                            frame_parms,
                            mi,
3808
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3809
                            ra_rnti,
hbilel's avatar
hbilel committed
3810
                            P_RNTI,
3811 3812 3813
                            0,
                            format1A,
                            format1A,
3814
                            format1A,
3815 3816 3817 3818 3819 3820 3821 3822 3823 3824
                            format2A,
                            format2A_size_bits,
                            format2A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

hbilel's avatar
hbilel committed
3825
    LOG_D(PHY," format 2A_2A search CCEmap0 %x, format0_found %d, format_c_found %d \n", CCEmap0, format0_found, format_c_found);
3826 3827
    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3828
      return(dci_cnt);
3829

hbilel's avatar
hbilel committed
3830
    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
3831 3832 3833
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3834
    // Now check UE_SPEC format 2 search spaces at aggregation 2
hbilel's avatar
hbilel committed
3835
    LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
hbilel's avatar
hbilel committed
3836
    old_dci_cnt=dci_cnt;
3837
    dci_decoding_procedure0(pdcch_vars,0,mode,
3838 3839 3840
                            subframe,
                            dci_alloc,
                            eNB_id,
3841
                            ue->current_thread_id[subframe],
3842 3843
                            frame_parms,
                            mi,
3844
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3845
                            ra_rnti,
3846
			    P_RNTI,
3847 3848 3849
                            1,
                            format1A,
                            format1A,
3850
                            format1A,
3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862
                            format2A,
                            format2A_size_bits,
                            format2A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3863
      return(dci_cnt);
3864

hbilel's avatar
hbilel committed
3865
    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
3866 3867 3868
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3869
    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
hbilel's avatar
hbilel committed
3870 3871
    LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n");
    old_dci_cnt=dci_cnt;
3872
    dci_decoding_procedure0(pdcch_vars,0,mode,
3873 3874 3875
                            subframe,
                            dci_alloc,
                            eNB_id,
3876
                            ue->current_thread_id[subframe],
3877 3878
                            frame_parms,
                            mi,
3879
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3880
                            ra_rnti,
hbilel's avatar
hbilel committed
3881
                            P_RNTI,
3882 3883 3884
                            2,
                            format1A,
                            format1A,
3885
                            format1A,
3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897
                            format2A,
                            format2A_size_bits,
                            format2A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3898
      return(dci_cnt);
3899

hbilel's avatar
hbilel committed
3900
    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
3901 3902 3903 3904
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#ifdef ALL_AGGREGATION
3905
    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
hbilel's avatar
hbilel committed
3906
    LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes);
hbilel's avatar
hbilel committed
3907
    old_dci_cnt=dci_cnt;
3908
    dci_decoding_procedure0(pdcch_vars,0,mode,
3909 3910 3911
                            subframe,
                            dci_alloc,
                            eNB_id,
3912
                            ue->current_thread_id[subframe],
3913 3914
                            frame_parms,
                            mi,
3915
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3916
                            ra_rnti,
3917
			    P_RNTI,
3918 3919 3920
                            3,
                            format1A,
                            format1A,
3921
                            format1A,
3922 3923 3924 3925 3926 3927 3928 3929 3930
                            format2A,
                            format2A_size_bits,
                            format2A_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
3931
    //#endif
hbilel's avatar
hbilel committed
3932 3933 3934 3935 3936 3937 3938
    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
      return(dci_cnt);

    LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt);
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
3939
  } else if (tmode == 4) {
3940

3941
    // Now check UE_SPEC format 2_2A search spaces at aggregation 1
hbilel's avatar
hbilel committed
3942
    old_dci_cnt=dci_cnt;
3943
    dci_decoding_procedure0(pdcch_vars,0,mode,
3944 3945 3946
                            subframe,
                            dci_alloc,
                            eNB_id,
3947
                            ue->current_thread_id[subframe],
3948 3949
                            frame_parms,
                            mi,
3950
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3951
                            ra_rnti,
3952
			    P_RNTI,
3953 3954 3955
                            0,
                            format1A,
                            format1A,
3956
                            format1A,
3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968
                            format2,
                            format2_size_bits,
                            format2_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
3969
      return(dci_cnt);
3970

3971 3972 3973
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

3974
    // Now check UE_SPEC format 2 search spaces at aggregation 2
hbilel's avatar
hbilel committed
3975
    old_dci_cnt=dci_cnt;
3976
    dci_decoding_procedure0(pdcch_vars,0,mode,
3977 3978 3979
                            subframe,
                            dci_alloc,
                            eNB_id,
3980
                            ue->current_thread_id[subframe],
3981 3982
                            frame_parms,
                            mi,
3983
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
3984
                            ra_rnti,
3985
			    P_RNTI,
3986 3987 3988
                            1,
                            format1A,
                            format1A,
3989
                            format1A,
3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001
                            format2,
                            format2_size_bits,
                            format2_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
4002
      return(dci_cnt);
4003

4004 4005 4006
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

4007
    // Now check UE_SPEC format 2_2A search spaces at aggregation 4
hbilel's avatar
hbilel committed
4008
    old_dci_cnt=dci_cnt;
4009
    dci_decoding_procedure0(pdcch_vars,0,mode,
4010 4011 4012
                            subframe,
                            dci_alloc,
                            eNB_id,
4013
                            ue->current_thread_id[subframe],
4014 4015
                            frame_parms,
                            mi,
4016
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4017
                            ra_rnti,
4018
			    P_RNTI,
4019 4020 4021
                            2,
                            format1A,
                            format1A,
4022
                            format1A,
4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034
                            format2,
                            format2_size_bits,
                            format2_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
4035
      return(dci_cnt);
4036

4037 4038 4039 4040
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#ifdef ALL_AGGREGATION
4041
    // Now check UE_SPEC format 2_2A search spaces at aggregation 8
hbilel's avatar
hbilel committed
4042
    old_dci_cnt=dci_cnt;
4043
    dci_decoding_procedure0(pdcch_vars,0,mode,
4044 4045 4046
                            subframe,
                            dci_alloc,
                            eNB_id,
4047
                            ue->current_thread_id[subframe],
4048 4049
                            frame_parms,
                            mi,
4050
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4051
                            ra_rnti,
4052
			    P_RNTI,
4053 4054 4055
                            3,
                            format1A,
                            format1A,
4056
                            format1A,
4057 4058 4059 4060 4061 4062 4063 4064 4065
                            format2,
                            format2_size_bits,
                            format2_size_bytes,
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);
4066
    //#endif
Xiwen JIANG's avatar
Xiwen JIANG committed
4067
  } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO
4068

4069
    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1
4070
#ifdef DEBUG_DCI_DECODING
4071
    LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n");
4072
#endif
hbilel's avatar
hbilel committed
4073
    old_dci_cnt=dci_cnt;
4074
    dci_decoding_procedure0(pdcch_vars,0,mode,
4075 4076 4077
                            subframe,
                            dci_alloc,
                            eNB_id,
4078
                            ue->current_thread_id[subframe],
4079 4080
                            frame_parms,
                            mi,
4081
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4082
                            ra_rnti,
4083
			    P_RNTI,
4084 4085 4086
                            0,
                            format1A,
                            format1A,
4087
                            format1A,
4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100
                            format1E_2A_M10PRB,
                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);


    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
4101
      return(dci_cnt);
4102

4103 4104
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
4105 4106

    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2
hbilel's avatar
hbilel committed
4107
    old_dci_cnt=dci_cnt;
4108
    dci_decoding_procedure0(pdcch_vars,0,mode,
4109 4110 4111
                            subframe,
                            dci_alloc,
                            eNB_id,
4112
                            ue->current_thread_id[subframe],
4113 4114
                            frame_parms,
                            mi,
4115
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4116
                            ra_rnti,
4117
			    P_RNTI,
4118 4119 4120
                            1,
                            format1A,
                            format1A,
4121
                            format1A,
4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134
                            format1E_2A_M10PRB,
                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
      return(dci_cnt);
4135

4136 4137
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
4138

4139
    // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4
hbilel's avatar
hbilel committed
4140
    old_dci_cnt=dci_cnt;
4141
    dci_decoding_procedure0(pdcch_vars,0,mode,
4142 4143 4144
                            subframe,
                            dci_alloc,
                            eNB_id,
4145
                            ue->current_thread_id[subframe],
4146 4147
                            frame_parms,
                            mi,
4148
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4149
                            ra_rnti,
4150
			    P_RNTI,
4151 4152 4153
                            2,
                            format1A,
                            format1A,
4154
                            format1A,
4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167
                            format1E_2A_M10PRB,
                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
      return(dci_cnt);
4168

4169 4170
    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);
4171

4172 4173 4174
    //#ifdef ALL_AGGREGATION

    // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8
hbilel's avatar
hbilel committed
4175
    old_dci_cnt=dci_cnt;
4176
    dci_decoding_procedure0(pdcch_vars,0,mode,
4177 4178 4179
                            subframe,
                            dci_alloc,
                            eNB_id,
4180
                            ue->current_thread_id[subframe],
4181 4182
                            frame_parms,
                            mi,
4183
                            ((ue->decode_SIB == 1) ? SI_RNTI : 0),
4184
                            ra_rnti,
4185
			    P_RNTI,
4186 4187 4188
                            3,
                            format1A,
                            format1A,
4189
                            format1A,
4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209
                            format1E_2A_M10PRB,
                            sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                            sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                            &dci_cnt,
                            &format0_found,
                            &format_c_found,
                            &CCEmap0,
                            &CCEmap1,
                            &CCEmap2);

    if ((CCEmap0==0xffff)||
        ((format0_found==1)&&(format_c_found==1)))
      return(dci_cnt);

    if (dci_cnt>old_dci_cnt)
      return(dci_cnt);

    //#endif  //ALL_AGGREGATION

  }
4210 4211 4212 4213 4214

  return(dci_cnt);
}

#ifdef PHY_ABSTRACTION
4215
uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **pdcch_vars,
4216 4217 4218 4219 4220 4221 4222
                                     uint8_t num_ue_spec_dci,
                                     uint8_t num_common_dci,
                                     DCI_ALLOC_t *dci_alloc_tx,
                                     DCI_ALLOC_t *dci_alloc_rx,
                                     int16_t eNB_id)
{

4223
  uint8_t  dci_cnt=0,i;
4224

4225 4226 4227 4228
  memcpy(dci_alloc_rx,dci_alloc_tx,num_common_dci*sizeof(DCI_ALLOC_t));
  dci_cnt = num_common_dci;
  LOG_D(PHY,"[DCI][EMUL] : num_common_dci %d\n",num_common_dci);

4229
  for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) {
4230
    LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format,
4231 4232
          dci_alloc_tx[i].dci_pdu[0]&0x80);

4233
    if (dci_alloc_tx[i].rnti == pdcch_vars[eNB_id]->crnti) {
4234 4235 4236 4237 4238 4239 4240 4241 4242
      memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t));
      dci_cnt++;
    }
  }


  return(dci_cnt);
}
#endif